Example #1
0
    def create(self, cr, uid, values, context=None):
        Acquirer = self.pool['payment.acquirer']

        if values.get('partner_id'):  # @TDENOTE: not sure
            values.update(self.on_change_partner_id(cr, uid, None, values.get('partner_id'), context=context)['value'])

        # call custom create method if defined (i.e. ogone_create for ogone)
        if values.get('acquirer_id'):
            acquirer = self.pool['payment.acquirer'].browse(cr, uid, values.get('acquirer_id'), context=context)

            # compute fees
            custom_method_name = '%s_compute_fees' % acquirer.provider
            if hasattr(Acquirer, custom_method_name):
                fees = getattr(Acquirer, custom_method_name)(
                    cr, uid, acquirer.id, values.get('amount', 0.0), values.get('currency_id'), values.get('partner_country_id'), context=None)
                values['fees'] = float_round(fees, 2)

            # custom create
            custom_method_name = '%s_create' % acquirer.provider
            if hasattr(self, custom_method_name):
                values.update(getattr(self, custom_method_name)(cr, uid, values, context=context))

        # Default value of reference is
        tx_id = super(PaymentTransaction, self).create(cr, uid, values, context=context)
        if not values.get('reference'):
            self.write(cr, uid, [tx_id], {'reference': str(tx_id)}, context=context)
        return tx_id
Example #2
0
 def ogone_form_generate_values(self, cr, uid, id, values, context=None):
     base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
     acquirer = self.browse(cr, uid, id, context=context)
     ogone_tx_values = dict(values)
     temp_ogone_tx_values = {
         'PSPID': acquirer.ogone_pspid,
         'ORDERID': values['reference'],
         'AMOUNT': float_repr(float_round(values['amount'], 2) * 100, 0),
         'CURRENCY': values['currency'] and values['currency'].name or '',
         'LANGUAGE': values.get('partner_lang'),
         'CN': values.get('partner_name'),
         'EMAIL': values.get('partner_email'),
         'OWNERZIP': values.get('partner_zip'),
         'OWNERADDRESS': values.get('partner_address'),
         'OWNERTOWN': values.get('partner_city'),
         'OWNERCTY': values.get('partner_country') and values.get('partner_country').code or '',
         'OWNERTELNO': values.get('partner_phone'),
         'ACCEPTURL': '%s' % urlparse.urljoin(base_url, OgoneController._accept_url),
         'DECLINEURL': '%s' % urlparse.urljoin(base_url, OgoneController._decline_url),
         'EXCEPTIONURL': '%s' % urlparse.urljoin(base_url, OgoneController._exception_url),
         'CANCELURL': '%s' % urlparse.urljoin(base_url, OgoneController._cancel_url),
         'PARAMPLUS': 'return_url=%s' % ogone_tx_values.pop('return_url') if ogone_tx_values.get('return_url') else False,
     }
     if values.get('type') == 'form_save':
         temp_ogone_tx_values.update({
             'ALIAS': 'eCore-NEW-ALIAS-%s' % time.time(),    # something unique,
             'ALIASUSAGE': values.get('alias_usage') or acquirer.ogone_alias_usage,
         })
     shasign = self._ogone_generate_shasign(acquirer, 'in', temp_ogone_tx_values)
     temp_ogone_tx_values['SHASIGN'] = shasign
     ogone_tx_values.update(temp_ogone_tx_values)
     return ogone_tx_values
Example #3
0
 def write(self, cr, uid, ids, values, context=None):
     Acquirer = self.pool['payment.acquirer']
     if ('acquirer_id' in values or 'amount' in values) and 'fees' not in values:
         # The acquirer or the amount has changed, and the fees are not explicitely forced. Fees must be recomputed.
         if isinstance(ids, (int, long)):
             ids = [ids]
         for txn_id in ids:
             vals = dict(values)
             vals['fees'] = 0.0
             transaction = self.browse(cr, uid, txn_id, context=context)
             if 'acquirer_id' in values:
                 acquirer = Acquirer.browse(cr, uid, values['acquirer_id'], context=context) if values['acquirer_id'] else None
             else:
                 acquirer = transaction.acquirer_id
             if acquirer:
                 custom_method_name = '%s_compute_fees' % acquirer.provider
                 if hasattr(Acquirer, custom_method_name):
                     amount = (values['amount'] if 'amount' in values else transaction.amount) or 0.0
                     currency_id = values.get('currency_id') or transaction.currency_id.id
                     country_id = values.get('partner_country_id') or transaction.partner_country_id.id
                     fees = getattr(Acquirer, custom_method_name)(cr, uid, acquirer.id, amount, currency_id, country_id, context=None)
                     vals['fees'] = float_round(fees, 2)
             res = super(PaymentTransaction, self).write(cr, uid, txn_id, vals, context=context)
         return res
     return super(PaymentTransaction, self).write(cr, uid, ids, values, context=context)
