diff --git a/addons/point_of_sale/models/pos_order.py b/addons/point_of_sale/models/pos_order.py index afe90c04ff8..2f63db01d9a 100644 --- a/addons/point_of_sale/models/pos_order.py +++ b/addons/point_of_sale/models/pos_order.py @@ -223,7 +223,7 @@ class PosOrder(models.Model): .mapped('picking_ids.move_ids')\ ._filter_anglo_saxon_moves(product)\ .sorted(lambda x: x.date) - price_unit = product._compute_average_price(0, quantity, moves) + price_unit = product.with_company(self.company_id)._compute_average_price(0, quantity, moves) return price_unit name = fields.Char(string='Order Ref', required=True, readonly=True, copy=False, default='/') diff --git a/addons/sale_mrp/models/account_move.py b/addons/sale_mrp/models/account_move.py index 9ecbb7c15b2..d08f2e92e61 100644 --- a/addons/sale_mrp/models/account_move.py +++ b/addons/sale_mrp/models/account_move.py @@ -26,8 +26,7 @@ class AccountMoveLine(models.Model): prod_moves = moves.filtered(lambda m: m.product_id == product) prod_qty_invoiced = factor * qty_invoiced prod_qty_to_invoice = factor * qty_to_invoice - average_price_unit += factor * product._compute_average_price(prod_qty_invoiced, prod_qty_to_invoice, prod_moves) + average_price_unit += factor * product.with_company(self.company_id)._compute_average_price(prod_qty_invoiced, prod_qty_to_invoice, prod_moves) price_unit = average_price_unit / bom.product_qty or price_unit price_unit = self.product_id.uom_id._compute_price(price_unit, self.product_uom_id) return price_unit - diff --git a/addons/sale_stock/models/account_move.py b/addons/sale_stock/models/account_move.py index db6fb3fd25d..a5ae7592f2c 100644 --- a/addons/sale_stock/models/account_move.py +++ b/addons/sale_stock/models/account_move.py @@ -110,7 +110,6 @@ class AccountMoveLine(models.Model): self.ensure_one() return not self.is_anglo_saxon_line and super(AccountMoveLine, self)._sale_can_be_reinvoice() - def _stock_account_get_anglo_saxon_price_unit(self): self.ensure_one() price_unit = super(AccountMoveLine, self)._stock_account_get_anglo_saxon_price_unit() @@ -119,9 +118,8 @@ class AccountMoveLine(models.Model): if so_line: qty_to_invoice = self.product_uom_id._compute_quantity(self.quantity, self.product_id.uom_id) qty_invoiced = sum([x.product_uom_id._compute_quantity(x.quantity, x.product_id.uom_id) for x in so_line.invoice_lines if x.move_id.state == 'posted']) - average_price_unit = self.product_id._compute_average_price(qty_invoiced, qty_to_invoice, so_line.move_ids) + average_price_unit = self.product_id.with_company(self.company_id)._compute_average_price(qty_invoiced, qty_to_invoice, so_line.move_ids) if average_price_unit: - price_unit = self.product_id.uom_id._compute_price(average_price_unit, self.product_uom_id) + price_unit = self.product_id.uom_id.with_company(self.company_id)._compute_price(average_price_unit, self.product_uom_id) return price_unit - diff --git a/addons/sale_stock/tests/__init__.py b/addons/sale_stock/tests/__init__.py index 5c84998bb9b..bf8a0765fe9 100644 --- a/addons/sale_stock/tests/__init__.py +++ b/addons/sale_stock/tests/__init__.py @@ -3,6 +3,7 @@ from . import test_anglo_saxon_valuation from . import test_anglo_saxon_valuation_reconciliation +from . import test_anglosaxon_account from . import test_sale_stock from . import test_sale_stock_lead_time from . import test_sale_stock_report diff --git a/addons/sale_stock/tests/test_anglosaxon_account.py b/addons/sale_stock/tests/test_anglosaxon_account.py new file mode 100644 index 00000000000..83d4f0080f3 --- /dev/null +++ b/addons/sale_stock/tests/test_anglosaxon_account.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from odoo.addons.sale_stock.tests.test_anglo_saxon_valuation_reconciliation import TestValuationReconciliation +from odoo.tests import tagged + +@tagged('post_install', '-at_install') +class TestAngloSaxonAccounting(TestValuationReconciliation): + + def test_cogs_should_use_price_from_the_right_company(self): + """ + Reproduce the flow of creating an invoice from a sale order with company A + and posting the invoice with both companies selected and company B as the main. + """ + company_a_data = self.company_data + company_b_data = self.company_data_2 + companies_with_b_first = company_b_data['company'] + company_a_data['company'] + product = self.test_product_delivery + + # set different cost price for the same product in the 2 companies + company_a_standard_price = 20.0 + product.with_company(company_a_data['company']).standard_price = company_a_standard_price + company_b_standard_price = 10.0 + product.with_company(company_b_data['company']).standard_price = company_b_standard_price + + # create sale order with company A in draft (by default, self.env.user.company_id is company A) + company_a_order = self._create_sale(product, '2021-01-01') + company_a_invoice = self._create_invoice_for_so(company_a_order, product, '2021-01-10') + + # Post the invoice from company A with company B + company_a_invoice.with_context(allowed_company_ids=companies_with_b_first.ids).action_post() + + # check cost used for anglo_saxon_line is from company A + anglo_saxon_lines = company_a_invoice.line_ids.filtered('is_anglo_saxon_line') + self.assertRecordValues(anglo_saxon_lines, [ + {'debit': 0.0, 'credit': company_a_standard_price}, + {'debit': company_a_standard_price, 'credit': 0.0}, + ]) diff --git a/addons/stock_account/models/account_move.py b/addons/stock_account/models/account_move.py index d4a198f547e..5a35728e127 100644 --- a/addons/stock_account/models/account_move.py +++ b/addons/stock_account/models/account_move.py @@ -106,6 +106,9 @@ class AccountMove(models.Model): ''' lines_vals_list = [] for move in self: + # Make the loop multi-company safe when accessing models like product.product + move = move.with_company(move.company_id) + if not move.is_sale_document(include_receipts=True) or not move.company_id.anglo_saxon_accounting: continue @@ -116,11 +119,7 @@ class AccountMove(models.Model): continue # Retrieve accounts needed to generate the COGS. - accounts = ( - line.product_id.product_tmpl_id - .with_company(line.company_id) - .get_product_accounts(fiscal_pos=move.fiscal_position_id) - ) + accounts = line.product_id.product_tmpl_id.get_product_accounts(fiscal_pos=move.fiscal_position_id) debit_interim_account = accounts['stock_output'] credit_expense_account = accounts['expense'] or self.journal_id.default_account_id if not debit_interim_account or not credit_expense_account: @@ -241,4 +240,4 @@ class AccountMoveLine(models.Model): self.ensure_one() if not self.product_id: return self.price_unit - return self.product_id._stock_account_get_anglo_saxon_price_unit(uom=self.product_uom_id) + return self.product_id.with_company(self.company_id)._stock_account_get_anglo_saxon_price_unit(uom=self.product_uom_id)