diff --git a/addons/mrp_account/models/mrp_production.py b/addons/mrp_account/models/mrp_production.py index d193a98eecd..74b10914178 100644 --- a/addons/mrp_account/models/mrp_production.py +++ b/addons/mrp_account/models/mrp_production.py @@ -70,6 +70,11 @@ class MrpProduction(models.Model): # able to produce orders AccountAnalyticLine.create(vals) + def _get_backorder_mo_vals(self): + res = super()._get_backorder_mo_vals() + res['extra_cost'] = self.extra_cost + return res + def button_mark_done(self): res = super(MrpProduction, self).button_mark_done() for order in self: diff --git a/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py b/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py index c144e3ed250..60e13d9e10f 100644 --- a/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py +++ b/addons/mrp_subcontracting_account/tests/test_subcontracting_account.py @@ -63,3 +63,72 @@ class TestAccountSubcontractingFlows(TestMrpSubcontractingCommon): self.assertEqual(mo.move_finished_ids.stock_valuation_layer_ids.value, 60) self.assertEqual(picking_receipt.move_lines.stock_valuation_layer_ids.value, 0) self.assertEqual(picking_receipt.move_lines.product_id.value_svl, 60) + + 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 + ensure the extra cost asked from the subcontractor is added correctly on all the finished + product valuation layer. Not only the first one. """ + todo_nb = 4 + self.comp2.tracking = 'lot' + self.comp1.tracking = 'serial' + self.comp2.standard_price = 100 + self.finished.tracking = 'serial' + self.env.ref('product.product_category_all').property_cost_method = 'fifo' + + # Create a receipt picking from the subcontractor + 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 = todo_nb + picking_receipt = picking_form.save() + # Mimic the extra cost on the po line + picking_receipt.move_lines.price_unit = 50 + picking_receipt.action_confirm() + + # We should be able to call the 'record_components' button + self.assertTrue(picking_receipt.display_action_record_components) + + lot_comp2 = self.env['stock.production.lot'].create({ + 'name': 'lot_comp2', + 'product_id': self.comp2.id, + 'company_id': self.env.company.id, + }) + serials_finished = [] + serials_comp1 = [] + for i in range(todo_nb): + serials_finished.append(self.env['stock.production.lot'].create({ + 'name': 'serial_fin_%s' % i, + 'product_id': self.finished.id, + 'company_id': self.env.company.id, + })) + serials_comp1.append(self.env['stock.production.lot'].create({ + 'name': 'serials_comp1_%s' % i, + 'product_id': self.comp1.id, + 'company_id': self.env.company.id, + })) + + for i in range(todo_nb): + action = picking_receipt.action_record_components() + mo = self.env['mrp.production'].browse(action['res_id']) + mo_form = Form(mo.with_context(**action['context']), view=action['view_id']) + mo_form.lot_producing_id = serials_finished[i] + with mo_form.move_line_raw_ids.edit(0) as ml: + self.assertEqual(ml.product_id, self.comp1) + ml.lot_id = serials_comp1[i] + with mo_form.move_line_raw_ids.edit(1) as ml: + self.assertEqual(ml.product_id, self.comp2) + ml.lot_id = lot_comp2 + mo = mo_form.save() + mo.subcontracting_record_component() + + # We should not be able to call the 'record_components' button + + picking_receipt.button_validate() + + f_layers = self.finished.stock_valuation_layer_ids + self.assertEqual(len(f_layers), 4) + for layer in f_layers: + self.assertEqual(layer.value, 100 + 50)