[FIX] account, purchase: price_unit as Float

The price unit on the account move line is defined as a monetary field.
However, on a Sales Order or on a Purchase Order, the price unit is
defined as a float with precision 'Product Price'. Therefore, when an
invoice is generated from a SO or a PO, inconsistencies arise if the
product price precision is larger than the currency precision.

opw-673251
This commit is contained in:
Nicolas Martinelli
2016-03-31 17:08:37 +02:00
parent b44cb82c1b
commit 2e4777bb32
5 changed files with 18 additions and 17 deletions
+4 -7
View File
@@ -635,7 +635,7 @@ class AccountTax(models.Model):
# the 'Account' decimal precision + 5), and that way it's like
# rounding after the sum of the tax amounts of each line
prec = currency.decimal_places
if company_id.tax_calculation_rounding_method == 'round_globally':
if company_id.tax_calculation_rounding_method == 'round_globally' or not bool(self.env.context.get("round", True)):
prec += 5
total_excluded = total_included = base = round(price_unit * quantity, prec)
@@ -650,7 +650,7 @@ class AccountTax(models.Model):
continue
tax_amount = tax._compute_amount(base, price_unit, quantity, product, partner)
if company_id.tax_calculation_rounding_method == 'round_globally':
if company_id.tax_calculation_rounding_method == 'round_globally' or not bool(self.env.context.get("round", True)):
tax_amount = round(tax_amount, prec)
else:
tax_amount = currency.round(tax_amount)
@@ -676,8 +676,8 @@ class AccountTax(models.Model):
return {
'taxes': sorted(taxes, key=lambda k: k['sequence']),
'total_excluded': currency.round(total_excluded),
'total_included': currency.round(total_included),
'total_excluded': currency.round(total_excluded) if bool(self.env.context.get("round", True)) else total_excluded,
'total_included': currency.round(total_included) if bool(self.env.context.get("round", True)) else total_included,
'base': base,
}
@@ -733,6 +733,3 @@ class AccountOperationTemplate(models.Model):
@api.onchange('name')
def onchange_name(self):
self.label = self.name
+3 -2
View File
@@ -1068,7 +1068,7 @@ class AccountInvoiceLine(models.Model):
required=True, domain=[('deprecated', '=', False)],
default=_default_account,
help="The income or expense account related to the selected product.")
price_unit = fields.Monetary(string='Unit Price', required=True)
price_unit = fields.Float(string='Unit Price', required=True, digits=dp.get_precision('Product Price'))
price_subtotal = fields.Monetary(string='Amount',
store=True, readonly=True, compute='_compute_price')
price_subtotal_signed = fields.Monetary(string='Amount Signed', currency_field='company_currency_id',
@@ -1126,7 +1126,8 @@ class AccountInvoiceLine(models.Model):
fix_price = self.env['account.tax']._fix_tax_included_price
if self.invoice_id.type in ('in_invoice', 'in_refund'):
if not self.price_unit or float_compare(self.price_unit, self.product_id.standard_price, precision_digits=self.currency_id.rounding) == 0:
prec = self.env['decimal.precision'].precision_get('Product Price')
if not self.price_unit or float_compare(self.price_unit, self.product_id.standard_price, precision_digits=prec) == 0:
self.price_unit = fix_price(self.product_id.standard_price, taxes, fp_taxes)
else:
self.price_unit = fix_price(self.product_id.lst_price, taxes, fp_taxes)
+1 -1
View File
@@ -322,7 +322,7 @@ class account_voucher_line(models.Model):
account_id = fields.Many2one('account.account', string='Account',
required=True, domain=[('deprecated', '=', False)],
help="The income or expense account related to the selected product.")
price_unit = fields.Monetary(string='Unit Price', required=True, oldname='amount')
price_unit = fields.Float(string='Unit Price', required=True, digits=dp.get_precision('Product Price'), oldname='amount')
price_subtotal = fields.Monetary(string='Amount',
store=True, readonly=True, compute='_compute_subtotal')
quantity = fields.Float(digits=dp.get_precision('Product Unit of Measure'),
+9 -6
View File
@@ -58,7 +58,7 @@ class AccountInvoice(models.Model):
'uom_id': line.product_uom.id,
'product_id': line.product_id.id,
'account_id': self.env['account.invoice.line'].with_context({'journal_id': self.journal_id.id, 'type': 'in_invoice'})._default_account(),
'price_unit': line.order_id.currency_id.compute(line.price_unit, self.currency_id),
'price_unit': line.order_id.currency_id.compute(line.price_unit, self.currency_id, round=False),
'quantity': qty,
'discount': 0.0,
'account_analytic_id': line.account_analytic_id.id,
@@ -79,7 +79,7 @@ class AccountInvoice(models.Model):
def _onchange_currency_id(self):
if self.currency_id:
for line in self.invoice_line_ids.filtered(lambda r: r.purchase_line_id):
line.price_unit = line.purchase_id.currency_id.compute(line.purchase_line_id.price_unit, self.currency_id)
line.price_unit = line.purchase_id.currency_id.compute(line.purchase_line_id.price_unit, self.currency_id, round=False)
@api.onchange('invoice_line_ids')
def _onchange_origin(self):
@@ -120,6 +120,7 @@ class AccountInvoice(models.Model):
reference_account_id = i_line.product_id.product_tmpl_id.get_product_accounts(fiscal_pos=fpos)['stock_input'].id
diff_res = []
account_prec = inv.company_id.currency_id.decimal_places
product_prec = self.env['decimal.precision'].precision_get('Product Price')
# calculate and write down the possible price difference between invoice price and product price
for line in res:
if line.get('invl_id', 0) == i_line.id and reference_account_id == line['account_id']:
@@ -131,19 +132,21 @@ class AccountInvoice(models.Model):
if valuation_stock_move:
valuation_price_unit = valuation_stock_move[0].price_unit
if inv.currency_id.id != company_currency.id:
valuation_price_unit = company_currency.with_context(date=inv.date_invoice).compute(valuation_price_unit, inv.currency_id)
if valuation_price_unit != i_line.price_unit and line['price_unit'] == i_line.price_unit and acc:
valuation_price_unit = company_currency.with_context(date=inv.date_invoice).compute(valuation_price_unit, inv.currency_id, round=False)
if float_compare(valuation_price_unit, i_line.price_unit, precision_digits=product_prec) != 0\
and float_compare(line['price_unit'], i_line.price_unit, precision_digits=product_prec) == 0\
and acc:
# price with discount and without tax included
price_unit = i_line.price_unit * (1 - (i_line.discount or 0.0) / 100.0)
if line['tax_ids']:
#line['tax_ids'] is like [(4, tax_id, None), (4, tax_id2, None)...]
taxes = self.env['account.tax'].browse([x[1] for x in line['tax_ids']])
price_unit = taxes.compute_all(price_unit, currency=inv.currency_id, quantity=1.0)['total_excluded']
price_unit = taxes.with_context(round=False).compute_all(price_unit, currency=inv.currency_id, quantity=1.0)['total_excluded']
line.update({'price': round(valuation_price_unit * line['quantity'], account_prec)})
diff_res.append({
'type': 'src',
'name': i_line.name[:64],
'price_unit': round(price_unit - valuation_price_unit, account_prec),
'price_unit': round(price_unit - valuation_price_unit, product_prec),
'quantity': line['quantity'],
'price': round((price_unit - valuation_price_unit) * line['quantity'], account_prec),
'account_id': acc,
+1 -1
View File
@@ -535,7 +535,7 @@ class PurchaseOrderLine(models.Model):
order = line.order_id
price_unit = line.price_unit
if line.taxes_id:
price_unit = line.taxes_id.compute_all(price_unit, currency=line.order_id.currency_id, quantity=1.0)['total_excluded']
price_unit = line.taxes_id.with_context(round=False).compute_all(price_unit, currency=line.order_id.currency_id, quantity=1.0)['total_excluded']
if line.product_uom.id != line.product_id.uom_id.id:
price_unit *= line.product_uom.factor / line.product_id.uom_id.factor
if order.currency_id != order.company_id.currency_id: