Supporting invoice-on-demand instead of autogeneration

This commit is contained in:
Raphael Michel
2016-06-05 18:01:10 +02:00
parent 5529ec5e0b
commit 4496f19a68
8 changed files with 84 additions and 6 deletions

View File

@@ -283,7 +283,7 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str],
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
pass pass
if event.settings.get('invoice_generate'): if event.settings.get('invoice_generate') == 'True':
generate_invoice(order) generate_invoice(order)
with language(order.locale): with language(order.locale):

View File

@@ -182,9 +182,15 @@ class EventSettingsForm(SettingsForm):
help_text=_("Does only work if an invoice address is asked for. VAT ID is not required."), help_text=_("Does only work if an invoice address is asked for. VAT ID is not required."),
required=False required=False
) )
invoice_generate = forms.BooleanField( invoice_generate = forms.ChoiceField(
label=_("Generate invoices"), label=_("Generate invoices"),
required=False required=False,
choices=(
('False', _('No')),
('admin', _('Manually in admin panel')),
('user', _('Automatically on user request')),
('True', _('Automatically for all created orders'))
)
) )
invoice_address_from = forms.CharField( invoice_address_from = forms.CharField(
widget=forms.Textarea(attrs={'rows': 5}), required=False, widget=forms.Textarea(attrs={'rows': 5}), required=False,

View File

@@ -1,5 +1,6 @@
{% extends "pretixcontrol/event/base.html" %} {% extends "pretixcontrol/event/base.html" %}
{% load i18n %} {% load i18n %}
{% load eventurl %}
{% block title %} {% block title %}
{% blocktrans trimmed with code=order.code %} {% blocktrans trimmed with code=order.code %}
Order details: {{ code }} Order details: {{ code }}
@@ -105,6 +106,17 @@
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</dd> </dd>
{% elif request.event.settings.invoice_generate == 'admin' or request.event.settings.invoice_generate == 'user' %}
<dt>{% trans "Invoices" %}</dt>
<dd>
<form class="form-inline helper-display-inline" method="post"
action="{% url "control:event.order.geninvoice" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}">
{% csrf_token %}
<button class="btn btn-default btn-xs">
{% trans "Generate invoice" %}
</button>
</form>
</dd>
{% endif %} {% endif %}
</dl> </dl>
</div> </div>

View File

@@ -66,6 +66,8 @@ urlpatterns = [
name='event.order.transition'), name='event.order.transition'),
url(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(), url(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
name='event.order.resendlink'), name='event.order.resendlink'),
url(r'^orders/(?P<code>[0-9A-Z]+)/invoice$', orders.OrderInvoiceCreate.as_view(),
name='event.order.geninvoice'),
url(r'^orders/(?P<code>[0-9A-Z]+)/extend$', orders.OrderExtend.as_view(), url(r'^orders/(?P<code>[0-9A-Z]+)/extend$', orders.OrderExtend.as_view(),
name='event.order.extend'), name='event.order.extend'),
url(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'), url(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),

View File

@@ -18,7 +18,7 @@ from pretix.base.models import (
) )
from pretix.base.services import tickets from pretix.base.services import tickets
from pretix.base.services.export import export from pretix.base.services.export import export
from pretix.base.services.invoices import invoice_pdf from pretix.base.services.invoices import generate_invoice, invoice_pdf
from pretix.base.services.mail import mail from pretix.base.services.mail import mail
from pretix.base.services.orders import cancel_order, mark_order_paid from pretix.base.services.orders import cancel_order, mark_order_paid
from pretix.base.services.stats import order_overview from pretix.base.services.stats import order_overview
@@ -209,6 +209,21 @@ class OrderTransition(OrderView):
return HttpResponseNotAllowed(['POST']) return HttpResponseNotAllowed(['POST'])
class OrderInvoiceCreate(OrderView):
permission = 'can_change_orders'
def post(self, *args, **kwargs):
if self.request.event.settings.get('invoice_generate') not in ('admin', 'user'):
messages.error(self.request, _('You cannot generate an invoice for this order.'))
elif self.order.invoices.exists():
messages.error(self.request, _('An invoice for this order already exists.'))
else:
generate_invoice(self.order)
self.order.log_action('pretix.event.order.invoice.generate', user=self.request.user)
messages.success(self.request, _('The invoice has been generated.'))
return redirect(self.get_order_url())
class OrderResendLink(OrderView): class OrderResendLink(OrderView):
permission = 'can_change_orders' permission = 'can_change_orders'

View File

@@ -113,9 +113,28 @@
</div> </div>
</div> </div>
</div> </div>
{% elif request.event.settings.invoice_generate == 'user' %}
<div class="col-xs-12 {% if request.event.settings.invoice_address_asked %}col-md-6{% endif %}">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">
{% trans "Invoices" %}
</h3>
</div>
<div class="panel-body">
<form class="form-inline helper-display-inline" method="post"
action="{% eventurl event "presale:event.order.geninvoice" order=order.code secret=order.secret %}">
{% csrf_token %}
<button class="btn btn-default">
{% trans "Request invoice" %}
</button>
</form>
</div>
</div>
</div>
{% endif %} {% endif %}
{% if request.event.settings.invoice_address_asked %} {% if request.event.settings.invoice_address_asked %}
<div class="col-xs-12 {% if invoices %}col-md-6{% endif %}"> <div class="col-xs-12 {% if invoices or request.event.settings.invoice_generate == 'user' %}col-md-6{% endif %}">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading"> <div class="panel-heading">
{% if order.can_modify_answers %} {% if order.can_modify_answers %}

View File

@@ -20,6 +20,9 @@ event_patterns = [
name='event.checkout'), name='event.checkout'),
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/$', pretix.presale.views.order.OrderDetails.as_view(), url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/$', pretix.presale.views.order.OrderDetails.as_view(),
name='event.order'), name='event.order'),
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/invoice$',
pretix.presale.views.order.OrderInvoiceCreate.as_view(),
name='event.order.geninvoice'),
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/cancel$', url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/cancel$',
pretix.presale.views.order.OrderCancel.as_view(), pretix.presale.views.order.OrderCancel.as_view(),
name='event.order.cancel'), name='event.order.cancel'),

