Skip to content

Commit

Permalink
[FIX] mrp_subcontracting_dropshipping: dropship twice from same vendor
Browse files Browse the repository at this point in the history
To reproduce the issue:
1. In Settings, enable "Multi-Step Routes"
2. Edit the route "Dropship Subcontractor on Order":
   - Open the Buy rule:
     - Propagation of Procurement Group: Leave Empty
3. Create three products P1, P2, P_comp:
   - Storable
   - With a vendor (V1, V2, V_comp)
   - P_comp's routes:
     - Dropship Subcontractor on Order
4. Create a BoM:
   - Product: P1
   - Type: Subcontracting
   - Subcontractors: V1
   - Components: 1 x P_comp
5. Repeat step 4 with P2 and V2
6. Create and confirm a PO:
   - Vendor: V1
   - Products: 1 x P1
7. Repeat step 6 with V2 and P2
8. Open the purchase orders list

Error: There is only one PO with V_comp. It contains 2 x P_comp and
the dropship address is P1. This is incorrect. There should be two
PO, one for P1 and another one for P2

When confirming the PO, a MO is created (subcontracted) and then the
system creates and processes a procurement for the component.
Because of the component's routes, it leads to the `_run_buy` method.
It will check whether a PO already exists or has to be created. To do
so, it creates a domain based on few criteria, such as the value of
`dest_address_id`:
https://github.com/odoo/odoo/blob/6d28c9c2e5ea3e9a3b8a872627a411bbfe2f2a59/addons/mrp_subcontracting_dropshipping/models/stock_rule.py#L17-L21
But here is the issue: `partner_id` is not defined.

OPW-3370648

closes odoo#128791

X-original-commit: 094e45d
Signed-off-by: William Henrotin (whe) <[email protected]>
Signed-off-by: Adrien Widart (awt) <[email protected]>
  • Loading branch information
adwid committed Jul 18, 2023
1 parent d4451de commit 01a86d8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
7 changes: 7 additions & 0 deletions addons/mrp_subcontracting_dropshipping/models/stock_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
class StockMove(models.Model):
_inherit = "stock.move"

def _prepare_procurement_values(self):
vals = super()._prepare_procurement_values()
partner = self.group_id.partner_id
if not vals.get('partner_id') and partner and self.location_id.is_subcontracting_location:
vals['partner_id'] = partner.id
return vals

def _is_purchase_return(self):
res = super()._is_purchase_return()
return res or self._is_dropshipped_returned()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,55 @@ def test_po_to_subcontractor(self):
delivery.button_validate()

self.assertEqual(po.order_line.qty_received, 1.0)

def test_two_boms_same_component_supplier(self):
"""
The "Dropship Subcontractor" route is modified: the propagation of the
buy rule is set to "Leave Empty".
Two subcontracted products (different subcontractor) that use the same
component. The component has its own supplier. Confirm one PO for each
subcontrated product. It should generate two PO from component's
supplier to each subcontractor.
"""
dropship_subcontractor_route = self.env.ref('mrp_subcontracting_dropshipping.route_subcontracting_dropshipping')
dropship_subcontractor_route.rule_ids.filtered(lambda r: r.action == 'buy').group_propagation_option = 'none'

subcontractor01, subcontractor02, component_supplier = self.env['res.partner'].create([{
'name': 'Super Partner %d' % i
} for i in range(3)])

product01, product02, component = self.env['product.product'].create([{
'name': name,
'type': 'product',
'seller_ids': [(0, 0, {'partner_id': vendor.id})],
'route_ids': [(6, 0, routes)],
} for name, vendor, routes in [
('SuperProduct 01', subcontractor01, []),
('SuperProduct 02', subcontractor02, []),
('Component', component_supplier, dropship_subcontractor_route.ids),
]])

self.env['mrp.bom'].create([{
'product_tmpl_id': finished.product_tmpl_id.id,
'type': 'subcontract',
'subcontractor_ids': [(4, subcontractor.id)],
'bom_line_ids': [(0, 0, {'product_id': component.id})]
} for finished, subcontractor in [
(product01, subcontractor01),
(product02, subcontractor02),
]])

for (partner, product) in [(subcontractor01, product01), (subcontractor02, product02)]:
po_form = Form(self.env['purchase.order'])
po_form.partner_id = partner
with po_form.order_line.new() as line:
line.product_id = product
po = po_form.save()
po.button_confirm()

supplier_orders = self.env['purchase.order'].search([('partner_id', '=', component_supplier.id)])
self.assertEqual(supplier_orders.dest_address_id, subcontractor01 | subcontractor02)
self.assertRecordValues(supplier_orders.order_line, [
{'product_id': component.id, 'product_qty': 1.0},
{'product_id': component.id, 'product_qty': 1.0},
])

0 comments on commit 01a86d8

Please sign in to comment.