Odoo18-Base/addons/marketing_card/models/mailing_mailing.py
2025-01-06 10:57:38 +07:00

80 lines
3.7 KiB
Python

from odoo import _, api, exceptions, fields, models, osv
class MassMailing(models.Model):
_name = 'mailing.mailing'
_inherit = 'mailing.mailing'
mailing_model_id = fields.Many2one(compute="_compute_mailing_model_id", store=True, readonly=False)
card_requires_sync_count = fields.Integer(compute="_compute_card_requires_sync_count")
card_campaign_id = fields.Many2one('card.campaign')
@api.constrains('card_campaign_id', 'mailing_domain', 'mailing_model_id')
def _check_mailing_domain(self):
for mailing in self:
if mailing.card_campaign_id:
if mailing.sudo().mailing_model_id.model != mailing.card_campaign_id.res_model:
raise exceptions.ValidationError(_(
"Card Campaign Mailing should target model %(model_name)s",
model_name=self.env['ir.model']._get(mailing.card_campaign_id.res_model).display_name
))
@api.depends('card_campaign_id')
def _compute_mailing_model_id(self):
for mailing in self.filtered('card_campaign_id'):
mailing.mailing_model_id = self.env['ir.model']._get_id(mailing.card_campaign_id.res_model)
@api.depends('card_campaign_id')
def _compute_card_requires_sync_count(self):
"""Check if there's any missing or outdated card."""
self.card_requires_sync_count = 0
# no point in updating sent mailings
card_mailings = self.filtered(lambda mailing: mailing.card_campaign_id and mailing.state == 'draft')
for mailing in card_mailings:
recipients = self.env[mailing.mailing_model_real].search(self._parse_mailing_domain())
out_of_date_count = self.env['card.card'].search_count([
('campaign_id', '=', mailing.card_campaign_id.id),
('res_id', 'in', recipients.ids),
('requires_sync', '=', False)
])
mailing.card_requires_sync_count = len(recipients) - out_of_date_count
def action_put_in_queue(self):
"""Detect mismatches before scheduling."""
for mailing in self.filtered('card_campaign_id'):
if mailing.card_requires_sync_count:
raise exceptions.UserError(_(
'You should update all the cards for %(mailing)s before scheduling a mailing.',
mailing=mailing.display_name
))
super().action_put_in_queue()
def action_send_mail(self, res_ids=None):
for mailing in self.filtered('card_campaign_id'):
if mailing.card_requires_sync_count:
raise exceptions.UserError(_(
'You should update all the cards for %(mailing)s before scheduling a mailing.',
mailing=mailing.display_name
))
return super().action_send_mail(res_ids)
def action_update_cards(self):
"""Update the cards in batches, commiting after each batch."""
for campaign in self.filtered(lambda mailing: mailing.state == 'draft').card_campaign_id:
campaign._update_cards(self._parse_mailing_domain(), auto_commit=True)
return {
'type': 'ir.actions.act_window',
'res_model': 'mailing.mailing',
'res_id': self[0].id,
'view_mode': 'form',
'target': 'current',
}
def _get_recipients_domain(self):
"""Domain with an additional condition that the card must exist for the records."""
domain = super()._get_recipients_domain()
if self.card_campaign_id:
res_ids = self.env['card.card'].search_fetch([('campaign_id', '=', self.card_campaign_id.id)], ['res_id']).mapped('res_id')
domain = osv.expression.AND([domain, [('id', 'in', res_ids)]])
return domain