Offer download options per position, not per order

This commit is contained in:
Raphael Michel
2016-11-01 17:58:41 +01:00
parent 3344c02c80
commit ad35110166
25 changed files with 630 additions and 703 deletions

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.2 on 2016-11-01 16:10
from __future__ import unicode_literals
import django.db.models.deletion
from django.db import migrations, models
def forwards(apps, schema_editor):
CachedTicket = apps.get_model('pretixbase', 'CachedTicket')
CachedTicket.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [
('pretixbase', '0043_globalsetting'),
]
operations = [
migrations.RunPython(
forwards, migrations.RunPython.noop
),
migrations.RemoveField(
model_name='cachedticket',
name='order',
),
migrations.AddField(
model_name='cachedticket',
name='order_position',
field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='pretixbase.OrderPosition'),
preserve_default=False,
),
]

View File

@@ -309,12 +309,6 @@ class Order(LoggedModel):
return True
class CachedTicket(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
cachedfile = models.ForeignKey(CachedFile, on_delete=models.CASCADE, null=True)
provider = models.CharField(max_length=255)
class QuestionAnswer(models.Model):
"""
The answer to a Question, connected to an OrderPosition or CartPosition.
@@ -554,3 +548,9 @@ class InvoiceAddress(models.Model):
city = models.CharField(max_length=255, verbose_name=_('City'), blank=False)
country = models.CharField(max_length=255, verbose_name=_('Country'), blank=False)
vat_id = models.CharField(max_length=255, blank=True, verbose_name=_('VAT ID'))
class CachedTicket(models.Model):
order_position = models.ForeignKey(OrderPosition, on_delete=models.CASCADE)
cachedfile = models.ForeignKey(CachedFile, on_delete=models.CASCADE, null=True)
provider = models.CharField(max_length=255)

View File

@@ -6,7 +6,7 @@ from django.utils.translation import ugettext as _
from pretix.base.i18n import language
from pretix.base.models import (
CachedFile, CachedTicket, Event, Order, cachedfile_name,
CachedFile, CachedTicket, Event, Order, OrderPosition, cachedfile_name,
)
from pretix.base.signals import register_ticket_outputs
from pretix.celery import app
@@ -14,23 +14,23 @@ from pretix.helpers.database import rolledback_transaction
@app.task
def generate(order: str, provider: str):
order = Order.objects.select_related('event').get(id=order)
ct = CachedTicket.objects.get_or_create(order=order, provider=provider)[0]
def generate(order_position: str, provider: str):
order_position = OrderPosition.objects.select_related('order', 'order__event').get(id=order_position)
ct = CachedTicket.objects.get_or_create(order_position=order_position, provider=provider)[0]
if not ct.cachedfile:
cf = CachedFile()
cf.date = now()
cf.expires = order.event.date_from + timedelta(days=30)
cf.expires = order_position.order.event.date_from + timedelta(days=30)
cf.save()
ct.cachedfile = cf
ct.save()
with language(order.locale):
responses = register_ticket_outputs.send(order.event)
with language(order_position.order.locale):
responses = register_ticket_outputs.send(order_position.order.event)
for receiver, response in responses:
prov = response(order.event)
prov = response(order_position.order.event)
if prov.identifier == provider:
ct.cachedfile.filename, ct.cachedfile.type, data = prov.generate(order)
ct.cachedfile.filename, ct.cachedfile.type, data = prov.generate(order_position)
ct.cachedfile.file.save(cachedfile_name(ct.cachedfile, ct.cachedfile.filename), ContentFile(data))
ct.cachedfile.save()
@@ -49,10 +49,10 @@ def preview(event: int, provider: str):
email='sample@pretix.eu',
expires=now(), code="PREVIEW1234", total=119)
order.positions.create(item=item, attendee_name=_("John Doe"), price=item.default_price)
p = order.positions.create(item=item, attendee_name=_("John Doe"), price=item.default_price)
responses = register_ticket_outputs.send(event)
for receiver, response in responses:
prov = response(event)
if prov.identifier == provider:
return prov.generate(order)
return prov.generate(p)

View File

@@ -5,7 +5,7 @@ from django import forms
from django.http import HttpRequest
from django.utils.translation import ugettext_lazy as _
from pretix.base.models import Event, Order
from pretix.base.models import Event, OrderPosition
from pretix.base.settings import SettingsSandbox
@@ -29,7 +29,7 @@ class BaseTicketOutput:
"""
return self.settings.get('_enabled', as_type=bool)
def generate(self, order: Order) -> Tuple[str, str, str]:
def generate(self, order: OrderPosition) -> Tuple[str, str, str]:
"""
This method should generate the download file and return a tuple consisting of a
filename, a file type and file content.
@@ -106,11 +106,3 @@ class BaseTicketOutput:
The text on the download button in the frontend.
"""
return _('Download ticket')
@property
def download_button_icon(self) -> str:
"""
The name of the FontAwesome icon on the download button in the frontend
(without the fa- prefix).
"""
return None

View File

@@ -38,14 +38,6 @@
</a>
{% endif %}
{% if can_download %}
{% for b in download_buttons %}
<a href="{% url "control:event.order.download" organizer=request.event.organizer.slug event=request.event.slug code=order.code output=b.identifier %}"
class="btn btn-default">
<span class="fa {{ b.icon }}"></span> {{ b.text }}
</a>
{% endfor %}
{% endif %}
<a href="{% eventurl request.event "presale:event.order" order=order.code secret=order.secret %}"
class="btn btn-default" target="_blank">
{% trans "View order as user" %}

View File

@@ -110,8 +110,6 @@ urlpatterns = [
url(r'^orders/(?P<code>[0-9A-Z]+)/change$', orders.OrderChange.as_view(),
name='event.order.change'),
url(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
url(r'^orders/(?P<code>[0-9A-Z]+)/download/(?P<output>[^/]+)$', orders.OrderDownload.as_view(),
name='event.order.download'),
url(r'^invoice/(?P<invoice>[^/]+)$', orders.InvoiceDownload.as_view(),
name='event.invoice.download'),
url(r'^orders/overview/$', orders.OverView.as_view(), name='event.orders.overview'),

View File

@@ -13,9 +13,8 @@ from django.views.generic import DetailView, ListView, TemplateView, View
from pretix.base.i18n import language
from pretix.base.models import (
CachedFile, CachedTicket, Invoice, Item, ItemVariation, Order, Quota,
CachedFile, Invoice, Item, ItemVariation, Order, Quota,
)
from pretix.base.services import tickets
from pretix.base.services.export import export
from pretix.base.services.invoices import (
generate_cancellation, generate_invoice, invoice_pdf, invoice_qualified,
@@ -29,7 +28,6 @@ from pretix.base.services.orders import (
from pretix.base.services.stats import order_overview
from pretix.base.signals import (
register_data_exporters, register_payment_providers,
register_ticket_outputs,
)
from pretix.control.forms.orders import (
CommentForm, ExporterForm, ExtendForm, OrderContactForm,
@@ -144,30 +142,10 @@ class OrderDetail(OrderView):
template_name = 'pretixcontrol/order/index.html'
permission = 'can_view_orders'
@cached_property
def download_buttons(self):
buttons = []
responses = register_ticket_outputs.send(self.request.event)
for receiver, response in responses:
provider = response(self.request.event)
if not provider.is_enabled:
continue
buttons.append({
'icon': provider.download_button_icon or 'fa-download',
'text': provider.download_button_text or 'fa-download',
'identifier': provider.identifier,
})
return buttons
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['items'] = self.get_items()
ctx['event'] = self.request.event
ctx['download_buttons'] = self.download_buttons
ctx['can_download'] = (
self.request.event.settings.ticket_download
and self.order.status == Order.STATUS_PAID
)
ctx['payment'] = self.payment_provider.order_control_render(self.request, self.object)
ctx['invoices'] = list(self.order.invoices.all().select_related('event'))
ctx['comment_form'] = CommentForm(initial={'comment': self.order.comment})
@@ -407,37 +385,6 @@ class InvoiceDownload(EventPermissionRequiredMixin, View):
return resp
class OrderDownload(OrderView):
@cached_property
def output(self):
responses = register_ticket_outputs.send(self.request.event)
for receiver, response in responses:
provider = response(self.request.event)
if provider.identifier == self.kwargs.get('output'):
return provider
def get(self, request, *args, **kwargs):
if not self.output or not self.output.is_enabled:
messages.error(request, _('You requested an invalid ticket output type.'))
return redirect(self.get_order_url())
if self.order.status != Order.STATUS_PAID:
messages.error(request, _('Order is not paid.'))
return redirect(self.get_order_url())
ct = CachedTicket.objects.get_or_create(order=self.order, provider=self.output.identifier)[0]
if not ct.cachedfile:
cf = CachedFile()
cf.date = now()
cf.expires = self.request.event.date_from + timedelta(days=30)
cf.save()
ct.cachedfile = cf
ct.save()
if not ct.cachedfile.file.name:
tickets.generate.apply_async(args=(self.order.id, self.output.identifier))
return redirect(reverse('cachedfile.download', kwargs={'id': ct.cachedfile.id}))
class OrderExtend(OrderView):
permission = 'can_change_orders'

View File

@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-01 18:22+0000\n"
"PO-Revision-Date: 2016-11-01 19:28+0100\n"
"POT-Creation-Date: 2016-11-02 13:49+0000\n"
"PO-Revision-Date: 2016-11-02 14:50+0100\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: Raphael Michel <michel@rami.io>\n"
"Language: de\n"
@@ -41,7 +41,7 @@ msgstr "Nur bezahlte Bestellungen"
#: pretix/base/exporters/orderlist.py:38 pretix/base/models/orders.py:97
#: pretix/base/services/invoices.py:243
#: pretix/control/templates/pretixcontrol/order/index.html:80
#: pretix/control/templates/pretixcontrol/order/index.html:72
#: pretix/control/templates/pretixcontrol/orders/index.html:32
#: pretix/control/templates/pretixcontrol/orders/index.html:76
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:32
@@ -67,53 +67,53 @@ msgid "Email"
msgstr "E-Mail"
#: pretix/base/exporters/orderlist.py:38 pretix/base/services/invoices.py:249
#: pretix/control/templates/pretixcontrol/order/index.html:82
#: pretix/control/templates/pretixcontrol/order/index.html:74
#: pretix/control/templates/pretixcontrol/orders/index.html:82
msgid "Order date"
msgstr "Bestelldatum"
#: pretix/base/exporters/orderlist.py:39
#: pretix/control/templates/pretixcontrol/order/index.html:274
#: pretix/control/templates/pretixcontrol/order/index.html:266
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:77
#: pretix/presale/templates/pretixpresale/event/order.html:174
#: pretix/presale/templates/pretixpresale/event/order.html:161
msgid "Company"
msgstr "Firma"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/event.py:55
#: pretix/base/models/items.py:499 pretix/base/models/organizer.py:26
#: pretix/control/templates/pretixcontrol/order/index.html:276
#: pretix/control/templates/pretixcontrol/order/index.html:268
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:79
#: pretix/presale/templates/pretixpresale/event/order.html:176
#: pretix/presale/templates/pretixpresale/event/order.html:163
#: pretix/presale/templates/pretixpresale/organizers/index.html:21
msgid "Name"
msgstr "Name"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:552
#: pretix/control/templates/pretixcontrol/order/index.html:278
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:546
#: pretix/control/templates/pretixcontrol/order/index.html:270
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:81
#: pretix/presale/templates/pretixpresale/event/order.html:178
#: pretix/presale/templates/pretixpresale/event/order.html:165
msgid "Address"
msgstr "Adresse"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:553
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:547
msgid "ZIP code"
msgstr "Postleitzahl"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:554
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:548
msgid "City"
msgstr "Ort"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:555
#: pretix/control/templates/pretixcontrol/order/index.html:282
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:549
#: pretix/control/templates/pretixcontrol/order/index.html:274
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:85
#: pretix/presale/templates/pretixpresale/event/order.html:182
#: pretix/presale/templates/pretixpresale/event/order.html:169
msgid "Country"
msgstr "Land"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:556
#: pretix/control/templates/pretixcontrol/order/index.html:285
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:550
#: pretix/control/templates/pretixcontrol/order/index.html:277
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:88
#: pretix/presale/templates/pretixpresale/event/order.html:185
#: pretix/presale/templates/pretixpresale/event/order.html:172
msgid "VAT ID"
msgstr "USt-ID"
@@ -249,7 +249,7 @@ msgstr "Zeitzone"
#: pretix/base/models/auth.py:89
#: pretix/control/templates/pretixcontrol/event/permissions.html:15
#: pretix/control/templates/pretixcontrol/order/index.html:91
#: pretix/control/templates/pretixcontrol/order/index.html:83
#: pretix/control/templates/pretixcontrol/orders/index.html:78
#: pretix/control/views/event.py:503 tests/base/test_mail.py:68
msgid "User"
@@ -339,7 +339,7 @@ msgstr "Erweiterungen"
#: pretix/base/models/event.py:99 pretix/base/models/items.py:118
#: pretix/base/models/items.py:495 pretix/base/models/orders.py:108
#: pretix/base/models/orders.py:513 pretix/base/models/vouchers.py:64
#: pretix/base/models/orders.py:507 pretix/base/models/vouchers.py:64
#: pretix/base/services/invoices.py:257
msgid "Event"
msgstr "Veranstaltung"
@@ -643,7 +643,7 @@ msgstr "Gesamtanzahl"
msgid "Leave empty for an unlimited number of tickets."
msgstr "Leer lassen für unbegrenzt viele Tickets."
#: pretix/base/models/items.py:508 pretix/base/models/orders.py:384
#: pretix/base/models/items.py:508 pretix/base/models/orders.py:378
msgid "Item"
msgstr "Produkt"
@@ -689,20 +689,20 @@ msgstr "erstattet"
msgid "Locale"
msgstr "Sprache"
#: pretix/base/models/orders.py:121 pretix/base/models/orders.py:520
#: pretix/base/models/orders.py:121 pretix/base/models/orders.py:514
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:17
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:9
#: pretix/presale/templates/pretixpresale/organizers/index.html:22
msgid "Date"
msgstr "Datum"
#: pretix/base/models/orders.py:124 pretix/base/models/orders.py:524
#: pretix/base/models/orders.py:124 pretix/base/models/orders.py:518
#: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form.html:23
msgid "Expiration date"
msgstr "Ablaufdatum"
#: pretix/base/models/orders.py:127
#: pretix/control/templates/pretixcontrol/order/index.html:85
#: pretix/control/templates/pretixcontrol/order/index.html:77
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:11
msgid "Payment date"
msgstr "Zahlungsdatum"
@@ -712,8 +712,8 @@ msgid "Payment provider"
msgstr "Zahlungsmethode"
#: pretix/base/models/orders.py:137
#: pretix/control/templates/pretixcontrol/order/index.html:216
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:84
#: pretix/control/templates/pretixcontrol/order/index.html:208
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:108
msgid "Payment method fee"
msgstr "Gebühr für gewählte Zahlungsmethode"
@@ -726,7 +726,7 @@ msgid "Payment method fee tax"
msgstr "Steuerbetrag auf Gebühr für gewählte Zahlungsmethode"
#: pretix/base/models/orders.py:148
#: pretix/control/templates/pretixcontrol/order/index.html:246
#: pretix/control/templates/pretixcontrol/order/index.html:238
msgid "Payment information"
msgstr "Zahlungsinformationen"
@@ -750,7 +750,7 @@ msgstr ""
"Der hier eingegebene Text wird dem Kunden nicht angezeigt und dient dazu, "
"Ihnen zu helfen, den Überblick zu behalten."
#: pretix/base/models/orders.py:169 pretix/base/models/orders.py:442
#: pretix/base/models/orders.py:169 pretix/base/models/orders.py:436
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13
msgid "Order"
msgstr "Bestellung"
@@ -771,7 +771,7 @@ msgstr "Die Zahlung kommt zu spät, um akzeptiert werden zu können."
msgid "Some of the ordered products are no longer available."
msgstr "Einige der ausgewählten Produkte sind nicht mehr verfügbar."
#: pretix/base/models/orders.py:351
#: pretix/base/models/orders.py:345
#: pretix/control/templates/pretixcontrol/vouchers/index.html:71
#: pretix/control/views/item.py:418 pretix/control/views/vouchers.py:78
#: pretix/control/views/vouchers.py:79 pretix/control/views/vouchers.py:82
@@ -779,7 +779,7 @@ msgstr "Einige der ausgewählten Produkte sind nicht mehr verfügbar."
msgid "Yes"
msgstr "Ja"
#: pretix/base/models/orders.py:353 pretix/control/forms/event.py:289
#: pretix/base/models/orders.py:347 pretix/control/forms/event.py:289
#: pretix/control/templates/pretixcontrol/vouchers/index.html:71
#: pretix/control/views/item.py:418 pretix/control/views/vouchers.py:78
#: pretix/control/views/vouchers.py:79 pretix/control/views/vouchers.py:82
@@ -787,61 +787,61 @@ msgstr "Ja"
msgid "No"
msgstr "Nein"
#: pretix/base/models/orders.py:390
#: pretix/base/models/orders.py:384
msgid "Variation"
msgstr "Variante"
#: pretix/base/models/orders.py:395 pretix/control/views/vouchers.py:62
#: pretix/base/models/orders.py:389 pretix/control/views/vouchers.py:62
#: pretix/plugins/checkinlists/exporters.py:81
msgid "Price"
msgstr "Preis"
#: pretix/base/models/orders.py:399
#: pretix/control/templates/pretixcontrol/order/index.html:183
#: pretix/base/models/orders.py:393
#: pretix/control/templates/pretixcontrol/order/index.html:175
#: pretix/plugins/checkinlists/exporters.py:48
#: pretix/plugins/checkinlists/exporters.py:81
#: pretix/presale/forms/checkout.py:67
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:16
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:18
msgid "Attendee name"
msgstr "Name des Teilnehmers"
#: pretix/base/models/orders.py:401
#: pretix/base/models/orders.py:395
msgid "Empty, if this product is not an admission ticket"
msgstr "Leer, wenn dies kein Eintrittsticket ist"
#: pretix/base/models/orders.py:448
#: pretix/base/models/orders.py:442
msgid "Tax rate"
msgstr "Steuersatz"
#: pretix/base/models/orders.py:452
#: pretix/base/models/orders.py:446
msgid "Tax value"
msgstr "Steuer"
#: pretix/base/models/orders.py:457
#: pretix/base/models/orders.py:451
msgid "Order position"
msgstr "Bestelltes Produkt"
#: pretix/base/models/orders.py:458
#: pretix/base/models/orders.py:452
msgid "Order positions"
msgstr "Bestellzeile"
#: pretix/base/models/orders.py:517
#: pretix/base/models/orders.py:511
msgid "Cart ID (e.g. session key)"
msgstr "Warenkorb-ID (z.B. Session-ID)"
#: pretix/base/models/orders.py:528
#: pretix/base/models/orders.py:522
msgid "Cart position"
msgstr "Produkt im Warenkorb"
#: pretix/base/models/orders.py:529
#: pretix/base/models/orders.py:523
msgid "Cart positions"
msgstr "Produkte im Warenkorb"
#: pretix/base/models/orders.py:550
#: pretix/base/models/orders.py:544
msgid "Company name"
msgstr "Firmenname"
#: pretix/base/models/orders.py:551
#: pretix/base/models/orders.py:545
msgid "Full name"
msgstr "Voller Name"
@@ -1396,12 +1396,12 @@ msgstr ""
msgid "Payment received for your order: %(code)s"
msgstr "Zahlung erhalten für die Bestellung: %(code)s"
#: pretix/base/services/orders.py:153 pretix/presale/views/order.py:434
#: pretix/presale/views/order.py:460
#: pretix/base/services/orders.py:153 pretix/presale/views/order.py:433
#: pretix/presale/views/order.py:459
msgid "You cannot cancel this order."
msgstr "Sie können diese Bestellung nicht stornieren."
#: pretix/base/services/orders.py:354 pretix/control/views/orders.py:353
#: pretix/base/services/orders.py:354 pretix/control/views/orders.py:331
#: pretix/presale/templates/pretixpresale/event/order.html:33
#, python-format
msgid "Your order: %(code)s"
@@ -1786,7 +1786,7 @@ msgstr ""
"Wenn Sie Cookies in Ihrem Browser deaktiviert haben, aktivieren Sie diese "
"bitte zumindest für diese Website."
#: pretix/control/forms/__init__.py:73
#: pretix/control/forms/__init__.py:89
msgid "Filetype not allowed!"
msgstr "Dateityp nicht erlaubt"
@@ -2417,11 +2417,11 @@ msgstr ""
msgid "The order's expiry date has been changed."
msgstr "Die Zahlungsfrist wurde geändert."
#: pretix/control/logdisplay.py:53 pretix/control/views/orders.py:256
#: pretix/control/logdisplay.py:53 pretix/control/views/orders.py:234
msgid "The order has been marked as expired."
msgstr "Die Bestellung wurde als abgelaufen markiert."
#: pretix/control/logdisplay.py:54 pretix/control/views/orders.py:242
#: pretix/control/logdisplay.py:54 pretix/control/views/orders.py:220
msgid "The order has been marked as paid."
msgstr "Die Bestellung wurde als bezahlt markiert."
@@ -2429,8 +2429,8 @@ msgstr "Die Bestellung wurde als bezahlt markiert."
msgid "The order has been refunded."
msgstr "Die Bestellung wurde zurückerstattet."
#: pretix/control/logdisplay.py:56 pretix/control/views/orders.py:245
#: pretix/presale/views/order.py:470
#: pretix/control/logdisplay.py:56 pretix/control/views/orders.py:223
#: pretix/presale/views/order.py:469
msgid "The order has been canceled."
msgstr "Die Bestellung wurde storniert."
@@ -2438,16 +2438,16 @@ msgstr "Die Bestellung wurde storniert."
msgid "The order has been created."
msgstr "Die Bestellung wurde erstellt."
#: pretix/control/logdisplay.py:58 pretix/control/views/orders.py:292
#: pretix/presale/views/order.py:360
#: pretix/control/logdisplay.py:58 pretix/control/views/orders.py:270
#: pretix/presale/views/order.py:359
msgid "The invoice has been generated."
msgstr "Die Rechnung wurde erstellt."
#: pretix/control/logdisplay.py:59 pretix/control/views/orders.py:315
#: pretix/control/logdisplay.py:59 pretix/control/views/orders.py:293
msgid "The invoice has been regenerated."
msgstr "Die Rechnung wurde neu generiert."
#: pretix/control/logdisplay.py:60 pretix/control/views/orders.py:339
#: pretix/control/logdisplay.py:60 pretix/control/views/orders.py:317
msgid "The invoice has been reissued."
msgstr "Die Rechnung wurde neu ausgestellt."
@@ -2856,7 +2856,7 @@ msgid "Free order"
msgstr "Kostenlose Bestellung"
#: pretix/control/templates/pretixcontrol/event/mail.html:62
#: pretix/control/templates/pretixcontrol/order/index.html:102
#: pretix/control/templates/pretixcontrol/order/index.html:94
msgid "Resend link"
msgstr "Link erneut senden"
@@ -2903,7 +2903,7 @@ msgid "Change settings"
msgstr "Kann Einstellungen ändern"
#: pretix/control/templates/pretixcontrol/event/permissions.html:17
#: pretix/control/templates/pretixcontrol/order/index.html:158
#: pretix/control/templates/pretixcontrol/order/index.html:150
msgid "Change products"
msgstr "Produkte bearbeiten"
@@ -3014,7 +3014,7 @@ msgstr "Allgemeines"
#: pretix/control/templates/pretixcontrol/event/settings_base.html:16
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:53
#: pretix/presale/templates/pretixpresale/event/order.html:51
#: pretix/presale/templates/pretixpresale/event/order.html:212
#: pretix/presale/templates/pretixpresale/event/order.html:199
msgid "Payment"
msgstr "Zahlung"
@@ -3027,7 +3027,6 @@ msgid "Tickets"
msgstr "Tickets"
#: pretix/control/templates/pretixcontrol/event/tickets.html:8
#: pretix/presale/templates/pretixpresale/event/order.html:72
msgid "Ticket download"
msgstr "Ticket-Download"
@@ -3536,7 +3535,7 @@ msgstr "Verbleibende Kapazität"
#: pretix/control/templates/pretixcontrol/order/cancel.html:4
#: pretix/control/templates/pretixcontrol/order/cancel.html:8
#: pretix/control/templates/pretixcontrol/order/index.html:32
#: pretix/presale/templates/pretixpresale/event/order.html:202
#: pretix/presale/templates/pretixpresale/event/order.html:189
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:4
msgid "Cancel order"
msgstr "Stornieren"
@@ -3658,15 +3657,15 @@ msgstr "Als nicht bezahlt markieren"
msgid "Refund order"
msgstr "Bestellung erstatten"
#: pretix/control/templates/pretixcontrol/order/index.html:51
#: pretix/control/templates/pretixcontrol/order/index.html:43
msgid "View order as user"
msgstr "Als Kunde ansehen"
#: pretix/control/templates/pretixcontrol/order/index.html:63
#: pretix/control/templates/pretixcontrol/order/index.html:55
msgid "Expire order"
msgstr "Als abgelaufen markieren"
#: pretix/control/templates/pretixcontrol/order/index.html:64
#: pretix/control/templates/pretixcontrol/order/index.html:56
msgid ""
"The payment for this order is overdue, but you have configured not to expire "
"orders automatically. To free quota capacity, you can mark it as expired "
@@ -3677,66 +3676,66 @@ msgstr ""
"Kontingent zu schaffen, können Sie die Bestellung manuell als abgelaufen "
"markieren."
#: pretix/control/templates/pretixcontrol/order/index.html:75
#: pretix/control/templates/pretixcontrol/order/index.html:67
#: pretix/presale/templates/pretixpresale/event/order.html:6
msgid "Order details"
msgstr "Bestellung"
#: pretix/control/templates/pretixcontrol/order/index.html:88
#: pretix/control/templates/pretixcontrol/order/index.html:80
msgid "Expiry date"
msgstr "Ablaufdatum"
#: pretix/control/templates/pretixcontrol/order/index.html:108
#: pretix/control/templates/pretixcontrol/order/index.html:138
#: pretix/presale/templates/pretixpresale/event/order.html:120
#: pretix/presale/templates/pretixpresale/event/order.html:141
#: pretix/control/templates/pretixcontrol/order/index.html:100
#: pretix/control/templates/pretixcontrol/order/index.html:130
#: pretix/presale/templates/pretixpresale/event/order.html:107
#: pretix/presale/templates/pretixpresale/event/order.html:128
msgid "Invoices"
msgstr "Rechnungen"
#: pretix/control/templates/pretixcontrol/order/index.html:112
#: pretix/presale/templates/pretixpresale/event/order.html:128
#: pretix/control/templates/pretixcontrol/order/index.html:104
#: pretix/presale/templates/pretixpresale/event/order.html:115
msgid "Cancellation"
msgstr "Rechnungskorrektur"
#: pretix/control/templates/pretixcontrol/order/index.html:112
#: pretix/presale/templates/pretixpresale/event/order.html:128
#: pretix/control/templates/pretixcontrol/order/index.html:104
#: pretix/presale/templates/pretixpresale/event/order.html:115
msgid "Invoice"
msgstr "Rechnung"
#: pretix/control/templates/pretixcontrol/order/index.html:119
#: pretix/control/templates/pretixcontrol/order/index.html:111
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html:20
msgid "Regenerate"
msgstr "Neu generieren"
#: pretix/control/templates/pretixcontrol/order/index.html:127
#: pretix/control/templates/pretixcontrol/order/index.html:119
msgid "Cancel and reissue"
msgstr "Stornieren und neu ausstellen"
#: pretix/control/templates/pretixcontrol/order/index.html:144
#: pretix/control/templates/pretixcontrol/order/index.html:136
msgid "Generate invoice"
msgstr "Rechnungen ausstellen"
#: pretix/control/templates/pretixcontrol/order/index.html:163
#: pretix/presale/templates/pretixpresale/event/order.html:106
#: pretix/control/templates/pretixcontrol/order/index.html:155
#: pretix/presale/templates/pretixpresale/event/order.html:93
msgid "Ordered items"
msgstr "Bestellte Produkte"
#: pretix/control/templates/pretixcontrol/order/index.html:175
#: pretix/control/templates/pretixcontrol/order/index.html:167
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:11
msgid "Voucher code used:"
msgstr "Verwendeter Gutscheincode:"
#: pretix/control/templates/pretixcontrol/order/index.html:185
#: pretix/control/templates/pretixcontrol/order/index.html:190
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:17
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:21
#: pretix/control/templates/pretixcontrol/order/index.html:177
#: pretix/control/templates/pretixcontrol/order/index.html:182
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:19
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:23
msgid "not answered"
msgstr "nicht beantwortet"
#: pretix/control/templates/pretixcontrol/order/index.html:205
#: pretix/control/templates/pretixcontrol/order/index.html:222
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:72
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:90
#: pretix/control/templates/pretixcontrol/order/index.html:197
#: pretix/control/templates/pretixcontrol/order/index.html:214
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:86
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:114
#: pretix/presale/templates/pretixpresale/event/index.html:132
#: pretix/presale/templates/pretixpresale/event/index.html:182
#: pretix/presale/templates/pretixpresale/event/voucher.html:74
@@ -3745,45 +3744,45 @@ msgstr "nicht beantwortet"
msgid "incl. %(rate)s%% taxes"
msgstr "inkl. %(rate)s%% MwSt."
#: pretix/control/templates/pretixcontrol/order/index.html:232
#: pretix/control/templates/pretixcontrol/order/index.html:224
#: pretix/control/templates/pretixcontrol/orders/overview.html:85
#: pretix/plugins/reports/exporters.py:199
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:100
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:124
msgid "Total"
msgstr "Gesamt"
#: pretix/control/templates/pretixcontrol/order/index.html:252
#: pretix/control/templates/pretixcontrol/order/index.html:244
msgid "The payment state of this order was manually modified."
msgstr "Der Status dieser Bestellung wurde manuell verändert."
#: pretix/control/templates/pretixcontrol/order/index.html:257
#: pretix/control/templates/pretixcontrol/order/index.html:249
#, python-format
msgid "The payment has to be completed before %(date)s."
msgstr "Die Zahlung muss bis zum %(date)s abgeschlossen sein."
#: pretix/control/templates/pretixcontrol/order/index.html:269
#: pretix/control/templates/pretixcontrol/order/index.html:261
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:72
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:30
#: pretix/presale/templates/pretixpresale/event/order.html:169
#: pretix/presale/templates/pretixpresale/event/order.html:156
#: pretix/presale/templates/pretixpresale/event/order_modify.html:25
msgid "Invoice information"
msgstr "Rechnungsinformationen"
#: pretix/control/templates/pretixcontrol/order/index.html:280
#: pretix/control/templates/pretixcontrol/order/index.html:272
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:83
#: pretix/presale/templates/pretixpresale/event/order.html:180
#: pretix/presale/templates/pretixpresale/event/order.html:167
msgid "ZIP code and city"
msgstr "PLZ und Ort"
#: pretix/control/templates/pretixcontrol/order/index.html:297
#: pretix/control/templates/pretixcontrol/order/index.html:289
msgid "Internal comment"
msgstr "Interner Kommentar"
#: pretix/control/templates/pretixcontrol/order/index.html:308
#: pretix/control/templates/pretixcontrol/order/index.html:300
msgid "Update comment"
msgstr "Kommentar speichern"
#: pretix/control/templates/pretixcontrol/order/index.html:319
#: pretix/control/templates/pretixcontrol/order/index.html:311
msgid "Order history"
msgstr "Bestellverlauf"
@@ -4263,7 +4262,7 @@ msgid "We already sent you an email in the last 24 hours."
msgstr ""
"Wir haben Ihnen in den letzten 24 Stunden bereits eine E-Mail geschickt."
#: pretix/control/views/auth.py:140 pretix/control/views/orders.py:365
#: pretix/control/views/auth.py:140 pretix/control/views/orders.py:343
msgid "There was an error sending the mail. Please try again later."
msgstr ""
"Es gab ein Fehler beim Senden der E-Mail. Bitte probieren Sie es später "
@@ -4417,8 +4416,7 @@ msgstr ""
"\"Eigenen SMTP-Server verwenden\" zu setzen, damit der Server auch benutzt "
"wird."
#: pretix/control/views/event.py:395 pretix/control/views/orders.py:422
#: pretix/presale/views/order.py:491
#: pretix/control/views/event.py:395 pretix/presale/views/order.py:498
msgid "You requested an invalid ticket output type."
msgstr "Sie haben einen ungültigen Ausgabetyp gewählt."
@@ -4540,15 +4538,15 @@ msgstr "Das ausgewählte Produkt wurde deaktiviert."
msgid "The new event has been created."
msgstr "Eine neue Veranstaltung wurde erstellt."
#: pretix/control/views/orders.py:223
#: pretix/control/views/orders.py:201
msgid "The comment has been updated."
msgstr "Der Kommentar wurde aktualisiert."
#: pretix/control/views/orders.py:225
#: pretix/control/views/orders.py:203
msgid "Could not update the comment."
msgstr "Kommentar konnte nicht gespeichert werden."
#: pretix/control/views/orders.py:240
#: pretix/control/views/orders.py:218
msgid ""
"The order has been marked as paid, but we were unable to send a confirmation "
"mail."
@@ -4556,35 +4554,35 @@ msgstr ""
"Die Bestellung wurde als bezahlt markiert, aber die Bestätigungsmail konnte "
"nicht verschickt werden."
#: pretix/control/views/orders.py:251
#: pretix/control/views/orders.py:229
msgid "The order has been marked as not paid."
msgstr "Die Bestellung wurde als nicht bezahlt markiert."
#: pretix/control/views/orders.py:284 pretix/presale/views/order.py:352
#: pretix/control/views/orders.py:262 pretix/presale/views/order.py:351
msgid "You cannot generate an invoice for this order."
msgstr "Sie können für diese Bestellung keine Rechnung erzeugen."
#: pretix/control/views/orders.py:286 pretix/presale/views/order.py:354
#: pretix/control/views/orders.py:264 pretix/presale/views/order.py:353
msgid "An invoice for this order already exists."
msgstr "Zu dieser Bestellung gibt es bereits eine Rechnung."
#: pretix/control/views/orders.py:306 pretix/control/views/orders.py:329
#: pretix/control/views/orders.py:284 pretix/control/views/orders.py:307
msgid "Unknown invoice."
msgstr "Unbekannte Rechnung"
#: pretix/control/views/orders.py:309 pretix/control/views/orders.py:332
#: pretix/control/views/orders.py:287 pretix/control/views/orders.py:310
msgid "The invoice has already been canceled."
msgstr "Die Rechnung wurde bereits storniert."
#: pretix/control/views/orders.py:368
#: pretix/control/views/orders.py:346
msgid "The email has been queued to be sent."
msgstr "Die E-Mail wurde zum Versenden gespeichert."
#: pretix/control/views/orders.py:393 pretix/presale/views/order.py:529
#: pretix/control/views/orders.py:371 pretix/presale/views/order.py:538
msgid "This invoice has not been found"
msgstr "Diese Rechnung wurde nicht gefunden"
#: pretix/control/views/orders.py:401 pretix/presale/views/order.py:537
#: pretix/control/views/orders.py:379 pretix/presale/views/order.py:546
msgid ""
"The invoice file has not yet been generated, we will generate it for you "
"now. Please try again in a few seconds."
@@ -4592,15 +4590,11 @@ msgstr ""
"Diese Rechnung wurde bisher noch nicht fertig erstellt, wir werden die PDF-"
"Datei jetzt erstellen. Bitte probieren Sie es in wenigen Sekunden erneut."
#: pretix/control/views/orders.py:425 pretix/presale/views/order.py:496
msgid "Order is not paid."
msgstr "Die Bestellung ist nicht bezahlt."
#: pretix/control/views/orders.py:447 pretix/control/views/orders.py:465
#: pretix/control/views/orders.py:394 pretix/control/views/orders.py:412
msgid "The payment term has been changed."
msgstr "Die Zahlungsfrist wurde geändert."
#: pretix/control/views/orders.py:469
#: pretix/control/views/orders.py:416
msgid ""
"We were not able to process the request completely as the server was too "
"busy."
@@ -4608,32 +4602,32 @@ msgstr ""
"Wir konnten Ihre Bestellung nicht durchführen, da der Server zu beschäftigt "
"war."
#: pretix/control/views/orders.py:477 pretix/control/views/orders.py:499
#: pretix/control/views/orders.py:424 pretix/control/views/orders.py:446
msgid "This action is only allowed for pending orders."
msgstr "Diese Aktion ist nur für unbezahlte Bestellungen möglich."
#: pretix/control/views/orders.py:548
#: pretix/control/views/orders.py:495
msgid "An error occured. Please see the details below."
msgstr ""
"Ein Fehler ist aufgetreten, bitte schauen Sie weiter unten für Details."
#: pretix/control/views/orders.py:555
#: pretix/control/views/orders.py:502
msgid "The order has been changed and the user has been notified."
msgstr "Die Bestellung wurde geändert und der Kunde benachrichtigt."
#: pretix/control/views/orders.py:584
#: pretix/control/views/orders.py:531
msgid "The order has been changed."
msgstr "Die Bestellung wurde geändert."
#: pretix/control/views/orders.py:619
#: pretix/control/views/orders.py:566
msgid "There is no order with the given order code."
msgstr "Es existiert keine Bestellung mit der eingegebenen Bestellnummer."
#: pretix/control/views/orders.py:653
#: pretix/control/views/orders.py:600
msgid "The selected exporter was not found."
msgstr "Das ausgewählte Exportformat wurde nicht gefunden."
#: pretix/control/views/orders.py:659
#: pretix/control/views/orders.py:606
msgid "There was a problem processing your input. See below for error details."
msgstr "Die Eingabe konnte nicht verarbeitet werden."
@@ -5628,8 +5622,8 @@ msgid "PDF output"
msgstr "PDF-Ausgabe"
#: pretix/plugins/ticketoutputpdf/ticketoutput.py:21
msgid "Download PDF"
msgstr "PDF herunterladen"
msgid "PDF"
msgstr "PDF"
#: pretix/plugins/ticketoutputpdf/ticketoutput.py:57
#, python-brace-format
@@ -5752,7 +5746,7 @@ msgstr "Teilnehmername-Größe (mm)"
msgid "Invisible by default, set this to a number greater than 0 to show."
msgstr "Standardmäßig unsichtbar, eine positive Größe zeigt das Element an."
#: pretix/presale/checkoutflow.py:167 pretix/presale/views/order.py:394
#: pretix/presale/checkoutflow.py:167 pretix/presale/views/order.py:393
msgid ""
"We had difficulties processing your input. Please review the errors below."
msgstr "Wir hatten Schwierigkeiten, Ihre Eingabe zu verarbeiten."
@@ -5765,12 +5759,12 @@ msgstr "Bitte geben Sie eine gültige E-Mail-Adresse ein."
msgid "Please fill in answers to all required questions."
msgstr "Bitte füllen Sie Antworten zu allen benötigten Fragen ein."
#: pretix/presale/checkoutflow.py:255 pretix/presale/views/order.py:326
#: pretix/presale/checkoutflow.py:255 pretix/presale/views/order.py:325
msgid "Please select a payment method."
msgstr "Bitte wählen Sie eine Zahlungsmethode aus."
#: pretix/presale/checkoutflow.py:276 pretix/presale/checkoutflow.py:282
#: pretix/presale/views/order.py:196 pretix/presale/views/order.py:232
#: pretix/presale/views/order.py:195 pretix/presale/views/order.py:231
msgid "The payment information you entered was incomplete."
msgstr "Die eingegebenen Zahlungsinformationen sind unvollständig."
@@ -6032,25 +6026,25 @@ msgstr "Zahlung abschließen"
msgid "Please complete your payment before %(date)s"
msgstr "Bitte schließen Sie Ihre Zahlung bis zum %(date)s ab."
#: pretix/presale/templates/pretixpresale/event/order.html:77
#: pretix/presale/templates/pretixpresale/event/order.html:72
msgid ""
"Please obtain your ticket below. Please have your ticket ready when entering "
"the event."
"You can download your tickets using the buttons below. Please have your "
"ticket ready when entering the event."
msgstr ""
"Bitte laden Sie Ihr Ticket hier herunter. Bitte halten Sie das Ticket am "
"Einlass bereit."
"Bitte laden Sie Ihr Ticket mit Hilfe der Buttons weiter unten herunter. "
"Bitte halten Sie das Ticket am Einlass bereit."
#: pretix/presale/templates/pretixpresale/event/order.html:88
#: pretix/presale/templates/pretixpresale/event/order.html:76
#, python-format
msgid "You will be able to download your tickets here starting on %(date)s."
msgstr "Sie können Ihre Tickets hier ab %(date)s herunterladen."
#: pretix/presale/templates/pretixpresale/event/order.html:101
#: pretix/presale/templates/pretixpresale/event/order.html:164
#: pretix/presale/templates/pretixpresale/event/order.html:88
#: pretix/presale/templates/pretixpresale/event/order.html:151
msgid "Change details"
msgstr "Details bearbeiten"
#: pretix/presale/templates/pretixpresale/event/order.html:149
#: pretix/presale/templates/pretixpresale/event/order.html:136
msgid "Request invoice"
msgstr "Rechnung anfragen"
@@ -6232,29 +6226,33 @@ msgstr "Die gewählten Produkte wurden Ihrem Warenkorb hinzugefügt."
msgid "Your cart is empty"
msgstr "Ihr Warenkorb ist leer."
#: pretix/presale/views/order.py:70 pretix/presale/views/order.py:142
#: pretix/presale/views/order.py:189 pretix/presale/views/order.py:229
#: pretix/presale/views/order.py:256 pretix/presale/views/order.py:347
#: pretix/presale/views/order.py:411 pretix/presale/views/order.py:432
#: pretix/presale/views/order.py:458 pretix/presale/views/order.py:494
#: pretix/presale/views/order.py:520
#: pretix/presale/views/order.py:70 pretix/presale/views/order.py:141
#: pretix/presale/views/order.py:188 pretix/presale/views/order.py:228
#: pretix/presale/views/order.py:255 pretix/presale/views/order.py:346
#: pretix/presale/views/order.py:410 pretix/presale/views/order.py:431
#: pretix/presale/views/order.py:457 pretix/presale/views/order.py:501
#: pretix/presale/views/order.py:529
msgid "Unknown order code or not authorized to access this order."
msgstr ""
"Unbekannte Bestellnummer oder Bestellung gehört einem anderen Benutzer."
#: pretix/presale/views/order.py:146 pretix/presale/views/order.py:192
#: pretix/presale/views/order.py:145 pretix/presale/views/order.py:191
msgid "The payment for this order cannot be continued."
msgstr "Diese Bestellung kann nicht mehr bezahlt werden."
#: pretix/presale/views/order.py:258
#: pretix/presale/views/order.py:257
msgid "The payment method for this order cannot be changed."
msgstr "Die Zahlungsmethode für diese Bestellung kann nicht geändert werden."
#: pretix/presale/views/order.py:413
#: pretix/presale/views/order.py:412
msgid "You cannot modify this order"
msgstr "Sie können diese Bestellung nicht bearbeiten"
#: pretix/presale/views/order.py:501
#: pretix/presale/views/order.py:503
msgid "Order is not paid."
msgstr "Die Bestellung ist nicht bezahlt."
#: pretix/presale/views/order.py:508
msgid "Ticket download is not (yet) enabled."
msgstr "Der Ticket-Download ist (noch) nicht freigeschaltet."
@@ -6292,6 +6290,9 @@ msgstr "Deutsch"
msgid "German (informal)"
msgstr "Deutsch (Du)"
#~ msgid "Download PDF"
#~ msgstr "PDF herunterladen"
#~ msgid "A voucher you tried to use already has been used."
#~ msgstr ""
#~ "Ein Gutscheincode, den Sie verwenden wollten, wurde zwischenzeitlich "

View File

@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-11-01 18:22+0000\n"
"PO-Revision-Date: 2016-11-01 19:28+0100\n"
"POT-Creation-Date: 2016-11-02 13:49+0000\n"
"PO-Revision-Date: 2016-11-02 14:50+0100\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: Raphael Michel <michel@rami.io>\n"
"Language: de\n"
@@ -41,7 +41,7 @@ msgstr "Nur bezahlte Bestellungen"
#: pretix/base/exporters/orderlist.py:38 pretix/base/models/orders.py:97
#: pretix/base/services/invoices.py:243
#: pretix/control/templates/pretixcontrol/order/index.html:80
#: pretix/control/templates/pretixcontrol/order/index.html:72
#: pretix/control/templates/pretixcontrol/orders/index.html:32
#: pretix/control/templates/pretixcontrol/orders/index.html:76
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:32
@@ -67,53 +67,53 @@ msgid "Email"
msgstr "E-Mail"
#: pretix/base/exporters/orderlist.py:38 pretix/base/services/invoices.py:249
#: pretix/control/templates/pretixcontrol/order/index.html:82
#: pretix/control/templates/pretixcontrol/order/index.html:74
#: pretix/control/templates/pretixcontrol/orders/index.html:82
msgid "Order date"
msgstr "Bestelldatum"
#: pretix/base/exporters/orderlist.py:39
#: pretix/control/templates/pretixcontrol/order/index.html:274
#: pretix/control/templates/pretixcontrol/order/index.html:266
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:77
#: pretix/presale/templates/pretixpresale/event/order.html:174
#: pretix/presale/templates/pretixpresale/event/order.html:161
msgid "Company"
msgstr "Firma"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/event.py:55
#: pretix/base/models/items.py:499 pretix/base/models/organizer.py:26
#: pretix/control/templates/pretixcontrol/order/index.html:276
#: pretix/control/templates/pretixcontrol/order/index.html:268
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:79
#: pretix/presale/templates/pretixpresale/event/order.html:176
#: pretix/presale/templates/pretixpresale/event/order.html:163
#: pretix/presale/templates/pretixpresale/organizers/index.html:21
msgid "Name"
msgstr "Name"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:552
#: pretix/control/templates/pretixcontrol/order/index.html:278
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:546
#: pretix/control/templates/pretixcontrol/order/index.html:270
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:81
#: pretix/presale/templates/pretixpresale/event/order.html:178
#: pretix/presale/templates/pretixpresale/event/order.html:165
msgid "Address"
msgstr "Adresse"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:553
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:547
msgid "ZIP code"
msgstr "Postleitzahl"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:554
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:548
msgid "City"
msgstr "Ort"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:555
#: pretix/control/templates/pretixcontrol/order/index.html:282
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:549
#: pretix/control/templates/pretixcontrol/order/index.html:274
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:85
#: pretix/presale/templates/pretixpresale/event/order.html:182
#: pretix/presale/templates/pretixpresale/event/order.html:169
msgid "Country"
msgstr "Land"
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:556
#: pretix/control/templates/pretixcontrol/order/index.html:285
#: pretix/base/exporters/orderlist.py:39 pretix/base/models/orders.py:550
#: pretix/control/templates/pretixcontrol/order/index.html:277
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:88
#: pretix/presale/templates/pretixpresale/event/order.html:185
#: pretix/presale/templates/pretixpresale/event/order.html:172
msgid "VAT ID"
msgstr "USt-ID"
@@ -249,7 +249,7 @@ msgstr "Zeitzone"
#: pretix/base/models/auth.py:89
#: pretix/control/templates/pretixcontrol/event/permissions.html:15
#: pretix/control/templates/pretixcontrol/order/index.html:91
#: pretix/control/templates/pretixcontrol/order/index.html:83
#: pretix/control/templates/pretixcontrol/orders/index.html:78
#: pretix/control/views/event.py:503 tests/base/test_mail.py:68
msgid "User"
@@ -339,7 +339,7 @@ msgstr "Erweiterungen"
#: pretix/base/models/event.py:99 pretix/base/models/items.py:118
#: pretix/base/models/items.py:495 pretix/base/models/orders.py:108
#: pretix/base/models/orders.py:513 pretix/base/models/vouchers.py:64
#: pretix/base/models/orders.py:507 pretix/base/models/vouchers.py:64
#: pretix/base/services/invoices.py:257
msgid "Event"
msgstr "Veranstaltung"
@@ -643,7 +643,7 @@ msgstr "Gesamtanzahl"
msgid "Leave empty for an unlimited number of tickets."
msgstr "Leer lassen für unbegrenzt viele Tickets."
#: pretix/base/models/items.py:508 pretix/base/models/orders.py:384
#: pretix/base/models/items.py:508 pretix/base/models/orders.py:378
msgid "Item"
msgstr "Produkt"
@@ -689,20 +689,20 @@ msgstr "erstattet"
msgid "Locale"
msgstr "Sprache"
#: pretix/base/models/orders.py:121 pretix/base/models/orders.py:520
#: pretix/base/models/orders.py:121 pretix/base/models/orders.py:514
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:17
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:9
#: pretix/presale/templates/pretixpresale/organizers/index.html:22
msgid "Date"
msgstr "Datum"
#: pretix/base/models/orders.py:124 pretix/base/models/orders.py:524
#: pretix/base/models/orders.py:124 pretix/base/models/orders.py:518
#: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_form.html:23
msgid "Expiration date"
msgstr "Ablaufdatum"
#: pretix/base/models/orders.py:127
#: pretix/control/templates/pretixcontrol/order/index.html:85
#: pretix/control/templates/pretixcontrol/order/index.html:77
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:11
msgid "Payment date"
msgstr "Zahlungsdatum"
@@ -712,8 +712,8 @@ msgid "Payment provider"
msgstr "Zahlungsmethode"
#: pretix/base/models/orders.py:137
#: pretix/control/templates/pretixcontrol/order/index.html:216
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:84
#: pretix/control/templates/pretixcontrol/order/index.html:208
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:108
msgid "Payment method fee"
msgstr "Gebühr für gewählte Zahlungsmethode"
@@ -726,7 +726,7 @@ msgid "Payment method fee tax"
msgstr "Steuerbetrag auf Gebühr für gewählte Zahlungsmethode"
#: pretix/base/models/orders.py:148
#: pretix/control/templates/pretixcontrol/order/index.html:246
#: pretix/control/templates/pretixcontrol/order/index.html:238
msgid "Payment information"
msgstr "Zahlungsinformationen"
@@ -750,7 +750,7 @@ msgstr ""
"Der hier eingegebene Text wird dem Kunden nicht angezeigt und dient dazu, "
"dir zu helfen, den Überblick zu behalten."
#: pretix/base/models/orders.py:169 pretix/base/models/orders.py:442
#: pretix/base/models/orders.py:169 pretix/base/models/orders.py:436
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13
msgid "Order"
msgstr "Bestellung"
@@ -771,7 +771,7 @@ msgstr "Die Zahlung kommt zu spät, um akzeptiert werden zu können."
msgid "Some of the ordered products are no longer available."
msgstr "Einige der ausgewählten Produkte sind nicht mehr verfügbar."
#: pretix/base/models/orders.py:351
#: pretix/base/models/orders.py:345
#: pretix/control/templates/pretixcontrol/vouchers/index.html:71
#: pretix/control/views/item.py:418 pretix/control/views/vouchers.py:78
#: pretix/control/views/vouchers.py:79 pretix/control/views/vouchers.py:82
@@ -779,7 +779,7 @@ msgstr "Einige der ausgewählten Produkte sind nicht mehr verfügbar."
msgid "Yes"
msgstr "Ja"
#: pretix/base/models/orders.py:353 pretix/control/forms/event.py:289
#: pretix/base/models/orders.py:347 pretix/control/forms/event.py:289
#: pretix/control/templates/pretixcontrol/vouchers/index.html:71
#: pretix/control/views/item.py:418 pretix/control/views/vouchers.py:78
#: pretix/control/views/vouchers.py:79 pretix/control/views/vouchers.py:82
@@ -787,61 +787,61 @@ msgstr "Ja"
msgid "No"
msgstr "Nein"
#: pretix/base/models/orders.py:390
#: pretix/base/models/orders.py:384
msgid "Variation"
msgstr "Variante"
#: pretix/base/models/orders.py:395 pretix/control/views/vouchers.py:62
#: pretix/base/models/orders.py:389 pretix/control/views/vouchers.py:62
#: pretix/plugins/checkinlists/exporters.py:81
msgid "Price"
msgstr "Preis"
#: pretix/base/models/orders.py:399
#: pretix/control/templates/pretixcontrol/order/index.html:183
#: pretix/base/models/orders.py:393
#: pretix/control/templates/pretixcontrol/order/index.html:175
#: pretix/plugins/checkinlists/exporters.py:48
#: pretix/plugins/checkinlists/exporters.py:81
#: pretix/presale/forms/checkout.py:67
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:16
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:18
msgid "Attendee name"
msgstr "Name des Teilnehmers"
#: pretix/base/models/orders.py:401
#: pretix/base/models/orders.py:395
msgid "Empty, if this product is not an admission ticket"
msgstr "Leer, wenn dies kein Eintrittsticket ist"
#: pretix/base/models/orders.py:448
#: pretix/base/models/orders.py:442
msgid "Tax rate"
msgstr "Steuersatz"
#: pretix/base/models/orders.py:452
#: pretix/base/models/orders.py:446
msgid "Tax value"
msgstr "Steuer"
#: pretix/base/models/orders.py:457
#: pretix/base/models/orders.py:451
msgid "Order position"
msgstr "Bestelltes Produkt"
#: pretix/base/models/orders.py:458
#: pretix/base/models/orders.py:452
msgid "Order positions"
msgstr "Bestellzeile"
#: pretix/base/models/orders.py:517
#: pretix/base/models/orders.py:511
msgid "Cart ID (e.g. session key)"
msgstr "Warenkorb-ID (z.B. Session-ID)"
#: pretix/base/models/orders.py:528
#: pretix/base/models/orders.py:522
msgid "Cart position"
msgstr "Produkt im Warenkorb"
#: pretix/base/models/orders.py:529
#: pretix/base/models/orders.py:523
msgid "Cart positions"
msgstr "Produkte im Warenkorb"
#: pretix/base/models/orders.py:550
#: pretix/base/models/orders.py:544
msgid "Company name"
msgstr "Firmenname"
#: pretix/base/models/orders.py:551
#: pretix/base/models/orders.py:545
msgid "Full name"
msgstr "Voller Name"
@@ -1394,12 +1394,12 @@ msgstr ""
msgid "Payment received for your order: %(code)s"
msgstr "Zahlung erhalten für die Bestellung: %(code)s"
#: pretix/base/services/orders.py:153 pretix/presale/views/order.py:434
#: pretix/presale/views/order.py:460
#: pretix/base/services/orders.py:153 pretix/presale/views/order.py:433
#: pretix/presale/views/order.py:459
msgid "You cannot cancel this order."
msgstr "Du kannst diese Bestellung nicht stornieren."
#: pretix/base/services/orders.py:354 pretix/control/views/orders.py:353
#: pretix/base/services/orders.py:354 pretix/control/views/orders.py:331
#: pretix/presale/templates/pretixpresale/event/order.html:33
#, python-format
msgid "Your order: %(code)s"
@@ -1782,7 +1782,7 @@ msgstr ""
"Wenn du Cookies in deinem Browser deaktiviert hast, aktiviere diese bitte "
"zumindest für diese Website."
#: pretix/control/forms/__init__.py:73
#: pretix/control/forms/__init__.py:89
msgid "Filetype not allowed!"
msgstr "Dateityp nicht erlaubt!"
@@ -2411,11 +2411,11 @@ msgstr ""
msgid "The order's expiry date has been changed."
msgstr "Die Zahlungsfrist wurde geändert."
#: pretix/control/logdisplay.py:53 pretix/control/views/orders.py:256
#: pretix/control/logdisplay.py:53 pretix/control/views/orders.py:234
msgid "The order has been marked as expired."
msgstr "Die Bestellung wurde als abgelaufen markiert."
#: pretix/control/logdisplay.py:54 pretix/control/views/orders.py:242
#: pretix/control/logdisplay.py:54 pretix/control/views/orders.py:220
msgid "The order has been marked as paid."
msgstr "Die Bestellung wurde als bezahlt markiert."
@@ -2423,8 +2423,8 @@ msgstr "Die Bestellung wurde als bezahlt markiert."
msgid "The order has been refunded."
msgstr "Die Bestellung wurde zurückerstattet."
#: pretix/control/logdisplay.py:56 pretix/control/views/orders.py:245
#: pretix/presale/views/order.py:470
#: pretix/control/logdisplay.py:56 pretix/control/views/orders.py:223
#: pretix/presale/views/order.py:469
msgid "The order has been canceled."
msgstr "Die Bestellung wurde storniert."
@@ -2432,16 +2432,16 @@ msgstr "Die Bestellung wurde storniert."
msgid "The order has been created."
msgstr "Die Bestellung wurde erstellt."
#: pretix/control/logdisplay.py:58 pretix/control/views/orders.py:292
#: pretix/presale/views/order.py:360
#: pretix/control/logdisplay.py:58 pretix/control/views/orders.py:270
#: pretix/presale/views/order.py:359
msgid "The invoice has been generated."
msgstr "Die Rechnung wurde erstellt."
#: pretix/control/logdisplay.py:59 pretix/control/views/orders.py:315
#: pretix/control/logdisplay.py:59 pretix/control/views/orders.py:293
msgid "The invoice has been regenerated."
msgstr "Die Rechnung wurde neu generiert."
#: pretix/control/logdisplay.py:60 pretix/control/views/orders.py:339
#: pretix/control/logdisplay.py:60 pretix/control/views/orders.py:317
msgid "The invoice has been reissued."
msgstr "Die Rechnung wurde neu ausgestellt."
@@ -2847,7 +2847,7 @@ msgid "Free order"
msgstr "Kostenlose Bestellung"
#: pretix/control/templates/pretixcontrol/event/mail.html:62
#: pretix/control/templates/pretixcontrol/order/index.html:102
#: pretix/control/templates/pretixcontrol/order/index.html:94
msgid "Resend link"
msgstr "Link erneut senden"
@@ -2893,7 +2893,7 @@ msgid "Change settings"
msgstr "Kann Einstellungen ändern"
#: pretix/control/templates/pretixcontrol/event/permissions.html:17
#: pretix/control/templates/pretixcontrol/order/index.html:158
#: pretix/control/templates/pretixcontrol/order/index.html:150
msgid "Change products"
msgstr "Produkte bearbeiten"
@@ -3004,7 +3004,7 @@ msgstr "Allgemeines"
#: pretix/control/templates/pretixcontrol/event/settings_base.html:16
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:53
#: pretix/presale/templates/pretixpresale/event/order.html:51
#: pretix/presale/templates/pretixpresale/event/order.html:212
#: pretix/presale/templates/pretixpresale/event/order.html:199
msgid "Payment"
msgstr "Zahlung"
@@ -3017,7 +3017,6 @@ msgid "Tickets"
msgstr "Tickets"
#: pretix/control/templates/pretixcontrol/event/tickets.html:8
#: pretix/presale/templates/pretixpresale/event/order.html:72
msgid "Ticket download"
msgstr "Ticket-Download"
@@ -3524,7 +3523,7 @@ msgstr "Verbleibende Kapazität"
#: pretix/control/templates/pretixcontrol/order/cancel.html:4
#: pretix/control/templates/pretixcontrol/order/cancel.html:8
#: pretix/control/templates/pretixcontrol/order/index.html:32
#: pretix/presale/templates/pretixpresale/event/order.html:202
#: pretix/presale/templates/pretixpresale/event/order.html:189
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:4
msgid "Cancel order"
msgstr "Stornieren"
@@ -3646,15 +3645,15 @@ msgstr "Als nicht bezahlt markieren"
msgid "Refund order"
msgstr "Bestellung erstatten"
#: pretix/control/templates/pretixcontrol/order/index.html:51
#: pretix/control/templates/pretixcontrol/order/index.html:43
msgid "View order as user"
msgstr "Als Kunde ansehen"
#: pretix/control/templates/pretixcontrol/order/index.html:63
#: pretix/control/templates/pretixcontrol/order/index.html:55
msgid "Expire order"
msgstr "Als abgelaufen markieren"
#: pretix/control/templates/pretixcontrol/order/index.html:64
#: pretix/control/templates/pretixcontrol/order/index.html:56
msgid ""
"The payment for this order is overdue, but you have configured not to expire "
"orders automatically. To free quota capacity, you can mark it as expired "
@@ -3664,66 +3663,66 @@ msgstr ""
"dass Bestellungen nicht automatisch ablaufen. Um freies Kontingent zu "
"schaffen, kannst du die Bestellung manuell als abgelaufen markieren."
#: pretix/control/templates/pretixcontrol/order/index.html:75
#: pretix/control/templates/pretixcontrol/order/index.html:67
#: pretix/presale/templates/pretixpresale/event/order.html:6
msgid "Order details"
msgstr "Bestellung"
#: pretix/control/templates/pretixcontrol/order/index.html:88
#: pretix/control/templates/pretixcontrol/order/index.html:80
msgid "Expiry date"
msgstr "Ablaufdatum"
#: pretix/control/templates/pretixcontrol/order/index.html:108
#: pretix/control/templates/pretixcontrol/order/index.html:138
#: pretix/presale/templates/pretixpresale/event/order.html:120
#: pretix/presale/templates/pretixpresale/event/order.html:141
#: pretix/control/templates/pretixcontrol/order/index.html:100
#: pretix/control/templates/pretixcontrol/order/index.html:130
#: pretix/presale/templates/pretixpresale/event/order.html:107
#: pretix/presale/templates/pretixpresale/event/order.html:128
msgid "Invoices"
msgstr "Rechnungen"
#: pretix/control/templates/pretixcontrol/order/index.html:112
#: pretix/presale/templates/pretixpresale/event/order.html:128
#: pretix/control/templates/pretixcontrol/order/index.html:104
#: pretix/presale/templates/pretixpresale/event/order.html:115
msgid "Cancellation"
msgstr "Rechnungskorrektur"
#: pretix/control/templates/pretixcontrol/order/index.html:112
#: pretix/presale/templates/pretixpresale/event/order.html:128
#: pretix/control/templates/pretixcontrol/order/index.html:104
#: pretix/presale/templates/pretixpresale/event/order.html:115
msgid "Invoice"
msgstr "Rechnung"
#: pretix/control/templates/pretixcontrol/order/index.html:119
#: pretix/control/templates/pretixcontrol/order/index.html:111
#: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html:20
msgid "Regenerate"
msgstr "Neu generieren"
#: pretix/control/templates/pretixcontrol/order/index.html:127
#: pretix/control/templates/pretixcontrol/order/index.html:119
msgid "Cancel and reissue"
msgstr "Stornieren und neu ausstellen"
#: pretix/control/templates/pretixcontrol/order/index.html:144
#: pretix/control/templates/pretixcontrol/order/index.html:136
msgid "Generate invoice"
msgstr "Rechnungen ausstellen"
#: pretix/control/templates/pretixcontrol/order/index.html:163
#: pretix/presale/templates/pretixpresale/event/order.html:106
#: pretix/control/templates/pretixcontrol/order/index.html:155
#: pretix/presale/templates/pretixpresale/event/order.html:93
msgid "Ordered items"
msgstr "Bestellte Produkte"
#: pretix/control/templates/pretixcontrol/order/index.html:175
#: pretix/control/templates/pretixcontrol/order/index.html:167
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:11
msgid "Voucher code used:"
msgstr "Verwendeter Gutscheincode:"
#: pretix/control/templates/pretixcontrol/order/index.html:185
#: pretix/control/templates/pretixcontrol/order/index.html:190
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:17
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:21
#: pretix/control/templates/pretixcontrol/order/index.html:177
#: pretix/control/templates/pretixcontrol/order/index.html:182
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:19
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:23
msgid "not answered"
msgstr "nicht beantwortet"
#: pretix/control/templates/pretixcontrol/order/index.html:205
#: pretix/control/templates/pretixcontrol/order/index.html:222
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:72
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:90
#: pretix/control/templates/pretixcontrol/order/index.html:197
#: pretix/control/templates/pretixcontrol/order/index.html:214
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:86
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:114
#: pretix/presale/templates/pretixpresale/event/index.html:132
#: pretix/presale/templates/pretixpresale/event/index.html:182
#: pretix/presale/templates/pretixpresale/event/voucher.html:74
@@ -3732,45 +3731,45 @@ msgstr "nicht beantwortet"
msgid "incl. %(rate)s%% taxes"
msgstr "inkl. %(rate)s%% MwSt."
#: pretix/control/templates/pretixcontrol/order/index.html:232
#: pretix/control/templates/pretixcontrol/order/index.html:224
#: pretix/control/templates/pretixcontrol/orders/overview.html:85
#: pretix/plugins/reports/exporters.py:199
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:100
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:124
msgid "Total"
msgstr "Gesamt"
#: pretix/control/templates/pretixcontrol/order/index.html:252
#: pretix/control/templates/pretixcontrol/order/index.html:244
msgid "The payment state of this order was manually modified."
msgstr "Der Status dieser Bestellung wurde manuell verändert."
#: pretix/control/templates/pretixcontrol/order/index.html:257
#: pretix/control/templates/pretixcontrol/order/index.html:249
#, python-format
msgid "The payment has to be completed before %(date)s."
msgstr "Die Zahlung muss bis zum %(date)s abgeschlossen sein."
#: pretix/control/templates/pretixcontrol/order/index.html:269
#: pretix/control/templates/pretixcontrol/order/index.html:261
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:72
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:30
#: pretix/presale/templates/pretixpresale/event/order.html:169
#: pretix/presale/templates/pretixpresale/event/order.html:156
#: pretix/presale/templates/pretixpresale/event/order_modify.html:25
msgid "Invoice information"
msgstr "Rechnungsinformationen"
#: pretix/control/templates/pretixcontrol/order/index.html:280
#: pretix/control/templates/pretixcontrol/order/index.html:272
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:83
#: pretix/presale/templates/pretixpresale/event/order.html:180
#: pretix/presale/templates/pretixpresale/event/order.html:167
msgid "ZIP code and city"
msgstr "PLZ und Ort"
#: pretix/control/templates/pretixcontrol/order/index.html:297
#: pretix/control/templates/pretixcontrol/order/index.html:289
msgid "Internal comment"
msgstr "Interner Kommentar"
#: pretix/control/templates/pretixcontrol/order/index.html:308
#: pretix/control/templates/pretixcontrol/order/index.html:300
msgid "Update comment"
msgstr "Kommentar speichern"
#: pretix/control/templates/pretixcontrol/order/index.html:319
#: pretix/control/templates/pretixcontrol/order/index.html:311
msgid "Order history"
msgstr "Bestellhistorie"
@@ -4247,7 +4246,7 @@ msgstr "Eingelöste Gutscheine"
msgid "We already sent you an email in the last 24 hours."
msgstr "Wir haben dir in den letzten 24 Stunden bereits eine E-Mail geschickt."
#: pretix/control/views/auth.py:140 pretix/control/views/orders.py:365
#: pretix/control/views/auth.py:140 pretix/control/views/orders.py:343
msgid "There was an error sending the mail. Please try again later."
msgstr ""
"Es gab ein Fehler beim Senden der E-Mail. Bitte probiere es später erneut."
@@ -4401,8 +4400,7 @@ msgstr ""
"\"Eigenen SMTP-Server verwenden\" zu setzen, damit der Server auch benutzt "
"wird."
#: pretix/control/views/event.py:395 pretix/control/views/orders.py:422
#: pretix/presale/views/order.py:491
#: pretix/control/views/event.py:395 pretix/presale/views/order.py:498
msgid "You requested an invalid ticket output type."
msgstr "Du hast einen ungültigen Ausgabetyp gewählt."
@@ -4524,15 +4522,15 @@ msgstr "Das ausgewählte Produkt wurde deaktiviert."
msgid "The new event has been created."
msgstr "Eine neue Veranstaltung wurde erstellt."
#: pretix/control/views/orders.py:223
#: pretix/control/views/orders.py:201
msgid "The comment has been updated."
msgstr "Der Kommentar wurde aktualisiert."
#: pretix/control/views/orders.py:225
#: pretix/control/views/orders.py:203
msgid "Could not update the comment."
msgstr "Kommentar konnte nicht gespeichert werden."
#: pretix/control/views/orders.py:240
#: pretix/control/views/orders.py:218
msgid ""
"The order has been marked as paid, but we were unable to send a confirmation "
"mail."
@@ -4540,35 +4538,35 @@ msgstr ""
"Die Bestellung wurde als bezahlt markiert, aber die Bestätigungsmail konnte "
"nicht verschickt werden."
#: pretix/control/views/orders.py:251
#: pretix/control/views/orders.py:229
msgid "The order has been marked as not paid."
msgstr "Die Bestellung wurde als unbezahlt markiert."
#: pretix/control/views/orders.py:284 pretix/presale/views/order.py:352
#: pretix/control/views/orders.py:262 pretix/presale/views/order.py:351
msgid "You cannot generate an invoice for this order."
msgstr "Du kannst für diese Bestellung keine Rechnung erzeugen."
#: pretix/control/views/orders.py:286 pretix/presale/views/order.py:354
#: pretix/control/views/orders.py:264 pretix/presale/views/order.py:353
msgid "An invoice for this order already exists."
msgstr "Zu dieser Bestellung gibt es bereits eine Rechnung."
#: pretix/control/views/orders.py:306 pretix/control/views/orders.py:329
#: pretix/control/views/orders.py:284 pretix/control/views/orders.py:307
msgid "Unknown invoice."
msgstr "Unbekannte Rechnung"
#: pretix/control/views/orders.py:309 pretix/control/views/orders.py:332
#: pretix/control/views/orders.py:287 pretix/control/views/orders.py:310
msgid "The invoice has already been canceled."
msgstr "Die Rechnung wurde bereits storniert."
#: pretix/control/views/orders.py:368
#: pretix/control/views/orders.py:346
msgid "The email has been queued to be sent."
msgstr "Die E-Mail wurde zum Versenden gespeichert."
#: pretix/control/views/orders.py:393 pretix/presale/views/order.py:529
#: pretix/control/views/orders.py:371 pretix/presale/views/order.py:538
msgid "This invoice has not been found"
msgstr "Diese Rechnung wurde nicht gefunden"
#: pretix/control/views/orders.py:401 pretix/presale/views/order.py:537
#: pretix/control/views/orders.py:379 pretix/presale/views/order.py:546
msgid ""
"The invoice file has not yet been generated, we will generate it for you "
"now. Please try again in a few seconds."
@@ -4576,15 +4574,11 @@ msgstr ""
"Diese Rechnung wurde bisher noch nicht fertig erstellt, wir werden die PDF-"
"Datei jetzt erstellen. Bitte probiere es in wenigen Sekunden erneut."
#: pretix/control/views/orders.py:425 pretix/presale/views/order.py:496
msgid "Order is not paid."
msgstr "Die Bestellung ist nicht bezahlt."
#: pretix/control/views/orders.py:447 pretix/control/views/orders.py:465
#: pretix/control/views/orders.py:394 pretix/control/views/orders.py:412
msgid "The payment term has been changed."
msgstr "Die Zahlungsfrist wurde geändert."
#: pretix/control/views/orders.py:469
#: pretix/control/views/orders.py:416
msgid ""
"We were not able to process the request completely as the server was too "
"busy."
@@ -4592,31 +4586,31 @@ msgstr ""
"Wir konnten deine Bestellung nicht durchführen, da der Server zu beschäftigt "
"war."
#: pretix/control/views/orders.py:477 pretix/control/views/orders.py:499
#: pretix/control/views/orders.py:424 pretix/control/views/orders.py:446
msgid "This action is only allowed for pending orders."
msgstr "Diese Aktion ist nur für unbezahlte Bestellungen möglich."
#: pretix/control/views/orders.py:548
#: pretix/control/views/orders.py:495
msgid "An error occured. Please see the details below."
msgstr "Ein Fehler ist aufgetreten, bitte schaue weiter unten für Details."
#: pretix/control/views/orders.py:555
#: pretix/control/views/orders.py:502
msgid "The order has been changed and the user has been notified."
msgstr "Die Bestellung wurde geändert und der Kunde benachrichtigt."
#: pretix/control/views/orders.py:584
#: pretix/control/views/orders.py:531
msgid "The order has been changed."
msgstr "Die Bestellung wurde geändert."
#: pretix/control/views/orders.py:619
#: pretix/control/views/orders.py:566
msgid "There is no order with the given order code."
msgstr "Es existiert keine Bestellung mit der eingegebenen Bestellnummer."
#: pretix/control/views/orders.py:653
#: pretix/control/views/orders.py:600
msgid "The selected exporter was not found."
msgstr "Das ausgewählte Exportformat wurde nicht gefunden."
#: pretix/control/views/orders.py:659
#: pretix/control/views/orders.py:606
msgid "There was a problem processing your input. See below for error details."
msgstr "Die Eingabe konnte nicht verarbeitet werden."
@@ -5608,8 +5602,8 @@ msgid "PDF output"
msgstr "PDF-Ausgabe"
#: pretix/plugins/ticketoutputpdf/ticketoutput.py:21
msgid "Download PDF"
msgstr "PDF herunterladen"
msgid "PDF"
msgstr "PDF"
#: pretix/plugins/ticketoutputpdf/ticketoutput.py:57
#, python-brace-format
@@ -5732,7 +5726,7 @@ msgstr "Teilnehmername-Größe (mm)"
msgid "Invisible by default, set this to a number greater than 0 to show."
msgstr "Standardmäßig unsichtbar, eine positive Größe zeigt das Element an."
#: pretix/presale/checkoutflow.py:167 pretix/presale/views/order.py:394
#: pretix/presale/checkoutflow.py:167 pretix/presale/views/order.py:393
msgid ""
"We had difficulties processing your input. Please review the errors below."
msgstr "Wir hatten Schwierigkeiten, deine Eingabe zu verarbeiten."
@@ -5745,12 +5739,12 @@ msgstr "Bitte gib eine gültige E-Mail-Adresse ein."
msgid "Please fill in answers to all required questions."
msgstr "Bitte fülle Antworten zu allen benötigten Fragen ein."
#: pretix/presale/checkoutflow.py:255 pretix/presale/views/order.py:326
#: pretix/presale/checkoutflow.py:255 pretix/presale/views/order.py:325
msgid "Please select a payment method."
msgstr "Bitte wähle eine Zahlungsmethode aus."
#: pretix/presale/checkoutflow.py:276 pretix/presale/checkoutflow.py:282
#: pretix/presale/views/order.py:196 pretix/presale/views/order.py:232
#: pretix/presale/views/order.py:195 pretix/presale/views/order.py:231
msgid "The payment information you entered was incomplete."
msgstr "Die eingegebenen Zahlungsinformationen sind unvollständig."
@@ -6010,25 +6004,25 @@ msgstr "Zahlung abschließen"
msgid "Please complete your payment before %(date)s"
msgstr "Bitte schließe deine Zahlung bis zum %(date)s ab."
#: pretix/presale/templates/pretixpresale/event/order.html:77
#: pretix/presale/templates/pretixpresale/event/order.html:72
msgid ""
"Please obtain your ticket below. Please have your ticket ready when entering "
"the event."
"You can download your tickets using the buttons below. Please have your "
"ticket ready when entering the event."
msgstr ""
"Bitte lade dein Ticket hier herunter und halte es am Einlass der "
"Veranstaltung bereit."
"Bitte lade dein Ticket mit den Buttons weiter unten herunter und halte es am "
"Einlass der Veranstaltung bereit."
#: pretix/presale/templates/pretixpresale/event/order.html:88
#: pretix/presale/templates/pretixpresale/event/order.html:76
#, python-format
msgid "You will be able to download your tickets here starting on %(date)s."
msgstr "Du kannst deine Tickets hier ab %(date)s herunterladen."
#: pretix/presale/templates/pretixpresale/event/order.html:101
#: pretix/presale/templates/pretixpresale/event/order.html:164
#: pretix/presale/templates/pretixpresale/event/order.html:88
#: pretix/presale/templates/pretixpresale/event/order.html:151
msgid "Change details"
msgstr "Details bearbeiten"
#: pretix/presale/templates/pretixpresale/event/order.html:149
#: pretix/presale/templates/pretixpresale/event/order.html:136
msgid "Request invoice"
msgstr "Rechnung anfragen"
@@ -6209,29 +6203,33 @@ msgstr "Die gewählten Produkte wurden deinem Warenkorb hinzugefügt."
msgid "Your cart is empty"
msgstr "Dein Warenkorb ist leer."
#: pretix/presale/views/order.py:70 pretix/presale/views/order.py:142
#: pretix/presale/views/order.py:189 pretix/presale/views/order.py:229
#: pretix/presale/views/order.py:256 pretix/presale/views/order.py:347
#: pretix/presale/views/order.py:411 pretix/presale/views/order.py:432
#: pretix/presale/views/order.py:458 pretix/presale/views/order.py:494
#: pretix/presale/views/order.py:520
#: pretix/presale/views/order.py:70 pretix/presale/views/order.py:141
#: pretix/presale/views/order.py:188 pretix/presale/views/order.py:228
#: pretix/presale/views/order.py:255 pretix/presale/views/order.py:346
#: pretix/presale/views/order.py:410 pretix/presale/views/order.py:431
#: pretix/presale/views/order.py:457 pretix/presale/views/order.py:501
#: pretix/presale/views/order.py:529
msgid "Unknown order code or not authorized to access this order."
msgstr ""
"Unbekannte Bestellnummer oder Bestellung gehört einem anderen Benutzer."
#: pretix/presale/views/order.py:146 pretix/presale/views/order.py:192
#: pretix/presale/views/order.py:145 pretix/presale/views/order.py:191
msgid "The payment for this order cannot be continued."
msgstr "Diese Bestellung kann nicht mehr bezahlt werden."
#: pretix/presale/views/order.py:258
#: pretix/presale/views/order.py:257
msgid "The payment method for this order cannot be changed."
msgstr "Die Zahlungsmethode für diese Bestellung kann nicht geändert werden."
#: pretix/presale/views/order.py:413
#: pretix/presale/views/order.py:412
msgid "You cannot modify this order"
msgstr "Du kannst diese Bestellung nicht bearbeiten"
#: pretix/presale/views/order.py:501
#: pretix/presale/views/order.py:503
msgid "Order is not paid."
msgstr "Die Bestellung ist nicht bezahlt."
#: pretix/presale/views/order.py:508
msgid "Ticket download is not (yet) enabled."
msgstr "Der Ticket-Download ist (noch) nicht freigeschaltet."
@@ -6268,6 +6266,9 @@ msgstr "Deutsch"
msgid "German (informal)"
msgstr "Deutsch (Du)"
#~ msgid "Download PDF"
#~ msgstr "PDF herunterladen"
#~ msgid "A voucher you tried to use already has been used."
#~ msgstr ""
#~ "Ein Gutscheincode, den du verwenden wolltest, wurde zwischenzeitlich "

View File

@@ -18,10 +18,9 @@ logger = logging.getLogger('pretix.plugins.ticketoutputpdf')
class PdfTicketOutput(BaseTicketOutput):
identifier = 'pdf'
verbose_name = _('PDF output')
download_button_text = _('Download PDF')
download_button_icon = 'fa-print'
download_button_text = _('PDF')
def generate(self, order):
def generate(self, op):
from reportlab.graphics.shapes import Drawing
from reportlab.pdfgen import canvas
from reportlab.lib import pagesizes, units
@@ -29,6 +28,8 @@ class PdfTicketOutput(BaseTicketOutput):
from reportlab.graphics import renderPDF
from PyPDF2 import PdfFileWriter, PdfFileReader
order = op.order
pagesize = self.settings.get('pagesize', default='A4')
if hasattr(pagesizes, pagesize):
pagesize = getattr(pagesizes, pagesize)
@@ -41,66 +42,65 @@ class PdfTicketOutput(BaseTicketOutput):
buffer = BytesIO()
p = canvas.Canvas(buffer, pagesize=pagesize)
for op in order.positions.all().select_related('item', 'variation'):
event_s = self.settings.get('event_s', default=22, as_type=float)
if event_s:
p.setFont("Helvetica", event_s)
event_x = self.settings.get('event_x', default=15, as_type=float)
event_y = self.settings.get('event_y', default=235, as_type=float)
p.drawString(event_x * units.mm, event_y * units.mm, str(self.event.name))
event_s = self.settings.get('event_s', default=22, as_type=float)
if event_s:
p.setFont("Helvetica", event_s)
event_x = self.settings.get('event_x', default=15, as_type=float)
event_y = self.settings.get('event_y', default=235, as_type=float)
p.drawString(event_x * units.mm, event_y * units.mm, str(self.event.name))
order_s = self.settings.get('order_s', default=17, as_type=float)
if order_s:
p.setFont("Helvetica", order_s)
order_x = self.settings.get('order_x', default=15, as_type=float)
order_y = self.settings.get('order_y', default=220, as_type=float)
p.drawString(order_x * units.mm, order_y * units.mm, _('Order code: {code}').format(code=order.code))
order_s = self.settings.get('order_s', default=17, as_type=float)
if order_s:
p.setFont("Helvetica", order_s)
order_x = self.settings.get('order_x', default=15, as_type=float)
order_y = self.settings.get('order_y', default=220, as_type=float)
p.drawString(order_x * units.mm, order_y * units.mm, _('Order code: {code}').format(code=order.code))
name_s = self.settings.get('name_s', default=17, as_type=float)
if name_s:
p.setFont("Helvetica", name_s)
name_x = self.settings.get('name_x', default=15, as_type=float)
name_y = self.settings.get('name_y', default=210, as_type=float)
item = str(op.item.name)
if op.variation:
item += " " + str(op.variation)
p.drawString(name_x * units.mm, name_y * units.mm, item)
name_s = self.settings.get('name_s', default=17, as_type=float)
if name_s:
p.setFont("Helvetica", name_s)
name_x = self.settings.get('name_x', default=15, as_type=float)
name_y = self.settings.get('name_y', default=210, as_type=float)
item = str(op.item.name)
if op.variation:
item += " " + str(op.variation)
p.drawString(name_x * units.mm, name_y * units.mm, item)
price_s = self.settings.get('price_s', default=17, as_type=float)
if price_s:
p.setFont("Helvetica", price_s)
price_x = self.settings.get('price_x', default=15, as_type=float)
price_y = self.settings.get('price_y', default=200, as_type=float)
p.drawString(price_x * units.mm, price_y * units.mm, "%s %s" % (str(op.price), self.event.currency))
price_s = self.settings.get('price_s', default=17, as_type=float)
if price_s:
p.setFont("Helvetica", price_s)
price_x = self.settings.get('price_x', default=15, as_type=float)
price_y = self.settings.get('price_y', default=200, as_type=float)
p.drawString(price_x * units.mm, price_y * units.mm, "%s %s" % (str(op.price), self.event.currency))
qr_s = self.settings.get('qr_s', default=80, as_type=float)
if qr_s:
reqs = qr_s * units.mm
qrw = QrCodeWidget(op.secret, barLevel='H')
b = qrw.getBounds()
w = b[2] - b[0]
h = b[3] - b[1]
d = Drawing(reqs, reqs, transform=[reqs / w, 0, 0, reqs / h, 0, 0])
d.add(qrw)
qr_x = self.settings.get('qr_x', default=10, as_type=float)
qr_y = self.settings.get('qr_y', default=120, as_type=float)
renderPDF.draw(d, p, qr_x * units.mm, qr_y * units.mm)
qr_s = self.settings.get('qr_s', default=80, as_type=float)
if qr_s:
reqs = qr_s * units.mm
qrw = QrCodeWidget(op.secret, barLevel='H')
b = qrw.getBounds()
w = b[2] - b[0]
h = b[3] - b[1]
d = Drawing(reqs, reqs, transform=[reqs / w, 0, 0, reqs / h, 0, 0])
d.add(qrw)
qr_x = self.settings.get('qr_x', default=10, as_type=float)
qr_y = self.settings.get('qr_y', default=120, as_type=float)
renderPDF.draw(d, p, qr_x * units.mm, qr_y * units.mm)
code_s = self.settings.get('code_s', default=11, as_type=float)
if code_s:
p.setFont("Helvetica", code_s)
code_x = self.settings.get('code_x', default=15, as_type=float)
code_y = self.settings.get('code_y', default=120, as_type=float)
p.drawString(code_x * units.mm, code_y * units.mm, op.secret)
code_s = self.settings.get('code_s', default=11, as_type=float)
if code_s:
p.setFont("Helvetica", code_s)
code_x = self.settings.get('code_x', default=15, as_type=float)
code_y = self.settings.get('code_y', default=120, as_type=float)
p.drawString(code_x * units.mm, code_y * units.mm, op.secret)
attendee_s = self.settings.get('attendee_s', default=0, as_type=float)
if code_s and op.attendee_name:
p.setFont("Helvetica", attendee_s)
attendee_x = self.settings.get('attendee_x', default=15, as_type=float)
attendee_y = self.settings.get('attendee_y', default=90, as_type=float)
p.drawString(attendee_x * units.mm, attendee_y * units.mm, op.attendee_name)
attendee_s = self.settings.get('attendee_s', default=0, as_type=float)
if code_s and op.attendee_name:
p.setFont("Helvetica", attendee_s)
attendee_x = self.settings.get('attendee_x', default=15, as_type=float)
attendee_y = self.settings.get('attendee_y', default=90, as_type=float)
p.drawString(attendee_x * units.mm, attendee_y * units.mm, op.attendee_name)
p.showPage()
p.showPage()
p.save()

View File

@@ -23,7 +23,7 @@
</div>
<div class="panel-body">
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=False %}
<div class="row-fluid">
<div class="cart-row row">
<div class="col-md-6 col-xs-12">
<em id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 %}

View File

@@ -1,8 +1,8 @@
{% load i18n %}
{% load eventurl %}
{% for line in cart.positions %}
<div class="row-fluid cart-row">
<div class="col-md-4 col-xs-6">
<div class="row cart-row {% if download %}has-downloads{% endif %}">
<div class="product">
<strong>{{ line.item.name }}</strong>
{% if line.variation %}
{{ line.variation }}
@@ -10,63 +10,77 @@
{% if line.voucher %}
<br /><span class="fa fa-tags"></span> {% trans "Voucher code used:" %} {{ line.voucher.code }}
{% endif %}
{% if line.has_questions %}
<dl>
{% if line.item.admission and event.settings.attendee_names_asked%}
<dt>{% trans "Attendee name" %}</dt>
<dd>{% if line.attendee_name %}{{ line.attendee_name }}{% else %}<em>{% trans "not answered" %}</em>{% endif %}</dd>
{% endif %}
{% for q in line.questions %}
<dt>{{ q.question }}</dt>
<dd>{% if q.answer %}{{ q.answer|linebreaksbr }}{% else %}<em>{% trans "not answered" %}</em>{% endif %}</dd>
{% endfor %}
</dl>
{% endif %}
</div>
<div class="col-md-2 col-xs-6 count">
{% if editable %}
<form action="{% eventurl event "presale:event.cart.remove" %}"
method="post" data-asynctask>
{% csrf_token %}
{% if line.variation %}
<input type="hidden" name="variation_{{ line.item.id }}_{{ line.variation.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}_{{ line.variation.id }}"
value="{{ line.price }}" />
{% else %}
<input type="hidden" name="item_{{ line.item.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}"
value="{{ line.price }}" />
{% endif %}
<button class="btn btn-mini btn-link"><i class="fa fa-minus"></i></button>
</form>
{% endif %}
{{ line.count }}
{% if editable %}
<form action="{% eventurl event "presale:event.cart.add" %}"
method="post" data-asynctask>
{% csrf_token %}
{% if line.variation %}
<input type="hidden" name="variation_{{ line.item.id }}_{{ line.variation.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}_{{ line.variation.id }}"
value="{{ line.price }}" />
{% else %}
<input type="hidden" name="item_{{ line.item.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}"
value="{{ line.price }}" />
{% endif %}
<button class="btn btn-mini btn-link"><i class="fa fa-plus"></i></button>
</form>
{% if line.has_questions %}
<dl>
{% if line.item.admission and event.settings.attendee_names_asked%}
<dt>{% trans "Attendee name" %}</dt>
<dd>{% if line.attendee_name %}{{ line.attendee_name }}{% else %}<em>{% trans "not answered" %}</em>{% endif %}</dd>
{% endif %}
{% for q in line.questions %}
<dt>{{ q.question }}</dt>
<dd>{% if q.answer %}{{ q.answer|linebreaksbr }}{% else %}<em>{% trans "not answered" %}</em>{% endif %}</dd>
{% endfor %}
</dl>
{% endif %}
</div>
<div class="col-md-3 col-xs-6 price">
{{ event.currency }} {{ line.price|floatformat:2 }}
</div>
<div class="col-md-3 col-xs-6 price">
{% if download %}
<div class="download-desktop">
{% for b in download_buttons %}
<a href="{% eventurl event "presale:event.order.download" secret=order.secret order=order.code output=b.identifier position=line.id %}"
class="btn btn-default btn-sm">
<span class="fa fa-download"></span> {{ b.text }}
</a>
{% endfor %}
</div>
{% else %}
<div class="count">
{% if editable %}
<form action="{% eventurl event "presale:event.cart.remove" %}"
method="post" data-asynctask>
{% csrf_token %}
{% if line.variation %}
<input type="hidden" name="variation_{{ line.item.id }}_{{ line.variation.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}_{{ line.variation.id }}"
value="{{ line.price }}" />
{% else %}
<input type="hidden" name="item_{{ line.item.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}"
value="{{ line.price }}" />
{% endif %}
<button class="btn btn-mini btn-link"><i class="fa fa-minus"></i></button>
</form>
{% endif %}
{{ line.count }}
{% if editable %}
<form action="{% eventurl event "presale:event.cart.add" %}"
method="post" data-asynctask>
{% csrf_token %}
{% if line.variation %}
<input type="hidden" name="variation_{{ line.item.id }}_{{ line.variation.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}_{{ line.variation.id }}"
value="{{ line.price }}" />
{% else %}
<input type="hidden" name="item_{{ line.item.id }}"
value="1" />
<input type="hidden" name="price_{{ line.item.id }}"
value="{{ line.price }}" />
{% endif %}
<button class="btn btn-mini btn-link"><i class="fa fa-plus"></i></button>
</form>
{% endif %}
</div>
<div class="singleprice price">
{{ event.currency }} {{ line.price|floatformat:2 }}
</div>
{% endif %}
<div class="totalprice price">
<strong>{{ event.currency }} {{ line.total|floatformat:2 }}</strong>
{% if line.tax_rate %}
<br /><small>{% blocktrans trimmed with rate=line.tax_rate %}
@@ -74,12 +88,22 @@
{% endblocktrans %}</small>
{% endif %}
</div>
{% if download %}
<div class="download-mobile">
{% for b in download_buttons %}
<a href="{% eventurl event "presale:event.order.download" secret=order.secret order=order.code output=b.identifier position=line.id %}"
class="btn btn-default btn-sm">
<span class="fa fa-download"></span> {{ b.text }}
</a>
{% endfor %}
</div>
{% endif %}
<div class="clearfix"></div>
</div>
{% endfor %}
{% if cart.payment_fee %}
{# TODO: Tax rate? #}
<div class="row-fluid cart-row">
<div class="row cart-row">
<div class="col-md-4 col-xs-6">
<strong>{% trans "Payment method fee" %}</strong>
</div>
@@ -95,7 +119,7 @@
<div class="clearfix"></div>
</div>
{% endif %}
<div class="row-fluid cart-row total">
<div class="row cart-row total">
<div class="col-md-4 col-xs-6">
<strong>{% trans "Total" %}</strong>
</div>

View File

@@ -15,7 +15,7 @@
</div>
<div class="panel-body">
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=True %}
<div class="row-fluid">
<div class="cart-row row">
<div class="col-md-6 col-xs-12">
<em id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
{% if cart.minutes_left > 0 %}

View File

@@ -67,29 +67,16 @@
</div>
{% endif %}
{% if order.status == 'p' and event.settings.ticket_download %}
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">{% trans "Ticket download" %}</h3>
</div>
<div class="panel-body">
{% if can_download %}
<p>
{% blocktrans trimmed %}
Please obtain your ticket below. Please have your ticket ready when entering the event.
{% endblocktrans %}
</p>
{% for b in download_buttons %}
<a href="{% eventurl event "presale:event.order.download" secret=order.secret order=order.code output=b.identifier %}"
class="btn btn-primary">
<span class="fa {{ b.icon }}"></span> {{ b.text }}
</a>
{% endfor %}
{% else %}
{% blocktrans trimmed with date=event.settings.ticket_download_date|date:"SHORT_DATE_FORMAT" %}
You will be able to download your tickets here starting on {{ date }}.
{% endblocktrans %}
{% endif %}
</div>
<div class="alert alert-info">
{% if can_download %}
{% blocktrans trimmed %}
You can download your tickets using the buttons below. Please have your ticket ready when entering the event.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed with date=event.settings.ticket_download_date|date:"SHORT_DATE_FORMAT" %}
You will be able to download your tickets here starting on {{ date }}.
{% endblocktrans %}
{% endif %}
</div>
{% endif %}
<div class="panel panel-primary cart">
@@ -107,7 +94,7 @@
</h3>
</div>
<div class="panel-body">
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=False %}
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event download=can_download editable=False %}
</div>
</div>
{% eventsignal event "pretix.presale.signals.order_info" order=order %}

View File

@@ -45,7 +45,7 @@ event_patterns = [
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/pay/change',
pretix.presale.views.order.OrderPayChangeMethod.as_view(),
name='event.order.pay.change'),
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/download/(?P<output>[^/]+)$',
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/download/(?P<position>[0-9]+)/(?P<output>[^/]+)$',
pretix.presale.views.order.OrderDownload.as_view(),
name='event.order.download'),
url(r'^order/(?P<order>[^/]+)/(?P<secret>[A-Za-z0-9]+)/invoice/(?P<invoice>[^/]+)$',

View File

@@ -25,7 +25,7 @@ class CartMixin:
'item__questions', 'answers'
))
def get_cart(self, answers=False, queryset=None, payment_fee=None, payment_fee_tax_rate=None):
def get_cart(self, answers=False, queryset=None, payment_fee=None, payment_fee_tax_rate=None, downloads=False):
queryset = queryset or CartPosition.objects.filter(
cart_id=self.request.session.session_key, event=self.request.event
)
@@ -47,6 +47,8 @@ class CartMixin:
# We do this by list manipulations instead of a GROUP BY query, as
# Django is unable to join related models in a .values() query
def keyfunc(pos):
if downloads:
return pos.id, 0, 0, 0, 0
if answers and ((pos.item.admission and self.request.event.settings.attendee_names_asked)
or pos.item.questions.all()):
return pos.id, 0, 0, 0, 0

