[FIX] stock: update quant with quantity

In case a quant for a product tracked by lot/sn exists but without any
lot/sn set and have some quantity, `_action_done()` should update it
instead of a quant with the correct lot but without any quantity

closes odoo/odoo#162683

X-original-commit: 534220ee90da3e213ea99ec5da7ce6cc9eff4203
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
William Henrotin
2024-04-22 10:12:55 +00:00
parent 9d37080b6a
commit f06da8b3c1
4 changed files with 72 additions and 3 deletions
+3 -1
View File
@@ -815,6 +815,8 @@ class StockQuant(models.Model):
else:
availaible_quantities = {lot_id: 0.0 for lot_id in list(set(quants.mapped('lot_id'))) + ['untracked']}
for quant in quants:
if not quant.lot_id and strict and lot_id:
continue
if not quant.lot_id:
availaible_quantities['untracked'] += quant.quantity - quant.reserved_quantity
else:
@@ -1073,7 +1075,7 @@ class StockQuant(models.Model):
if reserved_quantity:
vals['reserved_quantity'] = reserved_quantity
self.create(vals)
return self._get_available_quantity(product_id, location_id, lot_id=lot_id, package_id=package_id, owner_id=owner_id, strict=False, allow_negative=True), in_date
return self._get_available_quantity(product_id, location_id, lot_id=lot_id, package_id=package_id, owner_id=owner_id, strict=True, allow_negative=True), in_date
@api.model
def _update_reserved_quantity(self, product_id, location_id, quantity, lot_id=None, package_id=None, owner_id=None, strict=True):
+1 -1
View File
@@ -156,7 +156,7 @@ class TestInventory(TransactionCase):
stock_confirmation_wizard.action_confirm()
# check
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.stock_location, lot_id=lot1, strict=True), 11.0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.stock_location, lot_id=lot1, strict=False), 11.0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.stock_location, strict=True), 10.0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product2, self.stock_location), 11.0)
self.assertEqual(len(self.env['stock.quant']._gather(self.product2, self.stock_location, lot_id=lot1, strict=True).filtered(lambda q: q.lot_id)), 1.0)
+1 -1
View File
@@ -721,7 +721,7 @@ class StockMove(TransactionCase):
self.assertEqual(move1.quantity, 0.0)
self.assertEqual(len(move1.move_line_ids), 0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product_serial, self.stock_location, strict=True), 1.0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product_serial, self.stock_location, lot_id=lot1, strict=True), 2.0)
self.assertEqual(self.env['stock.quant']._get_available_quantity(self.product_serial, self.stock_location, lot_id=lot1, strict=False), 2.0)
def test_putaway_1(self):
""" Receive products from a supplier. Check that putaway rules are rightly applied on
+67
View File
@@ -1781,6 +1781,73 @@ class TestSinglePicking(TestStockCommon):
move_line.lot_id = lot1
delivery_order._action_done()
def test_use_create_lot_use_existing_lot_5(self):
"""Check if a quant without lot exist, it will be decrease even if a
quant with the right lot exists but is empty"""
self.env['stock.picking.type']\
.browse(self.picking_type_in)\
.write({
'use_create_lots': False,
'use_existing_lots': False,
})
self.productA.tracking = 'lot'
receipt = self.env['stock.picking'].create({
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
'picking_type_id': self.picking_type_in,
})
self.MoveObj.create({
'name': self.productA.name,
'product_id': self.productA.id,
'product_uom_qty': 2,
'product_uom': self.productA.uom_id.id,
'picking_id': receipt.id,
'picking_type_id': self.picking_type_in,
'location_id': self.supplier_location,
'location_dest_id': self.stock_location,
})
receipt.action_confirm()
receipt.move_ids.quantity = 2
receipt.move_ids.picked = True
receipt._action_done()
quant = self.env['stock.quant'].search([
('product_id', '=', self.productA.id),
('location_id', '=', self.stock_location),
('lot_id', '=', False),
])
self.assertTrue(quant, 'A quant without lot should exist')
self.assertEqual(quant.quantity, 2, 'The quantity of the quant without lot should be 2')
lot = self.env['stock.lot'].create({
'name': 'lot1',
'product_id': self.productA.id,
'company_id': self.env.company.id,
})
new_quant = self.env['stock.quant'].create({
'product_id': self.productA.id,
'location_id': self.stock_location,
'lot_id': lot.id,
})
out_move = self.MoveObj.create({
'name': self.productA.name,
'product_id': self.productA.id,
'product_uom_qty': 1,
'product_uom': self.productA.uom_id.id,
'picking_type_id': self.picking_type_out,
'location_id': self.stock_location,
'location_dest_id': self.customer_location,
})
out_move._action_confirm()
out_move._action_assign()
out_move.move_line_ids.lot_id = lot
out_move.move_line_ids.quantity = 1
out_move.picked = True
out_move._action_done()
self.assertEqual(new_quant.quantity, 0, 'The quant with lot should remain untouched 1')
self.assertEqual(quant.quantity, 1, 'The quantity of the quant without lot should be 1')
def test_merge_moves_1(self):
receipt = self.env['stock.picking'].create({
'location_id': self.supplier_location,