[FIX] sale_mrp: delivered qty in dropship

- Activate Dropshipping
- Create 3 products: KIT AB, A, B
  All have the Dropship route and a supplier set
- Create a BOM of type kit: KIT AB is composed of A & B
- Create a SO for 1 unit of KIT AB, validate
- Validate the created PO
- Deliver the products

The delivered quantity remains zero.

This happens because the `bom_line_id` was not written on the
`stock.move`. Indeed, the latter is created from a PO, not from a SO.
Since the PO doesn't have a `bom_line_id` field, the information is
lost.

As a solution, we apply the 'all or nothing' policy in case of
dropshipping.

opw-2207118

closes odoo/odoo#47014

X-original-commit: 6016476952f53097f8b04f34bdbaf09c12e431fe
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
This commit is contained in:
Nicolas Martinelli
2020-03-05 16:02:38 +00:00
parent cdddd45a73
commit 3c4c625a0a
+16
View File
@@ -56,6 +56,10 @@ class SaleOrderLine(models.Model):
for order_line in self:
if order_line.qty_delivered_method == 'stock_move':
boms = order_line.move_ids.mapped('bom_line_id.bom_id')
dropship = False
if not boms and any([m._is_dropshipped() for m in order_line.move_ids]):
boms = boms._bom_find(product=order_line.product_id, company_id=order_line.company_id.id, bom_type='phantom')
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 shoud be the only one since bom_line_id was written on the moves
@@ -63,6 +67,18 @@ class SaleOrderLine(models.Model):
(b.product_id == order_line.product_id or
(b.product_tmpl_id == order_line.product_id.product_tmpl_id and not b.product_id)))
if relevant_bom:
# In case of dropship, we use a 'all or nothing' policy since 'bom_line_id' was
# not written on a move coming from a PO.
# FIXME: if the components of a kit have different suppliers, multiple PO
# are generated. If one PO is confirmed and all the others are in draft, receiving
# the products for this PO will set the qty_delivered. We might need to check the
# state of all PO as well... but sale_mrp doesn't depend on purchase.
if dropship:
if order_line.move_ids and all([m.state == 'done' for m in order_line.move_ids]):
order_line.qty_delivered = order_line.product_uom_qty
else:
order_line.qty_delivered = 0.0
continue
moves = order_line.move_ids.filtered(lambda m: m.state == 'done' and not m.scrapped)
filters = {
'incoming_moves': lambda m: m.location_dest_id.usage == 'customer' and (not m.origin_returned_move_id or (m.origin_returned_move_id and m.to_refund)),