Example #4
0
    def adyen_form_generate_values(self, cr, uid, id, values, context=None):
        base_url = self.pool['ir.config_parameter'].get_param(
            cr, uid, 'web.base.url')
        acquirer = self.browse(cr, uid, id, context=context)
        # tmp
        import datetime
        from dateutil import relativedelta
        tmp_date = datetime.date.today() + relativedelta.relativedelta(days=1)

        values.update({
            'merchantReference':
            values['reference'],
            'paymentAmount':
            '%d' % int(float_round(values['amount'], 2) * 100),
            'currencyCode':
            values['currency'] and values['currency'].name or '',
            'shipBeforeDate':
            tmp_date,
            'skinCode':
            acquirer.adyen_skin_code,
            'merchantAccount':
            acquirer.adyen_merchant_account,
            'shopperLocale':
            values.get('partner_lang'),
            'sessionValidity':
            tmp_date,
            'resURL':
            '%s' % urlparse.urljoin(base_url, AdyenController._return_url),
            'merchantReturnData':
            json.dumps({'return_url': '%s' % values.pop('return_url')})
            if values.get('return_url') else False,
            'merchantSig':
            self._adyen_generate_merchant_sig(acquirer, 'in', values),
        })
        return values
Example #5
0
    def round(self, cr, uid, currency, amount):
        """Return ``amount`` rounded  according to ``currency``'s
           rounding rules.

           :param Record currency: currency for which we are rounding
           :param float amount: the amount to round
           :return: rounded float
        """
        return float_round(amount, precision_rounding=currency.rounding)
Example #6
0
 def _onchange_amount(self):
     if hasattr(super(account_payment, self), '_onchange_amount'):
         super(account_payment, self)._onchange_amount()
     check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(self.amount), lang='en', currency='')
     check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh
     decimals = self.amount % 1
     if decimals >= 10**-2:
         check_amount_in_words += _(' and %s/100') % str(int(round(float_round(decimals*100, precision_rounding=1))))
     self.check_amount_in_words = check_amount_in_words
Example #7
0
 def _onchange_amount(self):
     if hasattr(super(account_register_payments, self), '_onchange_amount'):
         super(account_register_payments, self)._onchange_amount()
     # TODO: merge, refactor and complete the amount_to_text and amount_to_text_en classes
     check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(self.amount), lang='en', currency='')
     check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh
     decimals = self.amount % 1
     if decimals >= 10**-2:
         check_amount_in_words += _(' and %s/100') % str(int(round(float_round(decimals*100, precision_rounding=1))))
     self.check_amount_in_words = check_amount_in_words
Example #8
0
 def ogone_form_generate_values(self, cr, uid, id, values, context=None):
     base_url = self.pool['ir.config_parameter'].get_param(
         cr, uid, 'web.base.url')
     acquirer = self.browse(cr, uid, id, context=context)
     ogone_tx_values = dict(values)
     temp_ogone_tx_values = {
         'PSPID':
         acquirer.ogone_pspid,
         'ORDERID':
         values['reference'],
         'AMOUNT':
         float_repr(float_round(values['amount'], 2) * 100, 0),
         'CURRENCY':
         values['currency'] and values['currency'].name or '',
         'LANGUAGE':
         values.get('partner_lang'),
         'CN':
         values.get('partner_name'),
         'EMAIL':
         values.get('partner_email'),
         'OWNERZIP':
         values.get('partner_zip'),
         'OWNERADDRESS':
         values.get('partner_address'),
         'OWNERTOWN':
         values.get('partner_city'),
         'OWNERCTY':
         values.get('partner_country')
         and values.get('partner_country').code or '',
         'OWNERTELNO':
         values.get('partner_phone'),
         'ACCEPTURL':
         '%s' % urlparse.urljoin(base_url, OgoneController._accept_url),
         'DECLINEURL':
         '%s' % urlparse.urljoin(base_url, OgoneController._decline_url),
         'EXCEPTIONURL':
         '%s' % urlparse.urljoin(base_url, OgoneController._exception_url),
         'CANCELURL':
         '%s' % urlparse.urljoin(base_url, OgoneController._cancel_url),
         'PARAMPLUS':
         'return_url=%s' % ogone_tx_values.pop('return_url')
         if ogone_tx_values.get('return_url') else False,
     }
     if values.get('type') == 'form_save':
         temp_ogone_tx_values.update({
             'ALIAS':
             'eCore-NEW-ALIAS-%s' % time.time(),  # something unique,
             'ALIASUSAGE':
             values.get('alias_usage') or acquirer.ogone_alias_usage,
         })
     shasign = self._ogone_generate_shasign(acquirer, 'in',
                                            temp_ogone_tx_values)
     temp_ogone_tx_values['SHASIGN'] = shasign
     ogone_tx_values.update(temp_ogone_tx_values)
     return ogone_tx_values
 def ret(comparator, amount, p=precision, f=field, c=currency):
     if comparator == '<':
         if amount < 0:
             domain = [(f, '<', 0), (f, '>', amount)]
         else:
             domain = [(f, '>', 0), (f, '<', amount)]
     elif comparator == '=':
         domain = [(f, '=', float_round(amount, precision_digits=p))]
     else:
         raise UserError(_("Programmation error : domain_maker_move_line_amount requires comparator '=' or '<'"))
     domain += [('currency_id', '=', c)]
     return domain
Example #10
0
 def _onchange_amount(self):
     if hasattr(super(account_payment, self), '_onchange_amount'):
         super(account_payment, self)._onchange_amount()
     check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(
         self.amount),
                                                              lang='en',
                                                              currency='')
     check_amount_in_words = check_amount_in_words.replace(
         ' and Zero Cent', '')  # Ugh
     decimals = self.amount % 1
     if decimals >= 10**-2:
         check_amount_in_words += _(' and %s/100') % str(
             int(round(float_round(decimals * 100, precision_rounding=1))))
     self.check_amount_in_words = check_amount_in_words
