[FIX] stock: filter on 'closest' strategy
Steps to reproduce: - Enable Storage locations - Add two lots in stock: - lot_shelf_2 in WH/Stock/Shelf 2 - lot_shelf_1 in WH/Stock/Shelf 1 - Enable the 'Closest Location' removal strategy on its product category - Create a delivery using this product and mark it as todo Issue: lot_shelf_2 will be selected even though it should take the one from Shelf 1. When filtering on the location, we need to filter on the location name instead of this is. Also, when creating a new quant on a product using the 'closest' location, the filter will create a traceback because it will try to filter on a NewId. closes odoo/odoo#140175 Signed-off-by: William Henrotin (whe) <whe@odoo.com>
This commit is contained in:
@@ -741,7 +741,7 @@ class StockQuant(models.Model):
|
||||
if removal_strategy == 'lifo':
|
||||
reverse = True
|
||||
elif removal_strategy == 'closest':
|
||||
key = lambda q: (q.location_id, -q.id)
|
||||
key = lambda q: (q.location_id.complete_name, -q.id)
|
||||
return key, reverse
|
||||
|
||||
def _get_gather_domain(self, product_id, location_id, lot_id=None, package_id=None, owner_id=None, strict=False):
|
||||
@@ -770,7 +770,7 @@ class StockQuant(models.Model):
|
||||
removal_strategy = self._get_removal_strategy(product_id, location_id)
|
||||
domain = self._get_gather_domain(product_id, location_id, lot_id, package_id, owner_id, strict)
|
||||
domain, order = self._get_removal_strategy_domain_order(domain, removal_strategy, qty)
|
||||
if self:
|
||||
if self.ids:
|
||||
sort_key = self._get_removal_strategy_sort_key(removal_strategy)
|
||||
res = self.filtered_domain(domain).sorted(key=sort_key[0], reverse=sort_key[1])
|
||||
else:
|
||||
|
||||
@@ -5,7 +5,7 @@ from datetime import datetime, timedelta
|
||||
from unittest.mock import patch
|
||||
from ast import literal_eval
|
||||
|
||||
from odoo import fields
|
||||
from odoo import Command, fields
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import Form, TransactionCase
|
||||
@@ -625,6 +625,10 @@ class StockQuant(TransactionCase):
|
||||
""" Check that the Closest location strategy correctly applies when you have multiple lot received
|
||||
at different locations for a tracked product.
|
||||
"""
|
||||
# Enable multi-locations to be able to set an origin location for delivery
|
||||
grp_multi_loc = self.env.ref('stock.group_stock_multi_locations')
|
||||
self.env.user.write({'groups_id': [Command.link(grp_multi_loc.id)]})
|
||||
|
||||
closest_strategy = self.env['product.removal'].search([('method', '=', 'closest')])
|
||||
self.stock_location.removal_strategy_id = closest_strategy
|
||||
lot1 = self.env['stock.lot'].create({
|
||||
@@ -638,14 +642,22 @@ class StockQuant(TransactionCase):
|
||||
'company_id': self.env.company.id,
|
||||
})
|
||||
in_date = datetime.now()
|
||||
# Add a product from lot1 in stock_location/subloc2
|
||||
self.env['stock.quant']._update_available_quantity(self.product_serial, self.stock_subloc2, 1.0, lot_id=lot1, in_date=in_date)
|
||||
# Add a product from lot2 in stock_location/subloc3
|
||||
self.env['stock.quant']._update_available_quantity(self.product_serial, self.stock_subloc3, 1.0, lot_id=lot2, in_date=in_date)
|
||||
# Require one unit of the product
|
||||
quants = self.env['stock.quant']._get_reserve_quantity(self.product_serial, self.stock_location, 1)
|
||||
# Default removal strategy is 'Closest location', so lot1 should be received as it was put in a closer location. (stock_location/subloc2 < stock_location/subloc3)
|
||||
self.assertEqual(quants[0][0].lot_id.id, lot1.id)
|
||||
# Add a product from lot1 in stock_location/subloc3
|
||||
self.env['stock.quant']._update_available_quantity(self.product_serial, self.stock_subloc3, 1.0, lot_id=lot1, in_date=in_date)
|
||||
# Add a product from lot2 in stock_location/subloc2
|
||||
self.env['stock.quant']._update_available_quantity(self.product_serial, self.stock_subloc2, 1.0, lot_id=lot2, in_date=in_date)
|
||||
# Require one unit of the product for a delivery
|
||||
with Form(self.env['stock.picking']) as picking_form:
|
||||
picking_form.picking_type_id = self.env.ref('stock.picking_type_out')
|
||||
picking_form.location_id = self.stock_location
|
||||
with picking_form.move_ids_without_package.new() as move_form:
|
||||
move_form.product_id = self.product_serial
|
||||
move_form.product_uom_qty = 1
|
||||
picking = picking_form.save()
|
||||
picking.action_confirm()
|
||||
|
||||
# Default removal strategy is 'Closest location', so lot2 should be received as it was put in a closer location. (stock_location/subloc2 < stock_location/subloc3)
|
||||
self.assertEqual(picking.move_ids.lot_ids.id, lot2.id)
|
||||
|
||||
def test_closest_removal_strategy_untracked(self):
|
||||
""" Check that the Closest location strategy correctly applies when you have multiple products received
|
||||
|
||||
Reference in New Issue
Block a user