View File

@@ -79,8 +79,7 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TemplateView):
if not provider.is_enabled:
continue
buttons.append({
'icon': provider.download_button_icon or 'fa-download',
'text': provider.download_button_text or 'fa-download',
'text': provider.download_button_text or 'Download',
'identifier': provider.identifier,
})
return buttons
@@ -97,7 +96,7 @@ class OrderDetails(EventViewMixin, OrderDetailMixin, CartMixin, TemplateView):
)
ctx['download_buttons'] = self.download_buttons
ctx['cart'] = self.get_cart(
answers=True,
answers=True, downloads=ctx['can_download'],
queryset=OrderPosition.objects.filter(order=self.order),
payment_fee=self.order.payment_fee, payment_fee_tax_rate=self.order.payment_fee_tax_rate
)
@@ -478,6 +477,7 @@ class OrderCancelDo(EventViewMixin, OrderDetailMixin, AsyncAction, View):
class OrderDownload(EventViewMixin, OrderDetailMixin, View):
@cached_property
def output(self):
responses = register_ticket_outputs.send(self.request.event)
@@ -486,11 +486,18 @@ class OrderDownload(EventViewMixin, OrderDetailMixin, View):
if provider.identifier == self.kwargs.get('output'):
return provider
@cached_property
def order_position(self):
try:
return self.order.positions.get(pk=self.kwargs.get('position'))
except OrderPosition.DoesNotExist:
return None
def get(self, request, *args, **kwargs):
if not self.output or not self.output.is_enabled:
messages.error(request, _('You requested an invalid ticket output type.'))
return redirect(self.get_order_url())
if not self.order:
if not self.order or not self.order_position:
raise Http404(_('Unknown order code or not authorized to access this order.'))
if self.order.status != Order.STATUS_PAID:
messages.error(request, _('Order is not paid.'))
@@ -501,7 +508,9 @@ class OrderDownload(EventViewMixin, OrderDetailMixin, View):
messages.error(request, _('Ticket download is not (yet) enabled.'))
return redirect(self.get_order_url())
ct = CachedTicket.objects.get_or_create(order=self.order, provider=self.output.identifier)[0]
ct = CachedTicket.objects.get_or_create(
order_position=self.order_position, provider=self.output.identifier
)[0]
if not ct.cachedfile:
cf = CachedFile()
cf.date = now()
@@ -509,7 +518,7 @@ class OrderDownload(EventViewMixin, OrderDetailMixin, View):
cf.save()
ct.cachedfile = cf
ct.save()
generate.apply_async(args=(self.order.id, self.output.identifier))
generate.apply_async(args=(self.order_position.id, self.output.identifier))
return redirect(reverse('cachedfile.download', kwargs={'id': ct.cachedfile.id}))

