From be911c2c587f7e191d141ae37602ddc590a8737a Mon Sep 17 00:00:00 2001 From: yhu-odoo Date: Thu, 6 Apr 2023 09:18:27 +0000 Subject: [PATCH] [FIX] mrp_subcontracting_account: wrong account subcontracting When we do subcontracting, components and final products are sent to/ received from production location. The account entries are also post using the accounting setting on production location like normal manufacturing which is not correct. To fix, we use account setting on product categories instead of production location for subcontracting. Task-3223451 X-original-commit: 017209068f308e87870e2b352afbdf6febc41da0 Part-of: odoo/odoo#132282 --- .../models/stock_move.py | 10 +++ .../tests/test_subcontracting_account.py | 85 +++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/addons/mrp_subcontracting_account/models/stock_move.py b/addons/mrp_subcontracting_account/models/stock_move.py index 2aaa49f795c..d964651b601 100644 --- a/addons/mrp_subcontracting_account/models/stock_move.py +++ b/addons/mrp_subcontracting_account/models/stock_move.py @@ -45,3 +45,13 @@ class StockMove(models.Model): 'account_id': credit_account_id, } return rslt + + def _get_dest_account(self, account_data): + if self.raw_material_production_id.subcontractor_id: + return account_data['production'].id + return super()._get_dest_account(account_data) + + def _get_src_account(self, account_data): + if self.production_id.subcontractor_id: + return account_data['production'].id + return super()._get_src_account(account_data) diff --git a/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py b/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py index b6c2d48a422..1e5a75864b1 100644 --- a/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py +++ b/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py @@ -128,6 +128,91 @@ class TestAccountSubcontractingFlows(TestMrpSubcontractingCommon): {'account_id': stock_cop_acc_id, 'product_id': self.comp1.id, 'debit': 10.0, 'credit': 0.0}, ]) + def test_subcontracting_account_flow_2(self): + """Test when set Cost of Production account on production location, subcontracting + won't use it. + """ + # pylint: disable=bad-whitespace + self.stock_location = self.env.ref('stock.stock_location_stock') + self.customer_location = self.env.ref('stock.stock_location_customers') + self.supplier_location = self.env.ref('stock.stock_location_suppliers') + self.uom_unit = self.env.ref('uom.product_uom_unit') + product_category_all = self.env.ref('product.product_category_all') + product_category_all.property_cost_method = 'fifo' + product_category_all.property_valuation = 'real_time' + stock_in_acc_id = product_category_all.property_stock_account_input_categ_id.id + stock_valu_acc_id = product_category_all.property_stock_valuation_account_id.id + stock_cop_acc_id = product_category_all.property_stock_account_production_cost_id.id + + # set Cost of Production account on production location + cop_account = self.env['account.account'].create({ + 'name': 'Cost of Production', + 'code': 'CoP', + "account_type": 'expense', + 'reconcile': False, + }) + self.comp1.property_stock_production.write({ + 'valuation_out_account_id': cop_account.id, + 'valuation_in_account_id': cop_account.id, + }) + + # IN 10@10 comp1 10@20 comp2 + move1 = self.env['stock.move'].create({ + 'name': 'IN 10 units @ 10.00 per unit', + 'location_id': self.supplier_location.id, + 'location_dest_id': self.env.company.subcontracting_location_id.id, + 'product_id': self.comp1.id, + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 10.0, + 'price_unit': 10.0, + }) + move1._action_confirm() + move1._action_assign() + move1.move_line_ids.qty_done = 10.0 + move1._action_done() + move2 = self.env['stock.move'].create({ + 'name': 'IN 10 units @ 20.00 per unit', + 'location_id': self.supplier_location.id, + 'location_dest_id': self.env.company.subcontracting_location_id.id, + 'product_id': self.comp2.id, + 'product_uom': self.uom_unit.id, + 'product_uom_qty': 10.0, + 'price_unit': 20.0, + }) + move2._action_confirm() + move2._action_assign() + move2.move_line_ids.qty_done = 10.0 + move2._action_done() + + all_amls_ids = self.env['account.move.line'].search([]).ids + + picking_form = Form(self.env['stock.picking']) + picking_form.picking_type_id = self.env.ref('stock.picking_type_in') + picking_form.partner_id = self.subcontractor_partner1 + with picking_form.move_ids_without_package.new() as move: + move.product_id = self.finished + move.product_uom_qty = 1 + picking_receipt = picking_form.save() + picking_receipt.move_ids.price_unit = 30.0 + picking_receipt.action_confirm() + picking_receipt.move_ids.quantity_done = 1.0 + picking_receipt._action_done() + + amls = self.env['account.move.line'].search([('id', 'not in', all_amls_ids)]) + all_amls_ids += amls.ids + self.assertRecordValues(amls, [ + # Receipt from subcontractor + {'account_id': stock_valu_acc_id, 'product_id': self.finished.id, 'debit': 60.0, 'credit': 0.0}, + {'account_id': stock_in_acc_id, 'product_id': self.finished.id, 'debit': 0.0, 'credit': 30.0}, + {'account_id': stock_cop_acc_id, 'product_id': self.finished.id, 'debit': 0.0, 'credit': 30.0}, + # Delivery com2 to subcontractor + {'account_id': stock_valu_acc_id, 'product_id': self.comp2.id, 'debit': 0.0, 'credit': 20.0}, + {'account_id': stock_cop_acc_id, 'product_id': self.comp2.id, 'debit': 20.0, 'credit': 0.0}, + # Delivery com2 to subcontractor + {'account_id': stock_valu_acc_id, 'product_id': self.comp1.id, 'debit': 0.0, 'credit': 10.0}, + {'account_id': stock_cop_acc_id, 'product_id': self.comp1.id, 'debit': 10.0, 'credit': 0.0}, + ]) + def test_subcontracting_account_backorder(self): """ This test uses tracked (serial and lot) component and tracked (serial) finished product The original subcontracting production order will be split into 4 backorders. This test