Example #11
0
 def _onchange_amount(self):
     if hasattr(super(account_register_payments, self), '_onchange_amount'):
         super(account_register_payments, self)._onchange_amount()
     # TODO: merge, refactor and complete the amount_to_text and amount_to_text_en classes
     check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(
         self.amount),
                                                              lang='en',
                                                              currency='')
     check_amount_in_words = check_amount_in_words.replace(
         ' and Zero Cent', '')  # Ugh
     decimals = self.amount % 1
     if decimals >= 10**-2:
         check_amount_in_words += _(' and %s/100') % str(
             int(round(float_round(decimals * 100, precision_rounding=1))))
     self.check_amount_in_words = check_amount_in_words
Example #12
0
    def adyen_form_generate_values(self, cr, uid, id, values, context=None):
        base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
        acquirer = self.browse(cr, uid, id, context=context)
        # tmp
        import datetime
        from dateutil import relativedelta
        tmp_date = datetime.date.today() + relativedelta.relativedelta(days=1)

        values.update({
            'merchantReference': values['reference'],
            'paymentAmount': '%d' % int(float_round(values['amount'], 2) * 100),
            'currencyCode': values['currency'] and values['currency'].name or '',
            'shipBeforeDate': tmp_date,
            'skinCode': acquirer.adyen_skin_code,
            'merchantAccount': acquirer.adyen_merchant_account,
            'shopperLocale': values.get('partner_lang'),
            'sessionValidity': tmp_date,
            'resURL': '%s' % urlparse.urljoin(base_url, AdyenController._return_url),
            'merchantReturnData': json.dumps({'return_url': '%s' % values.pop('return_url')}) if values.get('return_url') else False,
            'merchantSig': self._adyen_generate_merchant_sig(acquirer, 'in', values),
        })
        return values
Example #13
0
    def _price_rule_get_multi(self,
                              cr,
                              uid,
                              pricelist,
                              products_by_qty_by_partner,
                              context=None):
        context = context or {}
        date = context.get('date') and context['date'][0:10] or time.strftime(
            DEFAULT_SERVER_DATE_FORMAT)
        products = map(lambda x: x[0], products_by_qty_by_partner)
        product_uom_obj = self.pool.get('product.uom')

        if not products:
            return {}

        categ_ids = {}
        for p in products:
            categ = p.categ_id
            while categ:
                categ_ids[categ.id] = True
                categ = categ.parent_id
        categ_ids = categ_ids.keys()

        is_product_template = products[0]._name == "product.template"
        if is_product_template:
            prod_tmpl_ids = [tmpl.id for tmpl in products]
            # all variants of all products
            prod_ids = [
                p.id for p in list(
                    chain.from_iterable(
                        [t.product_variant_ids for t in products]))
            ]
        else:
            prod_ids = [product.id for product in products]
            prod_tmpl_ids = [
                product.product_tmpl_id.id for product in products
            ]

        # Load all rules
        cr.execute(
            'SELECT i.id '
            'FROM product_pricelist_item AS i '
            'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = any(%s))'
            'AND (product_id IS NULL OR product_id = any(%s))'
            'AND (categ_id IS NULL OR categ_id = any(%s)) '
            'AND (pricelist_id = %s) '
            'AND ((i.date_start IS NULL OR i.date_start<=%s) AND (i.date_end IS NULL OR i.date_end>=%s))'
            'ORDER BY applied_on, min_quantity desc',
            (prod_tmpl_ids, prod_ids, categ_ids, pricelist.id, date, date))

        item_ids = [x[0] for x in cr.fetchall()]
        items = self.pool.get('product.pricelist.item').browse(cr,
                                                               uid,
                                                               item_ids,
                                                               context=context)
        results = {}
        for product, qty, partner in products_by_qty_by_partner:
            results[product.id] = 0.0
            suitable_rule = False

            # Final unit price is computed according to `qty` in the `qty_uom_id` UoM.
            # An intermediary unit price may be computed according to a different UoM, in
            # which case the price_uom_id contains that UoM.
            # The final price will be converted to match `qty_uom_id`.
            qty_uom_id = context.get('uom') or product.uom_id.id
            price_uom_id = product.uom_id.id
            qty_in_product_uom = qty
            if qty_uom_id != product.uom_id.id:
                try:
                    qty_in_product_uom = product_uom_obj._compute_qty(
                        cr, uid, context['uom'], qty, product.uom_id.id)
                except UserError:
                    # Ignored - incompatible UoM in context, use default product UoM
                    pass

            # if Public user try to access standard price from website sale, need to call _price_get.
            price = self.pool['product.template']._price_get(
                cr, uid, [product], 'list_price', context=context)[product.id]

            price_uom_id = qty_uom_id
            for rule in items:
                if rule.min_quantity and qty_in_product_uom < rule.min_quantity:
                    continue
                if is_product_template:
                    if rule.product_tmpl_id and product.id != rule.product_tmpl_id.id:
                        continue
                    if rule.product_id and \
                            (product.product_variant_count > 1 or product.product_variant_ids[0].id != rule.product_id.id):
                        # product rule acceptable on template if has only one variant
                        continue
                else:
                    if rule.product_tmpl_id and product.product_tmpl_id.id != rule.product_tmpl_id.id:
                        continue
                    if rule.product_id and product.id != rule.product_id.id:
                        continue

                if rule.base == 'pricelist' and rule.base_pricelist_id:
                    price_tmp = self._price_get_multi(
                        cr,
                        uid,
                        rule.base_pricelist_id, [(product, qty, partner)],
                        context=context)[product.id]
                    ptype_src = rule.base_pricelist_id.currency_id.id
                    price = self.pool['res.currency'].compute(
                        cr,
                        uid,
                        ptype_src,
                        pricelist.currency_id.id,
                        price_tmp,
                        round=False,
                        context=context)
                else:
                    # if base option is public price take sale price else cost price of product
                    # price_get returns the price in the context UoM, i.e. qty_uom_id
                    price = self.pool['product.template']._price_get(
                        cr, uid, [product], rule.base,
                        context=context)[product.id]

                convert_to_price_uom = (
                    lambda price: product_uom_obj._compute_price(
                        cr, uid, product.uom_id.id, price, price_uom_id))

                if price is not False:
                    if rule.compute_price == 'fixed':
                        price = convert_to_price_uom(rule.fixed_price)
                    elif rule.compute_price == 'percentage':
                        price = (price - (price *
                                          (rule.percent_price / 100))) or 0.0
                    else:
                        #complete formula
                        price_limit = price
                        price = (price - (price *
                                          (rule.price_discount / 100))) or 0.0
                        if rule.price_round:
                            price = tools.float_round(
                                price, precision_rounding=rule.price_round)

                        if rule.price_surcharge:
                            price_surcharge = convert_to_price_uom(
                                rule.price_surcharge)
                            price += price_surcharge

                        if rule.price_min_margin:
                            price_min_margin = convert_to_price_uom(
                                rule.price_min_margin)
                            price = max(price, price_limit + price_min_margin)

                        if rule.price_max_margin:
                            price_max_margin = convert_to_price_uom(
                                rule.price_max_margin)
                            price = min(price, price_limit + price_max_margin)
                    suitable_rule = rule
                break
            # Final price conversion into pricelist currency
            if suitable_rule and suitable_rule.compute_price != 'fixed' and suitable_rule.base != 'pricelist':
                user_company = self.pool['res.users'].browse(
                    cr, uid, uid, context=context).company_id
                price = self.pool['res.currency'].compute(
                    cr,
                    uid,
                    user_company.currency_id.id,
                    pricelist.currency_id.id,
                    price,
                    context=context)

            results[product.id] = (price, suitable_rule and suitable_rule.id
                                   or False)
        return results
