forked from CGM_Public/pretix_original
Compare commits
1 Commits
django31
...
flaky-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ea8a47f17 |
@@ -60,7 +60,6 @@ Here is the currently recommended set of commands::
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_ia_company
|
||||
ON pretixbase_invoiceaddress
|
||||
USING gin (upper("company") gin_trgm_ops);
|
||||
CREATE INDEX CONCURRENTLY pretix_addidx_orderpos_email_upper ON public.pretixbase_orderposition (upper((attendee_email)::text));
|
||||
|
||||
|
||||
Also, if you use our ``pretix-shipping`` plugin::
|
||||
|
||||
@@ -15,24 +15,8 @@ number string Invoice number
|
||||
order string Order code of the order this invoice belongs to
|
||||
is_cancellation boolean ``true``, if this invoice is the cancellation of a
|
||||
different invoice.
|
||||
invoice_from_name string Sender address: Name
|
||||
invoice_from string Sender address: Address lines
|
||||
invoice_from_zipcode string Sender address: ZIP code
|
||||
invoice_from_city string Sender address: City
|
||||
invoice_from_country string Sender address: Country code
|
||||
invoice_from_tax_id string Sender address: Local Tax ID
|
||||
invoice_from_vat_id string Sender address: EU VAT ID
|
||||
invoice_to string Full recipient address
|
||||
invoice_to_company string Recipient address: Company name
|
||||
invoice_to_name string Recipient address: Person name
|
||||
invoice_to_street string Recipient address: Address lines
|
||||
invoice_to_zipcode string Recipient address: ZIP code
|
||||
invoice_to_city string Recipient address: City
|
||||
invoice_to_state string Recipient address: State (only used in some countries)
|
||||
invoice_to_country string Recipient address: Country code
|
||||
invoice_to_vat_id string Recipient address: EU VAT ID
|
||||
invoice_to_beneficiary string Invoice beneficiary
|
||||
custom_field string Custom invoice address field
|
||||
invoice_from string Sender address
|
||||
invoice_to string Receiver address
|
||||
date date Invoice date
|
||||
refers string Invoice number of an invoice this invoice refers to
|
||||
(for example a cancellation refers to the invoice it
|
||||
@@ -46,31 +30,6 @@ footer_text string Text to be prin
|
||||
lines list of objects The actual invoice contents
|
||||
├ position integer Number of the line within an invoice.
|
||||
├ description string Text representing the invoice line (e.g. product name)
|
||||
├ item integer Product used to create this line. Note that everything
|
||||
about the product might have changed since the creation
|
||||
of the invoice. Can be ``null`` for all invoice lines
|
||||
created before this field was introduced as well as for
|
||||
all lines not created by a product (e.g. a shipping or
|
||||
cancellation fee).
|
||||
├ variation integer Product variation used to create this line. Note that everything
|
||||
about the product might have changed since the creation
|
||||
of the invoice. Can be ``null`` for all invoice lines
|
||||
created before this field was introduced as well as for
|
||||
all lines not created by a product (e.g. a shipping or
|
||||
cancellation fee).
|
||||
├ event_date_from datetime Start date of the (sub)event this line was created for as it
|
||||
was set during invoice creation. Can be ``null`` for all invoice
|
||||
lines created before this was introduced as well as for lines in
|
||||
an event series not created by a product (e.g. shipping or
|
||||
cancellation fees).
|
||||
├ event_date_to datetime End date of the (sub)event this line was created for as it
|
||||
was set during invoice creation. Can be ``null`` for all invoice
|
||||
lines created before this was introduced as well as for lines in
|
||||
an event series not created by a product (e.g. shipping or
|
||||
cancellation fees) as well as whenever the respective (sub)event
|
||||
has no end date set.
|
||||
├ attendee_name string Attendee name at time of invoice creation. Can be ``null`` if no
|
||||
name was set or if names are configured to not be added to invoices.
|
||||
├ gross_value money (string) Price including taxes
|
||||
├ tax_value money (string) Tax amount included
|
||||
├ tax_name string Name of used tax rate (e.g. "VAT")
|
||||
@@ -91,12 +50,6 @@ internal_reference string Customer's refe
|
||||
|
||||
The attribute ``lines.number`` has been added.
|
||||
|
||||
.. versionchanged:: 3.17
|
||||
|
||||
The attribute ``invoice_to_*``, ``invoice_from_*``, ``custom_field``, ``lines.item``, ``lines.variation``, ``lines.event_date_from``,
|
||||
``lines.event_date_to``, and ``lines.attendee_name`` have been added.
|
||||
``refers`` now returns an invoice number including the prefix.
|
||||
|
||||
|
||||
Endpoints
|
||||
---------
|
||||
@@ -130,24 +83,8 @@ Endpoints
|
||||
"number": "SAMPLECONF-00001",
|
||||
"order": "ABC12",
|
||||
"is_cancellation": false,
|
||||
"invoice_from_name": "Big Events LLC",
|
||||
"invoice_from": "Demo street 12",
|
||||
"invoice_from_zipcode":"",
|
||||
"invoice_from_city":"Demo town",
|
||||
"invoice_from_country":"US",
|
||||
"invoice_from_tax_id":"",
|
||||
"invoice_from_vat_id":"",
|
||||
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT-ID: EU123456789",
|
||||
"invoice_to_company": "Sample company",
|
||||
"invoice_to_name": "John Doe",
|
||||
"invoice_to_street": "Test street 12",
|
||||
"invoice_to_zipcode": "12345",
|
||||
"invoice_to_city": "Testington",
|
||||
"invoice_to_state": null,
|
||||
"invoice_to_country": "TE",
|
||||
"invoice_to_vat_id": "EU123456789",
|
||||
"invoice_to_beneficiary": "",
|
||||
"custom_field": null,
|
||||
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
|
||||
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT ID: EU123456789",
|
||||
"date": "2017-12-01",
|
||||
"refers": null,
|
||||
"locale": "en",
|
||||
@@ -160,11 +97,6 @@ Endpoints
|
||||
{
|
||||
"position": 1,
|
||||
"description": "Budget Ticket",
|
||||
"item": 1234,
|
||||
"variation": 245,
|
||||
"event_date_from": "2017-12-27T10:00:00Z",
|
||||
"event_date_to": null,
|
||||
"attendee_name": null,
|
||||
"gross_value": "23.00",
|
||||
"tax_value": "0.00",
|
||||
"tax_name": "VAT",
|
||||
@@ -216,24 +148,8 @@ Endpoints
|
||||
"number": "SAMPLECONF-00001",
|
||||
"order": "ABC12",
|
||||
"is_cancellation": false,
|
||||
"invoice_from_name": "Big Events LLC",
|
||||
"invoice_from": "Demo street 12",
|
||||
"invoice_from_zipcode":"",
|
||||
"invoice_from_city":"Demo town",
|
||||
"invoice_from_country":"US",
|
||||
"invoice_from_tax_id":"",
|
||||
"invoice_from_vat_id":"",
|
||||
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT-ID: EU123456789",
|
||||
"invoice_to_company": "Sample company",
|
||||
"invoice_to_name": "John Doe",
|
||||
"invoice_to_street": "Test street 12",
|
||||
"invoice_to_zipcode": "12345",
|
||||
"invoice_to_city": "Testington",
|
||||
"invoice_to_state": null,
|
||||
"invoice_to_country": "TE",
|
||||
"invoice_to_vat_id": "EU123456789",
|
||||
"invoice_to_beneficiary": "",
|
||||
"custom_field": null,
|
||||
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
|
||||
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT ID: EU123456789",
|
||||
"date": "2017-12-01",
|
||||
"refers": null,
|
||||
"locale": "en",
|
||||
@@ -246,11 +162,6 @@ Endpoints
|
||||
{
|
||||
"position": 1,
|
||||
"description": "Budget Ticket",
|
||||
"item": 1234,
|
||||
"variation": 245,
|
||||
"event_date_from": "2017-12-27T10:00:00Z",
|
||||
"event_date_to": null,
|
||||
"attendee_name": null,
|
||||
"gross_value": "23.00",
|
||||
"tax_value": "0.00",
|
||||
"tax_name": "VAT",
|
||||
|
||||
@@ -13,10 +13,7 @@ Field Type Description
|
||||
===================================== ========================== =======================================================
|
||||
id integer Internal ID of the waiting list entry
|
||||
created datetime Creation date of the waiting list entry
|
||||
name string Name of the user on the waiting list (or ``null``)
|
||||
name_parts object of strings Decomposition of name of the user (or ``null``)
|
||||
email string Email address of the user on the waiting list
|
||||
phone string Phone number of the user on the waiting list (or ``null``)
|
||||
voucher integer Internal ID of the voucher sent to this user. If
|
||||
this field is set, the user has been sent a voucher
|
||||
and is no longer waiting. If it is ``null``, the
|
||||
|
||||
@@ -6,8 +6,8 @@ localecompile:
|
||||
./manage.py compilemessages
|
||||
|
||||
localegen:
|
||||
./manage.py makemessages --keep-pot --ignore "pretix/helpers/*" --ignore "pretix/static/npm_dir/*" $(LNGS)
|
||||
./manage.py makemessages --keep-pot -d djangojs --ignore "pretix/static/npm_dir/*" --ignore "pretix/helpers/*" --ignore "pretix/static/jsi18n/*" --ignore "pretix/static/jsi18n/*" --ignore "pretix/static.dist/*" --ignore "data/*" --ignore "pretix/static/rrule/*" --ignore "build/*" $(LNGS)
|
||||
./manage.py makemessages --keep-pot --ignore "pretix/helpers/*" $(LNGS)
|
||||
./manage.py makemessages --keep-pot -d djangojs --ignore "pretix/helpers/*" --ignore "pretix/static/jsi18n/*" --ignore "pretix/static/jsi18n/*" --ignore "pretix/static.dist/*" --ignore "data/*" --ignore "pretix/static/rrule/*" --ignore "build/*" $(LNGS)
|
||||
|
||||
staticfiles: jsi18n
|
||||
./manage.py collectstatic --noinput
|
||||
@@ -23,8 +23,3 @@ test:
|
||||
|
||||
coverage:
|
||||
coverage run -m py.test
|
||||
|
||||
npminstall:
|
||||
mkdir -p pretix/static.dist/node_prefix
|
||||
npm install --prefix=pretix/static.dist/node_prefix pretix/static/npm_dir/
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class FullAccessSecurityProfile:
|
||||
|
||||
@@ -614,11 +614,6 @@ class EventSettingsSerializer(SettingsSerializer):
|
||||
'waiting_list_enabled',
|
||||
'waiting_list_hours',
|
||||
'waiting_list_auto',
|
||||
'waiting_list_names_asked',
|
||||
'waiting_list_names_required',
|
||||
'waiting_list_phones_asked',
|
||||
'waiting_list_phones_required',
|
||||
'waiting_list_phones_explanation_text',
|
||||
'max_items_per_order',
|
||||
'reservation_time',
|
||||
'contact_mail',
|
||||
@@ -629,7 +624,6 @@ class EventSettingsSerializer(SettingsSerializer):
|
||||
'frontpage_subevent_ordering',
|
||||
'event_list_type',
|
||||
'frontpage_text',
|
||||
'event_info_text',
|
||||
'attendee_names_asked',
|
||||
'attendee_names_required',
|
||||
'attendee_emails_asked',
|
||||
|
||||
@@ -45,14 +45,6 @@ class CompatibleCountryField(serializers.Field):
|
||||
return instance.country_old
|
||||
|
||||
|
||||
class CountryField(serializers.Field):
|
||||
def to_internal_value(self, data):
|
||||
return {self.field_name: Country(data)}
|
||||
|
||||
def to_representation(self, src):
|
||||
return str(src) if src else None
|
||||
|
||||
|
||||
class InvoiceAddressSerializer(I18nAwareModelSerializer):
|
||||
country = CompatibleCountryField(source='*')
|
||||
name = serializers.CharField(required=False)
|
||||
@@ -1330,24 +1322,17 @@ class InlineInvoiceLineSerializer(I18nAwareModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = InvoiceLine
|
||||
fields = ('position', 'description', 'item', 'variation', 'attendee_name', 'event_date_from',
|
||||
'event_date_to', 'gross_value', 'tax_value', 'tax_rate', 'tax_name')
|
||||
fields = ('position', 'description', 'gross_value', 'tax_value', 'tax_rate', 'tax_name')
|
||||
|
||||
|
||||
class InvoiceSerializer(I18nAwareModelSerializer):
|
||||
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
|
||||
refers = serializers.SlugRelatedField(slug_field='full_invoice_no', read_only=True)
|
||||
refers = serializers.SlugRelatedField(slug_field='invoice_no', read_only=True)
|
||||
lines = InlineInvoiceLineSerializer(many=True)
|
||||
invoice_to_country = CountryField()
|
||||
invoice_from_country = CountryField()
|
||||
|
||||
class Meta:
|
||||
model = Invoice
|
||||
fields = ('order', 'number', 'is_cancellation', 'invoice_from', 'invoice_from_name', 'invoice_from_zipcode',
|
||||
'invoice_from_city', 'invoice_from_country', 'invoice_from_tax_id', 'invoice_from_vat_id',
|
||||
'invoice_to', 'invoice_to_company', 'invoice_to_name', 'invoice_to_street', 'invoice_to_zipcode',
|
||||
'invoice_to_city', 'invoice_to_state', 'invoice_to_country', 'invoice_to_vat_id', 'invoice_to_beneficiary',
|
||||
'custom_field', 'date', 'refers', 'locale',
|
||||
fields = ('order', 'number', 'is_cancellation', 'invoice_from', 'invoice_to', 'date', 'refers', 'locale',
|
||||
'introductory_text', 'additional_text', 'payment_provider_text', 'footer_text', 'lines',
|
||||
'foreign_currency_display', 'foreign_currency_rate', 'foreign_currency_rate_date',
|
||||
'internal_reference')
|
||||
|
||||
@@ -8,7 +8,7 @@ class WaitingListSerializer(I18nAwareModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = WaitingListEntry
|
||||
fields = ('id', 'created', 'name', 'name_parts', 'email', 'phone', 'voucher', 'item', 'variation', 'locale', 'subevent', 'priority')
|
||||
fields = ('id', 'created', 'email', 'voucher', 'item', 'variation', 'locale', 'subevent', 'priority')
|
||||
read_only_fields = ('id', 'created', 'voucher')
|
||||
|
||||
def validate(self, data):
|
||||
@@ -32,11 +32,4 @@ class WaitingListSerializer(I18nAwareModelSerializer):
|
||||
if availability[0] == 100:
|
||||
raise ValidationError("This product is currently available.")
|
||||
|
||||
if data.get('name') and data.get('name_parts'):
|
||||
raise ValidationError(
|
||||
{'name': ['Do not specify name if you specified name_parts.']}
|
||||
)
|
||||
if data.get('name_parts') and '_scheme' not in data.get('name_parts'):
|
||||
data['name_parts']['_scheme'] = event.settings.name_scheme
|
||||
|
||||
return data
|
||||
|
||||
@@ -8,7 +8,9 @@ from pretix.api.models import ApiCall, WebHookCall
|
||||
from pretix.base.signals import periodic_task
|
||||
from pretix.helpers.periodic import minimum_interval
|
||||
|
||||
register_webhook_events = Signal()
|
||||
register_webhook_events = Signal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known webhook events. Receivers should return an
|
||||
instance of a subclass of pretix.api.webhooks.WebhookEvent or a list of such
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import importlib
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf.urls import include, re_path
|
||||
from django.conf.urls import include, url
|
||||
from rest_framework import routers
|
||||
|
||||
from pretix.api.views import cart
|
||||
@@ -72,32 +72,30 @@ for app in apps.get_app_configs():
|
||||
importlib.import_module(app.name + '.urls')
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'^', include(router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/', include(orga_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/settings/$', organizer.OrganizerSettingsView.as_view(),
|
||||
name="organizer.settings"),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/giftcards/(?P<giftcard>[^/]+)/', include(giftcard_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/settings/$', event.EventSettingsView.as_view(),
|
||||
name="event.settings"),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/', include(event_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/teams/(?P<team>[^/]+)/', include(team_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/items/(?P<item>[^/]+)/',
|
||||
include(item_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/questions/(?P<question>[^/]+)/',
|
||||
include(question_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/checkinlists/(?P<list>[^/]+)/',
|
||||
include(checkinlist_router.urls)),
|
||||
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/orders/(?P<order>[^/]+)/',
|
||||
include(order_router.urls)),
|
||||
re_path(r"^oauth/authorize$", oauth.AuthorizationView.as_view(), name="authorize"),
|
||||
re_path(r"^oauth/token$", oauth.TokenView.as_view(), name="token"),
|
||||
re_path(r"^oauth/revoke_token$", oauth.RevokeTokenView.as_view(), name="revoke-token"),
|
||||
re_path(r"^device/initialize$", device.InitializeView.as_view(), name="device.initialize"),
|
||||
re_path(r"^device/update$", device.UpdateView.as_view(), name="device.update"),
|
||||
re_path(r"^device/roll$", device.RollKeyView.as_view(), name="device.roll"),
|
||||
re_path(r"^device/revoke$", device.RevokeKeyView.as_view(), name="device.revoke"),
|
||||
re_path(r"^device/eventselection$", device.EventSelectionView.as_view(), name="device.eventselection"),
|
||||
re_path(r"^upload$", upload.UploadView.as_view(), name="upload"),
|
||||
re_path(r"^me$", user.MeView.as_view(), name="user.me"),
|
||||
re_path(r"^version$", version.VersionView.as_view(), name="version"),
|
||||
url(r'^', include(router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/', include(orga_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/settings/$', organizer.OrganizerSettingsView.as_view(),
|
||||
name="organizer.settings"),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/giftcards/(?P<giftcard>[^/]+)/', include(giftcard_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/settings/$', event.EventSettingsView.as_view(),
|
||||
name="event.settings"),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/', include(event_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/teams/(?P<team>[^/]+)/', include(team_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/items/(?P<item>[^/]+)/', include(item_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/questions/(?P<question>[^/]+)/',
|
||||
include(question_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/checkinlists/(?P<list>[^/]+)/',
|
||||
include(checkinlist_router.urls)),
|
||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/orders/(?P<order>[^/]+)/', include(order_router.urls)),
|
||||
url(r"^oauth/authorize$", oauth.AuthorizationView.as_view(), name="authorize"),
|
||||
url(r"^oauth/token$", oauth.TokenView.as_view(), name="token"),
|
||||
url(r"^oauth/revoke_token$", oauth.RevokeTokenView.as_view(), name="revoke-token"),
|
||||
url(r"^device/initialize$", device.InitializeView.as_view(), name="device.initialize"),
|
||||
url(r"^device/update$", device.UpdateView.as_view(), name="device.update"),
|
||||
url(r"^device/roll$", device.RollKeyView.as_view(), name="device.roll"),
|
||||
url(r"^device/revoke$", device.RevokeKeyView.as_view(), name="device.revoke"),
|
||||
url(r"^device/eventselection$", device.EventSelectionView.as_view(), name="device.eventselection"),
|
||||
url(r"^upload$", upload.UploadView.as_view(), name="upload"),
|
||||
url(r"^me$", user.MeView.as_view(), name="user.me"),
|
||||
url(r"^version$", version.VersionView.as_view(), name="version"),
|
||||
]
|
||||
|
||||
@@ -2,12 +2,10 @@ import inspect
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from itertools import groupby
|
||||
from smtplib import SMTPResponseException
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.mail.backends.smtp import EmailBackend
|
||||
from django.db.models import Count
|
||||
from django.dispatch import receiver
|
||||
from django.template.loader import get_template
|
||||
from django.utils.timezone import now
|
||||
@@ -130,21 +128,9 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
|
||||
|
||||
if order:
|
||||
htmlctx['order'] = order
|
||||
positions = list(order.positions.select_related(
|
||||
'item', 'variation', 'subevent', 'addon_to'
|
||||
).annotate(
|
||||
has_addons=Count('addons')
|
||||
))
|
||||
htmlctx['cart'] = [(k, list(v)) for k, v in groupby(
|
||||
positions, key=lambda op: (
|
||||
op.item, op.variation, op.subevent, op.attendee_name,
|
||||
(op.pk if op.addon_to_id else None), (op.pk if op.has_addons else None)
|
||||
)
|
||||
)]
|
||||
|
||||
if position:
|
||||
htmlctx['position'] = position
|
||||
htmlctx['ev'] = position.subevent or self.event
|
||||
|
||||
tpl = get_template(self.template_name)
|
||||
body_html = inline_css(tpl.render(htmlctx))
|
||||
@@ -251,8 +237,6 @@ def get_email_context(**kwargs):
|
||||
from pretix.base.models import InvoiceAddress
|
||||
|
||||
event = kwargs['event']
|
||||
if 'position' in kwargs:
|
||||
kwargs.setdefault("position_or_address", kwargs['position'])
|
||||
if 'order' in kwargs:
|
||||
try:
|
||||
kwargs['invoice_address'] = kwargs['order'].invoice_address
|
||||
|
||||
@@ -13,12 +13,12 @@ from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext, gettext_lazy as _, pgettext
|
||||
|
||||
from pretix.base.models import Invoice, InvoiceLine, OrderPayment
|
||||
from ..services.export import ExportError
|
||||
|
||||
from ...control.forms.filter import get_all_payment_providers
|
||||
from ...helpers import GroupConcat
|
||||
from ...helpers.iter import chunked_iterable
|
||||
from ..exporter import BaseExporter, MultiSheetListExporter
|
||||
from ..services.export import ExportError
|
||||
from ..services.invoices import invoice_pdf_task
|
||||
from ..signals import (
|
||||
register_data_exporters, register_multievent_data_exporters,
|
||||
|
||||
@@ -691,18 +691,13 @@ class QuotaListExporter(ListExporter):
|
||||
verbose_name = gettext_lazy('Quota availabilities')
|
||||
|
||||
def iterate_list(self, form_data):
|
||||
has_subevents = self.event.has_subevents
|
||||
headers = [
|
||||
_('Quota name'), _('Total quota'), _('Paid orders'), _('Pending orders'), _('Blocking vouchers'),
|
||||
_('Current user\'s carts'), _('Waiting list'), _('Exited orders'), _('Current availability')
|
||||
]
|
||||
if has_subevents:
|
||||
headers.append(pgettext('subevent', 'Date'))
|
||||
headers.append(_('Start date'))
|
||||
headers.append(_('End date'))
|
||||
yield headers
|
||||
|
||||
quotas = list(self.event.quotas.select_related('subevent'))
|
||||
quotas = list(self.event.quotas.all())
|
||||
qa = QuotaAvailability(full_results=True)
|
||||
qa.queue(*quotas)
|
||||
qa.compute()
|
||||
@@ -720,18 +715,6 @@ class QuotaListExporter(ListExporter):
|
||||
qa.count_exited_orders[quota],
|
||||
_('Infinite') if avail[1] is None else avail[1]
|
||||
]
|
||||
if has_subevents:
|
||||
if quota.subevent:
|
||||
row.append(quota.subevent.name)
|
||||
row.append(quota.subevent.date_from.astimezone(self.event.timezone).strftime('%Y-%m-%d %H:%M:%S'))
|
||||
if quota.subevent.date_to:
|
||||
row.append(quota.subevent.date_to.astimezone(self.event.timezone).strftime('%Y-%m-%d %H:%M:%S'))
|
||||
else:
|
||||
row.append('')
|
||||
else:
|
||||
row.append('')
|
||||
row.append('')
|
||||
row.append('')
|
||||
yield row
|
||||
|
||||
def get_filename(self):
|
||||
|
||||
@@ -82,9 +82,7 @@ class WaitingListExporter(ListExporter):
|
||||
|
||||
headers = [
|
||||
_('Date'),
|
||||
_('Name'),
|
||||
_('Email'),
|
||||
_('Phone number'),
|
||||
_('Product name'),
|
||||
_('Variation'),
|
||||
_('Event slug'),
|
||||
@@ -119,9 +117,7 @@ class WaitingListExporter(ListExporter):
|
||||
|
||||
row = [
|
||||
entry.created.astimezone(tz).strftime(datetime_format), # alternative: .isoformat(),
|
||||
entry.name,
|
||||
entry.email,
|
||||
entry.phone,
|
||||
str(entry.item) if entry.item else "",
|
||||
str(entry.variation) if entry.variation else "",
|
||||
entry.event.slug,
|
||||
|
||||
@@ -475,7 +475,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
|
||||
if self.invoice.introductory_text:
|
||||
story.append(Paragraph(
|
||||
self.invoice.introductory_text,
|
||||
bleach.clean(self.invoice.introductory_text, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
story.append(Spacer(1, 10 * mm))
|
||||
@@ -578,13 +578,13 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
||||
|
||||
if self.invoice.payment_provider_text:
|
||||
story.append(Paragraph(
|
||||
self.invoice.payment_provider_text,
|
||||
bleach.clean(self.invoice.payment_provider_text, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
|
||||
if self.invoice.additional_text:
|
||||
story.append(Paragraph(
|
||||
self.invoice.additional_text,
|
||||
bleach.clean(self.invoice.additional_text, tags=[]).strip().replace('\n', '<br />\n'),
|
||||
self.stylesheet['Normal']
|
||||
))
|
||||
story.append(Spacer(1, 15 * mm))
|
||||
|
||||
@@ -16,8 +16,6 @@ class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--tasks', action='store', type=str, help='Only execute the tasks with this name '
|
||||
'(dotted path, comma separation)')
|
||||
parser.add_argument('--exclude', action='store', type=str, help='Exclude the tasks with this name '
|
||||
'(dotted path, comma separation)')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
verbosity = int(options['verbosity'])
|
||||
@@ -30,9 +28,6 @@ class Command(BaseCommand):
|
||||
if options.get('tasks'):
|
||||
if name not in options.get('tasks').split(','):
|
||||
continue
|
||||
if options.get('exclude'):
|
||||
if name in options.get('exclude').split(','):
|
||||
continue
|
||||
|
||||
if verbosity > 1:
|
||||
self.stdout.write(f'INFO Running {name}…')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Generated by Django 2.1 on 2018-10-17 00:24
|
||||
|
||||
|
||||
import jsonfallback.fields
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import migrations
|
||||
from django_mysql.checks import mysql_connections
|
||||
@@ -77,19 +77,19 @@ class Migration(migrations.Migration):
|
||||
migrations.AddField(
|
||||
model_name='cartposition',
|
||||
name='attendee_name_parts',
|
||||
field=models.JSONField(null=False, default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(null=False, default=dict),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='orderposition',
|
||||
name='attendee_name_parts',
|
||||
field=models.JSONField(null=False, default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(null=False, default=dict),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceaddress',
|
||||
name='name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.RunPython(set_attendee_name_parts, migrations.RunPython.noop)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.1 on 2018-11-21 12:24
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.db.models.manager
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1 on 2019-01-12 15:12
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.5 on 2019-01-29 13:37
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.5 on 2019-02-01 15:27
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from decimal import Decimal
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.db import migrations, models
|
||||
@@ -189,7 +190,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='cartposition',
|
||||
name='attendee_name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cartposition',
|
||||
@@ -209,7 +210,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='invoiceaddress',
|
||||
name='name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
@@ -224,7 +225,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='orderposition',
|
||||
name='attendee_name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='orderposition',
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1 on 2019-02-08 14:32
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.5 on 2019-02-19 12:45
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.5 on 2019-02-19 09:49
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.5 on 2019-03-12 09:42
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.7 on 2019-03-16 10:14
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from decimal import Decimal
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.1.5 on 2019-04-02 07:22
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.2 on 2019-04-23 08:39
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.2 on 2019-05-09 06:54
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 2.2 on 2019-05-09 07:36
|
||||
|
||||
import django.db.models.deletion
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.fields
|
||||
@@ -16,7 +17,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='cartposition',
|
||||
name='attendee_name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='cartposition',
|
||||
@@ -36,7 +37,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='invoiceaddress',
|
||||
name='name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
@@ -51,7 +52,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AlterField(
|
||||
model_name='orderposition',
|
||||
name='attendee_name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='orderposition',
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import django.db.models.deletion
|
||||
import django_countries.fields
|
||||
import jsonfallback.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.helpers.countries
|
||||
@@ -42,7 +43,7 @@ class Migration(migrations.Migration):
|
||||
migrations.AddField(
|
||||
model_name='checkinlist',
|
||||
name='rules',
|
||||
field=models.JSONField(default=dict),
|
||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='checkin',
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# Generated by Django 3.0.10 on 2021-03-01 15:10
|
||||
|
||||
|
||||
import phonenumber_field.modelfields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pretixbase', '0176_auto_20210205_1512'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='waitinglistentry',
|
||||
name='name_cached',
|
||||
field=models.CharField(max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='waitinglistentry',
|
||||
name='name_parts',
|
||||
field=models.JSONField(default=dict),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='waitinglistentry',
|
||||
name='phone',
|
||||
field=phonenumber_field.modelfields.PhoneNumberField(max_length=128, null=True, region=None),
|
||||
),
|
||||
]
|
||||
@@ -1,34 +0,0 @@
|
||||
# Generated by Django 3.0.12 on 2021-03-08 13:26
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pretixbase', '0177_auto_20210301_1510'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='attendee_name',
|
||||
field=models.TextField(null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='event_date_to',
|
||||
field=models.DateTimeField(null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='item',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.Item'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='invoiceline',
|
||||
name='variation',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.ItemVariation'),
|
||||
),
|
||||
]
|
||||
@@ -4,6 +4,7 @@ from django.db.models import Exists, F, Max, OuterRef, Q, Subquery
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
from django_scopes import ScopedManager, scopes_disabled
|
||||
from jsonfallback.fields import FallbackJSONField
|
||||
|
||||
from pretix.base.models import LoggedModel
|
||||
from pretix.base.models.fields import MultiStringField
|
||||
@@ -46,7 +47,7 @@ class CheckinList(LoggedModel):
|
||||
'any of the selected sales channels. This option can be useful when tickets sold at the box office '
|
||||
'are not checked again before entry and should be considered validated directly upon purchase.')
|
||||
)
|
||||
rules = models.JSONField(default=dict, blank=True)
|
||||
rules = FallbackJSONField(default=dict, blank=True)
|
||||
|
||||
objects = ScopedManager(organizer='event__organizer')
|
||||
|
||||
|
||||
@@ -697,9 +697,9 @@ class Event(EventMixin, LoggedModel):
|
||||
for k, v in rules.items():
|
||||
if k == 'lookup':
|
||||
if v[0] == 'product':
|
||||
v[1] = str(item_map.get(int(v[1]), 0).pk) if int(v[1]) in item_map else "0"
|
||||
v[1] = str(item_map.get(int(v[1]), 0).pk)
|
||||
elif v[0] == 'variation':
|
||||
v[1] = str(variation_map.get(int(v[1]), 0).pk) if int(v[1]) in variation_map else "0"
|
||||
v[1] = str(variation_map.get(int(v[1]), 0).pk)
|
||||
else:
|
||||
_walk_rules(v)
|
||||
elif isinstance(rules, list):
|
||||
|
||||
@@ -273,14 +273,6 @@ class InvoiceLine(models.Model):
|
||||
:type subevent: SubEvent
|
||||
:param event_date_from: Event date of the (sub)event at the time the invoice was created
|
||||
:type event_date_from: datetime
|
||||
:param event_date_to: Event end date of the (sub)event at the time the invoice was created
|
||||
:type event_date_to: datetime
|
||||
:param item: The item this line refers to
|
||||
:type item: Item
|
||||
:param variation: The variation this line refers to
|
||||
:type variation: ItemVariation
|
||||
:param attendee_name: The attendee name at the time the invoice was created
|
||||
:type attendee_name: str
|
||||
"""
|
||||
invoice = models.ForeignKey('Invoice', related_name='lines', on_delete=models.CASCADE)
|
||||
position = models.PositiveIntegerField(default=0)
|
||||
@@ -291,10 +283,6 @@ class InvoiceLine(models.Model):
|
||||
tax_name = models.CharField(max_length=190)
|
||||
subevent = models.ForeignKey('SubEvent', null=True, blank=True, on_delete=models.PROTECT)
|
||||
event_date_from = models.DateTimeField(null=True)
|
||||
event_date_to = models.DateTimeField(null=True)
|
||||
item = models.ForeignKey('Item', null=True, blank=True, on_delete=models.PROTECT)
|
||||
variation = models.ForeignKey('ItemVariation', null=True, blank=True, on_delete=models.PROTECT)
|
||||
attendee_name = models.TextField(null=True, blank=True)
|
||||
|
||||
@property
|
||||
def net_value(self):
|
||||
|
||||
@@ -29,6 +29,7 @@ from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
from django_countries.fields import Country
|
||||
from django_scopes import ScopedManager, scopes_disabled
|
||||
from i18nfield.strings import LazyI18nString
|
||||
from jsonfallback.fields import FallbackJSONField
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from phonenumber_field.phonenumber import PhoneNumber
|
||||
from phonenumbers import NumberParseException
|
||||
@@ -1131,7 +1132,7 @@ class AbstractPosition(models.Model):
|
||||
blank=True, null=True,
|
||||
help_text=_("Empty, if this product is not an admission ticket")
|
||||
)
|
||||
attendee_name_parts = models.JSONField(
|
||||
attendee_name_parts = FallbackJSONField(
|
||||
blank=True, default=dict
|
||||
)
|
||||
attendee_email = models.EmailField(
|
||||
@@ -2251,7 +2252,7 @@ class InvoiceAddress(models.Model):
|
||||
is_business = models.BooleanField(default=False, verbose_name=_('Business customer'))
|
||||
company = models.CharField(max_length=255, blank=True, verbose_name=_('Company name'))
|
||||
name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
||||
name_parts = models.JSONField(default=dict)
|
||||
name_parts = FallbackJSONField(default=dict)
|
||||
street = models.TextField(verbose_name=_('Address'), blank=False)
|
||||
zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=False)
|
||||
city = models.CharField(max_length=255, verbose_name=_('City'), blank=False)
|
||||
|
||||
@@ -5,13 +5,11 @@ from django.db import models, transaction
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
from django_scopes import ScopedManager
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
from pretix.base.email import get_email_context
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.models import Voucher
|
||||
from pretix.base.services.mail import mail
|
||||
from pretix.base.settings import PERSON_NAME_SCHEMES
|
||||
|
||||
from .base import LoggedModel
|
||||
from .event import Event, SubEvent
|
||||
@@ -39,21 +37,9 @@ class WaitingListEntry(LoggedModel):
|
||||
verbose_name=_("On waiting list since"),
|
||||
auto_now_add=True
|
||||
)
|
||||
name_cached = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Name"),
|
||||
blank=True, null=True,
|
||||
)
|
||||
name_parts = models.JSONField(
|
||||
blank=True, default=dict
|
||||
)
|
||||
email = models.EmailField(
|
||||
verbose_name=_("E-mail address")
|
||||
)
|
||||
phone = PhoneNumberField(
|
||||
null=True, blank=True,
|
||||
verbose_name=_("Phone number")
|
||||
)
|
||||
voucher = models.ForeignKey(
|
||||
'Voucher',
|
||||
verbose_name=_("Assigned voucher"),
|
||||
@@ -97,27 +83,6 @@ class WaitingListEntry(LoggedModel):
|
||||
WaitingListEntry.clean_itemvar(self.event, self.item, self.variation)
|
||||
WaitingListEntry.clean_subevent(self.event, self.subevent)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
update_fields = kwargs.get('update_fields', [])
|
||||
if 'name_parts' in update_fields:
|
||||
update_fields.append('name_cached')
|
||||
self.name_cached = self.name
|
||||
if self.name_parts is None:
|
||||
self.name_parts = {}
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if not self.name_parts:
|
||||
return None
|
||||
if '_legacy' in self.name_parts:
|
||||
return self.name_parts['_legacy']
|
||||
if '_scheme' in self.name_parts:
|
||||
scheme = PERSON_NAME_SCHEMES[self.name_parts['_scheme']]
|
||||
else:
|
||||
scheme = PERSON_NAME_SCHEMES[self.event.settings.name_scheme]
|
||||
return scheme['concatenation'](self.name_parts).strip()
|
||||
|
||||
def send_voucher(self, quota_cache=None, user=None, auth=None):
|
||||
availability = (
|
||||
self.variation.check_quotas(count_waitinglist=False, subevent=self.subevent, _cache=quota_cache)
|
||||
|
||||
@@ -970,17 +970,17 @@ class ManualPayment(BasePaymentProvider):
|
||||
label=_('Payment process description in order confirmation emails'),
|
||||
help_text=_('This text will be included for the {payment_info} placeholder in order confirmation '
|
||||
'mails. It should instruct the user on how to proceed with the payment. You can use '
|
||||
'the placeholders {order}, {amount}, {currency} and {amount_with_currency}.'),
|
||||
'the placeholders {order}, {total}, {currency} and {total_with_currency}.'),
|
||||
widget=I18nTextarea,
|
||||
validators=[PlaceholderValidator(['{order}', '{amount}', '{currency}', '{amount_with_currency}'])],
|
||||
validators=[PlaceholderValidator(['{order}', '{total}', '{currency}', '{total_with_currency}'])],
|
||||
)),
|
||||
('pending_description', I18nFormField(
|
||||
label=_('Payment process description for pending orders'),
|
||||
help_text=_('This text will be shown on the order confirmation page for pending orders. '
|
||||
'It should instruct the user on how to proceed with the payment. You can use '
|
||||
'the placeholders {order}, {amount}, {currency} and {amount_with_currency}.'),
|
||||
'the placeholders {order}, {total}, {currency} and {total_with_currency}.'),
|
||||
widget=I18nTextarea,
|
||||
validators=[PlaceholderValidator(['{order}', '{amount}', '{currency}', '{amount_with_currency}'])],
|
||||
validators=[PlaceholderValidator(['{order}', '{total}', '{currency}', '{total_with_currency}'])],
|
||||
)),
|
||||
] + list(super().settings_form_fields.items())
|
||||
)
|
||||
@@ -1001,24 +1001,21 @@ class ManualPayment(BasePaymentProvider):
|
||||
def checkout_confirm_render(self, request):
|
||||
return self.payment_form_render(request)
|
||||
|
||||
def format_map(self, order, payment):
|
||||
def format_map(self, order):
|
||||
return {
|
||||
'order': order.code,
|
||||
'amount': payment.amount,
|
||||
'currency': self.event.currency,
|
||||
'amount_with_currency': money_filter(payment.amount, self.event.currency),
|
||||
# {total} and {total_with_currency} are deprecated
|
||||
'total': order.total,
|
||||
'total_with_currency': money_filter(order.total, self.event.currency),
|
||||
'currency': self.event.currency,
|
||||
'total_with_currency': money_filter(order.total, self.event.currency)
|
||||
}
|
||||
|
||||
def order_pending_mail_render(self, order, payment) -> str:
|
||||
msg = str(self.settings.get('email_instructions', as_type=LazyI18nString)).format_map(self.format_map(order, payment))
|
||||
def order_pending_mail_render(self, order) -> str:
|
||||
msg = str(self.settings.get('email_instructions', as_type=LazyI18nString)).format_map(self.format_map(order))
|
||||
return msg
|
||||
|
||||
def payment_pending_render(self, request, payment) -> str:
|
||||
return rich_text(
|
||||
str(self.settings.get('pending_description', as_type=LazyI18nString)).format_map(self.format_map(payment.order, payment))
|
||||
str(self.settings.get('pending_description', as_type=LazyI18nString)).format_map(self.format_map(payment.order))
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -298,11 +298,6 @@ DEFAULT_VARIABLES = OrderedDict((
|
||||
"editor_sample": _("Event organizer info text"),
|
||||
"evaluate": lambda op, order, ev: str(order.event.settings.organizer_info_text)
|
||||
}),
|
||||
("event_info_text", {
|
||||
"label": _("Event info text"),
|
||||
"editor_sample": _("Event info text"),
|
||||
"evaluate": lambda op, order, ev: str(order.event.settings.event_info_text)
|
||||
}),
|
||||
("now_date", {
|
||||
"label": _("Printing date"),
|
||||
"editor_sample": _("2017-05-31"),
|
||||
|
||||
@@ -171,17 +171,9 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
||||
if invoice.event.has_subevents:
|
||||
desc += "<br />" + pgettext("subevent", "Date: {}").format(p.subevent)
|
||||
InvoiceLine.objects.create(
|
||||
position=i,
|
||||
invoice=invoice,
|
||||
description=desc,
|
||||
gross_value=p.price,
|
||||
tax_value=p.tax_value,
|
||||
subevent=p.subevent,
|
||||
item=p.item,
|
||||
variation=p.variation,
|
||||
attendee_name=p.attendee_name if invoice.event.settings.invoice_attendee_name else None,
|
||||
event_date_from=p.subevent.date_from if invoice.event.has_subevents else invoice.event.date_from,
|
||||
event_date_to=p.subevent.date_to if invoice.event.has_subevents else invoice.event.date_to,
|
||||
position=i, invoice=invoice, description=desc,
|
||||
gross_value=p.price, tax_value=p.tax_value,
|
||||
subevent=p.subevent, event_date_from=(p.subevent.date_from if p.subevent else invoice.event.date_from),
|
||||
tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else ''
|
||||
)
|
||||
|
||||
@@ -206,8 +198,6 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
||||
invoice=invoice,
|
||||
description=fee_title,
|
||||
gross_value=fee.value,
|
||||
event_date_from=None if invoice.event.has_subevents else invoice.event.date_from,
|
||||
event_date_to=None if invoice.event.has_subevents else invoice.event.date_to,
|
||||
tax_value=fee.tax_value,
|
||||
tax_rate=fee.tax_rate,
|
||||
tax_name=fee.tax_rule.name if fee.tax_rule else ''
|
||||
|
||||
@@ -19,7 +19,6 @@ from django.core.mail import (
|
||||
EmailMultiAlternatives, SafeMIMEMultipart, get_connection,
|
||||
)
|
||||
from django.core.mail.message import SafeMIMEText
|
||||
from django.db import transaction
|
||||
from django.template.loader import get_template
|
||||
from django.utils.translation import gettext as _, pgettext
|
||||
from django_scopes import scope, scopes_disabled
|
||||
@@ -241,15 +240,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
||||
task_chain = []
|
||||
|
||||
task_chain.append(send_task)
|
||||
|
||||
if 'locmem' in settings.EMAIL_BACKEND:
|
||||
# This clause is triggered during unit tests, because transaction.on_commit never fires due to the nature
|
||||
# Django's unit tests work
|
||||
chain(*task_chain).apply_async()
|
||||
else:
|
||||
transaction.on_commit(
|
||||
lambda: chain(*task_chain).apply_async()
|
||||
)
|
||||
chain(*task_chain).apply_async()
|
||||
|
||||
|
||||
class CustomEmail(EmailMultiAlternatives):
|
||||
|
||||
@@ -327,7 +327,7 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
|
||||
|
||||
|
||||
def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device=None, oauth_application=None,
|
||||
cancellation_fee=None, keep_fees=None, cancel_invoice=True):
|
||||
cancellation_fee=None, keep_fees=None):
|
||||
"""
|
||||
Mark this order as canceled
|
||||
:param order: The order to change
|
||||
@@ -351,10 +351,9 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
||||
if not order.cancel_allowed():
|
||||
raise OrderError(_('You cannot cancel this order.'))
|
||||
invoices = []
|
||||
if cancel_invoice:
|
||||
i = order.invoices.filter(is_cancellation=False).last()
|
||||
if i and not i.refered.exists():
|
||||
invoices.append(generate_cancellation(i))
|
||||
i = order.invoices.filter(is_cancellation=False).last()
|
||||
if i and not i.refered.exists():
|
||||
invoices.append(generate_cancellation(i))
|
||||
|
||||
for position in order.positions.all():
|
||||
for gc in position.issued_gift_cards.all():
|
||||
@@ -404,7 +403,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
||||
order.cancellation_date = now()
|
||||
order.save(update_fields=['status', 'cancellation_date', 'total'])
|
||||
|
||||
if cancel_invoice and i:
|
||||
if i:
|
||||
invoices.append(generate_invoice(order))
|
||||
else:
|
||||
with order.event.lock():
|
||||
@@ -2153,12 +2152,11 @@ def _try_auto_refund(order, manual_refund=False, allow_partial=False, source=Ord
|
||||
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,))
|
||||
@scopes_disabled()
|
||||
def cancel_order(self, order: int, user: int=None, send_mail: bool=True, api_token=None, oauth_application=None,
|
||||
device=None, cancellation_fee=None, try_auto_refund=False, refund_as_giftcard=False, comment=None,
|
||||
cancel_invoice=True):
|
||||
device=None, cancellation_fee=None, try_auto_refund=False, refund_as_giftcard=False, comment=None):
|
||||
try:
|
||||
try:
|
||||
ret = _cancel_order(order, user, send_mail, api_token, device, oauth_application,
|
||||
cancellation_fee, cancel_invoice=cancel_invoice)
|
||||
cancellation_fee)
|
||||
if try_auto_refund:
|
||||
_try_auto_refund(order, refund_as_giftcard=refund_as_giftcard,
|
||||
comment=comment)
|
||||
|
||||
@@ -975,61 +975,6 @@ DEFAULTS = {
|
||||
widget=forms.NumberInput(),
|
||||
)
|
||||
},
|
||||
'waiting_list_names_asked': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
'form_class': forms.BooleanField,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Ask for a name"),
|
||||
help_text=_("Ask for a name when signing up to the waiting list."),
|
||||
)
|
||||
},
|
||||
'waiting_list_names_required': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
'form_class': forms.BooleanField,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Require name"),
|
||||
help_text=_("Require a name when signing up to the waiting list.."),
|
||||
widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_settings-waiting_list_names_asked'}),
|
||||
)
|
||||
},
|
||||
'waiting_list_phones_asked': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
'form_class': forms.BooleanField,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Ask for a phone number"),
|
||||
help_text=_("Ask for a phone number when signing up to the waiting list."),
|
||||
)
|
||||
},
|
||||
'waiting_list_phones_required': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
'form_class': forms.BooleanField,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Require phone number"),
|
||||
help_text=_("Require a phone number when signing up to the waiting list.."),
|
||||
widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_settings-waiting_list_phones_asked'}),
|
||||
)
|
||||
},
|
||||
'waiting_list_phones_explanation_text': {
|
||||
'default': '',
|
||||
'type': LazyI18nString,
|
||||
'form_class': I18nFormField,
|
||||
'serializer_class': I18nField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Phone number explanation"),
|
||||
widget=I18nTextarea,
|
||||
widget_kwargs={'attrs': {'rows': '2'}},
|
||||
help_text=_("If you ask for a phone number, explain why you do so and what you will use the phone number for.")
|
||||
)
|
||||
},
|
||||
|
||||
'ticket_download': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
@@ -2000,18 +1945,6 @@ Your {event} team"""))
|
||||
widget=I18nTextarea
|
||||
)
|
||||
},
|
||||
'event_info_text': {
|
||||
'default': '',
|
||||
'type': LazyI18nString,
|
||||
'serializer_class': I18nField,
|
||||
'form_class': I18nFormField,
|
||||
'form_kwargs': dict(
|
||||
label=_('Info text'),
|
||||
widget=I18nTextarea,
|
||||
widget_kwargs={'attrs': {'rows': '2'}},
|
||||
help_text=_('Not displayed anywhere by default, but if you want to, you can use this e.g. in ticket templates.')
|
||||
)
|
||||
},
|
||||
'banner_text': {
|
||||
'default': '',
|
||||
'type': LazyI18nString,
|
||||
|
||||
@@ -203,7 +203,7 @@ class EmailAddressShredder(BaseDataShredder):
|
||||
class WaitingListShredder(BaseDataShredder):
|
||||
verbose_name = _('Waiting list')
|
||||
identifier = 'waiting_list'
|
||||
description = _('This will remove all names, email addresses, and phone numbers from the waiting list.')
|
||||
description = _('This will remove all email addresses from the waiting list.')
|
||||
|
||||
def generate_files(self) -> List[Tuple[str, str, str]]:
|
||||
yield 'waiting-list.json', 'application/json', json.dumps([
|
||||
@@ -213,7 +213,7 @@ class WaitingListShredder(BaseDataShredder):
|
||||
|
||||
@transaction.atomic
|
||||
def shred_data(self):
|
||||
self.event.waitinglistentries.update(name_cached=None, name_parts={'_shredded': True}, email='█', phone='█')
|
||||
self.event.waitinglistentries.update(email='█')
|
||||
|
||||
for wle in self.event.waitinglistentries.select_related('voucher').filter(voucher__isnull=False):
|
||||
if '@' in wle.voucher.comment:
|
||||
@@ -222,14 +222,7 @@ class WaitingListShredder(BaseDataShredder):
|
||||
|
||||
for le in self.event.logentry_set.filter(action_type="pretix.voucher.added.waitinglist").exclude(data=""):
|
||||
d = le.parsed_data
|
||||
if 'name' in d:
|
||||
d['name'] = '█'
|
||||
if 'name_parts' in d:
|
||||
d['name_parts'] = {
|
||||
'_legacy': '█'
|
||||
}
|
||||
d['email'] = '█'
|
||||
d['phone'] = '█'
|
||||
le.data = json.dumps(d)
|
||||
le.shredded = True
|
||||
le.save(update_fields=['data', 'shredded'])
|
||||
|
||||
@@ -164,7 +164,9 @@ class DeprecatedSignal(django.dispatch.Signal):
|
||||
super().connect(receiver, sender=None, weak=True, dispatch_uid=None)
|
||||
|
||||
|
||||
event_live_issues = EventPluginSignal()
|
||||
event_live_issues = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to determine whether an event can be taken live. If you want to
|
||||
prevent the event from going live, return a string that will be displayed to the user
|
||||
@@ -174,7 +176,9 @@ As with all event-plugin signals, the ``sender`` keyword argument will contain t
|
||||
"""
|
||||
|
||||
|
||||
register_payment_providers = EventPluginSignal()
|
||||
register_payment_providers = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known payment providers. Receivers should return a
|
||||
subclass of pretix.base.payment.BasePaymentProvider or a list of these
|
||||
@@ -182,7 +186,9 @@ subclass of pretix.base.payment.BasePaymentProvider or a list of these
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_mail_placeholders = EventPluginSignal()
|
||||
register_mail_placeholders = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known email text placeholders. Receivers should return
|
||||
an instance of a subclass of pretix.base.email.BaseMailTextPlaceholder or a list of these.
|
||||
@@ -190,7 +196,9 @@ an instance of a subclass of pretix.base.email.BaseMailTextPlaceholder or a list
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_html_mail_renderers = EventPluginSignal()
|
||||
register_html_mail_renderers = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known HTML email renderers. Receivers should return a
|
||||
subclass of pretix.base.email.BaseHTMLMailRenderer or a list of these
|
||||
@@ -198,7 +206,9 @@ subclass of pretix.base.email.BaseHTMLMailRenderer or a list of these
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_invoice_renderers = EventPluginSignal()
|
||||
register_invoice_renderers = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known invoice renderers. Receivers should return a
|
||||
subclass of pretix.base.invoice.BaseInvoiceRenderer or a list of these
|
||||
@@ -206,7 +216,9 @@ subclass of pretix.base.invoice.BaseInvoiceRenderer or a list of these
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_ticket_secret_generators = EventPluginSignal()
|
||||
register_ticket_secret_generators = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known ticket secret generators. Receivers should return a
|
||||
subclass of ``pretix.base.secrets.BaseTicketSecretGenerator`` or a list of these
|
||||
@@ -214,7 +226,9 @@ subclass of ``pretix.base.secrets.BaseTicketSecretGenerator`` or a list of these
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_data_shredders = EventPluginSignal()
|
||||
register_data_shredders = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known data shredders. Receivers should return a
|
||||
subclass of pretix.base.shredder.BaseDataShredder or a list of these
|
||||
@@ -222,7 +236,9 @@ subclass of pretix.base.shredder.BaseDataShredder or a list of these
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_ticket_outputs = EventPluginSignal()
|
||||
register_ticket_outputs = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known ticket outputs. Receivers should return a
|
||||
subclass of pretix.base.ticketoutput.BaseTicketOutput
|
||||
@@ -230,7 +246,9 @@ subclass of pretix.base.ticketoutput.BaseTicketOutput
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_notification_types = EventPluginSignal()
|
||||
register_notification_types = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known notification types. Receivers should return an
|
||||
instance of a subclass of pretix.base.notifications.NotificationType or a list of such
|
||||
@@ -241,14 +259,18 @@ however for this signal, the ``sender`` **may also be None** to allow creating t
|
||||
notification settings!
|
||||
"""
|
||||
|
||||
register_sales_channels = django.dispatch.Signal()
|
||||
register_sales_channels = django.dispatch.Signal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known sales channels types. Receivers should return an
|
||||
instance of a subclass of ``pretix.base.channels.SalesChannel`` or a list of such
|
||||
instances.
|
||||
"""
|
||||
|
||||
register_data_exporters = EventPluginSignal()
|
||||
register_data_exporters = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to get all known data exporters. Receivers should return a
|
||||
subclass of pretix.base.exporter.BaseExporter
|
||||
@@ -256,20 +278,21 @@ subclass of pretix.base.exporter.BaseExporter
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
register_multievent_data_exporters = django.dispatch.Signal()
|
||||
register_multievent_data_exporters = django.dispatch.Signal(
|
||||
providing_args=["event"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``event``
|
||||
|
||||
This signal is sent out to get all known data exporters, which support exporting data for
|
||||
multiple events. Receivers should return a subclass of pretix.base.exporter.BaseExporter
|
||||
|
||||
The ``sender`` keyword argument will contain an organizer.
|
||||
"""
|
||||
|
||||
validate_order = EventPluginSignal()
|
||||
validate_order = EventPluginSignal(
|
||||
providing_args=["payment_provider", "positions", "email", "locale", "invoice_address",
|
||||
"meta_info"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``payment_provider``, ``positions``, ``email``, ``locale``, ``invoice_address``, ``meta_info``
|
||||
|
||||
This signal is sent out when the user tries to confirm the order, before we actually create
|
||||
the order. It allows you to inspect the cart positions. Your return value will be ignored,
|
||||
but you can raise an OrderError with an appropriate exception message if you like to block
|
||||
@@ -278,10 +301,10 @@ the order. We strongly discourage making changes to the order here.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
validate_cart = EventPluginSignal()
|
||||
validate_cart = EventPluginSignal(
|
||||
providing_args=["positions"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``positions``
|
||||
|
||||
This signal is sent out before the user starts checkout. It includes an iterable
|
||||
with the current CartPosition objects.
|
||||
The response of receivers will be ignored, but you can raise a CartError with an
|
||||
@@ -290,10 +313,10 @@ appropriate exception message.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
validate_cart_addons = EventPluginSignal()
|
||||
validate_cart_addons = EventPluginSignal(
|
||||
providing_args=["addons", "base_position", "iao"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``addons``, ``base_position``, ``iao``
|
||||
|
||||
This signal is sent when a user tries to select a combination of addons. In contrast to
|
||||
``validate_cart``, this is executed before the cart is actually modified. You are passed
|
||||
an argument ``addons`` containing a dict of ``(item, variation or None) → count`` tuples as well
|
||||
@@ -305,10 +328,10 @@ appropriate exception message.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_placed = EventPluginSignal()
|
||||
order_placed = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order is placed. The order object is given
|
||||
as the first argument. This signal is *not* sent out if an order is created through
|
||||
splitting an existing order, so you can not expect to see all orders by listening
|
||||
@@ -317,10 +340,10 @@ to this signal.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_paid = EventPluginSignal()
|
||||
order_paid = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order is paid. The order object is given
|
||||
as the first argument. This signal is *not* sent out if an order is marked as paid
|
||||
because an already-paid order has been split.
|
||||
@@ -328,80 +351,80 @@ because an already-paid order has been split.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_canceled = EventPluginSignal()
|
||||
order_canceled = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order is canceled. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_reactivated = EventPluginSignal()
|
||||
order_reactivated = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time a canceled order is reactivated. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_expired = EventPluginSignal()
|
||||
order_expired = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order is marked as expired. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_modified = EventPluginSignal()
|
||||
order_modified = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order's information is modified. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_changed = EventPluginSignal()
|
||||
order_changed = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order's content is changed. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_approved = EventPluginSignal()
|
||||
order_approved = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order is being approved. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_denied = EventPluginSignal()
|
||||
order_denied = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time an order is being denied. The order object is given
|
||||
as the first argument.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
order_gracefully_delete = EventPluginSignal()
|
||||
order_gracefully_delete = EventPluginSignal(
|
||||
providing_args=["order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``
|
||||
|
||||
This signal is sent out every time a test-mode order is being deleted. The order object
|
||||
is given as the first argument.
|
||||
|
||||
@@ -412,10 +435,10 @@ the deletion of the order.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
checkin_created = EventPluginSignal()
|
||||
checkin_created = EventPluginSignal(
|
||||
providing_args=["checkin"],
|
||||
)
|
||||
"""
|
||||
Arguments: ``checkin``
|
||||
|
||||
This signal is sent out every time a check-in is created (i.e. an order position is marked as
|
||||
checked in). It is not send if the position was already checked in and is force-checked-in a second time.
|
||||
The check-in object is given as the first argument
|
||||
@@ -423,10 +446,10 @@ The check-in object is given as the first argument
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
logentry_display = EventPluginSignal()
|
||||
logentry_display = EventPluginSignal(
|
||||
providing_args=["logentry"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``logentry``
|
||||
|
||||
To display an instance of the ``LogEntry`` model to a human user,
|
||||
``pretix.base.signals.logentry_display`` will be sent out with a ``logentry`` argument.
|
||||
|
||||
@@ -436,10 +459,10 @@ to the user. The receivers are expected to return plain text.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
logentry_object_link = EventPluginSignal()
|
||||
logentry_object_link = EventPluginSignal(
|
||||
providing_args=["logentry"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``logentry``
|
||||
|
||||
To display the relationship of an instance of the ``LogEntry`` model to another model
|
||||
to a human user, ``pretix.base.signals.logentry_object_link`` will be sent out with a
|
||||
``logentry`` argument.
|
||||
@@ -464,10 +487,10 @@ Make sure that any user content in the HTML code you return is properly escaped!
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
requiredaction_display = EventPluginSignal()
|
||||
requiredaction_display = EventPluginSignal(
|
||||
providing_args=["action", "request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``action``, ``request``
|
||||
|
||||
To display an instance of the ``RequiredAction`` model to a human user,
|
||||
``pretix.base.signals.requiredaction_display`` will be sent out with a ``action`` argument.
|
||||
You will also get the current ``request`` in a different argument.
|
||||
@@ -478,10 +501,10 @@ to the user. The receivers are expected to return HTML code.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
event_copy_data = EventPluginSignal()
|
||||
event_copy_data = EventPluginSignal(
|
||||
providing_args=["other", "tax_map", "category_map", "item_map", "question_map", "variation_map", "checkin_list_map"]
|
||||
)
|
||||
"""
|
||||
Arguments: "other", ``tax_map``, ``category_map``, ``item_map``, ``question_map``, ``variation_map``, ``checkin_list_map``
|
||||
|
||||
This signal is sent out when a new event is created as a clone of an existing event, i.e.
|
||||
the settings from the older event are copied to the newer one. You can listen to this
|
||||
signal to copy data or configuration stored within your plugin's models as well.
|
||||
@@ -496,10 +519,10 @@ keyword argument will contain the event to **copy from**. The keyword arguments
|
||||
in the new event of the respective types.
|
||||
"""
|
||||
|
||||
item_copy_data = EventPluginSignal()
|
||||
item_copy_data = EventPluginSignal(
|
||||
providing_args=["source", "target"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``source``, ``target``
|
||||
|
||||
This signal is sent out when a new product is created as a clone of an existing product, i.e.
|
||||
the settings from the older product are copied to the newer one. You can listen to this
|
||||
signal to copy data or configuration stored within your plugin's models as well.
|
||||
@@ -523,10 +546,10 @@ All plugins that are installed may send fields for the global settings form, as
|
||||
an OrderedDict of (setting name, form field).
|
||||
"""
|
||||
|
||||
order_fee_calculation = EventPluginSignal()
|
||||
order_fee_calculation = EventPluginSignal(
|
||||
providing_args=['positions', 'invoice_address', 'meta_info', 'total', 'gift_cards']
|
||||
)
|
||||
"""
|
||||
Arguments: 'positions', 'invoice_address', 'meta_info', 'total', 'gift_cards'
|
||||
|
||||
This signals allows you to add fees to an order while it is being created. You are expected to
|
||||
return a list of ``OrderFee`` objects that are not yet saved to the database
|
||||
(because there is no order yet).
|
||||
@@ -539,10 +562,10 @@ keyword argument will contain the total cart sum without any fees. You should no
|
||||
the gift cards in use.
|
||||
"""
|
||||
|
||||
order_fee_type_name = EventPluginSignal()
|
||||
order_fee_type_name = EventPluginSignal(
|
||||
providing_args=['request', 'fee']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request', 'fee'
|
||||
|
||||
This signals allows you to return a human-readable description for a fee type based on the ``fee_type``
|
||||
and ``internal_type`` attributes of the ``OrderFee`` model that you get as keyword arguments. You are
|
||||
expected to return a string or None, if you don't know about this fee.
|
||||
@@ -550,20 +573,20 @@ expected to return a string or None, if you don't know about this fee.
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
allow_ticket_download = EventPluginSignal()
|
||||
allow_ticket_download = EventPluginSignal(
|
||||
providing_args=['order']
|
||||
)
|
||||
"""
|
||||
Arguments: 'order'
|
||||
|
||||
This signal is sent out to check if tickets for an order can be downloaded. If any receiver returns false,
|
||||
a download will not be offered.
|
||||
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
email_filter = EventPluginSignal()
|
||||
email_filter = EventPluginSignal(
|
||||
providing_args=['message', 'order', 'user']
|
||||
)
|
||||
"""
|
||||
Arguments: 'message', 'order', 'user'
|
||||
|
||||
This signal allows you to implement a middleware-style filter on all outgoing emails. You are expected to
|
||||
return a (possibly modified) copy of the message object passed to you.
|
||||
|
||||
@@ -575,10 +598,10 @@ If the email is associated with a specific user, e.g. a notification email, the
|
||||
well, otherwise it will be ``None``.
|
||||
"""
|
||||
|
||||
global_email_filter = GlobalSignal()
|
||||
global_email_filter = GlobalSignal(
|
||||
providing_args=['message', 'order', 'user']
|
||||
)
|
||||
"""
|
||||
Arguments: 'message', 'order', 'user'
|
||||
|
||||
This signal allows you to implement a middleware-style filter on all outgoing emails. You are expected to
|
||||
return a (possibly modified) copy of the message object passed to you.
|
||||
|
||||
@@ -643,10 +666,10 @@ a ``subevent`` argument which might be none and you are expected to return a lis
|
||||
"""
|
||||
|
||||
|
||||
quota_availability = EventPluginSignal()
|
||||
quota_availability = EventPluginSignal(
|
||||
providing_args=['quota', 'result', 'count_waitinglist']
|
||||
)
|
||||
"""
|
||||
Arguments: 'quota', 'result', 'count_waitinglist'
|
||||
|
||||
This signal allows you to modify the availability of a quota. You are passed the ``quota`` and an
|
||||
``availability`` result calculated by pretix code or other plugins. ``availability`` is a tuple
|
||||
with the first entry being one of the ``Quota.AVAILABILITY_*`` constants and the second entry being
|
||||
@@ -659,23 +682,25 @@ system really bad.** Also, keep in mind that your response is subject to caching
|
||||
quotas might be used for display (not for actual order processing).
|
||||
"""
|
||||
|
||||
order_split = EventPluginSignal()
|
||||
order_split = EventPluginSignal(
|
||||
providing_args=["original", "split_order"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``original``, ``split_order``
|
||||
|
||||
This signal is sent out when an order is split into two orders and allows you to copy related models
|
||||
to the new order. You will be passed the old order as ``original`` and the new order as ``split_order``.
|
||||
"""
|
||||
|
||||
invoice_line_text = EventPluginSignal()
|
||||
invoice_line_text = EventPluginSignal(
|
||||
providing_args=["position"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``position``
|
||||
|
||||
This signal is sent out when an invoice is built for an order. You can return additional text that
|
||||
should be shown on the invoice for the given ``position``.
|
||||
"""
|
||||
|
||||
order_import_columns = EventPluginSignal()
|
||||
order_import_columns = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out if the user performs an import of orders from an external source. You can use this
|
||||
to define additional columns that can be read during import. You are expected to return a list of instances of
|
||||
@@ -684,10 +709,10 @@ to define additional columns that can be read during import. You are expected to
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
validate_event_settings = EventPluginSignal()
|
||||
validate_event_settings = EventPluginSignal(
|
||||
providing_args=["settings_dict"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``settings_dict``
|
||||
|
||||
This signal is sent out if the user performs an update of event settings through the API or web interface.
|
||||
You are passed a ``settings_dict`` dictionary with the new state of the event settings object and are expected
|
||||
to raise a ``django.core.exceptions.ValidationError`` if the new state is not valid.
|
||||
@@ -698,7 +723,9 @@ serializer field instead.
|
||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
api_event_settings_fields = EventPluginSignal()
|
||||
api_event_settings_fields = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to collect serializable settings fields for the API. You are expected to
|
||||
return a dictionary mapping names of attributes in the settings store to DRF serializer field instances.
|
||||
|
||||
@@ -136,31 +136,6 @@
|
||||
text-decoration: none;
|
||||
color: {{ color }};
|
||||
}
|
||||
|
||||
.order-button {
|
||||
padding-top: 5px
|
||||
}
|
||||
.order-button a.button {
|
||||
font-size: 12px;
|
||||
}
|
||||
.order-info {
|
||||
padding-bottom: 5px
|
||||
}
|
||||
|
||||
.order {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.cart-table > tr > td:first-child {
|
||||
width: 40px;
|
||||
}
|
||||
.order-details > tr > td:first-child {
|
||||
width: 20%;
|
||||
}
|
||||
.order-details td {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
{% if rtl %}
|
||||
body {
|
||||
direction: rtl;
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
{% load eventurl %}
|
||||
{% load i18n %}
|
||||
|
||||
{% if position %}
|
||||
<div class="order-info">
|
||||
{% trans "You are receiving this email because someone signed you up for the following event:" %}
|
||||
</div>
|
||||
<table class="order-details">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Event:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ event.name }}
|
||||
<br>
|
||||
{% if event.has_subevents and ev.name|upper != event.name|upper %}{{ ev.name }}<br>{% endif %}
|
||||
{{ ev.get_date_range_display }}
|
||||
{% if event.settings.show_times %}
|
||||
{{ ev.date_from|date:"TIME_FORMAT" }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Order code:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ order.code }} ({{ order.datetime|date:"SHORT_DATE_FORMAT" }})<br>
|
||||
{% if order.email %}
|
||||
{% trans "created by" %} {{ order.email }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Organizer:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ event.organizer }}
|
||||
{% if event.settings.contact_mail %}
|
||||
<br>
|
||||
<a href="mailto:{{ event.settings.contact_mail }}">
|
||||
{{ event.settings.contact_mail }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="order-button">
|
||||
<a href="{% abseventurl event "presale:event.order.position" order=order.code secret=position.web_secret position=position.positionid %}" class="button">
|
||||
{% trans "View registration details" %}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="order-info">
|
||||
{% trans "You are receiving this email because you placed an order for the following event:" %}
|
||||
</div>
|
||||
<table class="order-details">
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Event:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ event.name }}
|
||||
{% if not event.has_subevents and event.settings.show_dates_on_frontpage %}
|
||||
<br>
|
||||
{{ event.get_date_range_display }}
|
||||
{% if event.settings.show_times %}
|
||||
{{ event.date_from|date:"TIME_FORMAT" }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Order code:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ order.code }} ({{ order.datetime|date:"SHORT_DATE_FORMAT" }})
|
||||
</td>
|
||||
</tr>
|
||||
{% if cart %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Details:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
<table class="cart-table">
|
||||
{% for groupkey, positions in cart %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if not groupkey.4 %} {# is addon #}
|
||||
{{ positions|length }}x
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if groupkey.4 %} {# is addon #}
|
||||
+
|
||||
{% endif %}
|
||||
{{ groupkey.0.name }}{% if groupkey.1 %} – {{ groupkey.1.value }}{% endif %}
|
||||
{% if groupkey.2 %} {# subevent #}
|
||||
<br>
|
||||
{% if groupkey.2.name|upper != event.name|upper %}
|
||||
{{ groupkey.2.name }} ·
|
||||
{% endif %}
|
||||
{{ groupkey.2.get_date_range_display }}
|
||||
{% if event.settings.show_times %}
|
||||
{{ groupkey.2.date_from|date:"TIME_FORMAT" }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if groupkey.3 %} {# attendee name #}
|
||||
<br>
|
||||
{{ groupkey.3.name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{% trans "Organizer:" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ event.organizer }}
|
||||
{% if event.settings.contact_mail %}
|
||||
<br>
|
||||
<a href="mailto:{{ event.settings.contact_mail }}">
|
||||
{{ event.settings.contact_mail }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="order-button">
|
||||
<a href="{% abseventurl event "presale:event.order.open" hash=order.email_confirm_hash order=order.code secret=order.secret %}" class="button">
|
||||
{% trans "View order details" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -23,7 +23,23 @@
|
||||
<table cellpadding="20"><tr><td>
|
||||
<![endif]-->
|
||||
<div class="content">
|
||||
{% include "pretixbase/email/order_details.html" %}
|
||||
{% if position %}
|
||||
{% trans "You are receiving this email because someone signed you up for the following event:" %}<br>
|
||||
<strong>{% trans "Event:" %}</strong> {{ event.name }}<br>
|
||||
<strong>{% trans "Order code:" %}</strong> {{ order.code }}<br>
|
||||
<strong>{% trans "Order date:" %}</strong> {{ order.datetime|date:"SHORT_DATE_FORMAT" }}<br>
|
||||
<a href="{% abseventurl event "presale:event.order.position" order=order.code secret=position.web_secret position=position.positionid %}">
|
||||
{% trans "View registration details" %}
|
||||
</a>
|
||||
{% else %}
|
||||
{% trans "You are receiving this email because you placed an order for the following event:" %}<br>
|
||||
<strong>{% trans "Event:" %}</strong> {{ event.name }}<br>
|
||||
<strong>{% trans "Order code:" %}</strong> {{ order.code }}<br>
|
||||
<strong>{% trans "Order date:" %}</strong> {{ order.datetime|date:"SHORT_DATE_FORMAT" }}<br>
|
||||
<a href="{% abseventurl event "presale:event.order.open" hash=order.email_confirm_hash order=order.code secret=order.secret %}">
|
||||
{% trans "View order details" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!--[if gte mso 9]>
|
||||
</td></tr></table>
|
||||
|
||||
@@ -147,31 +147,6 @@
|
||||
text-decoration: none;
|
||||
color: {{ color }};
|
||||
}
|
||||
|
||||
.order-button {
|
||||
padding-top: 5px
|
||||
}
|
||||
.order-button a.button {
|
||||
font-size: 12px;
|
||||
}
|
||||
.order-info {
|
||||
padding-bottom: 5px
|
||||
}
|
||||
|
||||
.order {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.cart-table > tr > td:first-child {
|
||||
width: 40px;
|
||||
}
|
||||
.order-details > tr > td:first-child {
|
||||
width: 20%;
|
||||
}
|
||||
.order-details td {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
{% if rtl %}
|
||||
body {
|
||||
direction: rtl;
|
||||
@@ -251,7 +226,23 @@
|
||||
<table cellpadding="20"><tr><td>
|
||||
<![endif]-->
|
||||
<div class="content">
|
||||
{% include "pretixbase/email/order_details.html" %}
|
||||
{% if position %}
|
||||
{% trans "You are receiving this email because someone signed you up for the following event:" %}<br>
|
||||
<strong>{% trans "Event:" %}</strong> {{ event.name }}<br>
|
||||
<strong>{% trans "Order code:" %}</strong> {{ order.code }}<br>
|
||||
<strong>{% trans "Order date:" %}</strong> {{ order.datetime|date:"SHORT_DATE_FORMAT" }}<br>
|
||||
<a href="{% abseventurl event "presale:event.order.position" order=order.code secret=position.web_secret position=position.positionid %}">
|
||||
{% trans "View registration details" %}
|
||||
</a>
|
||||
{% else %}
|
||||
{% trans "You are receiving this email because you placed an order for the following event:" %}<br>
|
||||
<strong>{% trans "Event:" %}</strong> {{ event.name }}<br>
|
||||
<strong>{% trans "Order code:" %}</strong> {{ order.code }}<br>
|
||||
<strong>{% trans "Order date:" %}</strong> {{ order.datetime|date:"SHORT_DATE_FORMAT" }}<br>
|
||||
<a href="{% abseventurl event "presale:event.order.open" hash=order.email_confirm_hash order=order.code secret=order.secret %}">
|
||||
{% trans "View order details" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<!--[if gte mso 9]>
|
||||
</td></tr></table>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load thumb %}
|
||||
{% if widget.is_initial %}{{ widget.initial_text }}: <a href="{{ widget.value.url }}">{{ widget.value }}</a>{% if not widget.required %}
|
||||
<input type="checkbox" name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}">
|
||||
<label for="{{ widget.checkbox_id }}">{{ widget.clear_checkbox_label }}</label>{% endif %}{% if widget.value.is_img %}<br><a href="{{ widget.value.url }}" data-lightbox="{{ widget.name }}"><img src="{{ widget.value|thumb:"200x100" }}" /></a>{% endif %}<br>
|
||||
<label for="{{ widget.checkbox_id }}">{{ widget.clear_checkbox_label }}</label>{% endif %}{% if widget.value.is_img %}<br><a href="{{ widget.value.url }}" data-lightbox="{{ widget.value.name }}"><img src="{{ widget.value|thumb:"200x100" }}" /></a>{% endif %}<br>
|
||||
{{ widget.input_text }}:{% endif %}
|
||||
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
|
||||
{% if widget.cachedfile %}<input type="hidden" name="{{ widget.hidden_name }}" value="{{ widget.cachedfile.id }}">{% endif %}
|
||||
|
||||
@@ -153,9 +153,9 @@ def markdown_compile_email(source):
|
||||
|
||||
class SnippetExtension(markdown.extensions.Extension):
|
||||
def extendMarkdown(self, md, *args, **kwargs):
|
||||
md.parser.blockprocessors.deregister('olist')
|
||||
md.parser.blockprocessors.deregister('ulist')
|
||||
md.parser.blockprocessors.deregister('quote')
|
||||
del md.parser.blockprocessors['olist']
|
||||
del md.parser.blockprocessors['ulist']
|
||||
del md.parser.blockprocessors['quote']
|
||||
|
||||
|
||||
def markdown_compile(source, snippet=False):
|
||||
|
||||
@@ -7,7 +7,6 @@ from django.core.exceptions import ValidationError
|
||||
from django.core.files import File
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from django.forms.utils import from_current_timezone
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@@ -123,7 +122,7 @@ class CachedFileInput(forms.ClearableFileInput):
|
||||
|
||||
@property
|
||||
def url(self):
|
||||
return reverse('cachedfile.download', kwargs={'id': self.file.id})
|
||||
return self.file.file.url
|
||||
|
||||
def value_from_datadict(self, data, files, name):
|
||||
from ...base.models import CachedFile
|
||||
@@ -201,8 +200,6 @@ class CachedFileField(ExtFileField):
|
||||
from ...base.models import CachedFile
|
||||
|
||||
if isinstance(data, File):
|
||||
if hasattr(data, '_uploaded_to'):
|
||||
return data._uploaded_to
|
||||
cf = CachedFile.objects.create(
|
||||
expires=now() + datetime.timedelta(days=1),
|
||||
date=now(),
|
||||
@@ -212,7 +209,6 @@ class CachedFileField(ExtFileField):
|
||||
)
|
||||
cf.file.save(data.name, data.file)
|
||||
cf.save()
|
||||
data._uploaded_to = cf
|
||||
return cf
|
||||
return super().bound_data(data, initial)
|
||||
|
||||
@@ -221,8 +217,6 @@ class CachedFileField(ExtFileField):
|
||||
|
||||
data = super().clean(*args, **kwargs)
|
||||
if isinstance(data, File):
|
||||
if hasattr(data, '_uploaded_to'):
|
||||
return data._uploaded_to
|
||||
cf = CachedFile.objects.create(
|
||||
expires=now() + datetime.timedelta(days=1),
|
||||
web_download=True,
|
||||
@@ -232,7 +226,6 @@ class CachedFileField(ExtFileField):
|
||||
)
|
||||
cf.file.save(data.name, data.file)
|
||||
cf.save()
|
||||
data._uploaded_to = cf
|
||||
return cf
|
||||
return data
|
||||
|
||||
|
||||
@@ -449,11 +449,6 @@ class EventSettingsForm(SettingsForm):
|
||||
'waiting_list_enabled',
|
||||
'waiting_list_hours',
|
||||
'waiting_list_auto',
|
||||
'waiting_list_names_asked',
|
||||
'waiting_list_names_required',
|
||||
'waiting_list_phones_asked',
|
||||
'waiting_list_phones_required',
|
||||
'waiting_list_phones_explanation_text',
|
||||
'max_items_per_order',
|
||||
'reservation_time',
|
||||
'contact_mail',
|
||||
@@ -464,7 +459,6 @@ class EventSettingsForm(SettingsForm):
|
||||
'frontpage_subevent_ordering',
|
||||
'event_list_type',
|
||||
'frontpage_text',
|
||||
'event_info_text',
|
||||
'attendee_names_asked',
|
||||
'attendee_names_required',
|
||||
'attendee_emails_asked',
|
||||
|
||||
@@ -5,9 +5,7 @@ from urllib.parse import urlencode
|
||||
from django import forms
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.db.models import (
|
||||
Count, Exists, F, Max, Model, OuterRef, Q, QuerySet,
|
||||
)
|
||||
from django.db.models import Exists, F, Max, Model, OuterRef, Q, QuerySet
|
||||
from django.db.models.functions import Coalesce, ExtractWeekDay
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.utils.formats import date_format, localize
|
||||
@@ -155,7 +153,6 @@ class OrderFilterForm(FilterForm):
|
||||
(Order.STATUS_CANCELED, _('Canceled (fully)')),
|
||||
('cp', _('Canceled (fully or with paid fee)')),
|
||||
('rc', _('Cancellation requested')),
|
||||
('cni', _('Fully canceled but invoice not canceled')),
|
||||
)),
|
||||
(_('Payment process'), (
|
||||
(Order.STATUS_EXPIRED, _('Expired')),
|
||||
@@ -267,18 +264,6 @@ class OrderFilterForm(FilterForm):
|
||||
status=Order.STATUS_PAID,
|
||||
pending_sum_t__gt=0
|
||||
)
|
||||
elif s == 'cni':
|
||||
i = Invoice.objects.filter(
|
||||
order=OuterRef('pk'),
|
||||
is_cancellation=False,
|
||||
refered__isnull=True,
|
||||
).order_by().values('order').annotate(k=Count('id')).values('k')
|
||||
qs = qs.annotate(
|
||||
icnt=i
|
||||
).filter(
|
||||
icnt__gt=0,
|
||||
status=Order.STATUS_CANCELED,
|
||||
)
|
||||
elif s == 'pa':
|
||||
qs = qs.filter(
|
||||
status=Order.STATUS_PENDING,
|
||||
|
||||
@@ -117,11 +117,6 @@ class CancelForm(ConfirmPaymentForm):
|
||||
'in your cancellation fee if you want to keep them. Please always enter a gross value, '
|
||||
'tax will be calculated automatically.'),
|
||||
)
|
||||
cancel_invoice = forms.BooleanField(
|
||||
label=_('Generate cancellation for invoice'),
|
||||
initial=True,
|
||||
required=False
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -135,8 +130,6 @@ class CancelForm(ConfirmPaymentForm):
|
||||
self.fields['cancellation_fee'].max_value = prs
|
||||
else:
|
||||
del self.fields['cancellation_fee']
|
||||
if not self.instance.invoices.exists():
|
||||
del self.fields['cancel_invoice']
|
||||
|
||||
def clean_cancellation_fee(self):
|
||||
val = self.cleaned_data['cancellation_fee'] or Decimal('0.00')
|
||||
|
||||
@@ -2,7 +2,9 @@ from django.dispatch import Signal
|
||||
|
||||
from pretix.base.signals import DeprecatedSignal, EventPluginSignal
|
||||
|
||||
html_page_start = Signal()
|
||||
html_page_start = Signal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal allows you to put code in the beginning of the main page for every
|
||||
page in the backend. You are expected to return HTML.
|
||||
@@ -10,10 +12,10 @@ page in the backend. You are expected to return HTML.
|
||||
The ``sender`` keyword argument will contain the request.
|
||||
"""
|
||||
|
||||
html_head = EventPluginSignal()
|
||||
html_head = EventPluginSignal(
|
||||
providing_args=["request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``request``
|
||||
|
||||
This signal allows you to put code inside the HTML ``<head>`` tag
|
||||
of every page in the backend. You will get the request as the keyword argument
|
||||
``request`` and are expected to return plain HTML.
|
||||
@@ -21,10 +23,10 @@ of every page in the backend. You will get the request as the keyword argument
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
nav_event = EventPluginSignal()
|
||||
nav_event = EventPluginSignal(
|
||||
providing_args=["request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``request``
|
||||
|
||||
This signal allows you to add additional views to the admin panel
|
||||
navigation. You will get the request as a keyword argument ``request``.
|
||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||
@@ -46,10 +48,10 @@ in pretix.
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
nav_topbar = Signal()
|
||||
nav_topbar = Signal(
|
||||
providing_args=["request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``request``
|
||||
|
||||
This signal allows you to add additional views to the top navigation bar.
|
||||
You will get the request as a keyword argument ``request``.
|
||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||
@@ -65,10 +67,10 @@ This is no ``EventPluginSignal``, so you do not get the event in the ``sender``
|
||||
and you may get the signal regardless of whether your plugin is active.
|
||||
"""
|
||||
|
||||
nav_global = Signal()
|
||||
nav_global = Signal(
|
||||
providing_args=["request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``request``
|
||||
|
||||
This signal allows you to add additional views to the navigation bar when no event is
|
||||
selected. You will get the request as a keyword argument ``request``.
|
||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||
@@ -90,10 +92,10 @@ This is no ``EventPluginSignal``, so you do not get the event in the ``sender``
|
||||
and you may get the signal regardless of whether your plugin is active.
|
||||
"""
|
||||
|
||||
event_dashboard_top = EventPluginSignal()
|
||||
event_dashboard_top = EventPluginSignal(
|
||||
providing_args=['request']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request'
|
||||
|
||||
This signal is sent out to include custom HTML in the top part of the the event dashboard.
|
||||
Receivers should return HTML.
|
||||
|
||||
@@ -101,7 +103,9 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
||||
An additional keyword argument ``subevent`` *can* contain a sub-event.
|
||||
"""
|
||||
|
||||
event_dashboard_widgets = EventPluginSignal()
|
||||
event_dashboard_widgets = EventPluginSignal(
|
||||
providing_args=[]
|
||||
)
|
||||
"""
|
||||
This signal is sent out to include widgets in the event dashboard. Receivers
|
||||
should return a list of dictionaries, where each dictionary can have the keys:
|
||||
@@ -116,10 +120,10 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
||||
An additional keyword argument ``subevent`` *can* contain a sub-event.
|
||||
"""
|
||||
|
||||
user_dashboard_widgets = Signal()
|
||||
user_dashboard_widgets = Signal(
|
||||
providing_args=['user']
|
||||
)
|
||||
"""
|
||||
Arguments: 'user'
|
||||
|
||||
This signal is sent out to include widgets in the personal user dashboard. Receivers
|
||||
should return a list of dictionaries, where each dictionary can have the keys:
|
||||
|
||||
@@ -132,20 +136,20 @@ should return a list of dictionaries, where each dictionary can have the keys:
|
||||
This is a regular django signal (no pretix event signal).
|
||||
"""
|
||||
|
||||
voucher_form_html = EventPluginSignal()
|
||||
voucher_form_html = EventPluginSignal(
|
||||
providing_args=['form']
|
||||
)
|
||||
"""
|
||||
Arguments: 'form'
|
||||
|
||||
This signal allows you to add additional HTML to the form that is used for modifying vouchers.
|
||||
You receive the form object in the ``form`` keyword argument.
|
||||
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
voucher_form_class = EventPluginSignal()
|
||||
voucher_form_class = EventPluginSignal(
|
||||
providing_args=['cls']
|
||||
)
|
||||
"""
|
||||
Arguments: 'cls'
|
||||
|
||||
This signal allows you to replace the form class that is used for modifying vouchers.
|
||||
You will receive the default form class (or the class set by a previous plugin) in the
|
||||
``cls`` argument so that you can inherit from it.
|
||||
@@ -153,10 +157,10 @@ You will receive the default form class (or the class set by a previous plugin)
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
voucher_form_validation = EventPluginSignal()
|
||||
voucher_form_validation = EventPluginSignal(
|
||||
providing_args=['form']
|
||||
)
|
||||
"""
|
||||
Arguments: 'form'
|
||||
|
||||
This signal allows you to add additional validation to the form that is used for
|
||||
creating and modifying vouchers. You will receive the form instance in the ``form``
|
||||
argument and the current data state in the ``data`` argument.
|
||||
@@ -164,28 +168,28 @@ argument and the current data state in the ``data`` argument.
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
quota_detail_html = EventPluginSignal()
|
||||
quota_detail_html = EventPluginSignal(
|
||||
providing_args=['quota']
|
||||
)
|
||||
"""
|
||||
Arguments: 'quota'
|
||||
|
||||
This signal allows you to append HTML to a Quota's detail view. You receive the
|
||||
quota as argument in the ``quota`` keyword argument.
|
||||
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
organizer_edit_tabs = DeprecatedSignal()
|
||||
organizer_edit_tabs = DeprecatedSignal(
|
||||
providing_args=['organizer', 'request']
|
||||
)
|
||||
"""
|
||||
Arguments: 'organizer', 'request'
|
||||
|
||||
Deprecated signal, no longer works. We just keep the definition so old plugins don't
|
||||
break the installation.
|
||||
"""
|
||||
|
||||
nav_organizer = Signal()
|
||||
nav_organizer = Signal(
|
||||
providing_args=['organizer', 'request']
|
||||
)
|
||||
"""
|
||||
Arguments: 'organizer', 'request'
|
||||
|
||||
This signal is sent out to include tab links on the detail page of an organizer.
|
||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||
should contain at least the keys ``label`` and ``url``. You should also return
|
||||
@@ -206,30 +210,30 @@ This is a regular django signal (no pretix event signal). Receivers will be pass
|
||||
the keyword arguments ``organizer`` and ``request``.
|
||||
"""
|
||||
|
||||
order_info = EventPluginSignal()
|
||||
order_info = EventPluginSignal(
|
||||
providing_args=["order", "request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``, ``request``
|
||||
|
||||
This signal is sent out to display additional information on the order detail page
|
||||
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
Additionally, the argument ``order`` and ``request`` are available.
|
||||
"""
|
||||
|
||||
order_position_buttons = EventPluginSignal()
|
||||
order_position_buttons = EventPluginSignal(
|
||||
providing_args=["order", "position", "request"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``order``, ``position``, ``request``
|
||||
|
||||
This signal is sent out to display additional buttons for a single position of an order.
|
||||
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
Additionally, the argument ``order`` and ``request`` are available.
|
||||
"""
|
||||
|
||||
nav_event_settings = EventPluginSignal()
|
||||
nav_event_settings = EventPluginSignal(
|
||||
providing_args=['request']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request'
|
||||
|
||||
This signal is sent out to include tab links on the settings page of an event.
|
||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||
should contain at least the keys ``label`` and ``url``. You should also return
|
||||
@@ -244,10 +248,10 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
||||
A second keyword argument ``request`` will contain the request object.
|
||||
"""
|
||||
|
||||
event_settings_widget = EventPluginSignal()
|
||||
event_settings_widget = EventPluginSignal(
|
||||
providing_args=['request']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request'
|
||||
|
||||
This signal is sent out to include template snippets on the settings page of an event
|
||||
that allows generating a pretix Widget code.
|
||||
|
||||
@@ -255,10 +259,10 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
||||
A second keyword argument ``request`` will contain the request object.
|
||||
"""
|
||||
|
||||
item_forms = EventPluginSignal()
|
||||
item_forms = EventPluginSignal(
|
||||
providing_args=['request', 'item']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request', 'item'
|
||||
|
||||
This signal allows you to return additional forms that should be rendered on the product
|
||||
modification page. You are passed ``request`` and ``item`` arguments and are expected to return
|
||||
an instance of a form class that you bind yourself when appropriate. Your form will be executed
|
||||
@@ -268,10 +272,10 @@ styles. It is advisable to set a prefix for your form to avoid clashes with othe
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
item_formsets = EventPluginSignal()
|
||||
item_formsets = EventPluginSignal(
|
||||
providing_args=['request', 'item']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request', 'item'
|
||||
|
||||
This signal allows you to return additional formsets that should be rendered on the product
|
||||
modification page. You are passed ``request`` and ``item`` arguments and are expected to return
|
||||
an instance of a formset class that you bind yourself when appropriate. Your formset will be
|
||||
@@ -286,10 +290,10 @@ will be passed a ``formset`` variable with your formset.
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
subevent_forms = EventPluginSignal()
|
||||
subevent_forms = EventPluginSignal(
|
||||
providing_args=['request', 'subevent', 'copy_from']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request', 'subevent', 'copy_from'
|
||||
|
||||
This signal allows you to return additional forms that should be rendered on the subevent creation
|
||||
or modification page. You are passed ``request`` and ``subevent`` arguments and are expected to return
|
||||
an instance of a form class that you bind yourself when appropriate. Your form will be executed
|
||||
@@ -303,17 +307,17 @@ creation, ``copy_from`` can be a subevent that is being copied from.
|
||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||
"""
|
||||
|
||||
oauth_application_registered = Signal()
|
||||
oauth_application_registered = Signal(
|
||||
providing_args=["user", "application"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``user``, ``application``
|
||||
|
||||
This signal will be called whenever a user registers a new OAuth application.
|
||||
"""
|
||||
|
||||
order_search_filter_q = Signal()
|
||||
order_search_filter_q = Signal(
|
||||
providing_args=["query"]
|
||||
)
|
||||
"""
|
||||
Arguments: ``query``
|
||||
|
||||
This signal will be called whenever a free-text order search is performed. You are expected to return one
|
||||
Q object that will be OR-ed with existing search queries. As order search exists on a global level as well,
|
||||
this is not an Event signal and will be called even if your plugin is not active. ``sender`` will contain the
|
||||
@@ -321,10 +325,10 @@ event if the search is performed within an event, and ``None`` otherwise. The se
|
||||
``query``.
|
||||
"""
|
||||
|
||||
order_search_forms = EventPluginSignal()
|
||||
order_search_forms = EventPluginSignal(
|
||||
providing_args=['request']
|
||||
)
|
||||
"""
|
||||
Arguments: 'request'
|
||||
|
||||
This signal allows you to return additional forms that should be rendered in the advanced order search.
|
||||
You are passed ``request`` argument and are expected to return an instance of a form class that you bind
|
||||
yourself when appropriate. Your form will be executed as part of the standard validation and rendering
|
||||
|
||||
@@ -193,7 +193,6 @@
|
||||
{% bootstrap_field sform.checkout_phone_helptext layout="control" %}
|
||||
{% bootstrap_field sform.banner_text layout="control" %}
|
||||
{% bootstrap_field sform.banner_text_bottom layout="control" %}
|
||||
{% bootstrap_field sform.event_info_text layout="control" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "Shop design" %}</legend>
|
||||
@@ -249,9 +248,6 @@
|
||||
{% bootstrap_field sform.waiting_list_enabled layout="control" %}
|
||||
{% bootstrap_field sform.waiting_list_auto layout="control" %}
|
||||
{% bootstrap_field sform.waiting_list_hours layout="control" %}
|
||||
{% bootstrap_field sform.waiting_list_names_asked_required layout="control" %}
|
||||
{% bootstrap_field sform.waiting_list_phones_asked_required layout="control" %}
|
||||
{% bootstrap_field sform.waiting_list_phones_explanation_text layout="control" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "Item metadata" %}</legend>
|
||||
|
||||
@@ -23,16 +23,13 @@
|
||||
<input type="hidden" name="status" value="c"/>
|
||||
{% bootstrap_form_errors form %}
|
||||
{% bootstrap_field form.send_email layout='' %}
|
||||
{% if form.cancel_invoice %}
|
||||
{% bootstrap_field form.cancel_invoice layout='' %}
|
||||
{% endif %}
|
||||
{% if form.cancellation_fee %}
|
||||
{% bootstrap_field form.cancellation_fee layout='' %}
|
||||
{% endif %}
|
||||
<div class="row checkout-button-row">
|
||||
<div class="col-md-4">
|
||||
<a class="btn btn-block btn-default btn-lg"
|
||||
href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}">
|
||||
href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}">
|
||||
{% trans "No, take me back" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -170,10 +170,6 @@
|
||||
</span>
|
||||
{% endif %}
|
||||
{{ o.total|money:request.event.currency }}
|
||||
{% if o.status == "c" and o.icnt %}
|
||||
<br>
|
||||
<span class="label label-warning">{% trans "INVOICE NOT CANCELED" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right flip">{{ o.pcnt|default_if_none:"0" }}</td>
|
||||
<td class="text-right flip">{% include "pretixcontrol/orders/fragment_order_status.html" with order=o %}</td>
|
||||
|
||||
@@ -132,13 +132,7 @@
|
||||
<table class="table table-condensed table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
{% if request.event.settings.waiting_list_names_asked %}
|
||||
<th>{% trans "Name" %}</th>
|
||||
{% endif %}
|
||||
<th>{% trans "Email" %}</th>
|
||||
{% if request.event.settings.waiting_list_phones_asked %}
|
||||
<th>{% trans "Phone number" %}</th>
|
||||
{% endif %}
|
||||
<th>{% trans "User" %}</th>
|
||||
<th>{% trans "Product" %}</th>
|
||||
{% if request.event.has_subevents %}
|
||||
<th>{% trans "Date" context "subevent" %}</th>
|
||||
@@ -152,13 +146,7 @@
|
||||
<tbody>
|
||||
{% for e in entries %}
|
||||
<tr>
|
||||
{% if request.event.settings.waiting_list_names_asked %}
|
||||
<td>{{ e.name|default:"" }}</td>
|
||||
{% endif %}
|
||||
<td>{{ e.email }}</td>
|
||||
{% if request.event.settings.waiting_list_phones_asked %}
|
||||
<td>{{ e.phone|default:"" }}</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
{{ e.item }}
|
||||
{% if e.variation %}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from django.conf.urls import include, re_path
|
||||
from django.conf.urls import include, url
|
||||
from django.views.generic.base import RedirectView
|
||||
|
||||
from pretix.control.views import (
|
||||
@@ -8,327 +8,310 @@ from pretix.control.views import (
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'^logout$', auth.logout, name='auth.logout'),
|
||||
re_path(r'^login$', auth.login, name='auth.login'),
|
||||
re_path(r'^login/2fa$', auth.Login2FAView.as_view(), name='auth.login.2fa'),
|
||||
re_path(r'^register$', auth.register, name='auth.register'),
|
||||
re_path(r'^invite/(?P<token>[a-zA-Z0-9]+)$', auth.invite, name='auth.invite'),
|
||||
re_path(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
|
||||
re_path(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
|
||||
re_path(r'^$', dashboards.user_index, name='index'),
|
||||
re_path(r'^widgets.json$', dashboards.user_index_widgets_lazy, name='index.widgets'),
|
||||
re_path(r'^global/settings/$', global_settings.GlobalSettingsView.as_view(), name='global.settings'),
|
||||
re_path(r'^global/update/$', global_settings.UpdateCheckView.as_view(), name='global.update'),
|
||||
re_path(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'),
|
||||
re_path(r'^logdetail/$', global_settings.LogDetailView.as_view(), name='global.logdetail'),
|
||||
re_path(r'^logdetail/payment/$', global_settings.PaymentDetailView.as_view(), name='global.paymentdetail'),
|
||||
re_path(r'^logdetail/refund/$', global_settings.RefundDetailView.as_view(), name='global.refunddetail'),
|
||||
re_path(r'^geocode/$', geo.GeoCodeView.as_view(), name='global.geocode'),
|
||||
re_path(r'^reauth/$', user.ReauthView.as_view(), name='user.reauth'),
|
||||
re_path(r'^sudo/$', user.StartStaffSession.as_view(), name='user.sudo'),
|
||||
re_path(r'^sudo/stop/$', user.StopStaffSession.as_view(), name='user.sudo.stop'),
|
||||
re_path(r'^sudo/(?P<id>\d+)/$', user.EditStaffSession.as_view(), name='user.sudo.edit'),
|
||||
re_path(r'^sudo/sessions/$', user.StaffSessionList.as_view(), name='user.sudo.list'),
|
||||
re_path(r'^users/$', users.UserListView.as_view(), name='users'),
|
||||
re_path(r'^users/select2$', typeahead.users_select2, name='users.select2'),
|
||||
re_path(r'^users/add$', users.UserCreateView.as_view(), name='users.add'),
|
||||
re_path(r'^users/impersonate/stop', users.UserImpersonateStopView.as_view(), name='users.impersonate.stop'),
|
||||
re_path(r'^users/(?P<id>\d+)/$', users.UserEditView.as_view(), name='users.edit'),
|
||||
re_path(r'^users/(?P<id>\d+)/reset$', users.UserResetView.as_view(), name='users.reset'),
|
||||
re_path(r'^users/(?P<id>\d+)/impersonate', users.UserImpersonateView.as_view(), name='users.impersonate'),
|
||||
re_path(r'^users/(?P<id>\d+)/anonymize', users.UserAnonymizeView.as_view(), name='users.anonymize'),
|
||||
re_path(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
||||
re_path(r'^settings/?$', user.UserSettings.as_view(), name='user.settings'),
|
||||
re_path(r'^settings/history/$', user.UserHistoryView.as_view(), name='user.settings.history'),
|
||||
re_path(r'^settings/notifications/$', user.UserNotificationsEditView.as_view(), name='user.settings.notifications'),
|
||||
re_path(r'^settings/notifications/off/(?P<id>\d+)/(?P<token>[^/]+)/$', user.UserNotificationsDisableView.as_view(),
|
||||
name='user.settings.notifications.off'),
|
||||
re_path(r'^settings/oauth/authorized/$', oauth.AuthorizationListView.as_view(),
|
||||
name='user.settings.oauth.list'),
|
||||
re_path(r'^settings/oauth/authorized/(?P<pk>\d+)/revoke$', oauth.AuthorizationRevokeView.as_view(),
|
||||
name='user.settings.oauth.revoke'),
|
||||
re_path(r'^settings/oauth/apps/$', oauth.OAuthApplicationListView.as_view(),
|
||||
name='user.settings.oauth.apps'),
|
||||
re_path(r'^settings/oauth/apps/add$', oauth.OAuthApplicationRegistrationView.as_view(),
|
||||
name='user.settings.oauth.apps.register'),
|
||||
re_path(r'^settings/oauth/apps/(?P<pk>\d+)/$', oauth.OAuthApplicationUpdateView.as_view(),
|
||||
name='user.settings.oauth.app'),
|
||||
re_path(r'^settings/oauth/apps/(?P<pk>\d+)/disable$', oauth.OAuthApplicationDeleteView.as_view(),
|
||||
name='user.settings.oauth.app.disable'),
|
||||
re_path(r'^settings/oauth/apps/(?P<pk>\d+)/roll$', oauth.OAuthApplicationRollView.as_view(),
|
||||
name='user.settings.oauth.app.roll'),
|
||||
re_path(r'^settings/2fa/$', user.User2FAMainView.as_view(), name='user.settings.2fa'),
|
||||
re_path(r'^settings/2fa/add$', user.User2FADeviceAddView.as_view(), name='user.settings.2fa.add'),
|
||||
re_path(r'^settings/2fa/enable', user.User2FAEnableView.as_view(), name='user.settings.2fa.enable'),
|
||||
re_path(r'^settings/2fa/disable', user.User2FADisableView.as_view(), name='user.settings.2fa.disable'),
|
||||
re_path(r'^settings/2fa/regenemergency', user.User2FARegenerateEmergencyView.as_view(),
|
||||
name='user.settings.2fa.regenemergency'),
|
||||
re_path(r'^settings/2fa/totp/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmTOTPView.as_view(),
|
||||
name='user.settings.2fa.confirm.totp'),
|
||||
re_path(r'^settings/2fa/webauthn/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmWebAuthnView.as_view(),
|
||||
name='user.settings.2fa.confirm.webauthn'),
|
||||
re_path(r'^settings/2fa/(?P<devicetype>[^/]+)/(?P<device>[0-9]+)/delete', user.User2FADeviceDeleteView.as_view(),
|
||||
name='user.settings.2fa.delete'),
|
||||
re_path(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'),
|
||||
re_path(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'),
|
||||
re_path(r'^organizers/select2$', typeahead.organizer_select2, name='organizers.select2'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/$', organizer.OrganizerDetail.as_view(), name='organizer'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/edit$', organizer.OrganizerUpdate.as_view(), name='organizer.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/delete$', organizer.OrganizerDelete.as_view(), name='organizer.delete'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/settings/display$', organizer.OrganizerDisplaySettings.as_view(),
|
||||
name='organizer.display'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/properties$', organizer.EventMetaPropertyListView.as_view(),
|
||||
name='organizer.properties'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/property/add$', organizer.EventMetaPropertyCreateView.as_view(),
|
||||
name='organizer.property.add'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/edit$',
|
||||
organizer.EventMetaPropertyUpdateView.as_view(),
|
||||
name='organizer.property.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/delete$',
|
||||
organizer.EventMetaPropertyDeleteView.as_view(),
|
||||
name='organizer.property.delete'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcards$', organizer.GiftCardListView.as_view(),
|
||||
name='organizer.giftcards'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcard/add$', organizer.GiftCardCreateView.as_view(),
|
||||
name='organizer.giftcard.add'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/$', organizer.GiftCardDetailView.as_view(),
|
||||
name='organizer.giftcard'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/edit$',
|
||||
organizer.GiftCardUpdateView.as_view(),
|
||||
name='organizer.giftcard.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/webhooks$', organizer.WebHookListView.as_view(),
|
||||
name='organizer.webhooks'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/webhook/add$', organizer.WebHookCreateView.as_view(),
|
||||
name='organizer.webhook.add'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/edit$', organizer.WebHookUpdateView.as_view(),
|
||||
name='organizer.webhook.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/logs$', organizer.WebHookLogsView.as_view(),
|
||||
name='organizer.webhook.logs'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/devices$', organizer.DeviceListView.as_view(), name='organizer.devices'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/device/add$', organizer.DeviceCreateView.as_view(),
|
||||
name='organizer.device.add'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/edit$', organizer.DeviceUpdateView.as_view(),
|
||||
name='organizer.device.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/connect$', organizer.DeviceConnectView.as_view(),
|
||||
name='organizer.device.connect'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/revoke$', organizer.DeviceRevokeView.as_view(),
|
||||
name='organizer.device.revoke'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/logs$', organizer.DeviceLogView.as_view(),
|
||||
name='organizer.device.logs'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/gates$', organizer.GateListView.as_view(), name='organizer.gates'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/gate/add$', organizer.GateCreateView.as_view(),
|
||||
name='organizer.gate.add'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/edit$', organizer.GateUpdateView.as_view(),
|
||||
name='organizer.gate.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/delete$', organizer.GateDeleteView.as_view(),
|
||||
name='organizer.gate.delete'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/teams$', organizer.TeamListView.as_view(), name='organizer.teams'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/team/add$', organizer.TeamCreateView.as_view(),
|
||||
name='organizer.team.add'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/$', organizer.TeamMemberView.as_view(),
|
||||
name='organizer.team'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/edit$', organizer.TeamUpdateView.as_view(),
|
||||
name='organizer.team.edit'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/delete$', organizer.TeamDeleteView.as_view(),
|
||||
name='organizer.team.delete'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/slugrng', main.SlugRNG.as_view(), name='events.add.slugrng'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/logs', organizer.LogView.as_view(), name='organizer.log'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/export/$', organizer.ExportView.as_view(), name='organizer.export'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/export/do$', organizer.ExportDoView.as_view(),
|
||||
name='organizer.export.do'),
|
||||
re_path(r'^nav/typeahead/$', typeahead.nav_context_list, name='nav.typeahead'),
|
||||
re_path(r'^events/$', main.EventList.as_view(), name='events'),
|
||||
re_path(r'^events/add$', main.EventWizard.as_view(), name='events.add'),
|
||||
re_path(r'^events/typeahead/$', typeahead.event_list, name='events.typeahead'),
|
||||
re_path(r'^events/typeahead/meta/$', typeahead.meta_values, name='events.meta.typeahead'),
|
||||
re_path(r'^search/orders/$', search.OrderSearch.as_view(), name='search.orders'),
|
||||
re_path(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
|
||||
re_path(r'^$', dashboards.event_index, name='event.index'),
|
||||
re_path(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
|
||||
re_path(r'^live/$', event.EventLive.as_view(), name='event.live'),
|
||||
re_path(r'^logs/$', event.EventLog.as_view(), name='event.log'),
|
||||
re_path(r'^delete/$', event.EventDelete.as_view(), name='event.delete'),
|
||||
re_path(r'^requiredactions/$', event.EventActions.as_view(), name='event.requiredactions'),
|
||||
re_path(r'^requiredactions/(?P<id>\d+)/discard$', event.EventActionDiscard.as_view(),
|
||||
name='event.requiredaction.discard'),
|
||||
re_path(r'^comment/$', event.EventComment.as_view(),
|
||||
name='event.comment'),
|
||||
re_path(r'^quickstart/$', event.QuickSetupView.as_view(), name='event.quick'),
|
||||
re_path(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
||||
re_path(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
||||
re_path(r'^settings/payment/(?P<provider>[^/]+)$', event.PaymentProviderSettings.as_view(),
|
||||
name='event.settings.payment.provider'),
|
||||
re_path(r'^settings/payment$', event.PaymentSettings.as_view(), name='event.settings.payment'),
|
||||
re_path(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'),
|
||||
re_path(r'^settings/tickets/preview/(?P<output>[^/]+)$', event.TicketSettingsPreview.as_view(),
|
||||
name='event.settings.tickets.preview'),
|
||||
re_path(r'^settings/email$', event.MailSettings.as_view(), name='event.settings.mail'),
|
||||
re_path(r'^settings/email/preview$', event.MailSettingsPreview.as_view(), name='event.settings.mail.preview'),
|
||||
re_path(r'^settings/email/layoutpreview$', event.MailSettingsRendererPreview.as_view(),
|
||||
name='event.settings.mail.preview.layout'),
|
||||
re_path(r'^settings/cancel', event.CancelSettings.as_view(), name='event.settings.cancel'),
|
||||
re_path(r'^settings/invoice$', event.InvoiceSettings.as_view(), name='event.settings.invoice'),
|
||||
re_path(r'^settings/invoice/preview$', event.InvoicePreview.as_view(), name='event.settings.invoice.preview'),
|
||||
re_path(r'^settings/display', event.DisplaySettings.as_view(), name='event.settings.display'),
|
||||
re_path(r'^settings/tax/$', event.TaxList.as_view(), name='event.settings.tax'),
|
||||
re_path(r'^settings/tax/(?P<rule>\d+)/$', event.TaxUpdate.as_view(), name='event.settings.tax.edit'),
|
||||
re_path(r'^settings/tax/add$', event.TaxCreate.as_view(), name='event.settings.tax.add'),
|
||||
re_path(r'^settings/tax/(?P<rule>\d+)/delete$', event.TaxDelete.as_view(), name='event.settings.tax.delete'),
|
||||
re_path(r'^settings/widget$', event.WidgetSettings.as_view(), name='event.settings.widget'),
|
||||
re_path(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
||||
re_path(r'^pdf/editor/(?P<filename>[^/]+).pdf$', pdf.PdfView.as_view(), name='pdf.background'),
|
||||
re_path(r'^subevents/$', subevents.SubEventList.as_view(), name='event.subevents'),
|
||||
re_path(r'^subevents/select2$', typeahead.subevent_select2, name='event.subevents.select2'),
|
||||
re_path(r'^subevents/(?P<subevent>\d+)/$', subevents.SubEventUpdate.as_view(), name='event.subevent'),
|
||||
re_path(r'^subevents/(?P<subevent>\d+)/delete$', subevents.SubEventDelete.as_view(),
|
||||
name='event.subevent.delete'),
|
||||
re_path(r'^subevents/add$', subevents.SubEventCreate.as_view(), name='event.subevents.add'),
|
||||
re_path(r'^subevents/bulk_add$', subevents.SubEventBulkCreate.as_view(), name='event.subevents.bulk'),
|
||||
re_path(r'^subevents/bulk_action$', subevents.SubEventBulkAction.as_view(), name='event.subevents.bulkaction'),
|
||||
re_path(r'^subevents/bulk_edit$', subevents.SubEventBulkEdit.as_view(), name='event.subevents.bulkedit'),
|
||||
re_path(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
||||
re_path(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),
|
||||
re_path(r'^items/(?P<item>\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
||||
re_path(r'^items/(?P<item>\d+)/up$', item.item_move_up, name='event.items.up'),
|
||||
re_path(r'^items/(?P<item>\d+)/down$', item.item_move_down, name='event.items.down'),
|
||||
re_path(r'^items/(?P<item>\d+)/delete$', item.ItemDelete.as_view(), name='event.items.delete'),
|
||||
re_path(r'^items/typeahead/meta/$', typeahead.item_meta_values, name='event.items.meta.typeahead'),
|
||||
re_path(r'^items/select2$', typeahead.items_select2, name='event.items.select2'),
|
||||
re_path(r'^items/select2/variation$', typeahead.variations_select2, name='event.items.variations.select2'),
|
||||
re_path(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
|
||||
re_path(r'^categories/select2$', typeahead.category_select2, name='event.items.categories.select2'),
|
||||
re_path(r'^categories/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(),
|
||||
name='event.items.categories.delete'),
|
||||
re_path(r'^categories/(?P<category>\d+)/up$', item.category_move_up, name='event.items.categories.up'),
|
||||
re_path(r'^categories/(?P<category>\d+)/down$', item.category_move_down,
|
||||
name='event.items.categories.down'),
|
||||
re_path(r'^categories/(?P<category>\d+)/$', item.CategoryUpdate.as_view(),
|
||||
name='event.items.categories.edit'),
|
||||
re_path(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
|
||||
re_path(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'),
|
||||
re_path(r'^questions/reorder$', item.reorder_questions, name='event.items.questions.reorder'),
|
||||
re_path(r'^questions/(?P<question>\d+)/delete$', item.QuestionDelete.as_view(),
|
||||
name='event.items.questions.delete'),
|
||||
re_path(r'^questions/(?P<question>\d+)/$', item.QuestionView.as_view(),
|
||||
name='event.items.questions.show'),
|
||||
re_path(r'^questions/(?P<question>\d+)/change$', item.QuestionUpdate.as_view(),
|
||||
name='event.items.questions.edit'),
|
||||
re_path(r'^questions/add$', item.QuestionCreate.as_view(), name='event.items.questions.add'),
|
||||
re_path(r'^quotas/$', item.QuotaList.as_view(), name='event.items.quotas'),
|
||||
re_path(r'^quotas/(?P<quota>\d+)/$', item.QuotaView.as_view(), name='event.items.quotas.show'),
|
||||
re_path(r'^quotas/select$', typeahead.quotas_select2, name='event.items.quotas.select2'),
|
||||
re_path(r'^quotas/(?P<quota>\d+)/change$', item.QuotaUpdate.as_view(), name='event.items.quotas.edit'),
|
||||
re_path(r'^quotas/(?P<quota>\d+)/delete$', item.QuotaDelete.as_view(),
|
||||
name='event.items.quotas.delete'),
|
||||
re_path(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
||||
re_path(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
||||
re_path(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
||||
re_path(r'^vouchers/rng$', vouchers.VoucherRNG.as_view(), name='event.vouchers.rng'),
|
||||
re_path(r'^vouchers/item_select$', typeahead.itemvarquota_select2, name='event.vouchers.itemselect2'),
|
||||
re_path(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
||||
re_path(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
|
||||
name='event.voucher.delete'),
|
||||
re_path(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
|
||||
re_path(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
|
||||
re_path(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
||||
re_path(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
||||
name='event.order.transition'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
|
||||
name='event.order.resendlink'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>\d+)/resend$', orders.OrderResendLink.as_view(),
|
||||
name='event.order.resendlink'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/invoice$', orders.OrderInvoiceCreate.as_view(),
|
||||
name='event.order.geninvoice'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/regenerate$',
|
||||
orders.OrderInvoiceRegenerate.as_view(),
|
||||
name='event.order.regeninvoice'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/reissue$', orders.OrderInvoiceReissue.as_view(),
|
||||
name='event.order.reissueinvoice'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/download/(?P<position>\d+)/(?P<output>[^/]+)/$',
|
||||
orders.OrderDownload.as_view(),
|
||||
name='event.order.download.ticket'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/answer/(?P<answer>[^/]+)/$',
|
||||
orders.AnswerDownload.as_view(),
|
||||
name='event.order.download.answer'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/checkvatid', orders.OrderCheckVATID.as_view(),
|
||||
name='event.order.checkvatid'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/extend$', orders.OrderExtend.as_view(),
|
||||
name='event.order.extend'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/reactivate$', orders.OrderReactivate.as_view(),
|
||||
name='event.order.reactivate'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/contact$', orders.OrderContactChange.as_view(),
|
||||
name='event.order.contact'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/locale', orders.OrderLocaleChange.as_view(),
|
||||
name='event.order.locale'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/comment$', orders.OrderComment.as_view(),
|
||||
name='event.order.comment'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/change$', orders.OrderChange.as_view(),
|
||||
name='event.order.change'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/approve', orders.OrderApprove.as_view(),
|
||||
name='event.order.approve'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/deny$', orders.OrderDeny.as_view(),
|
||||
name='event.order.deny'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/delete$', orders.OrderDelete.as_view(),
|
||||
name='event.order.delete'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/info', orders.OrderModifyInformation.as_view(),
|
||||
name='event.order.info'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/sendmail$', orders.OrderSendMail.as_view(),
|
||||
name='event.order.sendmail'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>[0-9A-Z]+)/sendmail$',
|
||||
orders.OrderPositionSendMail.as_view(),
|
||||
name='event.order.position.sendmail'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/mail_history$', orders.OrderEmailHistory.as_view(),
|
||||
name='event.order.mail_history'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/cancel$', orders.OrderPaymentCancel.as_view(),
|
||||
name='event.order.payments.cancel'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/confirm$', orders.OrderPaymentConfirm.as_view(),
|
||||
name='event.order.payments.confirm'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refund$', orders.OrderRefundView.as_view(),
|
||||
name='event.order.refunds.start'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/cancel$', orders.OrderRefundCancel.as_view(),
|
||||
name='event.order.refunds.cancel'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/process$', orders.OrderRefundProcess.as_view(),
|
||||
name='event.order.refunds.process'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/done$', orders.OrderRefundDone.as_view(),
|
||||
name='event.order.refunds.done'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/cancellationrequests/(?P<req>\d+)/delete$',
|
||||
orders.OrderCancellationRequestDelete.as_view(),
|
||||
name='event.order.cancellationrequests.delete'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
|
||||
re_path(r'^invoice/(?P<invoice>[^/]+)$', orders.InvoiceDownload.as_view(),
|
||||
name='event.invoice.download'),
|
||||
re_path(r'^orders/overview/$', orders.OverView.as_view(), name='event.orders.overview'),
|
||||
re_path(r'^orders/import/$', orderimport.ImportView.as_view(), name='event.orders.import'),
|
||||
re_path(r'^orders/import/(?P<file>[^/]+)/$', orderimport.ProcessView.as_view(),
|
||||
name='event.orders.import.process'),
|
||||
re_path(r'^orders/export/$', orders.ExportView.as_view(), name='event.orders.export'),
|
||||
re_path(r'^orders/export/do$', orders.ExportDoView.as_view(), name='event.orders.export.do'),
|
||||
re_path(r'^orders/refunds/$', orders.RefundList.as_view(), name='event.orders.refunds'),
|
||||
re_path(r'^orders/go$', orders.OrderGo.as_view(), name='event.orders.go'),
|
||||
re_path(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
||||
re_path(r'^orders/search$', orders.OrderSearch.as_view(), name='event.orders.search'),
|
||||
re_path(r'^dangerzone/$', event.DangerZone.as_view(), name='event.dangerzone'),
|
||||
re_path(r'^cancel/$', orders.EventCancel.as_view(), name='event.cancel'),
|
||||
re_path(r'^shredder/$', shredder.StartShredView.as_view(), name='event.shredder.start'),
|
||||
re_path(r'^shredder/export$', shredder.ShredExportView.as_view(), name='event.shredder.export'),
|
||||
re_path(r'^shredder/download/(?P<file>[^/]+)/$', shredder.ShredDownloadView.as_view(),
|
||||
name='event.shredder.download'),
|
||||
re_path(r'^shredder/shred', shredder.ShredDoView.as_view(), name='event.shredder.shred'),
|
||||
re_path(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'),
|
||||
re_path(r'^waitinglist/auto_assign$', waitinglist.AutoAssign.as_view(), name='event.orders.waitinglist.auto'),
|
||||
re_path(r'^waitinglist/(?P<entry>\d+)/delete$', waitinglist.EntryDelete.as_view(),
|
||||
name='event.orders.waitinglist.delete'),
|
||||
re_path(r'^checkinlists/$', checkin.CheckinListList.as_view(), name='event.orders.checkinlists'),
|
||||
re_path(r'^checkinlists/add$', checkin.CheckinListCreate.as_view(), name='event.orders.checkinlists.add'),
|
||||
re_path(r'^checkinlists/select2$', typeahead.checkinlist_select2, name='event.orders.checkinlists.select2'),
|
||||
re_path(r'^checkinlists/(?P<list>\d+)/$', checkin.CheckInListShow.as_view(),
|
||||
name='event.orders.checkinlists.show'),
|
||||
re_path(r'^checkinlists/(?P<list>\d+)/change$', checkin.CheckinListUpdate.as_view(),
|
||||
name='event.orders.checkinlists.edit'),
|
||||
re_path(r'^checkinlists/(?P<list>\d+)/delete$', checkin.CheckinListDelete.as_view(),
|
||||
name='event.orders.checkinlists.delete'),
|
||||
url(r'^logout$', auth.logout, name='auth.logout'),
|
||||
url(r'^login$', auth.login, name='auth.login'),
|
||||
url(r'^login/2fa$', auth.Login2FAView.as_view(), name='auth.login.2fa'),
|
||||
url(r'^register$', auth.register, name='auth.register'),
|
||||
url(r'^invite/(?P<token>[a-zA-Z0-9]+)$', auth.invite, name='auth.invite'),
|
||||
url(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
|
||||
url(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
|
||||
url(r'^$', dashboards.user_index, name='index'),
|
||||
url(r'^widgets.json$', dashboards.user_index_widgets_lazy, name='index.widgets'),
|
||||
url(r'^global/settings/$', global_settings.GlobalSettingsView.as_view(), name='global.settings'),
|
||||
url(r'^global/update/$', global_settings.UpdateCheckView.as_view(), name='global.update'),
|
||||
url(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'),
|
||||
url(r'^logdetail/$', global_settings.LogDetailView.as_view(), name='global.logdetail'),
|
||||
url(r'^logdetail/payment/$', global_settings.PaymentDetailView.as_view(), name='global.paymentdetail'),
|
||||
url(r'^logdetail/refund/$', global_settings.RefundDetailView.as_view(), name='global.refunddetail'),
|
||||
url(r'^geocode/$', geo.GeoCodeView.as_view(), name='global.geocode'),
|
||||
url(r'^reauth/$', user.ReauthView.as_view(), name='user.reauth'),
|
||||
url(r'^sudo/$', user.StartStaffSession.as_view(), name='user.sudo'),
|
||||
url(r'^sudo/stop/$', user.StopStaffSession.as_view(), name='user.sudo.stop'),
|
||||
url(r'^sudo/(?P<id>\d+)/$', user.EditStaffSession.as_view(), name='user.sudo.edit'),
|
||||
url(r'^sudo/sessions/$', user.StaffSessionList.as_view(), name='user.sudo.list'),
|
||||
url(r'^users/$', users.UserListView.as_view(), name='users'),
|
||||
url(r'^users/select2$', typeahead.users_select2, name='users.select2'),
|
||||
url(r'^users/add$', users.UserCreateView.as_view(), name='users.add'),
|
||||
url(r'^users/impersonate/stop', users.UserImpersonateStopView.as_view(), name='users.impersonate.stop'),
|
||||
url(r'^users/(?P<id>\d+)/$', users.UserEditView.as_view(), name='users.edit'),
|
||||
url(r'^users/(?P<id>\d+)/reset$', users.UserResetView.as_view(), name='users.reset'),
|
||||
url(r'^users/(?P<id>\d+)/impersonate', users.UserImpersonateView.as_view(), name='users.impersonate'),
|
||||
url(r'^users/(?P<id>\d+)/anonymize', users.UserAnonymizeView.as_view(), name='users.anonymize'),
|
||||
url(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
||||
url(r'^settings/?$', user.UserSettings.as_view(), name='user.settings'),
|
||||
url(r'^settings/history/$', user.UserHistoryView.as_view(), name='user.settings.history'),
|
||||
url(r'^settings/notifications/$', user.UserNotificationsEditView.as_view(), name='user.settings.notifications'),
|
||||
url(r'^settings/notifications/off/(?P<id>\d+)/(?P<token>[^/]+)/$', user.UserNotificationsDisableView.as_view(),
|
||||
name='user.settings.notifications.off'),
|
||||
url(r'^settings/oauth/authorized/$', oauth.AuthorizationListView.as_view(),
|
||||
name='user.settings.oauth.list'),
|
||||
url(r'^settings/oauth/authorized/(?P<pk>\d+)/revoke$', oauth.AuthorizationRevokeView.as_view(),
|
||||
name='user.settings.oauth.revoke'),
|
||||
url(r'^settings/oauth/apps/$', oauth.OAuthApplicationListView.as_view(),
|
||||
name='user.settings.oauth.apps'),
|
||||
url(r'^settings/oauth/apps/add$', oauth.OAuthApplicationRegistrationView.as_view(),
|
||||
name='user.settings.oauth.apps.register'),
|
||||
url(r'^settings/oauth/apps/(?P<pk>\d+)/$', oauth.OAuthApplicationUpdateView.as_view(),
|
||||
name='user.settings.oauth.app'),
|
||||
url(r'^settings/oauth/apps/(?P<pk>\d+)/disable$', oauth.OAuthApplicationDeleteView.as_view(),
|
||||
name='user.settings.oauth.app.disable'),
|
||||
url(r'^settings/oauth/apps/(?P<pk>\d+)/roll$', oauth.OAuthApplicationRollView.as_view(),
|
||||
name='user.settings.oauth.app.roll'),
|
||||
url(r'^settings/2fa/$', user.User2FAMainView.as_view(), name='user.settings.2fa'),
|
||||
url(r'^settings/2fa/add$', user.User2FADeviceAddView.as_view(), name='user.settings.2fa.add'),
|
||||
url(r'^settings/2fa/enable', user.User2FAEnableView.as_view(), name='user.settings.2fa.enable'),
|
||||
url(r'^settings/2fa/disable', user.User2FADisableView.as_view(), name='user.settings.2fa.disable'),
|
||||
url(r'^settings/2fa/regenemergency', user.User2FARegenerateEmergencyView.as_view(),
|
||||
name='user.settings.2fa.regenemergency'),
|
||||
url(r'^settings/2fa/totp/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmTOTPView.as_view(),
|
||||
name='user.settings.2fa.confirm.totp'),
|
||||
url(r'^settings/2fa/webauthn/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmWebAuthnView.as_view(),
|
||||
name='user.settings.2fa.confirm.webauthn'),
|
||||
url(r'^settings/2fa/(?P<devicetype>[^/]+)/(?P<device>[0-9]+)/delete', user.User2FADeviceDeleteView.as_view(),
|
||||
name='user.settings.2fa.delete'),
|
||||
url(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'),
|
||||
url(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'),
|
||||
url(r'^organizers/select2$', typeahead.organizer_select2, name='organizers.select2'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/$', organizer.OrganizerDetail.as_view(), name='organizer'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/edit$', organizer.OrganizerUpdate.as_view(), name='organizer.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/delete$', organizer.OrganizerDelete.as_view(), name='organizer.delete'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/settings/display$', organizer.OrganizerDisplaySettings.as_view(),
|
||||
name='organizer.display'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/properties$', organizer.EventMetaPropertyListView.as_view(), name='organizer.properties'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/property/add$', organizer.EventMetaPropertyCreateView.as_view(),
|
||||
name='organizer.property.add'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/edit$', organizer.EventMetaPropertyUpdateView.as_view(),
|
||||
name='organizer.property.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/delete$', organizer.EventMetaPropertyDeleteView.as_view(),
|
||||
name='organizer.property.delete'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcards$', organizer.GiftCardListView.as_view(), name='organizer.giftcards'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcard/add$', organizer.GiftCardCreateView.as_view(), name='organizer.giftcard.add'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/$', organizer.GiftCardDetailView.as_view(), name='organizer.giftcard'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/edit$', organizer.GiftCardUpdateView.as_view(),
|
||||
name='organizer.giftcard.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/webhooks$', organizer.WebHookListView.as_view(), name='organizer.webhooks'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/webhook/add$', organizer.WebHookCreateView.as_view(),
|
||||
name='organizer.webhook.add'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/edit$', organizer.WebHookUpdateView.as_view(),
|
||||
name='organizer.webhook.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/logs$', organizer.WebHookLogsView.as_view(),
|
||||
name='organizer.webhook.logs'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/devices$', organizer.DeviceListView.as_view(), name='organizer.devices'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/device/add$', organizer.DeviceCreateView.as_view(),
|
||||
name='organizer.device.add'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/edit$', organizer.DeviceUpdateView.as_view(),
|
||||
name='organizer.device.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/connect$', organizer.DeviceConnectView.as_view(),
|
||||
name='organizer.device.connect'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/revoke$', organizer.DeviceRevokeView.as_view(),
|
||||
name='organizer.device.revoke'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/logs$', organizer.DeviceLogView.as_view(),
|
||||
name='organizer.device.logs'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/gates$', organizer.GateListView.as_view(), name='organizer.gates'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/gate/add$', organizer.GateCreateView.as_view(), name='organizer.gate.add'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/edit$', organizer.GateUpdateView.as_view(),
|
||||
name='organizer.gate.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/delete$', organizer.GateDeleteView.as_view(),
|
||||
name='organizer.gate.delete'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/teams$', organizer.TeamListView.as_view(), name='organizer.teams'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/team/add$', organizer.TeamCreateView.as_view(), name='organizer.team.add'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/$', organizer.TeamMemberView.as_view(),
|
||||
name='organizer.team'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/edit$', organizer.TeamUpdateView.as_view(),
|
||||
name='organizer.team.edit'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/delete$', organizer.TeamDeleteView.as_view(),
|
||||
name='organizer.team.delete'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/slugrng', main.SlugRNG.as_view(), name='events.add.slugrng'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/logs', organizer.LogView.as_view(), name='organizer.log'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/export/$', organizer.ExportView.as_view(), name='organizer.export'),
|
||||
url(r'^organizer/(?P<organizer>[^/]+)/export/do$', organizer.ExportDoView.as_view(), name='organizer.export.do'),
|
||||
url(r'^nav/typeahead/$', typeahead.nav_context_list, name='nav.typeahead'),
|
||||
url(r'^events/$', main.EventList.as_view(), name='events'),
|
||||
url(r'^events/add$', main.EventWizard.as_view(), name='events.add'),
|
||||
url(r'^events/typeahead/$', typeahead.event_list, name='events.typeahead'),
|
||||
url(r'^events/typeahead/meta/$', typeahead.meta_values, name='events.meta.typeahead'),
|
||||
url(r'^search/orders/$', search.OrderSearch.as_view(), name='search.orders'),
|
||||
url(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
|
||||
url(r'^$', dashboards.event_index, name='event.index'),
|
||||
url(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
|
||||
url(r'^live/$', event.EventLive.as_view(), name='event.live'),
|
||||
url(r'^logs/$', event.EventLog.as_view(), name='event.log'),
|
||||
url(r'^delete/$', event.EventDelete.as_view(), name='event.delete'),
|
||||
url(r'^requiredactions/$', event.EventActions.as_view(), name='event.requiredactions'),
|
||||
url(r'^requiredactions/(?P<id>\d+)/discard$', event.EventActionDiscard.as_view(),
|
||||
name='event.requiredaction.discard'),
|
||||
url(r'^comment/$', event.EventComment.as_view(),
|
||||
name='event.comment'),
|
||||
url(r'^quickstart/$', event.QuickSetupView.as_view(), name='event.quick'),
|
||||
url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
||||
url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
||||
url(r'^settings/payment/(?P<provider>[^/]+)$', event.PaymentProviderSettings.as_view(),
|
||||
name='event.settings.payment.provider'),
|
||||
url(r'^settings/payment$', event.PaymentSettings.as_view(), name='event.settings.payment'),
|
||||
url(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'),
|
||||
url(r'^settings/tickets/preview/(?P<output>[^/]+)$', event.TicketSettingsPreview.as_view(),
|
||||
name='event.settings.tickets.preview'),
|
||||
url(r'^settings/email$', event.MailSettings.as_view(), name='event.settings.mail'),
|
||||
url(r'^settings/email/preview$', event.MailSettingsPreview.as_view(), name='event.settings.mail.preview'),
|
||||
url(r'^settings/email/layoutpreview$', event.MailSettingsRendererPreview.as_view(),
|
||||
name='event.settings.mail.preview.layout'),
|
||||
url(r'^settings/cancel', event.CancelSettings.as_view(), name='event.settings.cancel'),
|
||||
url(r'^settings/invoice$', event.InvoiceSettings.as_view(), name='event.settings.invoice'),
|
||||
url(r'^settings/invoice/preview$', event.InvoicePreview.as_view(), name='event.settings.invoice.preview'),
|
||||
url(r'^settings/display', event.DisplaySettings.as_view(), name='event.settings.display'),
|
||||
url(r'^settings/tax/$', event.TaxList.as_view(), name='event.settings.tax'),
|
||||
url(r'^settings/tax/(?P<rule>\d+)/$', event.TaxUpdate.as_view(), name='event.settings.tax.edit'),
|
||||
url(r'^settings/tax/add$', event.TaxCreate.as_view(), name='event.settings.tax.add'),
|
||||
url(r'^settings/tax/(?P<rule>\d+)/delete$', event.TaxDelete.as_view(), name='event.settings.tax.delete'),
|
||||
url(r'^settings/widget$', event.WidgetSettings.as_view(), name='event.settings.widget'),
|
||||
url(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
||||
url(r'^pdf/editor/(?P<filename>[^/]+).pdf$', pdf.PdfView.as_view(), name='pdf.background'),
|
||||
url(r'^subevents/$', subevents.SubEventList.as_view(), name='event.subevents'),
|
||||
url(r'^subevents/select2$', typeahead.subevent_select2, name='event.subevents.select2'),
|
||||
url(r'^subevents/(?P<subevent>\d+)/$', subevents.SubEventUpdate.as_view(), name='event.subevent'),
|
||||
url(r'^subevents/(?P<subevent>\d+)/delete$', subevents.SubEventDelete.as_view(),
|
||||
name='event.subevent.delete'),
|
||||
url(r'^subevents/add$', subevents.SubEventCreate.as_view(), name='event.subevents.add'),
|
||||
url(r'^subevents/bulk_add$', subevents.SubEventBulkCreate.as_view(), name='event.subevents.bulk'),
|
||||
url(r'^subevents/bulk_action$', subevents.SubEventBulkAction.as_view(), name='event.subevents.bulkaction'),
|
||||
url(r'^subevents/bulk_edit$', subevents.SubEventBulkEdit.as_view(), name='event.subevents.bulkedit'),
|
||||
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
||||
url(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),
|
||||
url(r'^items/(?P<item>\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
||||
url(r'^items/(?P<item>\d+)/up$', item.item_move_up, name='event.items.up'),
|
||||
url(r'^items/(?P<item>\d+)/down$', item.item_move_down, name='event.items.down'),
|
||||
url(r'^items/(?P<item>\d+)/delete$', item.ItemDelete.as_view(), name='event.items.delete'),
|
||||
url(r'^items/typeahead/meta/$', typeahead.item_meta_values, name='event.items.meta.typeahead'),
|
||||
url(r'^items/select2$', typeahead.items_select2, name='event.items.select2'),
|
||||
url(r'^items/select2/variation$', typeahead.variations_select2, name='event.items.variations.select2'),
|
||||
url(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
|
||||
url(r'^categories/select2$', typeahead.category_select2, name='event.items.categories.select2'),
|
||||
url(r'^categories/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(),
|
||||
name='event.items.categories.delete'),
|
||||
url(r'^categories/(?P<category>\d+)/up$', item.category_move_up, name='event.items.categories.up'),
|
||||
url(r'^categories/(?P<category>\d+)/down$', item.category_move_down,
|
||||
name='event.items.categories.down'),
|
||||
url(r'^categories/(?P<category>\d+)/$', item.CategoryUpdate.as_view(),
|
||||
name='event.items.categories.edit'),
|
||||
url(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
|
||||
url(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'),
|
||||
url(r'^questions/reorder$', item.reorder_questions, name='event.items.questions.reorder'),
|
||||
url(r'^questions/(?P<question>\d+)/delete$', item.QuestionDelete.as_view(),
|
||||
name='event.items.questions.delete'),
|
||||
url(r'^questions/(?P<question>\d+)/$', item.QuestionView.as_view(),
|
||||
name='event.items.questions.show'),
|
||||
url(r'^questions/(?P<question>\d+)/change$', item.QuestionUpdate.as_view(),
|
||||
name='event.items.questions.edit'),
|
||||
url(r'^questions/add$', item.QuestionCreate.as_view(), name='event.items.questions.add'),
|
||||
url(r'^quotas/$', item.QuotaList.as_view(), name='event.items.quotas'),
|
||||
url(r'^quotas/(?P<quota>\d+)/$', item.QuotaView.as_view(), name='event.items.quotas.show'),
|
||||
url(r'^quotas/select$', typeahead.quotas_select2, name='event.items.quotas.select2'),
|
||||
url(r'^quotas/(?P<quota>\d+)/change$', item.QuotaUpdate.as_view(), name='event.items.quotas.edit'),
|
||||
url(r'^quotas/(?P<quota>\d+)/delete$', item.QuotaDelete.as_view(),
|
||||
name='event.items.quotas.delete'),
|
||||
url(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
||||
url(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
||||
url(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
||||
url(r'^vouchers/rng$', vouchers.VoucherRNG.as_view(), name='event.vouchers.rng'),
|
||||
url(r'^vouchers/item_select$', typeahead.itemvarquota_select2, name='event.vouchers.itemselect2'),
|
||||
url(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
||||
url(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
|
||||
name='event.voucher.delete'),
|
||||
url(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
|
||||
url(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
|
||||
url(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
||||
url(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
||||
name='event.order.transition'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
|
||||
name='event.order.resendlink'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>\d+)/resend$', orders.OrderResendLink.as_view(),
|
||||
name='event.order.resendlink'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/invoice$', orders.OrderInvoiceCreate.as_view(),
|
||||
name='event.order.geninvoice'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/regenerate$', orders.OrderInvoiceRegenerate.as_view(),
|
||||
name='event.order.regeninvoice'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/reissue$', orders.OrderInvoiceReissue.as_view(),
|
||||
name='event.order.reissueinvoice'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/download/(?P<position>\d+)/(?P<output>[^/]+)/$',
|
||||
orders.OrderDownload.as_view(),
|
||||
name='event.order.download.ticket'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/answer/(?P<answer>[^/]+)/$',
|
||||
orders.AnswerDownload.as_view(),
|
||||
name='event.order.download.answer'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/checkvatid', orders.OrderCheckVATID.as_view(),
|
||||
name='event.order.checkvatid'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/extend$', orders.OrderExtend.as_view(),
|
||||
name='event.order.extend'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/reactivate$', orders.OrderReactivate.as_view(),
|
||||
name='event.order.reactivate'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/contact$', orders.OrderContactChange.as_view(),
|
||||
name='event.order.contact'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/locale', orders.OrderLocaleChange.as_view(),
|
||||
name='event.order.locale'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/comment$', orders.OrderComment.as_view(),
|
||||
name='event.order.comment'),
|
||||
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]+)/approve', orders.OrderApprove.as_view(),
|
||||
name='event.order.approve'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/deny$', orders.OrderDeny.as_view(),
|
||||
name='event.order.deny'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/delete$', orders.OrderDelete.as_view(),
|
||||
name='event.order.delete'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/info', orders.OrderModifyInformation.as_view(),
|
||||
name='event.order.info'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/sendmail$', orders.OrderSendMail.as_view(),
|
||||
name='event.order.sendmail'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>[0-9A-Z]+)/sendmail$', orders.OrderPositionSendMail.as_view(),
|
||||
name='event.order.position.sendmail'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/mail_history$', orders.OrderEmailHistory.as_view(),
|
||||
name='event.order.mail_history'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/cancel$', orders.OrderPaymentCancel.as_view(),
|
||||
name='event.order.payments.cancel'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/confirm$', orders.OrderPaymentConfirm.as_view(),
|
||||
name='event.order.payments.confirm'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refund$', orders.OrderRefundView.as_view(),
|
||||
name='event.order.refunds.start'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/cancel$', orders.OrderRefundCancel.as_view(),
|
||||
name='event.order.refunds.cancel'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/process$', orders.OrderRefundProcess.as_view(),
|
||||
name='event.order.refunds.process'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/done$', orders.OrderRefundDone.as_view(),
|
||||
name='event.order.refunds.done'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/cancellationrequests/(?P<req>\d+)/delete$',
|
||||
orders.OrderCancellationRequestDelete.as_view(),
|
||||
name='event.order.cancellationrequests.delete'),
|
||||
url(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
|
||||
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'),
|
||||
url(r'^orders/import/$', orderimport.ImportView.as_view(), name='event.orders.import'),
|
||||
url(r'^orders/import/(?P<file>[^/]+)/$', orderimport.ProcessView.as_view(), name='event.orders.import.process'),
|
||||
url(r'^orders/export/$', orders.ExportView.as_view(), name='event.orders.export'),
|
||||
url(r'^orders/export/do$', orders.ExportDoView.as_view(), name='event.orders.export.do'),
|
||||
url(r'^orders/refunds/$', orders.RefundList.as_view(), name='event.orders.refunds'),
|
||||
url(r'^orders/go$', orders.OrderGo.as_view(), name='event.orders.go'),
|
||||
url(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
||||
url(r'^orders/search$', orders.OrderSearch.as_view(), name='event.orders.search'),
|
||||
url(r'^dangerzone/$', event.DangerZone.as_view(), name='event.dangerzone'),
|
||||
url(r'^cancel/$', orders.EventCancel.as_view(), name='event.cancel'),
|
||||
url(r'^shredder/$', shredder.StartShredView.as_view(), name='event.shredder.start'),
|
||||
url(r'^shredder/export$', shredder.ShredExportView.as_view(), name='event.shredder.export'),
|
||||
url(r'^shredder/download/(?P<file>[^/]+)/$', shredder.ShredDownloadView.as_view(), name='event.shredder.download'),
|
||||
url(r'^shredder/shred', shredder.ShredDoView.as_view(), name='event.shredder.shred'),
|
||||
url(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'),
|
||||
url(r'^waitinglist/auto_assign$', waitinglist.AutoAssign.as_view(), name='event.orders.waitinglist.auto'),
|
||||
url(r'^waitinglist/(?P<entry>\d+)/delete$', waitinglist.EntryDelete.as_view(),
|
||||
name='event.orders.waitinglist.delete'),
|
||||
url(r'^checkinlists/$', checkin.CheckinListList.as_view(), name='event.orders.checkinlists'),
|
||||
url(r'^checkinlists/add$', checkin.CheckinListCreate.as_view(), name='event.orders.checkinlists.add'),
|
||||
url(r'^checkinlists/select2$', typeahead.checkinlist_select2, name='event.orders.checkinlists.select2'),
|
||||
url(r'^checkinlists/(?P<list>\d+)/$', checkin.CheckInListShow.as_view(), name='event.orders.checkinlists.show'),
|
||||
url(r'^checkinlists/(?P<list>\d+)/change$', checkin.CheckinListUpdate.as_view(),
|
||||
name='event.orders.checkinlists.edit'),
|
||||
url(r'^checkinlists/(?P<list>\d+)/delete$', checkin.CheckinListDelete.as_view(),
|
||||
name='event.orders.checkinlists.delete'),
|
||||
])),
|
||||
re_path(r'^event/(?P<organizer>[^/]+)/$', RedirectView.as_view(pattern_name='control:organizer'),
|
||||
name='event.organizerredirect'),
|
||||
url(r'^event/(?P<organizer>[^/]+)/$', RedirectView.as_view(pattern_name='control:organizer'), name='event.organizerredirect'),
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import collections.abc
|
||||
import collections
|
||||
import warnings
|
||||
|
||||
from django.core.paginator import (
|
||||
@@ -65,7 +65,7 @@ class PaginationMixin:
|
||||
return ctx
|
||||
|
||||
|
||||
class LargeResultSetPage(collections.abc.Sequence):
|
||||
class LargeResultSetPage(collections.Sequence):
|
||||
|
||||
def __init__(self, object_list, number, paginator):
|
||||
self.object_list = object_list
|
||||
|
||||
@@ -691,14 +691,14 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
||||
expires=now(), code="PREVIEW", total=119)
|
||||
item = request.event.items.create(name=gettext("Sample product"), default_price=42.23,
|
||||
description=gettext("Sample product description"))
|
||||
order.positions.create(item=item, attendee_name_parts={'_legacy': gettext("John Doe")},
|
||||
price=item.default_price, subevent=request.event.subevents.last())
|
||||
p = order.positions.create(item=item, attendee_name_parts={'_legacy': gettext("John Doe")},
|
||||
price=item.default_price)
|
||||
v = renderers[request.GET.get('renderer')].render(
|
||||
v,
|
||||
str(request.event.settings.mail_text_signature),
|
||||
gettext('Your order: %(code)s') % {'code': order.code},
|
||||
order,
|
||||
position=None
|
||||
position=p
|
||||
)
|
||||
r = HttpResponse(v, content_type='text/html')
|
||||
r._csp_ignore = True
|
||||
|
||||
@@ -151,11 +151,6 @@ class OrderList(OrderSearchMixin, EventPermissionRequiredMixin, PaginationMixin,
|
||||
s = OrderPosition.objects.filter(
|
||||
order=OuterRef('pk')
|
||||
).order_by().values('order').annotate(k=Count('id')).values('k')
|
||||
i = Invoice.objects.filter(
|
||||
order=OuterRef('pk'),
|
||||
is_cancellation=False,
|
||||
refered__isnull=True,
|
||||
).order_by().values('order').annotate(k=Count('id')).values('k')
|
||||
annotated = {
|
||||
o['pk']: o
|
||||
for o in
|
||||
@@ -163,11 +158,10 @@ class OrderList(OrderSearchMixin, EventPermissionRequiredMixin, PaginationMixin,
|
||||
pk__in=[o.pk for o in ctx['orders']]
|
||||
).annotate(
|
||||
pcnt=Subquery(s, output_field=IntegerField()),
|
||||
icnt=Subquery(i, output_field=IntegerField()),
|
||||
has_cancellation_request=Exists(CancellationRequest.objects.filter(order=OuterRef('pk')))
|
||||
).values(
|
||||
'pk', 'pcnt', 'is_overpaid', 'is_underpaid', 'is_pending_with_full_payment', 'has_external_refund',
|
||||
'has_pending_refund', 'has_cancellation_request', 'computed_payment_refund_sum', 'icnt'
|
||||
'has_pending_refund', 'has_cancellation_request', 'computed_payment_refund_sum'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -183,7 +177,6 @@ class OrderList(OrderSearchMixin, EventPermissionRequiredMixin, PaginationMixin,
|
||||
o.has_pending_refund = annotated.get(o.pk)['has_pending_refund']
|
||||
o.has_cancellation_request = annotated.get(o.pk)['has_cancellation_request']
|
||||
o.computed_payment_refund_sum = annotated.get(o.pk)['computed_payment_refund_sum']
|
||||
o.icnt = annotated.get(o.pk)['icnt']
|
||||
o.sales_channel_obj = scs[o.sales_channel]
|
||||
|
||||
if ctx['page_obj'].paginator.count < 1000:
|
||||
@@ -1141,7 +1134,6 @@ class OrderTransition(OrderView):
|
||||
try:
|
||||
cancel_order(self.order.pk, user=self.request.user,
|
||||
send_mail=self.mark_canceled_form.cleaned_data['send_email'],
|
||||
cancel_invoice=self.mark_canceled_form.cleaned_data.get('cancel_invoice', True),
|
||||
cancellation_fee=self.mark_canceled_form.cleaned_data.get('cancellation_fee'))
|
||||
except OrderError as e:
|
||||
messages.error(self.request, str(e))
|
||||
|
||||
@@ -938,7 +938,6 @@ class GiftCardListView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
|
||||
template_name = 'pretixcontrol/organizers/giftcards.html'
|
||||
permission = 'can_manage_gift_cards'
|
||||
context_object_name = 'giftcards'
|
||||
paginate_by = 50
|
||||
|
||||
def get_queryset(self):
|
||||
s = GiftCardTransaction.objects.filter(
|
||||
|
||||
@@ -1184,7 +1184,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
|
||||
for fname in ('size', 'name', 'release_after_exit'):
|
||||
setattr(q, fname, f.cleaned_data.get(fname))
|
||||
q.save(clear_cache=False)
|
||||
if 'itemvars' in f.changed_data:
|
||||
if 'itemvar' in f.changed_data:
|
||||
q.items.set(selected_items)
|
||||
q.variations.set(selected_variations)
|
||||
log_entries.append(
|
||||
|
||||
@@ -255,7 +255,7 @@ def subevent_select2(request, **kwargs):
|
||||
|
||||
qs = request.event.subevents.filter(
|
||||
qf
|
||||
).order_by('-date_from', 'name', 'pk')
|
||||
).order_by('-date_from')
|
||||
|
||||
total = qs.count()
|
||||
pagesize = 20
|
||||
|
||||
@@ -211,7 +211,7 @@ class WaitingListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC, delimiter=",")
|
||||
|
||||
headers = [
|
||||
_('Name'), _('E-mail address'), _('Phone number'), _('Product'), _('On list since'), _('Status'), _('Voucher code'),
|
||||
_('E-mail address'), _('Product'), _('On list since'), _('Status'), _('Voucher code'),
|
||||
_('Language'), _('Priority')
|
||||
]
|
||||
if self.request.event.has_subevents:
|
||||
@@ -235,9 +235,7 @@ class WaitingListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
||||
status = _('Waiting')
|
||||
|
||||
row = [
|
||||
w.name,
|
||||
w.email,
|
||||
w.phone,
|
||||
prod,
|
||||
w.created.isoformat(),
|
||||
status,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import copy
|
||||
|
||||
from django.core.files import File
|
||||
from django.db import models
|
||||
|
||||
|
||||
@@ -17,8 +16,7 @@ def modelcopy(obj: models.Model):
|
||||
n = obj.__class__()
|
||||
for f in obj._meta.fields:
|
||||
val = getattr(obj, f.name)
|
||||
print(f, f.name, val)
|
||||
if isinstance(val, (models.Model, File)):
|
||||
if isinstance(val, models.Model):
|
||||
setattr(n, f.name, copy.copy(val))
|
||||
else:
|
||||
setattr(n, f.name, copy.deepcopy(val))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-07-30 19:00+0000\n"
|
||||
"Last-Translator: Abdullah <abdullah.gumaijan@gmail.com>\n"
|
||||
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
||||
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-12-14 10:00+0000\n"
|
||||
"Last-Translator: Ondřej Sokol <osokol@treesoft.cz>\n"
|
||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-09-15 02:00+0000\n"
|
||||
"Last-Translator: Mie Frydensbjerg <mif@aarhus.dk>\n"
|
||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-08-25 02:00+0000\n"
|
||||
"Last-Translator: Dennis Lichtenthäler <lichtenthaeler@rami.io>\n"
|
||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-08-25 02:00+0000\n"
|
||||
"Last-Translator: Dennis Lichtenthäler <lichtenthaeler@rami.io>\n"
|
||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
||||
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
||||
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-04-27 20:00+0000\n"
|
||||
"Last-Translator: Gonzalo Gabriel Perez <zalitoar@gmail.com>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2021-01-20 16:10+0000\n"
|
||||
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
||||
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: French\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-09-15 17:00+0000\n"
|
||||
"Last-Translator: Martin Gross <martin@pc-coholic.de>\n"
|
||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-01-24 08:00+0000\n"
|
||||
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
|
||||
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
||||
"PO-Revision-Date: 2020-06-12 20:00+0000\n"
|
||||
"Last-Translator: Frank <webappconcept@gmail.com>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user