From 2bda112eedecf0d5ac730f5214cd0444125913d5 Mon Sep 17 00:00:00 2001 From: Arnold Moyaux Date: Mon, 5 Dec 2022 10:00:54 +0000 Subject: [PATCH] [FIX] stock_account: no amount currency on correction layer for discount Usecase to reproduce: - Set stock valuation as perpetual - Create a PO with a different currency than the company - Validate the receipt on create the invoice - Set a discount on the invoice and validate it The amount currency is not set on the account.move.line created by the valuation layer. It could prevent the reconciliation to succeed since it would be base on invoice currency. It happens because the amount currency is created from the difference between layer price converted to invoice currency and the invoice line `price_unit`. However `price_unit` is missing the discount. So this pr add extra computation to get the gross price unit discount applied. closes odoo/odoo#107256 X-original-commit: 493020b9317a439c0a61a34f37cc92b6779ef633 Signed-off-by: William Henrotin (whe) Signed-off-by: Olivier Colson (oco) --- addons/stock_account/models/account_move.py | 27 ++++++++++++--------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/addons/stock_account/models/account_move.py b/addons/stock_account/models/account_move.py index 9b5b675a2a3..5ea9009a272 100644 --- a/addons/stock_account/models/account_move.py +++ b/addons/stock_account/models/account_move.py @@ -290,16 +290,7 @@ class AccountMoveLine(models.Model): if not layers: continue - price_unit = -line.price_unit if move.move_type == 'in_refund' else line.price_unit - price_unit = price_unit * (1 - (line.discount or 0.0) / 100.0) - if line.tax_ids: - prec = 1e+6 - price_unit *= prec - price_unit = line.tax_ids.with_context(round=False).compute_all( - price_unit, currency=move.currency_id, quantity=1.0, is_refund=move.move_type == 'in_refund', - fixed_multiplicator=move.direction_sign, - )['total_excluded'] - price_unit /= prec + price_unit = line._get_gross_unit_price() price_unit = line.currency_id._convert(price_unit, line.company_id.currency_id, line.company_id, line.date, round=False) price_unit = line.product_uom_id._compute_price(price_unit, line.product_id.uom_id) layers_price_unit = line._get_stock_valuation_layers_price_unit(layers) @@ -311,6 +302,20 @@ class AccountMoveLine(models.Model): self.ensure_one() return self.product_id.type == 'product' and self.product_id.valuation == 'real_time' + def _get_gross_unit_price(self): + price_unit = -self.price_unit if self.move_id.move_type == 'in_refund' else self.price_unit + price_unit = price_unit * (1 - (self.discount or 0.0) / 100.0) + if not self.tax_ids: + return price_unit + prec = 1e+6 + price_unit *= prec + price_unit = self.tax_ids.with_context(round=False).compute_all( + price_unit, currency=self.move_id.currency_id, quantity=1.0, is_refund=self.move_id.move_type == 'in_refund', + fixed_multiplicator=self.move_id.direction_sign, + )['total_excluded'] + price_unit /= prec + return price_unit + def _get_stock_valuation_layers(self, move): valued_moves = self._get_valued_in_moves() if move.move_type == 'in_refund': @@ -353,7 +358,7 @@ class AccountMoveLine(models.Model): if float_is_zero(unit_valuation_difference * qty_to_correct, precision_rounding=self.company_id.currency_id.rounding): continue po_pu_curr = po_line.currency_id._convert(po_line.price_unit, self.currency_id, self.company_id, self.date, round=False) - price_difference_curr = po_pu_curr - self.price_unit + price_difference_curr = po_pu_curr - self._get_gross_unit_price() layers_to_correct[layer] = (qty_to_correct, unit_valuation_difference, price_difference_curr) return layers_to_correct