From 0a5a423bffeaa7745cddf7c80698989bd9908c5b Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 30 Jan 2017 16:50:27 +0100 Subject: [PATCH] [FIX] sale_mrp, purchase_mrp: delivered quantity - Create a manufactured Product A (sold as kit), invoicing based on delivered quantity. - Create the associated BOM, e.g. contains 2 Products B. - Create a SO with Product A, validate - Change the BOM so it contains 2 Products C - Validate the picking linked to the SO The delivered quantity is not updated since the delivered products (B) are not the same than the products of the BOM. This should not be the case. Changing a BOM should not affect the invoicing. To solve this, we simplify the check and only verifies that all moves are done. The same change is applied for PO. --- addons/purchase_mrp/models/purchase_mrp.py | 28 ++++++--------------- addons/sale_mrp/sale_mrp.py | 29 ++++++---------------- 2 files changed, 14 insertions(+), 43 deletions(-) diff --git a/addons/purchase_mrp/models/purchase_mrp.py b/addons/purchase_mrp/models/purchase_mrp.py index 4c22ee1a58c..25bfef78e85 100644 --- a/addons/purchase_mrp/models/purchase_mrp.py +++ b/addons/purchase_mrp/models/purchase_mrp.py @@ -19,26 +19,12 @@ class PurchaseOrderLine(models.Model): def _get_bom_delivered(self, bom=False): self.ensure_one() - precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') - # In the case of a kit, we need to check if all components are received or not. - # nothing policy. A product can have several BoMs, we don't know which one was used when the - # receipt was created. - bom_delivered = {} + # In the case of a kit, we need to check if all components are shipped. Since the BOM might + # have changed, we don't compute the quantities but verify the move state. if bom: - bom_delivered[bom.id] = False - product_uom_qty_bom = self.product_uom._compute_quantity(self.product_qty, bom.product_uom_id) / bom.product_qty - boms, lines = bom.explode(self.product_id, product_uom_qty_bom) - for bom_line, data in lines: - qty = 0.0 - for move in self.move_ids.filtered(lambda x: x.state == 'done' and x.product_id == bom_line.product_id): - qty += move.product_uom._compute_quantity(move.product_uom_qty, bom_line.product_uom_id) - if float_compare(qty, data['qty'], precision_digits=precision) < 0: - bom_delivered[bom.id] = False - break - else: - bom_delivered[bom.id] = True - if bom_delivered and any(bom_delivered.values()): - return self.product_qty - elif bom_delivered: - return 0.0 + bom_delivered = all([move.state == 'done' for move in self.move_ids]) + if bom_delivered: + return self.product_qty + else: + return 0.0 diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py index 7a98c95469b..8aa4074c8bb 100644 --- a/addons/sale_mrp/sale_mrp.py +++ b/addons/sale_mrp/sale_mrp.py @@ -30,31 +30,16 @@ class SaleOrderLine(models.Model): @api.multi def _get_delivered_qty(self): self.ensure_one() - precision = self.env['decimal.precision'].precision_get('Product Unit of Measure') - # In the case of a kit, we need to check if all components are shipped. We use a all or - # nothing policy. A product can have several BoMs, we don't know which one was used when the - # delivery was created. - bom_delivered = {} + # In the case of a kit, we need to check if all components are shipped. Since the BOM might + # have changed, we don't compute the quantities but verify the move state. bom = self.env['mrp.bom']._bom_find(product=self.product_id) if bom and bom.type == 'phantom': - bom_delivered[bom.id] = False - product_uom_qty_bom = self.product_uom._compute_quantity(self.product_uom_qty, bom.product_uom_id) / bom.product_qty - boms, lines = bom.explode(self.product_id, product_uom_qty_bom) - for bom_line, data in lines: - qty = 0.0 - for move in self.procurement_ids.mapped('move_ids'): - if move.state == 'done' and move.product_id.id == bom_line.product_id.id: - qty += move.product_uom._compute_quantity(move.product_uom_qty, bom_line.product_uom_id) - if float_compare(qty, data['qty'], precision_digits=precision) < 0: - bom_delivered[bom.id] = False - break - else: - bom_delivered[bom.id] = True - if bom_delivered and any(bom_delivered.values()): - return self.product_uom_qty - elif bom_delivered: - return 0.0 + bom_delivered = all([move.state == 'done' for move in self.procurement_ids.mapped('move_ids')]) + if bom_delivered: + return self.product_uom_qty + else: + return 0.0 return super(SaleOrderLine, self)._get_delivered_qty()