summaryrefslogtreecommitdiff
path: root/addons/mrp_subcontracting_dropshipping
diff options
context:
space:
mode:
authorArnold Moyaux <arm@odoo.com>2021-03-12 09:59:30 +0000
committerGoffin Simon <sig@odoo.com>2021-03-18 15:26:44 +0000
commit16c9f192f605aadfb4b3fdea5030ce3579ebb0df (patch)
treeeb5ccb73130215040b4d073307c6c7e068e1333d /addons/mrp_subcontracting_dropshipping
parent0ae22aa773f9343fc79937cceb5bf60c5fb3ba3c (diff)
[FIX] mrp_subcontracting, stock: Resupply Subcontractor on Order
Steps to reproduce the bug: - Let's consider a consumable product P with a subcontracted BOM B - Let's consider that B is subcontracted by a partner S and B has a storable component C - C has the route Resupply Subcontractor on Order and has a partner SUP as supplier - Create a purchase order PO with 1 P to S and confirm PO - A delivery order DO1 is created with C to S - Change the ordered quantity on PO and set 2 instead of 1 Bug: DO1 was canceled and a new delivery order DO2 was created with only 1 C instead of 2 It happens due to merge move, when updating the PO line a new rule is trigger and create the object in this order: - Move Sub-Stock(finished) -> Subcontract Order -> Move Stock-Sub(comp) Then the action_confirm is trigger and will run _merge_move on object from left to right order. But when the move Sub-Stock is merged, everything is write in the first move and the new move is unlink. It result by canceling all the following object (so the new subcontractor and the Move Stock-Sub). It was not an issue for the subcontracting since the write of stock.move is overridden in order to update the order quantity when the move quantity is updated. However in this case the rule are not triggered in order to create the moves that ressuply the subcontractor. In order to avoid this mess, this PR prevent the merge in case of a subcontracting move. opw-2419222 closes odoo/odoo#68098 X-original-commit: 48f2bbb844502c91dce59e8d869b56df0960fd0a Signed-off-by: Simon Goffin (sig) <sig@openerp.com> Co-authored-by: simongoffin <sig@odoo.com>
Diffstat (limited to 'addons/mrp_subcontracting_dropshipping')
-rw-r--r--addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py
index 41ed4a44fff..9d13f6c5c35 100644
--- a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py
+++ b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py
@@ -77,3 +77,60 @@ class TestSubcontractingDropshippingFlows(TestMrpSubcontractingCommon):
('partner_id', '=', partner.id),
]).order_id
self.assertTrue(po)
+
+ def test_mrp_subcontracting_purchase_2(self):
+ """Let's consider a subcontracted BOM with 1 component. Tick "Resupply Subcontractor on Order" on the component and set a supplier on it.
+ Purchase 1 BOM to the subcontractor. Confirm the purchase and change the purchased quantity to 2.
+ Check that 2 components are delivered to the subcontractor
+ """
+ # Tick "resupply subconractor on order on component"
+ self.bom.bom_line_ids = [(5, 0, 0)]
+ self.bom.bom_line_ids = [(0, 0, {'product_id': self.comp1.id, 'product_qty': 1})]
+ resupply_sub_on_order_route = self.env['stock.location.route'].search([('name', '=', 'Resupply Subcontractor on Order')])
+ (self.comp1).write({'route_ids': [(4, resupply_sub_on_order_route.id, None)]})
+ # Create a supplier and set it to component
+ vendor = self.env['res.partner'].create({'name': 'AAA', 'email': 'from.test@example.com'})
+ supplier_info1 = self.env['product.supplierinfo'].create({
+ 'name': vendor.id,
+ 'price': 50,
+ })
+ self.comp1.write({'seller_ids': [(0, 0, {'name': vendor.id, 'product_code': 'COMP1'})]})
+ # Purchase 1 BOM to the subcontractor
+ po = Form(self.env['purchase.order'])
+ po.partner_id = self.subcontractor_partner1
+ with po.order_line.new() as po_line:
+ po_line.product_id = self.finished
+ po_line.product_qty = 1
+ po_line.price_unit = 100
+ po = po.save()
+ # Confirm the purchase
+ po.button_confirm()
+ # Check one delivery order with the component has been created for the subcontractor
+ mo = self.env['mrp.production'].search([('bom_id', '=', self.bom.id)])
+ self.assertEqual(mo.state, 'confirmed')
+ # Check that 1 delivery with 1 component for the subcontractor has been created
+ picking_delivery = mo.picking_ids
+ wh = picking_delivery.picking_type_id.warehouse_id
+ origin = picking_delivery.origin
+ self.assertEqual(len(picking_delivery), 1)
+ self.assertEqual(len(picking_delivery.move_ids_without_package), 1)
+ self.assertEqual(picking_delivery.picking_type_id, wh.out_type_id)
+ self.assertEqual(picking_delivery.partner_id, self.subcontractor_partner1)
+
+ # Change the purchased quantity to 2
+ po.order_line.write({'product_qty': 2})
+ # Check that two deliveries with 1 component for the subcontractor have been created
+ picking_deliveries = self.env['stock.picking'].search([('origin', '=', origin)])
+ self.assertEqual(len(picking_deliveries), 2)
+ self.assertEqual(picking_deliveries[0].picking_type_id, wh.out_type_id)
+ self.assertEqual(picking_deliveries[0].partner_id, self.subcontractor_partner1)
+ self.assertTrue(picking_deliveries[0].state != 'cancel')
+ move1 = picking_deliveries[0].move_ids_without_package
+ self.assertEqual(picking_deliveries[1].picking_type_id, wh.out_type_id)
+ self.assertEqual(picking_deliveries[1].partner_id, self.subcontractor_partner1)
+ self.assertTrue(picking_deliveries[1].state != 'cancel')
+ move2 = picking_deliveries[1].move_ids_without_package
+ self.assertEqual(move1.product_id, self.comp1)
+ self.assertEqual(move1.product_uom_qty, 1)
+ self.assertEqual(move2.product_id, self.comp1)
+ self.assertEqual(move2.product_uom_qty, 1)