Scheduled emails: Extend filter by subevents (Z#23122902) (#3551)

To create automated mail rules for specific subevents only, this adds a selection widget to choose which, only appearing if there are any subevents to select.
This commit is contained in:
Phin Wolkwitz
2023-09-06 12:05:37 +02:00
committed by GitHub
parent 8913d35838
commit 991f245dce
7 changed files with 127 additions and 10 deletions

View File

@@ -309,8 +309,8 @@ class RuleForm(FormPlaceholderMixin, I18nModelForm):
class Meta:
model = Rule
fields = ['subject', 'template', 'attach_ical',
'send_date', 'send_offset_days', 'send_offset_time',
fields = ['subject', 'template', 'attach_ical', 'send_date',
'send_offset_days', 'send_offset_time', 'subevent',
'all_products', 'limit_products', 'restrict_to_status',
'checked_in_status', 'send_to', 'enabled']
@@ -359,6 +359,29 @@ class RuleForm(FormPlaceholderMixin, I18nModelForm):
super().__init__(*args, **kwargs)
self.fields['subevent'] = forms.ModelChoiceField(
SubEvent.objects.none(),
label=pgettext_lazy('sendmail_form', 'Restrict to a specific event date'),
required=False,
empty_label=pgettext_lazy('subevent', 'All dates')
)
if self.event.has_subevents:
self.fields['subevent'].queryset = self.event.subevents.all()
self.fields['subevent'].widget = Select2(
attrs={
'data-model-select2': 'event',
'data-select2-url': reverse('control:event.subevents.select2', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
}),
'data-placeholder': pgettext_lazy('subevent', 'Date')
}
)
self.fields['subevent'].widget.choices = self.fields['subevent'].choices
else:
del self.fields['subevent']
self.fields['limit_products'].queryset = Item.objects.filter(event=self.event)
self.fields['schedule_type'] = forms.ChoiceField(

View File

@@ -0,0 +1,24 @@
# Generated by Django 4.2.4 on 2023-08-29 15:31
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sendmail', '0005_rule_checked_in_status'),
]
operations = [
migrations.AddField(
model_name='rule',
name='subevent',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pretixbase.subevent'),
),
migrations.AlterField(
model_name='rule',
name='checked_in_status',
field=models.CharField(default=None, max_length=10, null=True),
),
]

View File

@@ -227,6 +227,7 @@ class Rule(models.Model, LoggingMixin):
id = models.BigAutoField(primary_key=True)
event = models.ForeignKey(Event, on_delete=models.CASCADE, related_name='sendmail_rules')
subevent = models.ForeignKey(SubEvent, null=True, on_delete=models.PROTECT)
subject = I18nCharField(max_length=255, verbose_name=_('Subject'))
template = I18nTextField(verbose_name=_('Message'))
@@ -278,16 +279,27 @@ class Rule(models.Model, LoggingMixin):
create_sms = []
if self.event.has_subevents:
for se in self.event.subevents.annotate(has_sm=Exists(ScheduledMail.objects.filter(
subevent=OuterRef('pk'), rule=self))).filter(has_sm=False):
sm = ScheduledMail(rule=self, subevent=se, event=self.event)
sm.recompute()
create_sms.append(sm)
if self.subevent:
ScheduledMail.objects.get_or_create(rule=self, subevent=self.subevent, event=self.event)
else:
for se in self.event.subevents.annotate(has_sm=Exists(ScheduledMail.objects.filter(
subevent=OuterRef('pk'), rule=self))).filter(has_sm=False):
sm = ScheduledMail(rule=self, subevent=se, event=self.event)
sm.recompute()
create_sms.append(sm)
ScheduledMail.objects.bulk_create(create_sms)
else:
ScheduledMail.objects.get_or_create(rule=self, event=self.event)
if not is_creation:
if self.subevent:
keep_states = [ScheduledMail.STATE_COMPLETED] # we keep rules where mails have already been sent
ScheduledMail.objects.filter(
Q(rule=self),
~Q(subevent=self.subevent),
~Q(state__in=keep_states)
).delete()
update_sms = []
for sm in self.scheduledmail_set.prefetch_related('event').select_related('subevent'):
if sm in create_sms:

View File

@@ -27,9 +27,12 @@
<fieldset>
<legend>{% trans "Recipients" %}</legend>
{% bootstrap_field form.send_to layout='control' %}
{% if form.subevent %}
{% bootstrap_field form.subevent layout='control' %}
{% endif %}
{% bootstrap_field form.restrict_to_status layout='control' %}
{% bootstrap_field form.checked_in_status layout='control' %}
<hr>
<hr>
{% bootstrap_field form.all_products layout='control' %}
{% bootstrap_field form.limit_products layout='horizontal' %}
</fieldset>

View File

@@ -47,7 +47,7 @@
<a href="{% url "control:event.subevent" organizer=request.event.organizer.slug event=request.event.slug subevent=sm.subevent.id %}?returnto={{ request.GET.urlencode|urlencode }}">
{{ sm.subevent.name }}
</a><br>
{{ sm.get_date_range_display }}
{{ sm.subevent.get_date_range_display }}
</td>
{% endif %}
<td>

View File

@@ -41,9 +41,12 @@
<fieldset>
<legend>{% trans "Recipients" %}</legend>
{% bootstrap_field form.send_to layout='control' %}
{% if form.subevent %}
{% bootstrap_field form.subevent layout='control' %}
{% endif %}
{% bootstrap_field form.restrict_to_status layout='control' %}
{% bootstrap_field form.checked_in_status layout='control' %}
<hr>
<hr>
{% bootstrap_field form.all_products layout='control' %}
{% bootstrap_field form.limit_products layout='horizontal' %}
</fieldset>