View File

@@ -0,0 +1,78 @@
.cart-row {
/* Cart grid */
padding: 10px 0;
.count form {
display: inline;
}
.price, .count, .download-desktop {
text-align: right;
}
.price small,
.availability-box small {
display: block;
line-height: 1;
}
&.total {
border-top: 1px solid $table-border-color;
}
dl {
padding-left: 20px;
margin-bottom: 0;
dd {
padding-left: 20px;
}
}
margin-left: 0;
margin-right: 0;
&>div {
position: relative;
min-height: 1px;
padding-left: ceil(($grid-gutter-width / 2));
padding-right: floor(($grid-gutter-width / 2));
float: left;
}
.download-mobile {
display: none;
width: 100%;
clear: both;
}
.download-desktop {
display: block;
width: percentage((4 / $grid-columns));
}
.product {
width: percentage((4 / $grid-columns));
}
.count {
width: percentage((2 / $grid-columns));
}
.singleprice, .totalprice {
width: percentage((3 / $grid-columns));
}
&.has-downloads .product {
width: percentage((5 / $grid-columns));
}
}
@media(max-width: $screen-sm-max) {
.cart-row {
.download-mobile {
display: block;
}
.download-desktop {
display: none;
}
&.has-downloads .product, .product, .count, .singleprice, .totalprice {
width: 50%;
}
.singleprice {
clear: both;
}
}
}