Example #14
0
    def _price_rule_get_multi(self, cr, uid, pricelist, products_by_qty_by_partner, context=None):
        context = context or {}
        date = context.get('date') and context['date'][0:10] or time.strftime(DEFAULT_SERVER_DATE_FORMAT)
        products = map(lambda x: x[0], products_by_qty_by_partner)
        product_uom_obj = self.pool.get('product.uom')

        if not products:
            return {}

        categ_ids = {}
        for p in products:
            categ = p.categ_id
            while categ:
                categ_ids[categ.id] = True
                categ = categ.parent_id
        categ_ids = categ_ids.keys()

        is_product_template = products[0]._name == "product.template"
        if is_product_template:
            prod_tmpl_ids = [tmpl.id for tmpl in products]
            # all variants of all products
            prod_ids = [p.id for p in
                        list(chain.from_iterable([t.product_variant_ids for t in products]))]
        else:
            prod_ids = [product.id for product in products]
            prod_tmpl_ids = [product.product_tmpl_id.id for product in products]

        # Load all rules
        cr.execute(
            'SELECT i.id '
            'FROM product_pricelist_item AS i '
            'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = any(%s))'
            'AND (product_id IS NULL OR product_id = any(%s))'
            'AND (categ_id IS NULL OR categ_id = any(%s)) '
            'AND (pricelist_id = %s) '
            'AND ((i.date_start IS NULL OR i.date_start<=%s) AND (i.date_end IS NULL OR i.date_end>=%s))'
            'ORDER BY applied_on, min_quantity desc',
            (prod_tmpl_ids, prod_ids, categ_ids, pricelist.id, date, date))

        item_ids = [x[0] for x in cr.fetchall()]
        items = self.pool.get('product.pricelist.item').browse(cr, uid, item_ids, context=context)
        results = {}
        for product, qty, partner in products_by_qty_by_partner:
            results[product.id] = 0.0
            suitable_rule = False

            # Final unit price is computed according to `qty` in the `qty_uom_id` UoM.
            # An intermediary unit price may be computed according to a different UoM, in
            # which case the price_uom_id contains that UoM.
            # The final price will be converted to match `qty_uom_id`.
            qty_uom_id = context.get('uom') or product.uom_id.id
            price_uom_id = product.uom_id.id
            qty_in_product_uom = qty
            if qty_uom_id != product.uom_id.id:
                try:
                    qty_in_product_uom = product_uom_obj._compute_qty(
                        cr, uid, context['uom'], qty, product.uom_id.id)
                except UserError:
                    # Ignored - incompatible UoM in context, use default product UoM
                    pass

            # if Public user try to access standard price from website sale, need to call _price_get.
            price = self.pool['product.template']._price_get(cr, uid, [product], 'list_price', context=context)[product.id]

            price_uom_id = qty_uom_id
            for rule in items:
                if rule.min_quantity and qty_in_product_uom < rule.min_quantity:
                    continue
                if is_product_template:
                    if rule.product_tmpl_id and product.id != rule.product_tmpl_id.id:
                        continue
                    if rule.product_id and \
                            (product.product_variant_count > 1 or product.product_variant_ids[0].id != rule.product_id.id):
                        # product rule acceptable on template if has only one variant
                        continue
                else:
                    if rule.product_tmpl_id and product.product_tmpl_id.id != rule.product_tmpl_id.id:
                        continue
                    if rule.product_id and product.id != rule.product_id.id:
                        continue

                if rule.base == 'pricelist' and rule.base_pricelist_id:
                    price_tmp = self._price_get_multi(cr, uid, rule.base_pricelist_id, [(product, qty, partner)], context=context)[product.id]
                    ptype_src = rule.base_pricelist_id.currency_id.id
                    price = self.pool['res.currency'].compute(cr, uid, ptype_src, pricelist.currency_id.id, price_tmp, round=False, context=context)
                else:
                    # if base option is public price take sale price else cost price of product
                    # price_get returns the price in the context UoM, i.e. qty_uom_id
                    price = self.pool['product.template']._price_get(cr, uid, [product], rule.base, context=context)[product.id]

                convert_to_price_uom = (lambda price: product_uom_obj._compute_price(
                                            cr, uid, product.uom_id.id,
                                            price, price_uom_id))

                if price is not False:
                    if rule.compute_price == 'fixed':
                        price = convert_to_price_uom(rule.fixed_price)
                    elif rule.compute_price == 'percentage':
                        price = (price - (price * (rule.percent_price / 100))) or 0.0
                    else:
                        #complete formula
                        price_limit = price
                        price = (price - (price * (rule.price_discount / 100))) or 0.0
                        if rule.price_round:
                            price = tools.float_round(price, precision_rounding=rule.price_round)

                        if rule.price_surcharge:
                            price_surcharge = convert_to_price_uom(rule.price_surcharge)
                            price += price_surcharge

                        if rule.price_min_margin:
                            price_min_margin = convert_to_price_uom(rule.price_min_margin)
                            price = max(price, price_limit + price_min_margin)

                        if rule.price_max_margin:
                            price_max_margin = convert_to_price_uom(rule.price_max_margin)
                            price = min(price, price_limit + price_max_margin)
                    suitable_rule = rule
                break
            # Final price conversion into pricelist currency
            if suitable_rule and suitable_rule.compute_price != 'fixed' and suitable_rule.base != 'pricelist':
                user_company = self.pool['res.users'].browse(cr, uid, uid, context=context).company_id
                price = self.pool['res.currency'].compute(cr, uid, user_company.currency_id.id, pricelist.currency_id.id, price, context=context)

            results[product.id] = (price, suitable_rule and suitable_rule.id or False)
        return results
