[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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user