mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
Sendmail rules: Add warnings and scheduling view (#2328)
This commit is contained in:
@@ -22739,7 +22739,7 @@ msgstr "Neue Regel erstellen"
|
||||
|
||||
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:24
|
||||
msgid "Email subject"
|
||||
msgstr "E-Mail wurde verschickt"
|
||||
msgstr "E-Mail-Betreff"
|
||||
|
||||
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:26
|
||||
msgid "Scheduled time"
|
||||
|
||||
@@ -45,10 +45,10 @@ class ScheduledMail(models.Model):
|
||||
STATE_MISSED = 'missed'
|
||||
|
||||
STATE_CHOICES = [
|
||||
(STATE_SCHEDULED, STATE_SCHEDULED),
|
||||
(STATE_FAILED, STATE_FAILED),
|
||||
(STATE_COMPLETED, STATE_COMPLETED),
|
||||
(STATE_MISSED, STATE_MISSED),
|
||||
(STATE_SCHEDULED, _('scheduled')),
|
||||
(STATE_FAILED, _('failed')),
|
||||
(STATE_COMPLETED, _('completed')),
|
||||
(STATE_MISSED, _('missed')),
|
||||
]
|
||||
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
@@ -71,6 +71,9 @@ class ScheduledMail(models.Model):
|
||||
super().save(**kwargs)
|
||||
|
||||
def recompute(self):
|
||||
if self.state in (self.STATE_COMPLETED, self.STATE_MISSED):
|
||||
return
|
||||
|
||||
if self.rule.date_is_absolute:
|
||||
self.computed_datetime = self.rule.send_date
|
||||
else:
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
{% extends "pretixcontrol/event/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% block title %}{% trans "Inspect Email Rule" %}{% endblock %}
|
||||
{% block content %}
|
||||
<h1>{% trans "Inspect Email Rule" %}</h1>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
This page shows when your rule is planned to be sent.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Email subject" %}</dt>
|
||||
<dd>{{ rule.subject }}</dd>
|
||||
<dt>{% trans "Recipient" %}</dt>
|
||||
<dd>{{ rule.get_send_to_display }}</dd>
|
||||
<dt>{% trans "Scheduled time" %}</dt>
|
||||
<dd>{{ rule.human_readable_time }}</dd>
|
||||
</dl>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-quotas">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Scheduled time" %}</th>
|
||||
{% if request.event.has_subevents %}
|
||||
<th>{% trans "Date" context "subevent" %}</th>
|
||||
{% endif %}
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th>{% trans "Last schedule computation" %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for sm in scheduled_mails %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ sm.computed_datetime|date:"SHORT_DATETIME_FORMAT" }}
|
||||
</td>
|
||||
{% if request.event.has_subevents %}
|
||||
<td>
|
||||
<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 }}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<span class="label {% if sm.state == "missed" %}label-warning{% elif sm.state == "failed" %}label-danger{% elif sm.state == "scheduled" %}label-info{% elif sm.state == "completed" %}label-success{% endif %}">
|
||||
{{ sm.get_state_display }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
{{ sm.last_computed|date:"SHORT_DATETIME_FORMAT" }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
@@ -74,6 +74,7 @@
|
||||
{{ r.sent_mails }} / {{ r.total_mails }}
|
||||
</td>
|
||||
<td class="text-right flip">
|
||||
<a class="btn btn-sm btn-default" href="{% url "plugins:sendmail:rule.schedule" organizer=request.organizer.slug event=request.event.slug rule=r.pk %}" data-toggle="tooltip" title="{% trans "Inspect scheduled times" %}"><i class="fa fa-list"></i></a>
|
||||
<a class="btn btn-sm btn-default" href="{% url "plugins:sendmail:rule.update" organizer=request.organizer.slug event=request.event.slug rule=r.pk %}"><i class="fa fa-edit"></i></a>
|
||||
<a class="btn btn-sm btn-danger" href="{% url "plugins:sendmail:rule.delete" organizer=request.organizer.slug event=request.event.slug rule=r.pk %}"><i class="fa fa-trash"></i></a>
|
||||
</td>
|
||||
@@ -95,4 +96,4 @@
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -10,8 +10,21 @@
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form %}
|
||||
|
||||
{% bootstrap_field form.enabled layout='control' %}
|
||||
{% if rule.total_mails == rule.sent_mails %}
|
||||
<div class="alert alert-warning">
|
||||
{% if event.has_subevents %}
|
||||
{% trans "This email has already been sent for all existing dates. Changing it will have no effect unless you create additional dates in this event series." %}
|
||||
{% else %}
|
||||
{% trans "This email has already been sent. Changing it will have no effect." %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% elif rule.total_mails > 0 and event.has_subevents %}
|
||||
<div class="alert alert-info">
|
||||
{% trans "This email has already been sent for some of the dates in your series. Changing it will only have an effect on dates for which the email has not yet been sent." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% bootstrap_field form.enabled layout='control' %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Content" %}</legend>
|
||||
{% bootstrap_field form.subject layout='control' %}
|
||||
@@ -63,4 +76,4 @@
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -46,6 +46,9 @@ urlpatterns = [
|
||||
name='history'),
|
||||
re_path(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sendmail/rules/create', views.CreateRule.as_view(),
|
||||
name='rule.create'),
|
||||
re_path(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sendmail/rules/(?P<rule>[^/]+)/schedule',
|
||||
views.ScheduleView.as_view(),
|
||||
name='rule.schedule'),
|
||||
re_path(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sendmail/rules/(?P<rule>[^/]+)/delete',
|
||||
views.DeleteRule.as_view(),
|
||||
name='rule.delete'),
|
||||
|
||||
@@ -43,6 +43,7 @@ from django.db.models import Count, Exists, Max, Min, OuterRef, Q
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DeleteView, FormView, ListView
|
||||
@@ -385,7 +386,14 @@ class UpdateRule(EventPermissionRequiredMixin, UpdateView):
|
||||
permission = 'can_change_event_settings'
|
||||
|
||||
def get_object(self, queryset=None) -> Rule:
|
||||
return get_object_or_404(Rule, event=self.request.event, id=self.kwargs['rule'])
|
||||
return get_object_or_404(
|
||||
Rule.objects.annotate(
|
||||
total_mails=Count('scheduledmail'),
|
||||
sent_mails=Count('scheduledmail', filter=Q(scheduledmail__state=ScheduledMail.STATE_COMPLETED)),
|
||||
),
|
||||
event=self.request.event,
|
||||
id=self.kwargs['rule']
|
||||
)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('plugins:sendmail:rule.update', kwargs={
|
||||
@@ -485,3 +493,23 @@ class DeleteRule(EventPermissionRequiredMixin, DeleteView):
|
||||
self.object.delete()
|
||||
messages.success(self.request, _('The selected rule has been deleted.'))
|
||||
return HttpResponseRedirect(success_url)
|
||||
|
||||
|
||||
class ScheduleView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
template_name = 'pretixplugins/sendmail/rule_inspect.html'
|
||||
model = ScheduledMail
|
||||
context_object_name = 'scheduled_mails'
|
||||
|
||||
@cached_property
|
||||
def rule(self):
|
||||
return get_object_or_404(Rule, event=self.request.event, id=self.kwargs['rule'])
|
||||
|
||||
def get_queryset(self):
|
||||
return self.rule.scheduledmail_set.select_related('subevent').order_by(
|
||||
'-computed_datetime'
|
||||
)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['rule'] = self.rule
|
||||
return ctx
|
||||
|
||||
Reference in New Issue
Block a user