forked from CGM_Public/pretix_original
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
267bac7a9d | ||
|
|
c7b951346b | ||
|
|
d8adfdd06f |
@@ -60,14 +60,6 @@ http {
|
|||||||
deny all;
|
deny all;
|
||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
location /static/staticfiles.json {
|
|
||||||
deny all;
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
location /static/CACHE/manifest.json {
|
|
||||||
deny all;
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
location /static/ {
|
location /static/ {
|
||||||
alias /pretix/src/pretix/static.dist/;
|
alias /pretix/src/pretix/static.dist/;
|
||||||
access_log off;
|
access_log off;
|
||||||
|
|||||||
@@ -248,14 +248,6 @@ The following snippet is an example on how to configure a nginx proxy for pretix
|
|||||||
return 404;
|
return 404;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /static/staticfiles.json {
|
|
||||||
deny all;
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
location /static/CACHE/manifest.json {
|
|
||||||
deny all;
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
location /static/ {
|
location /static/ {
|
||||||
alias /var/pretix/venv/lib/python3.11/site-packages/pretix/static.dist/;
|
alias /var/pretix/venv/lib/python3.11/site-packages/pretix/static.dist/;
|
||||||
access_log off;
|
access_log off;
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ lines list of objects The actual invo
|
|||||||
├ 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")
|
||||||
├ tax_code string Codified reason for tax rate (or ``null``), see :ref:`rest-taxcodes`.
|
|
||||||
└ tax_rate decimal (string) Used tax rate
|
└ tax_rate decimal (string) Used tax rate
|
||||||
foreign_currency_display string If the invoice should also show the total and tax
|
foreign_currency_display string If the invoice should also show the total and tax
|
||||||
amount in a different currency, this contains the
|
amount in a different currency, this contains the
|
||||||
@@ -127,10 +126,6 @@ internal_reference string Customer's refe
|
|||||||
|
|
||||||
The ``event`` attribute has been added. The organizer-level endpoint has been added.
|
The ``event`` attribute has been added. The organizer-level endpoint has been added.
|
||||||
|
|
||||||
.. versionchanged:: 2024.8
|
|
||||||
|
|
||||||
The ``tax_code`` attribute has been added.
|
|
||||||
|
|
||||||
|
|
||||||
List of all invoices
|
List of all invoices
|
||||||
--------------------
|
--------------------
|
||||||
@@ -208,7 +203,6 @@ List of all invoices
|
|||||||
"gross_value": "23.00",
|
"gross_value": "23.00",
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_name": "VAT",
|
"tax_name": "VAT",
|
||||||
"tax_code": "S/standard",
|
|
||||||
"tax_rate": "0.00"
|
"tax_rate": "0.00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -348,7 +342,6 @@ Fetching individual invoices
|
|||||||
"gross_value": "23.00",
|
"gross_value": "23.00",
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_name": "VAT",
|
"tax_name": "VAT",
|
||||||
"tax_code": "S/standard",
|
|
||||||
"tax_rate": "0.00"
|
"tax_rate": "0.00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ fees list of objects List of fees in
|
|||||||
├ tax_rate decimal (string) VAT rate applied for this fee
|
├ tax_rate decimal (string) VAT rate applied for this fee
|
||||||
├ tax_value money (string) VAT included in this fee
|
├ tax_value money (string) VAT included in this fee
|
||||||
├ tax_rule integer The ID of the used tax rule (or ``null``)
|
├ tax_rule integer The ID of the used tax rule (or ``null``)
|
||||||
├ tax_code string Codified reason for tax rate (or ``null``), see :ref:`rest-taxcodes`.
|
|
||||||
└ canceled boolean Whether or not this fee has been canceled.
|
└ canceled boolean Whether or not this fee has been canceled.
|
||||||
downloads list of objects List of ticket download options for order-wise ticket
|
downloads list of objects List of ticket download options for order-wise ticket
|
||||||
downloading. This might be a multi-page PDF or a ZIP
|
downloading. This might be a multi-page PDF or a ZIP
|
||||||
@@ -160,10 +159,6 @@ cancellation_date datetime Time of order c
|
|||||||
|
|
||||||
The ``cancellation_date`` attribute has been added and can also be used as an ordering key.
|
The ``cancellation_date`` attribute has been added and can also be used as an ordering key.
|
||||||
|
|
||||||
.. versionchanged:: 2025.1
|
|
||||||
|
|
||||||
The ``tax_code`` attribute has been added.
|
|
||||||
|
|
||||||
.. _order-position-resource:
|
.. _order-position-resource:
|
||||||
|
|
||||||
Order position resource
|
Order position resource
|
||||||
@@ -200,7 +195,6 @@ voucher_budget_use money (string) Amount of money
|
|||||||
are changed *after* the order was created. Can be ``null``.
|
are changed *after* the order was created. Can be ``null``.
|
||||||
tax_rate decimal (string) VAT rate applied for this position
|
tax_rate decimal (string) VAT rate applied for this position
|
||||||
tax_value money (string) VAT included in this position
|
tax_value money (string) VAT included in this position
|
||||||
tax_code string Codified reason for tax rate (or ``null``), see :ref:`rest-taxcodes`.
|
|
||||||
tax_rule integer The ID of the used tax rule (or ``null``)
|
tax_rule integer The ID of the used tax rule (or ``null``)
|
||||||
secret string Secret code printed on the tickets for validation
|
secret string Secret code printed on the tickets for validation
|
||||||
addon_to integer Internal ID of the position this position is an add-on for (or ``null``)
|
addon_to integer Internal ID of the position this position is an add-on for (or ``null``)
|
||||||
@@ -261,10 +255,6 @@ pdf_data object Data object req
|
|||||||
|
|
||||||
The attribute ``print_logs`` has been added.
|
The attribute ``print_logs`` has been added.
|
||||||
|
|
||||||
.. versionchanged:: 2025.1
|
|
||||||
|
|
||||||
The ``tax_code`` attribute has been added.
|
|
||||||
|
|
||||||
.. _order-payment-resource:
|
.. _order-payment-resource:
|
||||||
|
|
||||||
Order payment resource
|
Order payment resource
|
||||||
@@ -416,7 +406,6 @@ List of all orders
|
|||||||
"tax_rate": "0.00",
|
"tax_rate": "0.00",
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_rule": null,
|
"tax_rule": null,
|
||||||
"tax_code": null,
|
|
||||||
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
||||||
"addon_to": null,
|
"addon_to": null,
|
||||||
"subevent": null,
|
"subevent": null,
|
||||||
@@ -656,7 +645,6 @@ Fetching individual orders
|
|||||||
"tax_rate": "0.00",
|
"tax_rate": "0.00",
|
||||||
"tax_rule": null,
|
"tax_rule": null,
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_code": null,
|
|
||||||
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
||||||
"addon_to": null,
|
"addon_to": null,
|
||||||
"subevent": null,
|
"subevent": null,
|
||||||
@@ -855,7 +843,7 @@ Generating new secrets
|
|||||||
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/regenerate_secrets/
|
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orders/(code)/regenerate_secrets/
|
||||||
|
|
||||||
Triggers generation of new ``secret`` and ``ẁeb_secret`` attributes for both the order and all order positions.
|
Triggers generation of new ``secret`` attributes for both the order and all order positions.
|
||||||
|
|
||||||
**Example request**:
|
**Example request**:
|
||||||
|
|
||||||
@@ -886,7 +874,7 @@ Generating new secrets
|
|||||||
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/regenerate_secrets/
|
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/orderpositions/(id)/regenerate_secrets/
|
||||||
|
|
||||||
Triggers generation of a new ``secret`` and ``web_secret`` attribute for a single order position.
|
Triggers generation of a new ``secret`` attribute for a single order position.
|
||||||
|
|
||||||
**Example request**:
|
**Example request**:
|
||||||
|
|
||||||
@@ -1625,7 +1613,6 @@ List of all order positions
|
|||||||
"tax_rate": "0.00",
|
"tax_rate": "0.00",
|
||||||
"tax_rule": null,
|
"tax_rule": null,
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_code": null,
|
|
||||||
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
||||||
"discount": null,
|
"discount": null,
|
||||||
"pseudonymization_id": "MQLJvANO3B",
|
"pseudonymization_id": "MQLJvANO3B",
|
||||||
@@ -1752,7 +1739,6 @@ Fetching individual positions
|
|||||||
"tax_rate": "0.00",
|
"tax_rate": "0.00",
|
||||||
"tax_rule": null,
|
"tax_rule": null,
|
||||||
"tax_value": "0.00",
|
"tax_value": "0.00",
|
||||||
"tax_code": null,
|
|
||||||
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
"secret": "z3fsn8jyufm5kpk768q69gkbyr5f4h6w",
|
||||||
"addon_to": null,
|
"addon_to": null,
|
||||||
"subevent": null,
|
"subevent": null,
|
||||||
|
|||||||
+1
-112
@@ -249,7 +249,7 @@ Endpoints
|
|||||||
"orderposition": null,
|
"orderposition": null,
|
||||||
"cartposition": null,
|
"cartposition": null,
|
||||||
"voucher": null
|
"voucher": null
|
||||||
}
|
},
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to modify
|
:param organizer: The ``slug`` field of the organizer to modify
|
||||||
:param event: The ``slug`` field of the event to modify
|
:param event: The ``slug`` field of the event to modify
|
||||||
@@ -260,114 +260,3 @@ Endpoints
|
|||||||
:statuscode 401: Authentication failure
|
:statuscode 401: Authentication failure
|
||||||
:statuscode 403: The requested organizer or event does not exist **or** you have no permission to change this resource.
|
:statuscode 403: The requested organizer or event does not exist **or** you have no permission to change this resource.
|
||||||
:statuscode 404: Seat does not exist; or the endpoint without subevent id was used for event with subevents, or vice versa.
|
:statuscode 404: Seat does not exist; or the endpoint without subevent id was used for event with subevents, or vice versa.
|
||||||
|
|
||||||
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/seats/bulk_block/
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/subevents/(id)/seats/bulk_block/
|
|
||||||
|
|
||||||
Set the ``blocked`` attribute to ``true`` for a large number of seats at once.
|
|
||||||
You can pass either a list of ``id`` values or a list of ``seat_guid`` values.
|
|
||||||
You can pass up to 10,000 seats in one request.
|
|
||||||
|
|
||||||
The endpoint will return an error if you pass a seat ID that does not exist.
|
|
||||||
However, it will not return an error if one of the passed seats is already blocked or sold.
|
|
||||||
|
|
||||||
**Example request**:
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
PATCH /api/v1/organizers/bigevents/events/sampleconf/seats/bulk_block/ HTTP/1.1
|
|
||||||
Host: pretix.eu
|
|
||||||
Accept: application/json, text/javascript
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"ids": [12, 45, 56]
|
|
||||||
}
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
PATCH /api/v1/organizers/bigevents/events/sampleconf/seats/bulk_block/ HTTP/1.1
|
|
||||||
Host: pretix.eu
|
|
||||||
Accept: application/json, text/javascript
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"seat_guids": ["6c0e29e5-05d6-421f-99f3-afd01478ecad", "c2899340-e2e7-4d05-8100-000a4b6d7cf4"]
|
|
||||||
}
|
|
||||||
|
|
||||||
**Example response**:
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
|
||||||
Vary: Accept
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{}
|
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to modify
|
|
||||||
:param event: The ``slug`` field of the event to modify
|
|
||||||
:param subevent_id: The ``id`` field of the subevent to modify
|
|
||||||
:statuscode 200: no error
|
|
||||||
:statuscode 400: The seat could not be modified due to invalid submitted data
|
|
||||||
:statuscode 401: Authentication failure
|
|
||||||
:statuscode 403: The requested organizer or event does not exist **or** you have no permission to change this resource.
|
|
||||||
:statuscode 404: Seat does not exist; or the endpoint without subevent id was used for event with subevents, or vice versa.
|
|
||||||
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/seats/bulk_unblock/
|
|
||||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/subevents/(id)/seats/bulk_unblock/
|
|
||||||
|
|
||||||
Set the ``blocked`` attribute to ``false`` for a large number of seats at once.
|
|
||||||
You can pass either a list of ``id`` values or a list of ``seat_guid`` values.
|
|
||||||
You can pass up to 10,000 seats in one request.
|
|
||||||
|
|
||||||
The endpoint will return an error if you pass a seat ID that does not exist.
|
|
||||||
However, it will not return an error if one of the passed seat is already unblocked or is sold.
|
|
||||||
|
|
||||||
**Example request**:
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
PATCH /api/v1/organizers/bigevents/events/sampleconf/seats/bulk_unblock/ HTTP/1.1
|
|
||||||
Host: pretix.eu
|
|
||||||
Accept: application/json, text/javascript
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"ids": [12, 45, 56]
|
|
||||||
}
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
PATCH /api/v1/organizers/bigevents/events/sampleconf/seats/bulk_unblock/ HTTP/1.1
|
|
||||||
Host: pretix.eu
|
|
||||||
Accept: application/json, text/javascript
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{
|
|
||||||
"seat_guids": ["6c0e29e5-05d6-421f-99f3-afd01478ecad", "c2899340-e2e7-4d05-8100-000a4b6d7cf4"]
|
|
||||||
}
|
|
||||||
|
|
||||||
**Example response**:
|
|
||||||
|
|
||||||
.. sourcecode:: http
|
|
||||||
|
|
||||||
HTTP/1.1 200 OK
|
|
||||||
Vary: Accept
|
|
||||||
Content-Type: application/json
|
|
||||||
|
|
||||||
{}
|
|
||||||
|
|
||||||
:param organizer: The ``slug`` field of the organizer to modify
|
|
||||||
:param event: The ``slug`` field of the event to modify
|
|
||||||
:param subevent_id: The ``id`` field of the subevent to modify
|
|
||||||
:statuscode 200: no error
|
|
||||||
:statuscode 400: The seat could not be modified due to invalid submitted data
|
|
||||||
:statuscode 401: Authentication failure
|
|
||||||
:statuscode 403: The requested organizer or event does not exist **or** you have no permission to change this resource.
|
|
||||||
:statuscode 404: Seat does not exist; or the endpoint without subevent id was used for event with subevents, or vice versa.
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
.. spelling:word-list::
|
|
||||||
|
|
||||||
EN16931
|
|
||||||
DSFinV-K
|
|
||||||
|
|
||||||
.. _rest-taxrules:
|
.. _rest-taxrules:
|
||||||
|
|
||||||
Tax rules
|
Tax rules
|
||||||
@@ -23,7 +18,6 @@ id integer Internal ID of
|
|||||||
name multi-lingual string The tax rules' name
|
name multi-lingual string The tax rules' name
|
||||||
internal_name string An optional name that is only used in the backend
|
internal_name string An optional name that is only used in the backend
|
||||||
rate decimal (string) Tax rate in percent
|
rate decimal (string) Tax rate in percent
|
||||||
code string Codified reason for tax rate (or ``null``), see :ref:`rest-taxcodes`.
|
|
||||||
price_includes_tax boolean If ``true`` (default), tax is assumed to be included in
|
price_includes_tax boolean If ``true`` (default), tax is assumed to be included in
|
||||||
the specified product price
|
the specified product price
|
||||||
eu_reverse_charge boolean **DEPRECATED**. If ``true``, EU reverse charge rules
|
eu_reverse_charge boolean **DEPRECATED**. If ``true``, EU reverse charge rules
|
||||||
@@ -48,42 +42,6 @@ custom_rules object Dynamic rules s
|
|||||||
|
|
||||||
The ``custom_rules`` attribute has been added.
|
The ``custom_rules`` attribute has been added.
|
||||||
|
|
||||||
.. versionchanged:: 2023.8
|
|
||||||
|
|
||||||
The ``code`` attribute has been added.
|
|
||||||
|
|
||||||
.. _rest-taxcodes:
|
|
||||||
|
|
||||||
Tax codes
|
|
||||||
---------
|
|
||||||
|
|
||||||
For integration with external systems, such as electronic invoicing or bookkeeping systems, the tax rate itself is often
|
|
||||||
not sufficient information. For example, there could be many different reasons why a sale has a tax rate of 0 %, but the
|
|
||||||
external handling of the transaction depends on which reason applies. Therefore, pretix allows to supply a codified
|
|
||||||
reason that allows us to understand what the specific legal situation is. These tax codes are modeled after a combination
|
|
||||||
of the code lists from the European standard EN16931 and the German standard DSFinV-K.
|
|
||||||
|
|
||||||
The following codes are supported:
|
|
||||||
|
|
||||||
- ``S/standard`` -- Standard VAT rate in the merchant country
|
|
||||||
- ``S/reduced`` -- Reduced VAT rate in the merchant country
|
|
||||||
- ``S/averaged`` -- Averaged VAT rate in the merchant country (known use case: agricultural businesses in Germany)
|
|
||||||
- ``AE`` -- Reverse charge
|
|
||||||
- ``O`` -- Services outside of scope of tax
|
|
||||||
- ``E`` -- Exempt from tax (no reason given)
|
|
||||||
- ``E/<reason>`` -- Exempt from tax, where ``<reason>`` is one of the codes listed in the `VATEX code list`_ version 5.0.
|
|
||||||
- ``Z`` -- Zero-rated goods
|
|
||||||
- ``G`` -- Free export item, VAT not charged
|
|
||||||
- ``K`` -- VAT exempt for EEA intra-community supply of goods and services
|
|
||||||
- ``L`` -- Canary Islands general indirect tax
|
|
||||||
- ``M`` -- Tax for production, services and importation in Ceuta and Melilla
|
|
||||||
- ``B`` -- Transferred (VAT), only in Italy
|
|
||||||
|
|
||||||
The code set in the ``code`` attribute of the tax rule is used by default. When ``eu_reverse_charge`` is active, the
|
|
||||||
code is replaced by ``AE`` for reverse charge sales and by ``O`` for non-EU sales. When configuring custom rules, you
|
|
||||||
should actively set a ``"code"`` key on each rule. Only for ``"action": "reverse"`` we automatically apply the code
|
|
||||||
``AE``, in all other cases the default ``code`` of the tax rule is selected.
|
|
||||||
|
|
||||||
Endpoints
|
Endpoints
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@@ -116,7 +74,6 @@ Endpoints
|
|||||||
"id": 1,
|
"id": 1,
|
||||||
"name": {"en": "VAT"},
|
"name": {"en": "VAT"},
|
||||||
"internal_name": "VAT",
|
"internal_name": "VAT",
|
||||||
"code": "S/standard",
|
|
||||||
"rate": "19.00",
|
"rate": "19.00",
|
||||||
"price_includes_tax": true,
|
"price_includes_tax": true,
|
||||||
"eu_reverse_charge": false,
|
"eu_reverse_charge": false,
|
||||||
@@ -158,7 +115,6 @@ Endpoints
|
|||||||
"id": 1,
|
"id": 1,
|
||||||
"name": {"en": "VAT"},
|
"name": {"en": "VAT"},
|
||||||
"internal_name": "VAT",
|
"internal_name": "VAT",
|
||||||
"code": "S/standard",
|
|
||||||
"rate": "19.00",
|
"rate": "19.00",
|
||||||
"price_includes_tax": true,
|
"price_includes_tax": true,
|
||||||
"eu_reverse_charge": false,
|
"eu_reverse_charge": false,
|
||||||
@@ -208,7 +164,6 @@ Endpoints
|
|||||||
"id": 1,
|
"id": 1,
|
||||||
"name": {"en": "VAT"},
|
"name": {"en": "VAT"},
|
||||||
"internal_name": "VAT",
|
"internal_name": "VAT",
|
||||||
"code": "S/standard",
|
|
||||||
"rate": "19.00",
|
"rate": "19.00",
|
||||||
"price_includes_tax": true,
|
"price_includes_tax": true,
|
||||||
"eu_reverse_charge": false,
|
"eu_reverse_charge": false,
|
||||||
@@ -257,7 +212,6 @@ Endpoints
|
|||||||
"id": 1,
|
"id": 1,
|
||||||
"name": {"en": "VAT"},
|
"name": {"en": "VAT"},
|
||||||
"internal_name": "VAT",
|
"internal_name": "VAT",
|
||||||
"code": "S/standard",
|
|
||||||
"rate": "20.00",
|
"rate": "20.00",
|
||||||
"price_includes_tax": true,
|
"price_includes_tax": true,
|
||||||
"eu_reverse_charge": false,
|
"eu_reverse_charge": false,
|
||||||
@@ -304,4 +258,3 @@ Endpoints
|
|||||||
:statuscode 403: The requested organizer/event/rule does not exist **or** you have no permission to change it **or** this tax rule cannot be deleted since it is currently in use.
|
:statuscode 403: The requested organizer/event/rule does not exist **or** you have no permission to change it **or** this tax rule cannot be deleted since it is currently in use.
|
||||||
|
|
||||||
.. _here: https://github.com/pretix/pretix/blob/master/src/pretix/static/schema/tax-rules-custom.schema.json
|
.. _here: https://github.com/pretix/pretix/blob/master/src/pretix/static/schema/tax-rules-custom.schema.json
|
||||||
.. _VATEX code list: https://ec.europa.eu/digital-building-blocks/sites/display/DIGITAL/Registry+of+supporting+artefacts+to+implement+EN16931#RegistryofsupportingartefactstoimplementEN16931-Codelists
|
|
||||||
+5
-5
@@ -32,7 +32,7 @@ dependencies = [
|
|||||||
"bleach==6.2.*",
|
"bleach==6.2.*",
|
||||||
"celery==5.4.*",
|
"celery==5.4.*",
|
||||||
"chardet==5.2.*",
|
"chardet==5.2.*",
|
||||||
"cryptography>=44.0.0",
|
"cryptography>=3.4.2",
|
||||||
"css-inline==0.14.*",
|
"css-inline==0.14.*",
|
||||||
"defusedcsv>=1.1.0",
|
"defusedcsv>=1.1.0",
|
||||||
"Django[argon2]==4.2.*,>=4.2.15",
|
"Django[argon2]==4.2.*,>=4.2.15",
|
||||||
@@ -44,7 +44,7 @@ dependencies = [
|
|||||||
"django-formtools==2.5.1",
|
"django-formtools==2.5.1",
|
||||||
"django-hierarkey==1.2.*",
|
"django-hierarkey==1.2.*",
|
||||||
"django-hijack==3.7.*",
|
"django-hijack==3.7.*",
|
||||||
"django-i18nfield==1.10.*",
|
"django-i18nfield==1.9.*,>=1.9.4",
|
||||||
"django-libsass==0.9",
|
"django-libsass==0.9",
|
||||||
"django-localflavor==4.0",
|
"django-localflavor==4.0",
|
||||||
"django-markup",
|
"django-markup",
|
||||||
@@ -74,7 +74,7 @@ dependencies = [
|
|||||||
"paypal-checkout-serversdk==1.0.*",
|
"paypal-checkout-serversdk==1.0.*",
|
||||||
"PyJWT==2.9.*",
|
"PyJWT==2.9.*",
|
||||||
"phonenumberslite==8.13.*",
|
"phonenumberslite==8.13.*",
|
||||||
"Pillow==11.1.*",
|
"Pillow==11.0.*",
|
||||||
"pretix-plugin-build",
|
"pretix-plugin-build",
|
||||||
"protobuf==5.29.*",
|
"protobuf==5.29.*",
|
||||||
"psycopg2-binary",
|
"psycopg2-binary",
|
||||||
@@ -97,10 +97,10 @@ dependencies = [
|
|||||||
"text-unidecode==1.*",
|
"text-unidecode==1.*",
|
||||||
"tlds>=2020041600",
|
"tlds>=2020041600",
|
||||||
"tqdm==4.*",
|
"tqdm==4.*",
|
||||||
"ua-parser==1.0.*",
|
"ua-parser==0.18.*",
|
||||||
"vat_moss_forked==2020.3.20.0.11.0",
|
"vat_moss_forked==2020.3.20.0.11.0",
|
||||||
"vobject==0.9.*",
|
"vobject==0.9.*",
|
||||||
"webauthn==2.4.*",
|
"webauthn==2.2.*",
|
||||||
"zeep==4.3.*"
|
"zeep==4.3.*"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class SalesChannelMigrationMixin:
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
if set(data["sales_channels"]) == all_channels:
|
if data["sales_channels"] == all_channels:
|
||||||
data["all_sales_channels"] = True
|
data["all_sales_channels"] = True
|
||||||
data["limit_sales_channels"] = []
|
data["limit_sales_channels"] = []
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied, ValidationError
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
@@ -43,7 +43,6 @@ from django.utils.translation import gettext as _
|
|||||||
from django_countries.serializers import CountryFieldMixin
|
from django_countries.serializers import CountryFieldMixin
|
||||||
from pytz import common_timezones
|
from pytz import common_timezones
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ValidationError
|
|
||||||
from rest_framework.fields import ChoiceField, Field
|
from rest_framework.fields import ChoiceField, Field
|
||||||
from rest_framework.relations import SlugRelatedField
|
from rest_framework.relations import SlugRelatedField
|
||||||
|
|
||||||
@@ -437,8 +436,7 @@ class CloneEventSerializer(EventSerializer):
|
|||||||
testmode = validated_data.pop('testmode', None)
|
testmode = validated_data.pop('testmode', None)
|
||||||
has_subevents = validated_data.pop('has_subevents', None)
|
has_subevents = validated_data.pop('has_subevents', None)
|
||||||
tz = validated_data.pop('timezone', None)
|
tz = validated_data.pop('timezone', None)
|
||||||
all_sales_channels = validated_data.pop('all_sales_channels', None)
|
sales_channels = validated_data.pop('sales_channels', None)
|
||||||
limit_sales_channels = validated_data.pop('limit_sales_channels', None)
|
|
||||||
date_admission = validated_data.pop('date_admission', None)
|
date_admission = validated_data.pop('date_admission', None)
|
||||||
new_event = super().create({**validated_data, 'plugins': None})
|
new_event = super().create({**validated_data, 'plugins': None})
|
||||||
|
|
||||||
@@ -451,9 +449,8 @@ class CloneEventSerializer(EventSerializer):
|
|||||||
new_event.is_public = is_public
|
new_event.is_public = is_public
|
||||||
if testmode is not None:
|
if testmode is not None:
|
||||||
new_event.testmode = testmode
|
new_event.testmode = testmode
|
||||||
if all_sales_channels is not None or limit_sales_channels is not None:
|
if sales_channels is not None:
|
||||||
new_event.all_sales_channels = all_sales_channels
|
new_event.sales_channels = sales_channels
|
||||||
new_event.limit_sales_channels.set(limit_sales_channels)
|
|
||||||
if has_subevents is not None:
|
if has_subevents is not None:
|
||||||
new_event.has_subevents = has_subevents
|
new_event.has_subevents = has_subevents
|
||||||
if has_subevents is not None:
|
if has_subevents is not None:
|
||||||
@@ -681,8 +678,8 @@ class TaxRuleSerializer(CountryFieldMixin, I18nAwareModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TaxRule
|
model = TaxRule
|
||||||
fields = ('id', 'name', 'rate', 'code', 'price_includes_tax', 'eu_reverse_charge', 'home_country',
|
fields = ('id', 'name', 'rate', 'price_includes_tax', 'eu_reverse_charge', 'home_country', 'internal_name',
|
||||||
'internal_name', 'keep_gross_if_rate_changes', 'custom_rules')
|
'keep_gross_if_rate_changes', 'custom_rules')
|
||||||
|
|
||||||
|
|
||||||
class EventSettingsSerializer(SettingsSerializer):
|
class EventSettingsSerializer(SettingsSerializer):
|
||||||
@@ -992,40 +989,6 @@ def prefetch_by_id(items, qs, id_attr, target_attr):
|
|||||||
setattr(item, target_attr, result.get(getattr(item, id_attr)))
|
setattr(item, target_attr, result.get(getattr(item, id_attr)))
|
||||||
|
|
||||||
|
|
||||||
class SeatBulkBlockInputSerializer(serializers.Serializer):
|
|
||||||
ids = serializers.ListField(child=serializers.IntegerField(), required=False, allow_empty=True)
|
|
||||||
seat_guids = serializers.ListField(child=serializers.CharField(), required=False, allow_empty=True)
|
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
|
||||||
data = super().to_internal_value(data)
|
|
||||||
|
|
||||||
if data.get("seat_guids") and data.get("ids"):
|
|
||||||
raise ValidationError("Please pass either seat_guids or ids.")
|
|
||||||
|
|
||||||
if data.get("seat_guids"):
|
|
||||||
seat_ids = data["seat_guids"]
|
|
||||||
if len(seat_ids) > 10000:
|
|
||||||
raise ValidationError({"seat_guids": ["Please do not pass over 10000 seats."]})
|
|
||||||
|
|
||||||
seats = {s.seat_guid: s for s in self.context["queryset"].filter(seat_guid__in=seat_ids)}
|
|
||||||
for s in seat_ids:
|
|
||||||
if s not in seats:
|
|
||||||
raise ValidationError({"seat_guids": [f"The seat '{s}' does not exist."]})
|
|
||||||
elif data.get("ids"):
|
|
||||||
seat_ids = data["ids"]
|
|
||||||
if len(seat_ids) > 10000:
|
|
||||||
raise ValidationError({"ids": ["Please do not pass over 10000 seats."]})
|
|
||||||
|
|
||||||
seats = self.context["queryset"].in_bulk(seat_ids)
|
|
||||||
for s in seat_ids:
|
|
||||||
if s not in seats:
|
|
||||||
raise ValidationError({"ids": [f"The seat '{s}' does not exist."]})
|
|
||||||
else:
|
|
||||||
raise ValidationError("Please pass either seat_guids or ids.")
|
|
||||||
|
|
||||||
return {"seats": seats.values()}
|
|
||||||
|
|
||||||
|
|
||||||
class SeatSerializer(I18nAwareModelSerializer):
|
class SeatSerializer(I18nAwareModelSerializer):
|
||||||
orderposition = serializers.IntegerField(source='orderposition_id')
|
orderposition = serializers.IntegerField(source='orderposition_id')
|
||||||
cartposition = serializers.IntegerField(source='cartposition_id')
|
cartposition = serializers.IntegerField(source='cartposition_id')
|
||||||
|
|||||||
@@ -19,8 +19,57 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||||
# <https://www.gnu.org/licenses/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
from django.conf import settings
|
||||||
from django.core.validators import URLValidator
|
from django.core.validators import URLValidator
|
||||||
from i18nfield.rest_framework import I18nAwareModelSerializer, I18nField
|
from i18nfield.fields import I18nCharField, I18nTextField
|
||||||
|
from i18nfield.strings import LazyI18nString
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
|
from rest_framework.fields import Field
|
||||||
|
from rest_framework.serializers import ModelSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class I18nField(Field):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.allow_blank = kwargs.pop('allow_blank', False)
|
||||||
|
self.trim_whitespace = kwargs.pop('trim_whitespace', True)
|
||||||
|
self.max_length = kwargs.pop('max_length', None)
|
||||||
|
self.min_length = kwargs.pop('min_length', None)
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
def to_representation(self, value):
|
||||||
|
if hasattr(value, 'data'):
|
||||||
|
if isinstance(value.data, dict):
|
||||||
|
return value.data
|
||||||
|
elif value.data is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
settings.LANGUAGE_CODE: str(value.data)
|
||||||
|
}
|
||||||
|
elif value is None:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
settings.LANGUAGE_CODE: str(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
if isinstance(data, str):
|
||||||
|
return LazyI18nString(data)
|
||||||
|
elif isinstance(data, dict):
|
||||||
|
if any([k not in dict(settings.LANGUAGES) for k in data.keys()]):
|
||||||
|
raise ValidationError('Invalid languages included.')
|
||||||
|
return LazyI18nString(data)
|
||||||
|
else:
|
||||||
|
raise ValidationError('Invalid data type.')
|
||||||
|
|
||||||
|
|
||||||
|
class I18nAwareModelSerializer(ModelSerializer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
I18nAwareModelSerializer.serializer_field_mapping[I18nCharField] = I18nField
|
||||||
|
I18nAwareModelSerializer.serializer_field_mapping[I18nTextField] = I18nField
|
||||||
|
|
||||||
|
|
||||||
class I18nURLField(I18nField):
|
class I18nURLField(I18nField):
|
||||||
@@ -35,10 +84,3 @@ class I18nURLField(I18nField):
|
|||||||
else:
|
else:
|
||||||
URLValidator()(value.data)
|
URLValidator()(value.data)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"I18nAwareModelSerializer", # for backwards compatibility
|
|
||||||
"I18nField", # for backwards compatibility
|
|
||||||
"I18nURLField",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -512,12 +512,11 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
|
|||||||
'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount',
|
'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount',
|
||||||
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
||||||
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled',
|
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled',
|
||||||
'print_logs', 'downloads', 'answers', 'tax_rule', 'tax_code', 'pseudonymization_id', 'pdf_data', 'seat',
|
'valid_from', 'valid_until', 'blocked', 'voucher_budget_use')
|
||||||
'canceled', 'valid_from', 'valid_until', 'blocked', 'voucher_budget_use')
|
|
||||||
read_only_fields = (
|
read_only_fields = (
|
||||||
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
|
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
|
||||||
'addon_to', 'subevent', 'checkins', 'downloads', 'answers', 'tax_rule', 'tax_code', 'pseudonymization_id',
|
'addon_to', 'subevent', 'checkins', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data',
|
||||||
'pdf_data', 'seat', 'canceled', 'discount', 'valid_from', 'valid_until', 'blocked', 'voucher_budget_use'
|
'seat', 'canceled', 'discount', 'valid_from', 'valid_until', 'blocked', 'voucher_budget_use'
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -643,8 +642,7 @@ class OrderPaymentDateField(serializers.DateField):
|
|||||||
class OrderFeeSerializer(I18nAwareModelSerializer):
|
class OrderFeeSerializer(I18nAwareModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OrderFee
|
model = OrderFee
|
||||||
fields = ('id', 'fee_type', 'value', 'description', 'internal_type', 'tax_rate', 'tax_value', 'tax_rule',
|
fields = ('id', 'fee_type', 'value', 'description', 'internal_type', 'tax_rate', 'tax_value', 'tax_rule', 'canceled')
|
||||||
'tax_code', 'canceled')
|
|
||||||
|
|
||||||
|
|
||||||
class PaymentURLField(serializers.URLField):
|
class PaymentURLField(serializers.URLField):
|
||||||
@@ -1678,7 +1676,7 @@ class InlineInvoiceLineSerializer(I18nAwareModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = InvoiceLine
|
model = InvoiceLine
|
||||||
fields = ('position', 'description', 'item', 'variation', 'subevent', 'attendee_name', 'event_date_from',
|
fields = ('position', 'description', 'item', 'variation', 'subevent', 'attendee_name', 'event_date_from',
|
||||||
'event_date_to', 'gross_value', 'tax_value', 'tax_rate', 'tax_code', 'tax_name', 'fee_type',
|
'event_date_to', 'gross_value', 'tax_value', 'tax_rate', 'tax_name', 'fee_type',
|
||||||
'fee_internal_type', 'event_location')
|
'fee_internal_type', 'event_location')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ from django.utils.timezone import now
|
|||||||
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from rest_framework import serializers, views, viewsets
|
from rest_framework import serializers, views, viewsets
|
||||||
from rest_framework.decorators import action
|
|
||||||
from rest_framework.exceptions import (
|
from rest_framework.exceptions import (
|
||||||
NotFound, PermissionDenied, ValidationError,
|
NotFound, PermissionDenied, ValidationError,
|
||||||
)
|
)
|
||||||
@@ -51,9 +50,8 @@ from pretix.api.auth.permission import EventCRUDPermission
|
|||||||
from pretix.api.pagination import TotalOrderingFilter
|
from pretix.api.pagination import TotalOrderingFilter
|
||||||
from pretix.api.serializers.event import (
|
from pretix.api.serializers.event import (
|
||||||
CloneEventSerializer, DeviceEventSettingsSerializer, EventSerializer,
|
CloneEventSerializer, DeviceEventSettingsSerializer, EventSerializer,
|
||||||
EventSettingsSerializer, ItemMetaPropertiesSerializer,
|
EventSettingsSerializer, ItemMetaPropertiesSerializer, SeatSerializer,
|
||||||
SeatBulkBlockInputSerializer, SeatSerializer, SubEventSerializer,
|
SubEventSerializer, TaxRuleSerializer,
|
||||||
TaxRuleSerializer,
|
|
||||||
)
|
)
|
||||||
from pretix.api.views import ConditionalListView
|
from pretix.api.views import ConditionalListView
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
@@ -239,9 +237,9 @@ class EventViewSet(viewsets.ModelViewSet):
|
|||||||
disabled = {m: 'disabled' for m in current_plugins_value if m not in updated_plugins_value}
|
disabled = {m: 'disabled' for m in current_plugins_value if m not in updated_plugins_value}
|
||||||
changed = merge_dicts(enabled, disabled)
|
changed = merge_dicts(enabled, disabled)
|
||||||
|
|
||||||
for module, operation in changed.items():
|
for module, action in changed.items():
|
||||||
serializer.instance.log_action(
|
serializer.instance.log_action(
|
||||||
'pretix.event.plugins.' + operation,
|
'pretix.event.plugins.' + action,
|
||||||
user=self.request.user,
|
user=self.request.user,
|
||||||
auth=self.request.auth,
|
auth=self.request.auth,
|
||||||
data={'plugin': module}
|
data={'plugin': module}
|
||||||
@@ -746,24 +744,3 @@ class SeatViewSet(ConditionalListView, viewsets.ModelViewSet):
|
|||||||
auth=self.request.auth,
|
auth=self.request.auth,
|
||||||
data={"seats": [serializer.instance.pk]},
|
data={"seats": [serializer.instance.pk]},
|
||||||
)
|
)
|
||||||
|
|
||||||
def bulk_change_blocked(self, blocked):
|
|
||||||
s = SeatBulkBlockInputSerializer(
|
|
||||||
data=self.request.data,
|
|
||||||
context={"event": self.request.event, "queryset": self.get_queryset()},
|
|
||||||
)
|
|
||||||
s.is_valid(raise_exception=True)
|
|
||||||
|
|
||||||
seats = s.validated_data["seats"]
|
|
||||||
for seat in seats:
|
|
||||||
seat.blocked = blocked
|
|
||||||
Seat.objects.bulk_update(seats, ["blocked"], batch_size=1000)
|
|
||||||
return Response({})
|
|
||||||
|
|
||||||
@action(methods=["POST"], detail=False)
|
|
||||||
def bulk_block(self, request, *args, **kwargs):
|
|
||||||
return self.bulk_change_blocked(True)
|
|
||||||
|
|
||||||
@action(methods=["POST"], detail=False)
|
|
||||||
def bulk_unblock(self, request, *args, **kwargs):
|
|
||||||
return self.bulk_change_blocked(False)
|
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ from django.db.models import (
|
|||||||
from django.db.models.functions import Coalesce, Concat
|
from django.db.models.functions import Coalesce, Concat
|
||||||
from django.http import FileResponse, HttpResponse
|
from django.http import FileResponse, HttpResponse
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.utils import formats
|
|
||||||
from django.utils.timezone import make_aware, now
|
from django.utils.timezone import make_aware, now
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||||
@@ -68,7 +67,6 @@ from pretix.api.serializers.orderchange import (
|
|||||||
OrderPositionInfoPatchSerializer,
|
OrderPositionInfoPatchSerializer,
|
||||||
)
|
)
|
||||||
from pretix.api.views import RichOrderingFilter
|
from pretix.api.views import RichOrderingFilter
|
||||||
from pretix.base.decimal import round_decimal
|
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
CachedCombinedTicket, CachedTicket, Checkin, Device, EventMetaValue,
|
CachedCombinedTicket, CachedTicket, Checkin, Device, EventMetaValue,
|
||||||
@@ -99,6 +97,7 @@ from pretix.base.services.tickets import generate
|
|||||||
from pretix.base.signals import (
|
from pretix.base.signals import (
|
||||||
order_modified, order_paid, order_placed, register_ticket_outputs,
|
order_modified, order_paid, order_placed, register_ticket_outputs,
|
||||||
)
|
)
|
||||||
|
from pretix.base.templatetags.money import money_filter
|
||||||
from pretix.control.signals import order_search_filter_q
|
from pretix.control.signals import order_search_filter_q
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
|
|
||||||
@@ -647,8 +646,6 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
|
|||||||
order = self.get_object()
|
order = self.get_object()
|
||||||
order.secret = generate_secret()
|
order.secret = generate_secret()
|
||||||
for op in order.all_positions.all():
|
for op in order.all_positions.all():
|
||||||
op.web_secret = generate_secret()
|
|
||||||
op.save(update_fields=["web_secret"])
|
|
||||||
assign_ticket_secret(
|
assign_ticket_secret(
|
||||||
request.event, op, force_invalidate=True, save=True
|
request.event, op, force_invalidate=True, save=True
|
||||||
)
|
)
|
||||||
@@ -1231,10 +1228,9 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
|||||||
price = get_price(**kwargs)
|
price = get_price(**kwargs)
|
||||||
tr = kwargs.get('tax_rule', kwargs.get('item').tax_rule)
|
tr = kwargs.get('tax_rule', kwargs.get('item').tax_rule)
|
||||||
with language(data.get('locale') or self.request.event.settings.locale, self.request.event.settings.region):
|
with language(data.get('locale') or self.request.event.settings.locale, self.request.event.settings.region):
|
||||||
gross_formatted = formats.localize_input(round_decimal(price.gross, self.request.event.currency))
|
|
||||||
return Response({
|
return Response({
|
||||||
'gross': price.gross,
|
'gross': price.gross,
|
||||||
'gross_formatted': gross_formatted,
|
'gross_formatted': money_filter(price.gross, self.request.event.currency, hide_currency=True),
|
||||||
'net': price.net,
|
'net': price.net,
|
||||||
'rate': price.rate,
|
'rate': price.rate,
|
||||||
'name': str(price.name),
|
'name': str(price.name),
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ from django.utils.translation import get_language, gettext_lazy as _
|
|||||||
from pretix.base.models import Event
|
from pretix.base.models import Event
|
||||||
from pretix.base.signals import register_html_mail_renderers
|
from pretix.base.signals import register_html_mail_renderers
|
||||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||||
from pretix.helpers.format import SafeFormatter, format_map
|
|
||||||
|
|
||||||
from pretix.base.services.placeholders import ( # noqa
|
from pretix.base.services.placeholders import ( # noqa
|
||||||
get_available_placeholders, PlaceholderContext
|
get_available_placeholders, PlaceholderContext
|
||||||
@@ -80,7 +79,7 @@ class BaseHTMLMailRenderer:
|
|||||||
return self.identifier
|
return self.identifier
|
||||||
|
|
||||||
def render(self, plain_body: str, plain_signature: str, subject: str, order=None,
|
def render(self, plain_body: str, plain_signature: str, subject: str, order=None,
|
||||||
position=None, context=None) -> str:
|
position=None) -> str:
|
||||||
"""
|
"""
|
||||||
This method should generate the HTML part of the email.
|
This method should generate the HTML part of the email.
|
||||||
|
|
||||||
@@ -89,7 +88,6 @@ class BaseHTMLMailRenderer:
|
|||||||
:param subject: The email subject.
|
:param subject: The email subject.
|
||||||
:param order: The order if this email is connected to one, otherwise ``None``.
|
:param order: The order if this email is connected to one, otherwise ``None``.
|
||||||
:param position: The order position if this email is connected to one, otherwise ``None``.
|
:param position: The order position if this email is connected to one, otherwise ``None``.
|
||||||
:param context: Context to use to render placeholders in the plain body
|
|
||||||
:return: An HTML string
|
:return: An HTML string
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
@@ -136,10 +134,8 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
|
|||||||
def compile_markdown(self, plaintext):
|
def compile_markdown(self, plaintext):
|
||||||
return markdown_compile_email(plaintext)
|
return markdown_compile_email(plaintext)
|
||||||
|
|
||||||
def render(self, plain_body: str, plain_signature: str, subject: str, order, position, context) -> str:
|
def render(self, plain_body: str, plain_signature: str, subject: str, order, position) -> str:
|
||||||
body_md = self.compile_markdown(plain_body)
|
body_md = self.compile_markdown(plain_body)
|
||||||
if context:
|
|
||||||
body_md = format_map(body_md, context=context, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
|
||||||
htmlctx = {
|
htmlctx = {
|
||||||
'site': settings.PRETIX_INSTANCE_NAME,
|
'site': settings.PRETIX_INSTANCE_NAME,
|
||||||
'site_url': settings.SITE_URL,
|
'site_url': settings.SITE_URL,
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class MarkdownTextarea(forms.Textarea):
|
|||||||
|
|
||||||
|
|
||||||
class I18nMarkdownTextarea(i18nfield.forms.I18nTextarea):
|
class I18nMarkdownTextarea(i18nfield.forms.I18nTextarea):
|
||||||
def format_output(self, rendered_widgets, id_) -> str:
|
def format_output(self, rendered_widgets) -> str:
|
||||||
rendered_widgets = rendered_widgets + [
|
rendered_widgets = rendered_widgets + [
|
||||||
'<div class="i18n-field-markdown-note">%s</div>' % (
|
'<div class="i18n-field-markdown-note">%s</div>' % (
|
||||||
_("You can use {markup_name} in this field.").format(
|
_("You can use {markup_name} in this field.").format(
|
||||||
@@ -108,11 +108,11 @@ class I18nMarkdownTextarea(i18nfield.forms.I18nTextarea):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
return super().format_output(rendered_widgets, id_)
|
return super().format_output(rendered_widgets)
|
||||||
|
|
||||||
|
|
||||||
class I18nMarkdownTextInput(i18nfield.forms.I18nTextInput):
|
class I18nMarkdownTextInput(i18nfield.forms.I18nTextInput):
|
||||||
def format_output(self, rendered_widgets, id_) -> str:
|
def format_output(self, rendered_widgets) -> str:
|
||||||
rendered_widgets = rendered_widgets + [
|
rendered_widgets = rendered_widgets + [
|
||||||
'<div class="i18n-field-markdown-note">%s</div>' % (
|
'<div class="i18n-field-markdown-note">%s</div>' % (
|
||||||
_("You can use {markup_name} in this field.").format(
|
_("You can use {markup_name} in this field.").format(
|
||||||
@@ -120,7 +120,7 @@ class I18nMarkdownTextInput(i18nfield.forms.I18nTextInput):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
return super().format_output(rendered_widgets, id_)
|
return super().format_output(rendered_widgets)
|
||||||
|
|
||||||
|
|
||||||
SECRET_REDACTED = '*****'
|
SECRET_REDACTED = '*****'
|
||||||
|
|||||||
@@ -1035,18 +1035,6 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
'is_business': ''
|
'is_business': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def ask_vat_id(self):
|
|
||||||
return self.event.settings.invoice_address_vatid
|
|
||||||
|
|
||||||
@property
|
|
||||||
def address_required(self):
|
|
||||||
return self.event.settings.invoice_address_required
|
|
||||||
|
|
||||||
@property
|
|
||||||
def company_required(self):
|
|
||||||
return self.event.settings.invoice_address_company_required
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.event = event = kwargs.pop('event')
|
self.event = event = kwargs.pop('event')
|
||||||
self.request = kwargs.pop('request', None)
|
self.request = kwargs.pop('request', None)
|
||||||
@@ -1058,11 +1046,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
kwargs['initial']['country'] = guess_country_from_request(self.request, self.event)
|
kwargs['initial']['country'] = guess_country_from_request(self.request, self.event)
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
if not event.settings.invoice_address_vatid:
|
||||||
self.fields["company"].widget.attrs["data-display-dependency"] = f'#id_{self.add_prefix("is_business")}_1'
|
|
||||||
self.fields["vat_id"].widget.attrs["data-display-dependency"] = f'#id_{self.add_prefix("is_business")}_1'
|
|
||||||
|
|
||||||
if not self.ask_vat_id:
|
|
||||||
del self.fields['vat_id']
|
del self.fields['vat_id']
|
||||||
elif self.validate_vat_id:
|
elif self.validate_vat_id:
|
||||||
self.fields['vat_id'].help_text = '<br/>'.join([
|
self.fields['vat_id'].help_text = '<br/>'.join([
|
||||||
@@ -1116,13 +1100,13 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
self.data = self.data.copy()
|
self.data = self.data.copy()
|
||||||
del self.data[fprefix + 'vat_id']
|
del self.data[fprefix + 'vat_id']
|
||||||
|
|
||||||
if not self.address_required or self.all_optional:
|
if not event.settings.invoice_address_required or self.all_optional:
|
||||||
for k, f in self.fields.items():
|
for k, f in self.fields.items():
|
||||||
f.required = False
|
f.required = False
|
||||||
f.widget.is_required = False
|
f.widget.is_required = False
|
||||||
if 'required' in f.widget.attrs:
|
if 'required' in f.widget.attrs:
|
||||||
del f.widget.attrs['required']
|
del f.widget.attrs['required']
|
||||||
elif self.company_required and not self.all_optional:
|
elif event.settings.invoice_address_company_required and not self.all_optional:
|
||||||
self.initial['is_business'] = True
|
self.initial['is_business'] = True
|
||||||
|
|
||||||
self.fields['is_business'].widget = BusinessBooleanRadio(require_business=True)
|
self.fields['is_business'].widget = BusinessBooleanRadio(require_business=True)
|
||||||
@@ -1139,11 +1123,11 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
label=_('Name'),
|
label=_('Name'),
|
||||||
initial=self.instance.name_parts,
|
initial=self.instance.name_parts,
|
||||||
)
|
)
|
||||||
if self.address_required and not self.company_required and not self.all_optional:
|
if event.settings.invoice_address_required and not event.settings.invoice_address_company_required and not self.all_optional:
|
||||||
if not event.settings.invoice_name_required:
|
if not event.settings.invoice_name_required:
|
||||||
self.fields['name_parts'].widget.attrs['data-required-if'] = f'#id_{self.add_prefix("is_business")}_0'
|
self.fields['name_parts'].widget.attrs['data-required-if'] = '#id_is_business_0'
|
||||||
self.fields['name_parts'].widget.attrs['data-no-required-attr'] = '1'
|
self.fields['name_parts'].widget.attrs['data-no-required-attr'] = '1'
|
||||||
self.fields['company'].widget.attrs['data-required-if'] = f'#id_{self.add_prefix("is_business")}_1'
|
self.fields['company'].widget.attrs['data-required-if'] = '#id_is_business_1'
|
||||||
|
|
||||||
if not event.settings.invoice_address_beneficiary:
|
if not event.settings.invoice_address_beneficiary:
|
||||||
del self.fields['beneficiary']
|
del self.fields['beneficiary']
|
||||||
@@ -1169,7 +1153,7 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
data['vat_id'] = ''
|
data['vat_id'] = ''
|
||||||
if data.get('is_business') and not ask_for_vat_id(data.get('country')):
|
if data.get('is_business') and not ask_for_vat_id(data.get('country')):
|
||||||
data['vat_id'] = ''
|
data['vat_id'] = ''
|
||||||
if self.address_validation and self.address_required and not self.all_optional:
|
if self.address_validation and self.event.settings.invoice_address_required and not self.all_optional:
|
||||||
if data.get('is_business') and not data.get('company'):
|
if data.get('is_business') and not data.get('company'):
|
||||||
raise ValidationError({"company": _('You need to provide a company name.')})
|
raise ValidationError({"company": _('You need to provide a company name.')})
|
||||||
if not data.get('is_business') and name_parts_is_empty(data.get('name_parts', {})):
|
if not data.get('is_business') and name_parts_is_empty(data.get('name_parts', {})):
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class Command(BaseCommand):
|
|||||||
try:
|
try:
|
||||||
r = receiver(signal=periodic_task, sender=self)
|
r = receiver(signal=periodic_task, sender=self)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
if isinstance(err, KeyboardInterrupt):
|
if isinstance(Exception, KeyboardInterrupt):
|
||||||
raise err
|
raise err
|
||||||
if settings.SENTRY_ENABLED:
|
if settings.SENTRY_ENABLED:
|
||||||
from sentry_sdk import capture_exception
|
from sentry_sdk import capture_exception
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
# Generated by Django 4.2.8 on 2024-07-02 10:34
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
(
|
|
||||||
"pretixbase",
|
|
||||||
"0273_remove_checkinlist_auto_checkin_sales_channels",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="invoiceline",
|
|
||||||
name="tax_code",
|
|
||||||
field=models.CharField(max_length=190, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="orderfee",
|
|
||||||
name="tax_code",
|
|
||||||
field=models.CharField(max_length=190, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="orderposition",
|
|
||||||
name="tax_code",
|
|
||||||
field=models.CharField(max_length=190, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="taxrule",
|
|
||||||
name="code",
|
|
||||||
field=models.CharField(max_length=190, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name="transaction",
|
|
||||||
name="tax_code",
|
|
||||||
field=models.CharField(max_length=190, null=True),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@@ -441,7 +441,6 @@ class Price(DecimalColumnMixin, ImportColumn):
|
|||||||
position.price = p.gross
|
position.price = p.gross
|
||||||
position.tax_rule = position.item.tax_rule
|
position.tax_rule = position.item.tax_rule
|
||||||
position.tax_rate = p.rate
|
position.tax_rate = p.rate
|
||||||
position.tax_code = p.code
|
|
||||||
position.tax_value = p.tax
|
position.tax_value = p.tax
|
||||||
|
|
||||||
|
|
||||||
@@ -585,7 +584,7 @@ class SeatColumn(ImportColumn):
|
|||||||
raise ValidationError(_('Multiple matching seats were found.'))
|
raise ValidationError(_('Multiple matching seats were found.'))
|
||||||
except Seat.DoesNotExist:
|
except Seat.DoesNotExist:
|
||||||
raise ValidationError(_('No matching seat was found.'))
|
raise ValidationError(_('No matching seat was found.'))
|
||||||
if not value.is_available(sales_channel=previous_values.get('sales_channel')) or value in self._cached:
|
if not value.is_available() or value in self._cached:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_('The seat you selected has already been taken. Please select a different seat.'))
|
_('The seat you selected has already been taken. Please select a different seat.'))
|
||||||
self._cached.add(value)
|
self._cached.add(value)
|
||||||
@@ -754,11 +753,11 @@ def get_order_import_columns(event):
|
|||||||
AttendeeState(event),
|
AttendeeState(event),
|
||||||
Price(event),
|
Price(event),
|
||||||
Secret(event),
|
Secret(event),
|
||||||
Saleschannel(event),
|
|
||||||
SeatColumn(event),
|
SeatColumn(event),
|
||||||
ValidFrom(event),
|
ValidFrom(event),
|
||||||
ValidUntil(event),
|
ValidUntil(event),
|
||||||
Locale(event),
|
Locale(event),
|
||||||
|
Saleschannel(event),
|
||||||
CheckinAttentionColumn(event),
|
CheckinAttentionColumn(event),
|
||||||
CheckinTextColumn(event),
|
CheckinTextColumn(event),
|
||||||
Expires(event),
|
Expires(event),
|
||||||
|
|||||||
@@ -823,9 +823,6 @@ class Event(EventMixin, LoggedModel):
|
|||||||
self.save()
|
self.save()
|
||||||
self.log_action('pretix.object.cloned', data={'source': other.slug, 'source_id': other.pk})
|
self.log_action('pretix.object.cloned', data={'source': other.slug, 'source_id': other.pk})
|
||||||
|
|
||||||
if hasattr(other, 'alternative_domain_assignment'):
|
|
||||||
other.alternative_domain_assignment.domain.event_assignments.create(event=self)
|
|
||||||
|
|
||||||
if not self.all_sales_channels:
|
if not self.all_sales_channels:
|
||||||
self.limit_sales_channels.set(
|
self.limit_sales_channels.set(
|
||||||
self.organizer.sales_channels.filter(
|
self.organizer.sales_channels.filter(
|
||||||
|
|||||||
@@ -362,7 +362,6 @@ class InvoiceLine(models.Model):
|
|||||||
tax_value = models.DecimalField(max_digits=13, decimal_places=2, default=Decimal('0.00'))
|
tax_value = models.DecimalField(max_digits=13, decimal_places=2, default=Decimal('0.00'))
|
||||||
tax_rate = models.DecimalField(max_digits=7, decimal_places=2, default=Decimal('0.00'))
|
tax_rate = models.DecimalField(max_digits=7, decimal_places=2, default=Decimal('0.00'))
|
||||||
tax_name = models.CharField(max_length=190)
|
tax_name = models.CharField(max_length=190)
|
||||||
tax_code = models.CharField(max_length=190, null=True, blank=True)
|
|
||||||
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)
|
event_date_to = models.DateTimeField(null=True)
|
||||||
|
|||||||
@@ -837,7 +837,7 @@ class Item(LoggedModel):
|
|||||||
|
|
||||||
if not self.tax_rule:
|
if not self.tax_rule:
|
||||||
t = TaxedPrice(gross=price - bundled_sum, net=price - bundled_sum, tax=Decimal('0.00'),
|
t = TaxedPrice(gross=price - bundled_sum, net=price - bundled_sum, tax=Decimal('0.00'),
|
||||||
rate=Decimal('0.00'), name='', code=None)
|
rate=Decimal('0.00'), name='')
|
||||||
else:
|
else:
|
||||||
t = self.tax_rule.tax(price, base_price_is=base_price_is, invoice_address=invoice_address,
|
t = self.tax_rule.tax(price, base_price_is=base_price_is, invoice_address=invoice_address,
|
||||||
override_tax_rate=override_tax_rate, currency=currency or self.event.currency,
|
override_tax_rate=override_tax_rate, currency=currency or self.event.currency,
|
||||||
@@ -845,7 +845,6 @@ class Item(LoggedModel):
|
|||||||
|
|
||||||
if bundled_sum:
|
if bundled_sum:
|
||||||
t.name = "MIXED!"
|
t.name = "MIXED!"
|
||||||
t.code = None
|
|
||||||
t.gross += bundled_sum
|
t.gross += bundled_sum
|
||||||
t.net += bundled_sum_net
|
t.net += bundled_sum_net
|
||||||
t.tax += bundled_sum_tax
|
t.tax += bundled_sum_tax
|
||||||
@@ -1259,7 +1258,7 @@ class ItemVariation(models.Model):
|
|||||||
|
|
||||||
if not self.item.tax_rule:
|
if not self.item.tax_rule:
|
||||||
t = TaxedPrice(gross=price, net=price, tax=Decimal('0.00'),
|
t = TaxedPrice(gross=price, net=price, tax=Decimal('0.00'),
|
||||||
rate=Decimal('0.00'), name='', code=None)
|
rate=Decimal('0.00'), name='')
|
||||||
else:
|
else:
|
||||||
t = self.item.tax_rule.tax(price, base_price_is=base_price_is, currency=currency,
|
t = self.item.tax_rule.tax(price, base_price_is=base_price_is, currency=currency,
|
||||||
override_tax_rate=override_tax_rate,
|
override_tax_rate=override_tax_rate,
|
||||||
@@ -1281,7 +1280,6 @@ class ItemVariation(models.Model):
|
|||||||
t.net += bprice.net - compare_price.net
|
t.net += bprice.net - compare_price.net
|
||||||
t.tax += bprice.tax - compare_price.tax
|
t.tax += bprice.tax - compare_price.tax
|
||||||
t.name = "MIXED!"
|
t.name = "MIXED!"
|
||||||
t.code = None
|
|
||||||
|
|
||||||
return t
|
return t
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,9 @@ from django.db.models.signals import post_delete
|
|||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.crypto import get_random_string, salted_hmac
|
from django.utils.crypto import get_random_string, salted_hmac
|
||||||
from django.utils.encoding import escape_uri_path, force_str
|
from django.utils.encoding import escape_uri_path
|
||||||
from django.utils.formats import date_format
|
from django.utils.formats import date_format
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.hashable import make_hashable
|
|
||||||
from django.utils.timezone import get_current_timezone, make_aware, now
|
from django.utils.timezone import get_current_timezone, make_aware, now
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||||
from django_countries.fields import Country
|
from django_countries.fields import Country
|
||||||
@@ -1257,7 +1256,7 @@ class Order(LockModel, LoggedModel):
|
|||||||
keys = set(target_transaction_count.keys()) | set(current_transaction_count.keys())
|
keys = set(target_transaction_count.keys()) | set(current_transaction_count.keys())
|
||||||
create = []
|
create = []
|
||||||
for k in keys:
|
for k in keys:
|
||||||
positionid, itemid, variationid, subeventid, price, taxrate, taxruleid, taxvalue, feetype, internaltype, taxcode = k
|
positionid, itemid, variationid, subeventid, price, taxrate, taxruleid, taxvalue, feetype, internaltype = k
|
||||||
d = target_transaction_count[k] - current_transaction_count[k]
|
d = target_transaction_count[k] - current_transaction_count[k]
|
||||||
if d:
|
if d:
|
||||||
create.append(Transaction(
|
create.append(Transaction(
|
||||||
@@ -1273,7 +1272,6 @@ class Order(LockModel, LoggedModel):
|
|||||||
tax_rate=taxrate,
|
tax_rate=taxrate,
|
||||||
tax_rule_id=taxruleid,
|
tax_rule_id=taxruleid,
|
||||||
tax_value=taxvalue,
|
tax_value=taxvalue,
|
||||||
tax_code=taxcode,
|
|
||||||
fee_type=feetype,
|
fee_type=feetype,
|
||||||
internal_type=internaltype,
|
internal_type=internaltype,
|
||||||
))
|
))
|
||||||
@@ -2277,7 +2275,6 @@ class OrderFee(models.Model):
|
|||||||
FEE_TYPE_SERVICE = "service"
|
FEE_TYPE_SERVICE = "service"
|
||||||
FEE_TYPE_CANCELLATION = "cancellation"
|
FEE_TYPE_CANCELLATION = "cancellation"
|
||||||
FEE_TYPE_INSURANCE = "insurance"
|
FEE_TYPE_INSURANCE = "insurance"
|
||||||
FEE_TYPE_LATE = "late"
|
|
||||||
FEE_TYPE_OTHER = "other"
|
FEE_TYPE_OTHER = "other"
|
||||||
FEE_TYPE_GIFTCARD = "giftcard"
|
FEE_TYPE_GIFTCARD = "giftcard"
|
||||||
FEE_TYPES = (
|
FEE_TYPES = (
|
||||||
@@ -2286,7 +2283,6 @@ class OrderFee(models.Model):
|
|||||||
(FEE_TYPE_SERVICE, _("Service fee")),
|
(FEE_TYPE_SERVICE, _("Service fee")),
|
||||||
(FEE_TYPE_CANCELLATION, _("Cancellation fee")),
|
(FEE_TYPE_CANCELLATION, _("Cancellation fee")),
|
||||||
(FEE_TYPE_INSURANCE, _("Insurance fee")),
|
(FEE_TYPE_INSURANCE, _("Insurance fee")),
|
||||||
(FEE_TYPE_LATE, _("Late fee")),
|
|
||||||
(FEE_TYPE_OTHER, _("Other fees")),
|
(FEE_TYPE_OTHER, _("Other fees")),
|
||||||
(FEE_TYPE_GIFTCARD, _("Gift card")),
|
(FEE_TYPE_GIFTCARD, _("Gift card")),
|
||||||
)
|
)
|
||||||
@@ -2315,10 +2311,6 @@ class OrderFee(models.Model):
|
|||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
null=True, blank=True
|
null=True, blank=True
|
||||||
)
|
)
|
||||||
tax_code = models.CharField(
|
|
||||||
max_length=190,
|
|
||||||
null=True, blank=True,
|
|
||||||
)
|
|
||||||
tax_value = models.DecimalField(
|
tax_value = models.DecimalField(
|
||||||
max_digits=13, decimal_places=2,
|
max_digits=13, decimal_places=2,
|
||||||
verbose_name=_('Tax value')
|
verbose_name=_('Tax value')
|
||||||
@@ -2346,16 +2338,6 @@ class OrderFee(models.Model):
|
|||||||
self._transaction_key_reset()
|
self._transaction_key_reset()
|
||||||
return super().refresh_from_db(using, fields)
|
return super().refresh_from_db(using, fields)
|
||||||
|
|
||||||
def get_tax_code_display(self):
|
|
||||||
from pretix.base.models.tax import get_tax_code_labels
|
|
||||||
|
|
||||||
if self.tax_code:
|
|
||||||
choices_dict = get_tax_code_labels()
|
|
||||||
return force_str(
|
|
||||||
choices_dict.get(make_hashable(self.tax_code), self.tax_code), strings_only=True
|
|
||||||
)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def _transaction_key_reset(self):
|
def _transaction_key_reset(self):
|
||||||
self.__initial_transaction_key = Transaction.key(self)
|
self.__initial_transaction_key = Transaction.key(self)
|
||||||
self.__initial_canceled = self.canceled
|
self.__initial_canceled = self.canceled
|
||||||
@@ -2386,11 +2368,9 @@ class OrderFee(models.Model):
|
|||||||
if self.tax_rule:
|
if self.tax_rule:
|
||||||
tax = self.tax_rule.tax(self.value, base_price_is='gross', invoice_address=ia, force_fixed_gross_price=True)
|
tax = self.tax_rule.tax(self.value, base_price_is='gross', invoice_address=ia, force_fixed_gross_price=True)
|
||||||
self.tax_rate = tax.rate
|
self.tax_rate = tax.rate
|
||||||
self.tax_code = tax.code
|
|
||||||
self.tax_value = tax.tax
|
self.tax_value = tax.tax
|
||||||
else:
|
else:
|
||||||
self.tax_value = Decimal('0.00')
|
self.tax_value = Decimal('0.00')
|
||||||
self.tax_code = None
|
|
||||||
self.tax_rate = Decimal('0.00')
|
self.tax_rate = Decimal('0.00')
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
@@ -2399,7 +2379,6 @@ class OrderFee(models.Model):
|
|||||||
|
|
||||||
if self.tax_rate is None:
|
if self.tax_rate is None:
|
||||||
self._calculate_tax()
|
self._calculate_tax()
|
||||||
|
|
||||||
self.order.touch()
|
self.order.touch()
|
||||||
|
|
||||||
if not self.get_deferred_fields():
|
if not self.get_deferred_fields():
|
||||||
@@ -2487,10 +2466,6 @@ class OrderPosition(AbstractPosition):
|
|||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
null=True, blank=True
|
null=True, blank=True
|
||||||
)
|
)
|
||||||
tax_code = models.CharField(
|
|
||||||
max_length=190,
|
|
||||||
null=True, blank=True,
|
|
||||||
)
|
|
||||||
tax_value = models.DecimalField(
|
tax_value = models.DecimalField(
|
||||||
max_digits=13, decimal_places=2,
|
max_digits=13, decimal_places=2,
|
||||||
verbose_name=_('Tax value')
|
verbose_name=_('Tax value')
|
||||||
@@ -2548,16 +2523,6 @@ class OrderPosition(AbstractPosition):
|
|||||||
models.UniqueConstraint("organizer", "secret", name="orderposition_organizer_secret_uniq")
|
models.UniqueConstraint("organizer", "secret", name="orderposition_organizer_secret_uniq")
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_tax_code_display(self):
|
|
||||||
from pretix.base.models.tax import get_tax_code_labels
|
|
||||||
|
|
||||||
if self.tax_code:
|
|
||||||
choices_dict = get_tax_code_labels()
|
|
||||||
return force_str(
|
|
||||||
choices_dict.get(make_hashable(self.tax_code), self.tax_code), strings_only=True
|
|
||||||
)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def sort_key(self):
|
def sort_key(self):
|
||||||
return self.addon_to.positionid if self.addon_to else self.positionid, self.addon_to_id or 0, self.positionid
|
return self.addon_to.positionid if self.addon_to else self.positionid, self.addon_to_id or 0, self.positionid
|
||||||
@@ -2730,13 +2695,11 @@ class OrderPosition(AbstractPosition):
|
|||||||
if self.tax_rule:
|
if self.tax_rule:
|
||||||
tax = self.tax_rule.tax(self.price, invoice_address=ia, base_price_is='gross', force_fixed_gross_price=True)
|
tax = self.tax_rule.tax(self.price, invoice_address=ia, base_price_is='gross', force_fixed_gross_price=True)
|
||||||
self.tax_rate = tax.rate
|
self.tax_rate = tax.rate
|
||||||
self.tax_code = tax.code
|
|
||||||
self.tax_value = tax.tax
|
self.tax_value = tax.tax
|
||||||
if tax.gross != self.price:
|
if tax.gross != self.price:
|
||||||
raise ValueError('Invalid tax calculation')
|
raise ValueError('Invalid tax calculation')
|
||||||
else:
|
else:
|
||||||
self.tax_value = Decimal('0.00')
|
self.tax_value = Decimal('0.00')
|
||||||
self.tax_code = None
|
|
||||||
self.tax_rate = Decimal('0.00')
|
self.tax_rate = Decimal('0.00')
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
@@ -3007,10 +2970,6 @@ class Transaction(models.Model):
|
|||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
null=True, blank=True
|
null=True, blank=True
|
||||||
)
|
)
|
||||||
tax_code = models.CharField(
|
|
||||||
max_length=190,
|
|
||||||
null=True, blank=True,
|
|
||||||
)
|
|
||||||
tax_value = models.DecimalField(
|
tax_value = models.DecimalField(
|
||||||
max_digits=13, decimal_places=2,
|
max_digits=13, decimal_places=2,
|
||||||
verbose_name=_('Tax value')
|
verbose_name=_('Tax value')
|
||||||
@@ -3031,27 +2990,17 @@ class Transaction(models.Model):
|
|||||||
raise ValidationError('Should set either item or fee type')
|
raise ValidationError('Should set either item or fee type')
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
def get_tax_code_display(self):
|
|
||||||
from pretix.base.models.tax import get_tax_code_labels
|
|
||||||
|
|
||||||
if self.tax_code:
|
|
||||||
choices_dict = get_tax_code_labels()
|
|
||||||
return force_str(
|
|
||||||
choices_dict.get(make_hashable(self.tax_code), self.tax_code), strings_only=True
|
|
||||||
)
|
|
||||||
return ""
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def key(obj):
|
def key(obj):
|
||||||
if isinstance(obj, Transaction):
|
if isinstance(obj, Transaction):
|
||||||
return (obj.positionid, obj.item_id, obj.variation_id, obj.subevent_id, obj.price, obj.tax_rate,
|
return (obj.positionid, obj.item_id, obj.variation_id, obj.subevent_id, obj.price, obj.tax_rate,
|
||||||
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type, obj.tax_code)
|
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type)
|
||||||
elif isinstance(obj, OrderPosition):
|
elif isinstance(obj, OrderPosition):
|
||||||
return (obj.positionid, obj.item_id, obj.variation_id, obj.subevent_id, obj.price, obj.tax_rate,
|
return (obj.positionid, obj.item_id, obj.variation_id, obj.subevent_id, obj.price, obj.tax_rate,
|
||||||
obj.tax_rule_id, obj.tax_value, None, None, obj.tax_code)
|
obj.tax_rule_id, obj.tax_value, None, None)
|
||||||
elif isinstance(obj, OrderFee):
|
elif isinstance(obj, OrderFee):
|
||||||
return (None, None, None, None, obj.value, obj.tax_rate,
|
return (None, None, None, None, obj.value, obj.tax_rate,
|
||||||
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type, obj.tax_code)
|
obj.tax_rule_id, obj.tax_value, obj.fee_type, obj.internal_type)
|
||||||
raise ValueError('invalid state') # noqa
|
raise ValueError('invalid state') # noqa
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -3215,7 +3164,6 @@ class CartPosition(AbstractPosition):
|
|||||||
if line_price.gross != self.line_price_gross or line_price.rate != self.tax_rate:
|
if line_price.gross != self.line_price_gross or line_price.rate != self.tax_rate:
|
||||||
self.line_price_gross = line_price.gross
|
self.line_price_gross = line_price.gross
|
||||||
self.tax_rate = line_price.rate
|
self.tax_rate = line_price.rate
|
||||||
self.tax_code = line_price.code
|
|
||||||
self.save(update_fields=['line_price_gross', 'tax_rate'])
|
self.save(update_fields=['line_price_gross', 'tax_rate'])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
+12
-220
@@ -21,7 +21,6 @@
|
|||||||
#
|
#
|
||||||
import json
|
import json
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
from django.contrib.staticfiles import finders
|
from django.contrib.staticfiles import finders
|
||||||
@@ -31,9 +30,8 @@ from django.db import models
|
|||||||
from django.utils.deconstruct import deconstructible
|
from django.utils.deconstruct import deconstructible
|
||||||
from django.utils.formats import localize
|
from django.utils.formats import localize
|
||||||
from django.utils.functional import lazy
|
from django.utils.functional import lazy
|
||||||
from django.utils.hashable import make_hashable
|
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext, pgettext_lazy
|
from django.utils.translation import gettext_lazy as _, pgettext
|
||||||
from i18nfield.fields import I18nCharField
|
from i18nfield.fields import I18nCharField
|
||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
|
|
||||||
@@ -44,7 +42,7 @@ from pretix.helpers.countries import FastCountryField
|
|||||||
|
|
||||||
|
|
||||||
class TaxedPrice:
|
class TaxedPrice:
|
||||||
def __init__(self, *, gross: Decimal, net: Decimal, tax: Decimal, rate: Decimal, name: str, code: Optional[str]):
|
def __init__(self, *, gross: Decimal, net: Decimal, tax: Decimal, rate: Decimal, name: str):
|
||||||
if net + tax != gross:
|
if net + tax != gross:
|
||||||
raise ValueError('Net value and tax value need to add to the gross value')
|
raise ValueError('Net value and tax value need to add to the gross value')
|
||||||
self.gross = gross
|
self.gross = gross
|
||||||
@@ -52,7 +50,6 @@ class TaxedPrice:
|
|||||||
self.tax = tax
|
self.tax = tax
|
||||||
self.rate = rate
|
self.rate = rate
|
||||||
self.name = name
|
self.name = name
|
||||||
self.code = code
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '{} + {}% = {}'.format(localize(self.net), localize(self.rate), localize(self.gross))
|
return '{} + {}% = {}'.format(localize(self.net), localize(self.rate), localize(self.gross))
|
||||||
@@ -75,7 +72,6 @@ class TaxedPrice:
|
|||||||
tax=newgross - newnet,
|
tax=newgross - newnet,
|
||||||
rate=self.rate,
|
rate=self.rate,
|
||||||
name=self.name,
|
name=self.name,
|
||||||
code=self.code,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __mul__(self, other):
|
def __mul__(self, other):
|
||||||
@@ -89,7 +85,6 @@ class TaxedPrice:
|
|||||||
tax=newgross - newnet,
|
tax=newgross - newnet,
|
||||||
rate=self.rate,
|
rate=self.rate,
|
||||||
name=self.name,
|
name=self.name,
|
||||||
code=self.code,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
@@ -98,8 +93,7 @@ class TaxedPrice:
|
|||||||
self.net == other.net and
|
self.net == other.net and
|
||||||
self.tax == other.tax and
|
self.tax == other.tax and
|
||||||
self.rate == other.rate and
|
self.rate == other.rate and
|
||||||
self.name == other.name and
|
self.name == other.name
|
||||||
self.code == other.code
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -108,8 +102,7 @@ TAXED_ZERO = TaxedPrice(
|
|||||||
net=Decimal('0.00'),
|
net=Decimal('0.00'),
|
||||||
tax=Decimal('0.00'),
|
tax=Decimal('0.00'),
|
||||||
rate=Decimal('0.00'),
|
rate=Decimal('0.00'),
|
||||||
name='',
|
name=''
|
||||||
code=None,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
EU_COUNTRIES = {
|
EU_COUNTRIES = {
|
||||||
@@ -132,152 +125,6 @@ VAT_ID_COUNTRIES = EU_COUNTRIES | {'CH', 'NO'}
|
|||||||
format_html_lazy = lazy(format_html, str)
|
format_html_lazy = lazy(format_html, str)
|
||||||
|
|
||||||
|
|
||||||
TAX_CODE_LISTS = (
|
|
||||||
# Sources:
|
|
||||||
# https://ec.europa.eu/digital-building-blocks/sites/display/DIGITAL/Registry+of+supporting+artefacts+to+implement+EN16931#RegistryofsupportingartefactstoimplementEN16931-Codelists#RegistryofsupportingartefactstoimplementEN16931-Codelists
|
|
||||||
# https://docs.peppol.eu/poacc/billing/3.0/codelist/vatex/
|
|
||||||
# https://docs.peppol.eu/poacc/billing/3.0/codelist/UNCL5305/
|
|
||||||
# https://www.bzst.de/DE/Unternehmen/Aussenpruefungen/DigitaleSchnittstelleFinV/digitaleschnittstellefinv_node.html#js-toc-entry2
|
|
||||||
#
|
|
||||||
# !! When changed, also update tax-rules-custom.schema.json and doc/api/resources/taxrules.rst !!
|
|
||||||
(
|
|
||||||
_("Standard rates"),
|
|
||||||
(
|
|
||||||
# Standard rate in any country, such as 19% in Germany or 20% in Austria
|
|
||||||
# DSFinV-K mapping: 1
|
|
||||||
("S/standard", pgettext_lazy("tax_code", "Standard rate")),
|
|
||||||
|
|
||||||
# Reduced rate in any country, such as 7% in Germany or both 10% and 13% in Austria
|
|
||||||
# DSFinV-K mapping: 2
|
|
||||||
("S/reduced", pgettext_lazy("tax_code", "Reduced rate")),
|
|
||||||
|
|
||||||
# Averaged rate, for example Germany § 24 (1) Nr. 3 UStG "für die übrigen Umsätze" in agricultural and silvicultural businesses
|
|
||||||
# DSFinV-K mapping: 3
|
|
||||||
("S/averaged", pgettext_lazy("tax_code", "Averaged rate (other revenue in a agricultural and silvicultural business)")),
|
|
||||||
|
|
||||||
# We ignore the German special case of the actual silvicultural products as they won't be sold through pretix (DSFinV-K mapping: 4)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
_("Reverse charge"),
|
|
||||||
(
|
|
||||||
("AE", pgettext_lazy("tax_code", "Reverse charge")),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
_("Tax free"),
|
|
||||||
(
|
|
||||||
# DSFinV-K mapping: 5
|
|
||||||
("O", pgettext_lazy("tax_code", "Services outside of scope of tax")),
|
|
||||||
|
|
||||||
# DSFinV-K mapping: 6
|
|
||||||
("E", pgettext_lazy("tax_code", "Exempt from tax (no reason given)")),
|
|
||||||
|
|
||||||
# DSFinV-K mapping: 6
|
|
||||||
("Z", pgettext_lazy("tax_code", "Zero-rated goods")),
|
|
||||||
|
|
||||||
# DSFinV-K mapping: 5
|
|
||||||
("G", pgettext_lazy("tax_code", "Free export item, VAT not charged")),
|
|
||||||
|
|
||||||
# DSFinV-K mapping: 6?
|
|
||||||
("K", pgettext_lazy("tax_code", "VAT exempt for EEA intra-community supply of goods and services")),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
_("Special cases"),
|
|
||||||
(
|
|
||||||
("L", pgettext_lazy("tax_code", "Canary Islands general indirect tax")),
|
|
||||||
("M", pgettext_lazy("tax_code", "Tax for production, services and importation in Ceuta and Melilla")),
|
|
||||||
("B", pgettext_lazy("tax_code", "Transferred (VAT), only in Italy")),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
(
|
|
||||||
_("Exempt with specific reason"),
|
|
||||||
(
|
|
||||||
("E/VATEX-EU-79-C",
|
|
||||||
pgettext_lazy("tax_code", "Exempt based on article 79, point c of Council Directive 2006/112/EC")),
|
|
||||||
*[
|
|
||||||
(
|
|
||||||
f"E/VATEX-EU-132-1{letter.upper()}",
|
|
||||||
lazy(
|
|
||||||
lambda let: pgettext(
|
|
||||||
"tax_code",
|
|
||||||
"Exempt based on article {article}, section {section} ({letter}) of Council "
|
|
||||||
"Directive 2006/112/EC"
|
|
||||||
).format(article="132", section="1", letter=let),
|
|
||||||
str
|
|
||||||
)(letter)
|
|
||||||
) for letter in ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q")
|
|
||||||
],
|
|
||||||
*[
|
|
||||||
(
|
|
||||||
f"E/VATEX-EU-143-1{letter.upper()}",
|
|
||||||
lazy(
|
|
||||||
lambda let: pgettext(
|
|
||||||
"tax_code",
|
|
||||||
"Exempt based on article {article}, section {section} ({letter}) of Council "
|
|
||||||
"Directive 2006/112/EC"
|
|
||||||
).format(article="143", section="1", letter=let),
|
|
||||||
str
|
|
||||||
)(letter)
|
|
||||||
) for letter in ("a", "b", "c", "d", "e", "f", "fa", "g", "h", "i", "j", "k", "l")
|
|
||||||
],
|
|
||||||
*[
|
|
||||||
(
|
|
||||||
f"E/VATEX-EU-148-{letter.upper()}",
|
|
||||||
lazy(
|
|
||||||
lambda let: pgettext(
|
|
||||||
"tax_code",
|
|
||||||
"Exempt based on article {article}, section ({letter}) of Council "
|
|
||||||
"Directive 2006/112/EC"
|
|
||||||
).format(article="148", letter=let),
|
|
||||||
str
|
|
||||||
)(letter)
|
|
||||||
) for letter in ("a", "b", "c", "d", "e", "f", "g")
|
|
||||||
],
|
|
||||||
*[
|
|
||||||
(
|
|
||||||
f"E/VATEX-EU-151-1{letter.upper()}",
|
|
||||||
lazy(
|
|
||||||
lambda let: pgettext(
|
|
||||||
"tax_code",
|
|
||||||
"Exempt based on article {article}, section {section} ({letter}) of Council "
|
|
||||||
"Directive 2006/112/EC"
|
|
||||||
).format(article="151", section="1", letter=let),
|
|
||||||
str
|
|
||||||
)(letter)
|
|
||||||
) for letter in ("a", "aa", "b", "c", "d", "e")
|
|
||||||
],
|
|
||||||
("E/VATEX-EU-309",
|
|
||||||
pgettext_lazy("tax_code", "Exempt based on article 309 of Council Directive 2006/112/EC")),
|
|
||||||
("E/VATEX-EU-D",
|
|
||||||
pgettext_lazy("tax_code", "Intra-Community acquisition from second hand means of transport")),
|
|
||||||
("E/VATEX-EU-F",
|
|
||||||
pgettext_lazy("tax_code", "Intra-Community acquisition of second hand goods")),
|
|
||||||
("E/VATEX-EU-I",
|
|
||||||
pgettext_lazy("tax_code", "Intra-Community acquisition of works of art")),
|
|
||||||
("E/VATEX-EU-J",
|
|
||||||
pgettext_lazy("tax_code", "Intra-Community acquisition of collectors items and antiques")),
|
|
||||||
("E/VATEX-FR-FRANCHISE",
|
|
||||||
pgettext_lazy("tax_code", "France domestic VAT franchise in base")),
|
|
||||||
("E/VATEX-FR-CNWVAT",
|
|
||||||
pgettext_lazy("tax_code", "France domestic Credit Notes without VAT, due to supplier forfeit of VAT for discount")),
|
|
||||||
)
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_tax_code_labels():
|
|
||||||
flat = []
|
|
||||||
for choice, value in TAX_CODE_LISTS:
|
|
||||||
if isinstance(value, (list, tuple)):
|
|
||||||
flat.extend(value)
|
|
||||||
else:
|
|
||||||
flat.append((choice, value))
|
|
||||||
|
|
||||||
return dict(make_hashable(flat))
|
|
||||||
|
|
||||||
|
|
||||||
def is_eu_country(cc):
|
def is_eu_country(cc):
|
||||||
cc = str(cc)
|
cc = str(cc)
|
||||||
return cc in EU_COUNTRIES
|
return cc in EU_COUNTRIES
|
||||||
@@ -326,14 +173,6 @@ class TaxRule(LoggedModel):
|
|||||||
help_text=_('Should be short, e.g. "VAT"'),
|
help_text=_('Should be short, e.g. "VAT"'),
|
||||||
max_length=190,
|
max_length=190,
|
||||||
)
|
)
|
||||||
code = models.CharField(
|
|
||||||
verbose_name=_('Tax code'),
|
|
||||||
help_text=_('If you help us understand what this tax rules legally is, we can use this information for '
|
|
||||||
'eInvoices, exporting to accounting system, etc.'),
|
|
||||||
null=True, blank=True,
|
|
||||||
max_length=190,
|
|
||||||
choices=TAX_CODE_LISTS,
|
|
||||||
)
|
|
||||||
rate = models.DecimalField(
|
rate = models.DecimalField(
|
||||||
max_digits=10,
|
max_digits=10,
|
||||||
decimal_places=2,
|
decimal_places=2,
|
||||||
@@ -411,16 +250,6 @@ class TaxRule(LoggedModel):
|
|||||||
if self.eu_reverse_charge and not self.home_country:
|
if self.eu_reverse_charge and not self.home_country:
|
||||||
raise ValidationError(_('You need to set your home country to use the reverse charge feature.'))
|
raise ValidationError(_('You need to set your home country to use the reverse charge feature.'))
|
||||||
|
|
||||||
if self.rate != Decimal("0.00") and self.code and (self.code.split("/")[0] in ("O", "E", "Z", "G", "K", "AE")):
|
|
||||||
raise ValidationError({
|
|
||||||
"code": _("A combination of this tax code with a non-zero tax rate does not make sense.")
|
|
||||||
})
|
|
||||||
|
|
||||||
if self.rate == Decimal("0.00") and self.code and (self.code.split("/")[0] in ("S", "L", "M", "B")):
|
|
||||||
raise ValidationError({
|
|
||||||
"code": _("A combination of this tax code with a zero tax rate does not make sense.")
|
|
||||||
})
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.price_includes_tax:
|
if self.price_includes_tax:
|
||||||
s = _('incl. {rate}% {name}').format(rate=self.rate, name=self.name)
|
s = _('incl. {rate}% {name}').format(rate=self.rate, name=self.name)
|
||||||
@@ -447,9 +276,8 @@ class TaxRule(LoggedModel):
|
|||||||
return Decimal(rule.get('rate'))
|
return Decimal(rule.get('rate'))
|
||||||
return Decimal(self.rate)
|
return Decimal(self.rate)
|
||||||
|
|
||||||
def tax(self, base_price, base_price_is='auto', currency=None, override_tax_rate=None, override_tax_code=None,
|
def tax(self, base_price, base_price_is='auto', currency=None, override_tax_rate=None, invoice_address=None,
|
||||||
invoice_address=None, subtract_from_gross=Decimal('0.00'), gross_price_is_tax_rate: Decimal = None,
|
subtract_from_gross=Decimal('0.00'), gross_price_is_tax_rate: Decimal = None, force_fixed_gross_price=False):
|
||||||
force_fixed_gross_price=False):
|
|
||||||
from .event import Event
|
from .event import Event
|
||||||
try:
|
try:
|
||||||
currency = currency or self.event.currency
|
currency = currency or self.event.currency
|
||||||
@@ -457,13 +285,6 @@ class TaxRule(LoggedModel):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
rate = Decimal(self.rate)
|
rate = Decimal(self.rate)
|
||||||
code = self.code
|
|
||||||
|
|
||||||
if override_tax_code is not None:
|
|
||||||
code = override_tax_code
|
|
||||||
elif invoice_address:
|
|
||||||
code = self.tax_code_for(invoice_address)
|
|
||||||
|
|
||||||
if override_tax_rate is not None:
|
if override_tax_rate is not None:
|
||||||
rate = override_tax_rate
|
rate = override_tax_rate
|
||||||
elif invoice_address:
|
elif invoice_address:
|
||||||
@@ -496,8 +317,11 @@ class TaxRule(LoggedModel):
|
|||||||
if rate == Decimal('0.00'):
|
if rate == Decimal('0.00'):
|
||||||
gross = _limit_subtract(base_price, subtract_from_gross)
|
gross = _limit_subtract(base_price, subtract_from_gross)
|
||||||
return TaxedPrice(
|
return TaxedPrice(
|
||||||
net=gross, gross=gross, tax=Decimal('0.00'),
|
net=gross,
|
||||||
rate=rate, name=self.name, code=code,
|
gross=gross,
|
||||||
|
tax=Decimal('0.00'),
|
||||||
|
rate=rate,
|
||||||
|
name=self.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
if base_price_is == 'auto':
|
if base_price_is == 'auto':
|
||||||
@@ -522,7 +346,7 @@ class TaxRule(LoggedModel):
|
|||||||
|
|
||||||
return TaxedPrice(
|
return TaxedPrice(
|
||||||
net=net, gross=gross, tax=gross - net,
|
net=net, gross=gross, tax=gross - net,
|
||||||
rate=rate, name=self.name, code=code,
|
rate=rate, name=self.name
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -603,38 +427,6 @@ class TaxRule(LoggedModel):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def tax_code_for(self, invoice_address):
|
|
||||||
if self._custom_rules:
|
|
||||||
rule = self.get_matching_rule(invoice_address)
|
|
||||||
if rule.get("code"):
|
|
||||||
return rule["code"]
|
|
||||||
if rule.get("action", "vat") == "reverse":
|
|
||||||
return "AE"
|
|
||||||
return self.code
|
|
||||||
|
|
||||||
if not self.eu_reverse_charge:
|
|
||||||
# No reverse charge rules? Always apply VAT!
|
|
||||||
return self.code
|
|
||||||
|
|
||||||
if not invoice_address or not invoice_address.country:
|
|
||||||
# No country specified? Always apply VAT!
|
|
||||||
return self.code
|
|
||||||
|
|
||||||
if not is_eu_country(invoice_address.country):
|
|
||||||
# Non-EU country? "Non-taxable" since not in scope
|
|
||||||
return "O"
|
|
||||||
|
|
||||||
if invoice_address.country == self.home_country:
|
|
||||||
# Within same EU country? Always apply VAT!
|
|
||||||
return self.code
|
|
||||||
|
|
||||||
if invoice_address.is_business and invoice_address.vat_id and invoice_address.vat_id_validated:
|
|
||||||
# Reverse charge case
|
|
||||||
return "AE"
|
|
||||||
|
|
||||||
# Consumer in different EU country / invalid VAT
|
|
||||||
return self.code
|
|
||||||
|
|
||||||
def _tax_applicable(self, invoice_address):
|
def _tax_applicable(self, invoice_address):
|
||||||
if self._custom_rules:
|
if self._custom_rules:
|
||||||
rule = self.get_matching_rule(invoice_address)
|
rule = self.get_matching_rule(invoice_address)
|
||||||
|
|||||||
+33
-34
@@ -1419,51 +1419,50 @@ class GiftCardPayment(BasePaymentProvider):
|
|||||||
def payment_refund_supported(self, payment: OrderPayment) -> bool:
|
def payment_refund_supported(self, payment: OrderPayment) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _add_giftcard_to_cart(self, cs, gc):
|
|
||||||
from pretix.base.services.cart import add_payment_to_cart_session
|
|
||||||
|
|
||||||
if gc.currency != self.event.currency:
|
|
||||||
raise ValidationError(_("This gift card does not support this currency."))
|
|
||||||
if gc.testmode and not self.event.testmode:
|
|
||||||
raise ValidationError(_("This gift card can only be used in test mode."))
|
|
||||||
if not gc.testmode and self.event.testmode:
|
|
||||||
raise ValidationError(_("Only test gift cards can be used in test mode."))
|
|
||||||
if gc.expires and gc.expires < time_machine_now():
|
|
||||||
raise ValidationError(_("This gift card is no longer valid."))
|
|
||||||
if gc.value <= Decimal("0.00"):
|
|
||||||
raise ValidationError(_("All credit on this gift card has been used."))
|
|
||||||
|
|
||||||
for p in cs.get('payments', []):
|
|
||||||
if p['provider'] == self.identifier and p['info_data']['gift_card'] == gc.pk:
|
|
||||||
raise ValidationError(_("This gift card is already used for your payment."))
|
|
||||||
|
|
||||||
add_payment_to_cart_session(
|
|
||||||
cs,
|
|
||||||
self,
|
|
||||||
max_value=gc.value,
|
|
||||||
info_data={
|
|
||||||
'gift_card': gc.pk,
|
|
||||||
'gift_card_secret': gc.secret,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def checkout_prepare(self, request: HttpRequest, cart: Dict[str, Any]) -> Union[bool, str, None]:
|
def checkout_prepare(self, request: HttpRequest, cart: Dict[str, Any]) -> Union[bool, str, None]:
|
||||||
|
from pretix.base.services.cart import add_payment_to_cart
|
||||||
|
|
||||||
for p in get_cart(request):
|
for p in get_cart(request):
|
||||||
if p.item.issue_giftcard:
|
if p.item.issue_giftcard:
|
||||||
messages.error(request, _("You cannot pay with gift cards when buying a gift card."))
|
messages.error(request, _("You cannot pay with gift cards when buying a gift card."))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
cs = cart_session(request)
|
||||||
try:
|
try:
|
||||||
gc = self.event.organizer.accepted_gift_cards.get(
|
gc = self.event.organizer.accepted_gift_cards.get(
|
||||||
secret=request.POST.get("giftcard").strip()
|
secret=request.POST.get("giftcard").strip()
|
||||||
)
|
)
|
||||||
cs = cart_session(request)
|
if gc.currency != self.event.currency:
|
||||||
try:
|
messages.error(request, _("This gift card does not support this currency."))
|
||||||
self._add_giftcard_to_cart(cs, gc)
|
|
||||||
return True
|
|
||||||
except ValidationError as e:
|
|
||||||
messages.error(request, str(e.message))
|
|
||||||
return
|
return
|
||||||
|
if gc.testmode and not self.event.testmode:
|
||||||
|
messages.error(request, _("This gift card can only be used in test mode."))
|
||||||
|
return
|
||||||
|
if not gc.testmode and self.event.testmode:
|
||||||
|
messages.error(request, _("Only test gift cards can be used in test mode."))
|
||||||
|
return
|
||||||
|
if gc.expires and gc.expires < time_machine_now():
|
||||||
|
messages.error(request, _("This gift card is no longer valid."))
|
||||||
|
return
|
||||||
|
if gc.value <= Decimal("0.00"):
|
||||||
|
messages.error(request, _("All credit on this gift card has been used."))
|
||||||
|
return
|
||||||
|
|
||||||
|
for p in cs.get('payments', []):
|
||||||
|
if p['provider'] == self.identifier and p['info_data']['gift_card'] == gc.pk:
|
||||||
|
messages.error(request, _("This gift card is already used for your payment."))
|
||||||
|
return
|
||||||
|
|
||||||
|
add_payment_to_cart(
|
||||||
|
request,
|
||||||
|
self,
|
||||||
|
max_value=gc.value,
|
||||||
|
info_data={
|
||||||
|
'gift_card': gc.pk,
|
||||||
|
'gift_card_secret': gc.secret,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return True
|
||||||
except GiftCard.DoesNotExist:
|
except GiftCard.DoesNotExist:
|
||||||
if self.event.vouchers.filter(code__iexact=request.POST.get("giftcard")).exists():
|
if self.event.vouchers.filter(code__iexact=request.POST.get("giftcard")).exists():
|
||||||
messages.warning(request, _("You entered a voucher instead of a gift card. Vouchers can only be entered on the first page of the shop below "
|
messages.warning(request, _("You entered a voucher instead of a gift card. Vouchers can only be entered on the first page of the shop below "
|
||||||
|
|||||||
@@ -1426,28 +1426,6 @@ class CartManager:
|
|||||||
raise CartError(err)
|
raise CartError(err)
|
||||||
|
|
||||||
|
|
||||||
def add_payment_to_cart_session(cart_session, provider, min_value: Decimal=None, max_value: Decimal=None, info_data: dict=None):
|
|
||||||
"""
|
|
||||||
:param cart_session: The current cart session.
|
|
||||||
:param provider: The instance of your payment provider.
|
|
||||||
:param min_value: The minimum value this payment instrument supports, or ``None`` for unlimited.
|
|
||||||
:param max_value: The maximum value this payment instrument supports, or ``None`` for unlimited. Highly discouraged
|
|
||||||
to use for payment providers which charge a payment fee, as this can be very user-unfriendly if
|
|
||||||
users need a second payment method just for the payment fee of the first method.
|
|
||||||
:param info_data: A dictionary of information that will be passed through to the ``OrderPayment.info_data`` attribute.
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
cart_session.setdefault('payments', [])
|
|
||||||
cart_session['payments'].append({
|
|
||||||
'id': str(uuid.uuid4()),
|
|
||||||
'provider': provider.identifier,
|
|
||||||
'multi_use_supported': provider.multi_use_supported,
|
|
||||||
'min_value': str(min_value) if min_value is not None else None,
|
|
||||||
'max_value': str(max_value) if max_value is not None else None,
|
|
||||||
'info_data': info_data or {},
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def add_payment_to_cart(request, provider, min_value: Decimal=None, max_value: Decimal=None, info_data: dict=None):
|
def add_payment_to_cart(request, provider, min_value: Decimal=None, max_value: Decimal=None, info_data: dict=None):
|
||||||
"""
|
"""
|
||||||
:param request: The current HTTP request context.
|
:param request: The current HTTP request context.
|
||||||
@@ -1462,7 +1440,16 @@ def add_payment_to_cart(request, provider, min_value: Decimal=None, max_value: D
|
|||||||
from pretix.presale.views.cart import cart_session
|
from pretix.presale.views.cart import cart_session
|
||||||
|
|
||||||
cs = cart_session(request)
|
cs = cart_session(request)
|
||||||
add_payment_to_cart_session(cs, provider, min_value, max_value, info_data)
|
cs.setdefault('payments', [])
|
||||||
|
|
||||||
|
cs['payments'].append({
|
||||||
|
'id': str(uuid.uuid4()),
|
||||||
|
'provider': provider.identifier,
|
||||||
|
'multi_use_supported': provider.multi_use_supported,
|
||||||
|
'min_value': str(min_value) if min_value is not None else None,
|
||||||
|
'max_value': str(max_value) if max_value is not None else None,
|
||||||
|
'info_data': info_data or {},
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def get_fees(event, request, total, invoice_address, payments, positions):
|
def get_fees(event, request, total, invoice_address, payments, positions):
|
||||||
@@ -1513,7 +1500,6 @@ def get_fees(event, request, total, invoice_address, payments, positions):
|
|||||||
value=payment_fee,
|
value=payment_fee,
|
||||||
tax_rate=payment_fee_tax.rate,
|
tax_rate=payment_fee_tax.rate,
|
||||||
tax_value=payment_fee_tax.tax,
|
tax_value=payment_fee_tax.tax,
|
||||||
tax_code=payment_fee_tax.code,
|
|
||||||
tax_rule=payment_fee_tax_rule
|
tax_rule=payment_fee_tax_rule
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
@@ -271,9 +271,7 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
event_date_from=p.subevent.date_from if invoice.event.has_subevents else invoice.event.date_from,
|
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,
|
event_date_to=p.subevent.date_to if invoice.event.has_subevents else invoice.event.date_to,
|
||||||
event_location=location if invoice.event.settings.invoice_event_location else None,
|
event_location=location if invoice.event.settings.invoice_event_location else None,
|
||||||
tax_rate=p.tax_rate,
|
tax_rate=p.tax_rate, tax_name=p.tax_rule.name if p.tax_rule else ''
|
||||||
tax_code=p.tax_code,
|
|
||||||
tax_name=p.tax_rule.name if p.tax_rule else ''
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if p.tax_rule and p.tax_rule.is_reverse_charge(ia) and p.price and not p.tax_value:
|
if p.tax_rule and p.tax_rule.is_reverse_charge(ia) and p.price and not p.tax_value:
|
||||||
@@ -307,7 +305,6 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
|||||||
),
|
),
|
||||||
tax_value=fee.tax_value,
|
tax_value=fee.tax_value,
|
||||||
tax_rate=fee.tax_rate,
|
tax_rate=fee.tax_rate,
|
||||||
tax_code=fee.tax_code,
|
|
||||||
tax_name=fee.tax_rule.name if fee.tax_rule else '',
|
tax_name=fee.tax_rule.name if fee.tax_rule else '',
|
||||||
fee_type=fee.fee_type,
|
fee_type=fee.fee_type,
|
||||||
fee_internal_type=fee.internal_type or None,
|
fee_internal_type=fee.internal_type or None,
|
||||||
@@ -494,13 +491,13 @@ def build_preview_invoice_pdf(event):
|
|||||||
InvoiceLine.objects.create(
|
InvoiceLine.objects.create(
|
||||||
invoice=invoice, description=_("Sample product {}").format(i + 1),
|
invoice=invoice, description=_("Sample product {}").format(i + 1),
|
||||||
gross_value=tax.gross, tax_value=tax.tax,
|
gross_value=tax.gross, tax_value=tax.tax,
|
||||||
tax_rate=tax.rate, tax_name=tax.name, tax_code=tax.code,
|
tax_rate=tax.rate, tax_name=tax.name
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
InvoiceLine.objects.create(
|
InvoiceLine.objects.create(
|
||||||
invoice=invoice, description=_("Sample product A"),
|
invoice=invoice, description=_("Sample product A"),
|
||||||
gross_value=100, tax_value=0, tax_rate=0, tax_code=None,
|
gross_value=100, tax_value=0, tax_rate=0
|
||||||
)
|
)
|
||||||
|
|
||||||
return event.invoice_renderer.generate(invoice)
|
return event.invoice_renderer.generate(invoice)
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ from pretix.base.services.tasks import TransactionAwareTask
|
|||||||
from pretix.base.services.tickets import get_tickets_for_order
|
from pretix.base.services.tickets import get_tickets_for_order
|
||||||
from pretix.base.signals import email_filter, global_email_filter
|
from pretix.base.signals import email_filter, global_email_filter
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
from pretix.helpers.format import SafeFormatter, format_map
|
from pretix.helpers.format import format_map
|
||||||
from pretix.helpers.hierarkey import clean_filename
|
from pretix.helpers.hierarkey import clean_filename
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
from pretix.presale.ical import get_private_icals
|
from pretix.presale.ical import get_private_icals
|
||||||
@@ -311,13 +311,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
|||||||
try:
|
try:
|
||||||
if plain_text_only:
|
if plain_text_only:
|
||||||
body_html = None
|
body_html = None
|
||||||
elif 'context' in inspect.signature(renderer.render).parameters:
|
|
||||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position, context)
|
|
||||||
elif 'position' in inspect.signature(renderer.render).parameters:
|
elif 'position' in inspect.signature(renderer.render).parameters:
|
||||||
# Backwards compatibility
|
|
||||||
warnings.warn('Email renderer called without context argument because context argument is not '
|
|
||||||
'supported.',
|
|
||||||
DeprecationWarning)
|
|
||||||
body_html = renderer.render(content_plain, signature, raw_subject, order, position)
|
body_html = renderer.render(content_plain, signature, raw_subject, order, position)
|
||||||
else:
|
else:
|
||||||
# Backwards compatibility
|
# Backwards compatibility
|
||||||
@@ -329,8 +323,6 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
|||||||
logger.exception('Could not render HTML body')
|
logger.exception('Could not render HTML body')
|
||||||
body_html = None
|
body_html = None
|
||||||
|
|
||||||
body_plain = format_map(body_plain, context, mode=SafeFormatter.MODE_RICH_TO_PLAIN)
|
|
||||||
|
|
||||||
send_task = mail_send_task.si(
|
send_task = mail_send_task.si(
|
||||||
to=[email] if isinstance(email, str) else list(email),
|
to=[email] if isinstance(email, str) else list(email),
|
||||||
cc=cc,
|
cc=cc,
|
||||||
@@ -663,7 +655,7 @@ def render_mail(template, context):
|
|||||||
if isinstance(template, LazyI18nString):
|
if isinstance(template, LazyI18nString):
|
||||||
body = str(template)
|
body = str(template)
|
||||||
if context:
|
if context:
|
||||||
body = format_map(body, context, mode=SafeFormatter.MODE_IGNORE_RICH)
|
body = format_map(body, context)
|
||||||
else:
|
else:
|
||||||
tpl = get_template(template)
|
tpl = get_template(template)
|
||||||
body = tpl.render(context)
|
body = tpl.render(context)
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
c.assign(record.get(c.identifier), order, position, order._address)
|
c.assign(record.get(c.identifier), order, position, order._address)
|
||||||
|
|
||||||
if position.seat is not None:
|
if position.seat is not None:
|
||||||
lock_seats.append((order.sales_channel, position.seat))
|
lock_seats.append(position.seat)
|
||||||
except (ValidationError, ImportError) as e:
|
except (ValidationError, ImportError) as e:
|
||||||
raise DataImportError(
|
raise DataImportError(
|
||||||
_('Invalid data in row {row}: {message}').format(row=i, message=str(e))
|
_('Invalid data in row {row}: {message}').format(row=i, message=str(e))
|
||||||
@@ -128,9 +128,9 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# We don't support vouchers, quotas, or memberships here, so we only need to lock if seats are in use
|
# We don't support vouchers, quotas, or memberships here, so we only need to lock if seats are in use
|
||||||
if lock_seats:
|
if lock_seats:
|
||||||
lock_objects([s for c, s in lock_seats], shared_lock_objects=[event])
|
lock_objects(lock_seats, shared_lock_objects=[event])
|
||||||
for c, s in lock_seats:
|
for s in lock_seats:
|
||||||
if not s.is_available(sales_channel=c):
|
if not s.is_available():
|
||||||
raise DataImportError(_('The seat you selected has already been taken. Please select a different seat.'))
|
raise DataImportError(_('The seat you selected has already been taken. Please select a different seat.'))
|
||||||
|
|
||||||
save_transactions = []
|
save_transactions = []
|
||||||
|
|||||||
@@ -1721,17 +1721,16 @@ class OrderChangeManager:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
new_rate = tax_rule.tax_rate_for(ia)
|
new_rate = tax_rule.tax_rate_for(ia)
|
||||||
new_code = tax_rule.tax_code_for(ia)
|
|
||||||
except TaxRule.SaleNotAllowed:
|
except TaxRule.SaleNotAllowed:
|
||||||
raise OrderError(error_messages['tax_rule_country_blocked'])
|
raise OrderError(error_messages['tax_rule_country_blocked'])
|
||||||
# We use override_tax_rate to make sure .tax() doesn't get clever and re-adjusts the pricing itself
|
# We use override_tax_rate to make sure .tax() doesn't get clever and re-adjusts the pricing itself
|
||||||
if new_rate != pos.tax_rate or new_code != pos.tax_code:
|
if new_rate != pos.tax_rate:
|
||||||
if keep == 'net':
|
if keep == 'net':
|
||||||
new_tax = tax_rule.tax(pos.price - pos.tax_value, base_price_is='net', currency=self.event.currency,
|
new_tax = tax_rule.tax(pos.price - pos.tax_value, base_price_is='net', currency=self.event.currency,
|
||||||
override_tax_rate=new_rate, override_tax_code=new_code)
|
override_tax_rate=new_rate)
|
||||||
else:
|
else:
|
||||||
new_tax = tax_rule.tax(pos.price, base_price_is='gross', currency=self.event.currency,
|
new_tax = tax_rule.tax(pos.price, base_price_is='gross', currency=self.event.currency,
|
||||||
override_tax_rate=new_rate, override_tax_code=new_code)
|
override_tax_rate=new_rate)
|
||||||
self._totaldiff += new_tax.gross - pos.price
|
self._totaldiff += new_tax.gross - pos.price
|
||||||
self._operations.append(self.PriceOperation(pos, new_tax, new_tax.gross - pos.price))
|
self._operations.append(self.PriceOperation(pos, new_tax, new_tax.gross - pos.price))
|
||||||
self._invoice_dirty = True
|
self._invoice_dirty = True
|
||||||
@@ -2305,7 +2304,6 @@ class OrderChangeManager:
|
|||||||
op.position.price = op.price.gross
|
op.position.price = op.price.gross
|
||||||
op.position.tax_rate = op.price.rate
|
op.position.tax_rate = op.price.rate
|
||||||
op.position.tax_value = op.price.tax
|
op.position.tax_value = op.price.tax
|
||||||
op.position.tax_code = op.price.code
|
|
||||||
op.position.save()
|
op.position.save()
|
||||||
elif isinstance(op, self.TaxRuleOperation):
|
elif isinstance(op, self.TaxRuleOperation):
|
||||||
if isinstance(op.position, OrderPosition):
|
if isinstance(op.position, OrderPosition):
|
||||||
@@ -2402,7 +2400,7 @@ class OrderChangeManager:
|
|||||||
elif isinstance(op, self.AddOperation):
|
elif isinstance(op, self.AddOperation):
|
||||||
pos = OrderPosition.objects.create(
|
pos = OrderPosition.objects.create(
|
||||||
item=op.item, variation=op.variation, addon_to=op.addon_to,
|
item=op.item, variation=op.variation, addon_to=op.addon_to,
|
||||||
price=op.price.gross, order=self.order, tax_rate=op.price.rate, tax_code=op.price.code,
|
price=op.price.gross, order=self.order, tax_rate=op.price.rate,
|
||||||
tax_value=op.price.tax, tax_rule=op.item.tax_rule,
|
tax_value=op.price.tax, tax_rule=op.item.tax_rule,
|
||||||
positionid=nextposid, subevent=op.subevent, seat=op.seat,
|
positionid=nextposid, subevent=op.subevent, seat=op.seat,
|
||||||
used_membership=op.membership, valid_from=op.valid_from, valid_until=op.valid_until,
|
used_membership=op.membership, valid_from=op.valid_from, valid_until=op.valid_until,
|
||||||
@@ -2425,8 +2423,6 @@ class OrderChangeManager:
|
|||||||
elif isinstance(op, self.SplitOperation):
|
elif isinstance(op, self.SplitOperation):
|
||||||
split_positions.append(op.position)
|
split_positions.append(op.position)
|
||||||
elif isinstance(op, self.RegenerateSecretOperation):
|
elif isinstance(op, self.RegenerateSecretOperation):
|
||||||
op.position.web_secret = generate_secret()
|
|
||||||
op.position.save(update_fields=["web_secret"])
|
|
||||||
assign_ticket_secret(
|
assign_ticket_secret(
|
||||||
event=self.event, position=op.position, force_invalidate=True, save=True
|
event=self.event, position=op.position, force_invalidate=True, save=True
|
||||||
)
|
)
|
||||||
@@ -2533,7 +2529,6 @@ class OrderChangeManager:
|
|||||||
'new_order': split_order.code,
|
'new_order': split_order.code,
|
||||||
})
|
})
|
||||||
op.order = split_order
|
op.order = split_order
|
||||||
op.web_secret = generate_secret()
|
|
||||||
assign_ticket_secret(
|
assign_ticket_secret(
|
||||||
self.event, position=op, force_invalidate=True,
|
self.event, position=op, force_invalidate=True,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ from decimal import Decimal
|
|||||||
|
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils.formats import date_format
|
from django.utils.formats import date_format
|
||||||
from django.utils.html import escape
|
|
||||||
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 _
|
||||||
|
|
||||||
@@ -40,8 +39,7 @@ from pretix.base.settings import PERSON_NAME_SCHEMES, get_name_parts_localized
|
|||||||
from pretix.base.signals import (
|
from pretix.base.signals import (
|
||||||
register_mail_placeholders, register_text_placeholders,
|
register_mail_placeholders, register_text_placeholders,
|
||||||
)
|
)
|
||||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
from pretix.helpers.format import SafeFormatter
|
||||||
from pretix.helpers.format import PlainHtmlAlternativeString, SafeFormatter
|
|
||||||
|
|
||||||
logger = logging.getLogger('pretix.base.services.placeholders')
|
logger = logging.getLogger('pretix.base.services.placeholders')
|
||||||
|
|
||||||
@@ -109,91 +107,6 @@ class SimpleFunctionalTextPlaceholder(BaseTextPlaceholder):
|
|||||||
return self._sample
|
return self._sample
|
||||||
|
|
||||||
|
|
||||||
class BaseRichTextPlaceholder(BaseTextPlaceholder):
|
|
||||||
"""
|
|
||||||
This is the base class for all placeholders which can render either to plain text
|
|
||||||
or to a rich HTML element.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, identifier, args):
|
|
||||||
self._identifier = identifier
|
|
||||||
self._args = args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def identifier(self):
|
|
||||||
return self._identifier
|
|
||||||
|
|
||||||
@property
|
|
||||||
def required_context(self):
|
|
||||||
return self._args
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_block(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def render(self, context):
|
|
||||||
return PlainHtmlAlternativeString(
|
|
||||||
self.render_plain(**{k: context[k] for k in self._args}),
|
|
||||||
self.render_html(**{k: context[k] for k in self._args}),
|
|
||||||
self.is_block,
|
|
||||||
)
|
|
||||||
|
|
||||||
def render_html(self, **kwargs):
|
|
||||||
"""
|
|
||||||
HTML rendering of the placeholder. Should return "safe" HTML, i.e. everything needs to be
|
|
||||||
escaped.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def render_plain(self, **kwargs):
|
|
||||||
"""
|
|
||||||
Plain text rendering of the placeholder.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def render_sample(self, event):
|
|
||||||
return PlainHtmlAlternativeString(
|
|
||||||
self.render_sample_plain(event=event),
|
|
||||||
self.render_sample_html(event=event),
|
|
||||||
self.is_block,
|
|
||||||
)
|
|
||||||
|
|
||||||
def render_sample_html(self, event):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def render_sample_plain(self, event):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleButtonPlaceholder(BaseRichTextPlaceholder):
|
|
||||||
def __init__(self, identifier, args, url_func, text_func, sample_url_func, sample_text_func):
|
|
||||||
super().__init__(identifier, args)
|
|
||||||
self._url_func = url_func
|
|
||||||
self._text_func = text_func
|
|
||||||
self._sample_url_func = sample_url_func
|
|
||||||
self._sample_text_func = sample_text_func
|
|
||||||
|
|
||||||
def render_html(self, **context):
|
|
||||||
text = self._text_func(**{k: context[k] for k in self._args})
|
|
||||||
url = self._url_func(**{k: context[k] for k in self._args})
|
|
||||||
return f'<a href="{url}" class="button">{escape(text)}</a>'
|
|
||||||
|
|
||||||
def render_plain(self, **context):
|
|
||||||
text = self._text_func(**{k: context[k] for k in self._args})
|
|
||||||
url = self._url_func(**{k: context[k] for k in self._args})
|
|
||||||
return f'{text}: {url}'
|
|
||||||
|
|
||||||
def render_sample_html(self, event):
|
|
||||||
text = self._sample_text_func(event)
|
|
||||||
url = self._sample_url_func(event)
|
|
||||||
return f'<a href="{url}" class="button">{escape(text)}</a>'
|
|
||||||
|
|
||||||
def render_sample_plain(self, event):
|
|
||||||
text = self._sample_text_func(event)
|
|
||||||
url = self._sample_url_func(event)
|
|
||||||
return f'{text}: {url}'
|
|
||||||
|
|
||||||
|
|
||||||
class PlaceholderContext(SafeFormatter):
|
class PlaceholderContext(SafeFormatter):
|
||||||
"""
|
"""
|
||||||
Holds the contextual arguments and corresponding list of available placeholders for formatting
|
Holds the contextual arguments and corresponding list of available placeholders for formatting
|
||||||
@@ -371,27 +284,6 @@ def base_placeholders(sender, **kwargs):
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SimpleButtonPlaceholder(
|
|
||||||
'url_button', ['order', 'event'],
|
|
||||||
url_func=lambda order, event: build_absolute_uri(
|
|
||||||
event,
|
|
||||||
'presale:event.order.open', kwargs={
|
|
||||||
'order': order.code,
|
|
||||||
'secret': order.secret,
|
|
||||||
'hash': order.email_confirm_secret()
|
|
||||||
}
|
|
||||||
),
|
|
||||||
text_func=lambda order, event: _("View order details"),
|
|
||||||
sample_url_func=lambda event: build_absolute_uri(
|
|
||||||
event,
|
|
||||||
'presale:event.order.open', kwargs={
|
|
||||||
'order': 'F8VVL',
|
|
||||||
'secret': '6zzjnumtsx136ddy',
|
|
||||||
'hash': '98kusd8ofsj8dnkd'
|
|
||||||
}
|
|
||||||
),
|
|
||||||
sample_text_func=lambda event: _("View order details"),
|
|
||||||
),
|
|
||||||
SimpleFunctionalTextPlaceholder(
|
SimpleFunctionalTextPlaceholder(
|
||||||
'url_info_change', ['order', 'event'], lambda order, event: build_absolute_uri(
|
'url_info_change', ['order', 'event'], lambda order, event: build_absolute_uri(
|
||||||
event,
|
event,
|
||||||
@@ -456,27 +348,6 @@ def base_placeholders(sender, **kwargs):
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SimpleButtonPlaceholder(
|
|
||||||
'url_button', ['event', 'position'],
|
|
||||||
url_func=lambda event, position: build_absolute_uri(
|
|
||||||
event,
|
|
||||||
'presale:event.order.position', kwargs={
|
|
||||||
'order': position.order.code,
|
|
||||||
'secret': position.web_secret,
|
|
||||||
'position': position.positionid
|
|
||||||
}
|
|
||||||
),
|
|
||||||
text_func=lambda event, position: _("View registration details"),
|
|
||||||
sample_url_func=lambda event: build_absolute_uri(
|
|
||||||
event,
|
|
||||||
'presale:event.order.position', kwargs={
|
|
||||||
'order': 'F8VVL',
|
|
||||||
'secret': '6zzjnumtsx136ddy',
|
|
||||||
'position': '123'
|
|
||||||
}
|
|
||||||
),
|
|
||||||
sample_text_func=lambda event: _("View registration details"),
|
|
||||||
),
|
|
||||||
SimpleFunctionalTextPlaceholder(
|
SimpleFunctionalTextPlaceholder(
|
||||||
'url_info_change', ['position', 'event'], lambda position, event: build_absolute_uri(
|
'url_info_change', ['position', 'event'], lambda position, event: build_absolute_uri(
|
||||||
event,
|
event,
|
||||||
@@ -732,8 +603,8 @@ def base_placeholders(sender, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
class FormPlaceholderMixin:
|
class FormPlaceholderMixin:
|
||||||
def _set_field_placeholders(self, fn, base_parameters, rich=False):
|
def _set_field_placeholders(self, fn, base_parameters):
|
||||||
placeholders = get_available_placeholders(self.event, base_parameters, rich=rich)
|
placeholders = get_available_placeholders(self.event, base_parameters)
|
||||||
ht = format_placeholders_help_text(placeholders, self.event)
|
ht = format_placeholders_help_text(placeholders, self.event)
|
||||||
if self.fields[fn].help_text:
|
if self.fields[fn].help_text:
|
||||||
self.fields[fn].help_text += ' ' + str(ht)
|
self.fields[fn].help_text += ' ' + str(ht)
|
||||||
@@ -744,7 +615,7 @@ class FormPlaceholderMixin:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_available_placeholders(event, base_parameters, rich=False):
|
def get_available_placeholders(event, base_parameters):
|
||||||
if 'order' in base_parameters:
|
if 'order' in base_parameters:
|
||||||
base_parameters.append('invoice_address')
|
base_parameters.append('invoice_address')
|
||||||
base_parameters.append('position_or_address')
|
base_parameters.append('position_or_address')
|
||||||
@@ -753,35 +624,6 @@ def get_available_placeholders(event, base_parameters, rich=False):
|
|||||||
if not isinstance(val, (list, tuple)):
|
if not isinstance(val, (list, tuple)):
|
||||||
val = [val]
|
val = [val]
|
||||||
for v in val:
|
for v in val:
|
||||||
if isinstance(v, BaseRichTextPlaceholder) and not rich:
|
|
||||||
continue
|
|
||||||
if all(rp in base_parameters for rp in v.required_context):
|
if all(rp in base_parameters for rp in v.required_context):
|
||||||
params[v.identifier] = v
|
params[v.identifier] = v
|
||||||
return params
|
return params
|
||||||
|
|
||||||
|
|
||||||
def get_sample_context(event, context_parameters, rich=True):
|
|
||||||
context_dict = {}
|
|
||||||
lbl = _('This value will be replaced based on dynamic parameters.')
|
|
||||||
for k, v in get_available_placeholders(event, context_parameters, rich=rich).items():
|
|
||||||
sample = v.render_sample(event)
|
|
||||||
if isinstance(sample, PlainHtmlAlternativeString):
|
|
||||||
context_dict[k] = PlainHtmlAlternativeString(
|
|
||||||
sample.plain,
|
|
||||||
'<{el} class="placeholder placeholder-html" title="{title}">{html}</{el}>'.format(
|
|
||||||
el='div' if sample.is_block else 'span',
|
|
||||||
title=lbl,
|
|
||||||
html=sample.html,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
elif str(sample).strip().startswith('* ') or str(sample).startswith(' '):
|
|
||||||
context_dict[k] = '<div class="placeholder" title="{}">{}</div>'.format(
|
|
||||||
lbl,
|
|
||||||
markdown_compile_email(str(sample))
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
context_dict[k] = '<span class="placeholder" title="{}">{}</span>'.format(
|
|
||||||
lbl,
|
|
||||||
escape(sample)
|
|
||||||
)
|
|
||||||
return context_dict
|
|
||||||
|
|||||||
@@ -91,11 +91,9 @@ def get_price(item: Item, variation: ItemVariation = None,
|
|||||||
|
|
||||||
if custom_price_is_net:
|
if custom_price_is_net:
|
||||||
price = tax_rule.tax(max(custom_price, price.net), base_price_is='net', override_tax_rate=price.rate,
|
price = tax_rule.tax(max(custom_price, price.net), base_price_is='net', override_tax_rate=price.rate,
|
||||||
override_tax_code=price.code,
|
|
||||||
invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
||||||
else:
|
else:
|
||||||
price = tax_rule.tax(max(custom_price, price.gross), base_price_is='gross', override_tax_rate=price.rate,
|
price = tax_rule.tax(max(custom_price, price.gross), base_price_is='gross', override_tax_rate=price.rate,
|
||||||
override_tax_code=price.code,
|
|
||||||
invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
||||||
else:
|
else:
|
||||||
price = tax_rule.tax(price, invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
price = tax_rule.tax(price, invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
||||||
@@ -148,12 +146,10 @@ def get_line_price(price_after_voucher: Decimal, custom_price_input: Decimal, cu
|
|||||||
|
|
||||||
if custom_price_input_is_net:
|
if custom_price_input_is_net:
|
||||||
price = tax_rule.tax(max(custom_price_input, price.net), base_price_is='net', override_tax_rate=price.rate,
|
price = tax_rule.tax(max(custom_price_input, price.net), base_price_is='net', override_tax_rate=price.rate,
|
||||||
override_tax_code=price.code, invoice_address=invoice_address,
|
invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
||||||
subtract_from_gross=bundled_sum)
|
|
||||||
else:
|
else:
|
||||||
price = tax_rule.tax(max(custom_price_input, price.gross), base_price_is='gross', override_tax_rate=price.rate,
|
price = tax_rule.tax(max(custom_price_input, price.gross), base_price_is='gross', override_tax_rate=price.rate,
|
||||||
override_tax_code=price.code, invoice_address=invoice_address,
|
invoice_address=invoice_address, subtract_from_gross=bundled_sum)
|
||||||
subtract_from_gross=bundled_sum)
|
|
||||||
else:
|
else:
|
||||||
price = tax_rule.tax(price_after_voucher, invoice_address=invoice_address, subtract_from_gross=bundled_sum,
|
price = tax_rule.tax(price_after_voucher, invoice_address=invoice_address, subtract_from_gross=bundled_sum,
|
||||||
base_price_is='gross' if is_bundled else 'auto')
|
base_price_is='gross' if is_bundled else 'auto')
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
#
|
#
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@@ -98,9 +97,9 @@ def preview(event: int, provider: str):
|
|||||||
event = Event.objects.get(id=event)
|
event = Event.objects.get(id=event)
|
||||||
|
|
||||||
with rolledback_transaction(), language(event.settings.locale, event.settings.region):
|
with rolledback_transaction(), language(event.settings.locale, event.settings.region):
|
||||||
item = event.items.create(name=_("Sample product"), default_price=Decimal('42.23'),
|
item = event.items.create(name=_("Sample product"), default_price=42.23,
|
||||||
description=_("Sample product description"))
|
description=_("Sample product description"))
|
||||||
item2 = event.items.create(name=_("Sample workshop"), default_price=Decimal('23.40'))
|
item2 = event.items.create(name=_("Sample workshop"), default_price=23.40)
|
||||||
|
|
||||||
from pretix.base.models import Order
|
from pretix.base.models import Order
|
||||||
order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
|
order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ from django.utils.translation import (
|
|||||||
from django_countries.fields import Country
|
from django_countries.fields import Country
|
||||||
from hierarkey.models import GlobalSettingsBase, Hierarkey
|
from hierarkey.models import GlobalSettingsBase, Hierarkey
|
||||||
from i18nfield.forms import I18nFormField, I18nTextarea, I18nTextInput
|
from i18nfield.forms import I18nFormField, I18nTextarea, I18nTextInput
|
||||||
from i18nfield.rest_framework import I18nField
|
|
||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
from phonenumbers import PhoneNumber, parse
|
from phonenumbers import PhoneNumber, parse
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
@@ -64,7 +63,7 @@ from rest_framework import serializers
|
|||||||
from pretix.api.serializers.fields import (
|
from pretix.api.serializers.fields import (
|
||||||
ListMultipleChoiceField, UploadedFileField,
|
ListMultipleChoiceField, UploadedFileField,
|
||||||
)
|
)
|
||||||
from pretix.api.serializers.i18n import I18nURLField
|
from pretix.api.serializers.i18n import I18nField, I18nURLField
|
||||||
from pretix.base.forms import I18nMarkdownTextarea, I18nURLFormField
|
from pretix.base.forms import I18nMarkdownTextarea, I18nURLFormField
|
||||||
from pretix.base.models.tax import VAT_ID_COUNTRIES, TaxRule
|
from pretix.base.models.tax import VAT_ID_COUNTRIES, TaxRule
|
||||||
from pretix.base.reldate import (
|
from pretix.base.reldate import (
|
||||||
|
|||||||
@@ -131,9 +131,6 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.content table td.align-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.button {
|
a.button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -181,9 +178,6 @@
|
|||||||
pre, pre code {
|
pre, pre code {
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
}
|
}
|
||||||
.text-right, .content table td.text-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
{% if rtl %}
|
{% if rtl %}
|
||||||
body {
|
body {
|
||||||
@@ -192,9 +186,6 @@
|
|||||||
.content {
|
.content {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.text-right, .content table td.text-right {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block addcss %}{% endblock %}
|
{% block addcss %}{% endblock %}
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ def money_filter(value: Decimal, arg='', hide_currency=False):
|
|||||||
# would make the numbers incorrect. If this branch executes, it's likely a bug in
|
# would make the numbers incorrect. If this branch executes, it's likely a bug in
|
||||||
# pretix, but we won't show wrong numbers!
|
# pretix, but we won't show wrong numbers!
|
||||||
if hide_currency:
|
if hide_currency:
|
||||||
return floatformat(value, "2g")
|
return floatformat(value, 2)
|
||||||
else:
|
else:
|
||||||
return '{} {}'.format(arg, floatformat(value, "2g"))
|
return '{} {}'.format(arg, floatformat(value, 2))
|
||||||
|
|
||||||
if hide_currency:
|
if hide_currency:
|
||||||
return floatformat(value, f"{places}g")
|
return floatformat(value, places)
|
||||||
|
|
||||||
locale_parts = translation.get_language().split("-", 1)
|
locale_parts = translation.get_language().split("-", 1)
|
||||||
locale = locale_parts[0]
|
locale = locale_parts[0]
|
||||||
@@ -70,7 +70,7 @@ def money_filter(value: Decimal, arg='', hide_currency=False):
|
|||||||
try:
|
try:
|
||||||
return format_currency(value, arg, locale=locale)
|
return format_currency(value, arg, locale=locale)
|
||||||
except:
|
except:
|
||||||
return '{} {}'.format(arg, floatformat(value, f"{places}g"))
|
return '{} {}'.format(arg, floatformat(value, places))
|
||||||
|
|
||||||
|
|
||||||
@register.filter("money_numberfield")
|
@register.filter("money_numberfield")
|
||||||
|
|||||||
@@ -305,7 +305,6 @@ def markdown_compile_email(source, allowed_tags=ALLOWED_TAGS, allowed_attributes
|
|||||||
source,
|
source,
|
||||||
extensions=[
|
extensions=[
|
||||||
'markdown.extensions.sane_lists',
|
'markdown.extensions.sane_lists',
|
||||||
'markdown.extensions.tables',
|
|
||||||
EmailNl2BrExtension(),
|
EmailNl2BrExtension(),
|
||||||
LinkifyAndCleanExtension(
|
LinkifyAndCleanExtension(
|
||||||
linker,
|
linker,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
# License for the specific language governing permissions and limitations under the License.
|
# License for the specific language governing permissions and limitations under the License.
|
||||||
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode, urlparse
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
import pycountry
|
import pycountry
|
||||||
@@ -63,7 +63,6 @@ from pretix.base.forms import (
|
|||||||
)
|
)
|
||||||
from pretix.base.models import Event, Organizer, TaxRule, Team
|
from pretix.base.models import Event, Organizer, TaxRule, Team
|
||||||
from pretix.base.models.event import EventFooterLink, EventMetaValue, SubEvent
|
from pretix.base.models.event import EventFooterLink, EventMetaValue, SubEvent
|
||||||
from pretix.base.models.tax import TAX_CODE_LISTS
|
|
||||||
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
|
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
|
||||||
from pretix.base.services.placeholders import FormPlaceholderMixin
|
from pretix.base.services.placeholders import FormPlaceholderMixin
|
||||||
from pretix.base.settings import (
|
from pretix.base.settings import (
|
||||||
@@ -77,10 +76,8 @@ from pretix.control.forms import (
|
|||||||
)
|
)
|
||||||
from pretix.control.forms.widgets import Select2
|
from pretix.control.forms.widgets import Select2
|
||||||
from pretix.helpers.countries import CachedCountries
|
from pretix.helpers.countries import CachedCountries
|
||||||
from pretix.multidomain.models import AlternativeDomainAssignment, KnownDomain
|
from pretix.multidomain.models import KnownDomain
|
||||||
from pretix.multidomain.urlreverse import (
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
build_absolute_uri, get_organizer_domain,
|
|
||||||
)
|
|
||||||
from pretix.plugins.banktransfer.payment import BankTransfer
|
from pretix.plugins.banktransfer.payment import BankTransfer
|
||||||
from pretix.presale.style import get_fonts
|
from pretix.presale.style import get_fonts
|
||||||
|
|
||||||
@@ -366,9 +363,14 @@ class EventUpdateForm(I18nModelForm):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.change_slug = kwargs.pop('change_slug', False)
|
self.change_slug = kwargs.pop('change_slug', False)
|
||||||
|
self.domain = kwargs.pop('domain', False)
|
||||||
|
|
||||||
kwargs.setdefault('initial', {})
|
kwargs.setdefault('initial', {})
|
||||||
self.instance = kwargs['instance']
|
self.instance = kwargs['instance']
|
||||||
|
if self.domain and self.instance:
|
||||||
|
initial_domain = self.instance.domains.first()
|
||||||
|
if initial_domain:
|
||||||
|
kwargs['initial'].setdefault('domain', initial_domain.domainname)
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
if not self.change_slug:
|
if not self.change_slug:
|
||||||
@@ -377,54 +379,48 @@ class EventUpdateForm(I18nModelForm):
|
|||||||
self.fields['location'].widget.attrs['placeholder'] = _(
|
self.fields['location'].widget.attrs['placeholder'] = _(
|
||||||
'Sample Conference Center\nHeidelberg, Germany'
|
'Sample Conference Center\nHeidelberg, Germany'
|
||||||
)
|
)
|
||||||
|
if self.domain:
|
||||||
try:
|
|
||||||
self.fields['domain'] = forms.CharField(
|
self.fields['domain'] = forms.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
label=_('Domain'),
|
label=_('Custom domain'),
|
||||||
initial=self.instance.domain.domainname,
|
|
||||||
required=False,
|
|
||||||
disabled=True,
|
|
||||||
help_text=_('You can configure this in your organizer settings.')
|
|
||||||
)
|
|
||||||
except KnownDomain.DoesNotExist:
|
|
||||||
domain = get_organizer_domain(self.instance.organizer)
|
|
||||||
try:
|
|
||||||
current_domain_assignment = self.instance.alternative_domain_assignment
|
|
||||||
except AlternativeDomainAssignment.DoesNotExist:
|
|
||||||
current_domain_assignment = None
|
|
||||||
self.fields['domain'] = forms.ChoiceField(
|
|
||||||
label=_('Domain'),
|
|
||||||
help_text=_('You can add more domains in your organizer account.'),
|
|
||||||
choices=[('', _('Same as organizer account') + (f" ({domain})" if domain else ""))] + [
|
|
||||||
(d.domainname, d.domainname) for d in self.instance.organizer.domains.filter(mode=KnownDomain.MODE_ORG_ALT_DOMAIN)
|
|
||||||
],
|
|
||||||
initial=current_domain_assignment.domain_id if current_domain_assignment else "",
|
|
||||||
required=False,
|
required=False,
|
||||||
|
help_text=_('You need to configure the custom domain in the webserver beforehand.')
|
||||||
)
|
)
|
||||||
self.fields['limit_sales_channels'].queryset = self.event.organizer.sales_channels.all()
|
self.fields['limit_sales_channels'].queryset = self.event.organizer.sales_channels.all()
|
||||||
self.fields['limit_sales_channels'].widget = SalesChannelCheckboxSelectMultiple(self.event, attrs={
|
self.fields['limit_sales_channels'].widget = SalesChannelCheckboxSelectMultiple(self.event, attrs={
|
||||||
'data-inverse-dependency': '<[name$=all_sales_channels]',
|
'data-inverse-dependency': '<[name$=all_sales_channels]',
|
||||||
}, choices=self.fields['limit_sales_channels'].widget.choices)
|
}, choices=self.fields['limit_sales_channels'].widget.choices)
|
||||||
|
|
||||||
|
def clean_domain(self):
|
||||||
|
d = self.cleaned_data['domain']
|
||||||
|
if d:
|
||||||
|
if d == urlparse(settings.SITE_URL).hostname:
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot choose the base domain of this installation.')
|
||||||
|
)
|
||||||
|
if KnownDomain.objects.filter(domainname=d).exclude(event=self.instance.pk).exists():
|
||||||
|
raise ValidationError(
|
||||||
|
_('This domain is already in use for a different event or organizer.')
|
||||||
|
)
|
||||||
|
return d
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
instance = super().save(commit)
|
instance = super().save(commit)
|
||||||
|
|
||||||
try:
|
if self.domain:
|
||||||
current_domain_assignment = instance.alternative_domain_assignment
|
current_domain = instance.domains.first()
|
||||||
except AlternativeDomainAssignment.DoesNotExist:
|
if self.cleaned_data['domain']:
|
||||||
current_domain_assignment = None
|
if current_domain and current_domain.domainname != self.cleaned_data['domain']:
|
||||||
if self.cleaned_data['domain'] and not hasattr(instance, 'domain'):
|
current_domain.delete()
|
||||||
domain = self.instance.organizer.domains.get(mode=KnownDomain.MODE_ORG_ALT_DOMAIN, domainname=self.cleaned_data["domain"])
|
KnownDomain.objects.create(
|
||||||
AlternativeDomainAssignment.objects.update_or_create(
|
organizer=instance.organizer, event=instance, domainname=self.cleaned_data['domain']
|
||||||
event=instance,
|
)
|
||||||
defaults={
|
elif not current_domain:
|
||||||
"domain": domain,
|
KnownDomain.objects.create(
|
||||||
}
|
organizer=instance.organizer, event=instance, domainname=self.cleaned_data['domain']
|
||||||
)
|
)
|
||||||
instance.cache.clear()
|
elif current_domain:
|
||||||
elif current_domain_assignment:
|
current_domain.delete()
|
||||||
current_domain_assignment.delete()
|
|
||||||
instance.cache.clear()
|
instance.cache.clear()
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
@@ -1386,7 +1382,7 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm):
|
|||||||
self.event.meta_values_cached = self.event.meta_values.select_related('property').all()
|
self.event.meta_values_cached = self.event.meta_values.select_related('property').all()
|
||||||
|
|
||||||
for k, v in self.base_context.items():
|
for k, v in self.base_context.items():
|
||||||
self._set_field_placeholders(k, v, rich=k.startswith('mail_text_'))
|
self._set_field_placeholders(k, v)
|
||||||
|
|
||||||
for k, v in list(self.fields.items()):
|
for k, v in list(self.fields.items()):
|
||||||
if k.endswith('_attendee') and not event.settings.attendee_emails_asked:
|
if k.endswith('_attendee') and not event.settings.attendee_emails_asked:
|
||||||
@@ -1505,11 +1501,6 @@ class TaxRuleLineForm(I18nForm):
|
|||||||
('require_approval', _('Order requires approval')),
|
('require_approval', _('Order requires approval')),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
code = forms.ChoiceField(
|
|
||||||
label=_("Tax code"),
|
|
||||||
choices=[("", _("Default tax code")), *TAX_CODE_LISTS],
|
|
||||||
required=False,
|
|
||||||
)
|
|
||||||
rate = forms.DecimalField(
|
rate = forms.DecimalField(
|
||||||
label=_('Deviating tax rate'),
|
label=_('Deviating tax rate'),
|
||||||
max_digits=10, decimal_places=2,
|
max_digits=10, decimal_places=2,
|
||||||
@@ -1524,43 +1515,6 @@ class TaxRuleLineForm(I18nForm):
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.parent_form = kwargs.pop("parent_form")
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
d = super().clean()
|
|
||||||
|
|
||||||
parent_code = self.parent_form.cleaned_data.get("code")
|
|
||||||
parent_rate = self.parent_form.cleaned_data.get("rate")
|
|
||||||
|
|
||||||
code = d.get("code") or parent_code
|
|
||||||
rate = d.get("rate")
|
|
||||||
if rate is None:
|
|
||||||
rate = parent_rate
|
|
||||||
|
|
||||||
if d.get("action") in ("reverse", "no", "block") and d.get("rate"):
|
|
||||||
raise ValidationError(_("A combination of this calculation mode with a non-zero tax rate does not make sense."))
|
|
||||||
|
|
||||||
if d.get("action") == "reverse" and d.get("code") and code != "AE":
|
|
||||||
# Reverse charge but code is not reverse charge -- this is the one case we ignore if the "default code"
|
|
||||||
# is used because it is the one scenario we can auto-fix
|
|
||||||
raise ValidationError(_("This combination of calculation mode and tax code does not make sense."))
|
|
||||||
|
|
||||||
if d.get("action") == "no" and code and code.split("/")[0] in ("S", "AE", "L", "M", "B"):
|
|
||||||
# No VAT but code indicates VAT
|
|
||||||
raise ValidationError(_("This combination of calculation mode and tax code does not make sense."))
|
|
||||||
|
|
||||||
if d.get("action") == "vat" and code and rate != Decimal("0.00") and code.split("/")[0] in ("O", "E", "Z", "G", "K", "AE"):
|
|
||||||
# VAT, but code indicates exempt
|
|
||||||
raise ValidationError(_("A combination of this tax code with a non-zero tax rate does not make sense."))
|
|
||||||
|
|
||||||
if d.get("action") == "vat" and code and rate == Decimal("0.00") and code.split("/")[0] in ("S", "L", "M", "B"):
|
|
||||||
# no VAT, but code indicates non-exempt
|
|
||||||
raise ValidationError(_("A combination of this tax code with a zero tax rate does not make sense."))
|
|
||||||
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
class I18nBaseFormSet(I18nFormSetMixin, forms.BaseFormSet):
|
class I18nBaseFormSet(I18nFormSetMixin, forms.BaseFormSet):
|
||||||
# compatibility shim for django-i18nfield library
|
# compatibility shim for django-i18nfield library
|
||||||
@@ -1572,16 +1526,8 @@ class I18nBaseFormSet(I18nFormSetMixin, forms.BaseFormSet):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class BaseTaxRuleLineFormSet(I18nBaseFormSet):
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.parent_form = kwargs.pop('parent_form')
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.form_kwargs['parent_form'] = self.parent_form
|
|
||||||
|
|
||||||
|
|
||||||
TaxRuleLineFormSet = formset_factory(
|
TaxRuleLineFormSet = formset_factory(
|
||||||
TaxRuleLineForm, formset=BaseTaxRuleLineFormSet,
|
TaxRuleLineForm, formset=I18nBaseFormSet,
|
||||||
can_order=True, can_delete=True, extra=0
|
can_order=True, can_delete=True, extra=0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1589,16 +1535,7 @@ TaxRuleLineFormSet = formset_factory(
|
|||||||
class TaxRuleForm(I18nModelForm):
|
class TaxRuleForm(I18nModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TaxRule
|
model = TaxRule
|
||||||
fields = [
|
fields = ['name', 'rate', 'price_includes_tax', 'eu_reverse_charge', 'home_country', 'internal_name', 'keep_gross_if_rate_changes']
|
||||||
'name',
|
|
||||||
'rate',
|
|
||||||
'price_includes_tax',
|
|
||||||
'code',
|
|
||||||
'eu_reverse_charge',
|
|
||||||
'home_country',
|
|
||||||
'internal_name',
|
|
||||||
'keep_gross_if_rate_changes'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class WidgetCodeForm(forms.Form):
|
class WidgetCodeForm(forms.Form):
|
||||||
|
|||||||
@@ -490,9 +490,7 @@ class OrderPositionChangeForm(forms.Form):
|
|||||||
)
|
)
|
||||||
operation_secret = forms.BooleanField(
|
operation_secret = forms.BooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
label=_('Generate a new secret'),
|
label=_('Generate a new secret')
|
||||||
help_text=_('This affects both the ticket secret (often used as a QR code) as well as the link used to '
|
|
||||||
'individually access the ticket.')
|
|
||||||
)
|
)
|
||||||
operation_cancel = forms.BooleanField(
|
operation_cancel = forms.BooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
|
|||||||
@@ -133,108 +133,63 @@ class OrganizerDeleteForm(forms.Form):
|
|||||||
class OrganizerUpdateForm(OrganizerForm):
|
class OrganizerUpdateForm(OrganizerForm):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.domain = kwargs.pop('domain', False)
|
||||||
self.change_slug = kwargs.pop('change_slug', False)
|
self.change_slug = kwargs.pop('change_slug', False)
|
||||||
kwargs.setdefault('initial', {})
|
kwargs.setdefault('initial', {})
|
||||||
self.instance = kwargs['instance']
|
self.instance = kwargs['instance']
|
||||||
|
if self.domain and self.instance:
|
||||||
|
initial_domain = self.instance.domains.filter(event__isnull=True).first()
|
||||||
|
if initial_domain:
|
||||||
|
kwargs['initial'].setdefault('domain', initial_domain.domainname)
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
if not self.change_slug:
|
if not self.change_slug:
|
||||||
self.fields['slug'].widget.attrs['readonly'] = 'readonly'
|
self.fields['slug'].widget.attrs['readonly'] = 'readonly'
|
||||||
|
if self.domain:
|
||||||
|
self.fields['domain'] = forms.CharField(
|
||||||
|
max_length=255,
|
||||||
|
label=_('Custom domain'),
|
||||||
|
required=False,
|
||||||
|
help_text=_('You need to configure the custom domain in the webserver beforehand.')
|
||||||
|
)
|
||||||
|
|
||||||
|
def clean_domain(self):
|
||||||
|
d = self.cleaned_data['domain']
|
||||||
|
if d:
|
||||||
|
if d == urlparse(settings.SITE_URL).hostname:
|
||||||
|
raise ValidationError(
|
||||||
|
_('You cannot choose the base domain of this installation.')
|
||||||
|
)
|
||||||
|
if KnownDomain.objects.filter(domainname=d).exclude(organizer=self.instance.pk,
|
||||||
|
event__isnull=True).exists():
|
||||||
|
raise ValidationError(
|
||||||
|
_('This domain is already in use for a different event or organizer.')
|
||||||
|
)
|
||||||
|
return d
|
||||||
|
|
||||||
def clean_slug(self):
|
def clean_slug(self):
|
||||||
if self.change_slug:
|
if self.change_slug:
|
||||||
return self.cleaned_data['slug']
|
return self.cleaned_data['slug']
|
||||||
return self.instance.slug
|
return self.instance.slug
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
instance = super().save(commit)
|
||||||
|
|
||||||
class KnownDomainForm(forms.ModelForm):
|
if self.domain:
|
||||||
class Meta:
|
current_domain = instance.domains.filter(event__isnull=True).first()
|
||||||
model = KnownDomain
|
if self.cleaned_data['domain']:
|
||||||
fields = ["domainname", "mode", "event"]
|
if current_domain and current_domain.domainname != self.cleaned_data['domain']:
|
||||||
field_classes = {
|
current_domain.delete()
|
||||||
"event": SafeModelChoiceField,
|
KnownDomain.objects.create(organizer=instance, domainname=self.cleaned_data['domain'])
|
||||||
}
|
elif not current_domain:
|
||||||
|
KnownDomain.objects.create(organizer=instance, domainname=self.cleaned_data['domain'])
|
||||||
|
elif current_domain:
|
||||||
|
current_domain.delete()
|
||||||
|
instance.cache.clear()
|
||||||
|
for ev in instance.events.all():
|
||||||
|
ev.cache.clear()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
return instance
|
||||||
self.organizer = kwargs.pop('organizer')
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.fields["event"].queryset = self.organizer.events.all()
|
|
||||||
if self.instance and self.instance.pk:
|
|
||||||
self.fields["domainname"].widget.attrs['readonly'] = 'readonly'
|
|
||||||
|
|
||||||
def clean_domainname(self):
|
|
||||||
if self.instance and self.instance.pk:
|
|
||||||
return self.instance.domainname
|
|
||||||
d = self.cleaned_data['domainname']
|
|
||||||
if d:
|
|
||||||
if d == urlparse(settings.SITE_URL).hostname:
|
|
||||||
raise ValidationError(
|
|
||||||
_('You cannot choose the base domain of this installation.')
|
|
||||||
)
|
|
||||||
if KnownDomain.objects.filter(domainname=d).exclude(organizer=self.instance.organizer).exists():
|
|
||||||
raise ValidationError(
|
|
||||||
_('This domain is already in use for a different event or organizer.')
|
|
||||||
)
|
|
||||||
return d
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
d = super().clean()
|
|
||||||
|
|
||||||
if d["mode"] == KnownDomain.MODE_ORG_DOMAIN and d["event"]:
|
|
||||||
raise ValidationError(
|
|
||||||
_("Do not choose an event for this mode.")
|
|
||||||
)
|
|
||||||
|
|
||||||
if d["mode"] == KnownDomain.MODE_ORG_ALT_DOMAIN and d["event"]:
|
|
||||||
raise ValidationError(
|
|
||||||
_("Do not choose an event for this mode. You can assign events to this domain in event settings.")
|
|
||||||
)
|
|
||||||
|
|
||||||
if d["mode"] == KnownDomain.MODE_EVENT_DOMAIN and not d["event"]:
|
|
||||||
raise ValidationError(
|
|
||||||
_("You need to choose an event.")
|
|
||||||
)
|
|
||||||
|
|
||||||
return d
|
|
||||||
|
|
||||||
|
|
||||||
class BaseKnownDomainFormSet(forms.BaseInlineFormSet):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.organizer = kwargs.pop('organizer')
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
def _construct_form(self, i, **kwargs):
|
|
||||||
kwargs['organizer'] = self.organizer
|
|
||||||
return super()._construct_form(i, **kwargs)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def empty_form(self):
|
|
||||||
form = self.form(
|
|
||||||
auto_id=self.auto_id,
|
|
||||||
prefix=self.add_prefix('__prefix__'),
|
|
||||||
empty_permitted=True,
|
|
||||||
use_required_attribute=False,
|
|
||||||
organizer=self.organizer,
|
|
||||||
)
|
|
||||||
self.add_fields(form, None)
|
|
||||||
return form
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
super().clean()
|
|
||||||
data = [f.cleaned_data for f in self.forms]
|
|
||||||
|
|
||||||
if len([d for d in data if d.get("mode") == KnownDomain.MODE_ORG_DOMAIN and not d.get("DELETE")]) > 1:
|
|
||||||
raise ValidationError(_("You may set only one organizer domain."))
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
KnownDomainFormset = inlineformset_factory(
|
|
||||||
Organizer, KnownDomain,
|
|
||||||
KnownDomainForm,
|
|
||||||
formset=BaseKnownDomainFormSet,
|
|
||||||
can_order=False, can_delete=True, extra=0
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SafeOrderPositionChoiceField(forms.ModelChoiceField):
|
class SafeOrderPositionChoiceField(forms.ModelChoiceField):
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
{% bootstrap_field form.name layout="control" %}
|
{% bootstrap_field form.name layout="control" %}
|
||||||
{% bootstrap_field form.slug layout="control" %}
|
{% bootstrap_field form.slug layout="control" %}
|
||||||
{% if form.domain %}
|
{% if form.domain %}
|
||||||
{% bootstrap_field form.domain layout="horizontal" %}
|
{% bootstrap_field form.domain layout="control" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% bootstrap_field form.date_from layout="control" %}
|
{% bootstrap_field form.date_from layout="control" %}
|
||||||
{% bootstrap_field form.date_to layout="control" %}
|
{% bootstrap_field form.date_to layout="control" %}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
{% bootstrap_field form.name layout="control" %}
|
{% bootstrap_field form.name layout="control" %}
|
||||||
{% bootstrap_field form.internal_name layout="control" %}
|
{% bootstrap_field form.internal_name layout="control" %}
|
||||||
{% bootstrap_field form.rate addon_after="%" layout="control" %}
|
{% bootstrap_field form.rate addon_after="%" layout="control" %}
|
||||||
{% bootstrap_field form.code layout="control" %}
|
|
||||||
{% bootstrap_field form.price_includes_tax layout="control" %}
|
{% bootstrap_field form.price_includes_tax layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
@@ -53,18 +52,6 @@
|
|||||||
{% trans "All of these rules will only apply if an invoice address is set." %}
|
{% trans "All of these rules will only apply if an invoice address is set." %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
|
||||||
<strong>{% trans "Condition" %}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
|
||||||
<strong>{% trans "Calculation" %}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3 col-lg-4 col-sm-offset-6 col-md-offset-0">
|
|
||||||
<strong>{% trans "Reason" %}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="formset tax-rules-formset" data-formset data-formset-prefix="{{ formset.prefix }}">
|
<div class="formset tax-rules-formset" data-formset data-formset-prefix="{{ formset.prefix }}">
|
||||||
{{ formset.management_form }}
|
{{ formset.management_form }}
|
||||||
{% bootstrap_formset_errors formset %}
|
{% bootstrap_formset_errors formset %}
|
||||||
@@ -78,17 +65,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||||
{% bootstrap_field formset.empty_form.country layout='inline' form_group_class="" %}
|
{% bootstrap_field formset.empty_form.country layout='inline' form_group_class="" %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-3 col-lg-4">
|
||||||
{% bootstrap_field formset.empty_form.address_type layout='inline' form_group_class="" %}
|
{% bootstrap_field formset.empty_form.address_type layout='inline' form_group_class="" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||||
{% bootstrap_field formset.empty_form.action layout='inline' form_group_class="" %}
|
{% bootstrap_field formset.empty_form.action layout='inline' form_group_class="" %}
|
||||||
{% bootstrap_field formset.empty_form.rate layout='inline' form_group_class="" %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-4 col-sm-offset-6 col-md-offset-0">
|
<div class="col-sm-6 col-md-3 col-lg-2 text-right flip">
|
||||||
{% bootstrap_field formset.empty_form.code layout='inline' form_group_class="" %}
|
|
||||||
{% bootstrap_field formset.empty_form.invoice_text layout='inline' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3 col-lg-2 col-sm-offset-6 col-md-offset-0 text-right flip">
|
|
||||||
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
||||||
<i class="fa fa-arrow-up"></i></button>
|
<i class="fa fa-arrow-up"></i></button>
|
||||||
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
||||||
@@ -96,6 +80,12 @@
|
|||||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
||||||
<i class="fa fa-trash"></i></button>
|
<i class="fa fa-trash"></i></button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-3 col-lg-4 col-md-offset-3">
|
||||||
|
{% bootstrap_field formset.empty_form.invoice_text layout='inline' form_group_class="" %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||||
|
{% bootstrap_field formset.empty_form.rate layout='inline' form_group_class="" %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endescapescript %}
|
{% endescapescript %}
|
||||||
</script>
|
</script>
|
||||||
@@ -110,17 +100,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||||
{% bootstrap_field form.country layout='inline' form_group_class="" %}
|
{% bootstrap_field form.country layout='inline' form_group_class="" %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-3 col-lg-4">
|
||||||
{% bootstrap_field form.address_type layout='inline' form_group_class="" %}
|
{% bootstrap_field form.address_type layout='inline' form_group_class="" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-3">
|
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||||
{% bootstrap_field form.action layout='inline' form_group_class="" %}
|
{% bootstrap_field form.action layout='inline' form_group_class="" %}
|
||||||
{% bootstrap_field form.rate layout='inline' form_group_class="" %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6 col-md-3 col-lg-4 col-sm-offset-6 col-md-offset-0">
|
<div class="col-sm-6 col-md-3 col-lg-2 text-right flip">
|
||||||
{% bootstrap_field form.code layout='inline' form_group_class="" %}
|
|
||||||
{% bootstrap_field form.invoice_text layout='inline' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6 col-md-3 col-lg-2 col-sm-offset-6 col-md-offset-0 text-right flip">
|
|
||||||
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
||||||
<i class="fa fa-arrow-up"></i></button>
|
<i class="fa fa-arrow-up"></i></button>
|
||||||
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
||||||
@@ -128,6 +115,12 @@
|
|||||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
||||||
<i class="fa fa-trash"></i></button>
|
<i class="fa fa-trash"></i></button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-3 col-lg-4 col-md-offset-3">
|
||||||
|
{% bootstrap_field form.invoice_text layout='inline' form_group_class="" %}
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 col-md-3 col-lg-3">
|
||||||
|
{% bootstrap_field form.rate layout='inline' form_group_class="" %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -220,6 +220,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% bootstrap_field formset.empty_form.available_from visibility_field=formset.empty_form.available_from_mode layout="control_with_visibility" %}
|
{% bootstrap_field formset.empty_form.available_from visibility_field=formset.empty_form.available_from_mode layout="control_with_visibility" %}
|
||||||
{% bootstrap_field formset.empty_form.available_until visibility_field=formset.empty_form.available_until_mode layout="control_with_visibility" %}
|
{% bootstrap_field formset.empty_form.available_until visibility_field=formset.empty_form.available_until_mode layout="control_with_visibility" %}
|
||||||
|
{% bootstrap_field formset.empty_form.available_until layout="control" %}
|
||||||
{% bootstrap_field formset.empty_form.all_sales_channels layout="control" %}
|
{% bootstrap_field formset.empty_form.all_sales_channels layout="control" %}
|
||||||
{% bootstrap_field formset.empty_form.limit_sales_channels layout="control" %}
|
{% bootstrap_field formset.empty_form.limit_sales_channels layout="control" %}
|
||||||
{% bootstrap_field formset.empty_form.hide_without_voucher layout="control" %}
|
{% bootstrap_field formset.empty_form.hide_without_voucher layout="control" %}
|
||||||
|
|||||||
@@ -202,12 +202,6 @@
|
|||||||
+ {{ position.tax_rate }}%)
|
+ {{ position.tax_rate }}%)
|
||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if position.tax_code %}
|
|
||||||
<br>
|
|
||||||
<small>
|
|
||||||
{{ position.get_tax_code_display }}
|
|
||||||
</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 field-container">
|
<div class="col-sm-4 field-container">
|
||||||
{% bootstrap_field position.form.price addon_after=request.event.currency layout='inline' %}
|
{% bootstrap_field position.form.price addon_after=request.event.currency layout='inline' %}
|
||||||
@@ -426,12 +420,6 @@
|
|||||||
+ {{ fee.tax_rate }}%)
|
+ {{ fee.tax_rate }}%)
|
||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if fee.tax_code %}
|
|
||||||
<br>
|
|
||||||
<small>
|
|
||||||
{{ fee.get_tax_code_display }}
|
|
||||||
</small>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 field-container">
|
<div class="col-sm-4 field-container">
|
||||||
{% bootstrap_field fee.form.value addon_after=request.event.currency layout='inline' %}
|
{% bootstrap_field fee.form.value addon_after=request.event.currency layout='inline' %}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
<th>{% trans "Date" %}</th>
|
<th>{% trans "Date" %}</th>
|
||||||
<th>{% trans "Product" %}</th>
|
<th>{% trans "Product" %}</th>
|
||||||
<th class="text-right flip">{% trans "Tax rate" %}</th>
|
<th class="text-right flip">{% trans "Tax rate" %}</th>
|
||||||
<th>{% trans "Tax code" %}</th>
|
|
||||||
<th class="text-right flip">{% trans "Quantity" %}</th>
|
<th class="text-right flip">{% trans "Quantity" %}</th>
|
||||||
<th class="text-right flip">{% trans "Single price" %}</th>
|
<th class="text-right flip">{% trans "Single price" %}</th>
|
||||||
<th class="text-right flip">{% trans "Total tax value" %}</th>
|
<th class="text-right flip">{% trans "Total tax value" %}</th>
|
||||||
@@ -53,7 +52,6 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right flip">{{ t.tax_rate }} %</td>
|
<td class="text-right flip">{{ t.tax_rate }} %</td>
|
||||||
<td>{{ t.get_tax_code_display }}</td>
|
|
||||||
<td class="text-right flip">{{ t.count }} ×</td>
|
<td class="text-right flip">{{ t.count }} ×</td>
|
||||||
<td class="text-right flip">{{ t.price|money:request.event.currency }}</td>
|
<td class="text-right flip">{{ t.price|money:request.event.currency }}</td>
|
||||||
<td class="text-right flip">{{ t.full_tax_value|money:request.event.currency }}</td>
|
<td class="text-right flip">{{ t.full_tax_value|money:request.event.currency }}</td>
|
||||||
@@ -66,8 +64,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<strong>{% trans "Sum" %}</strong>
|
<strong>{% trans "Sum" %}</strong>
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td>
|
||||||
<td></td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td class="text-right flip">
|
<td class="text-right flip">
|
||||||
<strong>
|
<strong>
|
||||||
|
|||||||
@@ -294,71 +294,6 @@
|
|||||||
<legend>{% trans "Invoices" %}</legend>
|
<legend>{% trans "Invoices" %}</legend>
|
||||||
{% bootstrap_field sform.invoice_regenerate_allowed layout="control" %}
|
{% bootstrap_field sform.invoice_regenerate_allowed layout="control" %}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{% if domain_formset %}
|
|
||||||
<fieldset>
|
|
||||||
<legend>{% trans "Domains" %}</legend>
|
|
||||||
<div class="alert alert-warning">
|
|
||||||
{% trans "This dialog is intended for advanced users." %}
|
|
||||||
{% trans "The domain needs to be configured on your webserver before it can be used here." %}
|
|
||||||
</div>
|
|
||||||
<div class="formset" data-formset data-formset-prefix="{{ domain_formset.prefix }}">
|
|
||||||
{{ domain_formset.management_form }}
|
|
||||||
{% bootstrap_formset_errors domain_formset %}
|
|
||||||
<div data-formset-body>
|
|
||||||
{% for form in domain_formset %}
|
|
||||||
<div class="row formset-row" data-formset-form>
|
|
||||||
<div class="sr-only">
|
|
||||||
{{ form.id }}
|
|
||||||
{% bootstrap_field form.DELETE form_group_class="" layout="inline" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
{% bootstrap_field form.domainname layout='' form_group_class="" %}
|
|
||||||
{% bootstrap_form_errors form %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
{% bootstrap_field form.mode layout='' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
{% bootstrap_field form.event layout='' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 text-right flip">
|
|
||||||
<label aria-hidden="true"> </label><br>
|
|
||||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
|
||||||
<i class="fa fa-trash"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
<script type="form-template" data-formset-empty-form>
|
|
||||||
{% escapescript %}
|
|
||||||
<div class="row formset-row" data-formset-form>
|
|
||||||
<div class="sr-only">
|
|
||||||
{{ domain_formset.empty_form.id }}
|
|
||||||
{% bootstrap_field domain_formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
{% bootstrap_field domain_formset.empty_form.domainname layout='' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
{% bootstrap_field domain_formset.empty_form.mode layout='' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
{% bootstrap_field domain_formset.empty_form.event layout='' form_group_class="" %}
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 text-right flip">
|
|
||||||
<label aria-hidden="true"> </label><br>
|
|
||||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
|
||||||
<i class="fa fa-trash"></i></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endescapescript %}
|
|
||||||
</script>
|
|
||||||
<p>
|
|
||||||
<button type="button" class="btn btn-default" data-formset-add>
|
|
||||||
<i class="fa fa-plus"></i> {% trans "Add domain" %}</button>
|
|
||||||
</p>
|
|
||||||
</fieldset>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group submit-group">
|
<div class="form-group submit-group">
|
||||||
<button type="submit" class="btn btn-primary btn-save">
|
<button type="submit" class="btn btn-primary btn-save">
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ from zoneinfo import ZoneInfo
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.humanize.templatetags.humanize import intcomma
|
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Count, IntegerField, Max, Min, OuterRef, Prefetch, Q, Subquery, Sum,
|
Count, IntegerField, Max, Min, OuterRef, Prefetch, Q, Subquery, Sum,
|
||||||
)
|
)
|
||||||
@@ -48,6 +47,7 @@ from django.http import JsonResponse
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template.loader import get_template
|
from django.template.loader import get_template
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils import formats
|
||||||
from django.utils.formats import date_format
|
from django.utils.formats import date_format
|
||||||
from django.utils.html import escape
|
from django.utils.html import escape
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@@ -67,7 +67,6 @@ from pretix.control.signals import (
|
|||||||
from pretix.helpers.daterange import daterange
|
from pretix.helpers.daterange import daterange
|
||||||
|
|
||||||
from ...base.models.orders import CancellationRequest
|
from ...base.models.orders import CancellationRequest
|
||||||
from ...base.templatetags.money import money_filter
|
|
||||||
from ..logdisplay import OVERVIEW_BANLIST
|
from ..logdisplay import OVERVIEW_BANLIST
|
||||||
|
|
||||||
NUM_WIDGET = '<div class="numwidget"><span class="num">{num}</span><span class="text">{text}</span></div>'
|
NUM_WIDGET = '<div class="numwidget"><span class="num">{num}</span><span class="text">{text}</span></div>'
|
||||||
@@ -112,7 +111,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'content': None if lazy else NUM_WIDGET.format(num=intcomma(tickc), text=_('Attendees (ordered)')),
|
'content': None if lazy else NUM_WIDGET.format(num=tickc, text=_('Attendees (ordered)')),
|
||||||
'lazy': 'attendees-ordered',
|
'lazy': 'attendees-ordered',
|
||||||
'display_size': 'small',
|
'display_size': 'small',
|
||||||
'priority': 100,
|
'priority': 100,
|
||||||
@@ -122,7 +121,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
}) + ('?subevent={}'.format(subevent.pk) if subevent else '')
|
}) + ('?subevent={}'.format(subevent.pk) if subevent else '')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'content': None if lazy else NUM_WIDGET.format(num=intcomma(paidc), text=_('Attendees (paid)')),
|
'content': None if lazy else NUM_WIDGET.format(num=paidc, text=_('Attendees (paid)')),
|
||||||
'lazy': 'attendees-paid',
|
'lazy': 'attendees-paid',
|
||||||
'display_size': 'small',
|
'display_size': 'small',
|
||||||
'priority': 100,
|
'priority': 100,
|
||||||
@@ -133,9 +132,7 @@ def base_widgets(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'content': None if lazy else NUM_WIDGET.format(
|
'content': None if lazy else NUM_WIDGET.format(
|
||||||
num=money_filter(round_decimal(rev, sender.currency), sender.currency, hide_currency=True),
|
num=formats.localize(round_decimal(rev, sender.currency)), text=_('Total revenue ({currency})').format(currency=sender.currency)),
|
||||||
text=_('Total revenue ({currency})').format(currency=sender.currency)
|
|
||||||
),
|
|
||||||
'lazy': 'total-revenue',
|
'lazy': 'total-revenue',
|
||||||
'display_size': 'small',
|
'display_size': 'small',
|
||||||
'priority': 100,
|
'priority': 100,
|
||||||
@@ -210,7 +207,7 @@ def waitinglist_widgets(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
|
|
||||||
widgets.append({
|
widgets.append({
|
||||||
'content': None if lazy else NUM_WIDGET.format(
|
'content': None if lazy else NUM_WIDGET.format(
|
||||||
num=intcomma(happy), text=_('available to give to people on waiting list')
|
num=str(happy), text=_('available to give to people on waiting list')
|
||||||
),
|
),
|
||||||
'lazy': 'waitinglist-avail',
|
'lazy': 'waitinglist-avail',
|
||||||
'priority': 50,
|
'priority': 50,
|
||||||
@@ -220,7 +217,7 @@ def waitinglist_widgets(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
widgets.append({
|
widgets.append({
|
||||||
'content': None if lazy else NUM_WIDGET.format(num=intcomma(wles.count()), text=_('total waiting list length')),
|
'content': None if lazy else NUM_WIDGET.format(num=str(wles.count()), text=_('total waiting list length')),
|
||||||
'lazy': 'waitinglist-length',
|
'lazy': 'waitinglist-length',
|
||||||
'display_size': 'small',
|
'display_size': 'small',
|
||||||
'priority': 50,
|
'priority': 50,
|
||||||
@@ -248,7 +245,7 @@ def quota_widgets(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
status, left = qa.results[q] if q in qa.results else q.availability(allow_cache=True)
|
status, left = qa.results[q] if q in qa.results else q.availability(allow_cache=True)
|
||||||
widgets.append({
|
widgets.append({
|
||||||
'content': None if lazy else NUM_WIDGET.format(
|
'content': None if lazy else NUM_WIDGET.format(
|
||||||
num='{}/{}'.format(intcomma(left), intcomma(q.size)) if q.size is not None else '\u221e',
|
num='{}/{}'.format(left, q.size) if q.size is not None else '\u221e',
|
||||||
text=_('{quota} left').format(quota=escape(q.name))
|
text=_('{quota} left').format(quota=escape(q.name))
|
||||||
),
|
),
|
||||||
'lazy': 'quota-{}'.format(q.pk),
|
'lazy': 'quota-{}'.format(q.pk),
|
||||||
@@ -300,7 +297,7 @@ def checkin_widget(sender, subevent=None, lazy=False, **kwargs):
|
|||||||
for cl in qs:
|
for cl in qs:
|
||||||
widgets.append({
|
widgets.append({
|
||||||
'content': None if lazy else NUM_WIDGET.format(
|
'content': None if lazy else NUM_WIDGET.format(
|
||||||
num='{}/{}'.format(intcomma(cl.inside_count), intcomma(cl.position_count)),
|
num='{}/{}'.format(cl.inside_count, cl.position_count),
|
||||||
text=_('Present – {list}').format(list=escape(cl.name))
|
text=_('Present – {list}').format(list=escape(cl.name))
|
||||||
),
|
),
|
||||||
'lazy': 'checkin-{}'.format(cl.pk),
|
'lazy': 'checkin-{}'.format(cl.pk),
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ from django.http import (
|
|||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.html import conditional_escape
|
from django.utils.html import escape
|
||||||
from django.utils.http import url_has_allowed_host_and_scheme
|
from django.utils.http import url_has_allowed_host_and_scheme
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from django.utils.translation import gettext, gettext_lazy as _, gettext_noop
|
from django.utils.translation import gettext, gettext_lazy as _, gettext_noop
|
||||||
@@ -100,12 +100,9 @@ from ...base.models.items import (
|
|||||||
Item, ItemCategory, ItemMetaProperty, Question, Quota,
|
Item, ItemCategory, ItemMetaProperty, Question, Quota,
|
||||||
)
|
)
|
||||||
from ...base.services.mail import prefix_subject
|
from ...base.services.mail import prefix_subject
|
||||||
from ...base.services.placeholders import get_sample_context
|
|
||||||
from ...base.settings import LazyI18nStringList
|
from ...base.settings import LazyI18nStringList
|
||||||
from ...helpers.compat import CompatDeleteView
|
from ...helpers.compat import CompatDeleteView
|
||||||
from ...helpers.format import (
|
from ...helpers.format import format_map
|
||||||
PlainHtmlAlternativeString, SafeFormatter, format_map,
|
|
||||||
)
|
|
||||||
from ..logdisplay import OVERVIEW_BANLIST
|
from ..logdisplay import OVERVIEW_BANLIST
|
||||||
from . import CreateView, PaginationMixin, UpdateView
|
from . import CreateView, PaginationMixin, UpdateView
|
||||||
|
|
||||||
@@ -242,6 +239,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
|
|||||||
kwargs = super().get_form_kwargs()
|
kwargs = super().get_form_kwargs()
|
||||||
if self.request.user.has_active_staff_session(self.request.session.session_key):
|
if self.request.user.has_active_staff_session(self.request.session.session_key):
|
||||||
kwargs['change_slug'] = True
|
kwargs['change_slug'] = True
|
||||||
|
kwargs['domain'] = True
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
@@ -719,7 +717,20 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
|||||||
|
|
||||||
# get all supported placeholders with dummy values
|
# get all supported placeholders with dummy values
|
||||||
def placeholders(self, item):
|
def placeholders(self, item):
|
||||||
return get_sample_context(self.request.event, MailSettingsForm.base_context[item])
|
ctx = {}
|
||||||
|
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item]).values():
|
||||||
|
s = str(p.render_sample(self.request.event))
|
||||||
|
if s.strip().startswith('* '):
|
||||||
|
ctx[p.identifier] = '<div class="placeholder" title="{}">{}</div>'.format(
|
||||||
|
_('This value will be replaced based on dynamic parameters.'),
|
||||||
|
markdown_compile_email(s)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
|
||||||
|
_('This value will be replaced based on dynamic parameters.'),
|
||||||
|
escape(s)
|
||||||
|
)
|
||||||
|
return ctx
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
preview_item = request.POST.get('item', '')
|
preview_item = request.POST.get('item', '')
|
||||||
@@ -741,15 +752,9 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
|||||||
bleach.clean(v), self.placeholders(preview_item), raise_on_missing=True
|
bleach.clean(v), self.placeholders(preview_item), raise_on_missing=True
|
||||||
), highlight=True)
|
), highlight=True)
|
||||||
else:
|
else:
|
||||||
placeholders = self.placeholders(preview_item)
|
msgs[self.supported_locale[idx]] = markdown_compile_email(
|
||||||
msgs[self.supported_locale[idx]] = format_map(
|
format_map(v, self.placeholders(preview_item), raise_on_missing=True)
|
||||||
markdown_compile_email(
|
|
||||||
format_map(v, placeholders, raise_on_missing=True)
|
|
||||||
),
|
|
||||||
placeholders,
|
|
||||||
mode=SafeFormatter.MODE_RICH_TO_HTML,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
msgs[self.supported_locale[idx]] = '<div class="alert alert-danger">{}</div>'.format(
|
msgs[self.supported_locale[idx]] = '<div class="alert alert-danger">{}</div>'.format(
|
||||||
PlaceholderValidator.error_message)
|
PlaceholderValidator.error_message)
|
||||||
@@ -772,18 +777,13 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
|||||||
# get all supported placeholders with dummy values
|
# get all supported placeholders with dummy values
|
||||||
def placeholders(self, item):
|
def placeholders(self, item):
|
||||||
ctx = {}
|
ctx = {}
|
||||||
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item], rich=True).values():
|
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item]).values():
|
||||||
sample = p.render_sample(self.request.event)
|
ctx[p.identifier] = escape(str(p.render_sample(self.request.event)))
|
||||||
if isinstance(sample, PlainHtmlAlternativeString):
|
|
||||||
ctx[p.identifier] = sample
|
|
||||||
else:
|
|
||||||
ctx[p.identifier] = conditional_escape(sample)
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
v = str(request.event.settings.mail_text_order_placed)
|
v = str(request.event.settings.mail_text_order_placed)
|
||||||
context = self.placeholders('mail_text_order_placed')
|
v = format_map(v, self.placeholders('mail_text_order_placed'))
|
||||||
v = format_map(v, context)
|
|
||||||
renderers = request.event.get_html_mail_renderers()
|
renderers = request.event.get_html_mail_renderers()
|
||||||
if request.GET.get('renderer') in renderers:
|
if request.GET.get('renderer') in renderers:
|
||||||
with rolledback_transaction():
|
with rolledback_transaction():
|
||||||
@@ -801,8 +801,7 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
|||||||
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=None,
|
position=None
|
||||||
context=context,
|
|
||||||
)
|
)
|
||||||
r = HttpResponse(v, content_type='text/html')
|
r = HttpResponse(v, content_type='text/html')
|
||||||
r._csp_ignore = True
|
r._csp_ignore = True
|
||||||
@@ -1197,22 +1196,17 @@ class TaxCreate(EventSettingsViewMixin, EventPermissionRequiredMixin, CreateView
|
|||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.object = None
|
self.object = None
|
||||||
form = self.form
|
form = self.get_form()
|
||||||
if form.is_valid() and self.formset.is_valid():
|
if form.is_valid() and self.formset.is_valid():
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
else:
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def form(self):
|
|
||||||
return self.get_form()
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def formset(self):
|
def formset(self):
|
||||||
return TaxRuleLineFormSet(
|
return TaxRuleLineFormSet(
|
||||||
data=self.request.POST if self.request.method == "POST" else None,
|
data=self.request.POST if self.request.method == "POST" else None,
|
||||||
event=self.request.event,
|
event=self.request.event,
|
||||||
parent_form=self.form,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
@@ -1253,22 +1247,17 @@ class TaxUpdate(EventSettingsViewMixin, EventPermissionRequiredMixin, UpdateView
|
|||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object(self.get_queryset())
|
self.object = self.get_object(self.get_queryset())
|
||||||
form = self.form
|
form = self.get_form()
|
||||||
if form.is_valid() and self.formset.is_valid():
|
if form.is_valid() and self.formset.is_valid():
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
else:
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def form(self):
|
|
||||||
return self.get_form()
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def formset(self):
|
def formset(self):
|
||||||
return TaxRuleLineFormSet(
|
return TaxRuleLineFormSet(
|
||||||
data=self.request.POST if self.request.method == "POST" else None,
|
data=self.request.POST if self.request.method == "POST" else None,
|
||||||
event=self.request.event,
|
event=self.request.event,
|
||||||
parent_form=self.form,
|
|
||||||
initial=json.loads(self.object.custom_rules) if self.object.custom_rules else []
|
initial=json.loads(self.object.custom_rules) if self.object.custom_rules else []
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ from pretix.control.signals import order_search_forms
|
|||||||
from pretix.control.views import PaginationMixin
|
from pretix.control.views import PaginationMixin
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
from pretix.helpers.compat import CompatDeleteView
|
from pretix.helpers.compat import CompatDeleteView
|
||||||
from pretix.helpers.format import SafeFormatter, format_map
|
from pretix.helpers.format import format_map
|
||||||
from pretix.helpers.safedownload import check_token
|
from pretix.helpers.safedownload import check_token
|
||||||
from pretix.presale.signals import question_form_fields
|
from pretix.presale.signals import question_form_fields
|
||||||
|
|
||||||
@@ -2241,8 +2241,6 @@ class OrderContactChange(OrderView):
|
|||||||
changed = True
|
changed = True
|
||||||
self.order.secret = generate_secret()
|
self.order.secret = generate_secret()
|
||||||
for op in self.order.all_positions.all():
|
for op in self.order.all_positions.all():
|
||||||
op.web_secret = generate_secret()
|
|
||||||
op.save(update_fields=["web_secret"])
|
|
||||||
assign_ticket_secret(
|
assign_ticket_secret(
|
||||||
self.request.event, position=op, force_invalidate=True, save=True
|
self.request.event, position=op, force_invalidate=True, save=True
|
||||||
)
|
)
|
||||||
@@ -2353,7 +2351,7 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
|
|||||||
'subject': mark_safe(_('Subject: {subject}').format(
|
'subject': mark_safe(_('Subject: {subject}').format(
|
||||||
subject=prefix_subject(order.event, escape(email_subject), highlight=True)
|
subject=prefix_subject(order.event, escape(email_subject), highlight=True)
|
||||||
)),
|
)),
|
||||||
'html': format_map(markdown_compile_email(email_content), email_context, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
'html': markdown_compile_email(email_content)
|
||||||
}
|
}
|
||||||
return self.get(self.request, *self.args, **self.kwargs)
|
return self.get(self.request, *self.args, **self.kwargs)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -104,11 +104,11 @@ from pretix.control.forms.organizer import (
|
|||||||
CustomerCreateForm, CustomerUpdateForm, DeviceBulkEditForm, DeviceForm,
|
CustomerCreateForm, CustomerUpdateForm, DeviceBulkEditForm, DeviceForm,
|
||||||
EventMetaPropertyAllowedValueFormSet, EventMetaPropertyForm, GateForm,
|
EventMetaPropertyAllowedValueFormSet, EventMetaPropertyForm, GateForm,
|
||||||
GiftCardAcceptanceInviteForm, GiftCardCreateForm, GiftCardUpdateForm,
|
GiftCardAcceptanceInviteForm, GiftCardCreateForm, GiftCardUpdateForm,
|
||||||
KnownDomainFormset, MailSettingsForm, MembershipTypeForm,
|
MailSettingsForm, MembershipTypeForm, MembershipUpdateForm,
|
||||||
MembershipUpdateForm, OrganizerDeleteForm, OrganizerFooterLinkFormset,
|
OrganizerDeleteForm, OrganizerFooterLinkFormset, OrganizerForm,
|
||||||
OrganizerForm, OrganizerSettingsForm, OrganizerUpdateForm,
|
OrganizerSettingsForm, OrganizerUpdateForm, ReusableMediumCreateForm,
|
||||||
ReusableMediumCreateForm, ReusableMediumUpdateForm, SalesChannelForm,
|
ReusableMediumUpdateForm, SalesChannelForm, SSOClientForm, SSOProviderForm,
|
||||||
SSOClientForm, SSOProviderForm, TeamForm, WebHookForm,
|
TeamForm, WebHookForm,
|
||||||
)
|
)
|
||||||
from pretix.control.forms.rrule import RRuleForm
|
from pretix.control.forms.rrule import RRuleForm
|
||||||
from pretix.control.logdisplay import OVERVIEW_BANLIST
|
from pretix.control.logdisplay import OVERVIEW_BANLIST
|
||||||
@@ -122,7 +122,7 @@ from pretix.control.views.mailsetup import MailSettingsSetupView
|
|||||||
from pretix.helpers import OF_SELF, GroupConcat
|
from pretix.helpers import OF_SELF, GroupConcat
|
||||||
from pretix.helpers.compat import CompatDeleteView
|
from pretix.helpers.compat import CompatDeleteView
|
||||||
from pretix.helpers.dicts import merge_dicts
|
from pretix.helpers.dicts import merge_dicts
|
||||||
from pretix.helpers.format import SafeFormatter, format_map
|
from pretix.helpers.format import format_map
|
||||||
from pretix.helpers.urls import build_absolute_uri as build_global_uri
|
from pretix.helpers.urls import build_absolute_uri as build_global_uri
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
from pretix.presale.forms.customer import TokenGenerator
|
from pretix.presale.forms.customer import TokenGenerator
|
||||||
@@ -357,10 +357,9 @@ class MailSettingsPreview(OrganizerPermissionRequiredMixin, View):
|
|||||||
highlight=True,
|
highlight=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
placeholders = self.placeholders(preview_item)
|
msgs[self.supported_locale[idx]] = markdown_compile_email(
|
||||||
msgs[self.supported_locale[idx]] = format_map(markdown_compile_email(
|
format_map(v, self.placeholders(preview_item))
|
||||||
format_map(v, placeholders)
|
)
|
||||||
), placeholders, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
|
||||||
|
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'item': preview_item,
|
'item': preview_item,
|
||||||
@@ -448,10 +447,6 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
|
|||||||
def get_object(self, queryset=None) -> Organizer:
|
def get_object(self, queryset=None) -> Organizer:
|
||||||
return self.object
|
return self.object
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def domain_config(self):
|
|
||||||
return self.request.user.has_active_staff_session(self.request.session.session_key)
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def sform(self):
|
def sform(self):
|
||||||
return OrganizerSettingsForm(
|
return OrganizerSettingsForm(
|
||||||
@@ -466,8 +461,6 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
|
|||||||
context = super().get_context_data(*args, **kwargs)
|
context = super().get_context_data(*args, **kwargs)
|
||||||
context['sform'] = self.sform
|
context['sform'] = self.sform
|
||||||
context['footer_links_formset'] = self.footer_links_formset
|
context['footer_links_formset'] = self.footer_links_formset
|
||||||
if self.domain_config:
|
|
||||||
context['domain_formset'] = self.domain_formset
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
@@ -490,8 +483,6 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
|
|||||||
self.request.organizer.log_action('pretix.organizer.footerlinks.changed', user=self.request.user, data={
|
self.request.organizer.log_action('pretix.organizer.footerlinks.changed', user=self.request.user, data={
|
||||||
'data': self.footer_links_formset.cleaned_data
|
'data': self.footer_links_formset.cleaned_data
|
||||||
})
|
})
|
||||||
if self.domain_config and self.domain_formset.has_changed():
|
|
||||||
self._save_domain_config()
|
|
||||||
if form.has_changed():
|
if form.has_changed():
|
||||||
self.request.organizer.log_action(
|
self.request.organizer.log_action(
|
||||||
'pretix.organizer.changed',
|
'pretix.organizer.changed',
|
||||||
@@ -502,22 +493,10 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
|
|||||||
messages.success(self.request, _('Your changes have been saved.'))
|
messages.success(self.request, _('Your changes have been saved.'))
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
def _save_domain_config(self):
|
|
||||||
for form in self.domain_formset.initial_forms:
|
|
||||||
if form.instance.pk and form.has_changed():
|
|
||||||
self.object.domains.get(pk=form.instance.pk).log_delete(self.request.user)
|
|
||||||
self.domain_formset.save()
|
|
||||||
for new_obj in self.domain_formset.new_objects:
|
|
||||||
new_obj.log_create(self.request.user)
|
|
||||||
for ch_obj, form in self.domain_formset.changed_objects:
|
|
||||||
ch_obj.log_create(self.request.user)
|
|
||||||
self.request.organizer.cache.clear()
|
|
||||||
for ev in self.request.organizer.events.all():
|
|
||||||
ev.cache.clear()
|
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
def get_form_kwargs(self):
|
||||||
kwargs = super().get_form_kwargs()
|
kwargs = super().get_form_kwargs()
|
||||||
if self.request.user.has_active_staff_session(self.request.session.session_key):
|
if self.request.user.has_active_staff_session(self.request.session.session_key):
|
||||||
|
kwargs['domain'] = True
|
||||||
kwargs['change_slug'] = True
|
kwargs['change_slug'] = True
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
@@ -529,7 +508,7 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
|
|||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
form = self.get_form()
|
form = self.get_form()
|
||||||
if form.is_valid() and self.sform.is_valid() and self.footer_links_formset.is_valid() and (not self.domain_config or self.domain_formset.is_valid()):
|
if form.is_valid() and self.sform.is_valid() and self.footer_links_formset.is_valid():
|
||||||
return self.form_valid(form)
|
return self.form_valid(form)
|
||||||
else:
|
else:
|
||||||
return self.form_invalid(form)
|
return self.form_invalid(form)
|
||||||
@@ -540,11 +519,6 @@ class OrganizerUpdate(OrganizerPermissionRequiredMixin, UpdateView):
|
|||||||
organizer=self.object,
|
organizer=self.object,
|
||||||
prefix="footer-links", instance=self.object)
|
prefix="footer-links", instance=self.object)
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def domain_formset(self):
|
|
||||||
return KnownDomainFormset(self.request.POST if self.request.method == "POST" else None, prefix="domains",
|
|
||||||
instance=self.object, organizer=self.object)
|
|
||||||
|
|
||||||
def save_footer_links_formset(self, obj):
|
def save_footer_links_formset(self, obj):
|
||||||
self.footer_links_formset.save()
|
self.footer_links_formset.save()
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ from django.http import (
|
|||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.urls import resolve, reverse
|
from django.urls import resolve, reverse
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.html import format_html
|
from django.utils.html import escape, format_html
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
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 _
|
||||||
@@ -59,12 +59,12 @@ from django.views.generic import (
|
|||||||
)
|
)
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
|
from pretix.base.email import get_available_placeholders
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
CartPosition, LogEntry, Voucher, WaitingListEntry,
|
CartPosition, LogEntry, Voucher, WaitingListEntry,
|
||||||
)
|
)
|
||||||
from pretix.base.models.vouchers import generate_codes
|
from pretix.base.models.vouchers import generate_codes
|
||||||
from pretix.base.services.mail import prefix_subject
|
from pretix.base.services.mail import prefix_subject
|
||||||
from pretix.base.services.placeholders import get_sample_context
|
|
||||||
from pretix.base.services.vouchers import vouchers_send
|
from pretix.base.services.vouchers import vouchers_send
|
||||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||||
from pretix.base.views.tasks import AsyncFormView
|
from pretix.base.views.tasks import AsyncFormView
|
||||||
@@ -74,7 +74,7 @@ from pretix.control.permissions import EventPermissionRequiredMixin
|
|||||||
from pretix.control.signals import voucher_form_class
|
from pretix.control.signals import voucher_form_class
|
||||||
from pretix.control.views import PaginationMixin
|
from pretix.control.views import PaginationMixin
|
||||||
from pretix.helpers.compat import CompatDeleteView
|
from pretix.helpers.compat import CompatDeleteView
|
||||||
from pretix.helpers.format import SafeFormatter, format_map
|
from pretix.helpers.format import format_map
|
||||||
from pretix.helpers.models import modelcopy
|
from pretix.helpers.models import modelcopy
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
|
|
||||||
@@ -549,10 +549,22 @@ class VoucherBulkMailPreview(EventPermissionRequiredMixin, View):
|
|||||||
|
|
||||||
# get all supported placeholders with dummy values
|
# get all supported placeholders with dummy values
|
||||||
def placeholders(self, item):
|
def placeholders(self, item):
|
||||||
|
ctx = {}
|
||||||
base_ctx = ['event', 'name']
|
base_ctx = ['event', 'name']
|
||||||
if item == 'send_message':
|
if item == 'send_message':
|
||||||
base_ctx += ['voucher_list']
|
base_ctx += ['voucher_list']
|
||||||
ctx = get_sample_context(self.request.event, base_ctx)
|
for p in get_available_placeholders(self.request.event, base_ctx).values():
|
||||||
|
s = str(p.render_sample(self.request.event))
|
||||||
|
if s.strip().startswith('* ') or s.startswith(' '):
|
||||||
|
ctx[p.identifier] = '<div class="placeholder" title="{}">{}</div>'.format(
|
||||||
|
_('This value will be replaced based on dynamic parameters.'),
|
||||||
|
markdown_compile_email(s)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
|
||||||
|
_('This value will be replaced based on dynamic parameters.'),
|
||||||
|
escape(s)
|
||||||
|
)
|
||||||
return self.SafeDict(ctx)
|
return self.SafeDict(ctx)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
@@ -567,10 +579,9 @@ class VoucherBulkMailPreview(EventPermissionRequiredMixin, View):
|
|||||||
highlight=True
|
highlight=True
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
placeholders = self.placeholders(preview_item)
|
msgs["all"] = markdown_compile_email(
|
||||||
msgs["all"] = format_map(markdown_compile_email(
|
format_map(request.POST.get(preview_item), self.placeholders(preview_item))
|
||||||
format_map(request.POST.get(preview_item), placeholders)
|
)
|
||||||
), placeholders, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
|
||||||
|
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'item': preview_item,
|
'item': preview_item,
|
||||||
|
|||||||
@@ -25,29 +25,14 @@ from string import Formatter
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PlainHtmlAlternativeString:
|
|
||||||
def __init__(self, plain, html, is_block=False):
|
|
||||||
self.plain = plain
|
|
||||||
self.html = html
|
|
||||||
self.is_block = is_block
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"PlainHtmlAlternativeString('{self.plain}', '{self.html}')"
|
|
||||||
|
|
||||||
|
|
||||||
class SafeFormatter(Formatter):
|
class SafeFormatter(Formatter):
|
||||||
"""
|
"""
|
||||||
Customized version of ``str.format`` that (a) behaves just like ``str.format_map`` and
|
Customized version of ``str.format`` that (a) behaves just like ``str.format_map`` and
|
||||||
(b) does not allow any unwanted shenanigans like attribute access or format specifiers.
|
(b) does not allow any unwanted shenanigans like attribute access or format specifiers.
|
||||||
"""
|
"""
|
||||||
MODE_IGNORE_RICH = 0
|
def __init__(self, context, raise_on_missing=False):
|
||||||
MODE_RICH_TO_PLAIN = 1
|
|
||||||
MODE_RICH_TO_HTML = 2
|
|
||||||
|
|
||||||
def __init__(self, context, raise_on_missing=False, mode=MODE_IGNORE_RICH):
|
|
||||||
self.context = context
|
self.context = context
|
||||||
self.raise_on_missing = raise_on_missing
|
self.raise_on_missing = raise_on_missing
|
||||||
self.mode = mode
|
|
||||||
|
|
||||||
def get_field(self, field_name, args, kwargs):
|
def get_field(self, field_name, args, kwargs):
|
||||||
return self.get_value(field_name, args, kwargs), field_name
|
return self.get_value(field_name, args, kwargs), field_name
|
||||||
@@ -55,22 +40,14 @@ class SafeFormatter(Formatter):
|
|||||||
def get_value(self, key, args, kwargs):
|
def get_value(self, key, args, kwargs):
|
||||||
if not self.raise_on_missing and key not in self.context:
|
if not self.raise_on_missing and key not in self.context:
|
||||||
return '{' + str(key) + '}'
|
return '{' + str(key) + '}'
|
||||||
r = self.context[key]
|
return self.context[key]
|
||||||
if isinstance(r, PlainHtmlAlternativeString):
|
|
||||||
if self.mode == self.MODE_IGNORE_RICH:
|
|
||||||
return '{' + str(key) + '}'
|
|
||||||
elif self.mode == self.MODE_RICH_TO_PLAIN:
|
|
||||||
return r.plain
|
|
||||||
elif self.mode == self.MODE_RICH_TO_HTML:
|
|
||||||
return r.html
|
|
||||||
return r
|
|
||||||
|
|
||||||
def format_field(self, value, format_spec):
|
def format_field(self, value, format_spec):
|
||||||
# Ignore format_spec
|
# Ignore format _spec
|
||||||
return super().format_field(value, '')
|
return super().format_field(value, '')
|
||||||
|
|
||||||
|
|
||||||
def format_map(template, context, raise_on_missing=False, mode=SafeFormatter.MODE_IGNORE_RICH):
|
def format_map(template, context, raise_on_missing=False):
|
||||||
if not isinstance(template, str):
|
if not isinstance(template, str):
|
||||||
template = str(template)
|
template = str(template)
|
||||||
return SafeFormatter(context, raise_on_missing, mode=mode).format(template)
|
return SafeFormatter(context, raise_on_missing).format(template)
|
||||||
|
|||||||
+1844
-2117
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+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"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -705,20 +705,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1868
-2248
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
|
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
|
||||||
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
|
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
|
||||||
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -656,40 +656,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr "تباين اللون سيئ للخلفية البيضاء، الرجاء اختيار لون غامق."
|
msgstr "تباين اللون سيئ للخلفية البيضاء، الرجاء اختيار لون غامق."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "البحث في الاستفسارات"
|
msgstr "البحث في الاستفسارات"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "الكل"
|
msgstr "الكل"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "لا شيء"
|
msgstr "لا شيء"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "المختارة فقط"
|
msgstr "المختارة فقط"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "قم باستخدم اسم مختلف داخليا"
|
msgstr "قم باستخدم اسم مختلف داخليا"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "اضغط لاغلاق الصفحة"
|
msgstr "اضغط لاغلاق الصفحة"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "لم تقم بحفظ التعديلات!"
|
msgstr "لم تقم بحفظ التعديلات!"
|
||||||
|
|
||||||
@@ -753,20 +753,20 @@ msgstr "ستسترد %(currency)%(amount)"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "الرجاء إدخال المبلغ الذي يمكن للمنظم الاحتفاظ به."
|
msgstr "الرجاء إدخال المبلغ الذي يمكن للمنظم الاحتفاظ به."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "الرجاء إدخال عدد لأحد أنواع التذاكر."
|
msgstr "الرجاء إدخال عدد لأحد أنواع التذاكر."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "مطلوب"
|
msgstr "مطلوب"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "المنطقة الزمنية:"
|
msgstr "المنطقة الزمنية:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "التوقيت المحلي:"
|
msgstr "التوقيت المحلي:"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1854
-2206
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+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-"
|
||||||
@@ -623,40 +623,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -710,22 +710,22 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Cart expired"
|
#| msgid "Cart expired"
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "Cistella expirada"
|
msgstr "Cistella expirada"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1854
-2221
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
|
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
|
||||||
"Last-Translator: Michael <michael.happl@gmx.at>\n"
|
"Last-Translator: Michael <michael.happl@gmx.at>\n"
|
||||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -650,40 +650,40 @@ msgstr ""
|
|||||||
"Tato barva je pro text na bílém pozadí špatně kontrastní, zvolte prosím "
|
"Tato barva je pro text na bílém pozadí špatně kontrastní, zvolte prosím "
|
||||||
"tmavší odstín."
|
"tmavší odstín."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Hledaný výraz"
|
msgstr "Hledaný výraz"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Všechny"
|
msgstr "Všechny"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Žádný"
|
msgstr "Žádný"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Pouze vybrané"
|
msgstr "Pouze vybrané"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Interně používat jiný název"
|
msgstr "Interně používat jiný název"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Kliknutím zavřete"
|
msgstr "Kliknutím zavřete"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Máte neuložené změny!"
|
msgstr "Máte neuložené změny!"
|
||||||
|
|
||||||
@@ -740,20 +740,20 @@ msgstr "Dostanete %(currency)s %(amount)s zpět"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Zadejte částku, kterou si organizátor může ponechat."
|
msgstr "Zadejte částku, kterou si organizátor může ponechat."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Zadejte prosím množství pro jeden z typů vstupenek."
|
msgstr "Zadejte prosím množství pro jeden z typů vstupenek."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "povinný"
|
msgstr "povinný"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Časové pásmo:"
|
msgstr "Časové pásmo:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Místní čas:"
|
msgstr "Místní čas:"
|
||||||
|
|
||||||
|
|||||||
+1844
-2135
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+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"
|
||||||
@@ -623,40 +623,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -706,20 +706,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1859
-2212
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-07-10 15:00+0000\n"
|
"PO-Revision-Date: 2024-07-10 15:00+0000\n"
|
||||||
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
|
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
|
||||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -670,40 +670,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Ingen"
|
msgstr "Ingen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klik for at lukke"
|
msgstr "Klik for at lukke"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Du har ændringer, der ikke er gemt!"
|
msgstr "Du har ændringer, der ikke er gemt!"
|
||||||
|
|
||||||
@@ -763,22 +763,22 @@ msgstr "fra %(currency)s %(price)s"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Cart expired"
|
#| msgid "Cart expired"
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "Kurv udløbet"
|
msgstr "Kurv udløbet"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Tidszone:"
|
msgstr "Tidszone:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Din lokaltid:"
|
msgstr "Din lokaltid:"
|
||||||
|
|
||||||
|
|||||||
+1868
-2209
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
||||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
"Last-Translator: Raphael Michel <michel@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/"
|
||||||
@@ -644,40 +644,40 @@ msgstr ""
|
|||||||
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
||||||
"Hintergrund. Bitte wählen Sie eine dunklere Farbe."
|
"Hintergrund. Bitte wählen Sie eine dunklere Farbe."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Suchbegriff"
|
msgstr "Suchbegriff"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Keine"
|
msgstr "Keine"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Nur ausgewählte"
|
msgstr "Nur ausgewählte"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
|
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Ungültige Seitenzahl."
|
msgstr "Ungültige Seitenzahl."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Intern einen anderen Namen verwenden"
|
msgstr "Intern einen anderen Namen verwenden"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klicken zum Schließen"
|
msgstr "Klicken zum Schließen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Sie haben ungespeicherte Änderungen!"
|
msgstr "Sie haben ungespeicherte Änderungen!"
|
||||||
|
|
||||||
@@ -732,20 +732,20 @@ msgstr "Sie erhalten %(currency)s %(amount)s zurück"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Bitte geben Sie den Betrag ein, den der Veranstalter einbehalten darf."
|
msgstr "Bitte geben Sie den Betrag ein, den der Veranstalter einbehalten darf."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Bitte tragen Sie eine Menge für eines der Produkte ein."
|
msgstr "Bitte tragen Sie eine Menge für eines der Produkte ein."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "verpflichtend"
|
msgstr "verpflichtend"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Zeitzone:"
|
msgstr "Zeitzone:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Deine lokale Zeit:"
|
msgstr "Deine lokale Zeit:"
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,10 @@ BSD
|
|||||||
bspw
|
bspw
|
||||||
Bokmål
|
Bokmål
|
||||||
Boleto
|
Boleto
|
||||||
Buchhaltungs
|
|
||||||
Bundles
|
Bundles
|
||||||
Butterfly
|
Butterfly
|
||||||
bzw
|
bzw
|
||||||
ca
|
ca
|
||||||
Ceuta
|
|
||||||
Cc
|
Cc
|
||||||
chardet
|
chardet
|
||||||
charge
|
charge
|
||||||
@@ -160,12 +158,9 @@ Inc
|
|||||||
inkl
|
inkl
|
||||||
innenname
|
innenname
|
||||||
innennamen
|
innennamen
|
||||||
innergemeinschaftliche
|
|
||||||
Innergemeinschaftlicher
|
|
||||||
Input
|
Input
|
||||||
Installations
|
Installations
|
||||||
integrationen
|
integrationen
|
||||||
intra
|
|
||||||
INV
|
INV
|
||||||
invalidieren
|
invalidieren
|
||||||
invalidiert
|
invalidiert
|
||||||
@@ -182,12 +177,10 @@ Kombitickets
|
|||||||
Kompatibilitätsmodus
|
Kompatibilitätsmodus
|
||||||
Konfigurations
|
Konfigurations
|
||||||
Kosovo
|
Kosovo
|
||||||
land
|
|
||||||
landesspezifische
|
landesspezifische
|
||||||
Lead
|
Lead
|
||||||
Leaflet
|
Leaflet
|
||||||
Linktext
|
Linktext
|
||||||
lit
|
|
||||||
Logindaten
|
Logindaten
|
||||||
Lösch
|
Lösch
|
||||||
loszulegen
|
loszulegen
|
||||||
@@ -195,7 +188,6 @@ Ltd
|
|||||||
max
|
max
|
||||||
MariaDB
|
MariaDB
|
||||||
MapQuest
|
MapQuest
|
||||||
Melilla
|
|
||||||
Mercado
|
Mercado
|
||||||
Merchandise
|
Merchandise
|
||||||
Meta
|
Meta
|
||||||
@@ -277,7 +269,6 @@ rückabgewickelt
|
|||||||
Rundungsdifferenzen
|
Rundungsdifferenzen
|
||||||
Sa
|
Sa
|
||||||
Saalplan
|
Saalplan
|
||||||
Sammlungsstücken
|
|
||||||
SAQ
|
SAQ
|
||||||
SCA
|
SCA
|
||||||
Scan
|
Scan
|
||||||
@@ -366,7 +357,6 @@ USt
|
|||||||
Überzahlten
|
Überzahlten
|
||||||
Validierung
|
Validierung
|
||||||
Venmo
|
Venmo
|
||||||
Veranstalterdomain
|
|
||||||
Veranstaltereinstellungen
|
Veranstaltereinstellungen
|
||||||
Veranstalterkonten
|
Veranstalterkonten
|
||||||
Veranstalterkonto
|
Veranstalterkonto
|
||||||
@@ -377,7 +367,6 @@ Veranstalterseite
|
|||||||
Veranstalterübersicht
|
Veranstalterübersicht
|
||||||
veranstalterweiten
|
veranstalterweiten
|
||||||
Veranstaltungs
|
Veranstaltungs
|
||||||
Veranstalterdomain
|
|
||||||
veranstaltungsweiten
|
veranstaltungsweiten
|
||||||
Verfügbarkeitsberechnung
|
Verfügbarkeitsberechnung
|
||||||
Verfügbarkeitsstatus
|
Verfügbarkeitsstatus
|
||||||
|
|||||||
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
||||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||||
@@ -643,40 +643,40 @@ msgstr ""
|
|||||||
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
||||||
"Hintergrund. Bitte wähle eine dunklere Farbe."
|
"Hintergrund. Bitte wähle eine dunklere Farbe."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Suchbegriff"
|
msgstr "Suchbegriff"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Keine"
|
msgstr "Keine"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Nur ausgewählte"
|
msgstr "Nur ausgewählte"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
|
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Ungültige Seitenzahl."
|
msgstr "Ungültige Seitenzahl."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Intern einen anderen Namen verwenden"
|
msgstr "Intern einen anderen Namen verwenden"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klicken zum Schließen"
|
msgstr "Klicken zum Schließen"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Du hast ungespeicherte Änderungen!"
|
msgstr "Du hast ungespeicherte Änderungen!"
|
||||||
|
|
||||||
@@ -731,20 +731,20 @@ msgstr "Du erhältst %(currency)s %(amount)s zurück"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Bitte gib den Betrag ein, den der Veranstalter einbehalten darf."
|
msgstr "Bitte gib den Betrag ein, den der Veranstalter einbehalten darf."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Bitte trage eine Menge für eines der Produkte ein."
|
msgstr "Bitte trage eine Menge für eines der Produkte ein."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "verpflichtend"
|
msgstr "verpflichtend"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Zeitzone:"
|
msgstr "Zeitzone:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Deine lokale Zeit:"
|
msgstr "Deine lokale Zeit:"
|
||||||
|
|
||||||
|
|||||||
@@ -66,12 +66,10 @@ BSD
|
|||||||
bspw
|
bspw
|
||||||
Bokmål
|
Bokmål
|
||||||
Boleto
|
Boleto
|
||||||
Buchhaltungs
|
|
||||||
Bundles
|
Bundles
|
||||||
Butterfly
|
Butterfly
|
||||||
bzw
|
bzw
|
||||||
ca
|
ca
|
||||||
Ceuta
|
|
||||||
Cc
|
Cc
|
||||||
chardet
|
chardet
|
||||||
charge
|
charge
|
||||||
@@ -160,12 +158,9 @@ Inc
|
|||||||
inkl
|
inkl
|
||||||
innenname
|
innenname
|
||||||
innennamen
|
innennamen
|
||||||
innergemeinschaftliche
|
|
||||||
Innergemeinschaftlicher
|
|
||||||
Input
|
Input
|
||||||
Installations
|
Installations
|
||||||
integrationen
|
integrationen
|
||||||
intra
|
|
||||||
INV
|
INV
|
||||||
invalidieren
|
invalidieren
|
||||||
invalidiert
|
invalidiert
|
||||||
@@ -182,12 +177,10 @@ Kombitickets
|
|||||||
Kompatibilitätsmodus
|
Kompatibilitätsmodus
|
||||||
Konfigurations
|
Konfigurations
|
||||||
Kosovo
|
Kosovo
|
||||||
land
|
|
||||||
landesspezifische
|
landesspezifische
|
||||||
Lead
|
Lead
|
||||||
Leaflet
|
Leaflet
|
||||||
Linktext
|
Linktext
|
||||||
lit
|
|
||||||
Logindaten
|
Logindaten
|
||||||
Lösch
|
Lösch
|
||||||
loszulegen
|
loszulegen
|
||||||
@@ -195,7 +188,6 @@ Ltd
|
|||||||
max
|
max
|
||||||
MariaDB
|
MariaDB
|
||||||
MapQuest
|
MapQuest
|
||||||
Melilla
|
|
||||||
Mercado
|
Mercado
|
||||||
Merchandise
|
Merchandise
|
||||||
Meta
|
Meta
|
||||||
@@ -277,7 +269,6 @@ rückabgewickelt
|
|||||||
Rundungsdifferenzen
|
Rundungsdifferenzen
|
||||||
Sa
|
Sa
|
||||||
Saalplan
|
Saalplan
|
||||||
Sammlungsstücken
|
|
||||||
SAQ
|
SAQ
|
||||||
SCA
|
SCA
|
||||||
Scan
|
Scan
|
||||||
@@ -366,7 +357,6 @@ USt
|
|||||||
Überzahlten
|
Überzahlten
|
||||||
Validierung
|
Validierung
|
||||||
Venmo
|
Venmo
|
||||||
Veranstalterdomain
|
|
||||||
Veranstaltereinstellungen
|
Veranstaltereinstellungen
|
||||||
Veranstalterkonten
|
Veranstalterkonten
|
||||||
Veranstalterkonto
|
Veranstalterkonto
|
||||||
@@ -377,7 +367,6 @@ Veranstalterseite
|
|||||||
Veranstalterübersicht
|
Veranstalterübersicht
|
||||||
veranstalterweiten
|
veranstalterweiten
|
||||||
Veranstaltungs
|
Veranstaltungs
|
||||||
Veranstalterdomain
|
|
||||||
veranstaltungsweiten
|
veranstaltungsweiten
|
||||||
Verfügbarkeitsberechnung
|
Verfügbarkeitsberechnung
|
||||||
Verfügbarkeitsstatus
|
Verfügbarkeitsstatus
|
||||||
|
|||||||
+1844
-2117
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-19 15:34+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"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -705,20 +705,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1871
-2244
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,9 @@ 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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-12-22 00:00+0000\n"
|
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
||||||
"Last-Translator: Dimitris Tsimpidis <tsimpidisd@gmail.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/"
|
||||||
"el/>\n"
|
"el/>\n"
|
||||||
"Language: el\n"
|
"Language: el\n"
|
||||||
@@ -17,7 +17,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.9.2\n"
|
"X-Generator: Weblate 3.5.1\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||||
@@ -31,7 +31,7 @@ msgstr "Σχόλιο:"
|
|||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
|
||||||
msgid "PayPal"
|
msgid "PayPal"
|
||||||
msgstr "PayPal"
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
|
||||||
msgid "Venmo"
|
msgid "Venmo"
|
||||||
@@ -64,7 +64,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
||||||
msgid "SEPA Direct Debit"
|
msgid "SEPA Direct Debit"
|
||||||
msgstr "Τραπεζική μεταφορά"
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
|
||||||
msgid "Bancontact"
|
msgid "Bancontact"
|
||||||
@@ -79,8 +79,10 @@ msgid "SOFORT"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Yes"
|
||||||
msgid "eps"
|
msgid "eps"
|
||||||
msgstr "EPS"
|
msgstr "Ναι"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
|
||||||
msgid "MyBank"
|
msgid "MyBank"
|
||||||
@@ -145,11 +147,11 @@ msgstr "Συνέχεια"
|
|||||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:317
|
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:317
|
||||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:341
|
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:341
|
||||||
msgid "Confirming your payment …"
|
msgid "Confirming your payment …"
|
||||||
msgstr "Επιβεβαίωση πληρωμής…"
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
|
||||||
msgid "Payment method unavailable"
|
msgid "Payment method unavailable"
|
||||||
msgstr "Μη διαθέσιμος τρόπος πληρωμής"
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||||
@@ -174,8 +176,10 @@ msgid "Total"
|
|||||||
msgstr "Σύνολο"
|
msgstr "Σύνολο"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:291
|
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:291
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Contacting Stripe …"
|
||||||
msgid "Contacting your bank …"
|
msgid "Contacting your bank …"
|
||||||
msgstr "Επικοινωνία με την τράπεζα …"
|
msgstr "Επικοινωνία με το Stripe …"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
|
||||||
msgid "Select a check-in list"
|
msgid "Select a check-in list"
|
||||||
@@ -682,40 +686,40 @@ msgstr ""
|
|||||||
"Το χρώμα σας έχει κακή αντίθεση για κείμενο σε λευκό φόντο, επιλέξτε μια πιο "
|
"Το χρώμα σας έχει κακή αντίθεση για κείμενο σε λευκό φόντο, επιλέξτε μια πιο "
|
||||||
"σκούρα σκιά."
|
"σκούρα σκιά."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Όλα"
|
msgstr "Όλα"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Κανένας"
|
msgstr "Κανένας"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
|
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Κάντε κλικ για να κλείσετε"
|
msgstr "Κάντε κλικ για να κλείσετε"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -777,22 +781,22 @@ msgstr "απο %(currency)s %(price)s"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Εισαγάγετε μια ποσότητα για έναν από τους τύπους εισιτηρίων."
|
msgstr "Εισαγάγετε μια ποσότητα για έναν από τους τύπους εισιτηρίων."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Cart expired"
|
#| msgid "Cart expired"
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "Το καλάθι έληξε"
|
msgstr "Το καλάθι έληξε"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1844
-2117
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+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"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -705,20 +705,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1923
-2266
File diff suppressed because it is too large
Load Diff
@@ -7,11 +7,11 @@ 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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-18 15:48+0000\n"
|
"PO-Revision-Date: 2024-11-18 15:48+0000\n"
|
||||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
|
||||||
"js/es/>\n"
|
"pretix-js/es/>\n"
|
||||||
"Language: es\n"
|
"Language: es\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -642,40 +642,40 @@ msgstr ""
|
|||||||
"Tu color tiene mal contraste para un texto con fondo blanco, por favor, "
|
"Tu color tiene mal contraste para un texto con fondo blanco, por favor, "
|
||||||
"escoge un tono más oscuro."
|
"escoge un tono más oscuro."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Consulta de búsqueda"
|
msgstr "Consulta de búsqueda"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Ninguno"
|
msgstr "Ninguno"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Solamente seleccionados"
|
msgstr "Solamente seleccionados"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Introduce un número de página entre 1 y %(max)s."
|
msgstr "Introduce un número de página entre 1 y %(max)s."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Número de página inválido."
|
msgstr "Número de página inválido."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Usar un nombre diferente internamente"
|
msgstr "Usar un nombre diferente internamente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Click para cerrar"
|
msgstr "Click para cerrar"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "¡Tienes cambios sin guardar!"
|
msgstr "¡Tienes cambios sin guardar!"
|
||||||
|
|
||||||
@@ -730,20 +730,20 @@ msgstr "Obtienes %(currency)s %(price)s de vuelta"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Por favor, ingrese el importe que el organizador puede quedarse."
|
msgstr "Por favor, ingrese el importe que el organizador puede quedarse."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Por favor, introduzca un valor para cada tipo de entrada."
|
msgstr "Por favor, introduzca un valor para cada tipo de entrada."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "campo requerido"
|
msgstr "campo requerido"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Zona horaria:"
|
msgstr "Zona horaria:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Su hora local:"
|
msgstr "Su hora local:"
|
||||||
|
|
||||||
|
|||||||
+1844
-2117
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+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"
|
||||||
@@ -622,40 +622,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -705,20 +705,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1855
-2227
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
|
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
|
||||||
"Last-Translator: Albizuri <oier@puntu.eus>\n"
|
"Last-Translator: Albizuri <oier@puntu.eus>\n"
|
||||||
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -635,40 +635,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Guztiak"
|
msgstr "Guztiak"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -721,20 +721,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+2494
-2866
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
|
"PO-Revision-Date: 2021-11-10 05:00+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-"
|
||||||
@@ -651,40 +651,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Kaikki"
|
msgstr "Kaikki"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Käytä toista nimeä sisäisesti"
|
msgstr "Käytä toista nimeä sisäisesti"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Sulje klikkaamalla"
|
msgstr "Sulje klikkaamalla"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Sinulla on tallentamattomia muutoksia!"
|
msgstr "Sinulla on tallentamattomia muutoksia!"
|
||||||
|
|
||||||
@@ -738,22 +738,22 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Cart expired"
|
#| msgid "Cart expired"
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "Ostoskori on vanhentunut"
|
msgstr "Ostoskori on vanhentunut"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Aikavyöhyke:"
|
msgstr "Aikavyöhyke:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1872
-2214
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@ 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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-12-03 20:00+0000\n"
|
"PO-Revision-Date: 2024-11-16 05:00+0000\n"
|
||||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
"fr/>\n"
|
"fr/>\n"
|
||||||
@@ -16,7 +16,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 5.8.4\n"
|
"X-Generator: Weblate 5.8.3\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||||
@@ -150,7 +150,7 @@ msgstr "Méthode de paiement non disponible"
|
|||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||||
msgid "Placed orders"
|
msgid "Placed orders"
|
||||||
msgstr "Commandes réalisées"
|
msgstr "Commandes placées"
|
||||||
|
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||||
@@ -643,40 +643,40 @@ msgstr ""
|
|||||||
"Votre choix de couleur n'a pas un bon contraste avec du texte sur un fond "
|
"Votre choix de couleur n'a pas un bon contraste avec du texte sur un fond "
|
||||||
"blanc, SVP choisissez un ton plus sombre."
|
"blanc, SVP choisissez un ton plus sombre."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Requête de recherche"
|
msgstr "Requête de recherche"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tous"
|
msgstr "Tous"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Aucun"
|
msgstr "Aucun"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Seuls les sélectionnés"
|
msgstr "Seuls les sélectionnés"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr "Saisir le numéro de page entre 1 et %(max)s."
|
msgstr "Saisir le numéro de page entre 1 et %(max)s."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr "Numéro de page invalide."
|
msgstr "Numéro de page invalide."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Utiliser un nom différent en interne"
|
msgstr "Utiliser un nom différent en interne"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Cliquez pour fermer"
|
msgstr "Cliquez pour fermer"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Vous avez des modifications non sauvegardées !"
|
msgstr "Vous avez des modifications non sauvegardées !"
|
||||||
|
|
||||||
@@ -729,20 +729,20 @@ msgid "Please enter the amount the organizer can keep."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Veuillez indiquer le montant que l'organisateur est autorisé à retenir."
|
"Veuillez indiquer le montant que l'organisateur est autorisé à retenir."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "SVP entrez une quantité pour un de vos types de billets."
|
msgstr "SVP entrez une quantité pour un de vos types de billets."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "obligatoire"
|
msgstr "obligatoire"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Fuseau horaire :"
|
msgstr "Fuseau horaire :"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Votre heure locale :"
|
msgstr "Votre heure locale :"
|
||||||
|
|
||||||
|
|||||||
+1874
-2219
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
||||||
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
||||||
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
@@ -658,40 +658,40 @@ msgstr ""
|
|||||||
"A túa cor ten mal contraste para un texto con fondo branco. Por favor, "
|
"A túa cor ten mal contraste para un texto con fondo branco. Por favor, "
|
||||||
"escolle un ton máis escuro."
|
"escolle un ton máis escuro."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Consultar unha procura"
|
msgstr "Consultar unha procura"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Todos"
|
msgstr "Todos"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Ningún"
|
msgstr "Ningún"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Soamente seleccionados"
|
msgstr "Soamente seleccionados"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Usar un nome diferente internamente"
|
msgstr "Usar un nome diferente internamente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Click para cerrar"
|
msgstr "Click para cerrar"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Tes cambios sen gardar!"
|
msgstr "Tes cambios sen gardar!"
|
||||||
|
|
||||||
@@ -744,20 +744,20 @@ msgstr "Obtés %(currency)s %(price)s de volta"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Por favor, ingrese a cantidade que pode conservar o organizador."
|
msgstr "Por favor, ingrese a cantidade que pode conservar o organizador."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Por favor, introduza un valor para cada tipo de entrada."
|
msgstr "Por favor, introduza un valor para cada tipo de entrada."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "campo requirido"
|
msgstr "campo requirido"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Zona horaria:"
|
msgstr "Zona horaria:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "A súa hora local:"
|
msgstr "A súa hora local:"
|
||||||
|
|
||||||
|
|||||||
+1844
-2121
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
|
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
|
||||||
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
|
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
|
||||||
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||||
@@ -630,40 +630,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -717,20 +717,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1844
-2119
File diff suppressed because it is too large
Load Diff
@@ -7,11 +7,11 @@ 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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-17 00:00+0000\n"
|
"PO-Revision-Date: 2024-11-17 00:00+0000\n"
|
||||||
"Last-Translator: Pavle Ergović <pavleergovic@gmail.com>\n"
|
"Last-Translator: Pavle Ergović <pavleergovic@gmail.com>\n"
|
||||||
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/"
|
||||||
"js/hr/>\n"
|
"pretix-js/hr/>\n"
|
||||||
"Language: hr\n"
|
"Language: hr\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -624,40 +624,40 @@ msgid ""
|
|||||||
"darker shade."
|
"darker shade."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -707,20 +707,20 @@ msgstr ""
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1903
-2180
File diff suppressed because it is too large
Load Diff
@@ -7,11 +7,11 @@ 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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2024-11-28 06:00+0000\n"
|
"PO-Revision-Date: 2024-11-28 06:00+0000\n"
|
||||||
"Last-Translator: Patrick Chilton <chpatrick@gmail.com>\n"
|
"Last-Translator: Patrick Chilton <chpatrick@gmail.com>\n"
|
||||||
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/"
|
||||||
"js/hu/>\n"
|
"pretix-js/hu/>\n"
|
||||||
"Language: hu\n"
|
"Language: hu\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
@@ -671,40 +671,40 @@ msgstr ""
|
|||||||
"A választott színek kontrasztja elégtelen, kérjük válassz sötétebb "
|
"A választott színek kontrasztja elégtelen, kérjük válassz sötétebb "
|
||||||
"árnyalatot."
|
"árnyalatot."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Összes"
|
msgstr "Összes"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Semmi"
|
msgstr "Semmi"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Használj másik nevet"
|
msgstr "Használj másik nevet"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Bezárásért kattints"
|
msgstr "Bezárásért kattints"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Mentetlen változtatások!"
|
msgstr "Mentetlen változtatások!"
|
||||||
|
|
||||||
@@ -766,22 +766,22 @@ msgstr "%(currency) %(price)-tól"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Adjon meg egy mennyiséget az egyik jegytípusból."
|
msgstr "Adjon meg egy mennyiséget az egyik jegytípusból."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Cart expired"
|
#| msgid "Cart expired"
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "A kosár lejárt"
|
msgstr "A kosár lejárt"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Időzona:"
|
msgstr "Időzona:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+1855
-2231
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2023-09-20 14:01+0000\n"
|
"PO-Revision-Date: 2023-09-20 14:01+0000\n"
|
||||||
"Last-Translator: Mahdia Aliyy <mahdlyy.k@gmail.com>\n"
|
"Last-Translator: Mahdia Aliyy <mahdlyy.k@gmail.com>\n"
|
||||||
"Language-Team: Indonesian <https://translate.pretix.eu/projects/pretix/"
|
"Language-Team: Indonesian <https://translate.pretix.eu/projects/pretix/"
|
||||||
@@ -657,40 +657,40 @@ msgstr ""
|
|||||||
"Warna Anda memiliki kontras yang buruk untuk teks dengan latar belakang "
|
"Warna Anda memiliki kontras yang buruk untuk teks dengan latar belakang "
|
||||||
"putih, harap pilih warna yang lebih gelap."
|
"putih, harap pilih warna yang lebih gelap."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Permintaan pencarian"
|
msgstr "Permintaan pencarian"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Semua"
|
msgstr "Semua"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Tidak ada"
|
msgstr "Tidak ada"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Hanya dipilih"
|
msgstr "Hanya dipilih"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Gunakan nama yang berbeda secara internal"
|
msgstr "Gunakan nama yang berbeda secara internal"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Klik untuk menutup"
|
msgstr "Klik untuk menutup"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Anda memiliki perubahan yang belum disimpan!"
|
msgstr "Anda memiliki perubahan yang belum disimpan!"
|
||||||
|
|
||||||
@@ -740,20 +740,20 @@ msgstr "Anda mendapatkan %(currency)s %(amount)s kembali"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Silakan masukkan jumlah yang dapat disimpan oleh penyelenggara."
|
msgstr "Silakan masukkan jumlah yang dapat disimpan oleh penyelenggara."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Masukkan jumlah untuk salah satu jenis tiket."
|
msgstr "Masukkan jumlah untuk salah satu jenis tiket."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "diperlukan"
|
msgstr "diperlukan"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Zona waktu:"
|
msgstr "Zona waktu:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Waktu setempat Anda:"
|
msgstr "Waktu setempat Anda:"
|
||||||
|
|
||||||
|
|||||||
+1854
-2171
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: 2024-12-16 14:20+0000\n"
|
"POT-Creation-Date: 2024-11-08 13:45+0000\n"
|
||||||
"PO-Revision-Date: 2023-05-18 01:00+0000\n"
|
"PO-Revision-Date: 2023-05-18 01:00+0000\n"
|
||||||
"Last-Translator: M C <micasadmail@gmail.com>\n"
|
"Last-Translator: M C <micasadmail@gmail.com>\n"
|
||||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||||
@@ -652,40 +652,40 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Il colore scelto non ha un buon contrasto, per favore scegline uno più scuro."
|
"Il colore scelto non ha un buon contrasto, per favore scegline uno più scuro."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:442
|
#: pretix/static/pretixcontrol/js/ui/main.js:496
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:462
|
#: pretix/static/pretixcontrol/js/ui/main.js:516
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr "Chiave di ricerca"
|
msgstr "Chiave di ricerca"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:460
|
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "Tutto"
|
msgstr "Tutto"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:461
|
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||||
msgid "None"
|
msgid "None"
|
||||||
msgstr "Nessuno"
|
msgstr "Nessuno"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:465
|
#: pretix/static/pretixcontrol/js/ui/main.js:519
|
||||||
msgid "Selected only"
|
msgid "Selected only"
|
||||||
msgstr "Solo i selezionati"
|
msgstr "Solo i selezionati"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:808
|
#: pretix/static/pretixcontrol/js/ui/main.js:862
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:811
|
#: pretix/static/pretixcontrol/js/ui/main.js:865
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:969
|
#: pretix/static/pretixcontrol/js/ui/main.js:1023
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
msgstr "Utilizza un nome diverso internamente"
|
msgstr "Utilizza un nome diverso internamente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1009
|
#: pretix/static/pretixcontrol/js/ui/main.js:1063
|
||||||
msgid "Click to close"
|
msgid "Click to close"
|
||||||
msgstr "Clicca per chiudere"
|
msgstr "Clicca per chiudere"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1084
|
#: pretix/static/pretixcontrol/js/ui/main.js:1138
|
||||||
msgid "You have unsaved changes!"
|
msgid "You have unsaved changes!"
|
||||||
msgstr "Hai cambiamenti non salvati!"
|
msgstr "Hai cambiamenti non salvati!"
|
||||||
|
|
||||||
@@ -737,20 +737,20 @@ msgstr "Ricevi indietro %(currency)s %(amount)s"
|
|||||||
msgid "Please enter the amount the organizer can keep."
|
msgid "Please enter the amount the organizer can keep."
|
||||||
msgstr "Inserisci l'importo che l'organizzatore può trattenere."
|
msgstr "Inserisci l'importo che l'organizzatore può trattenere."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:454
|
#: pretix/static/pretixpresale/js/ui/main.js:449
|
||||||
msgid "Please enter a quantity for one of the ticket types."
|
msgid "Please enter a quantity for one of the ticket types."
|
||||||
msgstr "Inserisci la quantità per una tipologia di biglietto."
|
msgstr "Inserisci la quantità per una tipologia di biglietto."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:506
|
#: pretix/static/pretixpresale/js/ui/main.js:485
|
||||||
msgid "required"
|
msgid "required"
|
||||||
msgstr "richiesta"
|
msgstr "richiesta"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:550
|
#: pretix/static/pretixpresale/js/ui/main.js:588
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:569
|
#: pretix/static/pretixpresale/js/ui/main.js:607
|
||||||
msgid "Time zone:"
|
msgid "Time zone:"
|
||||||
msgstr "Fuso orario:"
|
msgstr "Fuso orario:"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:560
|
#: pretix/static/pretixpresale/js/ui/main.js:598
|
||||||
msgid "Your local time:"
|
msgid "Your local time:"
|
||||||
msgstr "Ora locale:"
|
msgstr "Ora locale:"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user