[FIX] stock: negative move propagation
When a warehouse used multi-steps for incoming/outgoing shipments, negative procurements could create returns pickings instead of reducing the quantity of subsequent moves down the chain. For example a two-step delivery, a sale order with 5 product A would have the following pickings linked : Pick: - product A : 5 qty Out: - product A : 5 qty Then reducing the amount of product A to 2 in the sale order would do : Pick: - product A : 2 qty Out: - product A : 5 qty Return: - product A : 3 qty closes odoo/odoo#84900 X-original-commit: c9bc689468d2c775d3b3ec65c8894e4dd66e7249 Signed-off-by: Arnold Moyaux <arm@odoo.com>
This commit is contained in:
@@ -1122,8 +1122,11 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
|
||||
def test_17_qty_update_propagation(self):
|
||||
""" Creates a sale order, then modifies the sale order lines qty and verifies
|
||||
that quantity changes are correctly propagated to the delivery picking.
|
||||
that quantity changes are correctly propagated to the picking and delivery picking.
|
||||
"""
|
||||
# Set the delivery in two steps.
|
||||
warehouse = self.company_data['default_warehouse']
|
||||
warehouse.delivery_steps = 'pick_ship'
|
||||
# Sell a product.
|
||||
product = self.company_data['product_delivery_no'] # storable
|
||||
product.type = 'product' # storable
|
||||
@@ -1138,8 +1141,10 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
sale_order.action_confirm()
|
||||
|
||||
# Check picking created
|
||||
self.assertEqual(len(sale_order.picking_ids), 1, 'A delivery picking should have been created.')
|
||||
move_out = sale_order.picking_ids.move_ids
|
||||
self.assertEqual(len(sale_order.picking_ids), 2, 'A picking and a delivery picking should have been created.')
|
||||
customer_location = self.env.ref('stock.stock_location_customers')
|
||||
move_pick = sale_order.picking_ids.filtered(lambda p: p.location_dest_id.id != customer_location.id).move_ids
|
||||
move_out = sale_order.picking_ids.filtered(lambda p: p.location_dest_id.id == customer_location.id).move_ids
|
||||
self.assertEqual(len(move_out), 1, 'Only one move should be created for a single product.')
|
||||
self.assertEqual(move_out.product_uom_qty, 50, 'The move quantity should be the same as the quantity sold.')
|
||||
|
||||
@@ -1149,7 +1154,9 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
(1, sale_order.order_line.id, {'product_uom_qty': 30}),
|
||||
]
|
||||
})
|
||||
self.assertEqual(move_out.product_uom_qty, 30, 'The move quantity should have been decreased as the sale order line was.')
|
||||
self.assertEqual(move_pick.product_uom_qty, 30, 'The move quantity should have been decreased as the sale order line was.')
|
||||
self.assertEqual(move_out.product_uom_qty, 30, 'The move quantity should have been decreased as the sale order line and the pick line were.')
|
||||
self.assertEqual(len(sale_order.picking_ids), 2, 'No additionnal picking should have been created.')
|
||||
|
||||
# Increase the quantity in the sale order and check the move has been updated.
|
||||
sale_order.write({
|
||||
@@ -1157,4 +1164,5 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
(1, sale_order.order_line.id, {'product_uom_qty': 40})
|
||||
]
|
||||
})
|
||||
self.assertEqual(move_out.product_uom_qty, 40, 'The move quantity should have been increased as the sale order line was.')
|
||||
self.assertEqual(move_pick.product_uom_qty, 40, 'The move quantity should have been increased as the sale order line was.')
|
||||
self.assertEqual(move_out.product_uom_qty, 40, 'The move quantity should have been increased as the sale order line and the pick line were.')
|
||||
|
||||
@@ -6,7 +6,7 @@ from collections import defaultdict
|
||||
from datetime import timedelta
|
||||
from operator import itemgetter
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo import _, api, Command, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools.float_utils import float_compare, float_is_zero, float_round
|
||||
@@ -878,6 +878,10 @@ class StockMove(models.Model):
|
||||
# If quantity can be fully absorbed by a single move, update its quantity and remove the negative move
|
||||
if float_compare(pos_move.product_uom_qty, abs(neg_move.product_uom_qty), precision_rounding=pos_move.product_uom.rounding) >= 0:
|
||||
pos_move.product_uom_qty += neg_move.product_uom_qty
|
||||
pos_move.write({
|
||||
'move_dest_ids': [Command.link(m.id) for m in self.mapped('move_dest_ids')],
|
||||
'move_orig_ids': [Command.link(m.id) for m in self.mapped('move_orig_ids')],
|
||||
})
|
||||
merged_moves |= pos_move
|
||||
moves_to_unlink |= neg_move
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user