[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:
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user