Example #15
0
 def round(self, amount):
     """ Return `amount` rounded according to currency `self`. """
     return float_round(amount, precision_rounding=self.rounding)
Example #16
0
    def render(self, cr, uid, id, reference, amount, currency_id, partner_id=False, values=None, context=None):
        """ Renders the form template of the given acquirer as a qWeb template.
        :param string reference: the transaction reference
        :param float amount: the amount the buyer has to pay
        :param currency_id: currency id
        :param dict partner_id: optional partner_id to fill values
        :param dict values: a dictionary of values for the transction that is
        given to the acquirer-specific method generating the form values
        :param dict context: eCore context

        All templates will receive:

         - acquirer: the payment.acquirer browse record
         - user: the current user browse record
         - currency_id: id of the transaction currency
         - amount: amount of the transaction
         - reference: reference of the transaction
         - partner_*: partner-related values
         - partner: optional partner browse record
         - 'feedback_url': feedback URL, controler that manage answer of the acquirer (without base url) -> FIXME
         - 'return_url': URL for coming back after payment validation (wihout base url) -> FIXME
         - 'cancel_url': URL if the client cancels the payment -> FIXME
         - 'error_url': URL if there is an issue with the payment -> FIXME
         - context: eCore context dictionary

        """
        if context is None:
            context = {}
        if values is None:
            values = {}
        acquirer = self.browse(cr, uid, id, context=context)

        # reference and amount
        values.setdefault('reference', reference)
        amount = float_round(amount, 2)
        values.setdefault('amount', amount)

        # currency id
        currency_id = values.setdefault('currency_id', currency_id)
        if currency_id:
            currency = self.pool['res.currency'].browse(cr, uid, currency_id, context=context)
        else:
            currency = self.pool['res.users'].browse(cr, uid, uid, context=context).company_id.currency_id
        values['currency'] = currency

        # Fill partner_* using values['partner_id'] or partner_id arguement
        partner_id = values.get('partner_id', partner_id)
        if partner_id:
            partner = self.pool['res.partner'].browse(cr, uid, partner_id, context=context)
            values.update({
                'partner': partner,
                'partner_id': partner_id,
                'partner_name': partner.name,
                'partner_lang': partner.lang,
                'partner_email': partner.email,
                'partner_zip': partner.zip,
                'partner_city': partner.city,
                'partner_address': _partner_format_address(partner.street, partner.street2),
                'partner_country_id': partner.country_id.id,
                'partner_country': partner.country_id,
                'partner_phone': partner.phone,
                'partner_state': partner.state_id,
            })
        if values.get('partner_name'):
            values.update({
                'partner_first_name': _partner_split_name(values.get('partner_name'))[0],
                'partner_last_name': _partner_split_name(values.get('partner_name'))[1],
            })

        # Fix address, country fields
        if not values.get('partner_address'):
            values['address'] = _partner_format_address(values.get('partner_street', ''), values.get('partner_street2', ''))
        if not values.get('partner_country') and values.get('partner_country_id'):
            values['country'] = self.pool['res.country'].browse(cr, uid, values.get('partner_country_id'), context=context)


        # compute fees
        fees_method_name = '%s_compute_fees' % acquirer.provider
        if hasattr(self, fees_method_name):
            fees = getattr(self, fees_method_name)(cr, uid, id, values['amount'], values['currency_id'], values['partner_country_id'], context=None)
            values['fees'] = float_round(fees, 2)

        # call <name>_form_generate_values to update the tx dict with acqurier specific values
        cust_method_name = '%s_form_generate_values' % (acquirer.provider)
        if hasattr(self, cust_method_name):
            method = getattr(self, cust_method_name)
            values = method(cr, uid, id, values, context=context)

        values.update({
            'tx_url': context.get('tx_url', self.get_form_action_url(cr, uid, id, context=context)),
            'submit_class': context.get('submit_class', 'btn btn-link'),
            'submit_txt': context.get('submit_txt'),
            'acquirer': acquirer,
            'user': self.pool.get("res.users").browse(cr, uid, uid, context=context),
            'context': context,
            'type': values.get('type') or 'form',
        })
        values.setdefault('return_url', False)

        # because render accepts view ids but not qweb -> need to use the xml_id
        return self.pool['ir.ui.view'].render(cr, uid, acquirer.view_template_id.xml_id, values, engine='ir.qweb', context=context)
