From da18c86117b5b98006e3e6789e756f545dc3a526 Mon Sep 17 00:00:00 2001 From: "Eteil Djoumatchoua(etdj)" Date: Mon, 11 Sep 2023 14:10:43 +0000 Subject: [PATCH] [FIX] stock: Enable searching on lot's product qunatity Steps: - In ``stock.production.lot`` list view, use the filter 'Expiration Alerts' Issue: Every lots with ``product_expiration_alert`` set to True are returned but also the ones with ``product_qty`` set to 0.0. Reason: The ``StockProductionLot.product_expiration_alert`` represents lots with expiration before or equal to the current date but don't consider the quantity of product on hand. Solution: After discussing with Thomas (THD), and Tiffany (TIC) the solution is to add a new custom search function on the compute field ``product_qty`` that will be used with the 'Expiration Alerts' filter to solve the problem. opw-3474622 closes odoo/odoo#137251 X-original-commit: 09f1a45ccbb8b463e7d9326a25c2b0b18173b133 Signed-off-by: Tiffany Chang (tic) Signed-off-by: Eteil Junior Djoumatchoua (etdj) --- addons/stock/models/stock_lot.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/addons/stock/models/stock_lot.py b/addons/stock/models/stock_lot.py index 6db3f15cdbb..e9496a12a02 100644 --- a/addons/stock/models/stock_lot.py +++ b/addons/stock/models/stock_lot.py @@ -4,10 +4,21 @@ from operator import attrgetter from re import findall as regex_findall, split as regex_split +import operator as py_operator + from odoo import _, api, fields, models from odoo.exceptions import UserError, ValidationError from odoo.osv import expression +OPERATORS = { + '<': py_operator.lt, + '>': py_operator.gt, + '<=': py_operator.le, + '>=': py_operator.ge, + '=': py_operator.eq, + '!=': py_operator.ne +} + class StockLot(models.Model): _name = 'stock.lot' @@ -33,7 +44,7 @@ class StockLot(models.Model): 'uom.uom', 'Unit of Measure', related='product_id.uom_id', store=True) quant_ids = fields.One2many('stock.quant', 'lot_id', 'Quants', readonly=True) - product_qty = fields.Float('Quantity', compute='_product_qty') + product_qty = fields.Float('Quantity', compute='_product_qty', search='_search_product_qty') note = fields.Html(string='Description') display_complete = fields.Boolean(compute='_compute_display_complete') company_id = fields.Many2one('res.company', 'Company', required=True, index=True, default=lambda self: self.env.company.id) @@ -165,6 +176,22 @@ class StockLot(models.Model): quants = lot.quant_ids.filtered(lambda q: q.location_id.usage == 'internal' or (q.location_id.usage == 'transit' and q.location_id.company_id)) lot.product_qty = sum(quants.mapped('quantity')) + def _search_product_qty(self, operator, value): + domain = [ + ('lot_id', '!=', False), + '|', ('location_id.usage', '=', 'internal'), + '&', ('location_id.usage', '=', 'transit'), ('location_id.company_id', '!=', False) + ] + lots_w_qty = { + id: qty for id, qty in map(lambda l: (l['lot_id'][0], l['quantity']), self.env['stock.quant'].read_group(domain=domain, fields=['quantity:sum'], groupby=['lot_id'])) + } + all_lots = self.env['stock.lot'].search([]) + ids = [] + for lot in all_lots: + if OPERATORS[operator](lots_w_qty.get(lot.id, 0), value): + ids.append(lot.id) + return [('id', 'in', ids)] + def action_lot_open_quants(self): self = self.with_context(search_default_lot_id=self.id, create=False) if self.user_has_groups('stock.group_stock_manager'):