View File

@@ -61,7 +61,7 @@
margin-bottom: 0;
}
.cart-row, .product-row {
.product-row {
padding: 10px 0;
.count form {
@@ -79,15 +79,6 @@
&.total {
border-top: 1px solid $table-border-color;
}
dl {
padding-left: 20px;
margin-bottom: 0;
dd {
padding-left: 20px;
}
}
}
.panel-contact dl {
margin-bottom: 0;

View File

@@ -4,6 +4,7 @@ $fa-font-path: static("fontawesome/fonts");
@import "../../fontawesome/scss/font-awesome.scss";
@import "_event.scss";
@import "_cart.scss";
@import "_forms.scss";
footer {

View File

@@ -3,13 +3,12 @@ from decimal import Decimal
import pytest
from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile
from django.utils.timezone import now
from tests.base import SoupTest
from pretix.base.models import (
CachedTicket, Event, EventPermission, InvoiceAddress, Item, Order,
OrderPosition, Organizer, Quota, User,
Event, EventPermission, InvoiceAddress, Item, Order, OrderPosition,
Organizer, Quota, User,
)
from pretix.base.services.invoices import (
generate_cancellation, generate_invoice,
@@ -196,135 +195,6 @@ def test_order_transition(client, env, process):
assert o.status == process[0]
@pytest.mark.django_db
def test_order_detail_download_buttons_hidden_if_not_paid(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PENDING
o.save()
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', True)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/')
assert '/control/event/dummy/dummy/orders/FOO/download/testdummy' not in response.rendered_content
@pytest.mark.django_db
def test_order_detail_download_buttons_visible(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', True)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/')
assert '/control/event/dummy/dummy/orders/FOO/download/testdummy' in response.rendered_content
@pytest.mark.django_db
def test_order_detail_download_buttons_hidden_of(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', False)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', True)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/')
assert '/control/event/dummy/dummy/orders/FOO/download/testdummy' not in response.rendered_content
@pytest.mark.django_db
def test_order_detail_download_buttons_visible_before_date(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', True)
env[0].settings.set('ticketoutput_testdummy__enabled', True)
env[0].settings['ticket_download_date'] = now() + timedelta(days=30)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/')
assert '/control/event/dummy/dummy/orders/FOO/download/testdummy' in response.rendered_content
@pytest.mark.django_db
def test_order_detail_download_buttons_hidden_if_provider_disabled(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', False)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/')
assert '/control/event/dummy/dummy/orders/FOO/download/testdummy' not in response.rendered_content
@pytest.mark.django_db
def test_order_download_unpaid(client, env):
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', True)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/download/testdummy', follow=True)
assert 'alert-danger' in response.rendered_content
@pytest.mark.django_db
def test_order_download_unknown_provider(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/download/foobar', follow=True)
assert 'alert-danger' in response.rendered_content
@pytest.mark.django_db
def test_order_download_disabled_provider(client, env):
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', False)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/download/testdummy', follow=True)
assert 'alert-danger' in response.rendered_content
@pytest.mark.django_db
def test_order_download_success(client, env, mocker):
from pretix.base.services import tickets
mocker.patch('pretix.base.services.tickets.generate.apply_async')
o = Order.objects.get(id=env[2].id)
o.status = Order.STATUS_PAID
o.save()
env[0].settings.set('ticket_download', True)
del env[0].settings['ticket_download_date']
env[0].settings.set('ticketoutput_testdummy__enabled', True)
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.get('/control/event/dummy/dummy/orders/FOO/download/testdummy')
assert response.status_code == 302
tickets.generate.apply_async.assert_any_call(args=(o.id, 'testdummy'))
assert 'download' in response['Location']
dl = response['Location']
# test caching
mocker.resetall()
ct = CachedTicket.objects.get(order=o, provider='testdummy')
ct.cachedfile.file.save('foo.jpg', SimpleUploadedFile("sample_invalid_image.jpg", b"file_content",
content_type="image/jpeg"))
ct.cachedfile.save()
response = client.get('/control/event/dummy/dummy/orders/FOO/download/testdummy')
assert response.status_code == 302
tickets.generate.apply_async.assert_not_called()
assert dl == response['Location']
@pytest.mark.django_db
def test_order_invoice_create_forbidden(client, env):
client.login(email='dummy@dummy.dummy', password='dummy')

View File

@@ -67,7 +67,6 @@ event_urls = [
"orders/ABC/extend",
"orders/ABC/change",
"orders/ABC/contact",
"orders/ABC/download/pdf",
"orders/ABC/",
"orders/",
"invoice/1",

View File

@@ -46,8 +46,8 @@ def test_generate_pdf(env, mocker):
event.settings.set('ticketoutput_pdf_code_y', 50)
event.settings.set('ticketoutput_pdf_code_s', 2)
o = PdfTicketOutput(event)
fname, ftype, buf = o.generate(order)
fname, ftype, buf = o.generate(order.positions.first())
assert ftype == 'application/pdf'
pdf = PdfFileReader(BytesIO(buf))
assert pdf.numPages == 2
assert pdf.numPages == 1
assert mocked.called

View File

@@ -307,7 +307,8 @@ class OrdersTest(TestCase):
self.event.settings.set('ticket_download', True)
del self.event.settings['ticket_download_date']
response = self.client.get(
'/%s/%s/order/%s/%s/download/pdf' % (self.orga.slug, self.event.slug, self.order.code, self.order.secret),
'/%s/%s/order/%s/%s/download/%d/pdf' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret, self.ticket_pos.pk),
follow=True)
self.assertRedirects(response,
'/%s/%s/order/%s/%s/' % (self.orga.slug, self.event.slug, self.order.code,
@@ -315,13 +316,14 @@ class OrdersTest(TestCase):
target_status_code=200)
response = self.client.get(
'/%s/%s/order/ABC/123/download/testdummy' % (self.orga.slug, self.event.slug)
'/%s/%s/order/ABC/123/download/%d/testdummy' % (self.orga.slug, self.event.slug,
self.ticket_pos.pk)
)
assert response.status_code == 404
response = self.client.get(
'/%s/%s/order/%s/%s/download/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret),
'/%s/%s/order/%s/%s/download/%d/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret, self.ticket_pos.pk),
follow=True
)
self.assertRedirects(response,
@@ -332,15 +334,15 @@ class OrdersTest(TestCase):
self.order.status = Order.STATUS_PAID
self.order.save()
response = self.client.get(
'/%s/%s/order/%s/%s/download/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret),
'/%s/%s/order/%s/%s/download/%d/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret, self.ticket_pos.pk),
)
assert response.status_code == 302
self.event.settings.set('ticket_download_date', now() + datetime.timedelta(days=1))
response = self.client.get(
'/%s/%s/order/%s/%s/download/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret),
'/%s/%s/order/%s/%s/download/%d/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret, self.ticket_pos.pk),
follow=True
)
self.assertRedirects(response,
@@ -350,15 +352,15 @@ class OrdersTest(TestCase):
del self.event.settings['ticket_download_date']
response = self.client.get(
'/%s/%s/order/%s/%s/download/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret),
'/%s/%s/order/%s/%s/download/%d/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret, self.ticket_pos.pk),
)
assert response.status_code == 302
self.event.settings.set('ticket_download', False)
response = self.client.get(
'/%s/%s/order/%s/%s/download/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret),
'/%s/%s/order/%s/%s/download/%d/testdummy' % (self.orga.slug, self.event.slug, self.order.code,
self.order.secret, self.ticket_pos.pk),
follow=True
)
self.assertRedirects(response, '/%s/%s/order/%s/%s/' % (self.orga.slug, self.event.slug, self.order.code,

View File

@@ -9,7 +9,6 @@ class DummyTicketOutput(BaseTicketOutput):
identifier = 'testdummy'
verbose_name = 'Test dummy'
download_button_text = 'Download test file'
download_button_icon = 'fa-print'
def generate(self, order):
return 'test.txt', 'text/plain', str(order.id)
def generate(self, op):
return 'test.txt', 'text/plain', str(op.order.id)