Example #17
0
    def _procure_orderpoint_confirm(self,
                                    cr,
                                    uid,
                                    use_new_cursor=False,
                                    company_id=False,
                                    context=None):
        '''
        Create procurement based on Orderpoint

        :param bool use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement.
            This is appropriate for batch jobs only.
        '''
        if context is None:
            context = {}
        if use_new_cursor:
            cr = ecore.registry(cr.dbname).cursor()
        orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
        procurement_obj = self.pool.get('procurement.order')
        product_obj = self.pool.get('product.product')

        dom = company_id and [('company_id', '=', company_id)] or []
        orderpoint_ids = orderpoint_obj.search(cr,
                                               uid,
                                               dom,
                                               order="location_id")
        prev_ids = []
        tot_procs = []
        while orderpoint_ids:
            ids = orderpoint_ids[:1000]
            del orderpoint_ids[:1000]
            product_dict = {}
            ops_dict = {}
            ops = orderpoint_obj.browse(cr, uid, ids, context=context)

            #Calculate groups that can be executed together
            for op in ops:
                key = (op.location_id.id, )
                if not product_dict.get(key):
                    product_dict[key] = [op.product_id]
                    ops_dict[key] = [op]
                else:
                    product_dict[key] += [op.product_id]
                    ops_dict[key] += [op]

            for key in product_dict.keys():
                ctx = context.copy()
                ctx.update({'location': ops_dict[key][0].location_id.id})
                prod_qty = product_obj._product_available(
                    cr, uid, [x.id for x in product_dict[key]], context=ctx)
                subtract_qty = orderpoint_obj.subtract_procurements_from_orderpoints(
                    cr, uid, [x.id for x in ops_dict[key]], context=context)
                for op in ops_dict[key]:
                    try:
                        prods = prod_qty[op.product_id.id]['virtual_available']
                        if prods is None:
                            continue
                        if float_compare(prods,
                                         op.product_min_qty,
                                         precision_rounding=op.product_uom.
                                         rounding) <= 0:
                            qty = max(op.product_min_qty,
                                      op.product_max_qty) - prods
                            reste = op.qty_multiple > 0 and qty % op.qty_multiple or 0.0
                            if float_compare(reste,
                                             0.0,
                                             precision_rounding=op.product_uom.
                                             rounding) > 0:
                                qty += op.qty_multiple - reste

                            if float_compare(qty,
                                             0.0,
                                             precision_rounding=op.product_uom.
                                             rounding) < 0:
                                continue

                            qty -= subtract_qty[op.id]

                            qty_rounded = float_round(
                                qty,
                                precision_rounding=op.product_uom.rounding)
                            if qty_rounded > 0:
                                proc_id = procurement_obj.create(
                                    cr,
                                    uid,
                                    self._prepare_orderpoint_procurement(
                                        cr,
                                        uid,
                                        op,
                                        qty_rounded,
                                        context=context),
                                    context=context)
                                tot_procs.append(proc_id)
                            if use_new_cursor:
                                cr.commit()
                    except OperationalError:
                        if use_new_cursor:
                            orderpoint_ids.append(op.id)
                            cr.rollback()
                            continue
                        else:
                            raise
            try:
                tot_procs.reverse()
                self.run(cr, uid, tot_procs, context=context)
                tot_procs = []
                if use_new_cursor:
                    cr.commit()
            except OperationalError:
                if use_new_cursor:
                    cr.rollback()
                    continue
                else:
                    raise

            if use_new_cursor:
                cr.commit()
            if prev_ids == ids:
                break
            else:
                prev_ids = ids

        if use_new_cursor:
            cr.commit()
            cr.close()
        return {}
Example #18
0
    def _procure_orderpoint_confirm(self, cr, uid, use_new_cursor=False, company_id=False, context=None):
        '''
        Create procurement based on Orderpoint

        :param bool use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement.
            This is appropriate for batch jobs only.
        '''
        if context is None:
            context = {}
        if use_new_cursor:
            cr = ecore.registry(cr.dbname).cursor()
        orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
        procurement_obj = self.pool.get('procurement.order')
        product_obj = self.pool.get('product.product')

        dom = company_id and [('company_id', '=', company_id)] or []
        orderpoint_ids = orderpoint_obj.search(cr, uid, dom, order="location_id")
        prev_ids = []
        tot_procs = []
        while orderpoint_ids:
            ids = orderpoint_ids[:1000]
            del orderpoint_ids[:1000]
            product_dict = {}
            ops_dict = {}
            ops = orderpoint_obj.browse(cr, uid, ids, context=context)

            #Calculate groups that can be executed together
            for op in ops:
                key = (op.location_id.id,)
                if not product_dict.get(key):
                    product_dict[key] = [op.product_id]
                    ops_dict[key] = [op]
                else:
                    product_dict[key] += [op.product_id]
                    ops_dict[key] += [op]

            for key in product_dict.keys():
                ctx = context.copy()
                ctx.update({'location': ops_dict[key][0].location_id.id})
                prod_qty = product_obj._product_available(cr, uid, [x.id for x in product_dict[key]],
                                                          context=ctx)
                subtract_qty = orderpoint_obj.subtract_procurements_from_orderpoints(cr, uid, [x.id for x in ops_dict[key]], context=context)
                for op in ops_dict[key]:
                    try:
                        prods = prod_qty[op.product_id.id]['virtual_available']
                        if prods is None:
                            continue
                        if float_compare(prods, op.product_min_qty, precision_rounding=op.product_uom.rounding) <= 0:
                            qty = max(op.product_min_qty, op.product_max_qty) - prods
                            reste = op.qty_multiple > 0 and qty % op.qty_multiple or 0.0
                            if float_compare(reste, 0.0, precision_rounding=op.product_uom.rounding) > 0:
                                qty += op.qty_multiple - reste

                            if float_compare(qty, 0.0, precision_rounding=op.product_uom.rounding) < 0:
                                continue

                            qty -= subtract_qty[op.id]

                            qty_rounded = float_round(qty, precision_rounding=op.product_uom.rounding)
                            if qty_rounded > 0:
                                proc_id = procurement_obj.create(cr, uid,
                                                                 self._prepare_orderpoint_procurement(cr, uid, op, qty_rounded, context=context),
                                                                 context=context)
                                tot_procs.append(proc_id)
                            if use_new_cursor:
                                cr.commit()
                    except OperationalError:
                        if use_new_cursor:
                            orderpoint_ids.append(op.id)
                            cr.rollback()
                            continue
                        else:
                            raise
            try:
                tot_procs.reverse()
                self.run(cr, uid, tot_procs, context=context)
                tot_procs = []
                if use_new_cursor:
                    cr.commit()
            except OperationalError:
                if use_new_cursor:
                    cr.rollback()
                    continue
                else:
                    raise

            if use_new_cursor:
                cr.commit()
            if prev_ids == ids:
                break
            else:
                prev_ids = ids

        if use_new_cursor:
            cr.commit()
            cr.close()
        return {}
Example #19
0
    def compute_landed_cost(self, cr, uid, ids, context=None):
        line_obj = self.pool.get('stock.valuation.adjustment.lines')
        unlink_ids = line_obj.search(cr, uid, [('cost_id', 'in', ids)], context=context)
        line_obj.unlink(cr, uid, unlink_ids, context=context)
        digits = dp.get_precision('Product Price')(cr)
        towrite_dict = {}
        for cost in self.browse(cr, uid, ids, context=None):
            if not cost.picking_ids:
                continue
            picking_ids = [p.id for p in cost.picking_ids]
            total_qty = 0.0
            total_cost = 0.0
            total_weight = 0.0
            total_volume = 0.0
            total_line = 0.0
            vals = self.get_valuation_lines(cr, uid, [cost.id], picking_ids=picking_ids, context=context)
            for v in vals:
                for line in cost.cost_lines:
                    v.update({'cost_id': cost.id, 'cost_line_id': line.id})
                    self.pool.get('stock.valuation.adjustment.lines').create(cr, uid, v, context=context)
                total_qty += v.get('quantity', 0.0)
                total_cost += v.get('former_cost', 0.0)
                total_weight += v.get('weight', 0.0)
                total_volume += v.get('volume', 0.0)
                total_line += 1

            for line in cost.cost_lines:
                value_split = 0.0
                for valuation in cost.valuation_adjustment_lines:
                    value = 0.0
                    if valuation.cost_line_id and valuation.cost_line_id.id == line.id:
                        if line.split_method == 'by_quantity' and total_qty:
                            per_unit = (line.price_unit / total_qty)
                            value = valuation.quantity * per_unit
                        elif line.split_method == 'by_weight' and total_weight:
                            per_unit = (line.price_unit / total_weight)
                            value = valuation.weight * per_unit
                        elif line.split_method == 'by_volume' and total_volume:
                            per_unit = (line.price_unit / total_volume)
                            value = valuation.volume * per_unit
                        elif line.split_method == 'equal':
                            value = (line.price_unit / total_line)
                        elif line.split_method == 'by_current_cost_price' and total_cost:
                            per_unit = (line.price_unit / total_cost)
                            value = valuation.former_cost * per_unit
                        else:
                            value = (line.price_unit / total_line)

                        if digits:
                            value = float_round(value, precision_digits=digits[1], rounding_method='UP')
                            fnc = min if line.price_unit > 0 else max
                            value = fnc(value, line.price_unit - value_split)
                            value_split += value

                        if valuation.id not in towrite_dict:
                            towrite_dict[valuation.id] = value
                        else:
                            towrite_dict[valuation.id] += value
        if towrite_dict:
            for key, value in towrite_dict.items():
                line_obj.write(cr, uid, key, {'additional_landed_cost': value}, context=context)
        return True
