mirror of
https://github.com/pretix/pretix.git
synced 2026-01-30 01:32:28 +00:00
Compare commits
7 Commits
release/3.
...
flaky-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ea8a47f17 | ||
|
|
a09dac89c4 | ||
|
|
8af91b691d | ||
|
|
2221b57dc9 | ||
|
|
8d99388c08 | ||
|
|
de597ba864 | ||
|
|
2d9a16e94d |
@@ -1 +1 @@
|
||||
__version__ = "3.16.0"
|
||||
__version__ = "3.17.0.dev0"
|
||||
|
||||
@@ -596,6 +596,7 @@ class EventSettingsSerializer(SettingsSerializer):
|
||||
'checkout_email_helptext',
|
||||
'presale_has_ended_text',
|
||||
'voucher_explanation_text',
|
||||
'checkout_success_text',
|
||||
'banner_text',
|
||||
'banner_text_bottom',
|
||||
'show_dates_on_frontpage',
|
||||
@@ -656,6 +657,7 @@ class EventSettingsSerializer(SettingsSerializer):
|
||||
'mail_from',
|
||||
'mail_from_name',
|
||||
'mail_attach_ical',
|
||||
'mail_attach_tickets',
|
||||
'invoice_address_asked',
|
||||
'invoice_address_required',
|
||||
'invoice_address_vatid',
|
||||
|
||||
@@ -13,6 +13,7 @@ from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext, gettext_lazy as _, pgettext
|
||||
|
||||
from pretix.base.models import Invoice, InvoiceLine, OrderPayment
|
||||
from ..services.export import ExportError
|
||||
|
||||
from ...control.forms.filter import get_all_payment_providers
|
||||
from ...helpers import GroupConcat
|
||||
@@ -111,6 +112,8 @@ class InvoiceExporter(InvoiceExporterMixin, BaseExporter):
|
||||
if not i.file:
|
||||
invoice_pdf_task.apply(args=(i.pk,))
|
||||
i.refresh_from_db()
|
||||
if not i.file:
|
||||
raise ExportError('Could not generate PDF for invoice {nr}'.format(nr=i.full_invoice_no))
|
||||
i.file.open('rb')
|
||||
zipf.writestr('{}-{}.pdf'.format(i.number, i.order.code), i.file.read())
|
||||
i.file.close()
|
||||
|
||||
@@ -255,8 +255,10 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
invoice_from_top = 17 * mm
|
||||
|
||||
def _draw_invoice_from(self, canvas):
|
||||
p = Paragraph(self.invoice.full_invoice_from.strip().replace('\n', '<br />\n'), style=self.stylesheet[
|
||||
'InvoiceFrom'])
|
||||
p = Paragraph(
|
||||
bleach.clean(self.invoice.full_invoice_from, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
style=self.stylesheet['InvoiceFrom']
|
||||
)
|
||||
p.wrapOn(canvas, self.invoice_from_width, self.invoice_from_height)
|
||||
p_size = p.wrap(self.invoice_from_width, self.invoice_from_height)
|
||||
p.drawOn(canvas, self.invoice_from_left, self.pagesize[1] - p_size[1] - self.invoice_from_top)
|
||||
@@ -361,6 +363,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
def _draw_event(self, canvas):
|
||||
def shorten(txt):
|
||||
txt = str(txt)
|
||||
txt = bleach.clean(txt, tags=[]).strip()
|
||||
p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
|
||||
p_size = p.wrap(self.event_width, self.event_height)
|
||||
|
||||
@@ -441,13 +444,18 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
story = []
|
||||
if self.invoice.custom_field:
|
||||
story.append(Paragraph(
|
||||
'{}: {}'.format(self.invoice.event.settings.invoice_address_custom_field, self.invoice.custom_field),
|
||||
'{}: {}'.format(
|
||||
bleach.clean(self.invoice.event.settings.invoice_address_custom_field, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
bleach.clean(self.invoice.custom_field, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
|
||||
if self.invoice.internal_reference:
|
||||
story.append(Paragraph(
|
||||
pgettext('invoice', 'Customer reference: {reference}').format(reference=self.invoice.internal_reference),
|
||||
pgettext('invoice', 'Customer reference: {reference}').format(
|
||||
reference=bleach.clean(self.invoice.internal_reference, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
|
||||
@@ -466,7 +474,10 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
))
|
||||
|
||||
if self.invoice.introductory_text:
|
||||
story.append(Paragraph(self.invoice.introductory_text, self.stylesheet['Normal']))
|
||||
story.append(Paragraph(
|
||||
bleach.clean(self.invoice.introductory_text, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
story.append(Spacer(1, 10 * mm))
|
||||
|
||||
return story
|
||||
@@ -566,10 +577,16 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
story.append(Spacer(1, 15 * mm))
|
||||
|
||||
if self.invoice.payment_provider_text:
|
||||
story.append(Paragraph(self.invoice.payment_provider_text, self.stylesheet['Normal']))
|
||||
story.append(Paragraph(
|
||||
bleach.clean(self.invoice.payment_provider_text, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
|
||||
if self.invoice.additional_text:
|
||||
story.append(Paragraph(self.invoice.additional_text, self.stylesheet['Normal']))
|
||||
story.append(Paragraph(
|
||||
bleach.clean(self.invoice.additional_text, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
story.append(Spacer(1, 15 * mm))
|
||||
|
||||
tstyledata = [
|
||||
@@ -701,7 +718,10 @@ class Modern1Renderer(ClassicInvoiceRenderer):
|
||||
def _draw_invoice_from(self, canvas):
|
||||
if not self.invoice.invoice_from:
|
||||
return
|
||||
c = self.invoice.address_invoice_from.strip().split('\n')
|
||||
c = [
|
||||
bleach.clean(l, tags=[]).strip().replace('\n', '<br />\n')
|
||||
for l in self.invoice.address_invoice_from.strip().split('\n')
|
||||
]
|
||||
p = Paragraph(' · '.join(c), style=self.stylesheet['Sender'])
|
||||
p.wrapOn(canvas, self.invoice_to_width, 15.7 * mm)
|
||||
p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - self.invoice_to_top + 2 * mm)
|
||||
|
||||
@@ -291,6 +291,8 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st
|
||||
order = None
|
||||
else:
|
||||
with language(order.locale, event.settings.region):
|
||||
if not event.settings.mail_attach_tickets:
|
||||
attach_tickets = False
|
||||
if position:
|
||||
try:
|
||||
position = order.positions.get(pk=position)
|
||||
|
||||
@@ -13,6 +13,7 @@ from django.core.validators import (
|
||||
MaxValueValidator, MinValueValidator, RegexValidator,
|
||||
)
|
||||
from django.db.models import Model
|
||||
from django.utils.text import format_lazy
|
||||
from django.utils.translation import (
|
||||
gettext_lazy as _, gettext_noop, pgettext, pgettext_lazy,
|
||||
)
|
||||
@@ -1322,6 +1323,19 @@ DEFAULTS = {
|
||||
'default': 'classic',
|
||||
'type': str
|
||||
},
|
||||
'mail_attach_tickets': {
|
||||
'default': 'True',
|
||||
'type': bool,
|
||||
'form_class': forms.BooleanField,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Attach ticket files"),
|
||||
help_text=format_lazy(
|
||||
_("Tickets will never be attached if they're larger than {size} to avoid email delivery problems."),
|
||||
size='4 MB'
|
||||
),
|
||||
)
|
||||
},
|
||||
'mail_attach_ical': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
@@ -1983,6 +1997,19 @@ Your {event} team"""))
|
||||
"why you need information from them.")
|
||||
)
|
||||
},
|
||||
'checkout_success_text': {
|
||||
'default': '',
|
||||
'type': LazyI18nString,
|
||||
'serializer_class': I18nField,
|
||||
'form_class': I18nFormField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Additional success message"),
|
||||
help_text=_("This message will be shown after an order has been created successfully. It will be shown in additional "
|
||||
"to the default text."),
|
||||
widget_kwargs={'attrs': {'rows': '2'}},
|
||||
widget=I18nTextarea
|
||||
)
|
||||
},
|
||||
'checkout_phone_helptext': {
|
||||
'default': '',
|
||||
'type': LazyI18nString,
|
||||
|
||||
@@ -435,6 +435,7 @@ class EventSettingsForm(SettingsForm):
|
||||
'checkout_email_helptext',
|
||||
'presale_has_ended_text',
|
||||
'voucher_explanation_text',
|
||||
'checkout_success_text',
|
||||
'show_dates_on_frontpage',
|
||||
'show_date_to',
|
||||
'show_times',
|
||||
@@ -786,6 +787,7 @@ class MailSettingsForm(SettingsForm):
|
||||
'mail_from',
|
||||
'mail_from_name',
|
||||
'mail_attach_ical',
|
||||
'mail_attach_tickets',
|
||||
]
|
||||
|
||||
mail_sales_channel_placed_paid = forms.MultipleChoiceField(
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
{% bootstrap_field form.mail_from_name layout="control" %}
|
||||
{% bootstrap_field form.mail_text_signature layout="control" %}
|
||||
{% bootstrap_field form.mail_bcc layout="control" %}
|
||||
{% bootstrap_field form.mail_attach_tickets layout="control" %}
|
||||
{% bootstrap_field form.mail_attach_ical layout="control" %}
|
||||
{% bootstrap_field form.mail_sales_channel_placed_paid layout="control" %}
|
||||
</fieldset>
|
||||
|
||||
@@ -188,6 +188,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% bootstrap_field sform.checkout_success_text layout="control" %}
|
||||
{% bootstrap_field sform.checkout_email_helptext layout="control" %}
|
||||
{% bootstrap_field sform.checkout_phone_helptext layout="control" %}
|
||||
{% bootstrap_field sform.banner_text layout="control" %}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
{% load expiresformat %}
|
||||
{% load eventurl %}
|
||||
{% load phone_format %}
|
||||
{% load rich_text %}
|
||||
{% block title %}
|
||||
{% if "thanks" in request.GET or "paid" in request.GET %}
|
||||
{% trans "Thank you!" %}
|
||||
@@ -44,6 +45,9 @@
|
||||
{% else %}
|
||||
<p>{% trans "We successfully received your payment. See below for details." %}</p>
|
||||
{% endif %}
|
||||
{% if request.event.settings.checkout_success_text %}
|
||||
{{ request.event.settings.checkout_success_text|rich_text }}
|
||||
{% endif %}
|
||||
<p class="iframe-hidden">{% blocktrans trimmed %}
|
||||
Please bookmark or save the link to this exact page if you want to access your order later. We also sent you an email containing the link to the address you specified.
|
||||
{% endblocktrans %}</p>
|
||||
|
||||
@@ -918,12 +918,10 @@ class SubEventsTest(SoupTest):
|
||||
assert doc.select(".alert-success")
|
||||
with scopes_disabled():
|
||||
for se in [self.subevent1, self.subevent2]:
|
||||
q = se.quotas.first()
|
||||
assert q.name == 'Q1'
|
||||
q = se.quotas.get(name='Q1')
|
||||
assert q.size == 50
|
||||
assert list(q.items.all()) == [self.ticket]
|
||||
q = se.quotas.last()
|
||||
assert q.name == 'Q2'
|
||||
q = se.quotas.get(name='Q2')
|
||||
assert q.size == 25
|
||||
assert list(q.items.all()) == [self.ticket]
|
||||
|
||||
@@ -931,6 +929,8 @@ class SubEventsTest(SoupTest):
|
||||
'__ALL': 'on',
|
||||
}, follow=True)
|
||||
fields = extract_form_fields(doc)
|
||||
assert fields['quotas-0-name'] == 'Q1'
|
||||
assert fields['quotas-1-name'] == 'Q2'
|
||||
fields.update({
|
||||
'_bulk': ['__quotas'],
|
||||
'quotas-0-size': '25',
|
||||
|
||||
Reference in New Issue
Block a user