View File

@@ -1,6 +1,7 @@
from datetime import timedelta from datetime import timedelta
from django.contrib import messages from django.contrib import messages
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import Http404 from django.http import Http404
from django.shortcuts import redirect from django.shortcuts import redirect
@@ -13,7 +14,7 @@ from pretix.base.models import (
CachedFile, CachedTicket, Invoice, Order, OrderPosition, CachedFile, CachedTicket, Invoice, Order, OrderPosition,
) )
from pretix.base.models.orders import InvoiceAddress from pretix.base.models.orders import InvoiceAddress
from pretix.base.services.invoices import invoice_pdf from pretix.base.services.invoices import generate_invoice, invoice_pdf
from pretix.base.services.orders import OrderError, cancel_order from pretix.base.services.orders import OrderError, cancel_order
from pretix.base.services.tickets import generate from pretix.base.services.tickets import generate
from pretix.base.signals import ( from pretix.base.signals import (
@@ -145,6 +146,26 @@ class OrderPay(EventViewMixin, OrderDetailMixin, TemplateView):
}) })
class OrderInvoiceCreate(EventViewMixin, OrderDetailMixin, View):
def dispatch(self, request, *args, **kwargs):
self.request = request
if not self.order:
raise Http404(_('Unknown order code or not authorized to access this order.'))
return super().dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
if self.request.event.settings.get('invoice_generate') != 'user':
messages.error(self.request, _('You cannot generate an invoice for this order.'))
elif self.order.invoices.exists():
messages.error(self.request, _('An invoice for this order already exists.'))
else:
generate_invoice(self.order)
self.order.log_action('pretix.event.order.invoice.generate', user=self.request.user)
messages.success(self.request, _('The invoice has been generated.'))
return redirect(self.get_order_url())
class OrderPayDo(EventViewMixin, OrderDetailMixin, TemplateView): class OrderPayDo(EventViewMixin, OrderDetailMixin, TemplateView):
template_name = "pretixpresale/event/order_pay_confirm.html" template_name = "pretixpresale/event/order_pay_confirm.html"