[FIX] sale_mrp: sell kit with dropshipped component
When selling a kit with a dropshipped component, the delivered quantity
will be incorrect
To reproduce the issue:
1. Create 3 consumable products P01, P02, P_kit:
- P02:
- Add a seller S
- Enable the dropship route
2. Create a bill of materials:
- Product: P_kit
- Type: Kit
- Components:
- 1 x P01
- 1 x P02
3. Create and confirm a sale order SO with 1 x P_kit
4. Confirm the generated purchase order (with vendor S)
5. Process the two pickings of SO
6. Go back to SO
Error: The delivered quantity of P_kit is 0 instead of 1
When computing the delivered quantity, because the `dropship` flag is
not set, we don't reach the revelant code:
https://github.com/odoo/odoo/blob/3db136f19480b31ca3f60a77c0c7354161bedde0/addons/sale_mrp/models/sale_mrp.py#L37-L44
OPW-2870893
closes odoo/odoo#94364
X-original-commit: fff6edad8cfb45b9a622bceefa4b83f620d7fe86
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
@@ -250,3 +250,44 @@ class TestSaleDropshippingFlows(TestMrpSubcontractingCommon):
|
||||
|
||||
sale_order.picking_ids.action_cancel()
|
||||
self.assertEqual(sale_order.order_line.qty_delivered, 0.0)
|
||||
|
||||
def test_sale_kit_with_dropshipped_component(self):
|
||||
"""
|
||||
The test checks the delivered quantity of a kit when one of the
|
||||
components is dropshipped
|
||||
"""
|
||||
compo01, compo02, kit = self.env['product.product'].create([{
|
||||
'name': n,
|
||||
'type': 'consu',
|
||||
} for n in ['compo01', 'compo02', 'super kit']])
|
||||
|
||||
compo02.write({
|
||||
'route_ids': [(6, 0, [self.dropship_route.id])],
|
||||
'seller_ids': [(0, 0, {'partner_id': self.supplier.id})],
|
||||
})
|
||||
|
||||
self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': kit.product_tmpl_id.id,
|
||||
'product_qty': 1,
|
||||
'type': 'phantom',
|
||||
'bom_line_ids': [
|
||||
(0, 0, {'product_id': compo01.id, 'product_qty': 1}),
|
||||
(0, 0, {'product_id': compo02.id, 'product_qty': 1}),
|
||||
],
|
||||
})
|
||||
|
||||
sale_order = self.env['sale.order'].create({
|
||||
'partner_id': self.customer.id,
|
||||
'picking_policy': 'direct',
|
||||
'order_line': [
|
||||
(0, 0, {'name': kit.name, 'product_id': kit.id, 'product_uom_qty': 1}),
|
||||
],
|
||||
})
|
||||
sale_order.action_confirm()
|
||||
self.env['purchase.order'].search([], order='id desc', limit=1).button_confirm()
|
||||
|
||||
sale_order.picking_ids.move_ids.quantity_done = 1
|
||||
sale_order.picking_ids[0].button_validate()
|
||||
sale_order.picking_ids[1].button_validate()
|
||||
|
||||
self.assertEqual(sale_order.order_line.qty_delivered, 1.0)
|
||||
|
||||
@@ -35,10 +35,9 @@ class SaleOrderLine(models.Model):
|
||||
for order_line in self:
|
||||
if order_line.qty_delivered_method == 'stock_move':
|
||||
boms = order_line.move_ids.filtered(lambda m: m.state != 'cancel').mapped('bom_line_id.bom_id')
|
||||
dropship = False
|
||||
if not boms and any(m._is_dropshipped() for m in order_line.move_ids):
|
||||
dropship = any(m._is_dropshipped() for m in order_line.move_ids)
|
||||
if not boms and dropship:
|
||||
boms = boms._bom_find(order_line.product_id, company_id=order_line.company_id.id, bom_type='phantom')[order_line.product_id]
|
||||
dropship = True
|
||||
# We fetch the BoMs of type kits linked to the order_line,
|
||||
# the we keep only the one related to the finished produst.
|
||||
# This bom should be the only one since bom_line_id was written on the moves
|
||||
|
||||
Reference in New Issue
Block a user