Bank transfer: Allow customer to send latest invoice via email (Z#207218) (#3511)

Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
Mira
2023-08-09 18:23:45 +02:00
committed by GitHub
parent 6ada83df9a
commit 6250ab2165
6 changed files with 168 additions and 4 deletions

View File

@@ -535,9 +535,11 @@ class BankTransfer(BasePaymentProvider):
'eu_barcodes': self.event.currency == 'EUR',
'pending_description': self.settings.get('pending_description', as_type=LazyI18nString),
'details': self.settings.get('bank_details', as_type=LazyI18nString),
'has_invoices': payment.order.invoices.exists(),
'invoice_email_enabled': self.settings.get('invoice_email', as_type=bool),
}
ctx['any_barcodes'] = ctx['swiss_qrbill'] or ctx['eu_barcodes']
return template.render(ctx)
return template.render(ctx, request=request)
def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
warning = None

View File

@@ -7,6 +7,7 @@
{% load money %}
{% load unidecode %}
{% load rich_text %}
{% load eventurl %}
{% if pending_description %}
{{ pending_description|rich_text }}
@@ -103,3 +104,28 @@ SCT
{% if swiss_qrbill %}
<link rel="stylesheet" href="{% static "pretixplugins/banktransfer/swisscross.css" %}">
{% endif %}
{% if invoice_email_enabled and has_invoices %}
<form method="post" action="{% eventurl event "plugins:banktransfer:mail_invoice" order=order.code secret=order.secret %}">
{% csrf_token %}
<p>
{% blocktrans trimmed %}
To send the invoice directly to your accounting department, please enter their email address:
{% endblocktrans %}
</p>
<div class="row">
<div class="col-md-9 col-xs-12">
<label for="mail_invoice_email" class="sr-only">{% trans "Invoice recipient email" %}:</label>
<input type="email" name="email" id="mail_invoice_email" class="form-control" value="" required
placeholder="{% trans "Email address" %}" />
</div>
<div class="col-md-3 col-xs-12">
<button class="btn btn-default btn-block">
<span class="fa fa-envelope-o" aria-hidden="true"></span>
{% trans "Send invoice via email" %}
</button>
</div>
</div>
</form>
<hr>
{% endif %}

View File

@@ -19,13 +19,19 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.urls import re_path
from django.urls import include, re_path
from pretix.api.urls import orga_router
from pretix.plugins.banktransfer.api import BankImportJobViewSet
from . import views
event_patterns = [
re_path(r'^banktransfer/', include([
re_path(r'^(?P<order>[^/][^w]+)/(?P<secret>[A-Za-z0-9]+)/mail-invoice/$', views.SendInvoiceMailView.as_view(), name='mail_invoice'),
])),
]
urlpatterns = [
re_path(r'^control/organizer/(?P<organizer>[^/]+)/banktransfer/import/',
views.OrganizerImportView.as_view(),

View File

@@ -44,14 +44,18 @@ from typing import Set
from django import forms
from django.contrib import messages
from django.core.exceptions import ValidationError
from django.core.validators import validate_email
from django.db import transaction
from django.db.models import Count, Q, QuerySet
from django.http import FileResponse, JsonResponse
from django.http import FileResponse, Http404, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.functional import cached_property
from django.utils.timezone import now
from django.utils.translation import gettext as _
from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import DetailView, FormView, ListView, View
from django.views.generic.detail import SingleObjectMixin
from localflavor.generic.forms import BICFormField, IBANFormField
@@ -75,6 +79,8 @@ from pretix.plugins.banktransfer.refund_export import (
build_sepa_xml, get_refund_export_csv,
)
from pretix.plugins.banktransfer.tasks import process_banktransfers
from pretix.presale.views import EventViewMixin
from pretix.presale.views.order import OrderDetailMixin
logger = logging.getLogger('pretix.plugins.banktransfer')
@@ -886,3 +892,36 @@ class OrganizerSepaXMLExportView(OrganizerPermissionRequiredMixin, OrganizerDeta
organizer=self.request.organizer,
pk=self.kwargs.get('id')
)
@method_decorator(xframe_options_exempt, 'dispatch')
class SendInvoiceMailView(EventViewMixin, OrderDetailMixin, View):
def post(self, request, *args, **kwargs):
if not self.order:
raise Http404(_('Unknown order code or not authorized to access this order.'))
try:
validate_email(request.POST['email'])
except ValidationError:
messages.error(request, _('Please enter a valid email address.'))
return redirect(self.get_order_url())
last_payment = self.order.payments.last()
if (not last_payment
or last_payment.provider != BankTransfer.identifier
or last_payment.state != OrderPayment.PAYMENT_STATE_CREATED):
messages.error(request, _('No pending bank transfer payment found. Maybe the order has been paid already?'))
return redirect(self.get_order_url())
if not last_payment.payment_provider.settings.get('invoice_email', as_type=bool):
messages.error(request, _('Sending invoices via email is disabled by the event organizer.'))
return redirect(self.get_order_url())
last_invoice = self.order.invoices.last()
if not last_invoice:
messages.error(request, _('No invoice found, please request an invoice first.'))
return redirect(self.get_order_url())
provider = last_payment.payment_provider
provider.send_invoice_to_alternate_email(self.order, last_invoice, request.POST['email'])
messages.success(request, _('Sending the latest invoice via e-mail to {email}.').format(email=request.POST['email']))
return redirect(self.get_order_url())