From e50dbe096d30e77697e447fd3bce803e6a1da7f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Voet=20=28ryv=29?= Date: Thu, 10 Dec 2020 09:50:33 +0000 Subject: [PATCH] [REF] stock: _gather use now the ORM Remove the feature of `NULL` order of stock.quant and put the `in_date` required because it is always set (and should). task-2413099 closes odoo/odoo#63165 Related: odoo/upgrade#2019 Signed-off-by: Arnold Moyaux --- addons/stock/models/stock_quant.py | 25 ++++++------------------- addons/stock/tests/test_quant.py | 28 ---------------------------- 2 files changed, 6 insertions(+), 47 deletions(-) diff --git a/addons/stock/models/stock_quant.py b/addons/stock/models/stock_quant.py index b4fe09f8066..58bbc5d0b69 100644 --- a/addons/stock/models/stock_quant.py +++ b/addons/stock/models/stock_quant.py @@ -92,7 +92,7 @@ class StockQuant(models.Model): 'Available Quantity', help="On hand quantity which hasn't been reserved on a transfer, in the default unit of measure of the product", compute='_compute_available_quantity') - in_date = fields.Datetime('Incoming Date', readonly=True) + in_date = fields.Datetime('Incoming Date', readonly=True, required=True, default=fields.Datetime.now()) tracking = fields.Selection(related='product_id.tracking', readonly=True) on_hand = fields.Boolean('On Hand', store=False, search='_search_on_hand') @@ -264,19 +264,16 @@ class StockQuant(models.Model): @api.model def _get_removal_strategy_order(self, removal_strategy): if removal_strategy == 'fifo': - return 'in_date ASC NULLS FIRST, id' + return 'in_date ASC, id' elif removal_strategy == 'lifo': - return 'in_date DESC NULLS LAST, id desc' + return 'in_date DESC, id DESC' raise UserError(_('Removal strategy %s not implemented.') % (removal_strategy,)) def _gather(self, product_id, location_id, lot_id=None, package_id=None, owner_id=None, strict=False): - self.env['stock.quant'].flush(['location_id', 'owner_id', 'package_id', 'lot_id', 'product_id']) - self.env['product.product'].flush(['virtual_available']) removal_strategy = self._get_removal_strategy(product_id, location_id) removal_strategy_order = self._get_removal_strategy_order(removal_strategy) - domain = [ - ('product_id', '=', product_id.id), - ] + + domain = [('product_id', '=', product_id.id)] if not strict: if lot_id: domain = expression.AND([[('lot_id', '=', lot_id.id)], domain]) @@ -291,17 +288,7 @@ class StockQuant(models.Model): domain = expression.AND([[('owner_id', '=', owner_id and owner_id.id or False)], domain]) domain = expression.AND([[('location_id', '=', location_id.id)], domain]) - # Copy code of _search for special NULLS FIRST/LAST order - self.check_access_rights('read') - query = self._where_calc(domain) - self._apply_ir_rules(query, 'read') - from_clause, where_clause, where_clause_params = query.get_sql() - where_str = where_clause and (" WHERE %s" % where_clause) or '' - query_str = 'SELECT "%s".id FROM ' % self._table + from_clause + where_str + " ORDER BY "+ removal_strategy_order - self._cr.execute(query_str, where_clause_params) - res = self._cr.fetchall() - # No uniquify list necessary as auto_join is not applied anyways... - return self.browse([x[0] for x in res]) + return self.search(domain, order=removal_strategy_order) @api.model def _get_available_quantity(self, product_id, location_id, lot_id=None, package_id=None, owner_id=None, strict=False, allow_negative=False): diff --git a/addons/stock/tests/test_quant.py b/addons/stock/tests/test_quant.py index a9259af0caa..b763ac96df1 100644 --- a/addons/stock/tests/test_quant.py +++ b/addons/stock/tests/test_quant.py @@ -598,34 +598,6 @@ class StockQuant(TransactionCase): # Removal strategy is LIFO, so lot1 should be received as it was received later. self.assertEqual(quants[0][0].lot_id.id, lot1.id) - def test_in_date_4b(self): - """ Check for LIFO and max with/without in_date that it handles the LIFO NULLS LAST well - """ - stock_location1 = self.env['stock.location'].create({ - 'name': 'Shelf 1', - 'location_id': self.stock_location.id - }) - stock_location2 = self.env['stock.location'].create({ - 'name': 'Shelf 2', - 'location_id': self.stock_location.id - }) - lifo_strategy = self.env['product.removal'].search([('method', '=', 'lifo')]) - self.stock_location.removal_strategy_id = lifo_strategy - - self.env['stock.quant'].create({ - 'product_id': self.product_serial.id, - 'location_id': stock_location1.id, - 'quantity': 1.0, - }) - - in_date_location2 = datetime.now() - self.env['stock.quant']._update_available_quantity(self.product_serial, stock_location2, 1.0, in_date=in_date_location2) - - quants = self.env['stock.quant']._update_reserved_quantity(self.product_serial, self.stock_location, 1) - - # Removal strategy is LIFO, so the one with date is the most recent one and should be selected - self.assertEqual(quants[0][0].location_id.id, stock_location2.id) - def test_in_date_5(self): """ Receive the same lot at different times, once they're in the same location, the quants are merged and only the earliest incoming date is kept.