add a quick mass edit view for OutgoingEmail objects so we can release the held emails in the queue
This commit is contained in:
parent
57dc6f12d8
commit
de0901b68d
|
@ -135,6 +135,10 @@
|
||||||
<h4 class="list-group-item-heading">Shop Ticket Overview</h4>
|
<h4 class="list-group-item-heading">Shop Ticket Overview</h4>
|
||||||
<p class="list-group-item-text">Use this to list shop tickets</p>
|
<p class="list-group-item-text">Use this to list shop tickets</p>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="{% url 'backoffice:outgoing_email_release' camp_slug=camp.slug %}" class="list-group-item">
|
||||||
|
<h4 class="list-group-item-heading">Edit and Release Held Emails</h4>
|
||||||
|
<p class="list-group-item-text">Use this view to edit and release OutgoingEmailQueue objects on hold.</p>
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.camps.economyteam_permission %}
|
{% if perms.camps.economyteam_permission %}
|
||||||
|
|
63
src/backoffice/templates/outgoing_email_mass_update.html
Normal file
63
src/backoffice/templates/outgoing_email_mass_update.html
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
{% extends 'program_base.html' %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load bornhack %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
Edit and Release Held Emails | {{ block.super }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">Edit and Release Held Emails ({{ formset|length }})</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="post">
|
||||||
|
{{ formset.management_form }}
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for form in formset %}
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4 class="panel-title">From {{ form.instance.sender }}: {{ form.instance.subject }}</h4>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Created</th>
|
||||||
|
<td>{{ form.instance.created }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Team</th>
|
||||||
|
<td>{{ form.instance.responsible_team }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>To</th>
|
||||||
|
<td>{{ form.instance.to_recipients|join:"<br>"|default:"N/A" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Cc</th>
|
||||||
|
<td>{{ form.instance.cc_recipients|join:"<br>"|default:"N/A" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Bcc</th>
|
||||||
|
<td>{{ form.instance.bcc_recipients|join:"<br>"|default:"N/A" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Attachment</th>
|
||||||
|
<td>{{ form.instance.attachment|default:"N/A" }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Form</th>
|
||||||
|
<td>{% bootstrap_form form %}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit" class="btn btn-success"><i class="fas fa-check"></i> Submit</button>
|
||||||
|
<a href="{% url 'backoffice:index' camp_slug=camp.slug %}" class="btn btn-primary"><i class="fas fa-undo"></i> Cancel</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -58,6 +58,7 @@ from .views import (
|
||||||
FacilityUpdateView,
|
FacilityUpdateView,
|
||||||
MerchandiseOrdersView,
|
MerchandiseOrdersView,
|
||||||
MerchandiseToOrderView,
|
MerchandiseToOrderView,
|
||||||
|
OutgoingEmailMassUpdateView,
|
||||||
PendingProposalsView,
|
PendingProposalsView,
|
||||||
ProductHandoutView,
|
ProductHandoutView,
|
||||||
ReimbursementCreateUserSelectView,
|
ReimbursementCreateUserSelectView,
|
||||||
|
@ -625,4 +626,10 @@ urlpatterns = [
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
# release held emails
|
||||||
|
path(
|
||||||
|
"release_emails",
|
||||||
|
OutgoingEmailMassUpdateView.as_view(),
|
||||||
|
name="outgoing_email_release",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -46,6 +46,7 @@ from program.utils import save_speaker_availability
|
||||||
from shop.models import Order, OrderProductRelation
|
from shop.models import Order, OrderProductRelation
|
||||||
from teams.models import Team
|
from teams.models import Team
|
||||||
from tickets.models import DiscountTicket, ShopTicket, SponsorTicket, TicketType
|
from tickets.models import DiscountTicket, ShopTicket, SponsorTicket, TicketType
|
||||||
|
from utils.models import OutgoingEmail
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
AutoScheduleApplyForm,
|
AutoScheduleApplyForm,
|
||||||
|
@ -1904,3 +1905,54 @@ class BackofficeProxyView(CampViewMixin, RaisePermissionRequiredMixin, TemplateV
|
||||||
context = super().get_context_data(*args, **kwargs)
|
context = super().get_context_data(*args, **kwargs)
|
||||||
context["urls"] = settings.BACKOFFICE_PROXY_URLS
|
context["urls"] = settings.BACKOFFICE_PROXY_URLS
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
################################
|
||||||
|
# UPDATE HELD OUTGOING EMAILS
|
||||||
|
|
||||||
|
|
||||||
|
class OutgoingEmailMassUpdateView(CampViewMixin, OrgaTeamPermissionMixin, FormView):
|
||||||
|
"""
|
||||||
|
This view shows a list with forms to edit OutgoingEmail objects with hold=True
|
||||||
|
"""
|
||||||
|
|
||||||
|
template_name = "outgoing_email_mass_update.html"
|
||||||
|
|
||||||
|
def setup(self, *args, **kwargs):
|
||||||
|
"""Get emails with no team and emails with a team for the current camp."""
|
||||||
|
super().setup(*args, **kwargs)
|
||||||
|
self.queryset = OutgoingEmail.objects.filter(
|
||||||
|
hold=True, responsible_team__isnull=True
|
||||||
|
).prefetch_related("responsible_team") | OutgoingEmail.objects.filter(
|
||||||
|
hold=True, responsible_team__camp=self.camp
|
||||||
|
).prefetch_related(
|
||||||
|
"responsible_team"
|
||||||
|
)
|
||||||
|
self.form_class = modelformset_factory(
|
||||||
|
OutgoingEmail,
|
||||||
|
fields=["subject", "text_template", "html_template", "hold"],
|
||||||
|
min_num=self.queryset.count(),
|
||||||
|
validate_min=True,
|
||||||
|
max_num=self.queryset.count(),
|
||||||
|
validate_max=True,
|
||||||
|
extra=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_context_data(self, *args, **kwargs):
|
||||||
|
"""Include the formset in the context."""
|
||||||
|
context = super().get_context_data(*args, **kwargs)
|
||||||
|
context["formset"] = self.form_class(queryset=self.queryset)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
"""Show a message saying how many objects were updated."""
|
||||||
|
form.save()
|
||||||
|
if form.changed_objects:
|
||||||
|
messages.success(
|
||||||
|
self.request, f"Updated {len(form.changed_objects)} OutgoingEmails"
|
||||||
|
)
|
||||||
|
return redirect(self.get_success_url())
|
||||||
|
|
||||||
|
def get_success_url(self, *args, **kwargs):
|
||||||
|
"""Return to the backoffice index."""
|
||||||
|
return reverse("backoffice:index", kwargs={"camp_slug": self.camp.slug})
|
||||||
|
|
|
@ -195,3 +195,6 @@ LEAFLET_CONFIG = {
|
||||||
|
|
||||||
# used to find the economy team
|
# used to find the economy team
|
||||||
ECONOMY_TEAM_NAME = "Economy"
|
ECONOMY_TEAM_NAME = "Economy"
|
||||||
|
|
||||||
|
# we have some large formsets sometimes
|
||||||
|
DATA_UPLOAD_MAX_NUMBER_FIELDS = 5000
|
||||||
|
|
Loading…
Reference in a new issue