File: mailing_mailing.py

package info (click to toggle)
odoo 18.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 878,716 kB
  • sloc: javascript: 927,937; python: 685,670; xml: 388,524; sh: 1,033; sql: 415; makefile: 26
file content (79 lines) | stat: -rw-r--r-- 3,829 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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