mirror of
https://github.com/pretix/pretix.git
synced 2026-10-03 19:34:41 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc64109e11 | ||
|
|
40018b0937 | ||
|
|
cffcddaf26 | ||
|
|
bd70a2e7bf | ||
|
|
76e9093fea | ||
|
|
b3c9dca024 | ||
|
|
f4710cf019 | ||
|
|
5f192fd0ce | ||
|
|
a897f60fc5 | ||
|
|
74107781ce | ||
|
|
ad219df7cf | ||
|
|
002ab4aa06 | ||
|
|
a84a726185 | ||
|
|
5f58b93c71 | ||
|
|
3eaaf80c0a | ||
|
|
3b5d811b27 | ||
|
|
f0da2b7233 | ||
|
|
d8d7440b52 | ||
|
|
a1ec9fceb0 | ||
|
|
27ff73255b | ||
|
|
bba103156c | ||
|
|
f1a98b5c30 | ||
|
|
405b3a22e1 | ||
|
|
a51c2a36a6 | ||
|
|
8e00970f04 | ||
|
|
8ca2fe7707 | ||
|
|
b93e2307d0 | ||
|
|
97f3b72254 | ||
|
|
00a77d3de9 | ||
|
|
35d9a0dacf | ||
|
|
d2e6320e1e | ||
|
|
671eb902a8 | ||
|
|
be67059099 | ||
|
|
6e3791a49e | ||
|
|
e3bd665093 | ||
|
|
748e2bb2fa | ||
|
|
b13b34f00d | ||
|
|
641e3216d9 | ||
|
|
c70901c129 | ||
|
|
460d39b8c2 | ||
|
|
a9963aead1 | ||
|
|
a09dac89c4 | ||
|
|
8af91b691d | ||
|
|
2221b57dc9 | ||
|
|
8d99388c08 | ||
|
|
de597ba864 | ||
|
|
2d9a16e94d |
@@ -60,6 +60,7 @@ Here is the currently recommended set of commands::
|
|||||||
CREATE INDEX CONCURRENTLY pretix_addidx_ia_company
|
CREATE INDEX CONCURRENTLY pretix_addidx_ia_company
|
||||||
ON pretixbase_invoiceaddress
|
ON pretixbase_invoiceaddress
|
||||||
USING gin (upper("company") gin_trgm_ops);
|
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::
|
Also, if you use our ``pretix-shipping`` plugin::
|
||||||
|
|||||||
@@ -15,8 +15,24 @@ number string Invoice number
|
|||||||
order string Order code of the order this invoice belongs to
|
order string Order code of the order this invoice belongs to
|
||||||
is_cancellation boolean ``true``, if this invoice is the cancellation of a
|
is_cancellation boolean ``true``, if this invoice is the cancellation of a
|
||||||
different invoice.
|
different invoice.
|
||||||
invoice_from string Sender address
|
invoice_from_name string Sender address: Name
|
||||||
invoice_to string Receiver address
|
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
|
||||||
date date Invoice date
|
date date Invoice date
|
||||||
refers string Invoice number of an invoice this invoice refers to
|
refers string Invoice number of an invoice this invoice refers to
|
||||||
(for example a cancellation refers to the invoice it
|
(for example a cancellation refers to the invoice it
|
||||||
@@ -30,6 +46,31 @@ footer_text string Text to be prin
|
|||||||
lines list of objects The actual invoice contents
|
lines list of objects The actual invoice contents
|
||||||
├ position integer Number of the line within an invoice.
|
├ position integer Number of the line within an invoice.
|
||||||
├ description string Text representing the invoice line (e.g. product name)
|
├ 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
|
├ gross_value money (string) Price including taxes
|
||||||
├ tax_value money (string) Tax amount included
|
├ tax_value money (string) Tax amount included
|
||||||
├ tax_name string Name of used tax rate (e.g. "VAT")
|
├ tax_name string Name of used tax rate (e.g. "VAT")
|
||||||
@@ -50,6 +91,12 @@ internal_reference string Customer's refe
|
|||||||
|
|
||||||
The attribute ``lines.number`` has been added.
|
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
|
Endpoints
|
||||||
---------
|
---------
|
||||||
@@ -83,8 +130,24 @@ Endpoints
|
|||||||
"number": "SAMPLECONF-00001",
|
"number": "SAMPLECONF-00001",
|
||||||
"order": "ABC12",
|
"order": "ABC12",
|
||||||
"is_cancellation": false,
|
"is_cancellation": false,
|
||||||
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
|
"invoice_from_name": "Big Events LLC",
|
||||||
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT ID: EU123456789",
|
"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,
|
||||||
"date": "2017-12-01",
|
"date": "2017-12-01",
|
||||||
"refers": null,
|
"refers": null,
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
@@ -97,6 +160,11 @@ Endpoints
|
|||||||
{
|
{
|
||||||
"position": 1,
|
"position": 1,
|
||||||
"description": "Budget Ticket",
|
"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",
|
"gross_value": "23.00",
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_name": "VAT",
|
"tax_name": "VAT",
|
||||||
@@ -148,8 +216,24 @@ Endpoints
|
|||||||
"number": "SAMPLECONF-00001",
|
"number": "SAMPLECONF-00001",
|
||||||
"order": "ABC12",
|
"order": "ABC12",
|
||||||
"is_cancellation": false,
|
"is_cancellation": false,
|
||||||
"invoice_from": "Big Events LLC\nDemo street 12\nDemo town",
|
"invoice_from_name": "Big Events LLC",
|
||||||
"invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT ID: EU123456789",
|
"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,
|
||||||
"date": "2017-12-01",
|
"date": "2017-12-01",
|
||||||
"refers": null,
|
"refers": null,
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
@@ -162,6 +246,11 @@ Endpoints
|
|||||||
{
|
{
|
||||||
"position": 1,
|
"position": 1,
|
||||||
"description": "Budget Ticket",
|
"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",
|
"gross_value": "23.00",
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_name": "VAT",
|
"tax_name": "VAT",
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ Field Type Description
|
|||||||
===================================== ========================== =======================================================
|
===================================== ========================== =======================================================
|
||||||
id integer Internal ID of the waiting list entry
|
id integer Internal ID of the waiting list entry
|
||||||
created datetime Creation date 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
|
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
|
voucher integer Internal ID of the voucher sent to this user. If
|
||||||
this field is set, the user has been sent a voucher
|
this field is set, the user has been sent a voucher
|
||||||
and is no longer waiting. If it is ``null``, the
|
and is no longer waiting. If it is ``null``, the
|
||||||
|
|||||||
+7
-2
@@ -6,8 +6,8 @@ localecompile:
|
|||||||
./manage.py compilemessages
|
./manage.py compilemessages
|
||||||
|
|
||||||
localegen:
|
localegen:
|
||||||
./manage.py makemessages --keep-pot --ignore "pretix/helpers/*" $(LNGS)
|
./manage.py makemessages --keep-pot --ignore "pretix/helpers/*" --ignore "pretix/static/npm_dir/*" $(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)
|
./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)
|
||||||
|
|
||||||
staticfiles: jsi18n
|
staticfiles: jsi18n
|
||||||
./manage.py collectstatic --noinput
|
./manage.py collectstatic --noinput
|
||||||
@@ -23,3 +23,8 @@ test:
|
|||||||
|
|
||||||
coverage:
|
coverage:
|
||||||
coverage run -m py.test
|
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 +1 @@
|
|||||||
__version__ = "3.16.0"
|
__version__ = "3.17.0.dev0"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class FullAccessSecurityProfile:
|
class FullAccessSecurityProfile:
|
||||||
|
|||||||
@@ -596,6 +596,7 @@ class EventSettingsSerializer(SettingsSerializer):
|
|||||||
'checkout_email_helptext',
|
'checkout_email_helptext',
|
||||||
'presale_has_ended_text',
|
'presale_has_ended_text',
|
||||||
'voucher_explanation_text',
|
'voucher_explanation_text',
|
||||||
|
'checkout_success_text',
|
||||||
'banner_text',
|
'banner_text',
|
||||||
'banner_text_bottom',
|
'banner_text_bottom',
|
||||||
'show_dates_on_frontpage',
|
'show_dates_on_frontpage',
|
||||||
@@ -613,6 +614,11 @@ class EventSettingsSerializer(SettingsSerializer):
|
|||||||
'waiting_list_enabled',
|
'waiting_list_enabled',
|
||||||
'waiting_list_hours',
|
'waiting_list_hours',
|
||||||
'waiting_list_auto',
|
'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',
|
'max_items_per_order',
|
||||||
'reservation_time',
|
'reservation_time',
|
||||||
'contact_mail',
|
'contact_mail',
|
||||||
@@ -623,6 +629,7 @@ class EventSettingsSerializer(SettingsSerializer):
|
|||||||
'frontpage_subevent_ordering',
|
'frontpage_subevent_ordering',
|
||||||
'event_list_type',
|
'event_list_type',
|
||||||
'frontpage_text',
|
'frontpage_text',
|
||||||
|
'event_info_text',
|
||||||
'attendee_names_asked',
|
'attendee_names_asked',
|
||||||
'attendee_names_required',
|
'attendee_names_required',
|
||||||
'attendee_emails_asked',
|
'attendee_emails_asked',
|
||||||
@@ -656,6 +663,7 @@ class EventSettingsSerializer(SettingsSerializer):
|
|||||||
'mail_from',
|
'mail_from',
|
||||||
'mail_from_name',
|
'mail_from_name',
|
||||||
'mail_attach_ical',
|
'mail_attach_ical',
|
||||||
|
'mail_attach_tickets',
|
||||||
'invoice_address_asked',
|
'invoice_address_asked',
|
||||||
'invoice_address_required',
|
'invoice_address_required',
|
||||||
'invoice_address_vatid',
|
'invoice_address_vatid',
|
||||||
|
|||||||
@@ -45,6 +45,14 @@ class CompatibleCountryField(serializers.Field):
|
|||||||
return instance.country_old
|
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):
|
class InvoiceAddressSerializer(I18nAwareModelSerializer):
|
||||||
country = CompatibleCountryField(source='*')
|
country = CompatibleCountryField(source='*')
|
||||||
name = serializers.CharField(required=False)
|
name = serializers.CharField(required=False)
|
||||||
@@ -1322,17 +1330,24 @@ class InlineInvoiceLineSerializer(I18nAwareModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InvoiceLine
|
model = InvoiceLine
|
||||||
fields = ('position', 'description', 'gross_value', 'tax_value', 'tax_rate', 'tax_name')
|
fields = ('position', 'description', 'item', 'variation', 'attendee_name', 'event_date_from',
|
||||||
|
'event_date_to', 'gross_value', 'tax_value', 'tax_rate', 'tax_name')
|
||||||
|
|
||||||
|
|
||||||
class InvoiceSerializer(I18nAwareModelSerializer):
|
class InvoiceSerializer(I18nAwareModelSerializer):
|
||||||
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
|
order = serializers.SlugRelatedField(slug_field='code', read_only=True)
|
||||||
refers = serializers.SlugRelatedField(slug_field='invoice_no', read_only=True)
|
refers = serializers.SlugRelatedField(slug_field='full_invoice_no', read_only=True)
|
||||||
lines = InlineInvoiceLineSerializer(many=True)
|
lines = InlineInvoiceLineSerializer(many=True)
|
||||||
|
invoice_to_country = CountryField()
|
||||||
|
invoice_from_country = CountryField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Invoice
|
model = Invoice
|
||||||
fields = ('order', 'number', 'is_cancellation', 'invoice_from', 'invoice_to', 'date', 'refers', 'locale',
|
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',
|
||||||
'introductory_text', 'additional_text', 'payment_provider_text', 'footer_text', 'lines',
|
'introductory_text', 'additional_text', 'payment_provider_text', 'footer_text', 'lines',
|
||||||
'foreign_currency_display', 'foreign_currency_rate', 'foreign_currency_rate_date',
|
'foreign_currency_display', 'foreign_currency_rate', 'foreign_currency_rate_date',
|
||||||
'internal_reference')
|
'internal_reference')
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class WaitingListSerializer(I18nAwareModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = WaitingListEntry
|
model = WaitingListEntry
|
||||||
fields = ('id', 'created', 'email', 'voucher', 'item', 'variation', 'locale', 'subevent', 'priority')
|
fields = ('id', 'created', 'name', 'name_parts', 'email', 'phone', 'voucher', 'item', 'variation', 'locale', 'subevent', 'priority')
|
||||||
read_only_fields = ('id', 'created', 'voucher')
|
read_only_fields = ('id', 'created', 'voucher')
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
@@ -32,4 +32,11 @@ class WaitingListSerializer(I18nAwareModelSerializer):
|
|||||||
if availability[0] == 100:
|
if availability[0] == 100:
|
||||||
raise ValidationError("This product is currently available.")
|
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
|
return data
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ from pretix.api.models import ApiCall, WebHookCall
|
|||||||
from pretix.base.signals import periodic_task
|
from pretix.base.signals import periodic_task
|
||||||
from pretix.helpers.periodic import minimum_interval
|
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
|
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
|
instance of a subclass of pretix.api.webhooks.WebhookEvent or a list of such
|
||||||
|
|||||||
+29
-27
@@ -1,7 +1,7 @@
|
|||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, re_path
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
from pretix.api.views import cart
|
from pretix.api.views import cart
|
||||||
@@ -72,30 +72,32 @@ for app in apps.get_app_configs():
|
|||||||
importlib.import_module(app.name + '.urls')
|
importlib.import_module(app.name + '.urls')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^', include(router.urls)),
|
re_path(r'^', include(router.urls)),
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/', include(orga_router.urls)),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/', include(orga_router.urls)),
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/settings/$', organizer.OrganizerSettingsView.as_view(),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/settings/$', organizer.OrganizerSettingsView.as_view(),
|
||||||
name="organizer.settings"),
|
name="organizer.settings"),
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/giftcards/(?P<giftcard>[^/]+)/', include(giftcard_router.urls)),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/giftcards/(?P<giftcard>[^/]+)/', include(giftcard_router.urls)),
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/settings/$', event.EventSettingsView.as_view(),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/settings/$', event.EventSettingsView.as_view(),
|
||||||
name="event.settings"),
|
name="event.settings"),
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/', include(event_router.urls)),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/', include(event_router.urls)),
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/teams/(?P<team>[^/]+)/', include(team_router.urls)),
|
re_path(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)),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/items/(?P<item>[^/]+)/',
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/questions/(?P<question>[^/]+)/',
|
include(item_router.urls)),
|
||||||
include(question_router.urls)),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/questions/(?P<question>[^/]+)/',
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/checkinlists/(?P<list>[^/]+)/',
|
include(question_router.urls)),
|
||||||
include(checkinlist_router.urls)),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/checkinlists/(?P<list>[^/]+)/',
|
||||||
url(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/orders/(?P<order>[^/]+)/', include(order_router.urls)),
|
include(checkinlist_router.urls)),
|
||||||
url(r"^oauth/authorize$", oauth.AuthorizationView.as_view(), name="authorize"),
|
re_path(r'^organizers/(?P<organizer>[^/]+)/events/(?P<event>[^/]+)/orders/(?P<order>[^/]+)/',
|
||||||
url(r"^oauth/token$", oauth.TokenView.as_view(), name="token"),
|
include(order_router.urls)),
|
||||||
url(r"^oauth/revoke_token$", oauth.RevokeTokenView.as_view(), name="revoke-token"),
|
re_path(r"^oauth/authorize$", oauth.AuthorizationView.as_view(), name="authorize"),
|
||||||
url(r"^device/initialize$", device.InitializeView.as_view(), name="device.initialize"),
|
re_path(r"^oauth/token$", oauth.TokenView.as_view(), name="token"),
|
||||||
url(r"^device/update$", device.UpdateView.as_view(), name="device.update"),
|
re_path(r"^oauth/revoke_token$", oauth.RevokeTokenView.as_view(), name="revoke-token"),
|
||||||
url(r"^device/roll$", device.RollKeyView.as_view(), name="device.roll"),
|
re_path(r"^device/initialize$", device.InitializeView.as_view(), name="device.initialize"),
|
||||||
url(r"^device/revoke$", device.RevokeKeyView.as_view(), name="device.revoke"),
|
re_path(r"^device/update$", device.UpdateView.as_view(), name="device.update"),
|
||||||
url(r"^device/eventselection$", device.EventSelectionView.as_view(), name="device.eventselection"),
|
re_path(r"^device/roll$", device.RollKeyView.as_view(), name="device.roll"),
|
||||||
url(r"^upload$", upload.UploadView.as_view(), name="upload"),
|
re_path(r"^device/revoke$", device.RevokeKeyView.as_view(), name="device.revoke"),
|
||||||
url(r"^me$", user.MeView.as_view(), name="user.me"),
|
re_path(r"^device/eventselection$", device.EventSelectionView.as_view(), name="device.eventselection"),
|
||||||
url(r"^version$", version.VersionView.as_view(), name="version"),
|
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"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ import inspect
|
|||||||
import logging
|
import logging
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from itertools import groupby
|
||||||
from smtplib import SMTPResponseException
|
from smtplib import SMTPResponseException
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.mail.backends.smtp import EmailBackend
|
from django.core.mail.backends.smtp import EmailBackend
|
||||||
|
from django.db.models import Count
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@@ -128,9 +130,21 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
|
|||||||
|
|
||||||
if order:
|
if order:
|
||||||
htmlctx['order'] = 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:
|
if position:
|
||||||
htmlctx['position'] = position
|
htmlctx['position'] = position
|
||||||
|
htmlctx['ev'] = position.subevent or self.event
|
||||||
|
|
||||||
tpl = get_template(self.template_name)
|
tpl = get_template(self.template_name)
|
||||||
body_html = inline_css(tpl.render(htmlctx))
|
body_html = inline_css(tpl.render(htmlctx))
|
||||||
@@ -237,6 +251,8 @@ def get_email_context(**kwargs):
|
|||||||
from pretix.base.models import InvoiceAddress
|
from pretix.base.models import InvoiceAddress
|
||||||
|
|
||||||
event = kwargs['event']
|
event = kwargs['event']
|
||||||
|
if 'position' in kwargs:
|
||||||
|
kwargs.setdefault("position_or_address", kwargs['position'])
|
||||||
if 'order' in kwargs:
|
if 'order' in kwargs:
|
||||||
try:
|
try:
|
||||||
kwargs['invoice_address'] = kwargs['order'].invoice_address
|
kwargs['invoice_address'] = kwargs['order'].invoice_address
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from ...control.forms.filter import get_all_payment_providers
|
|||||||
from ...helpers import GroupConcat
|
from ...helpers import GroupConcat
|
||||||
from ...helpers.iter import chunked_iterable
|
from ...helpers.iter import chunked_iterable
|
||||||
from ..exporter import BaseExporter, MultiSheetListExporter
|
from ..exporter import BaseExporter, MultiSheetListExporter
|
||||||
|
from ..services.export import ExportError
|
||||||
from ..services.invoices import invoice_pdf_task
|
from ..services.invoices import invoice_pdf_task
|
||||||
from ..signals import (
|
from ..signals import (
|
||||||
register_data_exporters, register_multievent_data_exporters,
|
register_data_exporters, register_multievent_data_exporters,
|
||||||
@@ -111,6 +112,8 @@ class InvoiceExporter(InvoiceExporterMixin, BaseExporter):
|
|||||||
if not i.file:
|
if not i.file:
|
||||||
invoice_pdf_task.apply(args=(i.pk,))
|
invoice_pdf_task.apply(args=(i.pk,))
|
||||||
i.refresh_from_db()
|
i.refresh_from_db()
|
||||||
|
if not i.file:
|
||||||
|
raise ExportError('Could not generate PDF for invoice {nr}'.format(nr=i.full_invoice_no))
|
||||||
i.file.open('rb')
|
i.file.open('rb')
|
||||||
zipf.writestr('{}-{}.pdf'.format(i.number, i.order.code), i.file.read())
|
zipf.writestr('{}-{}.pdf'.format(i.number, i.order.code), i.file.read())
|
||||||
i.file.close()
|
i.file.close()
|
||||||
|
|||||||
@@ -691,13 +691,18 @@ class QuotaListExporter(ListExporter):
|
|||||||
verbose_name = gettext_lazy('Quota availabilities')
|
verbose_name = gettext_lazy('Quota availabilities')
|
||||||
|
|
||||||
def iterate_list(self, form_data):
|
def iterate_list(self, form_data):
|
||||||
|
has_subevents = self.event.has_subevents
|
||||||
headers = [
|
headers = [
|
||||||
_('Quota name'), _('Total quota'), _('Paid orders'), _('Pending orders'), _('Blocking vouchers'),
|
_('Quota name'), _('Total quota'), _('Paid orders'), _('Pending orders'), _('Blocking vouchers'),
|
||||||
_('Current user\'s carts'), _('Waiting list'), _('Exited orders'), _('Current availability')
|
_('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
|
yield headers
|
||||||
|
|
||||||
quotas = list(self.event.quotas.all())
|
quotas = list(self.event.quotas.select_related('subevent'))
|
||||||
qa = QuotaAvailability(full_results=True)
|
qa = QuotaAvailability(full_results=True)
|
||||||
qa.queue(*quotas)
|
qa.queue(*quotas)
|
||||||
qa.compute()
|
qa.compute()
|
||||||
@@ -715,6 +720,18 @@ class QuotaListExporter(ListExporter):
|
|||||||
qa.count_exited_orders[quota],
|
qa.count_exited_orders[quota],
|
||||||
_('Infinite') if avail[1] is None else avail[1]
|
_('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
|
yield row
|
||||||
|
|
||||||
def get_filename(self):
|
def get_filename(self):
|
||||||
|
|||||||
@@ -82,7 +82,9 @@ class WaitingListExporter(ListExporter):
|
|||||||
|
|
||||||
headers = [
|
headers = [
|
||||||
_('Date'),
|
_('Date'),
|
||||||
|
_('Name'),
|
||||||
_('Email'),
|
_('Email'),
|
||||||
|
_('Phone number'),
|
||||||
_('Product name'),
|
_('Product name'),
|
||||||
_('Variation'),
|
_('Variation'),
|
||||||
_('Event slug'),
|
_('Event slug'),
|
||||||
@@ -117,7 +119,9 @@ class WaitingListExporter(ListExporter):
|
|||||||
|
|
||||||
row = [
|
row = [
|
||||||
entry.created.astimezone(tz).strftime(datetime_format), # alternative: .isoformat(),
|
entry.created.astimezone(tz).strftime(datetime_format), # alternative: .isoformat(),
|
||||||
|
entry.name,
|
||||||
entry.email,
|
entry.email,
|
||||||
|
entry.phone,
|
||||||
str(entry.item) if entry.item else "",
|
str(entry.item) if entry.item else "",
|
||||||
str(entry.variation) if entry.variation else "",
|
str(entry.variation) if entry.variation else "",
|
||||||
entry.event.slug,
|
entry.event.slug,
|
||||||
|
|||||||
@@ -255,8 +255,10 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
invoice_from_top = 17 * mm
|
invoice_from_top = 17 * mm
|
||||||
|
|
||||||
def _draw_invoice_from(self, canvas):
|
def _draw_invoice_from(self, canvas):
|
||||||
p = Paragraph(self.invoice.full_invoice_from.strip().replace('\n', '<br />\n'), style=self.stylesheet[
|
p = Paragraph(
|
||||||
'InvoiceFrom'])
|
bleach.clean(self.invoice.full_invoice_from, tags=[]).strip().replace('\n', '<br />\n'),
|
||||||
|
style=self.stylesheet['InvoiceFrom']
|
||||||
|
)
|
||||||
p.wrapOn(canvas, self.invoice_from_width, self.invoice_from_height)
|
p.wrapOn(canvas, self.invoice_from_width, self.invoice_from_height)
|
||||||
p_size = p.wrap(self.invoice_from_width, self.invoice_from_height)
|
p_size = p.wrap(self.invoice_from_width, self.invoice_from_height)
|
||||||
p.drawOn(canvas, self.invoice_from_left, self.pagesize[1] - p_size[1] - self.invoice_from_top)
|
p.drawOn(canvas, self.invoice_from_left, self.pagesize[1] - p_size[1] - self.invoice_from_top)
|
||||||
@@ -361,6 +363,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
def _draw_event(self, canvas):
|
def _draw_event(self, canvas):
|
||||||
def shorten(txt):
|
def shorten(txt):
|
||||||
txt = str(txt)
|
txt = str(txt)
|
||||||
|
txt = bleach.clean(txt, tags=[]).strip()
|
||||||
p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
|
p = Paragraph(txt.strip().replace('\n', '<br />\n'), style=self.stylesheet['Normal'])
|
||||||
p_size = p.wrap(self.event_width, self.event_height)
|
p_size = p.wrap(self.event_width, self.event_height)
|
||||||
|
|
||||||
@@ -441,13 +444,18 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
story = []
|
story = []
|
||||||
if self.invoice.custom_field:
|
if self.invoice.custom_field:
|
||||||
story.append(Paragraph(
|
story.append(Paragraph(
|
||||||
'{}: {}'.format(self.invoice.event.settings.invoice_address_custom_field, self.invoice.custom_field),
|
'{}: {}'.format(
|
||||||
|
bleach.clean(self.invoice.event.settings.invoice_address_custom_field, tags=[]).strip().replace('\n', '<br />\n'),
|
||||||
|
bleach.clean(self.invoice.custom_field, tags=[]).strip().replace('\n', '<br />\n'),
|
||||||
|
),
|
||||||
self.stylesheet['Normal']
|
self.stylesheet['Normal']
|
||||||
))
|
))
|
||||||
|
|
||||||
if self.invoice.internal_reference:
|
if self.invoice.internal_reference:
|
||||||
story.append(Paragraph(
|
story.append(Paragraph(
|
||||||
pgettext('invoice', 'Customer reference: {reference}').format(reference=self.invoice.internal_reference),
|
pgettext('invoice', 'Customer reference: {reference}').format(
|
||||||
|
reference=bleach.clean(self.invoice.internal_reference, tags=[]).strip().replace('\n', '<br />\n'),
|
||||||
|
),
|
||||||
self.stylesheet['Normal']
|
self.stylesheet['Normal']
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -466,7 +474,10 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
))
|
))
|
||||||
|
|
||||||
if self.invoice.introductory_text:
|
if self.invoice.introductory_text:
|
||||||
story.append(Paragraph(self.invoice.introductory_text, self.stylesheet['Normal']))
|
story.append(Paragraph(
|
||||||
|
self.invoice.introductory_text,
|
||||||
|
self.stylesheet['Normal']
|
||||||
|
))
|
||||||
story.append(Spacer(1, 10 * mm))
|
story.append(Spacer(1, 10 * mm))
|
||||||
|
|
||||||
return story
|
return story
|
||||||
@@ -566,10 +577,16 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
story.append(Spacer(1, 15 * mm))
|
story.append(Spacer(1, 15 * mm))
|
||||||
|
|
||||||
if self.invoice.payment_provider_text:
|
if self.invoice.payment_provider_text:
|
||||||
story.append(Paragraph(self.invoice.payment_provider_text, self.stylesheet['Normal']))
|
story.append(Paragraph(
|
||||||
|
self.invoice.payment_provider_text,
|
||||||
|
self.stylesheet['Normal']
|
||||||
|
))
|
||||||
|
|
||||||
if self.invoice.additional_text:
|
if self.invoice.additional_text:
|
||||||
story.append(Paragraph(self.invoice.additional_text, self.stylesheet['Normal']))
|
story.append(Paragraph(
|
||||||
|
self.invoice.additional_text,
|
||||||
|
self.stylesheet['Normal']
|
||||||
|
))
|
||||||
story.append(Spacer(1, 15 * mm))
|
story.append(Spacer(1, 15 * mm))
|
||||||
|
|
||||||
tstyledata = [
|
tstyledata = [
|
||||||
@@ -701,7 +718,10 @@ class Modern1Renderer(ClassicInvoiceRenderer):
|
|||||||
def _draw_invoice_from(self, canvas):
|
def _draw_invoice_from(self, canvas):
|
||||||
if not self.invoice.invoice_from:
|
if not self.invoice.invoice_from:
|
||||||
return
|
return
|
||||||
c = self.invoice.address_invoice_from.strip().split('\n')
|
c = [
|
||||||
|
bleach.clean(l, tags=[]).strip().replace('\n', '<br />\n')
|
||||||
|
for l in self.invoice.address_invoice_from.strip().split('\n')
|
||||||
|
]
|
||||||
p = Paragraph(' · '.join(c), style=self.stylesheet['Sender'])
|
p = Paragraph(' · '.join(c), style=self.stylesheet['Sender'])
|
||||||
p.wrapOn(canvas, self.invoice_to_width, 15.7 * mm)
|
p.wrapOn(canvas, self.invoice_to_width, 15.7 * mm)
|
||||||
p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - self.invoice_to_top + 2 * mm)
|
p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - self.invoice_to_top + 2 * mm)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ class Command(BaseCommand):
|
|||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
parser.add_argument('--tasks', action='store', type=str, help='Only execute the tasks with this name '
|
parser.add_argument('--tasks', action='store', type=str, help='Only execute the tasks with this name '
|
||||||
'(dotted path, comma separation)')
|
'(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):
|
def handle(self, *args, **options):
|
||||||
verbosity = int(options['verbosity'])
|
verbosity = int(options['verbosity'])
|
||||||
@@ -28,6 +30,9 @@ class Command(BaseCommand):
|
|||||||
if options.get('tasks'):
|
if options.get('tasks'):
|
||||||
if name not in options.get('tasks').split(','):
|
if name not in options.get('tasks').split(','):
|
||||||
continue
|
continue
|
||||||
|
if options.get('exclude'):
|
||||||
|
if name in options.get('exclude').split(','):
|
||||||
|
continue
|
||||||
|
|
||||||
if verbosity > 1:
|
if verbosity > 1:
|
||||||
self.stdout.write(f'INFO Running {name}…')
|
self.stdout.write(f'INFO Running {name}…')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Generated by Django 2.1 on 2018-10-17 00:24
|
# Generated by Django 2.1 on 2018-10-17 00:24
|
||||||
|
|
||||||
import jsonfallback.fields
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
from django_mysql.checks import mysql_connections
|
from django_mysql.checks import mysql_connections
|
||||||
@@ -77,19 +77,19 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='cartposition',
|
model_name='cartposition',
|
||||||
name='attendee_name_parts',
|
name='attendee_name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(null=False, default=dict),
|
field=models.JSONField(null=False, default=dict),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='orderposition',
|
model_name='orderposition',
|
||||||
name='attendee_name_parts',
|
name='attendee_name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(null=False, default=dict),
|
field=models.JSONField(null=False, default=dict),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='invoiceaddress',
|
model_name='invoiceaddress',
|
||||||
name='name_parts',
|
name='name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
),
|
||||||
migrations.RunPython(set_attendee_name_parts, migrations.RunPython.noop)
|
migrations.RunPython(set_attendee_name_parts, migrations.RunPython.noop)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.1 on 2018-11-21 12:24
|
# Generated by Django 2.1.1 on 2018-11-21 12:24
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import django.db.models.manager
|
import django.db.models.manager
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1 on 2019-01-12 15:12
|
# Generated by Django 2.1 on 2019-01-12 15:12
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.5 on 2019-01-29 13:37
|
# Generated by Django 2.1.5 on 2019-01-29 13:37
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.5 on 2019-02-01 15:27
|
# Generated by Django 2.1.5 on 2019-02-01 15:27
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
+3
-4
@@ -3,7 +3,6 @@
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
@@ -190,7 +189,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cartposition',
|
model_name='cartposition',
|
||||||
name='attendee_name_parts',
|
name='attendee_name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cartposition',
|
model_name='cartposition',
|
||||||
@@ -210,7 +209,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='invoiceaddress',
|
model_name='invoiceaddress',
|
||||||
name='name_parts',
|
name='name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='item',
|
model_name='item',
|
||||||
@@ -225,7 +224,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='orderposition',
|
model_name='orderposition',
|
||||||
name='attendee_name_parts',
|
name='attendee_name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='orderposition',
|
model_name='orderposition',
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1 on 2019-02-08 14:32
|
# Generated by Django 2.1 on 2019-02-08 14:32
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.5 on 2019-02-19 12:45
|
# Generated by Django 2.1.5 on 2019-02-19 12:45
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.5 on 2019-02-19 09:49
|
# Generated by Django 2.1.5 on 2019-02-19 09:49
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.5 on 2019-03-12 09:42
|
# Generated by Django 2.1.5 on 2019-03-12 09:42
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.7 on 2019-03-16 10:14
|
# Generated by Django 2.1.7 on 2019-03-16 10:14
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.1.5 on 2019-04-02 07:22
|
# Generated by Django 2.1.5 on 2019-04-02 07:22
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.2 on 2019-04-23 08:39
|
# Generated by Django 2.2 on 2019-04-23 08:39
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.2 on 2019-05-09 06:54
|
# Generated by Django 2.2 on 2019-05-09 06:54
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.2 on 2019-05-09 07:36
|
# Generated by Django 2.2 on 2019-05-09 07:36
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.base.models.fields
|
import pretix.base.models.fields
|
||||||
@@ -17,7 +16,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cartposition',
|
model_name='cartposition',
|
||||||
name='attendee_name_parts',
|
name='attendee_name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='cartposition',
|
model_name='cartposition',
|
||||||
@@ -37,7 +36,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='invoiceaddress',
|
model_name='invoiceaddress',
|
||||||
name='name_parts',
|
name='name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='item',
|
model_name='item',
|
||||||
@@ -52,7 +51,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='orderposition',
|
model_name='orderposition',
|
||||||
name='attendee_name_parts',
|
name='attendee_name_parts',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='orderposition',
|
model_name='orderposition',
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import django_countries.fields
|
import django_countries.fields
|
||||||
import jsonfallback.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import pretix.helpers.countries
|
import pretix.helpers.countries
|
||||||
@@ -43,7 +42,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='checkinlist',
|
model_name='checkinlist',
|
||||||
name='rules',
|
name='rules',
|
||||||
field=jsonfallback.fields.FallbackJSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterUniqueTogether(
|
migrations.AlterUniqueTogether(
|
||||||
name='checkin',
|
name='checkin',
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# 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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
# 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,7 +4,6 @@ from django.db.models import Exists, F, Max, OuterRef, Q, Subquery
|
|||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||||
from django_scopes import ScopedManager, scopes_disabled
|
from django_scopes import ScopedManager, scopes_disabled
|
||||||
from jsonfallback.fields import FallbackJSONField
|
|
||||||
|
|
||||||
from pretix.base.models import LoggedModel
|
from pretix.base.models import LoggedModel
|
||||||
from pretix.base.models.fields import MultiStringField
|
from pretix.base.models.fields import MultiStringField
|
||||||
@@ -47,7 +46,7 @@ class CheckinList(LoggedModel):
|
|||||||
'any of the selected sales channels. This option can be useful when tickets sold at the box office '
|
'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.')
|
'are not checked again before entry and should be considered validated directly upon purchase.')
|
||||||
)
|
)
|
||||||
rules = FallbackJSONField(default=dict, blank=True)
|
rules = models.JSONField(default=dict, blank=True)
|
||||||
|
|
||||||
objects = ScopedManager(organizer='event__organizer')
|
objects = ScopedManager(organizer='event__organizer')
|
||||||
|
|
||||||
|
|||||||
@@ -697,9 +697,9 @@ class Event(EventMixin, LoggedModel):
|
|||||||
for k, v in rules.items():
|
for k, v in rules.items():
|
||||||
if k == 'lookup':
|
if k == 'lookup':
|
||||||
if v[0] == 'product':
|
if v[0] == 'product':
|
||||||
v[1] = str(item_map.get(int(v[1]), 0).pk)
|
v[1] = str(item_map.get(int(v[1]), 0).pk) if int(v[1]) in item_map else "0"
|
||||||
elif v[0] == 'variation':
|
elif v[0] == 'variation':
|
||||||
v[1] = str(variation_map.get(int(v[1]), 0).pk)
|
v[1] = str(variation_map.get(int(v[1]), 0).pk) if int(v[1]) in variation_map else "0"
|
||||||
else:
|
else:
|
||||||
_walk_rules(v)
|
_walk_rules(v)
|
||||||
elif isinstance(rules, list):
|
elif isinstance(rules, list):
|
||||||
|
|||||||
@@ -273,6 +273,14 @@ class InvoiceLine(models.Model):
|
|||||||
:type subevent: SubEvent
|
:type subevent: SubEvent
|
||||||
:param event_date_from: Event date of the (sub)event at the time the invoice was created
|
:param event_date_from: Event date of the (sub)event at the time the invoice was created
|
||||||
:type event_date_from: datetime
|
: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)
|
invoice = models.ForeignKey('Invoice', related_name='lines', on_delete=models.CASCADE)
|
||||||
position = models.PositiveIntegerField(default=0)
|
position = models.PositiveIntegerField(default=0)
|
||||||
@@ -283,6 +291,10 @@ class InvoiceLine(models.Model):
|
|||||||
tax_name = models.CharField(max_length=190)
|
tax_name = models.CharField(max_length=190)
|
||||||
subevent = models.ForeignKey('SubEvent', null=True, blank=True, on_delete=models.PROTECT)
|
subevent = models.ForeignKey('SubEvent', null=True, blank=True, on_delete=models.PROTECT)
|
||||||
event_date_from = models.DateTimeField(null=True)
|
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
|
@property
|
||||||
def net_value(self):
|
def net_value(self):
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
|||||||
from django_countries.fields import Country
|
from django_countries.fields import Country
|
||||||
from django_scopes import ScopedManager, scopes_disabled
|
from django_scopes import ScopedManager, scopes_disabled
|
||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
from jsonfallback.fields import FallbackJSONField
|
|
||||||
from phonenumber_field.modelfields import PhoneNumberField
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
from phonenumber_field.phonenumber import PhoneNumber
|
from phonenumber_field.phonenumber import PhoneNumber
|
||||||
from phonenumbers import NumberParseException
|
from phonenumbers import NumberParseException
|
||||||
@@ -1132,7 +1131,7 @@ class AbstractPosition(models.Model):
|
|||||||
blank=True, null=True,
|
blank=True, null=True,
|
||||||
help_text=_("Empty, if this product is not an admission ticket")
|
help_text=_("Empty, if this product is not an admission ticket")
|
||||||
)
|
)
|
||||||
attendee_name_parts = FallbackJSONField(
|
attendee_name_parts = models.JSONField(
|
||||||
blank=True, default=dict
|
blank=True, default=dict
|
||||||
)
|
)
|
||||||
attendee_email = models.EmailField(
|
attendee_email = models.EmailField(
|
||||||
@@ -2252,7 +2251,7 @@ class InvoiceAddress(models.Model):
|
|||||||
is_business = models.BooleanField(default=False, verbose_name=_('Business customer'))
|
is_business = models.BooleanField(default=False, verbose_name=_('Business customer'))
|
||||||
company = models.CharField(max_length=255, blank=True, verbose_name=_('Company name'))
|
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_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
||||||
name_parts = FallbackJSONField(default=dict)
|
name_parts = models.JSONField(default=dict)
|
||||||
street = models.TextField(verbose_name=_('Address'), blank=False)
|
street = models.TextField(verbose_name=_('Address'), blank=False)
|
||||||
zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), 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)
|
city = models.CharField(max_length=255, verbose_name=_('City'), blank=False)
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ from django.db import models, transaction
|
|||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||||
from django_scopes import ScopedManager
|
from django_scopes import ScopedManager
|
||||||
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
|
|
||||||
from pretix.base.email import get_email_context
|
from pretix.base.email import get_email_context
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.base.models import Voucher
|
from pretix.base.models import Voucher
|
||||||
from pretix.base.services.mail import mail
|
from pretix.base.services.mail import mail
|
||||||
|
from pretix.base.settings import PERSON_NAME_SCHEMES
|
||||||
|
|
||||||
from .base import LoggedModel
|
from .base import LoggedModel
|
||||||
from .event import Event, SubEvent
|
from .event import Event, SubEvent
|
||||||
@@ -37,9 +39,21 @@ class WaitingListEntry(LoggedModel):
|
|||||||
verbose_name=_("On waiting list since"),
|
verbose_name=_("On waiting list since"),
|
||||||
auto_now_add=True
|
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(
|
email = models.EmailField(
|
||||||
verbose_name=_("E-mail address")
|
verbose_name=_("E-mail address")
|
||||||
)
|
)
|
||||||
|
phone = PhoneNumberField(
|
||||||
|
null=True, blank=True,
|
||||||
|
verbose_name=_("Phone number")
|
||||||
|
)
|
||||||
voucher = models.ForeignKey(
|
voucher = models.ForeignKey(
|
||||||
'Voucher',
|
'Voucher',
|
||||||
verbose_name=_("Assigned voucher"),
|
verbose_name=_("Assigned voucher"),
|
||||||
@@ -83,6 +97,27 @@ class WaitingListEntry(LoggedModel):
|
|||||||
WaitingListEntry.clean_itemvar(self.event, self.item, self.variation)
|
WaitingListEntry.clean_itemvar(self.event, self.item, self.variation)
|
||||||
WaitingListEntry.clean_subevent(self.event, self.subevent)
|
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):
|
def send_voucher(self, quota_cache=None, user=None, auth=None):
|
||||||
availability = (
|
availability = (
|
||||||
self.variation.check_quotas(count_waitinglist=False, subevent=self.subevent, _cache=quota_cache)
|
self.variation.check_quotas(count_waitinglist=False, subevent=self.subevent, _cache=quota_cache)
|
||||||
|
|||||||
+13
-10
@@ -970,17 +970,17 @@ class ManualPayment(BasePaymentProvider):
|
|||||||
label=_('Payment process description in order confirmation emails'),
|
label=_('Payment process description in order confirmation emails'),
|
||||||
help_text=_('This text will be included for the {payment_info} placeholder in order confirmation '
|
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 '
|
'mails. It should instruct the user on how to proceed with the payment. You can use '
|
||||||
'the placeholders {order}, {total}, {currency} and {total_with_currency}.'),
|
'the placeholders {order}, {amount}, {currency} and {amount_with_currency}.'),
|
||||||
widget=I18nTextarea,
|
widget=I18nTextarea,
|
||||||
validators=[PlaceholderValidator(['{order}', '{total}', '{currency}', '{total_with_currency}'])],
|
validators=[PlaceholderValidator(['{order}', '{amount}', '{currency}', '{amount_with_currency}'])],
|
||||||
)),
|
)),
|
||||||
('pending_description', I18nFormField(
|
('pending_description', I18nFormField(
|
||||||
label=_('Payment process description for pending orders'),
|
label=_('Payment process description for pending orders'),
|
||||||
help_text=_('This text will be shown on the order confirmation page 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 '
|
'It should instruct the user on how to proceed with the payment. You can use '
|
||||||
'the placeholders {order}, {total}, {currency} and {total_with_currency}.'),
|
'the placeholders {order}, {amount}, {currency} and {amount_with_currency}.'),
|
||||||
widget=I18nTextarea,
|
widget=I18nTextarea,
|
||||||
validators=[PlaceholderValidator(['{order}', '{total}', '{currency}', '{total_with_currency}'])],
|
validators=[PlaceholderValidator(['{order}', '{amount}', '{currency}', '{amount_with_currency}'])],
|
||||||
)),
|
)),
|
||||||
] + list(super().settings_form_fields.items())
|
] + list(super().settings_form_fields.items())
|
||||||
)
|
)
|
||||||
@@ -1001,21 +1001,24 @@ class ManualPayment(BasePaymentProvider):
|
|||||||
def checkout_confirm_render(self, request):
|
def checkout_confirm_render(self, request):
|
||||||
return self.payment_form_render(request)
|
return self.payment_form_render(request)
|
||||||
|
|
||||||
def format_map(self, order):
|
def format_map(self, order, payment):
|
||||||
return {
|
return {
|
||||||
'order': order.code,
|
'order': order.code,
|
||||||
'total': order.total,
|
'amount': payment.amount,
|
||||||
'currency': self.event.currency,
|
'currency': self.event.currency,
|
||||||
'total_with_currency': money_filter(order.total, 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),
|
||||||
}
|
}
|
||||||
|
|
||||||
def order_pending_mail_render(self, order) -> str:
|
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))
|
msg = str(self.settings.get('email_instructions', as_type=LazyI18nString)).format_map(self.format_map(order, payment))
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def payment_pending_render(self, request, payment) -> str:
|
def payment_pending_render(self, request, payment) -> str:
|
||||||
return rich_text(
|
return rich_text(
|
||||||
str(self.settings.get('pending_description', as_type=LazyI18nString)).format_map(self.format_map(payment.order))
|
str(self.settings.get('pending_description', as_type=LazyI18nString)).format_map(self.format_map(payment.order, payment))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -298,6 +298,11 @@ DEFAULT_VARIABLES = OrderedDict((
|
|||||||
"editor_sample": _("Event organizer info text"),
|
"editor_sample": _("Event organizer info text"),
|
||||||
"evaluate": lambda op, order, ev: str(order.event.settings.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", {
|
("now_date", {
|
||||||
"label": _("Printing date"),
|
"label": _("Printing date"),
|
||||||
"editor_sample": _("2017-05-31"),
|
"editor_sample": _("2017-05-31"),
|
||||||
|
|||||||
@@ -171,9 +171,17 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
if invoice.event.has_subevents:
|
if invoice.event.has_subevents:
|
||||||
desc += "<br />" + pgettext("subevent", "Date: {}").format(p.subevent)
|
desc += "<br />" + pgettext("subevent", "Date: {}").format(p.subevent)
|
||||||
InvoiceLine.objects.create(
|
InvoiceLine.objects.create(
|
||||||
position=i, invoice=invoice, description=desc,
|
position=i,
|
||||||
gross_value=p.price, tax_value=p.tax_value,
|
invoice=invoice,
|
||||||
subevent=p.subevent, event_date_from=(p.subevent.date_from if p.subevent else invoice.event.date_from),
|
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,
|
||||||
tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else ''
|
tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else ''
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -198,6 +206,8 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
invoice=invoice,
|
invoice=invoice,
|
||||||
description=fee_title,
|
description=fee_title,
|
||||||
gross_value=fee.value,
|
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_value=fee.tax_value,
|
||||||
tax_rate=fee.tax_rate,
|
tax_rate=fee.tax_rate,
|
||||||
tax_name=fee.tax_rule.name if fee.tax_rule else ''
|
tax_name=fee.tax_rule.name if fee.tax_rule else ''
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from django.core.mail import (
|
|||||||
EmailMultiAlternatives, SafeMIMEMultipart, get_connection,
|
EmailMultiAlternatives, SafeMIMEMultipart, get_connection,
|
||||||
)
|
)
|
||||||
from django.core.mail.message import SafeMIMEText
|
from django.core.mail.message import SafeMIMEText
|
||||||
|
from django.db import transaction
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.utils.translation import gettext as _, pgettext
|
from django.utils.translation import gettext as _, pgettext
|
||||||
from django_scopes import scope, scopes_disabled
|
from django_scopes import scope, scopes_disabled
|
||||||
@@ -240,7 +241,15 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
|||||||
task_chain = []
|
task_chain = []
|
||||||
|
|
||||||
task_chain.append(send_task)
|
task_chain.append(send_task)
|
||||||
chain(*task_chain).apply_async()
|
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CustomEmail(EmailMultiAlternatives):
|
class CustomEmail(EmailMultiAlternatives):
|
||||||
@@ -291,6 +300,8 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st
|
|||||||
order = None
|
order = None
|
||||||
else:
|
else:
|
||||||
with language(order.locale, event.settings.region):
|
with language(order.locale, event.settings.region):
|
||||||
|
if not event.settings.mail_attach_tickets:
|
||||||
|
attach_tickets = False
|
||||||
if position:
|
if position:
|
||||||
try:
|
try:
|
||||||
position = order.positions.get(pk=position)
|
position = order.positions.get(pk=position)
|
||||||
|
|||||||
@@ -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,
|
def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device=None, oauth_application=None,
|
||||||
cancellation_fee=None, keep_fees=None):
|
cancellation_fee=None, keep_fees=None, cancel_invoice=True):
|
||||||
"""
|
"""
|
||||||
Mark this order as canceled
|
Mark this order as canceled
|
||||||
:param order: The order to change
|
:param order: The order to change
|
||||||
@@ -351,9 +351,10 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
|||||||
if not order.cancel_allowed():
|
if not order.cancel_allowed():
|
||||||
raise OrderError(_('You cannot cancel this order.'))
|
raise OrderError(_('You cannot cancel this order.'))
|
||||||
invoices = []
|
invoices = []
|
||||||
i = order.invoices.filter(is_cancellation=False).last()
|
if cancel_invoice:
|
||||||
if i and not i.refered.exists():
|
i = order.invoices.filter(is_cancellation=False).last()
|
||||||
invoices.append(generate_cancellation(i))
|
if i and not i.refered.exists():
|
||||||
|
invoices.append(generate_cancellation(i))
|
||||||
|
|
||||||
for position in order.positions.all():
|
for position in order.positions.all():
|
||||||
for gc in position.issued_gift_cards.all():
|
for gc in position.issued_gift_cards.all():
|
||||||
@@ -403,7 +404,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
|||||||
order.cancellation_date = now()
|
order.cancellation_date = now()
|
||||||
order.save(update_fields=['status', 'cancellation_date', 'total'])
|
order.save(update_fields=['status', 'cancellation_date', 'total'])
|
||||||
|
|
||||||
if i:
|
if cancel_invoice and i:
|
||||||
invoices.append(generate_invoice(order))
|
invoices.append(generate_invoice(order))
|
||||||
else:
|
else:
|
||||||
with order.event.lock():
|
with order.event.lock():
|
||||||
@@ -2152,11 +2153,12 @@ 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,))
|
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,))
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def cancel_order(self, order: int, user: int=None, send_mail: bool=True, api_token=None, oauth_application=None,
|
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):
|
device=None, cancellation_fee=None, try_auto_refund=False, refund_as_giftcard=False, comment=None,
|
||||||
|
cancel_invoice=True):
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
ret = _cancel_order(order, user, send_mail, api_token, device, oauth_application,
|
ret = _cancel_order(order, user, send_mail, api_token, device, oauth_application,
|
||||||
cancellation_fee)
|
cancellation_fee, cancel_invoice=cancel_invoice)
|
||||||
if try_auto_refund:
|
if try_auto_refund:
|
||||||
_try_auto_refund(order, refund_as_giftcard=refund_as_giftcard,
|
_try_auto_refund(order, refund_as_giftcard=refund_as_giftcard,
|
||||||
comment=comment)
|
comment=comment)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ from django.core.validators import (
|
|||||||
MaxValueValidator, MinValueValidator, RegexValidator,
|
MaxValueValidator, MinValueValidator, RegexValidator,
|
||||||
)
|
)
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
|
from django.utils.text import format_lazy
|
||||||
from django.utils.translation import (
|
from django.utils.translation import (
|
||||||
gettext_lazy as _, gettext_noop, pgettext, pgettext_lazy,
|
gettext_lazy as _, gettext_noop, pgettext, pgettext_lazy,
|
||||||
)
|
)
|
||||||
@@ -974,6 +975,61 @@ DEFAULTS = {
|
|||||||
widget=forms.NumberInput(),
|
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': {
|
'ticket_download': {
|
||||||
'default': 'False',
|
'default': 'False',
|
||||||
'type': bool,
|
'type': bool,
|
||||||
@@ -1322,6 +1378,19 @@ DEFAULTS = {
|
|||||||
'default': 'classic',
|
'default': 'classic',
|
||||||
'type': str
|
'type': str
|
||||||
},
|
},
|
||||||
|
'mail_attach_tickets': {
|
||||||
|
'default': 'True',
|
||||||
|
'type': bool,
|
||||||
|
'form_class': forms.BooleanField,
|
||||||
|
'serializer_class': serializers.BooleanField,
|
||||||
|
'form_kwargs': dict(
|
||||||
|
label=_("Attach ticket files"),
|
||||||
|
help_text=format_lazy(
|
||||||
|
_("Tickets will never be attached if they're larger than {size} to avoid email delivery problems."),
|
||||||
|
size='4 MB'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
'mail_attach_ical': {
|
'mail_attach_ical': {
|
||||||
'default': 'False',
|
'default': 'False',
|
||||||
'type': bool,
|
'type': bool,
|
||||||
@@ -1931,6 +2000,18 @@ Your {event} team"""))
|
|||||||
widget=I18nTextarea
|
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': {
|
'banner_text': {
|
||||||
'default': '',
|
'default': '',
|
||||||
'type': LazyI18nString,
|
'type': LazyI18nString,
|
||||||
@@ -1983,6 +2064,19 @@ Your {event} team"""))
|
|||||||
"why you need information from them.")
|
"why you need information from them.")
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
'checkout_success_text': {
|
||||||
|
'default': '',
|
||||||
|
'type': LazyI18nString,
|
||||||
|
'serializer_class': I18nField,
|
||||||
|
'form_class': I18nFormField,
|
||||||
|
'form_kwargs': dict(
|
||||||
|
label=_("Additional success message"),
|
||||||
|
help_text=_("This message will be shown after an order has been created successfully. It will be shown in additional "
|
||||||
|
"to the default text."),
|
||||||
|
widget_kwargs={'attrs': {'rows': '2'}},
|
||||||
|
widget=I18nTextarea
|
||||||
|
)
|
||||||
|
},
|
||||||
'checkout_phone_helptext': {
|
'checkout_phone_helptext': {
|
||||||
'default': '',
|
'default': '',
|
||||||
'type': LazyI18nString,
|
'type': LazyI18nString,
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ class EmailAddressShredder(BaseDataShredder):
|
|||||||
class WaitingListShredder(BaseDataShredder):
|
class WaitingListShredder(BaseDataShredder):
|
||||||
verbose_name = _('Waiting list')
|
verbose_name = _('Waiting list')
|
||||||
identifier = 'waiting_list'
|
identifier = 'waiting_list'
|
||||||
description = _('This will remove all email addresses from the waiting list.')
|
description = _('This will remove all names, email addresses, and phone numbers from the waiting list.')
|
||||||
|
|
||||||
def generate_files(self) -> List[Tuple[str, str, str]]:
|
def generate_files(self) -> List[Tuple[str, str, str]]:
|
||||||
yield 'waiting-list.json', 'application/json', json.dumps([
|
yield 'waiting-list.json', 'application/json', json.dumps([
|
||||||
@@ -213,7 +213,7 @@ class WaitingListShredder(BaseDataShredder):
|
|||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def shred_data(self):
|
def shred_data(self):
|
||||||
self.event.waitinglistentries.update(email='█')
|
self.event.waitinglistentries.update(name_cached=None, name_parts={'_shredded': True}, email='█', phone='█')
|
||||||
|
|
||||||
for wle in self.event.waitinglistentries.select_related('voucher').filter(voucher__isnull=False):
|
for wle in self.event.waitinglistentries.select_related('voucher').filter(voucher__isnull=False):
|
||||||
if '@' in wle.voucher.comment:
|
if '@' in wle.voucher.comment:
|
||||||
@@ -222,7 +222,14 @@ class WaitingListShredder(BaseDataShredder):
|
|||||||
|
|
||||||
for le in self.event.logentry_set.filter(action_type="pretix.voucher.added.waitinglist").exclude(data=""):
|
for le in self.event.logentry_set.filter(action_type="pretix.voucher.added.waitinglist").exclude(data=""):
|
||||||
d = le.parsed_data
|
d = le.parsed_data
|
||||||
|
if 'name' in d:
|
||||||
|
d['name'] = '█'
|
||||||
|
if 'name_parts' in d:
|
||||||
|
d['name_parts'] = {
|
||||||
|
'_legacy': '█'
|
||||||
|
}
|
||||||
d['email'] = '█'
|
d['email'] = '█'
|
||||||
|
d['phone'] = '█'
|
||||||
le.data = json.dumps(d)
|
le.data = json.dumps(d)
|
||||||
le.shredded = True
|
le.shredded = True
|
||||||
le.save(update_fields=['data', 'shredded'])
|
le.save(update_fields=['data', 'shredded'])
|
||||||
|
|||||||
+100
-127
@@ -164,9 +164,7 @@ class DeprecatedSignal(django.dispatch.Signal):
|
|||||||
super().connect(receiver, sender=None, weak=True, dispatch_uid=None)
|
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
|
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
|
prevent the event from going live, return a string that will be displayed to the user
|
||||||
@@ -176,9 +174,7 @@ 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
|
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
|
subclass of pretix.base.payment.BasePaymentProvider or a list of these
|
||||||
@@ -186,9 +182,7 @@ 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.
|
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
|
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.
|
an instance of a subclass of pretix.base.email.BaseMailTextPlaceholder or a list of these.
|
||||||
@@ -196,9 +190,7 @@ 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.
|
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
|
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
|
subclass of pretix.base.email.BaseHTMLMailRenderer or a list of these
|
||||||
@@ -206,9 +198,7 @@ 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.
|
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
|
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
|
subclass of pretix.base.invoice.BaseInvoiceRenderer or a list of these
|
||||||
@@ -216,9 +206,7 @@ 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.
|
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
|
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
|
subclass of ``pretix.base.secrets.BaseTicketSecretGenerator`` or a list of these
|
||||||
@@ -226,9 +214,7 @@ 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.
|
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
|
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
|
subclass of pretix.base.shredder.BaseDataShredder or a list of these
|
||||||
@@ -236,9 +222,7 @@ 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.
|
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
|
This signal is sent out to get all known ticket outputs. Receivers should return a
|
||||||
subclass of pretix.base.ticketoutput.BaseTicketOutput
|
subclass of pretix.base.ticketoutput.BaseTicketOutput
|
||||||
@@ -246,9 +230,7 @@ subclass of pretix.base.ticketoutput.BaseTicketOutput
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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
|
instance of a subclass of pretix.base.notifications.NotificationType or a list of such
|
||||||
@@ -259,18 +241,14 @@ however for this signal, the ``sender`` **may also be None** to allow creating t
|
|||||||
notification settings!
|
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
|
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
|
instance of a subclass of ``pretix.base.channels.SalesChannel`` or a list of such
|
||||||
instances.
|
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
|
This signal is sent out to get all known data exporters. Receivers should return a
|
||||||
subclass of pretix.base.exporter.BaseExporter
|
subclass of pretix.base.exporter.BaseExporter
|
||||||
@@ -278,21 +256,20 @@ subclass of pretix.base.exporter.BaseExporter
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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
|
multiple events. Receivers should return a subclass of pretix.base.exporter.BaseExporter
|
||||||
|
|
||||||
The ``sender`` keyword argument will contain an organizer.
|
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
|
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,
|
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
|
but you can raise an OrderError with an appropriate exception message if you like to block
|
||||||
@@ -301,10 +278,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.
|
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
|
This signal is sent out before the user starts checkout. It includes an iterable
|
||||||
with the current CartPosition objects.
|
with the current CartPosition objects.
|
||||||
The response of receivers will be ignored, but you can raise a CartError with an
|
The response of receivers will be ignored, but you can raise a CartError with an
|
||||||
@@ -313,10 +290,10 @@ appropriate exception message.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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
|
``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
|
an argument ``addons`` containing a dict of ``(item, variation or None) → count`` tuples as well
|
||||||
@@ -328,10 +305,10 @@ appropriate exception message.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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
|
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
|
splitting an existing order, so you can not expect to see all orders by listening
|
||||||
@@ -340,10 +317,10 @@ to this signal.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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
|
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.
|
because an already-paid order has been split.
|
||||||
@@ -351,80 +328,80 @@ because an already-paid order has been split.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time an order is canceled. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time a canceled order is reactivated. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time an order is marked as expired. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time an order's information is modified. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time an order's content is changed. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time an order is being approved. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time an order is being denied. The order object is given
|
||||||
as the first argument.
|
as the first argument.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal is sent out every time a test-mode order is being deleted. The order object
|
||||||
is given as the first argument.
|
is given as the first argument.
|
||||||
|
|
||||||
@@ -435,10 +412,10 @@ the deletion of the order.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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.
|
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
|
The check-in object is given as the first argument
|
||||||
@@ -446,10 +423,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.
|
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,
|
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.
|
``pretix.base.signals.logentry_display`` will be sent out with a ``logentry`` argument.
|
||||||
|
|
||||||
@@ -459,10 +436,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.
|
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 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
|
to a human user, ``pretix.base.signals.logentry_object_link`` will be sent out with a
|
||||||
``logentry`` argument.
|
``logentry`` argument.
|
||||||
@@ -487,10 +464,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.
|
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,
|
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.
|
``pretix.base.signals.requiredaction_display`` will be sent out with a ``action`` argument.
|
||||||
You will also get the current ``request`` in a different argument.
|
You will also get the current ``request`` in a different argument.
|
||||||
@@ -501,10 +478,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.
|
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.
|
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
|
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.
|
signal to copy data or configuration stored within your plugin's models as well.
|
||||||
@@ -519,10 +496,10 @@ keyword argument will contain the event to **copy from**. The keyword arguments
|
|||||||
in the new event of the respective types.
|
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.
|
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
|
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.
|
signal to copy data or configuration stored within your plugin's models as well.
|
||||||
@@ -546,10 +523,10 @@ All plugins that are installed may send fields for the global settings form, as
|
|||||||
an OrderedDict of (setting name, form field).
|
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
|
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
|
return a list of ``OrderFee`` objects that are not yet saved to the database
|
||||||
(because there is no order yet).
|
(because there is no order yet).
|
||||||
@@ -562,10 +539,10 @@ keyword argument will contain the total cart sum without any fees. You should no
|
|||||||
the gift cards in use.
|
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``
|
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
|
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.
|
expected to return a string or None, if you don't know about this fee.
|
||||||
@@ -573,20 +550,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.
|
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,
|
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.
|
a download will not be offered.
|
||||||
|
|
||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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.
|
return a (possibly modified) copy of the message object passed to you.
|
||||||
|
|
||||||
@@ -598,10 +575,10 @@ If the email is associated with a specific user, e.g. a notification email, the
|
|||||||
well, otherwise it will be ``None``.
|
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
|
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.
|
return a (possibly modified) copy of the message object passed to you.
|
||||||
|
|
||||||
@@ -666,10 +643,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
|
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
|
``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
|
with the first entry being one of the ``Quota.AVAILABILITY_*`` constants and the second entry being
|
||||||
@@ -682,25 +659,23 @@ 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).
|
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
|
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``.
|
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
|
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``.
|
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
|
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
|
to define additional columns that can be read during import. You are expected to return a list of instances of
|
||||||
@@ -709,10 +684,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.
|
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.
|
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
|
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.
|
to raise a ``django.core.exceptions.ValidationError`` if the new state is not valid.
|
||||||
@@ -723,9 +698,7 @@ serializer field instead.
|
|||||||
As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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.
|
return a dictionary mapping names of attributes in the settings store to DRF serializer field instances.
|
||||||
|
|||||||
@@ -136,6 +136,31 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: {{ color }};
|
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 %}
|
{% if rtl %}
|
||||||
body {
|
body {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
{% 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,23 +23,7 @@
|
|||||||
<table cellpadding="20"><tr><td>
|
<table cellpadding="20"><tr><td>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{% if position %}
|
{% include "pretixbase/email/order_details.html" %}
|
||||||
{% 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>
|
</div>
|
||||||
<!--[if gte mso 9]>
|
<!--[if gte mso 9]>
|
||||||
</td></tr></table>
|
</td></tr></table>
|
||||||
|
|||||||
@@ -147,6 +147,31 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: {{ color }};
|
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 %}
|
{% if rtl %}
|
||||||
body {
|
body {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
@@ -226,23 +251,7 @@
|
|||||||
<table cellpadding="20"><tr><td>
|
<table cellpadding="20"><tr><td>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{% if position %}
|
{% include "pretixbase/email/order_details.html" %}
|
||||||
{% 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>
|
</div>
|
||||||
<!--[if gte mso 9]>
|
<!--[if gte mso 9]>
|
||||||
</td></tr></table>
|
</td></tr></table>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% load thumb %}
|
{% load thumb %}
|
||||||
{% if widget.is_initial %}{{ widget.initial_text }}: <a href="{{ widget.value.url }}">{{ widget.value }}</a>{% if not widget.required %}
|
{% 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 }}">
|
<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.value.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.name }}"><img src="{{ widget.value|thumb:"200x100" }}" /></a>{% endif %}<br>
|
||||||
{{ widget.input_text }}:{% endif %}
|
{{ widget.input_text }}:{% endif %}
|
||||||
<input type="{{ widget.type }}" name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
|
<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 %}
|
{% 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):
|
class SnippetExtension(markdown.extensions.Extension):
|
||||||
def extendMarkdown(self, md, *args, **kwargs):
|
def extendMarkdown(self, md, *args, **kwargs):
|
||||||
del md.parser.blockprocessors['olist']
|
md.parser.blockprocessors.deregister('olist')
|
||||||
del md.parser.blockprocessors['ulist']
|
md.parser.blockprocessors.deregister('ulist')
|
||||||
del md.parser.blockprocessors['quote']
|
md.parser.blockprocessors.deregister('quote')
|
||||||
|
|
||||||
|
|
||||||
def markdown_compile(source, snippet=False):
|
def markdown_compile(source, snippet=False):
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from django.core.exceptions import ValidationError
|
|||||||
from django.core.files import File
|
from django.core.files import File
|
||||||
from django.core.files.uploadedfile import UploadedFile
|
from django.core.files.uploadedfile import UploadedFile
|
||||||
from django.forms.utils import from_current_timezone
|
from django.forms.utils import from_current_timezone
|
||||||
|
from django.urls import reverse
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ class CachedFileInput(forms.ClearableFileInput):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
return self.file.file.url
|
return reverse('cachedfile.download', kwargs={'id': self.file.id})
|
||||||
|
|
||||||
def value_from_datadict(self, data, files, name):
|
def value_from_datadict(self, data, files, name):
|
||||||
from ...base.models import CachedFile
|
from ...base.models import CachedFile
|
||||||
@@ -200,6 +201,8 @@ class CachedFileField(ExtFileField):
|
|||||||
from ...base.models import CachedFile
|
from ...base.models import CachedFile
|
||||||
|
|
||||||
if isinstance(data, File):
|
if isinstance(data, File):
|
||||||
|
if hasattr(data, '_uploaded_to'):
|
||||||
|
return data._uploaded_to
|
||||||
cf = CachedFile.objects.create(
|
cf = CachedFile.objects.create(
|
||||||
expires=now() + datetime.timedelta(days=1),
|
expires=now() + datetime.timedelta(days=1),
|
||||||
date=now(),
|
date=now(),
|
||||||
@@ -209,6 +212,7 @@ class CachedFileField(ExtFileField):
|
|||||||
)
|
)
|
||||||
cf.file.save(data.name, data.file)
|
cf.file.save(data.name, data.file)
|
||||||
cf.save()
|
cf.save()
|
||||||
|
data._uploaded_to = cf
|
||||||
return cf
|
return cf
|
||||||
return super().bound_data(data, initial)
|
return super().bound_data(data, initial)
|
||||||
|
|
||||||
@@ -217,6 +221,8 @@ class CachedFileField(ExtFileField):
|
|||||||
|
|
||||||
data = super().clean(*args, **kwargs)
|
data = super().clean(*args, **kwargs)
|
||||||
if isinstance(data, File):
|
if isinstance(data, File):
|
||||||
|
if hasattr(data, '_uploaded_to'):
|
||||||
|
return data._uploaded_to
|
||||||
cf = CachedFile.objects.create(
|
cf = CachedFile.objects.create(
|
||||||
expires=now() + datetime.timedelta(days=1),
|
expires=now() + datetime.timedelta(days=1),
|
||||||
web_download=True,
|
web_download=True,
|
||||||
@@ -226,6 +232,7 @@ class CachedFileField(ExtFileField):
|
|||||||
)
|
)
|
||||||
cf.file.save(data.name, data.file)
|
cf.file.save(data.name, data.file)
|
||||||
cf.save()
|
cf.save()
|
||||||
|
data._uploaded_to = cf
|
||||||
return cf
|
return cf
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|||||||
@@ -435,6 +435,7 @@ class EventSettingsForm(SettingsForm):
|
|||||||
'checkout_email_helptext',
|
'checkout_email_helptext',
|
||||||
'presale_has_ended_text',
|
'presale_has_ended_text',
|
||||||
'voucher_explanation_text',
|
'voucher_explanation_text',
|
||||||
|
'checkout_success_text',
|
||||||
'show_dates_on_frontpage',
|
'show_dates_on_frontpage',
|
||||||
'show_date_to',
|
'show_date_to',
|
||||||
'show_times',
|
'show_times',
|
||||||
@@ -448,6 +449,11 @@ class EventSettingsForm(SettingsForm):
|
|||||||
'waiting_list_enabled',
|
'waiting_list_enabled',
|
||||||
'waiting_list_hours',
|
'waiting_list_hours',
|
||||||
'waiting_list_auto',
|
'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',
|
'max_items_per_order',
|
||||||
'reservation_time',
|
'reservation_time',
|
||||||
'contact_mail',
|
'contact_mail',
|
||||||
@@ -458,6 +464,7 @@ class EventSettingsForm(SettingsForm):
|
|||||||
'frontpage_subevent_ordering',
|
'frontpage_subevent_ordering',
|
||||||
'event_list_type',
|
'event_list_type',
|
||||||
'frontpage_text',
|
'frontpage_text',
|
||||||
|
'event_info_text',
|
||||||
'attendee_names_asked',
|
'attendee_names_asked',
|
||||||
'attendee_names_required',
|
'attendee_names_required',
|
||||||
'attendee_emails_asked',
|
'attendee_emails_asked',
|
||||||
@@ -786,6 +793,7 @@ class MailSettingsForm(SettingsForm):
|
|||||||
'mail_from',
|
'mail_from',
|
||||||
'mail_from_name',
|
'mail_from_name',
|
||||||
'mail_attach_ical',
|
'mail_attach_ical',
|
||||||
|
'mail_attach_tickets',
|
||||||
]
|
]
|
||||||
|
|
||||||
mail_sales_channel_placed_paid = forms.MultipleChoiceField(
|
mail_sales_channel_placed_paid = forms.MultipleChoiceField(
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ from urllib.parse import urlencode
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Exists, F, Max, Model, OuterRef, Q, QuerySet
|
from django.db.models import (
|
||||||
|
Count, Exists, F, Max, Model, OuterRef, Q, QuerySet,
|
||||||
|
)
|
||||||
from django.db.models.functions import Coalesce, ExtractWeekDay
|
from django.db.models.functions import Coalesce, ExtractWeekDay
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils.formats import date_format, localize
|
from django.utils.formats import date_format, localize
|
||||||
@@ -153,6 +155,7 @@ class OrderFilterForm(FilterForm):
|
|||||||
(Order.STATUS_CANCELED, _('Canceled (fully)')),
|
(Order.STATUS_CANCELED, _('Canceled (fully)')),
|
||||||
('cp', _('Canceled (fully or with paid fee)')),
|
('cp', _('Canceled (fully or with paid fee)')),
|
||||||
('rc', _('Cancellation requested')),
|
('rc', _('Cancellation requested')),
|
||||||
|
('cni', _('Fully canceled but invoice not canceled')),
|
||||||
)),
|
)),
|
||||||
(_('Payment process'), (
|
(_('Payment process'), (
|
||||||
(Order.STATUS_EXPIRED, _('Expired')),
|
(Order.STATUS_EXPIRED, _('Expired')),
|
||||||
@@ -264,6 +267,18 @@ class OrderFilterForm(FilterForm):
|
|||||||
status=Order.STATUS_PAID,
|
status=Order.STATUS_PAID,
|
||||||
pending_sum_t__gt=0
|
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':
|
elif s == 'pa':
|
||||||
qs = qs.filter(
|
qs = qs.filter(
|
||||||
status=Order.STATUS_PENDING,
|
status=Order.STATUS_PENDING,
|
||||||
|
|||||||
@@ -117,6 +117,11 @@ class CancelForm(ConfirmPaymentForm):
|
|||||||
'in your cancellation fee if you want to keep them. Please always enter a gross value, '
|
'in your cancellation fee if you want to keep them. Please always enter a gross value, '
|
||||||
'tax will be calculated automatically.'),
|
'tax will be calculated automatically.'),
|
||||||
)
|
)
|
||||||
|
cancel_invoice = forms.BooleanField(
|
||||||
|
label=_('Generate cancellation for invoice'),
|
||||||
|
initial=True,
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@@ -130,6 +135,8 @@ class CancelForm(ConfirmPaymentForm):
|
|||||||
self.fields['cancellation_fee'].max_value = prs
|
self.fields['cancellation_fee'].max_value = prs
|
||||||
else:
|
else:
|
||||||
del self.fields['cancellation_fee']
|
del self.fields['cancellation_fee']
|
||||||
|
if not self.instance.invoices.exists():
|
||||||
|
del self.fields['cancel_invoice']
|
||||||
|
|
||||||
def clean_cancellation_fee(self):
|
def clean_cancellation_fee(self):
|
||||||
val = self.cleaned_data['cancellation_fee'] or Decimal('0.00')
|
val = self.cleaned_data['cancellation_fee'] or Decimal('0.00')
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ from django.dispatch import Signal
|
|||||||
|
|
||||||
from pretix.base.signals import DeprecatedSignal, EventPluginSignal
|
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
|
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.
|
page in the backend. You are expected to return HTML.
|
||||||
@@ -12,10 +10,10 @@ page in the backend. You are expected to return HTML.
|
|||||||
The ``sender`` keyword argument will contain the request.
|
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
|
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
|
of every page in the backend. You will get the request as the keyword argument
|
||||||
``request`` and are expected to return plain HTML.
|
``request`` and are expected to return plain HTML.
|
||||||
@@ -23,10 +21,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.
|
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
|
This signal allows you to add additional views to the admin panel
|
||||||
navigation. You will get the request as a keyword argument ``request``.
|
navigation. You will get the request as a keyword argument ``request``.
|
||||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||||
@@ -48,10 +46,10 @@ in pretix.
|
|||||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
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.
|
This signal allows you to add additional views to the top navigation bar.
|
||||||
You will get the request as a keyword argument ``request``.
|
You will get the request as a keyword argument ``request``.
|
||||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||||
@@ -67,10 +65,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.
|
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
|
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``.
|
selected. You will get the request as a keyword argument ``request``.
|
||||||
Receivers are expected to return a list of dictionaries. The dictionaries
|
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||||
@@ -92,10 +90,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.
|
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.
|
This signal is sent out to include custom HTML in the top part of the the event dashboard.
|
||||||
Receivers should return HTML.
|
Receivers should return HTML.
|
||||||
|
|
||||||
@@ -103,9 +101,7 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
|||||||
An additional keyword argument ``subevent`` *can* contain a sub-event.
|
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
|
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:
|
should return a list of dictionaries, where each dictionary can have the keys:
|
||||||
@@ -120,10 +116,10 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
|||||||
An additional keyword argument ``subevent`` *can* contain a sub-event.
|
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
|
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:
|
should return a list of dictionaries, where each dictionary can have the keys:
|
||||||
|
|
||||||
@@ -136,20 +132,20 @@ should return a list of dictionaries, where each dictionary can have the keys:
|
|||||||
This is a regular django signal (no pretix event signal).
|
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.
|
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.
|
You receive the form object in the ``form`` keyword argument.
|
||||||
|
|
||||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
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.
|
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
|
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.
|
``cls`` argument so that you can inherit from it.
|
||||||
@@ -157,10 +153,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.
|
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
|
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``
|
creating and modifying vouchers. You will receive the form instance in the ``form``
|
||||||
argument and the current data state in the ``data`` argument.
|
argument and the current data state in the ``data`` argument.
|
||||||
@@ -168,28 +164,28 @@ argument and the current data state in the ``data`` argument.
|
|||||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
This signal allows you to append HTML to a Quota's detail view. You receive the
|
||||||
quota as argument in the ``quota`` keyword argument.
|
quota as argument in the ``quota`` keyword argument.
|
||||||
|
|
||||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
Deprecated signal, no longer works. We just keep the definition so old plugins don't
|
||||||
break the installation.
|
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.
|
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
|
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||||
should contain at least the keys ``label`` and ``url``. You should also return
|
should contain at least the keys ``label`` and ``url``. You should also return
|
||||||
@@ -210,30 +206,30 @@ This is a regular django signal (no pretix event signal). Receivers will be pass
|
|||||||
the keyword arguments ``organizer`` and ``request``.
|
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
|
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.
|
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
Additionally, the argument ``order`` and ``request`` are available.
|
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.
|
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.
|
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
||||||
Additionally, the argument ``order`` and ``request`` are available.
|
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.
|
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
|
Receivers are expected to return a list of dictionaries. The dictionaries
|
||||||
should contain at least the keys ``label`` and ``url``. You should also return
|
should contain at least the keys ``label`` and ``url``. You should also return
|
||||||
@@ -248,10 +244,10 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
|||||||
A second keyword argument ``request`` will contain the request object.
|
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
|
This signal is sent out to include template snippets on the settings page of an event
|
||||||
that allows generating a pretix Widget code.
|
that allows generating a pretix Widget code.
|
||||||
|
|
||||||
@@ -259,10 +255,10 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
|
|||||||
A second keyword argument ``request`` will contain the request object.
|
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
|
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
|
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
|
an instance of a form class that you bind yourself when appropriate. Your form will be executed
|
||||||
@@ -272,10 +268,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.
|
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
|
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
|
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
|
an instance of a formset class that you bind yourself when appropriate. Your formset will be
|
||||||
@@ -290,10 +286,10 @@ will be passed a ``formset`` variable with your formset.
|
|||||||
As with all plugin signals, the ``sender`` keyword argument will contain the event.
|
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
|
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
|
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
|
an instance of a form class that you bind yourself when appropriate. Your form will be executed
|
||||||
@@ -307,17 +303,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.
|
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.
|
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
|
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,
|
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
|
this is not an Event signal and will be called even if your plugin is not active. ``sender`` will contain the
|
||||||
@@ -325,10 +321,10 @@ event if the search is performed within an event, and ``None`` otherwise. The se
|
|||||||
``query``.
|
``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.
|
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
|
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
|
yourself when appropriate. Your form will be executed as part of the standard validation and rendering
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
{% bootstrap_field form.mail_from_name layout="control" %}
|
{% bootstrap_field form.mail_from_name layout="control" %}
|
||||||
{% bootstrap_field form.mail_text_signature layout="control" %}
|
{% bootstrap_field form.mail_text_signature layout="control" %}
|
||||||
{% bootstrap_field form.mail_bcc layout="control" %}
|
{% bootstrap_field form.mail_bcc layout="control" %}
|
||||||
|
{% bootstrap_field form.mail_attach_tickets layout="control" %}
|
||||||
{% bootstrap_field form.mail_attach_ical layout="control" %}
|
{% bootstrap_field form.mail_attach_ical layout="control" %}
|
||||||
{% bootstrap_field form.mail_sales_channel_placed_paid layout="control" %}
|
{% bootstrap_field form.mail_sales_channel_placed_paid layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -188,10 +188,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% bootstrap_field sform.checkout_success_text layout="control" %}
|
||||||
{% bootstrap_field sform.checkout_email_helptext layout="control" %}
|
{% bootstrap_field sform.checkout_email_helptext layout="control" %}
|
||||||
{% bootstrap_field sform.checkout_phone_helptext layout="control" %}
|
{% bootstrap_field sform.checkout_phone_helptext layout="control" %}
|
||||||
{% bootstrap_field sform.banner_text layout="control" %}
|
{% bootstrap_field sform.banner_text layout="control" %}
|
||||||
{% bootstrap_field sform.banner_text_bottom layout="control" %}
|
{% bootstrap_field sform.banner_text_bottom layout="control" %}
|
||||||
|
{% bootstrap_field sform.event_info_text layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "Shop design" %}</legend>
|
<legend>{% trans "Shop design" %}</legend>
|
||||||
@@ -247,6 +249,9 @@
|
|||||||
{% bootstrap_field sform.waiting_list_enabled layout="control" %}
|
{% bootstrap_field sform.waiting_list_enabled layout="control" %}
|
||||||
{% bootstrap_field sform.waiting_list_auto layout="control" %}
|
{% bootstrap_field sform.waiting_list_auto layout="control" %}
|
||||||
{% bootstrap_field sform.waiting_list_hours 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>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>{% trans "Item metadata" %}</legend>
|
<legend>{% trans "Item metadata" %}</legend>
|
||||||
|
|||||||
@@ -23,13 +23,16 @@
|
|||||||
<input type="hidden" name="status" value="c"/>
|
<input type="hidden" name="status" value="c"/>
|
||||||
{% bootstrap_form_errors form %}
|
{% bootstrap_form_errors form %}
|
||||||
{% bootstrap_field form.send_email layout='' %}
|
{% bootstrap_field form.send_email layout='' %}
|
||||||
|
{% if form.cancel_invoice %}
|
||||||
|
{% bootstrap_field form.cancel_invoice layout='' %}
|
||||||
|
{% endif %}
|
||||||
{% if form.cancellation_fee %}
|
{% if form.cancellation_fee %}
|
||||||
{% bootstrap_field form.cancellation_fee layout='' %}
|
{% bootstrap_field form.cancellation_fee layout='' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="row checkout-button-row">
|
<div class="row checkout-button-row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<a class="btn btn-block btn-default btn-lg"
|
<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" %}
|
{% trans "No, take me back" %}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -170,6 +170,10 @@
|
|||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ o.total|money:request.event.currency }}
|
{{ 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>
|
||||||
<td class="text-right flip">{{ o.pcnt|default_if_none:"0" }}</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>
|
<td class="text-right flip">{% include "pretixcontrol/orders/fragment_order_status.html" with order=o %}</td>
|
||||||
|
|||||||
@@ -132,7 +132,13 @@
|
|||||||
<table class="table table-condensed table-hover">
|
<table class="table table-condensed table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "User" %}</th>
|
{% 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 "Product" %}</th>
|
<th>{% trans "Product" %}</th>
|
||||||
{% if request.event.has_subevents %}
|
{% if request.event.has_subevents %}
|
||||||
<th>{% trans "Date" context "subevent" %}</th>
|
<th>{% trans "Date" context "subevent" %}</th>
|
||||||
@@ -146,7 +152,13 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for e in entries %}
|
{% for e in entries %}
|
||||||
<tr>
|
<tr>
|
||||||
|
{% if request.event.settings.waiting_list_names_asked %}
|
||||||
|
<td>{{ e.name|default:"" }}</td>
|
||||||
|
{% endif %}
|
||||||
<td>{{ e.email }}</td>
|
<td>{{ e.email }}</td>
|
||||||
|
{% if request.event.settings.waiting_list_phones_asked %}
|
||||||
|
<td>{{ e.phone|default:"" }}</td>
|
||||||
|
{% endif %}
|
||||||
<td>
|
<td>
|
||||||
{{ e.item }}
|
{{ e.item }}
|
||||||
{% if e.variation %}
|
{% if e.variation %}
|
||||||
|
|||||||
+323
-306
@@ -1,4 +1,4 @@
|
|||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, re_path
|
||||||
from django.views.generic.base import RedirectView
|
from django.views.generic.base import RedirectView
|
||||||
|
|
||||||
from pretix.control.views import (
|
from pretix.control.views import (
|
||||||
@@ -8,310 +8,327 @@ from pretix.control.views import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^logout$', auth.logout, name='auth.logout'),
|
re_path(r'^logout$', auth.logout, name='auth.logout'),
|
||||||
url(r'^login$', auth.login, name='auth.login'),
|
re_path(r'^login$', auth.login, name='auth.login'),
|
||||||
url(r'^login/2fa$', auth.Login2FAView.as_view(), name='auth.login.2fa'),
|
re_path(r'^login/2fa$', auth.Login2FAView.as_view(), name='auth.login.2fa'),
|
||||||
url(r'^register$', auth.register, name='auth.register'),
|
re_path(r'^register$', auth.register, name='auth.register'),
|
||||||
url(r'^invite/(?P<token>[a-zA-Z0-9]+)$', auth.invite, name='auth.invite'),
|
re_path(r'^invite/(?P<token>[a-zA-Z0-9]+)$', auth.invite, name='auth.invite'),
|
||||||
url(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
|
re_path(r'^forgot$', auth.Forgot.as_view(), name='auth.forgot'),
|
||||||
url(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
|
re_path(r'^forgot/recover$', auth.Recover.as_view(), name='auth.forgot.recover'),
|
||||||
url(r'^$', dashboards.user_index, name='index'),
|
re_path(r'^$', dashboards.user_index, name='index'),
|
||||||
url(r'^widgets.json$', dashboards.user_index_widgets_lazy, name='index.widgets'),
|
re_path(r'^widgets.json$', dashboards.user_index_widgets_lazy, name='index.widgets'),
|
||||||
url(r'^global/settings/$', global_settings.GlobalSettingsView.as_view(), name='global.settings'),
|
re_path(r'^global/settings/$', global_settings.GlobalSettingsView.as_view(), name='global.settings'),
|
||||||
url(r'^global/update/$', global_settings.UpdateCheckView.as_view(), name='global.update'),
|
re_path(r'^global/update/$', global_settings.UpdateCheckView.as_view(), name='global.update'),
|
||||||
url(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'),
|
re_path(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'),
|
||||||
url(r'^logdetail/$', global_settings.LogDetailView.as_view(), name='global.logdetail'),
|
re_path(r'^logdetail/$', global_settings.LogDetailView.as_view(), name='global.logdetail'),
|
||||||
url(r'^logdetail/payment/$', global_settings.PaymentDetailView.as_view(), name='global.paymentdetail'),
|
re_path(r'^logdetail/payment/$', global_settings.PaymentDetailView.as_view(), name='global.paymentdetail'),
|
||||||
url(r'^logdetail/refund/$', global_settings.RefundDetailView.as_view(), name='global.refunddetail'),
|
re_path(r'^logdetail/refund/$', global_settings.RefundDetailView.as_view(), name='global.refunddetail'),
|
||||||
url(r'^geocode/$', geo.GeoCodeView.as_view(), name='global.geocode'),
|
re_path(r'^geocode/$', geo.GeoCodeView.as_view(), name='global.geocode'),
|
||||||
url(r'^reauth/$', user.ReauthView.as_view(), name='user.reauth'),
|
re_path(r'^reauth/$', user.ReauthView.as_view(), name='user.reauth'),
|
||||||
url(r'^sudo/$', user.StartStaffSession.as_view(), name='user.sudo'),
|
re_path(r'^sudo/$', user.StartStaffSession.as_view(), name='user.sudo'),
|
||||||
url(r'^sudo/stop/$', user.StopStaffSession.as_view(), name='user.sudo.stop'),
|
re_path(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'),
|
re_path(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'),
|
re_path(r'^sudo/sessions/$', user.StaffSessionList.as_view(), name='user.sudo.list'),
|
||||||
url(r'^users/$', users.UserListView.as_view(), name='users'),
|
re_path(r'^users/$', users.UserListView.as_view(), name='users'),
|
||||||
url(r'^users/select2$', typeahead.users_select2, name='users.select2'),
|
re_path(r'^users/select2$', typeahead.users_select2, name='users.select2'),
|
||||||
url(r'^users/add$', users.UserCreateView.as_view(), name='users.add'),
|
re_path(r'^users/add$', users.UserCreateView.as_view(), name='users.add'),
|
||||||
url(r'^users/impersonate/stop', users.UserImpersonateStopView.as_view(), name='users.impersonate.stop'),
|
re_path(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'),
|
re_path(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'),
|
re_path(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'),
|
re_path(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'),
|
re_path(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'),
|
re_path(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
||||||
url(r'^settings/?$', user.UserSettings.as_view(), name='user.settings'),
|
re_path(r'^settings/?$', user.UserSettings.as_view(), name='user.settings'),
|
||||||
url(r'^settings/history/$', user.UserHistoryView.as_view(), name='user.settings.history'),
|
re_path(r'^settings/history/$', user.UserHistoryView.as_view(), name='user.settings.history'),
|
||||||
url(r'^settings/notifications/$', user.UserNotificationsEditView.as_view(), name='user.settings.notifications'),
|
re_path(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(),
|
re_path(r'^settings/notifications/off/(?P<id>\d+)/(?P<token>[^/]+)/$', user.UserNotificationsDisableView.as_view(),
|
||||||
name='user.settings.notifications.off'),
|
name='user.settings.notifications.off'),
|
||||||
url(r'^settings/oauth/authorized/$', oauth.AuthorizationListView.as_view(),
|
re_path(r'^settings/oauth/authorized/$', oauth.AuthorizationListView.as_view(),
|
||||||
name='user.settings.oauth.list'),
|
name='user.settings.oauth.list'),
|
||||||
url(r'^settings/oauth/authorized/(?P<pk>\d+)/revoke$', oauth.AuthorizationRevokeView.as_view(),
|
re_path(r'^settings/oauth/authorized/(?P<pk>\d+)/revoke$', oauth.AuthorizationRevokeView.as_view(),
|
||||||
name='user.settings.oauth.revoke'),
|
name='user.settings.oauth.revoke'),
|
||||||
url(r'^settings/oauth/apps/$', oauth.OAuthApplicationListView.as_view(),
|
re_path(r'^settings/oauth/apps/$', oauth.OAuthApplicationListView.as_view(),
|
||||||
name='user.settings.oauth.apps'),
|
name='user.settings.oauth.apps'),
|
||||||
url(r'^settings/oauth/apps/add$', oauth.OAuthApplicationRegistrationView.as_view(),
|
re_path(r'^settings/oauth/apps/add$', oauth.OAuthApplicationRegistrationView.as_view(),
|
||||||
name='user.settings.oauth.apps.register'),
|
name='user.settings.oauth.apps.register'),
|
||||||
url(r'^settings/oauth/apps/(?P<pk>\d+)/$', oauth.OAuthApplicationUpdateView.as_view(),
|
re_path(r'^settings/oauth/apps/(?P<pk>\d+)/$', oauth.OAuthApplicationUpdateView.as_view(),
|
||||||
name='user.settings.oauth.app'),
|
name='user.settings.oauth.app'),
|
||||||
url(r'^settings/oauth/apps/(?P<pk>\d+)/disable$', oauth.OAuthApplicationDeleteView.as_view(),
|
re_path(r'^settings/oauth/apps/(?P<pk>\d+)/disable$', oauth.OAuthApplicationDeleteView.as_view(),
|
||||||
name='user.settings.oauth.app.disable'),
|
name='user.settings.oauth.app.disable'),
|
||||||
url(r'^settings/oauth/apps/(?P<pk>\d+)/roll$', oauth.OAuthApplicationRollView.as_view(),
|
re_path(r'^settings/oauth/apps/(?P<pk>\d+)/roll$', oauth.OAuthApplicationRollView.as_view(),
|
||||||
name='user.settings.oauth.app.roll'),
|
name='user.settings.oauth.app.roll'),
|
||||||
url(r'^settings/2fa/$', user.User2FAMainView.as_view(), name='user.settings.2fa'),
|
re_path(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'),
|
re_path(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'),
|
re_path(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'),
|
re_path(r'^settings/2fa/disable', user.User2FADisableView.as_view(), name='user.settings.2fa.disable'),
|
||||||
url(r'^settings/2fa/regenemergency', user.User2FARegenerateEmergencyView.as_view(),
|
re_path(r'^settings/2fa/regenemergency', user.User2FARegenerateEmergencyView.as_view(),
|
||||||
name='user.settings.2fa.regenemergency'),
|
name='user.settings.2fa.regenemergency'),
|
||||||
url(r'^settings/2fa/totp/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmTOTPView.as_view(),
|
re_path(r'^settings/2fa/totp/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmTOTPView.as_view(),
|
||||||
name='user.settings.2fa.confirm.totp'),
|
name='user.settings.2fa.confirm.totp'),
|
||||||
url(r'^settings/2fa/webauthn/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmWebAuthnView.as_view(),
|
re_path(r'^settings/2fa/webauthn/(?P<device>[0-9]+)/confirm', user.User2FADeviceConfirmWebAuthnView.as_view(),
|
||||||
name='user.settings.2fa.confirm.webauthn'),
|
name='user.settings.2fa.confirm.webauthn'),
|
||||||
url(r'^settings/2fa/(?P<devicetype>[^/]+)/(?P<device>[0-9]+)/delete', user.User2FADeviceDeleteView.as_view(),
|
re_path(r'^settings/2fa/(?P<devicetype>[^/]+)/(?P<device>[0-9]+)/delete', user.User2FADeviceDeleteView.as_view(),
|
||||||
name='user.settings.2fa.delete'),
|
name='user.settings.2fa.delete'),
|
||||||
url(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'),
|
re_path(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'),
|
||||||
url(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'),
|
re_path(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'),
|
||||||
url(r'^organizers/select2$', typeahead.organizer_select2, name='organizers.select2'),
|
re_path(r'^organizers/select2$', typeahead.organizer_select2, name='organizers.select2'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/$', organizer.OrganizerDetail.as_view(), name='organizer'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/$', organizer.OrganizerDetail.as_view(), name='organizer'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/edit$', organizer.OrganizerUpdate.as_view(), name='organizer.edit'),
|
re_path(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'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/delete$', organizer.OrganizerDelete.as_view(), name='organizer.delete'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/settings/display$', organizer.OrganizerDisplaySettings.as_view(),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/settings/display$', organizer.OrganizerDisplaySettings.as_view(),
|
||||||
name='organizer.display'),
|
name='organizer.display'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/properties$', organizer.EventMetaPropertyListView.as_view(), name='organizer.properties'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/properties$', organizer.EventMetaPropertyListView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/property/add$', organizer.EventMetaPropertyCreateView.as_view(),
|
name='organizer.properties'),
|
||||||
name='organizer.property.add'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/property/add$', organizer.EventMetaPropertyCreateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/edit$', organizer.EventMetaPropertyUpdateView.as_view(),
|
name='organizer.property.add'),
|
||||||
name='organizer.property.edit'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/edit$',
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/delete$', organizer.EventMetaPropertyDeleteView.as_view(),
|
organizer.EventMetaPropertyUpdateView.as_view(),
|
||||||
name='organizer.property.delete'),
|
name='organizer.property.edit'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcards$', organizer.GiftCardListView.as_view(), name='organizer.giftcards'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/property/(?P<property>[^/]+)/delete$',
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcard/add$', organizer.GiftCardCreateView.as_view(), name='organizer.giftcard.add'),
|
organizer.EventMetaPropertyDeleteView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/$', organizer.GiftCardDetailView.as_view(), name='organizer.giftcard'),
|
name='organizer.property.delete'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/edit$', organizer.GiftCardUpdateView.as_view(),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcards$', organizer.GiftCardListView.as_view(),
|
||||||
name='organizer.giftcard.edit'),
|
name='organizer.giftcards'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/webhooks$', organizer.WebHookListView.as_view(), name='organizer.webhooks'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcard/add$', organizer.GiftCardCreateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/webhook/add$', organizer.WebHookCreateView.as_view(),
|
name='organizer.giftcard.add'),
|
||||||
name='organizer.webhook.add'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/$', organizer.GiftCardDetailView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/edit$', organizer.WebHookUpdateView.as_view(),
|
name='organizer.giftcard'),
|
||||||
name='organizer.webhook.edit'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/giftcard/(?P<giftcard>[^/]+)/edit$',
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/logs$', organizer.WebHookLogsView.as_view(),
|
organizer.GiftCardUpdateView.as_view(),
|
||||||
name='organizer.webhook.logs'),
|
name='organizer.giftcard.edit'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/devices$', organizer.DeviceListView.as_view(), name='organizer.devices'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/webhooks$', organizer.WebHookListView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/device/add$', organizer.DeviceCreateView.as_view(),
|
name='organizer.webhooks'),
|
||||||
name='organizer.device.add'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/webhook/add$', organizer.WebHookCreateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/edit$', organizer.DeviceUpdateView.as_view(),
|
name='organizer.webhook.add'),
|
||||||
name='organizer.device.edit'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/edit$', organizer.WebHookUpdateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/connect$', organizer.DeviceConnectView.as_view(),
|
name='organizer.webhook.edit'),
|
||||||
name='organizer.device.connect'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/webhook/(?P<webhook>[^/]+)/logs$', organizer.WebHookLogsView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/revoke$', organizer.DeviceRevokeView.as_view(),
|
name='organizer.webhook.logs'),
|
||||||
name='organizer.device.revoke'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/devices$', organizer.DeviceListView.as_view(), name='organizer.devices'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/logs$', organizer.DeviceLogView.as_view(),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/device/add$', organizer.DeviceCreateView.as_view(),
|
||||||
name='organizer.device.logs'),
|
name='organizer.device.add'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/gates$', organizer.GateListView.as_view(), name='organizer.gates'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/edit$', organizer.DeviceUpdateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/gate/add$', organizer.GateCreateView.as_view(), name='organizer.gate.add'),
|
name='organizer.device.edit'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/edit$', organizer.GateUpdateView.as_view(),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/connect$', organizer.DeviceConnectView.as_view(),
|
||||||
name='organizer.gate.edit'),
|
name='organizer.device.connect'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/delete$', organizer.GateDeleteView.as_view(),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/revoke$', organizer.DeviceRevokeView.as_view(),
|
||||||
name='organizer.gate.delete'),
|
name='organizer.device.revoke'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/teams$', organizer.TeamListView.as_view(), name='organizer.teams'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/device/(?P<device>[^/]+)/logs$', organizer.DeviceLogView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/team/add$', organizer.TeamCreateView.as_view(), name='organizer.team.add'),
|
name='organizer.device.logs'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/$', organizer.TeamMemberView.as_view(),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/gates$', organizer.GateListView.as_view(), name='organizer.gates'),
|
||||||
name='organizer.team'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/gate/add$', organizer.GateCreateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/edit$', organizer.TeamUpdateView.as_view(),
|
name='organizer.gate.add'),
|
||||||
name='organizer.team.edit'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/edit$', organizer.GateUpdateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/delete$', organizer.TeamDeleteView.as_view(),
|
name='organizer.gate.edit'),
|
||||||
name='organizer.team.delete'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/gate/(?P<gate>[^/]+)/delete$', organizer.GateDeleteView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/slugrng', main.SlugRNG.as_view(), name='events.add.slugrng'),
|
name='organizer.gate.delete'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/logs', organizer.LogView.as_view(), name='organizer.log'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/teams$', organizer.TeamListView.as_view(), name='organizer.teams'),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/export/$', organizer.ExportView.as_view(), name='organizer.export'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/team/add$', organizer.TeamCreateView.as_view(),
|
||||||
url(r'^organizer/(?P<organizer>[^/]+)/export/do$', organizer.ExportDoView.as_view(), name='organizer.export.do'),
|
name='organizer.team.add'),
|
||||||
url(r'^nav/typeahead/$', typeahead.nav_context_list, name='nav.typeahead'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/$', organizer.TeamMemberView.as_view(),
|
||||||
url(r'^events/$', main.EventList.as_view(), name='events'),
|
name='organizer.team'),
|
||||||
url(r'^events/add$', main.EventWizard.as_view(), name='events.add'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/edit$', organizer.TeamUpdateView.as_view(),
|
||||||
url(r'^events/typeahead/$', typeahead.event_list, name='events.typeahead'),
|
name='organizer.team.edit'),
|
||||||
url(r'^events/typeahead/meta/$', typeahead.meta_values, name='events.meta.typeahead'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/team/(?P<team>[^/]+)/delete$', organizer.TeamDeleteView.as_view(),
|
||||||
url(r'^search/orders/$', search.OrderSearch.as_view(), name='search.orders'),
|
name='organizer.team.delete'),
|
||||||
url(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
|
re_path(r'^organizer/(?P<organizer>[^/]+)/slugrng', main.SlugRNG.as_view(), name='events.add.slugrng'),
|
||||||
url(r'^$', dashboards.event_index, name='event.index'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/logs', organizer.LogView.as_view(), name='organizer.log'),
|
||||||
url(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/export/$', organizer.ExportView.as_view(), name='organizer.export'),
|
||||||
url(r'^live/$', event.EventLive.as_view(), name='event.live'),
|
re_path(r'^organizer/(?P<organizer>[^/]+)/export/do$', organizer.ExportDoView.as_view(),
|
||||||
url(r'^logs/$', event.EventLog.as_view(), name='event.log'),
|
name='organizer.export.do'),
|
||||||
url(r'^delete/$', event.EventDelete.as_view(), name='event.delete'),
|
re_path(r'^nav/typeahead/$', typeahead.nav_context_list, name='nav.typeahead'),
|
||||||
url(r'^requiredactions/$', event.EventActions.as_view(), name='event.requiredactions'),
|
re_path(r'^events/$', main.EventList.as_view(), name='events'),
|
||||||
url(r'^requiredactions/(?P<id>\d+)/discard$', event.EventActionDiscard.as_view(),
|
re_path(r'^events/add$', main.EventWizard.as_view(), name='events.add'),
|
||||||
name='event.requiredaction.discard'),
|
re_path(r'^events/typeahead/$', typeahead.event_list, name='events.typeahead'),
|
||||||
url(r'^comment/$', event.EventComment.as_view(),
|
re_path(r'^events/typeahead/meta/$', typeahead.meta_values, name='events.meta.typeahead'),
|
||||||
name='event.comment'),
|
re_path(r'^search/orders/$', search.OrderSearch.as_view(), name='search.orders'),
|
||||||
url(r'^quickstart/$', event.QuickSetupView.as_view(), name='event.quick'),
|
re_path(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
|
||||||
url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
re_path(r'^$', dashboards.event_index, name='event.index'),
|
||||||
url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
re_path(r'^widgets.json$', dashboards.event_index_widgets_lazy, name='event.index.widgets'),
|
||||||
url(r'^settings/payment/(?P<provider>[^/]+)$', event.PaymentProviderSettings.as_view(),
|
re_path(r'^live/$', event.EventLive.as_view(), name='event.live'),
|
||||||
name='event.settings.payment.provider'),
|
re_path(r'^logs/$', event.EventLog.as_view(), name='event.log'),
|
||||||
url(r'^settings/payment$', event.PaymentSettings.as_view(), name='event.settings.payment'),
|
re_path(r'^delete/$', event.EventDelete.as_view(), name='event.delete'),
|
||||||
url(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'),
|
re_path(r'^requiredactions/$', event.EventActions.as_view(), name='event.requiredactions'),
|
||||||
url(r'^settings/tickets/preview/(?P<output>[^/]+)$', event.TicketSettingsPreview.as_view(),
|
re_path(r'^requiredactions/(?P<id>\d+)/discard$', event.EventActionDiscard.as_view(),
|
||||||
name='event.settings.tickets.preview'),
|
name='event.requiredaction.discard'),
|
||||||
url(r'^settings/email$', event.MailSettings.as_view(), name='event.settings.mail'),
|
re_path(r'^comment/$', event.EventComment.as_view(),
|
||||||
url(r'^settings/email/preview$', event.MailSettingsPreview.as_view(), name='event.settings.mail.preview'),
|
name='event.comment'),
|
||||||
url(r'^settings/email/layoutpreview$', event.MailSettingsRendererPreview.as_view(),
|
re_path(r'^quickstart/$', event.QuickSetupView.as_view(), name='event.quick'),
|
||||||
name='event.settings.mail.preview.layout'),
|
re_path(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
||||||
url(r'^settings/cancel', event.CancelSettings.as_view(), name='event.settings.cancel'),
|
re_path(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
||||||
url(r'^settings/invoice$', event.InvoiceSettings.as_view(), name='event.settings.invoice'),
|
re_path(r'^settings/payment/(?P<provider>[^/]+)$', event.PaymentProviderSettings.as_view(),
|
||||||
url(r'^settings/invoice/preview$', event.InvoicePreview.as_view(), name='event.settings.invoice.preview'),
|
name='event.settings.payment.provider'),
|
||||||
url(r'^settings/display', event.DisplaySettings.as_view(), name='event.settings.display'),
|
re_path(r'^settings/payment$', event.PaymentSettings.as_view(), name='event.settings.payment'),
|
||||||
url(r'^settings/tax/$', event.TaxList.as_view(), name='event.settings.tax'),
|
re_path(r'^settings/tickets$', event.TicketSettings.as_view(), name='event.settings.tickets'),
|
||||||
url(r'^settings/tax/(?P<rule>\d+)/$', event.TaxUpdate.as_view(), name='event.settings.tax.edit'),
|
re_path(r'^settings/tickets/preview/(?P<output>[^/]+)$', event.TicketSettingsPreview.as_view(),
|
||||||
url(r'^settings/tax/add$', event.TaxCreate.as_view(), name='event.settings.tax.add'),
|
name='event.settings.tickets.preview'),
|
||||||
url(r'^settings/tax/(?P<rule>\d+)/delete$', event.TaxDelete.as_view(), name='event.settings.tax.delete'),
|
re_path(r'^settings/email$', event.MailSettings.as_view(), name='event.settings.mail'),
|
||||||
url(r'^settings/widget$', event.WidgetSettings.as_view(), name='event.settings.widget'),
|
re_path(r'^settings/email/preview$', event.MailSettingsPreview.as_view(), name='event.settings.mail.preview'),
|
||||||
url(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
re_path(r'^settings/email/layoutpreview$', event.MailSettingsRendererPreview.as_view(),
|
||||||
url(r'^pdf/editor/(?P<filename>[^/]+).pdf$', pdf.PdfView.as_view(), name='pdf.background'),
|
name='event.settings.mail.preview.layout'),
|
||||||
url(r'^subevents/$', subevents.SubEventList.as_view(), name='event.subevents'),
|
re_path(r'^settings/cancel', event.CancelSettings.as_view(), name='event.settings.cancel'),
|
||||||
url(r'^subevents/select2$', typeahead.subevent_select2, name='event.subevents.select2'),
|
re_path(r'^settings/invoice$', event.InvoiceSettings.as_view(), name='event.settings.invoice'),
|
||||||
url(r'^subevents/(?P<subevent>\d+)/$', subevents.SubEventUpdate.as_view(), name='event.subevent'),
|
re_path(r'^settings/invoice/preview$', event.InvoicePreview.as_view(), name='event.settings.invoice.preview'),
|
||||||
url(r'^subevents/(?P<subevent>\d+)/delete$', subevents.SubEventDelete.as_view(),
|
re_path(r'^settings/display', event.DisplaySettings.as_view(), name='event.settings.display'),
|
||||||
name='event.subevent.delete'),
|
re_path(r'^settings/tax/$', event.TaxList.as_view(), name='event.settings.tax'),
|
||||||
url(r'^subevents/add$', subevents.SubEventCreate.as_view(), name='event.subevents.add'),
|
re_path(r'^settings/tax/(?P<rule>\d+)/$', event.TaxUpdate.as_view(), name='event.settings.tax.edit'),
|
||||||
url(r'^subevents/bulk_add$', subevents.SubEventBulkCreate.as_view(), name='event.subevents.bulk'),
|
re_path(r'^settings/tax/add$', event.TaxCreate.as_view(), name='event.settings.tax.add'),
|
||||||
url(r'^subevents/bulk_action$', subevents.SubEventBulkAction.as_view(), name='event.subevents.bulkaction'),
|
re_path(r'^settings/tax/(?P<rule>\d+)/delete$', event.TaxDelete.as_view(), name='event.settings.tax.delete'),
|
||||||
url(r'^subevents/bulk_edit$', subevents.SubEventBulkEdit.as_view(), name='event.subevents.bulkedit'),
|
re_path(r'^settings/widget$', event.WidgetSettings.as_view(), name='event.settings.widget'),
|
||||||
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
re_path(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'),
|
||||||
url(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),
|
re_path(r'^pdf/editor/(?P<filename>[^/]+).pdf$', pdf.PdfView.as_view(), name='pdf.background'),
|
||||||
url(r'^items/(?P<item>\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
re_path(r'^subevents/$', subevents.SubEventList.as_view(), name='event.subevents'),
|
||||||
url(r'^items/(?P<item>\d+)/up$', item.item_move_up, name='event.items.up'),
|
re_path(r'^subevents/select2$', typeahead.subevent_select2, name='event.subevents.select2'),
|
||||||
url(r'^items/(?P<item>\d+)/down$', item.item_move_down, name='event.items.down'),
|
re_path(r'^subevents/(?P<subevent>\d+)/$', subevents.SubEventUpdate.as_view(), name='event.subevent'),
|
||||||
url(r'^items/(?P<item>\d+)/delete$', item.ItemDelete.as_view(), name='event.items.delete'),
|
re_path(r'^subevents/(?P<subevent>\d+)/delete$', subevents.SubEventDelete.as_view(),
|
||||||
url(r'^items/typeahead/meta/$', typeahead.item_meta_values, name='event.items.meta.typeahead'),
|
name='event.subevent.delete'),
|
||||||
url(r'^items/select2$', typeahead.items_select2, name='event.items.select2'),
|
re_path(r'^subevents/add$', subevents.SubEventCreate.as_view(), name='event.subevents.add'),
|
||||||
url(r'^items/select2/variation$', typeahead.variations_select2, name='event.items.variations.select2'),
|
re_path(r'^subevents/bulk_add$', subevents.SubEventBulkCreate.as_view(), name='event.subevents.bulk'),
|
||||||
url(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
|
re_path(r'^subevents/bulk_action$', subevents.SubEventBulkAction.as_view(), name='event.subevents.bulkaction'),
|
||||||
url(r'^categories/select2$', typeahead.category_select2, name='event.items.categories.select2'),
|
re_path(r'^subevents/bulk_edit$', subevents.SubEventBulkEdit.as_view(), name='event.subevents.bulkedit'),
|
||||||
url(r'^categories/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(),
|
re_path(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
||||||
name='event.items.categories.delete'),
|
re_path(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),
|
||||||
url(r'^categories/(?P<category>\d+)/up$', item.category_move_up, name='event.items.categories.up'),
|
re_path(r'^items/(?P<item>\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
||||||
url(r'^categories/(?P<category>\d+)/down$', item.category_move_down,
|
re_path(r'^items/(?P<item>\d+)/up$', item.item_move_up, name='event.items.up'),
|
||||||
name='event.items.categories.down'),
|
re_path(r'^items/(?P<item>\d+)/down$', item.item_move_down, name='event.items.down'),
|
||||||
url(r'^categories/(?P<category>\d+)/$', item.CategoryUpdate.as_view(),
|
re_path(r'^items/(?P<item>\d+)/delete$', item.ItemDelete.as_view(), name='event.items.delete'),
|
||||||
name='event.items.categories.edit'),
|
re_path(r'^items/typeahead/meta/$', typeahead.item_meta_values, name='event.items.meta.typeahead'),
|
||||||
url(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
|
re_path(r'^items/select2$', typeahead.items_select2, name='event.items.select2'),
|
||||||
url(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'),
|
re_path(r'^items/select2/variation$', typeahead.variations_select2, name='event.items.variations.select2'),
|
||||||
url(r'^questions/reorder$', item.reorder_questions, name='event.items.questions.reorder'),
|
re_path(r'^categories/$', item.CategoryList.as_view(), name='event.items.categories'),
|
||||||
url(r'^questions/(?P<question>\d+)/delete$', item.QuestionDelete.as_view(),
|
re_path(r'^categories/select2$', typeahead.category_select2, name='event.items.categories.select2'),
|
||||||
name='event.items.questions.delete'),
|
re_path(r'^categories/(?P<category>\d+)/delete$', item.CategoryDelete.as_view(),
|
||||||
url(r'^questions/(?P<question>\d+)/$', item.QuestionView.as_view(),
|
name='event.items.categories.delete'),
|
||||||
name='event.items.questions.show'),
|
re_path(r'^categories/(?P<category>\d+)/up$', item.category_move_up, name='event.items.categories.up'),
|
||||||
url(r'^questions/(?P<question>\d+)/change$', item.QuestionUpdate.as_view(),
|
re_path(r'^categories/(?P<category>\d+)/down$', item.category_move_down,
|
||||||
name='event.items.questions.edit'),
|
name='event.items.categories.down'),
|
||||||
url(r'^questions/add$', item.QuestionCreate.as_view(), name='event.items.questions.add'),
|
re_path(r'^categories/(?P<category>\d+)/$', item.CategoryUpdate.as_view(),
|
||||||
url(r'^quotas/$', item.QuotaList.as_view(), name='event.items.quotas'),
|
name='event.items.categories.edit'),
|
||||||
url(r'^quotas/(?P<quota>\d+)/$', item.QuotaView.as_view(), name='event.items.quotas.show'),
|
re_path(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'),
|
||||||
url(r'^quotas/select$', typeahead.quotas_select2, name='event.items.quotas.select2'),
|
re_path(r'^questions/$', item.QuestionList.as_view(), name='event.items.questions'),
|
||||||
url(r'^quotas/(?P<quota>\d+)/change$', item.QuotaUpdate.as_view(), name='event.items.quotas.edit'),
|
re_path(r'^questions/reorder$', item.reorder_questions, name='event.items.questions.reorder'),
|
||||||
url(r'^quotas/(?P<quota>\d+)/delete$', item.QuotaDelete.as_view(),
|
re_path(r'^questions/(?P<question>\d+)/delete$', item.QuestionDelete.as_view(),
|
||||||
name='event.items.quotas.delete'),
|
name='event.items.questions.delete'),
|
||||||
url(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
re_path(r'^questions/(?P<question>\d+)/$', item.QuestionView.as_view(),
|
||||||
url(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
name='event.items.questions.show'),
|
||||||
url(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
re_path(r'^questions/(?P<question>\d+)/change$', item.QuestionUpdate.as_view(),
|
||||||
url(r'^vouchers/rng$', vouchers.VoucherRNG.as_view(), name='event.vouchers.rng'),
|
name='event.items.questions.edit'),
|
||||||
url(r'^vouchers/item_select$', typeahead.itemvarquota_select2, name='event.vouchers.itemselect2'),
|
re_path(r'^questions/add$', item.QuestionCreate.as_view(), name='event.items.questions.add'),
|
||||||
url(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
re_path(r'^quotas/$', item.QuotaList.as_view(), name='event.items.quotas'),
|
||||||
url(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
|
re_path(r'^quotas/(?P<quota>\d+)/$', item.QuotaView.as_view(), name='event.items.quotas.show'),
|
||||||
name='event.voucher.delete'),
|
re_path(r'^quotas/select$', typeahead.quotas_select2, name='event.items.quotas.select2'),
|
||||||
url(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
|
re_path(r'^quotas/(?P<quota>\d+)/change$', item.QuotaUpdate.as_view(), name='event.items.quotas.edit'),
|
||||||
url(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
|
re_path(r'^quotas/(?P<quota>\d+)/delete$', item.QuotaDelete.as_view(),
|
||||||
url(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
name='event.items.quotas.delete'),
|
||||||
url(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
|
re_path(r'^quotas/add$', item.QuotaCreate.as_view(), name='event.items.quotas.add'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
re_path(r'^vouchers/$', vouchers.VoucherList.as_view(), name='event.vouchers'),
|
||||||
name='event.order.transition'),
|
re_path(r'^vouchers/tags/$', vouchers.VoucherTags.as_view(), name='event.vouchers.tags'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
|
re_path(r'^vouchers/rng$', vouchers.VoucherRNG.as_view(), name='event.vouchers.rng'),
|
||||||
name='event.order.resendlink'),
|
re_path(r'^vouchers/item_select$', typeahead.itemvarquota_select2, name='event.vouchers.itemselect2'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>\d+)/resend$', orders.OrderResendLink.as_view(),
|
re_path(r'^vouchers/(?P<voucher>\d+)/$', vouchers.VoucherUpdate.as_view(), name='event.voucher'),
|
||||||
name='event.order.resendlink'),
|
re_path(r'^vouchers/(?P<voucher>\d+)/delete$', vouchers.VoucherDelete.as_view(),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/invoice$', orders.OrderInvoiceCreate.as_view(),
|
name='event.voucher.delete'),
|
||||||
name='event.order.geninvoice'),
|
re_path(r'^vouchers/add$', vouchers.VoucherCreate.as_view(), name='event.vouchers.add'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/regenerate$', orders.OrderInvoiceRegenerate.as_view(),
|
re_path(r'^vouchers/go$', vouchers.VoucherGo.as_view(), name='event.vouchers.go'),
|
||||||
name='event.order.regeninvoice'),
|
re_path(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/reissue$', orders.OrderInvoiceReissue.as_view(),
|
re_path(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
|
||||||
name='event.order.reissueinvoice'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/download/(?P<position>\d+)/(?P<output>[^/]+)/$',
|
name='event.order.transition'),
|
||||||
orders.OrderDownload.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/resend$', orders.OrderResendLink.as_view(),
|
||||||
name='event.order.download.ticket'),
|
name='event.order.resendlink'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/answer/(?P<answer>[^/]+)/$',
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>\d+)/resend$', orders.OrderResendLink.as_view(),
|
||||||
orders.AnswerDownload.as_view(),
|
name='event.order.resendlink'),
|
||||||
name='event.order.download.answer'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/invoice$', orders.OrderInvoiceCreate.as_view(),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/checkvatid', orders.OrderCheckVATID.as_view(),
|
name='event.order.geninvoice'),
|
||||||
name='event.order.checkvatid'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/regenerate$',
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/extend$', orders.OrderExtend.as_view(),
|
orders.OrderInvoiceRegenerate.as_view(),
|
||||||
name='event.order.extend'),
|
name='event.order.regeninvoice'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/reactivate$', orders.OrderReactivate.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/invoices/(?P<id>\d+)/reissue$', orders.OrderInvoiceReissue.as_view(),
|
||||||
name='event.order.reactivate'),
|
name='event.order.reissueinvoice'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/contact$', orders.OrderContactChange.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/download/(?P<position>\d+)/(?P<output>[^/]+)/$',
|
||||||
name='event.order.contact'),
|
orders.OrderDownload.as_view(),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/locale', orders.OrderLocaleChange.as_view(),
|
name='event.order.download.ticket'),
|
||||||
name='event.order.locale'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/answer/(?P<answer>[^/]+)/$',
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/comment$', orders.OrderComment.as_view(),
|
orders.AnswerDownload.as_view(),
|
||||||
name='event.order.comment'),
|
name='event.order.download.answer'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/change$', orders.OrderChange.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/checkvatid', orders.OrderCheckVATID.as_view(),
|
||||||
name='event.order.change'),
|
name='event.order.checkvatid'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/approve', orders.OrderApprove.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/extend$', orders.OrderExtend.as_view(),
|
||||||
name='event.order.approve'),
|
name='event.order.extend'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/deny$', orders.OrderDeny.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/reactivate$', orders.OrderReactivate.as_view(),
|
||||||
name='event.order.deny'),
|
name='event.order.reactivate'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/delete$', orders.OrderDelete.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/contact$', orders.OrderContactChange.as_view(),
|
||||||
name='event.order.delete'),
|
name='event.order.contact'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/info', orders.OrderModifyInformation.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/locale', orders.OrderLocaleChange.as_view(),
|
||||||
name='event.order.info'),
|
name='event.order.locale'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/sendmail$', orders.OrderSendMail.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/comment$', orders.OrderComment.as_view(),
|
||||||
name='event.order.sendmail'),
|
name='event.order.comment'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>[0-9A-Z]+)/sendmail$', orders.OrderPositionSendMail.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/change$', orders.OrderChange.as_view(),
|
||||||
name='event.order.position.sendmail'),
|
name='event.order.change'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/mail_history$', orders.OrderEmailHistory.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/approve', orders.OrderApprove.as_view(),
|
||||||
name='event.order.mail_history'),
|
name='event.order.approve'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/cancel$', orders.OrderPaymentCancel.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/deny$', orders.OrderDeny.as_view(),
|
||||||
name='event.order.payments.cancel'),
|
name='event.order.deny'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/confirm$', orders.OrderPaymentConfirm.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/delete$', orders.OrderDelete.as_view(),
|
||||||
name='event.order.payments.confirm'),
|
name='event.order.delete'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refund$', orders.OrderRefundView.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/info', orders.OrderModifyInformation.as_view(),
|
||||||
name='event.order.refunds.start'),
|
name='event.order.info'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/cancel$', orders.OrderRefundCancel.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/sendmail$', orders.OrderSendMail.as_view(),
|
||||||
name='event.order.refunds.cancel'),
|
name='event.order.sendmail'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/process$', orders.OrderRefundProcess.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/(?P<position>[0-9A-Z]+)/sendmail$',
|
||||||
name='event.order.refunds.process'),
|
orders.OrderPositionSendMail.as_view(),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/done$', orders.OrderRefundDone.as_view(),
|
name='event.order.position.sendmail'),
|
||||||
name='event.order.refunds.done'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/mail_history$', orders.OrderEmailHistory.as_view(),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/cancellationrequests/(?P<req>\d+)/delete$',
|
name='event.order.mail_history'),
|
||||||
orders.OrderCancellationRequestDelete.as_view(),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/cancel$', orders.OrderPaymentCancel.as_view(),
|
||||||
name='event.order.cancellationrequests.delete'),
|
name='event.order.payments.cancel'),
|
||||||
url(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/payments/(?P<payment>\d+)/confirm$', orders.OrderPaymentConfirm.as_view(),
|
||||||
url(r'^invoice/(?P<invoice>[^/]+)$', orders.InvoiceDownload.as_view(),
|
name='event.order.payments.confirm'),
|
||||||
name='event.invoice.download'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refund$', orders.OrderRefundView.as_view(),
|
||||||
url(r'^orders/overview/$', orders.OverView.as_view(), name='event.orders.overview'),
|
name='event.order.refunds.start'),
|
||||||
url(r'^orders/import/$', orderimport.ImportView.as_view(), name='event.orders.import'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/cancel$', orders.OrderRefundCancel.as_view(),
|
||||||
url(r'^orders/import/(?P<file>[^/]+)/$', orderimport.ProcessView.as_view(), name='event.orders.import.process'),
|
name='event.order.refunds.cancel'),
|
||||||
url(r'^orders/export/$', orders.ExportView.as_view(), name='event.orders.export'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/process$', orders.OrderRefundProcess.as_view(),
|
||||||
url(r'^orders/export/do$', orders.ExportDoView.as_view(), name='event.orders.export.do'),
|
name='event.order.refunds.process'),
|
||||||
url(r'^orders/refunds/$', orders.RefundList.as_view(), name='event.orders.refunds'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/refunds/(?P<refund>\d+)/done$', orders.OrderRefundDone.as_view(),
|
||||||
url(r'^orders/go$', orders.OrderGo.as_view(), name='event.orders.go'),
|
name='event.order.refunds.done'),
|
||||||
url(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/cancellationrequests/(?P<req>\d+)/delete$',
|
||||||
url(r'^orders/search$', orders.OrderSearch.as_view(), name='event.orders.search'),
|
orders.OrderCancellationRequestDelete.as_view(),
|
||||||
url(r'^dangerzone/$', event.DangerZone.as_view(), name='event.dangerzone'),
|
name='event.order.cancellationrequests.delete'),
|
||||||
url(r'^cancel/$', orders.EventCancel.as_view(), name='event.cancel'),
|
re_path(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
|
||||||
url(r'^shredder/$', shredder.StartShredView.as_view(), name='event.shredder.start'),
|
re_path(r'^invoice/(?P<invoice>[^/]+)$', orders.InvoiceDownload.as_view(),
|
||||||
url(r'^shredder/export$', shredder.ShredExportView.as_view(), name='event.shredder.export'),
|
name='event.invoice.download'),
|
||||||
url(r'^shredder/download/(?P<file>[^/]+)/$', shredder.ShredDownloadView.as_view(), name='event.shredder.download'),
|
re_path(r'^orders/overview/$', orders.OverView.as_view(), name='event.orders.overview'),
|
||||||
url(r'^shredder/shred', shredder.ShredDoView.as_view(), name='event.shredder.shred'),
|
re_path(r'^orders/import/$', orderimport.ImportView.as_view(), name='event.orders.import'),
|
||||||
url(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'),
|
re_path(r'^orders/import/(?P<file>[^/]+)/$', orderimport.ProcessView.as_view(),
|
||||||
url(r'^waitinglist/auto_assign$', waitinglist.AutoAssign.as_view(), name='event.orders.waitinglist.auto'),
|
name='event.orders.import.process'),
|
||||||
url(r'^waitinglist/(?P<entry>\d+)/delete$', waitinglist.EntryDelete.as_view(),
|
re_path(r'^orders/export/$', orders.ExportView.as_view(), name='event.orders.export'),
|
||||||
name='event.orders.waitinglist.delete'),
|
re_path(r'^orders/export/do$', orders.ExportDoView.as_view(), name='event.orders.export.do'),
|
||||||
url(r'^checkinlists/$', checkin.CheckinListList.as_view(), name='event.orders.checkinlists'),
|
re_path(r'^orders/refunds/$', orders.RefundList.as_view(), name='event.orders.refunds'),
|
||||||
url(r'^checkinlists/add$', checkin.CheckinListCreate.as_view(), name='event.orders.checkinlists.add'),
|
re_path(r'^orders/go$', orders.OrderGo.as_view(), name='event.orders.go'),
|
||||||
url(r'^checkinlists/select2$', typeahead.checkinlist_select2, name='event.orders.checkinlists.select2'),
|
re_path(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
||||||
url(r'^checkinlists/(?P<list>\d+)/$', checkin.CheckInListShow.as_view(), name='event.orders.checkinlists.show'),
|
re_path(r'^orders/search$', orders.OrderSearch.as_view(), name='event.orders.search'),
|
||||||
url(r'^checkinlists/(?P<list>\d+)/change$', checkin.CheckinListUpdate.as_view(),
|
re_path(r'^dangerzone/$', event.DangerZone.as_view(), name='event.dangerzone'),
|
||||||
name='event.orders.checkinlists.edit'),
|
re_path(r'^cancel/$', orders.EventCancel.as_view(), name='event.cancel'),
|
||||||
url(r'^checkinlists/(?P<list>\d+)/delete$', checkin.CheckinListDelete.as_view(),
|
re_path(r'^shredder/$', shredder.StartShredView.as_view(), name='event.shredder.start'),
|
||||||
name='event.orders.checkinlists.delete'),
|
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'^event/(?P<organizer>[^/]+)/$', RedirectView.as_view(pattern_name='control:organizer'), name='event.organizerredirect'),
|
re_path(r'^event/(?P<organizer>[^/]+)/$', RedirectView.as_view(pattern_name='control:organizer'),
|
||||||
|
name='event.organizerredirect'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import collections
|
import collections.abc
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.core.paginator import (
|
from django.core.paginator import (
|
||||||
@@ -65,7 +65,7 @@ class PaginationMixin:
|
|||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
class LargeResultSetPage(collections.Sequence):
|
class LargeResultSetPage(collections.abc.Sequence):
|
||||||
|
|
||||||
def __init__(self, object_list, number, paginator):
|
def __init__(self, object_list, number, paginator):
|
||||||
self.object_list = object_list
|
self.object_list = object_list
|
||||||
|
|||||||
@@ -691,14 +691,14 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
|||||||
expires=now(), code="PREVIEW", total=119)
|
expires=now(), code="PREVIEW", total=119)
|
||||||
item = request.event.items.create(name=gettext("Sample product"), default_price=42.23,
|
item = request.event.items.create(name=gettext("Sample product"), default_price=42.23,
|
||||||
description=gettext("Sample product description"))
|
description=gettext("Sample product description"))
|
||||||
p = order.positions.create(item=item, attendee_name_parts={'_legacy': gettext("John Doe")},
|
order.positions.create(item=item, attendee_name_parts={'_legacy': gettext("John Doe")},
|
||||||
price=item.default_price)
|
price=item.default_price, subevent=request.event.subevents.last())
|
||||||
v = renderers[request.GET.get('renderer')].render(
|
v = renderers[request.GET.get('renderer')].render(
|
||||||
v,
|
v,
|
||||||
str(request.event.settings.mail_text_signature),
|
str(request.event.settings.mail_text_signature),
|
||||||
gettext('Your order: %(code)s') % {'code': order.code},
|
gettext('Your order: %(code)s') % {'code': order.code},
|
||||||
order,
|
order,
|
||||||
position=p
|
position=None
|
||||||
)
|
)
|
||||||
r = HttpResponse(v, content_type='text/html')
|
r = HttpResponse(v, content_type='text/html')
|
||||||
r._csp_ignore = True
|
r._csp_ignore = True
|
||||||
|
|||||||
@@ -151,6 +151,11 @@ class OrderList(OrderSearchMixin, EventPermissionRequiredMixin, PaginationMixin,
|
|||||||
s = OrderPosition.objects.filter(
|
s = OrderPosition.objects.filter(
|
||||||
order=OuterRef('pk')
|
order=OuterRef('pk')
|
||||||
).order_by().values('order').annotate(k=Count('id')).values('k')
|
).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 = {
|
annotated = {
|
||||||
o['pk']: o
|
o['pk']: o
|
||||||
for o in
|
for o in
|
||||||
@@ -158,10 +163,11 @@ class OrderList(OrderSearchMixin, EventPermissionRequiredMixin, PaginationMixin,
|
|||||||
pk__in=[o.pk for o in ctx['orders']]
|
pk__in=[o.pk for o in ctx['orders']]
|
||||||
).annotate(
|
).annotate(
|
||||||
pcnt=Subquery(s, output_field=IntegerField()),
|
pcnt=Subquery(s, output_field=IntegerField()),
|
||||||
|
icnt=Subquery(i, output_field=IntegerField()),
|
||||||
has_cancellation_request=Exists(CancellationRequest.objects.filter(order=OuterRef('pk')))
|
has_cancellation_request=Exists(CancellationRequest.objects.filter(order=OuterRef('pk')))
|
||||||
).values(
|
).values(
|
||||||
'pk', 'pcnt', 'is_overpaid', 'is_underpaid', 'is_pending_with_full_payment', 'has_external_refund',
|
'pk', 'pcnt', 'is_overpaid', 'is_underpaid', 'is_pending_with_full_payment', 'has_external_refund',
|
||||||
'has_pending_refund', 'has_cancellation_request', 'computed_payment_refund_sum'
|
'has_pending_refund', 'has_cancellation_request', 'computed_payment_refund_sum', 'icnt'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,6 +183,7 @@ class OrderList(OrderSearchMixin, EventPermissionRequiredMixin, PaginationMixin,
|
|||||||
o.has_pending_refund = annotated.get(o.pk)['has_pending_refund']
|
o.has_pending_refund = annotated.get(o.pk)['has_pending_refund']
|
||||||
o.has_cancellation_request = annotated.get(o.pk)['has_cancellation_request']
|
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.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]
|
o.sales_channel_obj = scs[o.sales_channel]
|
||||||
|
|
||||||
if ctx['page_obj'].paginator.count < 1000:
|
if ctx['page_obj'].paginator.count < 1000:
|
||||||
@@ -1134,6 +1141,7 @@ class OrderTransition(OrderView):
|
|||||||
try:
|
try:
|
||||||
cancel_order(self.order.pk, user=self.request.user,
|
cancel_order(self.order.pk, user=self.request.user,
|
||||||
send_mail=self.mark_canceled_form.cleaned_data['send_email'],
|
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'))
|
cancellation_fee=self.mark_canceled_form.cleaned_data.get('cancellation_fee'))
|
||||||
except OrderError as e:
|
except OrderError as e:
|
||||||
messages.error(self.request, str(e))
|
messages.error(self.request, str(e))
|
||||||
|
|||||||
@@ -938,6 +938,7 @@ class GiftCardListView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
|
|||||||
template_name = 'pretixcontrol/organizers/giftcards.html'
|
template_name = 'pretixcontrol/organizers/giftcards.html'
|
||||||
permission = 'can_manage_gift_cards'
|
permission = 'can_manage_gift_cards'
|
||||||
context_object_name = 'giftcards'
|
context_object_name = 'giftcards'
|
||||||
|
paginate_by = 50
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
s = GiftCardTransaction.objects.filter(
|
s = GiftCardTransaction.objects.filter(
|
||||||
|
|||||||
@@ -1184,7 +1184,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
|
|||||||
for fname in ('size', 'name', 'release_after_exit'):
|
for fname in ('size', 'name', 'release_after_exit'):
|
||||||
setattr(q, fname, f.cleaned_data.get(fname))
|
setattr(q, fname, f.cleaned_data.get(fname))
|
||||||
q.save(clear_cache=False)
|
q.save(clear_cache=False)
|
||||||
if 'itemvar' in f.changed_data:
|
if 'itemvars' in f.changed_data:
|
||||||
q.items.set(selected_items)
|
q.items.set(selected_items)
|
||||||
q.variations.set(selected_variations)
|
q.variations.set(selected_variations)
|
||||||
log_entries.append(
|
log_entries.append(
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ def subevent_select2(request, **kwargs):
|
|||||||
|
|
||||||
qs = request.event.subevents.filter(
|
qs = request.event.subevents.filter(
|
||||||
qf
|
qf
|
||||||
).order_by('-date_from')
|
).order_by('-date_from', 'name', 'pk')
|
||||||
|
|
||||||
total = qs.count()
|
total = qs.count()
|
||||||
pagesize = 20
|
pagesize = 20
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ class WaitingListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
|||||||
writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC, delimiter=",")
|
writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC, delimiter=",")
|
||||||
|
|
||||||
headers = [
|
headers = [
|
||||||
_('E-mail address'), _('Product'), _('On list since'), _('Status'), _('Voucher code'),
|
_('Name'), _('E-mail address'), _('Phone number'), _('Product'), _('On list since'), _('Status'), _('Voucher code'),
|
||||||
_('Language'), _('Priority')
|
_('Language'), _('Priority')
|
||||||
]
|
]
|
||||||
if self.request.event.has_subevents:
|
if self.request.event.has_subevents:
|
||||||
@@ -235,7 +235,9 @@ class WaitingListView(EventPermissionRequiredMixin, PaginationMixin, ListView):
|
|||||||
status = _('Waiting')
|
status = _('Waiting')
|
||||||
|
|
||||||
row = [
|
row = [
|
||||||
|
w.name,
|
||||||
w.email,
|
w.email,
|
||||||
|
w.phone,
|
||||||
prod,
|
prod,
|
||||||
w.created.isoformat(),
|
w.created.isoformat(),
|
||||||
status,
|
status,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
from django.core.files import File
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
@@ -16,7 +17,8 @@ def modelcopy(obj: models.Model):
|
|||||||
n = obj.__class__()
|
n = obj.__class__()
|
||||||
for f in obj._meta.fields:
|
for f in obj._meta.fields:
|
||||||
val = getattr(obj, f.name)
|
val = getattr(obj, f.name)
|
||||||
if isinstance(val, models.Model):
|
print(f, f.name, val)
|
||||||
|
if isinstance(val, (models.Model, File)):
|
||||||
setattr(n, f.name, copy.copy(val))
|
setattr(n, f.name, copy.copy(val))
|
||||||
else:
|
else:
|
||||||
setattr(n, f.name, copy.deepcopy(val))
|
setattr(n, f.name, copy.deepcopy(val))
|
||||||
|
|||||||
+1353
-1204
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-07-30 19:00+0000\n"
|
"PO-Revision-Date: 2020-07-30 19:00+0000\n"
|
||||||
"Last-Translator: Abdullah <abdullah.gumaijan@gmail.com>\n"
|
"Last-Translator: Abdullah <abdullah.gumaijan@gmail.com>\n"
|
||||||
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
|
|||||||
+1350
-1202
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
||||||
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
||||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
|
|||||||
+1358
-1239
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-12-14 10:00+0000\n"
|
"PO-Revision-Date: 2020-12-14 10:00+0000\n"
|
||||||
"Last-Translator: Ondřej Sokol <osokol@treesoft.cz>\n"
|
"Last-Translator: Ondřej Sokol <osokol@treesoft.cz>\n"
|
||||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
|
|||||||
+1348
-1202
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-09-15 02:00+0000\n"
|
"PO-Revision-Date: 2020-09-15 02:00+0000\n"
|
||||||
"Last-Translator: Mie Frydensbjerg <mif@aarhus.dk>\n"
|
"Last-Translator: Mie Frydensbjerg <mif@aarhus.dk>\n"
|
||||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
|
|||||||
+1332
-1209
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-08-25 02:00+0000\n"
|
"PO-Revision-Date: 2020-08-25 02:00+0000\n"
|
||||||
"Last-Translator: Dennis Lichtenthäler <lichtenthaeler@rami.io>\n"
|
"Last-Translator: Dennis Lichtenthäler <lichtenthaeler@rami.io>\n"
|
||||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"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 ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-08-25 02:00+0000\n"
|
"PO-Revision-Date: 2020-08-25 02:00+0000\n"
|
||||||
"Last-Translator: Dennis Lichtenthäler <lichtenthaeler@rami.io>\n"
|
"Last-Translator: Dennis Lichtenthäler <lichtenthaeler@rami.io>\n"
|
||||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||||
|
|||||||
+1344
-1239
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
|||||||
+1354
-1204
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
||||||
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
||||||
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
|
|||||||
+1353
-1204
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-04-27 20:00+0000\n"
|
"PO-Revision-Date: 2020-04-27 20:00+0000\n"
|
||||||
"Last-Translator: Gonzalo Gabriel Perez <zalitoar@gmail.com>\n"
|
"Last-Translator: Gonzalo Gabriel Perez <zalitoar@gmail.com>\n"
|
||||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
|
|||||||
+1338
-1205
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2021-01-20 16:10+0000\n"
|
"PO-Revision-Date: 2021-01-20 16:10+0000\n"
|
||||||
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
||||||
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
|
|||||||
+1352
-1204
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: French\n"
|
"Project-Id-Version: French\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-09-15 17:00+0000\n"
|
"PO-Revision-Date: 2020-09-15 17:00+0000\n"
|
||||||
"Last-Translator: Martin Gross <martin@pc-coholic.de>\n"
|
"Last-Translator: Martin Gross <martin@pc-coholic.de>\n"
|
||||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
|
|||||||
+1348
-1239
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-02-26 09:06+0000\n"
|
"POT-Creation-Date: 2021-03-08 16:40+0000\n"
|
||||||
"PO-Revision-Date: 2020-01-24 08:00+0000\n"
|
"PO-Revision-Date: 2020-01-24 08:00+0000\n"
|
||||||
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
|
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
|
||||||
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
|
|||||||
+1369
-1241
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