Skip to content

Commit 4706ecf

Browse files
committed
[IMP] event: mailing amdi updates
The slot scheduled dates are in utc, not in the event tz. Archive slot mailing when the slot is archived to prevent them being send. Task-4307566
1 parent c17e0a1 commit 4706ecf

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

addons/event/models/event_mail.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -305,14 +305,14 @@ def _refresh_mail_count_done(self, mail_slot=False):
305305
elif mail_slot and mail_slot.last_registration_id:
306306
total_sent = self.env["event.registration"].search_count([
307307
("id", "<=", mail_slot.last_registration_id.id),
308-
("event_id", "=", self.event_id.id),
308+
("event_id", "=", scheduler.event_id.id),
309309
("event_slot_id", "=", mail_slot.event_slot_id.id),
310310
("state", "not in", ["draft", "cancel"]),
311311
])
312312
mail_slot.mail_count_done = total_sent
313313
mail_slot.mail_done = total_sent >= mail_slot.event_slot_id.seats_taken
314-
self.mail_count_done = sum(self.mail_slot_ids.mapped('mail_count_done'))
315-
self.mail_done = total_sent >= self.event_id.seats_taken
314+
scheduler.mail_count_done = sum(scheduler.mail_slot_ids.mapped('mail_count_done'))
315+
scheduler.mail_done = total_sent >= scheduler.event_id.seats_taken
316316
elif scheduler.last_registration_id:
317317
total_sent = self.env["event.registration"].search_count([
318318
("id", "<=", self.last_registration_id.id),

addons/event/models/event_mail_slot.py

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class EventMailRegistration(models.Model):
1212
_rec_name = 'scheduler_id'
1313
_order = 'scheduled_date DESC, id ASC'
1414

15+
active = fields.Boolean("Active", default=True)
1516
event_slot_id = fields.Many2one('event.slot', 'Slot', ondelete='cascade', required=True)
1617
error_datetime = fields.Datetime('Last Error')
1718
scheduled_date = fields.Datetime('Schedule Date', compute='_compute_scheduled_date', store=True)

addons/event/models/event_slot.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class EventSlot(models.Model):
2828
end_hour = fields.Float("Ending Hour", required=True, default=12.0, help="Expressed in the event timezone.")
2929
start_datetime = fields.Datetime("Start Datetime", compute="_compute_datetimes", store=True)
3030
end_datetime = fields.Datetime("End Datetime", compute="_compute_datetimes", store=True)
31+
slot_mail_ids = fields.One2many("event.mail.slot", "event_slot_id", string="Mail Schedule", copy=True)
3132

3233
# Registrations
3334
is_sold_out = fields.Boolean(
@@ -140,14 +141,15 @@ def _compute_seats(self):
140141
slot.seats_taken = slot.seats_reserved + slot.seats_used
141142

142143
def unlink(self):
143-
""" Archive the slot instead of deleting it if it's linked to existing registrations.
144-
This allows an easier slots management from the calendar view (can unlink a slot without validation errors).
145-
The slot cannot be registered to anymore and its related registrations are also archived as
146-
they're now considered unrelevant.
144+
""" Archive the slot instead of deleting it if it's linked to existing
145+
registrations from a direct relation or from its related slot tickets.
146+
Archive the related slot tickets to prevent any further registrations.
147+
Also archive the existing registrations and scheduled mailings as they're not relevant anymore.
147148
"""
148149
slots_w_registrations = self.filtered(lambda slot: slot.registration_ids)
149-
slots_w_registrations.action_archive()
150150
slots_w_registrations.registration_ids.action_archive()
151+
slots_w_registrations.slot_mail_ids.action_archive()
152+
slots_w_registrations.action_archive()
151153
return super(EventSlot, self - slots_w_registrations).unlink()
152154

153155
@staticmethod

addons/event/tests/test_event_mail_schedule.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from odoo import exceptions
1010
from odoo.addons.base.tests.test_ir_cron import CronMixinCase
1111
from odoo.addons.event.tests.common import EventCase
12+
from odoo.addons.event.models.event_mail import EventMail
1213
from odoo.addons.mail.tests.common import MailCase
1314
from odoo.tests import tagged, users, warmup
1415
from odoo.tools import formataddr, mute_logger
@@ -47,7 +48,7 @@ def setUpClass(cls):
4748
cls._setup_test_reports()
4849
with cls.mock_datetime_and_now(cls, cls.reference_now):
4950
# create with admin to force create_date
50-
cls.test_event = cls.env['event.event'].create({
51+
cls.test_event = cls.env['event.event'].with_user(cls.user_eventmanager).create({
5152
'name': 'TestEventMail',
5253
'user_id': cls.user_eventmanager.id,
5354
'date_begin': cls.event_date_begin,
@@ -635,6 +636,8 @@ def test_event_mail_schedule_on_slot(self):
635636
test_event = self.test_event.with_env(self.env)
636637
test_event.write({
637638
'is_multi_slots': True,
639+
# Start and end hours expressed in event tz
640+
# The slots datetimes will be saved in utc
638641
'event_slot_ids': [
639642
(0, 0, {
640643
'date': self.event_date_end.date() - relativedelta(days=1),
@@ -648,12 +651,14 @@ def test_event_mail_schedule_on_slot(self):
648651
}),
649652
],
650653
})
654+
# Verify datetimes in UTC
655+
self.assertEqual(test_event.date_tz, 'Europe/Brussels')
651656
self.assertEqual(
652657
test_event.event_slot_ids.mapped('start_datetime'),
653-
[datetime(2021, 3, 23, 8, 0, 0), datetime(2021, 3, 24, 8, 0, 0)])
658+
[datetime(2021, 3, 23, 7, 0, 0), datetime(2021, 3, 24, 7, 0, 0)])
654659
self.assertEqual(
655660
test_event.event_slot_ids.mapped('end_datetime'),
656-
[datetime(2021, 3, 23, 18, 0, 0), datetime(2021, 3, 24, 18, 0, 0)])
661+
[datetime(2021, 3, 23, 17, 0, 0), datetime(2021, 3, 24, 17, 0, 0)])
657662

658663
# create some registrations (even wrong registrations without slot)
659664
with self.mock_datetime_and_now(self.reference_now):
@@ -686,13 +691,12 @@ def test_event_mail_schedule_on_slot(self):
686691
self.assertFalse(mail_slot.mail_count_done)
687692
self.assertFalse(mail_slot.mail_done)
688693
mail_slot_1 = event_prev_scheduler.mail_slot_ids.filtered(lambda s: s.event_slot_id.date == self.event_date_end.date() - relativedelta(days=1))
689-
self.assertEqual(mail_slot_1.scheduled_date, datetime(2021, 3, 22, 8, 0, 0))
694+
self.assertEqual(mail_slot_1.scheduled_date, datetime(2021, 3, 22, 7, 0, 0))
690695
mail_slot_2 = event_prev_scheduler.mail_slot_ids.filtered(lambda s: s.event_slot_id.date == self.event_date_end.date())
691-
self.assertEqual(mail_slot_2.scheduled_date, datetime(2021, 3, 23, 8, 0, 0))
696+
self.assertEqual(mail_slot_2.scheduled_date, datetime(2021, 3, 23, 7, 0, 0))
692697

693698
# execute cron to run scheduler on first slot
694-
slot1_before_oneday = datetime(2021, 3, 23, 8, 0, 0) - relativedelta(days=1)
695-
EventMail = type(self.env['event.mail'])
699+
slot1_before_oneday = datetime(2021, 3, 23, 7, 0, 0) - relativedelta(days=1)
696700
exec_origin = EventMail._execute_event_based_for_registrations
697701
with patch.object(
698702
EventMail, '_execute_event_based_for_registrations', autospec=True, wraps=EventMail, side_effect=exec_origin,
@@ -716,6 +720,27 @@ def test_event_mail_schedule_on_slot(self):
716720
self.assertFalse(event_prev_scheduler.mail_done)
717721
self.assertSchedulerCronTriggers(capture, [slot1_before_oneday])
718722

723+
# deleting a slot with registrations archives it and prevents its mailings to be send
724+
first_slot = test_event.event_slot_ids[0]
725+
first_slot.unlink()
726+
self.assertFalse(first_slot.active)
727+
for mail_slot in first_slot.slot_mail_ids:
728+
self.assertFalse(mail_slot.active)
729+
730+
slot1_before_oneday_archived = datetime(2021, 3, 23, 7, 0, 0) - relativedelta(days=1)
731+
exec_origin = EventMail._execute_event_based_for_registrations
732+
with patch.object(
733+
EventMail, '_execute_event_based_for_registrations', autospec=True, wraps=EventMail, side_effect=exec_origin,
734+
) as mock_exec:
735+
capture = self.execute_event_cron(freeze_date=slot1_before_oneday_archived)
736+
737+
# mailing hasn't been sent, info should stay the same
738+
self.assertEqual(mail_slot_1.mail_count_done, 4)
739+
self.assertFalse(mail_slot_1.mail_done)
740+
self.assertEqual(event_prev_scheduler.mail_count_done, 4)
741+
self.assertFalse(event_prev_scheduler.mail_done)
742+
self.assertSchedulerCronTriggers(capture, [])
743+
719744
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')
720745
@users('user_eventmanager')
721746
@warmup

0 commit comments

Comments
 (0)