[FIX] product_expiry: handle missing lot in FEFO removal strategy

Before this commit, using the First Expiry First Out (FEFO) removal
strategy led to a traceback error during stock move confirmation if a
stock quant of a product was missing its lot. This issue arose because
the removal strategy's sort key was based on `removal_date`, which is a
field related to `lot_id`.

To address this problem, the sorting logic has been modified. Now, it
uses `removal_date` or `fields.datetime.max` as the sort key.

opw-3625784

closes odoo/odoo#145274

Signed-off-by: Quentin Wolfs (quwo) <quwo@odoo.com>
This commit is contained in:
Pedram (PEBR)
2023-12-07 10:07:57 +00:00
parent 4ef05755bb
commit c569a0d41b
2 changed files with 37 additions and 1 deletions
+1 -1
View File
@@ -19,5 +19,5 @@ class StockQuant(models.Model):
def _get_removal_strategy_sort_key(self, removal_strategy):
if removal_strategy == 'fefo':
return lambda q: (q.removal_date, q.in_date, q.id), False
return lambda q: (q.removal_date or fields.datetime.max, q.in_date, q.id), False
return super()._get_removal_strategy_sort_key(removal_strategy)
@@ -615,3 +615,39 @@ class TestStockLot(TestStockCommon):
picking_out.action_confirm()
picking_out.action_assign()
self.assertEqual(picking_out.move_ids.state, 'assigned', 'Wrong state of move line.')
def test_no_lot(self):
"""
Try to reserve a move that for an expirable product that has both quants with and without lot attached.
"""
# Set the removal strategy to 'First Expiry First Out'
fefo_strategy = self.env['product.removal'].search(
[('method', '=', 'fefo')])
self.apple_product.categ_id.removal_strategy_id = fefo_strategy.id
apple_lot = self.LotObj.create({
'name': 'LOT001',
'product_id': self.apple_product.id,
'company_id': self.env.company.id,
})
self.StockQuantObj.with_context(inventory_mode=True).create([{
'product_id': self.apple_product.id,
'location_id': self.stock_location,
'quantity': 100,
}, {
'product_id': self.apple_product.id,
'location_id': self.stock_location,
'quantity': 100,
'lot_id': apple_lot.id,
}])
with Form(self.PickingObj) as picking_form:
picking_form.picking_type_id = self.env.ref('stock.picking_type_out')
with picking_form.move_ids_without_package.new() as move:
move.product_id = self.apple_product
move.product_uom_qty = 10
picking_out = picking_form.save()
picking_out.action_assign()
self.assertEqual(picking_out.move_line_ids.lot_id, apple_lot)