From 4952d150ee55dab01313aef01e8e90e7059a67c8 Mon Sep 17 00:00:00 2001 From: Adrien Widart Date: Fri, 20 May 2022 08:00:40 +0000 Subject: [PATCH] [FIX] mrp_subcontracting_dropshipping: use a sub-location When using a sub-location of "Subcontracing Location" and a dropshipped component, the purchase order doesn't have any dropship address. To reproduce the issue: (Enable debug mode) 1. In Settings, enable "Multi-Step Routes" 2. Create a new location L: - Parent: Physical Locations/Subcontracting Location - Type: Internal Location 3. In Rules, duplicate the rules of route "Dropship Subcontractor on Order" and replace "Physical Locations/Subcontracting Location" with L 4. Create two products: - P_finished: - Type: Storable - Vendor: V_subcontractor - P_compo: - Type: Consumable - Vendor: V_compo - Routes: Dropship Subcontractor on Order 5. Edit V_subcontractor: - Subcontractor Location: L 6. Create a bill of materials: - Product: P_finished - Type: Subcontracting - Subcontractor: V_subcontractor - Components: 1 x P_compo 7. Create and confirm a purchase order: - Vendor: V_subcontractor - Products: 1 x P_finished 8. Open the purchase order linked with P_compo Error: the Dropship Address is not defined This address is defined thanks to the value of `partner_id`: https://github.com/odoo/odoo/blob/aec7fcdb693729f432ae2341c00ef317b65fbcbc/addons/purchase_stock/models/stock_rule.py#L300 However, this key is missing OPW-2721474 closes odoo/odoo#92249 X-original-commit: 587d8cd0ecb956a5c1b1a32a7abadea3019f848e Signed-off-by: William Henrotin (whe) Signed-off-by: Adrien Widart --- .../models/stock_rule.py | 2 +- .../tests/test_purchase_subcontracting.py | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/addons/mrp_subcontracting_dropshipping/models/stock_rule.py b/addons/mrp_subcontracting_dropshipping/models/stock_rule.py index 44bf11fb9fd..21090a7ee88 100644 --- a/addons/mrp_subcontracting_dropshipping/models/stock_rule.py +++ b/addons/mrp_subcontracting_dropshipping/models/stock_rule.py @@ -8,6 +8,6 @@ class StockRule(models.Model): _inherit = 'stock.rule' def _prepare_purchase_order(self, company_id, origins, values): - if 'partner_id' not in values[0] and self.location_dest_id.id == company_id.subcontracting_location_id.id: + if 'partner_id' not in values[0] and company_id.subcontracting_location_id.parent_path in self.location_dest_id.parent_path: values[0]['partner_id'] = values[0]['group_id'].partner_id.id return super()._prepare_purchase_order(company_id, origins, values) diff --git a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py index a27cc822bf3..eeb3d9c68c9 100644 --- a/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py +++ b/addons/mrp_subcontracting_dropshipping/tests/test_purchase_subcontracting.py @@ -134,3 +134,60 @@ class TestSubcontractingDropshippingFlows(TestMrpSubcontractingCommon): self.assertEqual(move1.product_uom_qty, 1) self.assertEqual(move2.product_id, self.comp1) self.assertEqual(move2.product_uom_qty, 1) + + def test_dropshipped_component_and_sub_location(self): + """ + Suppose: + - a subcontracted product and a component dropshipped to the subcontractor + - the location of the subcontractor is a sub-location of the main subcontrating location + This test ensures that the PO that brings the component to the subcontractor has a correct + destination address + """ + subcontract_location = self.env.company.subcontracting_location_id + sub_location = self.env['stock.location'].create({ + 'name': 'Super Location', + 'location_id': subcontract_location.id, + }) + + dropship_subcontractor_route = self.env['stock.route'].search([('name', '=', 'Dropship Subcontractor on Order')]) + dropship_subcontractor_route.rule_ids.filtered(lambda rule: rule.location_dest_id == subcontract_location).copy(default={'location_dest_id': sub_location.id}) + dropship_subcontractor_route.rule_ids.filtered(lambda rule: rule.location_src_id == subcontract_location).copy(default={'location_src_id': sub_location.id}) + + subcontractor, vendor = self.env['res.partner'].create([ + {'name': 'SuperSubcontractor', 'property_stock_subcontractor': sub_location.id}, + {'name': 'SuperVendor'}, + ]) + + p_finished, p_compo = self.env['product.product'].create([{ + 'name': 'Finished Product', + 'type': 'product', + 'seller_ids': [(0, 0, {'partner_id': subcontractor.id})], + }, { + 'name': 'Component', + 'type': 'consu', + 'seller_ids': [(0, 0, {'partner_id': vendor.id})], + 'route_ids': [(6, 0, dropship_subcontractor_route.ids)] + }]) + + self.env['mrp.bom'].create({ + 'product_tmpl_id': p_finished.product_tmpl_id.id, + 'product_qty': 1, + 'type': 'subcontract', + 'subcontractor_ids': [(6, 0, subcontractor.ids)], + 'bom_line_ids': [ + (0, 0, {'product_id': p_compo.id, 'product_qty': 1}), + ], + }) + + subcontract_po = self.env['purchase.order'].create({ + "partner_id": subcontractor.id, + "order_line": [(0, 0, { + 'product_id': p_finished.id, + 'name': p_finished.name, + 'product_qty': 1.0, + })], + }) + subcontract_po.button_confirm() + + dropship_po = self.env['purchase.order'].search([('partner_id', '=', vendor.id)]) + self.assertEqual(dropship_po.dest_address_id, subcontractor)