diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index 587271f386..a4e1df9333 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -530,27 +530,21 @@ def send_expiry_warnings(sender, **kwargs): @receiver(signal=periodic_task) def send_download_reminders(sender, **kwargs): - eventcache = {} - today = now().replace(hour=0, minute=0, second=0) + today = now().replace(hour=0, minute=0, second=0, microsecond=0) for e in Event.objects.filter(date_from__gte=today): - eventsettings = eventcache.get(e.pk, None) - if eventsettings is None: - eventsettings = e.settings - eventcache[e.pk] = eventsettings - - days = eventsettings.get('mail_days_download_reminder', as_type=int) - if days is not None: + days = e.settings.get('mail_days_download_reminder', as_type=int) + if days is None: continue - reminder_date = (e.date_from - timedelta(days=days)).replace(hour=0, minute=0, second=0) + reminder_date = (e.date_from - timedelta(days=days)).replace(hour=0, minute=0, second=0, microsecond=0) - if (today > reminder_date): + if now() < reminder_date: continue - for o in e.orders.filter(status="paid", download_reminder_sent=False): + for o in e.orders.filter(status=Order.STATUS_PAID, download_reminder_sent=False): o.download_reminder_sent = True o.save() - email_template = eventsettings.mail_text_download_reminder + email_template = e.settings.mail_text_download_reminder email_context = { 'event': o.event.name, 'url': build_absolute_uri(o.event, 'presale:event.order', kwargs={ diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index b09e133b8b..5437c4ec34 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -373,7 +373,8 @@ Your {event} team""")) you bought a ticket for {event}. -This is to remind you that your ticket is ready for downloading! +If you did not do so already, you can download your ticket here: +{url} Best regards, Your {event} team""")) diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 9dd8d8ce77..35d1e0c7d5 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -638,6 +638,13 @@ class MailSettingsForm(SettingsForm): help_text=_("Available placeholders: {event}, {url}"), validators=[PlaceholderValidator(['{event}', '{url}'])] ) + mail_days_download_reminder = forms.IntegerField( + label=_("Number of days"), + required=False, + min_value=0, + help_text=_("This email will be sent out this many days before the order event starts. If the " + "field is empty, the mail will never be sent.") + ) smtp_use_custom = forms.BooleanField( label=_("Use custom SMTP server"), help_text=_("All mail related to your event will be sent over the smtp server specified by you."), diff --git a/src/pretix/control/templates/pretixcontrol/event/mail.html b/src/pretix/control/templates/pretixcontrol/event/mail.html index dbb898bfc4..99c756730c 100644 --- a/src/pretix/control/templates/pretixcontrol/event/mail.html +++ b/src/pretix/control/templates/pretixcontrol/event/mail.html @@ -43,7 +43,7 @@ {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="custom_mail" title=title_order_custom_mail items="mail_text_order_custom_mail" %} {% blocktrans asvar title_download_tickets_reminder %}Reminder to download tickets{% endblocktrans %} - {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="ticket_reminder" title=title_download_tickets_reminder items="mail_text_download_reminder" %} + {% include "pretixcontrol/event/mail_settings_fragment.html" with pid="ticket_reminder" title=title_download_tickets_reminder items="mail_days_download_reminder,mail_text_download_reminder" exclude="mail_days_download_reminder" %}
diff --git a/src/tests/base/test_orders.py b/src/tests/base/test_orders.py index ff6bf34994..021d28ef6b 100644 --- a/src/tests/base/test_orders.py +++ b/src/tests/base/test_orders.py @@ -3,6 +3,7 @@ from decimal import Decimal import pytest import pytz +from django.core import mail as djmail from django.test import TestCase from django.utils.timezone import make_aware, now @@ -16,6 +17,7 @@ from pretix.base.reldate import RelativeDate, RelativeDateWrapper from pretix.base.services.invoices import generate_invoice from pretix.base.services.orders import ( OrderChangeManager, OrderError, _create_order, expire_orders, + send_download_reminders, ) @@ -178,6 +180,55 @@ def test_expiring_auto_disabled(event): assert o2.status == Order.STATUS_PENDING +class DownloadReminderTests(TestCase): + def setUp(self): + super().setUp() + o = Organizer.objects.create(name='Dummy', slug='dummy') + self.event = Event.objects.create( + organizer=o, name='Dummy', slug='dummy', + date_from=now() + timedelta(days=2), + plugins='pretix.plugins.banktransfer' + ) + self.order = Order.objects.create( + code='FOO', event=self.event, email='dummy@dummy.test', + status=Order.STATUS_PAID, locale='en', + datetime=now(), + expires=now() + timedelta(days=10), + total=Decimal('46.00'), payment_provider='banktransfer' + ) + self.ticket = Item.objects.create(event=self.event, name='Early-bird ticket', tax_rate=Decimal('7.00'), + default_price=Decimal('23.00'), admission=True) + self.op1 = OrderPosition.objects.create( + order=self.order, item=self.ticket, variation=None, + price=Decimal("23.00"), attendee_name="Peter", positionid=1 + ) + djmail.outbox = [] + + def test_disabled(self): + send_download_reminders(sender=self.event) + assert len(djmail.outbox) == 0 + + def test_sent_once(self): + self.event.settings.mail_days_download_reminder = 2 + send_download_reminders(sender=self.event) + assert len(djmail.outbox) == 1 + assert djmail.outbox[0].to == ['dummy@dummy.test'] + send_download_reminders(sender=self.event) + assert len(djmail.outbox) == 1 + + def test_sent_paid_only(self): + self.event.settings.mail_days_download_reminder = 2 + self.order.status = Order.STATUS_PENDING + self.order.save() + send_download_reminders(sender=self.event) + assert len(djmail.outbox) == 0 + + def test_not_sent_too_early(self): + self.event.settings.mail_days_download_reminder = 1 + send_download_reminders(sender=self.event) + assert len(djmail.outbox) == 0 + + class OrderChangeManagerTests(TestCase): def setUp(self): super().setUp()