From f0182a0b16b0a3a61aec228e4bb34e1696f3a98b Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Fri, 10 May 2019 13:17:22 +0000 Subject: [PATCH] [FIX] product_expiry: activities generation This commit improves the performance of product expiry activities generation. It also removes direct refs to activity types to ensure code stability in case of user deletion of system data. The xml refs to activity types should only be used through mail methods to ensure fallback strategies can be managed in the mail module only. closes odoo/odoo#33300 Signed-off-by: Thibault Delavallee (tde) --- .../product_expiry/models/production_lot.py | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/addons/product_expiry/models/production_lot.py b/addons/product_expiry/models/production_lot.py index bb40157dc76..a37f44de93c 100644 --- a/addons/product_expiry/models/production_lot.py +++ b/addons/product_expiry/models/production_lot.py @@ -16,6 +16,7 @@ class StockProductionLot(models.Model): alert_date = fields.Datetime(string='Alert Date', help='Date to determine the expired lots and serial numbers using the filter "Expiration Alerts".') product_expiry_alert = fields.Boolean(compute='_compute_product_expiry_alert', help="The Alert Date has been reached.") + product_expiry_reminded = fields.Boolean(string="Expiry has been reminded") @api.depends('alert_date') def _compute_product_expiry_alert(self): @@ -58,31 +59,31 @@ class StockProductionLot(models.Model): @api.model def _alert_date_exceeded(self): - # if the alert_date is in the past and the lot is linked to an internal quant - # log a next activity on the next.production.lot - alert_lot_ids = self.env['stock.production.lot'].search([('alert_date', '<=', fields.Date.today())]) - mail_activity_type = self.env.ref('product_expiry.mail_activity_type_alert_date_reached').id - stock_quants = self.env['stock.quant'].search([ - ('lot_id', 'in', alert_lot_ids.ids), - ('quantity', '>', 0)]).filtered(lambda quant: quant.location_id.usage == 'internal' ) - lots = stock_quants.mapped('lot_id') + """Log an activity on internally stored lots whose alert_date has been reached. + + No further activity will be generated on lots whose alert_date + has already been reached (even if the alert_date is changed). + """ + alert_lots = self.env['stock.production.lot'].search([ + ('alert_date', '<=', fields.Date.today()), + ('product_expiry_reminded', '=', False)]) + + lot_stock_quants = self.env['stock.quant'].search([ + ('lot_id', 'in', alert_lots.ids), + ('quantity', '>', 0), + ('location_id.usage', '=', 'internal')]) + alert_lots = lot_stock_quants.mapped('lot_id') + + for lot in alert_lots: + lot.activity_schedule( + 'product_expiry.mail_activity_type_alert_date_reached', + user_id=lot.product_id.responsible_id.id or SUPERUSER_ID, + note=_("The alert date has been reached for this lot/serial number") + ) + alert_lots.write({ + 'product_expiry_reminded': True + }) - # only for lots that do not have already an activity - # or that do not have a done alert activity, i.e. a mail.message - lots = lots.filtered(lambda lot: - not self.env['mail.activity'].search_count([ - ('res_model', '=', 'stock.production.lot'), - ('res_id', '=', lot.id), - ('activity_type_id','=', mail_activity_type)]) - and not self.env['mail.message'].search_count([ - ('model', '=', 'stock.production.lot'), - ('res_id', '=', lot.id), - ('subtype_id', '=', self.env.ref('mail.mt_activities').id), - ('mail_activity_type_id','=', mail_activity_type)])) - for lot in lots: - lot.activity_schedule('product_expiry.mail_activity_type_alert_date_reached', - user_id=lot.product_id.responsible_id.id or SUPERUSER_ID, note=_("The alert date has been reached for this lot/serial number") - ) class ProcurementGroup(models.Model): _inherit = 'procurement.group'