From c890f4cdc09eee8dfbe4de3c2d7a7aa5dc512a38 Mon Sep 17 00:00:00 2001
From: Michael Stapelberg
Date: Mon, 17 Apr 2023 09:38:36 +0200
Subject: [PATCH] Sendmail: Add option to attach calendar invites (#3224)
---
src/pretix/plugins/sendmail/forms.py | 6 +++++-
.../migrations/0003_rule_attach_ical.py | 18 ++++++++++++++++++
src/pretix/plugins/sendmail/models.py | 8 ++++++++
src/pretix/plugins/sendmail/tasks.py | 5 ++++-
.../pretixplugins/sendmail/rule_create.html | 3 +++
.../pretixplugins/sendmail/rule_update.html | 3 +++
.../pretixplugins/sendmail/send_form.html | 9 +++++++++
src/pretix/plugins/sendmail/views.py | 3 +++
8 files changed, 53 insertions(+), 2 deletions(-)
create mode 100644 src/pretix/plugins/sendmail/migrations/0003_rule_attach_ical.py
diff --git a/src/pretix/plugins/sendmail/forms.py b/src/pretix/plugins/sendmail/forms.py
index 52f96a3a9..500be2e80 100644
--- a/src/pretix/plugins/sendmail/forms.py
+++ b/src/pretix/plugins/sendmail/forms.py
@@ -218,6 +218,10 @@ class OrderMailForm(BaseMailForm):
help_text=_("Will be ignored if tickets exceed a given size limit to ensure email deliverability."),
required=False
)
+ attach_ical = forms.BooleanField(
+ label=_("Attach calendar files"),
+ required=False
+ )
def clean(self):
d = super().clean()
@@ -305,7 +309,7 @@ class RuleForm(FormPlaceholderMixin, I18nModelForm):
class Meta:
model = Rule
- fields = ['subject', 'template',
+ fields = ['subject', 'template', 'attach_ical',
'send_date', 'send_offset_days', 'send_offset_time',
'include_pending', 'all_products', 'limit_products',
'send_to', 'enabled']
diff --git a/src/pretix/plugins/sendmail/migrations/0003_rule_attach_ical.py b/src/pretix/plugins/sendmail/migrations/0003_rule_attach_ical.py
new file mode 100644
index 000000000..784ca394f
--- /dev/null
+++ b/src/pretix/plugins/sendmail/migrations/0003_rule_attach_ical.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.18 on 2023-04-13 21:39
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('sendmail', '0002_rule_enabled'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='rule',
+ name='attach_ical',
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/src/pretix/plugins/sendmail/models.py b/src/pretix/plugins/sendmail/models.py
index 191f7cd5d..18e53afbe 100644
--- a/src/pretix/plugins/sendmail/models.py
+++ b/src/pretix/plugins/sendmail/models.py
@@ -153,6 +153,7 @@ class ScheduledMail(models.Model):
email_ctx = get_email_context(event=e, order=o, invoice_address=ia)
try:
o.send_mail(self.rule.subject, self.rule.template, email_ctx,
+ attach_ical=self.rule.attach_ical,
log_entry_type='pretix.plugins.sendmail.rule.order.email.sent')
o_sent = True
except SendMailException:
@@ -169,10 +170,12 @@ class ScheduledMail(models.Model):
if p.attendee_email and (p.attendee_email != o.email or not o_sent):
email_ctx = get_email_context(event=e, order=o, invoice_address=ia, position=p)
p.send_mail(self.rule.subject, self.rule.template, email_ctx,
+ attach_ical=self.rule.attach_ical,
log_entry_type='pretix.plugins.sendmail.rule.order.position.email.sent')
elif not o_sent and o.email:
email_ctx = get_email_context(event=e, order=o, invoice_address=ia)
o.send_mail(self.rule.subject, self.rule.template, email_ctx,
+ attach_ical=self.rule.attach_ical,
log_entry_type='pretix.plugins.sendmail.rule.order.email.sent')
o_sent = True
except SendMailException:
@@ -207,6 +210,11 @@ class Rule(models.Model, LoggingMixin):
help_text=_('By default, only paid orders will receive the email')
)
+ attach_ical = models.BooleanField(
+ default=False,
+ verbose_name=_("Attach calendar files"),
+ )
+
# either send_date or send_offset_* have to be set
send_date = models.DateTimeField(null=True, blank=True, verbose_name=_('Send date'))
send_offset_days = models.IntegerField(null=True, blank=True, verbose_name=_('Number of days'))
diff --git a/src/pretix/plugins/sendmail/tasks.py b/src/pretix/plugins/sendmail/tasks.py
index af04f369d..d224dc263 100644
--- a/src/pretix/plugins/sendmail/tasks.py
+++ b/src/pretix/plugins/sendmail/tasks.py
@@ -46,7 +46,8 @@ from pretix.helpers.format import format_map
@app.task(base=ProfiledEventTask, acks_late=True)
def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, objects: list, items: list,
recipients: str, filter_checkins: bool, not_checked_in: bool, checkin_lists: list,
- attachments: list = None, attach_tickets: bool = False) -> None:
+ attachments: list = None, attach_tickets: bool = False,
+ attach_ical: bool = False) -> None:
failures = []
user = User.objects.get(pk=user) if user else None
orders = Order.objects.filter(pk__in=objects, event=event)
@@ -110,6 +111,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
order=o,
position=p,
attach_tickets=attach_tickets,
+ attach_ical=attach_ical,
attach_cached_files=attachments
)
o.log_action(
@@ -138,6 +140,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
locale=o.locale,
order=o,
attach_tickets=attach_tickets,
+ attach_ical=attach_ical,
attach_cached_files=attachments,
)
o.log_action(
diff --git a/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html b/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html
index a34e1dc92..ca510197a 100644
--- a/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html
+++ b/src/pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html
@@ -20,6 +20,9 @@
{% bootstrap_field form.subject layout='control' %}
{% bootstrap_field form.template layout='control' %}
+ {% if form.attach_ical %}
+ {% bootstrap_field form.attach_ical layout='horizontal' %}
+ {% endif %}
{% if is_preview %}
{% endif %}
+ {% if form.cleaned_data.attach_ical %}
+
+
+ {% trans "Attach calendar files" %}
+
+ {% endif %}
{% endfor %}
diff --git a/src/pretix/plugins/sendmail/views.py b/src/pretix/plugins/sendmail/views.py
index f173d5547..1ab67cb55 100644
--- a/src/pretix/plugins/sendmail/views.py
+++ b/src/pretix/plugins/sendmail/views.py
@@ -330,6 +330,8 @@ class OrderSendView(BaseSenderView):
initial['created_to'] = dateutil.parser.parse(logentry.parsed_data['created_to'])
if logentry.parsed_data.get('attach_tickets'):
initial['attach_tickets'] = logentry.parsed_data['attach_tickets']
+ if logentry.parsed_data.get('attach_ical'):
+ initial['attach_ical'] = logentry.parsed_data['attach_ical']
if logentry.parsed_data.get('subevent'):
try:
initial['subevent'] = self.request.event.subevents.get(
@@ -425,6 +427,7 @@ class OrderSendView(BaseSenderView):
'checkin_lists': [i.pk for i in form.cleaned_data.get('checkin_lists')],
'filter_checkins': form.cleaned_data.get('filter_checkins'),
'attach_tickets': form.cleaned_data.get('attach_tickets'),
+ 'attach_ical': form.cleaned_data.get('attach_ical'),
})
return kwargs