Fix #278 -- Preview for invoices

This commit is contained in:
Raphael Michel
2016-10-20 18:58:05 +02:00
parent 05ecfdb9e2
commit d6478e66de
4 changed files with 73 additions and 1 deletions

View File

@@ -9,6 +9,7 @@ from django.contrib.staticfiles import finders
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.db import transaction from django.db import transaction
from django.utils.formats import date_format from django.utils.formats import date_format
from django.utils.timezone import now
from django.utils.translation import pgettext, ugettext as _ from django.utils.translation import pgettext, ugettext as _
from reportlab.lib import pagesizes from reportlab.lib import pagesizes
from reportlab.lib.styles import ParagraphStyle, StyleSheet1 from reportlab.lib.styles import ParagraphStyle, StyleSheet1
@@ -399,3 +400,53 @@ def invoice_pdf(*args, **kwargs):
# was committed and therefore fails to find the invoice object. The invoice_pdf_task # was committed and therefore fails to find the invoice object. The invoice_pdf_task
# will prevent this kind of race condition. # will prevent this kind of race condition.
invoice_pdf_task.apply_async(args=args, kwargs=kwargs) invoice_pdf_task.apply_async(args=args, kwargs=kwargs)
class DummyRollbackException(Exception):
pass
def build_preview_invoice_pdf(event):
locale = event.settings.invoice_language
pdf = None
if not locale or locale == '__user__':
locale = event.settings.locale
try:
with transaction.atomic(), language(locale):
order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
expires=now(), code="PREVIEW", total=119)
invoice = Invoice(
order=order, event=event, invoice_no="PREVIEW",
date=date.today(), locale=locale
)
invoice.invoice_from = event.settings.get('invoice_address_from')
introductory = event.settings.get('invoice_introductory_text', as_type=LazyI18nString)
additional = event.settings.get('invoice_additional_text', as_type=LazyI18nString)
footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString)
payment = _("A payment provider specific text might appear here.")
invoice.introductory_text = str(introductory).replace('\n', '<br />')
invoice.additional_text = str(additional).replace('\n', '<br />')
invoice.footer_text = str(footer)
invoice.payment_provider_text = str(payment).replace('\n', '<br />')
invoice.invoice_to = _("John Doe\n214th Example Street\n012345 Somecity")
invoice.file = None
invoice.save()
invoice.lines.all().delete()
InvoiceLine.objects.create(
invoice=invoice, description=_("Sample product A"),
gross_value=119, tax_value=19,
tax_rate=19
)
with tempfile.NamedTemporaryFile(suffix=".pdf") as f:
_invoice_generate_german(invoice, f)
f.seek(0)
pdf = f.read()
raise DummyRollbackException()
except DummyRollbackException:
return pdf
else:
raise Exception('Invalid state, should have rolled back.')

View File

@@ -19,6 +19,9 @@
{% bootstrap_field form.invoice_footer_text layout="horizontal" %} {% bootstrap_field form.invoice_footer_text layout="horizontal" %}
</fieldset> </fieldset>
<div class="form-group submit-group"> <div class="form-group submit-group">
<button type="submit" class="btn btn-default btn-lg" name="preview" value="preview" formtarget="_blank">
{% trans "Save and show preview" %}
</button>
<button type="submit" class="btn btn-primary btn-save"> <button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %} {% trans "Save" %}
</button> </button>

View File

@@ -44,6 +44,7 @@ urlpatterns = [
url(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'), url(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'),
url(r'^settings/email$', event.MailSettings.as_view(), name='event.settings.mail'), url(r'^settings/email$', event.MailSettings.as_view(), name='event.settings.mail'),
url(r'^settings/invoice$', event.InvoiceSettings.as_view(), name='event.settings.invoice'), url(r'^settings/invoice$', event.InvoiceSettings.as_view(), name='event.settings.invoice'),
url(r'^settings/invoice/preview$', event.InvoicePreview.as_view(), name='event.settings.invoice.preview'),
url(r'^settings/display', event.DisplaySettings.as_view(), name='event.settings.display'), url(r'^settings/display', event.DisplaySettings.as_view(), name='event.settings.display'),
url(r'^items/$', item.ItemList.as_view(), name='event.items'), url(r'^items/$', item.ItemList.as_view(), name='event.items'),
url(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'), url(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),

View File

@@ -6,17 +6,19 @@ from django.core.files import File
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import transaction from django.db import transaction
from django.forms import modelformset_factory from django.forms import modelformset_factory
from django.http import HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.generic import FormView from django.views.generic import FormView
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView, View
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from pretix.base.forms import I18nModelForm from pretix.base.forms import I18nModelForm
from pretix.base.models import ( from pretix.base.models import (
Event, EventPermission, Item, ItemVariation, User, Event, EventPermission, Item, ItemVariation, User,
) )
from pretix.base.services.invoices import build_preview_invoice_pdf
from pretix.base.signals import ( from pretix.base.signals import (
register_payment_providers, register_ticket_outputs, register_payment_providers, register_ticket_outputs,
) )
@@ -273,12 +275,27 @@ class InvoiceSettings(EventSettingsFormView):
permission = 'can_change_settings' permission = 'can_change_settings'
def get_success_url(self) -> str: def get_success_url(self) -> str:
if 'preview' in self.request.POST:
return reverse('control:event.settings.invoice.preview', kwargs={
'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug
})
return reverse('control:event.settings.invoice', kwargs={ return reverse('control:event.settings.invoice', kwargs={
'organizer': self.request.event.organizer.slug, 'organizer': self.request.event.organizer.slug,
'event': self.request.event.slug 'event': self.request.event.slug
}) })
class InvoicePreview(EventPermissionRequiredMixin, View):
permission = 'can_change_settings'
def get(self, request, *args, **kwargs):
pdf = build_preview_invoice_pdf(request.event)
resp = HttpResponse(pdf, content_type='application/pdf')
resp['Content-Disposition'] = 'attachment; filename="invoice-preview.pdf"'
return resp
class DisplaySettings(EventSettingsFormView): class DisplaySettings(EventSettingsFormView):
model = Event model = Event
form_class = DisplaySettingsForm form_class = DisplaySettingsForm