From f02397dc5eea7e824f5c0af4fbee5790e8a6653a Mon Sep 17 00:00:00 2001 From: Djamel Touati Date: Mon, 29 Jan 2024 15:24:21 +0000 Subject: [PATCH] [FIX] purchase_stock: move test to avoid error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: Run the following command: `-i purchase_stock,l10n_fr -d cro_test --test-enable --test-tags purchase_stock --stop-after-init` Problem: An error is triggered: “odoo.exceptions.UserError: Cannot find a stock input account for the product Analytic Product. You must define one on the product category, or on the location, before processing this operation.” When installing the "l10n_fr" module, the French accounting for the default company will be set. so the "property_stock_account_input_categ_id" will not be set when creating a product category with "property_valuation" set as real_time because the user's company has no chart of accounts: https://github.com/odoo/odoo/blob/c3b4c7d8f2c260c31f9549d480ed2db4159a8119/addons/stock_account/models/product.py#L833-L835 Therefore, when validating the picking related to the purchase order created: https://github.com/odoo/odoo/blob/31d1a2a8a0f1490dd49d86628c0f856ca82198c8/addons/purchase_stock/tests/test_purchase_order_process.py#L124 The product accounts are then retrieved, but will be False: https://github.com/odoo/odoo/blob/9215e73fa229d64167de076ef0a288dd8d89a2cc/addons/stock_account/models/stock_move.py#L336 https://github.com/odoo/odoo/blob/493502bc4ad3ac35b1c0cb2eeb73ac6b6d0fe5b5/addons/stock_account/models/product.py#L29 Solution: skip the test if the user's company has no chart of accounts. opw-3698341 closes odoo/odoo#152128 X-original-commit: 80fd9f9875d5966f5f7f1f44849f27e4b2f112e6 Signed-off-by: John Laterre (jol) Signed-off-by: Djamel Touati (otd) --- .../tests/test_purchase_order_process.py | 88 ------------------- .../tests/test_stockvaluation.py | 88 +++++++++++++++++++ 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/addons/purchase_stock/tests/test_purchase_order_process.py b/addons/purchase_stock/tests/test_purchase_order_process.py index 2968ba7c08d..a8a836349c3 100644 --- a/addons/purchase_stock/tests/test_purchase_order_process.py +++ b/addons/purchase_stock/tests/test_purchase_order_process.py @@ -57,91 +57,3 @@ class TestPurchaseOrderProcess(PurchaseTestCommon): }) po.button_confirm() self.assertEqual(po.order_line.move_ids.product_packaging_id, packaging) - - def test_analytic_distribution_propagation_with_exchange_difference(self): - # Create 2 rates in order to generate an exchange difference later. - eur = self.env.ref('base.EUR') - eur.write({ - 'rate_ids': [ - Command.clear(), - Command.create({ - 'name': fields.Date.from_string('2023-01-01'), - 'company_rate': 2.0, - }), - Command.create({ - 'name': fields.Date.from_string('2023-12-01'), - 'company_rate': 3.0, - }), - ], - 'active': True, - }) - - # Create a mandatory analytic account. - analytic_plan = self.env['account.analytic.plan'].create({ - 'name': 'Analytic Plan', - 'default_applicability': 'mandatory', - }) - analytic_account = self.env['account.analytic.account'].create({ - 'name': 'Analytic Account', - 'plan_id': analytic_plan.id}, - ) - - # Create a storable product with FIFO costing method and automated inventory valuation. - analytic_product_category = self.env['product.category'].create({ - 'name': 'Analytic Product Category', - 'property_cost_method': 'fifo', - 'property_valuation': 'real_time', - }) - analytic_product = self.env['product.product'].create({ - 'name': 'Analytic Product', - 'detailed_type': 'product', - 'categ_id': analytic_product_category.id, - 'lst_price': 100.0, - 'standard_price': 25.0, - }) - - # Create and confirm a Purchase Order using aforementioned product and currency. - purchase_order = self.env['purchase.order'].create({ - 'date_order': fields.Date.from_string('2023-12-04'), - 'currency_id': eur.id, - 'partner_id': self.partner.id, - 'order_line': [ - Command.create({ - 'product_id': analytic_product.id, - 'product_qty': 10.0, - 'analytic_distribution': {analytic_account.id: 100}, - }), - ], - }) - purchase_order.button_confirm() - - # Make sure a stock move has been created to replenish the product. - self.assertEqual(len(purchase_order.picking_ids.move_ids), 1) - - stock_move = purchase_order.picking_ids.move_ids - stock_move.quantity = stock_move.product_uom_qty - - purchase_order.picking_ids.button_validate() - purchase_order.action_create_invoice() - - # Make sure a first Journal Entry has been created (to account for the stock move). - self.assertEqual(len(stock_move.account_move_ids), 1) - stock_account_move = stock_move.account_move_ids - - # Make sure the Vendor Bill has been created, - # and confirm it at an earlier date (to generate the exchange difference). - self.assertEqual(len(purchase_order.invoice_ids), 1) - - vendor_bill = purchase_order.invoice_ids - vendor_bill.invoice_date = fields.Date.from_string('2023-11-01') - vendor_bill.action_post() - - # Make sure a second Journal Entry has been created (to account for the exchange difference). - self.assertEqual(len(stock_move.account_move_ids), 2) - exchange_account_move = stock_move.account_move_ids - stock_account_move - - # Make sure both exchange Journal Items have the correct analytic distribution. - self.assertEqual(len(exchange_account_move.line_ids), 2) - for line in exchange_account_move.line_ids: - self.assertTrue(line.analytic_distribution) - self.assertEqual(line.analytic_distribution[str(analytic_account.id)], 100) diff --git a/addons/purchase_stock/tests/test_stockvaluation.py b/addons/purchase_stock/tests/test_stockvaluation.py index 9d857c79f38..77e4cb93bac 100644 --- a/addons/purchase_stock/tests/test_stockvaluation.py +++ b/addons/purchase_stock/tests/test_stockvaluation.py @@ -2986,3 +2986,91 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon): [self.eur_currency._convert(line.amount_currency, company.currency_id, company, bill_date) for line in bill.line_ids], [line.balance for line in bill.line_ids] ) + + def test_analytic_distribution_propagation_with_exchange_difference(self): + # Create 2 rates in order to generate an exchange difference later. + eur = self.env.ref('base.EUR') + eur.write({ + 'rate_ids': [ + Command.clear(), + Command.create({ + 'name': fields.Date.from_string('2023-01-01'), + 'company_rate': 2.0, + }), + Command.create({ + 'name': fields.Date.from_string('2023-12-01'), + 'company_rate': 3.0, + }), + ], + 'active': True, + }) + + # Create a mandatory analytic account. + analytic_plan = self.env['account.analytic.plan'].create({ + 'name': 'Analytic Plan', + 'default_applicability': 'mandatory', + }) + analytic_account = self.env['account.analytic.account'].create({ + 'name': 'Analytic Account', + 'plan_id': analytic_plan.id}, + ) + + # Create a storable product with FIFO costing method and automated inventory valuation. + analytic_product_category = self.env['product.category'].create({ + 'name': 'Analytic Product Category', + 'property_cost_method': 'fifo', + 'property_valuation': 'real_time', + }) + analytic_product = self.env['product.product'].create({ + 'name': 'Analytic Product', + 'detailed_type': 'product', + 'categ_id': analytic_product_category.id, + 'lst_price': 100.0, + 'standard_price': 25.0, + }) + + # Create and confirm a Purchase Order using aforementioned product and currency. + purchase_order = self.env['purchase.order'].create({ + 'date_order': fields.Date.from_string('2023-12-04'), + 'currency_id': eur.id, + 'partner_id': self.partner_a.id, + 'order_line': [ + Command.create({ + 'product_id': analytic_product.id, + 'product_qty': 10.0, + 'analytic_distribution': {analytic_account.id: 100}, + }), + ], + }) + purchase_order.button_confirm() + + # Make sure a stock move has been created to replenish the product. + self.assertEqual(len(purchase_order.picking_ids.move_ids), 1) + + stock_move = purchase_order.picking_ids.move_ids + stock_move.quantity = stock_move.product_uom_qty + + purchase_order.picking_ids.button_validate() + purchase_order.action_create_invoice() + + # Make sure a first Journal Entry has been created (to account for the stock move). + self.assertEqual(len(stock_move.account_move_ids), 1) + stock_account_move = stock_move.account_move_ids + + # Make sure the Vendor Bill has been created, + # and confirm it at an earlier date (to generate the exchange difference). + self.assertEqual(len(purchase_order.invoice_ids), 1) + + vendor_bill = purchase_order.invoice_ids + vendor_bill.invoice_date = fields.Date.from_string('2023-11-01') + vendor_bill.action_post() + + # Make sure a second Journal Entry has been created (to account for the exchange difference). + self.assertEqual(len(stock_move.account_move_ids), 2) + exchange_account_move = stock_move.account_move_ids - stock_account_move + + # Make sure both exchange Journal Items have the correct analytic distribution. + self.assertEqual(len(exchange_account_move.line_ids), 2) + for line in exchange_account_move.line_ids: + self.assertTrue(line.analytic_distribution) + self.assertEqual(line.analytic_distribution[str(analytic_account.id)], 100)