From 4a820bf72321aaee4cfeff3de34ae1b175609bb5 Mon Sep 17 00:00:00 2001 From: Djamel Touati Date: Fri, 2 Feb 2024 14:51:18 +0100 Subject: [PATCH] [FIX] purchase_stock: update the PO qty without traceback Steps to reproduce the bug: - Create a storable product X1: - Route: MTO + buy - Vendor: Azure Interior - BoM: - Type: subcontractor - Subcontractor: Azure interior - Component: any component - Create a MO: - product: P1 - Component: X1, qty: 3 - Confirm the MO - Go to the created PO - Confirm the PO - Go to the picking - receive 2 units of P1 and validate it - create a backorder - Cancel the backorder - Try to update the purchased qty in the PO line to 2 Problem: A traceback is triggered: File "/home/odoo/src/odoo/addons/purchase_stock/models/purchase.py", line 542, in _prepare_stock_move_vals 'picking_id': picking.id, AttributeError: 'bool' object has no attribute 'id' Solution: When updating the quantity in the purchase order, if no picking requires an update, it is better to avoid creating a new picking and new moves. opw-3681064 closes odoo/odoo#152577 X-original-commit: 0da5d6cc0c94320ad39fe9b930dde4b0ef6feff5 Signed-off-by: William Henrotin (whe) Signed-off-by: Djamel Touati (otd) --- .../tests/test_mrp_subcontracting_purchase.py | 30 +++++++++++++------ .../models/purchase_order_line.py | 4 ++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py index fa0e26e8709..74693f5e376 100644 --- a/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py +++ b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py @@ -621,16 +621,28 @@ class MrpSubcontractingPurchaseTest(TestMrpSubcontractingCommon): """ Test That we can update the quantity of a purchase order line with a subcontracted product """ - po = self.env['purchase.order'].create({ - 'partner_id': self.subcontractor_partner1.id, - 'order_line': [Command.create({ - 'name': 'finished', - 'product_id': self.finished.id, - 'product_qty': 3.0, - 'product_uom': self.finished.uom_id.id, - 'price_unit': 50.0} - )], + mto_route = self.env.ref('stock.route_warehouse0_mto') + buy_route = self.env['stock.route'].search([('name', '=', 'Buy')]) + mto_route.active = True + self.finished.route_ids = mto_route.ids + buy_route.ids + seller = self.env['product.supplierinfo'].create({ + 'partner_id': self.vendor.id, + 'price': 12.0, + 'delay': 0 }) + self.finished.seller_ids = [(6, 0, [seller.id])] + + mo = self.env['mrp.production'].create({ + 'product_id': self.finished2.id, + 'product_qty': 3.0, + 'move_raw_ids': [(0, 0, { + 'product_id': self.finished.id, + 'product_uom_qty': 3.0, + 'product_uom': self.finished.uom_id.id, + })] + }) + mo.action_confirm() + po = self.env['purchase.order.line'].search([('product_id', '=', self.finished.id)]).order_id po.button_confirm() self.assertEqual(len(po.picking_ids), 1) picking = po.picking_ids diff --git a/addons/purchase_stock/models/purchase_order_line.py b/addons/purchase_stock/models/purchase_order_line.py index f133d60d2c3..fd40e3fbd65 100644 --- a/addons/purchase_stock/models/purchase_order_line.py +++ b/addons/purchase_stock/models/purchase_order_line.py @@ -174,7 +174,9 @@ class PurchaseOrderLine(models.Model): # If the user increased quantity of existing line or created a new line pickings = line.order_id.picking_ids.filtered(lambda x: x.state not in ('done', 'cancel') and x.location_dest_id.usage in ('internal', 'transit', 'customer')) picking = pickings and pickings[0] or False - if not picking and line.product_qty > line.qty_received: + if not picking: + if not line.product_qty > line.qty_received: + continue res = line.order_id._prepare_picking() picking = self.env['stock.picking'].create(res)