[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) <whe@odoo.com>
Signed-off-by: Djamel Touati (otd) <otd@odoo.com>
This commit is contained in:
Djamel Touati
2024-02-06 15:59:55 +00:00
parent cac7a44dd2
commit 4a820bf723
2 changed files with 24 additions and 10 deletions
@@ -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
@@ -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)