[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) <tde@openerp.com>
This commit is contained in:
Victor Feyens
2019-05-15 09:13:40 +00:00
parent 46954178a9
commit f0182a0b16
+25 -24
View File
@@ -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'