Example #20
0
    def _procure_orderpoint_confirm(self,
                                    cr,
                                    uid,
                                    use_new_cursor=False,
                                    company_id=False,
                                    context=None):
        '''
        Create procurement based on Orderpoint

        :param bool use_new_cursor: if set, use a dedicated cursor and auto-commit after processing each procurement.
            This is appropriate for batch jobs only.
        '''
        if context is None:
            context = {}
        if use_new_cursor:
            cr = ecore.registry(cr.dbname).cursor()
        orderpoint_obj = self.pool.get('stock.warehouse.orderpoint')
        procurement_obj = self.pool.get('procurement.order')
        product_obj = self.pool.get('product.product')
        dom = company_id and [('company_id', '=', company_id)] or []
        orderpoint_ids = orderpoint_obj.search(
            cr,
            uid,
            dom,
            order="location_id, purchase_calendar_id, calendar_id")
        prev_ids = []
        tot_procs = []
        while orderpoint_ids:
            ids = orderpoint_ids[:1000]
            del orderpoint_ids[:1000]
            dates_dict = {}
            product_dict = {}
            ops_dict = {}
            ops = orderpoint_obj.browse(cr, uid, ids, context=context)

            #Calculate groups that can be executed together
            for op in ops:
                key = (op.location_id.id, op.purchase_calendar_id.id,
                       op.calendar_id.id)
                res_groups = []
                if not dates_dict.get(key):
                    date_groups = self._get_group(cr, uid, op, context=context)
                    for date, group in date_groups:
                        if op.calendar_id and op.calendar_id.attendance_ids:
                            date1, date2 = self._get_next_dates(
                                cr, uid, op, date, group, context=context)
                            res_groups += [
                                (group, date1, date2, date)
                            ]  #date1/date2 as deliveries and date as purchase confirmation date
                        else:
                            res_groups += [(group, date, False, date)]
                    dates_dict[key] = res_groups
                    product_dict[key] = [op.product_id]
                    ops_dict[key] = [op]
                else:
                    product_dict[key] += [op.product_id]
                    ops_dict[key] += [op]

            for key in product_dict.keys():
                for res_group in dates_dict[key]:
                    ctx = context.copy()
                    ctx.update({'location': ops_dict[key][0].location_id.id})
                    if res_group[2]:
                        ctx.update({
                            'to_date':
                            res_group[2].strftime(
                                DEFAULT_SERVER_DATETIME_FORMAT)
                        })
                    prod_qty = product_obj._product_available(
                        cr,
                        uid, [x.id for x in product_dict[key]],
                        context=ctx)
                    group = res_group[0]
                    date = res_group[1]
                    subtract_qty = orderpoint_obj.subtract_procurements_from_orderpoints(
                        cr,
                        uid, [x.id for x in ops_dict[key]],
                        context=context)
                    first_op = True
                    ndelivery = date and self._convert_to_UTC(
                        cr, uid, date, context=context) or False
                    npurchase = res_group[3] and self._convert_to_UTC(
                        cr, uid, res_group[3], context=context) or False
                    for op in ops_dict[key]:
                        try:
                            prods = prod_qty[
                                op.product_id.id]['virtual_available']
                            if prods is None:
                                continue

                            if float_compare(prods,
                                             op.product_min_qty,
                                             precision_rounding=op.product_uom.
                                             rounding) < 0:
                                qty = max(op.product_min_qty,
                                          op.product_max_qty) - prods
                                reste = op.qty_multiple > 0 and qty % op.qty_multiple or 0.0
                                if float_compare(reste,
                                                 0.0,
                                                 precision_rounding=op.
                                                 product_uom.rounding) > 0:
                                    qty += op.qty_multiple - reste

                                if float_compare(qty,
                                                 0.0,
                                                 precision_rounding=op.
                                                 product_uom.rounding) <= 0:
                                    continue

                                qty -= subtract_qty[op.id]

                                qty_rounded = float_round(
                                    qty,
                                    precision_rounding=op.product_uom.rounding)
                                if qty_rounded > 0:
                                    proc_id = procurement_obj.create(
                                        cr,
                                        uid,
                                        self._prepare_orderpoint_procurement(
                                            cr,
                                            uid,
                                            op,
                                            qty_rounded,
                                            date=ndelivery,
                                            purchase_date=npurchase,
                                            group=group,
                                            context=context),
                                        context=context)
                                    tot_procs.append(proc_id)
                                    orderpoint_obj.write(
                                        cr,
                                        uid, [op.id], {
                                            'last_execution_date':
                                            datetime.utcnow().strftime(
                                                DEFAULT_SERVER_DATETIME_FORMAT)
                                        },
                                        context=context)
                                if use_new_cursor:
                                    cr.commit()
                        except OperationalError:
                            if use_new_cursor:
                                orderpoint_ids.append(op.id)
                                cr.rollback()
                                continue
                            else:
                                raise
            try:
                tot_procs.reverse()
                self.run(cr, uid, tot_procs, context=context)
                tot_procs = []
                if use_new_cursor:
                    cr.commit()
            except OperationalError:
                if use_new_cursor:
                    cr.rollback()
                    continue
                else:
                    raise

            if use_new_cursor:
                cr.commit()
            if prev_ids == ids:
                break
            else:
                prev_ids = ids

        if use_new_cursor:
            cr.commit()
            cr.close()
        return {}