[FIX] stock: button_validate: forced move lines
When a move line is not linked to a move, it'll be linked to the first move of the same product at validation time. We slightly improve this logic by linking it to the first non-completed move. To be completely correct, we should split the move line if necessary and link it to all needed moves, but at this time we don't want to make the logic too complex. Use case: create a sale order with three sale order lines of the same products, use the detailed operations view and add three move lines of the same products, validate the picking. Before the patch, all move lines were linked to the first move and thus only the first sale order line had delivered quantities. Fixes #25488 opw-1861765
This commit is contained in:
@@ -421,3 +421,76 @@ class TestSaleStock(TestSale):
|
||||
# check the delivered quantity
|
||||
self.assertEqual(so1.order_line.qty_delivered, 3.0)
|
||||
|
||||
def test_07_forced_qties(self):
|
||||
""" Make multiple sale order lines of the same product which isn't available in stock. On
|
||||
the picking, create new move lines (through the detailed operations view). See that the move
|
||||
lines are correctly dispatched through the moves.
|
||||
"""
|
||||
uom_unit = self.env.ref('product.product_uom_unit')
|
||||
uom_dozen = self.env.ref('product.product_uom_dozen')
|
||||
item1 = self.products['prod_order']
|
||||
|
||||
self.assertEqual(item1.uom_id.id, uom_unit.id)
|
||||
|
||||
# sell a dozen
|
||||
so1 = self.env['sale.order'].create({
|
||||
'partner_id': self.partner.id,
|
||||
'order_line': [
|
||||
(0, 0, {
|
||||
'name': item1.name,
|
||||
'product_id': item1.id,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': uom_dozen.id,
|
||||
'price_unit': item1.list_price,
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': item1.name,
|
||||
'product_id': item1.id,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': uom_dozen.id,
|
||||
'price_unit': item1.list_price,
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': item1.name,
|
||||
'product_id': item1.id,
|
||||
'product_uom_qty': 1,
|
||||
'product_uom': uom_dozen.id,
|
||||
'price_unit': item1.list_price,
|
||||
}),
|
||||
],
|
||||
})
|
||||
so1.action_confirm()
|
||||
|
||||
self.assertEqual(len(so1.picking_ids.move_lines), 3)
|
||||
so1.picking_ids.write({
|
||||
'move_line_ids': [
|
||||
(0, 0, {
|
||||
'product_id': item1.id,
|
||||
'product_uom_qty': 0,
|
||||
'qty_done': 1,
|
||||
'product_uom_id': uom_dozen.id,
|
||||
'location_id': so1.picking_ids.location_id.id,
|
||||
'location_dest_id': so1.picking_ids.location_dest_id.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': item1.id,
|
||||
'product_uom_qty': 0,
|
||||
'qty_done': 1,
|
||||
'product_uom_id': uom_dozen.id,
|
||||
'location_id': so1.picking_ids.location_id.id,
|
||||
'location_dest_id': so1.picking_ids.location_dest_id.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'product_id': item1.id,
|
||||
'product_uom_qty': 0,
|
||||
'qty_done': 1,
|
||||
'product_uom_id': uom_dozen.id,
|
||||
'location_id': so1.picking_ids.location_id.id,
|
||||
'location_dest_id': so1.picking_ids.location_dest_id.id,
|
||||
}),
|
||||
],
|
||||
})
|
||||
so1.picking_ids.button_validate()
|
||||
self.assertEqual(so1.picking_ids.state, 'done')
|
||||
self.assertEqual(so1.order_line.mapped('qty_delivered'), [1, 1, 1])
|
||||
|
||||
|
||||
@@ -631,8 +631,9 @@ class Picking(models.Model):
|
||||
# # Link existing moves or add moves when no one is related
|
||||
for ops in pick.move_line_ids.filtered(lambda x: not x.move_id):
|
||||
# Search move with this product
|
||||
moves = pick.move_lines.filtered(lambda x: x.product_id == ops.product_id)
|
||||
if moves: #could search move that needs it the most (that has some quantities left)
|
||||
moves = pick.move_lines.filtered(lambda x: x.product_id == ops.product_id)
|
||||
moves = sorted(moves, key=lambda m: m.quantity_done < m.product_qty, reverse=True)
|
||||
if moves:
|
||||
ops.move_id = moves[0].id
|
||||
else:
|
||||
new_move = self.env['stock.move'].create({
|
||||
@@ -802,7 +803,7 @@ class Picking(models.Model):
|
||||
quantity_done[quant.product_id.id] += quant.qty
|
||||
for pack in self.mapped('move_line_ids').filtered(lambda x: x.product_id and not x.move_id):
|
||||
quantity_done.setdefault(pack.product_id.id, 0)
|
||||
quantity_done[pack.product_id.id] += pack.qty_done
|
||||
quantity_done[pack.product_id.id] += pack.product_uom_id._compute_quantity(pack.qty_done, pack.product_id.uom_id)
|
||||
return any(quantity_done[x] < quantity_todo.get(x, 0) for x in quantity_done)
|
||||
|
||||
@api.multi
|
||||
|
||||
Reference in New Issue
Block a user