diff --git a/README.rst b/README.rst index 919de97e9..4a6bfb99b 100644 --- a/README.rst +++ b/README.rst @@ -8,6 +8,7 @@ pretix :target: https://docs.pretix.eu/ .. image:: https://github.com/pretix/pretix/workflows/Tests/badge.svg + :target: https://github.com/pretix/pretix/actions/workflows/tests.yml .. image:: https://codecov.io/gh/pretix/pretix/branch/master/graph/badge.svg :target: https://codecov.io/gh/pretix/pretix diff --git a/doc/api/resources/checkin.rst b/doc/api/resources/checkin.rst index 16e36424d..89ab1cff1 100644 --- a/doc/api/resources/checkin.rst +++ b/doc/api/resources/checkin.rst @@ -359,3 +359,65 @@ Performing a ticket search :statuscode 401: Authentication failure :statuscode 403: The requested organizer or check-in list does not exist **or** you have no permission to view this resource. :statuscode 404: The requested check-in list does not exist. + +.. _`rest-checkin-annul`: + +Annulment of a check-in +----------------------- + +.. http:post:: /api/v1/organizers/(organizer)/checkinrpc/annul/ + + If a check-in was made in error and the person was not let in, it can be annulled. We do not recommend this to be used + in case of manual check-ins or user interfaces because it is too prone for human errors. It is mostly intended for + automated entry systems like a turnstile or automated door, where the check-in is first created, then the door is + opened, and then the check-in may be annulled if the system knows that the turnstile did not turn or was out of + order. + + This endpoint supports passing multiple check-in lists for the context of a multi-event scan. However, each + check-in list passed needs to be from a distinct event. + + Check-ins created by a device can only be annulled by the same device. The datetime of annulment may not be more than + 15 minutes after the datetime of check-in (value subject to change). + + A status code of 404 is returned if no check-in was found for the given nonce. A status code of 400 is returned when + multiple check-ins match the nonce, the input is invalid in another way, the annulment is made from the wrong device, + the check-in is already in an annulled or failed state, or the datetime constraint is not valid. + + :json string status: ``"ok"`` + + **Example request**: + + .. sourcecode:: http + + POST /api/v1/organizers/bigevents/checkinrpc/annul/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + { + "lists": [1], + "nonce": "Pvrk50vUzQd0DhdpNRL4I4OcXsvg70uA", + "error_explanation": "Turnstile did not turn" + } + + **Example successful response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + { + "status": "ok", + } + + :param organizer: The ``slug`` field of the organizer to fetch + :statuscode 200: no error + :statuscode 400: Invalid or incomplete request, see above + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource. + :statuscode 404: The requested nonce does not exist. diff --git a/doc/api/resources/events.rst b/doc/api/resources/events.rst index 5064377b6..95bd5e249 100644 --- a/doc/api/resources/events.rst +++ b/doc/api/resources/events.rst @@ -424,9 +424,9 @@ Endpoints :param organizer: The ``slug`` field of the organizer of the event to create. :param event: The ``slug`` field of the event to copy settings and items from. :statuscode 201: no error - :statuscode 400: The event could not be created due to invalid submitted data. + :statuscode 400: The event could not be updated due to invalid submitted data. :statuscode 401: Authentication failure - :statuscode 403: The requested organizer does not exist **or** you have no permission to create this resource. + :statuscode 403: The requested organizer does not exist **or** you have no permission to update this resource. .. http:patch:: /api/v1/organizers/(organizer)/events/(event)/ diff --git a/doc/api/resources/exhibitors.rst b/doc/api/resources/exhibitors.rst index c7bf9f5bc..8f6a89a08 100644 --- a/doc/api/resources/exhibitors.rst +++ b/doc/api/resources/exhibitors.rst @@ -349,6 +349,45 @@ Endpoints :statuscode 401: Authentication failure :statuscode 403: The requested organizer or event or exhibitor does not exist **or** you have no permission to view it. +.. http:post:: /api/v1/organizers/(organizer)/events/(event)/exhibitors/(id)/vouchers/bulk_attach/ + + Attaches many **existing** vouchers to an exhibitor. You need to send either the ``id`` **or** the ``code`` field of + the voucher, but you need to send the same field for all entries. + + **Example request**: + + .. sourcecode:: http + + POST /api/v1/organizers/bigevents/events/sampleconf/exhibitors/1/vouchers/bulk_attach/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + [ + { + "id": 15, + "exhibitor_comment": "Free ticket" + }, + .. + ] + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + {} + + :param organizer: The ``slug`` field of a valid organizer + :param event: The ``slug`` field of the event to use + :param id: The ``id`` field of the exhibitor to use + :statuscode 200: no error + :statuscode 400: Invalid data sent, e.g. voucher does not exist + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer or event or exhibitor does not exist **or** you have no permission to view it. + .. http:post:: /api/v1/organizers/(organizer)/events/(event)/exhibitors/ Create a new exhibitor. diff --git a/doc/api/resources/index.rst b/doc/api/resources/index.rst index 8e6e6f8fc..642befcce 100644 --- a/doc/api/resources/index.rst +++ b/doc/api/resources/index.rst @@ -25,6 +25,7 @@ at :ref:`plugin-docs`. seats orders invoices + transactions vouchers discounts checkin @@ -54,6 +55,7 @@ at :ref:`plugin-docs`. digital exhibitors imported_secrets + offlinesales shipping billing_invoices billing_var diff --git a/doc/api/resources/invoices.rst b/doc/api/resources/invoices.rst index 8e4aae644..bc5723b4c 100644 --- a/doc/api/resources/invoices.rst +++ b/doc/api/resources/invoices.rst @@ -1,3 +1,5 @@ +.. _rest-invoices: + Invoices ======== @@ -24,6 +26,8 @@ invoice_from_country string Sender address: invoice_from_tax_id string Sender address: Local Tax ID invoice_from_vat_id string Sender address: EU VAT ID invoice_to string Full recipient address +invoice_to_is_business boolean Recipient address: Business vs individual (``null`` for + invoices created before pretix 2025.6). invoice_to_company string Recipient address: Company name invoice_to_name string Recipient address: Person name invoice_to_street string Recipient address: Address lines @@ -33,6 +37,7 @@ invoice_to_state string Recipient addre invoice_to_country string Recipient address: Country code invoice_to_vat_id string Recipient address: EU VAT ID invoice_to_beneficiary string Invoice beneficiary +invoice_to_transmission_info object Additional transmission info (see :ref:`rest-transmission-types`) custom_field string Custom invoice address field date date Invoice date refers string Invoice number of an invoice this invoice refers to @@ -108,6 +113,12 @@ foreign_currency_rate decimal (string) If ``foreign_cu foreign_currency_rate_date date If ``foreign_currency_rate`` is set, this signifies the date at which the currency rate was obtained. internal_reference string Customer's reference to be printed on the invoice. +transmission_type string Requested transmission channel (see :ref:`rest-transmission-types`) +transmission_provider string Selected transmission provider (depends on installed + plugins). ``null`` if not yet chosen. +transmission_status string Transmission status, one of ``unknown`` (pre-2025.6), + ``pending``, ``inflight``, ``failed``, and ``completed``. +transmission_date datetime Time of last change in transmission status (may be ``null``). ===================================== ========================== ======================================================= @@ -119,6 +130,76 @@ internal_reference string Customer's refe The ``tax_code`` attribute has been added. +.. versionchanged:: 2025.6 + + The attributes ``invoice_to_is_business``, ``invoice_to_transmission_info``, ``transmission_type``, + ``transmission_provider``, ``transmission_status``, and ``transmission_date`` have been added. + + +.. _`rest-transmission-types`: + +Transmission types +------------------ + +pretix supports multiple ways to transmit an invoice from the organizer to the invoice recipient. +For each transmission type, different fields are supported in the ``transmission_info`` object of the +invoice address. Currently, pretix supports the following transmission types: + +Email +""""" + +The identifier ``"email"`` represents the transmission of PDF invoices through email. +This is the default transmission type in pretix and has some special behavior for backwards compatibility. +Transmission is always executed through the provider ``"email_pdf"``. +The ``transmission_info`` object may contain the following properties: + +.. rst-class:: rest-resource-table + +===================================== ========================== ======================================================= +Field Type Description +===================================== ========================== ======================================================= +transmission_email_address string Optional. An email address other than the order address + that the invoice should be sent to. + Business customers only. +===================================== ========================== ======================================================= + +PEPPOL +"""""" + +The identifier ``"peppol"`` represents the transmission of XML invoices through the `PEPPOL`_ network. +This is only available for business addresses. +This is not supported by pretix out of the box and requires the use of a suitable plugin. +The ``transmission_info`` object may contain the following properties: + +.. rst-class:: rest-resource-table + +===================================== ========================== ======================================================= +Field Type Description +===================================== ========================== ======================================================= +transmission_peppol_participant_id string Required. The PEPPOL participant ID of the recipient. +===================================== ========================== ======================================================= + +Italian Exchange System +""""""""""""""""""""""" + +The identifier ``"it_sdi"`` represents the transmission of XML invoices through the `Sistema di Interscambio`_ network used in Italy. +This is only available for addresses with country ``"IT"``. +This is not supported by pretix out of the box and requires the use of a suitable plugin. +The ``transmission_info`` object may contain the following properties: + +.. rst-class:: rest-resource-table + +===================================== ========================== ======================================================= +Field Type Description +===================================== ========================== ======================================================= +transmission_it_sdi_codice_fiscale string Required for non-business address. Fiscal code of the + recipient. +transmission_it_sdi_pec string Required for business addresses. Address for certified + electronic mail. +transmission_it_sdi_recipient_code string Required for businesses. SdI recipient code. +===================================== ========================== ======================================================= + +If this type is selected, ``vat_id`` is required for business addresses. List of all invoices -------------------- @@ -162,6 +243,7 @@ List of all invoices "invoice_from_vat_id":"", "invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT-ID: EU123456789", "invoice_to_company": "Sample company", + "invoice_to_is_business": true, "invoice_to_name": "John Doe", "invoice_to_street": "Test street 12", "invoice_to_zipcode": "12345", @@ -170,6 +252,7 @@ List of all invoices "invoice_to_country": "TE", "invoice_to_vat_id": "EU123456789", "invoice_to_beneficiary": "", + "invoice_to_transmission_info": {}, "custom_field": null, "date": "2017-12-01", "refers": null, @@ -202,7 +285,11 @@ List of all invoices ], "foreign_currency_display": "PLN", "foreign_currency_rate": "4.2408", - "foreign_currency_rate_date": "2017-07-24" + "foreign_currency_rate_date": "2017-07-24", + "transmission_type": "email", + "transmission_provider": "email_pdf", + "transmission_status": "completed", + "transmission_date": "2017-07-24T10:00:00Z" } ] } @@ -302,6 +389,7 @@ Fetching individual invoices "invoice_from_vat_id":"", "invoice_to": "Sample company\nJohn Doe\nTest street 12\n12345 Testington\nTestikistan\nVAT-ID: EU123456789", "invoice_to_company": "Sample company", + "invoice_to_is_business": true, "invoice_to_name": "John Doe", "invoice_to_street": "Test street 12", "invoice_to_zipcode": "12345", @@ -310,6 +398,7 @@ Fetching individual invoices "invoice_to_country": "TE", "invoice_to_vat_id": "EU123456789", "invoice_to_beneficiary": "", + "invoice_to_transmission_info": {}, "custom_field": null, "date": "2017-12-01", "refers": null, @@ -342,7 +431,11 @@ Fetching individual invoices ], "foreign_currency_display": "PLN", "foreign_currency_rate": "4.2408", - "foreign_currency_rate_date": "2017-07-24" + "foreign_currency_rate_date": "2017-07-24", + "transmission_type": "email", + "transmission_provider": "email_pdf", + "transmission_status": "completed", + "transmission_date": "2017-07-24T10:00:00Z" } :param organizer: The ``slug`` field of the organizer to fetch @@ -447,3 +540,70 @@ Invoices cannot be edited directly, but the following actions can be triggered: :statuscode 400: The invoice has already been canceled :statuscode 401: Authentication failure :statuscode 403: The requested organizer/event does not exist **or** you have no permission to change this resource. + + +Transmitting invoices +--------------------- + +Invoices are transmitted automatically when created during order creation or payment receipt, +but in other cases transmission may need to be triggered manually. + +.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/transmit/ + + Transmits the invoice to the recipient, but only if it is in ``pending`` state. + + **Example request**: + + .. sourcecode:: http + + GET /api/v1/organizers/bigevents/events/sampleconf/invoices/00001/transmit/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 No Content + Vary: Accept + Content-Type: application/pdf + + :param organizer: The ``slug`` field of the organizer to fetch + :param event: The ``slug`` field of the event to fetch + :param number: The ``number`` field of the invoice to transmit + :statuscode 200: no error + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer/event does not exist **or** you have no permission to transmit this invoice **or** the invoice may not be transmitted + :statuscode 409: The invoice is currently in transmission + +.. http:post:: /api/v1/organizers/(organizer)/events/(event)/invoices/(number)/retransmit/ + + Transmits the invoice to the recipient even if transmission was already attempted previously. + + **Example request**: + + .. sourcecode:: http + + GET /api/v1/organizers/bigevents/events/sampleconf/invoices/00001/retransmit/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 204 No Content + Vary: Accept + Content-Type: application/pdf + + :param organizer: The ``slug`` field of the organizer to fetch + :param event: The ``slug`` field of the event to fetch + :param number: The ``number`` field of the invoice to transmit + :statuscode 200: no error + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer/event does not exist **or** you have no permission to transmit this invoice **or** the invoice may not be transmitted + :statuscode 409: The invoice is currently in transmission + + +.. _PEPPOL: https://en.wikipedia.org/wiki/PEPPOL +.. _Sistema di Interscambio: https://it.wikipedia.org/wiki/Fattura_elettronica_in_Italia \ No newline at end of file diff --git a/doc/api/resources/offlinesales.rst b/doc/api/resources/offlinesales.rst new file mode 100644 index 000000000..2a5f937ae --- /dev/null +++ b/doc/api/resources/offlinesales.rst @@ -0,0 +1,219 @@ +Offline sales +============= + +.. note:: This API is only available when the plugin **pretix-offlinesales** is installed (pretix Hosted and Enterprise only). + +The offline sales module allows you to create batches of tickets intended for the sale outside the system. + +Resource description +-------------------- + +The offline sales batch resource contains the following public fields: + +.. rst-class:: rest-resource-table + +===================================== ========================== ======================================================= +Field Type Description +===================================== ========================== ======================================================= +id integer Internal batch ID +creation datetime Time of creation +testmode boolean ``true`` if orders are created in test mode +sales_channel string Sales channel of the orders +layout integer Internal ID of the chosen ticket layout +subevent integer Internal ID of the chosen subevent (or ``null``) +item integer Internal ID of the chosen product +variation integer Internal ID of the chosen variation (or ``null``) +amount integer Number of tickets in the batch +comment string Internal comment +orders list of strings List of order codes (omitted in list view for performance reasons) +===================================== ========================== ======================================================= + +Endpoints +--------- + +.. http:get:: /api/v1/organizers/(organizer)/events/(event)/offlinesalesbatches/ + + Returns a list of all offline sales batches + + **Example request**: + + .. sourcecode:: http + + GET /api/v1/organizers/bigevents/events/democon/offlinesalesbatches/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: text/javascript + + { + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 1, + "creation": "2025-07-08T18:27:32.134368+02:00", + "testmode": False, + "sales_channel": "web", + "comment": "Batch for sale at the event", + "layout": 3, + "subevent": null, + "item": 23, + "variation": null, + "amount": 7 + } + ] + } + + :query page: The page number in case of a multi-page result set, default is 1 + :param organizer: The ``slug`` field of a valid organizer + :param event: The ``slug`` field of a valid event + :statuscode 200: no error + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer does not exist **or** you have no permission to view it. + +.. http:get:: /api/v1/organizers/(organizer)/events/(event)/offlinesalesbatches/(id)/ + + Returns information on a given batch. + + **Example request**: + + .. sourcecode:: http + + GET /api/v1/organizers/bigevents/events/democon/offlinesalesbatches/1/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: text/javascript + + { + "id": 1, + "creation": "2025-07-08T18:27:32.134368+02:00", + "testmode": False, + "sales_channel": "web", + "comment": "Batch for sale at the event", + "layout": 3, + "subevent": null, + "item": 23, + "variation": null, + "amount": 7, + "orders": ["TSRNN", "3FBSL", "WMDNJ", "BHW9H", "MXSUG", "DSDAP", "URLLE"] + } + + :param organizer: The ``slug`` field of the organizer to fetch + :param event: The ``slug`` field of the event to fetch + :param id: The ``id`` field of the batch to fetch + :statuscode 200: no error + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer/event does not exist **or** you have no permission to view it. + + +.. http:post:: /api/v1/organizers/(organizer)/events/(event)/offlinesalesbatches/ + + With this API call, you can instruct the system to create a new batch. + + Since batches can contain up to 10,000 tickets, they are created asynchronously on the server. + If your input parameters validate correctly, a ``202 Accepted`` status code is returned. + The body points you to the check URL of the result. Running a ``GET`` request on that result URL will + yield one of the following status codes: + + * ``200 OK`` – The creation of the batch has succeeded. The body will be your resulting batch with the same information as in the detail endpoint above. + * ``409 Conflict`` – Your creation job is still running. The body will be JSON with the structure ``{"status": "running"}``. ``status`` can be ``waiting`` before the task is actually being processed. Please retry, but wait at least one second before you do. + * ``410 Gone`` – Creating the batch has failed permanently (e.g. quota no longer available). The body will be JSON with the structure ``{"status": "failed", "message": "Error message"}`` + * ``404 Not Found`` – The job does not exist / is expired. + + .. note:: To avoid performance issues, a maximum amount of 10000 is currently allowed. + + .. note:: Do not wait multiple hours or more to retrieve your result. After a longer wait time, ``409`` might be returned permanently due to technical constraints, even though nothing will happen any more. + + **Example request**: + + .. sourcecode:: http + + POST /api/v1/organizers/bigevents/events/sampleconf/offlinesalesbatches/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + Content-Type: application/json + + { + "testmode": True, + "layout": 123, + "item": 14, + "sales_channel": "web", + "amount": 10, + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + { + "check": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/offlinesalesbatches/check/29891ede-196f-4942-9e26-d055a36e98b8/" + } + + :param organizer: The ``slug`` field of the organizer to fetch + :param event: The ``slug`` field of the event to fetch + :statuscode 202: no error + :statuscode 400: Invalid input options + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource. + + +.. http:post:: /api/v1/organizers/(organizer)/events/(event)/offlinesalesbatches/(id)/render/ + + With this API call, you can render the PDF representation of a batch. + + Since batches can contain up to 10,000 tickets, they are rendered asynchronously on the server. + If your input parameters validate correctly, a ``202 Accepted`` status code is returned. + The body points you to the download URL of the result. Running a ``GET`` request on that result URL will + yield one of the following status codes: + + * ``200 OK`` – The creation of the batch has succeeded. The body will be your resulting batch with the same information as in the detail endpoint above. + * ``409 Conflict`` – Your rendering process is still running. The body will be JSON with the structure ``{"status": "running"}``. ``status`` can be ``waiting`` before the task is actually being processed. Please retry, but wait at least one second before you do. + * ``410 Gone`` – Rendering the batch has failed permanently. The body will be JSON with the structure ``{"status": "failed", "message": "Error message"}`` + * ``404 Not Found`` – The rendering job does not exist / is expired. + + **Example request**: + + .. sourcecode:: http + + POST /api/v1/organizers/bigevents/events/sampleconf/offlinesalesbatches/1/render HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + { + "download": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/offlinesalesbatches/1/download/29891ede-196f-4942-9e26-d055a36e98b8/3f279f13-c198-4137-b49b-9b360ce9fcce/" + } + + :param organizer: The ``slug`` field of the organizer to fetch + :param event: The ``slug`` field of the event to fetch + :param id: The ``id`` field of the batch to fetch + :statuscode 202: no error + :statuscode 400: Invalid input options + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource. + diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 23ea2954a..e1c3c30a6 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -65,11 +65,16 @@ invoice_address object Invoice address ├ state string Customer state (ISO 3166-2 code). Only supported in AU, BR, CA, CN, MY, MX, and US. ├ internal_reference string Customer's internal reference to be printed on the invoice + ├ custom_field string Custom invoice address field ├ vat_id string Customer VAT ID -└ vat_id_validated string ``true``, if the VAT ID has been validated against the +├ vat_id_validated string ``true``, if the VAT ID has been validated against the EU VAT service and validation was successful. This only happens in rare cases. +├ transmission_type string Transmission channel for invoice (see also :ref:`rest-transmission-types`). + Defaults to ``email``. +└ transmission_info object Transmission-channel specific information (or ``null``). + See also :ref:`rest-transmission-types`. positions list of objects List of order positions (see below). By default, only non-canceled positions are included. fees list of objects List of fees included in the order total. By default, only @@ -142,6 +147,10 @@ plugin_data object Additional data The ``plugin_data`` attribute has been added. +.. versionchanged:: 2025.6 + + The ``invoice_address.transmission_type`` and ``invoice_address.transmission_info`` attributes have been added. + .. _order-position-resource: Order position resource @@ -368,7 +377,9 @@ List of all orders "state": "", "internal_reference": "", "vat_id": "EU123456789", - "vat_id_validated": false + "vat_id_validated": false, + "transmission_type": "email", + "transmission_info": {} }, "positions": [ { @@ -610,7 +621,9 @@ Fetching individual orders "state": "", "internal_reference": "", "vat_id": "EU123456789", - "vat_id_validated": false + "vat_id_validated": false, + "transmission_type": "email", + "transmission_info": {} }, "positions": [ { @@ -1017,6 +1030,8 @@ Creating orders * ``vat_id_validated`` (optional) – If you need support for reverse charge (rarely the case), you need to check yourself if the passed VAT ID is a valid EU VAT ID. In that case, set this to ``true``. Only valid VAT IDs will trigger reverse charge taxation. Don't forget to set ``is_business`` as well! + * ``transmission_type`` (optional, defaults to ``email``) + * ``transmission_info`` (optional, see also :ref:`rest-transmission-types`) * ``positions`` @@ -1926,6 +1941,7 @@ Manipulating individual positions (Full order position resource, see above.) + :query boolean check_quotas: Whether to check quotas before committing item changes, default is ``true`` :param organizer: The ``slug`` field of the organizer of the event :param event: The ``slug`` field of the event :param id: The ``id`` field of the order position to update @@ -2005,6 +2021,7 @@ Manipulating individual positions (Full order position resource, see above.) + :query boolean check_quotas: Whether to check quotas before creating the new position, default is ``true`` :param organizer: The ``slug`` field of the organizer of the event :param event: The ``slug`` field of the event @@ -2291,6 +2308,7 @@ otherwise, such as splitting an order or changing fees. (Full order position resource, see above.) + :query boolean check_quotas: Whether to check quotas before patching or creating positions, default is ``true`` :param organizer: The ``slug`` field of the organizer of the event :param event: The ``slug`` field of the event :param code: The ``code`` field of the order to update diff --git a/doc/api/resources/organizers.rst b/doc/api/resources/organizers.rst index eb3b28fe4..066657a4d 100644 --- a/doc/api/resources/organizers.rst +++ b/doc/api/resources/organizers.rst @@ -19,6 +19,11 @@ name string The organizer's slug string A short form of the name, used e.g. in URLs. public_url string The public, customer-facing URL of the organizer, where the list of all events can be found (read-only). +plugins list A list of package names of the enabled plugins for this + organizer. Note that most plugins are enabled on the + event level (or both levels). If you remove a plugin + that is also enabled on some events, it will + automatically be removed from all events as well. ===================================== ========================== ======================================================= @@ -53,7 +58,10 @@ Endpoints { "name": "Big Events LLC", "slug": "Big Events", - "public_url": "https://pretix.eu/bigevents/" + "public_url": "https://pretix.eu/bigevents/", + "plugins": [ + "pretix_datev" + ] } ] } @@ -87,7 +95,10 @@ Endpoints { "name": "Big Events LLC", "slug": "Big Events", - "public_url": "https://pretix.eu/bigevents/" + "public_url": "https://pretix.eu/bigevents/", + "plugins": [ + "pretix_datev" + ] } :param organizer: The ``slug`` field of the organizer to fetch @@ -95,6 +106,50 @@ Endpoints :statuscode 401: Authentication failure :statuscode 403: The requested organizer does not exist **or** you have no permission to view it. +.. http:patch:: /api/v1/organizers/(organizer)/ + + Updates an organizer. Currently only the ``plugins`` field may be updated. + + Permission required: "Can change organizer settings" + + **Example request**: + + .. sourcecode:: http + + PATCH /api/v1/organizers/bigevents/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + Content-Type: application/json + + { + "plugins": [ + "pretix_seating" + ] + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + { + "name": "Big Events LLC", + "slug": "Big Events", + "public_url": "https://pretix.eu/bigevents/", + "plugins": [ + "pretix_seating" + ] + } + + :param organizer: The ``slug`` field of the organizer to update + :statuscode 200: no error + :statuscode 400: The organizer could not be updated due to invalid submitted data. + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer does not exist **or** you have no permission to update this resource. + Organizer settings ------------------ diff --git a/doc/api/resources/quotas.rst b/doc/api/resources/quotas.rst index 87a985e18..42e263c2a 100644 --- a/doc/api/resources/quotas.rst +++ b/doc/api/resources/quotas.rst @@ -28,6 +28,8 @@ closed boolean Whether the quo field). release_after_exit boolean Whether the quota regains capacity as soon as some tickets have been scanned at an exit. +ignore_for_event_availability boolean Whether the quota is ignored when calculating the event's + availability of tickets. available boolean Whether this quota is available. Only returned if ``with_availability=true`` is set on the request. Do not rely on this value for critical operations, it may be slightly out of date. @@ -36,6 +38,10 @@ available_number integer Number of avail slightly out of date. ``null`` means unlimited. ===================================== ========================== ======================================================= +.. versionchanged:: 2025.7 + + The attribute ``ignore_for_event_availability`` has been added. + Endpoints --------- @@ -72,7 +78,8 @@ Endpoints "variations": [1, 4, 5, 7], "subevent": null, "close_when_sold_out": false, - "closed": false + "closed": false, + "ignore_for_event_availability": false } ] } @@ -118,7 +125,8 @@ Endpoints "variations": [1, 4, 5, 7], "subevent": null, "close_when_sold_out": false, - "closed": false + "closed": false, + "ignore_for_event_availability": false } :param organizer: The ``slug`` field of the organizer to fetch @@ -149,7 +157,8 @@ Endpoints "variations": [1, 4, 5, 7], "subevent": null, "close_when_sold_out": false, - "closed": false + "closed": false, + "ignore_for_event_availability": false } **Example response**: @@ -168,7 +177,8 @@ Endpoints "variations": [1, 4, 5, 7], "subevent": null, "close_when_sold_out": false, - "closed": false + "closed": false, + "ignore_for_event_availability": false } :param organizer: The ``slug`` field of the organizer of the event/item to create a quota for @@ -223,7 +233,8 @@ Endpoints ], "subevent": null, "close_when_sold_out": false, - "closed": false + "closed": false, + "ignore_for_event_availability": false } :param organizer: The ``slug`` field of the organizer to modify diff --git a/doc/api/resources/taxrules.rst b/doc/api/resources/taxrules.rst index 2947015f1..a8e6b7239 100644 --- a/doc/api/resources/taxrules.rst +++ b/doc/api/resources/taxrules.rst @@ -26,6 +26,8 @@ rate decimal (string) Tax rate in per 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 the specified product price +default boolean If ``true`` (default), this is the default tax rate for this event + (there can only be one per event). eu_reverse_charge boolean **DEPRECATED**. If ``true``, EU reverse charge rules are applied. Will be ignored if custom rules are set. Use custom rules instead. @@ -48,6 +50,10 @@ custom_rules object Dynamic rules s The ``code`` attribute has been added. +.. versionchanged:: 2025.4 + + The ``default`` attribute has been added. + .. _rest-taxcodes: Tax codes @@ -111,6 +117,7 @@ Endpoints { "id": 1, "name": {"en": "VAT"}, + "default": true, "internal_name": "VAT", "code": "S/standard", "rate": "19.00", @@ -153,6 +160,7 @@ Endpoints { "id": 1, "name": {"en": "VAT"}, + "default": true, "internal_name": "VAT", "code": "S/standard", "rate": "19.00", @@ -203,6 +211,7 @@ Endpoints { "id": 1, "name": {"en": "VAT"}, + "default": false, "internal_name": "VAT", "code": "S/standard", "rate": "19.00", diff --git a/doc/api/resources/transactions.rst b/doc/api/resources/transactions.rst new file mode 100644 index 000000000..387b7b288 --- /dev/null +++ b/doc/api/resources/transactions.rst @@ -0,0 +1,232 @@ +.. _rest-transactions: + +Transactions +============ + +Transactions are an additional way to think about orders. They are are an immutable, filterable view into an order's +history and are a good basis for financial reporting. + +Our financial model +------------------- + +You can think of a pretix order similar to a debtor account in double-entry bookkeeping. For example, the flow of an +order could look like this: + +===================================================== ==================== ===================== +Transaction Debit Credit +===================================================== ==================== ===================== +Order is placed with two tickets € 500 +Order is paid partially with a gift card € 200 +Remainder is paid with a credit card € 300 +One of the tickets is canceled **-** € 250 +Refund is made to the credit card **-** € 250 +**Balance** **€ 250** **€ 250** +===================================================== ==================== ===================== + +If an order is fully settled, the sums of both columns match. However, as the movements in both columns do not always +happen at the same time, at some times during the lifecycle of an order the sums are not balanced, in which case we +consider an order to be "pending payment" or "overpaid". + +In the API, the "Debit" column is represented by the "transaction" resource listed on this page. +In many cases, the left column *usually* also matches the data returned by the :ref:`rest-invoices` resource, but there +are two important differences: + +- pretix may be configured such that an invoice is not always generated for an order. In this case, only the transactions + return the full data set. + +- pretix does not enforce a new invoice to be created e.g. when a ticket is changed to a different subevent. However, + pretix always creates a new transaction whenever there is a change to a ticket that concerns the **price**, **tax rate**, + **product**, or **date** (in an event series). + +The :ref:`rest-orders` themselves are not a good representation of the "Debit" side of the table for accounting +purposes since they are not immutable: +They will only tell you the current state of the order, not what it was a week ago. + +The "Credit" column is represented by the :ref:`order-payment-resource` and :ref:`order-refund-resource`. + + +Resource description +-------------------- + +.. rst-class:: rest-resource-table + +===================================== ========================== ======================================================= +Field Type Description +===================================== ========================== ======================================================= +id integer Internal ID of the transaction +order string Order code the transaction was created from +event string Event slug, only present on organizer-level API calls +created datetime The creation time of the transaction in the database +datetime datetime The time at which the transaction is financially relevant. + This is usually the same as created, but may vary for + retroactively created transactions after software bugs or + for data that preceeds this data model. +positionid integer Number of the position within the order this refers to, + is ``null`` for transactions that refer to a fee +count integer Number of items purchased, is negative for cancellations +item integer The internal ID of the item purchased (or ``null`` for fees) +variation integer The internal ID of the variation purchased (or ``null``) +subevent integer The internal ID of the event series date (or ``null``) +price money (string) Gross price of the transaction +tax_rate decimal (string) Tax rate applied in transaction +tax_rule integer The internal ID of the tax rule used (or ``null``) +tax_code string The selected tax code (or ``null``) +tax_value money (string) The computed tax value +fee_type string The type of fee (or ``null`` for products) +internal_type string Additional type classification of the fee (or ``null`` for products) +===================================== ========================== ======================================================= + +.. versionchanged:: 2025.7.0 + + This resource was added to the API. + + +Endpoints +--------- + +.. http:get:: /api/v1/organizers/(organizer)/events/(event)/transactions/ + + Returns a list of all transactions of an event. + + **Example request**: + + .. sourcecode:: http + + GET /api/v1/organizers/bigevents/events/sampleconf/transactions/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + { + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 123, + "order": "FOO", + "count": 1, + "created": "2017-12-01T10:00:00Z", + "datetime": "2017-12-01T10:00:00Z", + "item": null, + "variation": null, + "positionid": 1, + "price": "23.00", + "subevent": null, + "tax_code": "E", + "tax_rate": "0.00", + "tax_rule": 23, + "tax_value": "0.00", + "fee_type": null, + "internal_type": null + } + ] + } + + :query integer page: The page number in case of a multi-page result set, default is 1 + :query string order: Only return transactions matching the given order code. + :query datetime_since: Only return transactions with a datetime at or after the given time. + :query datetime_before: Only return transactions with a datetime before the given time. + :query created_since: Only return transactions with a creation time at or after the given time. + :query created_before: Only return transactions with a creation time before the given time. + :query item: Only return transactions that match the given item ID. + :query item__in: Only return transactions that match one of the given item IDs (separated with a comma). + :query variation: Only return transactions that match the given variation ID. + :query variation__in: Only return transactions that match one of the given variation IDs (separated with a comma). + :query subevent: Only return transactions that match the given subevent ID. + :query subevent__in: Only return transactions that match one of the given subevent IDs (separated with a comma). + :query tax_rule: Only return transactions that match the given tax rule ID. + :query tax_rule__in: Only return transactions that match one of the given tax rule IDs (separated with a comma). + :query tax_code: Only return transactions that match the given tax code. + :query tax_code__in: Only return transactions that match one of the given tax codes (separated with a comma). + :query tax_rate: Only return transactions that match the given tax rate. + :query tax_rate__in: Only return transactions that match one of the given tax rates (separated with a comma). + :query fee_type: Only return transactions that match the given fee type. + :query fee_type__in: Only return transactions that match one of the given fee types (separated with a comma). + :query string ordering: Manually set the ordering of results. Valid fields to be used are ``datetime``, ``created``, and ``id``. + :param organizer: The ``slug`` field of a valid organizer + :param event: The ``slug`` field of a valid event + :statuscode 200: no error + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer or event does not exist **or** you have no permission to view it. + +.. http:get:: /api/v1/organizers/(organizer)/transactions/ + + Returns a list of all transactions of an organizer that you have access to. + + **Example request**: + + .. sourcecode:: http + + GET /api/v1/organizers/bigevents/transactions/ HTTP/1.1 + Host: pretix.eu + Accept: application/json, text/javascript + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept + Content-Type: application/json + + { + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 123, + "event": "sampleconf", + "order": "FOO", + "count": 1, + "created": "2017-12-01T10:00:00Z", + "datetime": "2017-12-01T10:00:00Z", + "item": null, + "variation": null, + "positionid": 1, + "price": "23.00", + "subevent": null, + "tax_code": "E", + "tax_rate": "0.00", + "tax_rule": 23, + "tax_value": "0.00", + "fee_type": null, + "internal_type": null + } + ] + } + + :query integer page: The page number in case of a multi-page result set, default is 1 + :query string event: Only return transactions matching the given event slug. + :query string order: Only return transactions matching the given order code. + :query datetime_since: Only return transactions with a datetime at or after the given time. + :query datetime_before: Only return transactions with a datetime before the given time. + :query created_since: Only return transactions with a creation time at or after the given time. + :query created_before: Only return transactions with a creation time before the given time. + :query item: Only return transactions that match the given item ID. + :query item__in: Only return transactions that match one of the given item IDs (separated with a comma). + :query variation: Only return transactions that match the given variation ID. + :query variation__in: Only return transactions that match one of the given variation IDs (separated with a comma). + :query subevent: Only return transactions that match the given subevent ID. + :query subevent__in: Only return transactions that match one of the given subevent IDs (separated with a comma). + :query tax_rule: Only return transactions that match the given tax rule ID. + :query tax_rule__in: Only return transactions that match one of the given tax rule IDs (separated with a comma). + :query tax_code: Only return transactions that match the given tax code. + :query tax_code__in: Only return transactions that match one of the given tax codes (separated with a comma). + :query tax_rate: Only return transactions that match the given tax rate. + :query tax_rate__in: Only return transactions that match one of the given tax rates (separated with a comma). + :query fee_type: Only return transactions that match the given fee type. + :query fee_type__in: Only return transactions that match one of the given fee types (separated with a comma). + :query string ordering: Manually set the ordering of results. Valid fields to be used are ``datetime``, ``created``, and ``id``. + :param organizer: The ``slug`` field of a valid organizer + :statuscode 200: no error + :statuscode 401: Authentication failure + :statuscode 403: The requested organizer does not exist **or** you have no permission to view it. diff --git a/doc/api/resources/vouchers.rst b/doc/api/resources/vouchers.rst index 35dc78241..87fdd47b8 100644 --- a/doc/api/resources/vouchers.rst +++ b/doc/api/resources/vouchers.rst @@ -14,6 +14,7 @@ The voucher resource contains the following public fields: Field Type Description ===================================== ========================== ======================================================= id integer Internal ID of the voucher +created datetime The creation date of the voucher. For vouchers created before pretix 2025.7.0, this is guessed retroactively and might not be accurate. code string The voucher code that is required to redeem the voucher max_usages integer The maximum number of times this voucher can be redeemed (default: 1). @@ -49,8 +50,14 @@ subevent integer ID of the date show_hidden_items boolean Only if set to ``true``, this voucher allows to buy products with the property ``hide_without_voucher``. Defaults to ``true``. all_addons_included boolean If set to ``true``, all add-on products for the product purchased with this voucher are included in the base price. all_bundles_included boolean If set to ``true``, all bundled products for the product purchased with this voucher are added without their designated price. +budget money (string) The budget a voucher is allowed to consume before being used up (or ``null``) +budget_used money (string) The amount of budget the voucher has already used up. ===================================== ========================== ======================================================= +.. versionchanged:: 2025.7 + + The attributes ``created``, ``budget``, and ``budget_used`` have been added. + Endpoints --------- @@ -82,6 +89,7 @@ Endpoints "results": [ { "id": 1, + "created": "2020-09-18T14:17:40.971519Z", "code": "43K6LKM37FBVR2YG", "max_usages": 1, "redeemed": 0, @@ -99,7 +107,9 @@ Endpoints "subevent": null, "show_hidden_items": false, "all_addons_included": false, - "all_bundles_included": false + "all_bundles_included": false, + "budget": None, + "budget_used": "0.00" } ] } @@ -152,6 +162,7 @@ Endpoints { "id": 1, + "created": "2020-09-18T14:17:40.971519Z", "code": "43K6LKM37FBVR2YG", "max_usages": 1, "redeemed": 0, @@ -169,7 +180,9 @@ Endpoints "subevent": null, "show_hidden_items": false, "all_addons_included": false, - "all_bundles_included": false + "all_bundles_included": false, + "budget": None, + "budget_used": "0.00" } :param organizer: The ``slug`` field of the organizer to fetch @@ -222,6 +235,7 @@ Endpoints { "id": 1, + "created": "2020-09-18T14:17:40.971519Z", "code": "43K6LKM37FBVR2YG", "max_usages": 1, "redeemed": 0, @@ -239,7 +253,9 @@ Endpoints "subevent": null, "show_hidden_items": false, "all_addons_included": false, - "all_bundles_included": false + "all_bundles_included": false, + "budget": None, + "budget_used": "0.00" } :param organizer: The ``slug`` field of the organizer to create a voucher for @@ -313,6 +329,7 @@ Endpoints [ { "id": 1, + "created": "2020-09-18T14:17:40.971519Z", "code": "43K6LKM37FBVR2YG", … }, … @@ -359,6 +376,7 @@ Endpoints { "id": 1, + "created": "2020-09-18T14:17:40.971519Z", "code": "43K6LKM37FBVR2YG", "max_usages": 1, "redeemed": 0, @@ -376,7 +394,9 @@ Endpoints "subevent": null, "show_hidden_items": false, "all_addons_included": false, - "all_bundles_included": false + "all_bundles_included": false, + "budget": None, + "budget_used": "0.00" } :param organizer: The ``slug`` field of the organizer to modify diff --git a/doc/api/resources/webhooks.rst b/doc/api/resources/webhooks.rst index c7be77326..94dcc1b68 100644 --- a/doc/api/resources/webhooks.rst +++ b/doc/api/resources/webhooks.rst @@ -60,6 +60,9 @@ The following values for ``action_types`` are valid with pretix core: * ``pretix.event.added`` * ``pretix.event.changed`` * ``pretix.event.deleted`` + * ``pretix.voucher.added`` + * ``pretix.voucher.changed`` + * ``pretix.voucher.deleted`` * ``pretix.subevent.added`` * ``pretix.subevent.changed`` * ``pretix.subevent.deleted`` diff --git a/doc/development/api/datasync.rst b/doc/development/api/datasync.rst new file mode 100644 index 000000000..31e0e7147 --- /dev/null +++ b/doc/development/api/datasync.rst @@ -0,0 +1,207 @@ +.. highlight:: python + :linenothreshold: 5 + +Data sync providers +=================== + +.. warning:: This feature is considered **experimental**. It might change at any time without prior notice. + +pretix provides connectivity to many external services through plugins. A common requirement +is unidirectionally sending (order, customer, ticket, ...) data into external systems. +The transfer is usually triggered by signals provided by pretix core (e.g. :data:`order_placed`), +but performed asynchronously. + +Such plugins should use the :class:`OutboundSyncProvider` API to utilize the queueing, retry and mapping +mechanisms as well as the user interface for configuration and monitoring. Sync providers are registered +in the :py:attr:`pretix.base.datasync.datasync.datasync_providers` :ref:`registry `. + +An :class:`OutboundSyncProvider` for subscribing event participants to a mailing list could start +like this, for example: + +.. code-block:: python + + from pretix.base.datasync.datasync import (OutboundSyncProvider, datasync_providers) + + @datasync_providers.register + class MyListSyncProvider(OutboundSyncProvider): + identifier = "my_list" + display_name = "My Mailing List Service" + # ... + + +The plugin must register listeners in `signals.py` for all signals that should to trigger a sync and +within it has to call :meth:`MyListSyncProvider.enqueue_order` to enqueue the order for synchronization: + +.. code-block:: python + + @receiver(order_placed, dispatch_uid="mylist_order_placed") + def on_order_placed(sender, order, **kwargs): + MyListSyncProvider.enqueue_order(order, "order_placed") + + +Property mappings +----------------- + +Most of these plugins need to translate data from some pretix objects (e.g. orders) +into an external system's data structures. Sometimes, there is only one reasonable way or the +plugin author makes an opinionated decision what information from which objects should be +transferred into which data structures in the external system. + +Otherwise, you can use a :class:`PropertyMappingFormSet` to let the user set up a mapping from pretix model fields +to external data fields. You could store the mapping information either in the event settings, or in a separate +data model. Your implementation of :attr:`OutboundSyncProvider.mappings` +needs to provide a list of mappings, which can be e.g. static objects or model instances, as long as they +have at least the properties defined in +:class:`pretix.base.datasync.datasync.StaticMapping`. + +.. code-block:: python + + # class MyListSyncProvider, contd. + def mappings(self): + return [ + StaticMapping( + id=1, pretix_model='Order', external_object_type='Contact', + pretix_id_field='email', external_id_field='email', + property_mappings=self.event.settings.mylist_order_mapping, + )) + ] + + +Currently, we support `orders` and `order positions` as data sources, with the data fields defined in +:func:`pretix.base.datasync.sourcefields.get_data_fields`. + +To perform the actual sync, implement :func:`sync_object_with_properties` and optionally +:func:`finalize_sync_order`. The former is called for each object to be created according to the ``mappings``. +For each order that was enqueued using :func:`enqueue_order`: + +- each Mapping with ``pretix_model == "Order"`` results in one call to :func:`sync_object_with_properties`, +- each Mapping with ``pretix_model == "OrderPosition"`` results in one call to + :func:`sync_object_with_properties` per order position, +- :func:`finalize_sync_order` is called one time after all calls to :func:`sync_object_with_properties`. + + +Implementation examples +----------------------- + +For example implementations, see the test cases in :mod:`tests.base.test_datasync`. + +In :class:`SimpleOrderSync`, a basic data transfer of order data only is +shown. Therein, a ``sync_object_with_properties`` method is defined as follows: + +.. code-block:: python + + from pretix.base.datasync.utils import assign_properties + + # class MyListSyncProvider, contd. + def sync_object_with_properties( + self, external_id_field, id_value, properties: list, inputs: dict, + mapping, mapped_objects: dict, **kwargs, + ): + # First, we query the external service if our object-to-sync already exists there. + # This is necessary to make sure our method is idempotent, i.e. handles already synced + # data gracefully. + pre_existing_object = self.fake_api_client.retrieve_object( + mapping.external_object_type, + external_id_field, + id_value + ) + + # We use the helper function ``assign_properties`` to update a pre-existing object. + update_values = assign_properties( + new_values=properties, + old_values=pre_existing_object or {}, + is_new=pre_existing_object is None, + list_sep=";", + ) + + # Then we can send our new data to the external service. The specifics of course depends + # on your API, e.g. you may need to use different endpoints for creating or updating an + # object, or pass the identifier separately instead of in the same dictionary as the + # other properties. + result = self.fake_api_client.create_or_update_object(mapping.external_object_type, { + **update_values, + external_id_field: id_value, + "_id": pre_existing_object and pre_existing_object.get("_id"), + }) + + # Finally, return a dictionary containing at least `object_type`, `external_id_field`, + # `id_value`, `external_link_href`, and `external_link_display_name` keys. + # Further keys may be provided for your internal use. This dictionary is provided + # in following calls in the ``mapped_objects`` dict, to allow creating associations + # to this object. + return { + "object_type": mapping.external_object_type, + "external_id_field": external_id_field, + "id_value": id_value, + "external_link_href": f"https://example.org/external-system/{mapping.external_object_type}/{id_value}/", + "external_link_display_name": f"Contact #{id_value} - Jane Doe", + "my_result": result, + } + +.. note:: The result dictionaries of earlier invocations of :func:`sync_object_with_properties` are + only provided in subsequent calls of the same sync run, such that a mapping can + refer to e.g. the external id of an object created by a preceding mapping. + However, the result dictionaries are currently not provided across runs. This will + likely change in a future revision of this API, to allow easier integration of external + systems that do not allow retrieving/updating data by a pretix-provided key. + +``mapped_objects`` is a dictionary of lists of dictionaries. The keys to the dictionary are +the mapping identifiers (``mapping.id``), the lists contain the result dictionaries returned +by :func:`sync_object_with_properties`. + + +In :class:`OrderAndTicketAssociationSync`, an example is given where orders, order positions, +and the association between them are transferred. + + +The OutboundSyncProvider base class +----------------------------------- + +.. autoclass:: pretix.base.datasync.datasync.OutboundSyncProvider + :members: + + +Property mapping format +----------------------- + +To allow the user to configure property mappings, you can use the PropertyMappingFormSet, +which will generate the required ``property_mappings`` value automatically. If you need +to specify the property mappings programmatically, you can refer to the description below +on their format. + +.. autoclass:: pretix.control.forms.mapping.PropertyMappingFormSet + :members: to_property_mappings_json + +A simple JSON-serialized ``property_mappings`` list for mapping some order information can look like this: + +.. code-block:: json + + [ + { + "pretix_field": "email", + "external_field": "orderemail", + "value_map": "", + "overwrite": "overwrite", + }, + { + "pretix_field": "order_status", + "external_field": "status", + "value_map": "{\"n\": \"pending\", \"p\": \"paid\", \"e\": \"expired\", \"c\": \"canceled\", \"r\": \"refunded\"}", + "overwrite": "overwrite", + }, + { + "pretix_field": "order_total", + "external_field": "total", + "value_map": "", + "overwrite": "overwrite", + } + ] + + +Translating mappings on Event copy +---------------------------------- + +Property mappings can contain references to event-specific primary keys. Therefore, plugins must register to the +event_copy_data signal and call translate_property_mappings on all property mappings they store. + +.. autofunction:: pretix.base.datasync.utils.translate_property_mappings diff --git a/doc/development/api/general.rst b/doc/development/api/general.rst index c1d3a4202..b17f08913 100644 --- a/doc/development/api/general.rst +++ b/doc/development/api/general.rst @@ -30,7 +30,7 @@ Check-ins .. automodule:: pretix.base.signals :no-index: - :members: checkin_created + :members: checkin_created, checkin_annulled Frontend diff --git a/doc/development/api/index.rst b/doc/development/api/index.rst index eeb7ea445..3d18ff922 100644 --- a/doc/development/api/index.rst +++ b/doc/development/api/index.rst @@ -13,10 +13,12 @@ Contents: email placeholder invoice + invoicetransmission shredder import customview cookieconsent auth + datasync general quality diff --git a/doc/development/api/invoicetransmission.rst b/doc/development/api/invoicetransmission.rst new file mode 100644 index 000000000..e897dcbf8 --- /dev/null +++ b/doc/development/api/invoicetransmission.rst @@ -0,0 +1,65 @@ +.. highlight:: python + :linenothreshold: 5 + +Writing an invoice transmission plugin +====================================== + +An invoice transmission provider transports an invoice from the sender to the recipient. +There are pre-defined types of invoice transmission in pretix, currently ``"email"``, ``"peppol"``, and ``"it_sdi"``. +You can find more information about them at :ref:`rest-transmission-types`. + +New transmission types can not be added by plugins but need to be added to pretix itself. +However, plugins can provide implementations for the actual transmission. +Please read :ref:`Creating a plugin ` first, if you haven't already. + +Output registration +------------------- + +New invoice transmission providers can be registered through the :ref:`registry ` mechanism + +.. code-block:: python + + from pretix.base.invoicing.transmission import transmission_providers, TransmissionProvider + + @transmission_providers.new() + class SdiTransmissionProvider(TransmissionProvider): + identifier = "fatturapa_providerabc" + type = "it_sdi" + verbose_name = _("FatturaPA through provider ABC") + ... + + +The provider class +------------------ + +.. class:: pretix.base.invoicing.transmission.TransmissionProvider + + .. autoattribute:: identifier + + This is an abstract attribute, you **must** override this! + + .. autoattribute:: type + + This is an abstract attribute, you **must** override this! + + .. autoattribute:: verbose_name + + This is an abstract attribute, you **must** override this! + + .. autoattribute:: priority + + .. autoattribute:: testmode_supported + + .. automethod:: is_ready + + This is an abstract method, you **must** override this! + + .. automethod:: is_available + + This is an abstract method, you **must** override this! + + .. automethod:: transmit + + This is an abstract method, you **must** override this! + + .. automethod:: settings_url diff --git a/doc/development/api/plugins.rst b/doc/development/api/plugins.rst index fe2287eee..e81112dbc 100644 --- a/doc/development/api/plugins.rst +++ b/doc/development/api/plugins.rst @@ -56,6 +56,20 @@ restricted boolean (optional) ``False`` by default, restricts a plugin for an event by system administrators / superusers. experimental boolean (optional) ``False`` by default, marks a plugin as an experimental feature in the plugins list. compatibility string Specifier for compatible pretix versions. +level string System level the plugin can be activated at. + Set to ``pretix.base.plugins.PLUGIN_LEVEL_EVENT`` for plugins that can be activated + at event level and then be active for that event only. + Set to ``pretix.base.plugins.PLUGIN_LEVEL_ORGANIZER`` for plugins that can be + activated only for the organizer as a whole and are active for any event within + that organizer. + Set to ``pretix.base.plugins.PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID`` for plugins that + can be activated at organizer level but are considered active only within events + for which they have also been specifically activated. + More levels, e.g. user-level plugins, might be invented in the future. +settings_links list List of ``((menu name, submenu name, …), urlname, url_kwargs)`` tuples that point + to the plugin's settings. +navigation_links list List of ``((menu name, submenu name, …), urlname, url_kwargs)`` tuples that point + to the plugin's system pages. ================== ==================== =========================================================== A working example would be: @@ -63,9 +77,9 @@ A working example would be: .. code-block:: python try: - from pretix.base.plugins import PluginConfig + from pretix.base.plugins import PluginConfig, PLUGIN_LEVEL_EVENT except ImportError: - raise RuntimeError("Please use pretix 2.7 or above to run this plugin!") + raise RuntimeError("Please use pretix 2025.7 or above to run this plugin!") from django.utils.translation import gettext_lazy as _ @@ -79,6 +93,7 @@ A working example would be: version = '1.0.0' category = 'PAYMENT' picture = 'pretix_paypal/paypal_logo.svg' + level = PLUGIN_LEVEL_EVENT visible = True featured = False restricted = False @@ -142,14 +157,14 @@ method to make your receivers available: from . import signals # NOQA You can optionally specify code that is executed when your plugin is activated for an event -in the ``installed`` method: +or organizer in the ``installed`` method: .. code-block:: python class PaypalApp(AppConfig): … - def installed(self, event): + def installed(self, event_or_organizer): pass # Your code here diff --git a/doc/development/setup.rst b/doc/development/setup.rst index 1975d757e..9d34aa4d4 100644 --- a/doc/development/setup.rst +++ b/doc/development/setup.rst @@ -5,7 +5,7 @@ Development setup This tutorial helps you to get started hacking with pretix on your own computer. You need this to be able to contribute to pretix, but it might also be helpful if you want to write your own plugins. -If you want to install pretix on a server for actual usage, go to the [administrator documentation](https://docs.pretix.eu/self-hosting/) instead. +If you want to install pretix on a server for actual usage, go to the `administrator documentation`_ instead. Obtain a copy of the source code -------------------------------- @@ -221,3 +221,4 @@ your virtual environment.:: .. _Django's documentation: https://docs.djangoproject.com/en/1.11/ref/django-admin/#runserver .. _pretixdroid: https://github.com/pretix/pretixdroid +.. _administrator documentation: https://docs.pretix.eu/self-hosting/ diff --git a/pyproject.toml b/pyproject.toml index fc0ad0d5b..9c689167d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,16 +33,16 @@ dependencies = [ "celery==5.5.*", "chardet==5.2.*", "cryptography>=44.0.0", - "css-inline==0.15.*", + "css-inline==0.17.*", "defusedcsv>=1.1.0", "Django[argon2]==4.2.*,>=4.2.15", - "django-bootstrap3==25.1", + "django-bootstrap3==25.2", "django-compressor==4.5.1", "django-countries==7.6.*", "django-filter==25.1", "django-formset-js-improved==0.5.0.3", "django-formtools==2.5.1", - "django-hierarkey==1.2.*", + "django-hierarkey==2.0.*,>=2.0.1", "django-hijack==3.7.*", "django-i18nfield==1.10.*", "django-libsass==0.9", @@ -74,24 +74,24 @@ dependencies = [ "paypal-checkout-serversdk==1.0.*", "PyJWT==2.10.*", "phonenumberslite==9.0.*", - "Pillow==11.2.*", + "Pillow==11.3.*", "pretix-plugin-build", - "protobuf==6.31.*", + "protobuf==6.32.*", "psycopg2-binary", "pycountry", "pycparser==2.22", "pycryptodome==3.23.*", - "pypdf==5.6.*", + "pypdf==6.0.*", "python-bidi==0.6.*", # Support for Arabic in reportlab "python-dateutil==2.9.*", "pytz", "pytz-deprecation-shim==0.1.*", "pyuca", "qrcode==8.2", - "redis==6.2.*", + "redis==6.4.*", "reportlab==4.4.*", "requests==2.31.*", - "sentry-sdk==2.31.*", + "sentry-sdk==2.35.*", "sepaxml==2.6.*", "stripe==7.9.*", "text-unidecode==1.*", @@ -110,7 +110,7 @@ dev = [ "aiohttp==3.12.*", "coverage", "coveralls", - "fakeredis==2.30.*", + "fakeredis==2.31.*", "flake8==7.3.*", "freezegun", "isort==6.0.*", @@ -122,7 +122,7 @@ dev = [ "pytest-django==4.*", "pytest-mock==3.14.*", "pytest-sugar", - "pytest-xdist==3.7.*", + "pytest-xdist==3.8.*", "pytest==8.4.*", "responses", ] diff --git a/src/pretix/__init__.py b/src/pretix/__init__.py index a81053032..400002680 100644 --- a/src/pretix/__init__.py +++ b/src/pretix/__init__.py @@ -19,4 +19,4 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -__version__ = "2025.6.0" +__version__ = "2025.7.1" diff --git a/src/pretix/_base_settings.py b/src/pretix/_base_settings.py index 8d4a90f93..97d79b036 100644 --- a/src/pretix/_base_settings.py +++ b/src/pretix/_base_settings.py @@ -115,6 +115,7 @@ ALL_LANGUAGES = [ ('sk', _('Slovak')), ('sv', _('Swedish')), ('es', _('Spanish')), + ('es-419', _('Spanish (Latin America)')), ('tr', _('Turkish')), ('uk', _('Ukrainian')), ] @@ -172,6 +173,12 @@ EXTRA_LANG_INFO = { 'name': 'Norwegian Bokmal', 'name_local': 'norsk (bokmål)', }, + 'es-419': { + 'bidi': False, + 'code': 'es-419', + 'name': 'Spanish (Latin America)', + 'name_local': 'Español', + }, } django.conf.locale.LANG_INFO.update(EXTRA_LANG_INFO) diff --git a/src/pretix/api/serializers/checkin.py b/src/pretix/api/serializers/checkin.py index 564665f3a..c28dfada9 100644 --- a/src/pretix/api/serializers/checkin.py +++ b/src/pretix/api/serializers/checkin.py @@ -104,3 +104,14 @@ class MiniCheckinListSerializer(I18nAwareModelSerializer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + + +class CheckinRPCAnnulInputSerializer(serializers.Serializer): + lists = serializers.PrimaryKeyRelatedField(required=True, many=True, queryset=CheckinList.objects.none()) + nonce = serializers.CharField(required=True, allow_null=False) + datetime = serializers.DateTimeField(required=False, allow_null=True) + error_explanation = serializers.CharField(required=False, allow_null=True) + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['lists'].child_relation.queryset = CheckinList.objects.filter(event__in=self.context['events']).select_related('event') diff --git a/src/pretix/api/serializers/event.py b/src/pretix/api/serializers/event.py index 616122179..e271ecc9c 100644 --- a/src/pretix/api/serializers/event.py +++ b/src/pretix/api/serializers/event.py @@ -50,6 +50,7 @@ from rest_framework.relations import SlugRelatedField from pretix.api.serializers import ( CompatibleJSONField, SalesChannelMigrationMixin, ) +from pretix.api.serializers.fields import PluginsField from pretix.api.serializers.i18n import I18nAwareModelSerializer from pretix.api.serializers.settings import SettingsSerializer from pretix.base.models import ( @@ -61,6 +62,9 @@ from pretix.base.models.items import ( ItemMetaProperty, SubEventItem, SubEventItemVariation, ) from pretix.base.models.tax import CustomRulesValidator +from pretix.base.plugins import ( + PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, +) from pretix.base.services.seating import ( SeatProtected, generate_seats, validate_plan_change, ) @@ -126,22 +130,6 @@ class SeatCategoryMappingField(Field): } -class PluginsField(Field): - - def to_representation(self, obj): - from pretix.base.plugins import get_all_plugins - - return sorted([ - p.module for p in get_all_plugins() - if not p.name.startswith('.') and getattr(p, 'visible', True) and p.module in obj.get_plugins() - ]) - - def to_internal_value(self, data): - return { - 'plugins': data - } - - class TimeZoneField(ChoiceField): def get_attribute(self, instance): return instance.cache.get_or_set( @@ -283,17 +271,28 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer): from pretix.base.plugins import get_all_plugins plugins_available = { - p.module: p for p in get_all_plugins(self.instance) + p.module: p for p in get_all_plugins(event=self.instance) if not p.name.startswith('.') and getattr(p, 'visible', True) } + current_plugins = self.instance.get_plugins() if self.instance and self.instance.pk else [] settings_holder = self.instance if self.instance and self.instance.pk else self.context['organizer'] + allowed_levels = (PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID) for plugin in value.get('plugins'): if plugin not in plugins_available: raise ValidationError(_('Unknown plugin: \'{name}\'.').format(name=plugin)) if getattr(plugins_available[plugin], 'restricted', False): if plugin not in settings_holder.settings.allowed_restricted_plugins: raise ValidationError(_('Restricted plugin: \'{name}\'.').format(name=plugin)) + level = getattr(plugins_available[plugin], 'level', PLUGIN_LEVEL_EVENT) + if level not in allowed_levels: + raise ValidationError('Plugin cannot be enabled on this level: \'{name}\'.'.format(name=plugin)) + + if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID and plugin not in self.context['organizer'].get_plugins(): + if plugin not in current_plugins: + # Technically, this is allowed, but consumers might be confused if the API call doesn't do anything + # so we prevent this change. + raise ValidationError('Plugin should be enabled on organizer level first: \'{name}\'.'.format(name=plugin)) return value @@ -685,8 +684,26 @@ class TaxRuleSerializer(CountryFieldMixin, I18nAwareModelSerializer): class Meta: model = TaxRule - fields = ('id', 'name', 'rate', 'code', 'price_includes_tax', 'eu_reverse_charge', 'home_country', - 'internal_name', 'keep_gross_if_rate_changes', 'custom_rules') + fields = ('id', 'name', 'default', 'rate', 'code', 'price_includes_tax', 'eu_reverse_charge', 'home_country', + 'internal_name', 'keep_gross_if_rate_changes', 'custom_rules', 'default') + + def create(self, validated_data): + if "default" not in validated_data and not self.context["event"].tax_rules.exists(): + validated_data["default"] = True + return super().create(validated_data) + + def save(self, **kwargs): + if self.validated_data.get("default"): + if self.instance and self.instance.pk: + self.context["event"].tax_rules.exclude(pk=self.instance.pk).update(default=False) + else: + self.context["event"].tax_rules.update(default=False) + return super().save(**kwargs) + + def validate_default(self, value): + if not value and self.instance.default: + raise ValidationError("You can't remove the default property, instead set it on another tax rule.") + return value class EventSettingsSerializer(SettingsSerializer): @@ -712,6 +729,8 @@ class EventSettingsSerializer(SettingsSerializer): 'allow_modifications_after_checkin', 'last_order_modification_date', 'show_quota_left', + 'tax_rule_payment', + 'tax_rule_cancellation', 'waiting_list_enabled', 'waiting_list_auto_disable', 'waiting_list_hours', @@ -942,6 +961,8 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer): 'reusable_media_type_nfc_mf0aes', 'reusable_media_type_nfc_mf0aes_random_uid', 'system_question_order', + 'tax_rule_payment', + 'tax_rule_cancellation', ] def __init__(self, *args, **kwargs): diff --git a/src/pretix/api/serializers/exporters.py b/src/pretix/api/serializers/exporters.py index 52827b99a..785e607a0 100644 --- a/src/pretix/api/serializers/exporters.py +++ b/src/pretix/api/serializers/exporters.py @@ -19,45 +19,16 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -from django import forms from django.conf import settings from django.http import QueryDict from pytz import common_timezones from rest_framework import serializers from rest_framework.exceptions import ValidationError +from pretix.api.serializers.forms import form_field_to_serializer_field from pretix.base.exporter import OrganizerLevelExportMixin from pretix.base.models import ScheduledEventExport, ScheduledOrganizerExport -from pretix.base.timeframes import DateFrameField, SerializerDateFrameField - - -class FormFieldWrapperField(serializers.Field): - def __init__(self, *args, **kwargs): - self.form_field = kwargs.pop('form_field') - super().__init__(*args, **kwargs) - - def to_representation(self, value): - return self.form_field.widget.format_value(value) - - def to_internal_value(self, data): - d = self.form_field.widget.value_from_datadict({'name': data}, {}, 'name') - d = self.form_field.clean(d) - return d - - -simple_mappings = ( - (forms.DateField, serializers.DateField, ()), - (forms.TimeField, serializers.TimeField, ()), - (forms.SplitDateTimeField, serializers.DateTimeField, ()), - (forms.DateTimeField, serializers.DateTimeField, ()), - (forms.DecimalField, serializers.DecimalField, ('max_digits', 'decimal_places', 'min_value', 'max_value')), - (forms.FloatField, serializers.FloatField, ()), - (forms.IntegerField, serializers.IntegerField, ()), - (forms.EmailField, serializers.EmailField, ()), - (forms.UUIDField, serializers.UUIDField, ()), - (forms.URLField, serializers.URLField, ()), - (forms.BooleanField, serializers.BooleanField, ()), -) +from pretix.base.timeframes import SerializerDateFrameField class SerializerDescriptionField(serializers.Field): @@ -81,13 +52,6 @@ class ExporterSerializer(serializers.Serializer): input_parameters = SerializerDescriptionField(source='_serializer') -class PrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField): - def to_representation(self, value): - if isinstance(value, int): - return value - return super().to_representation(value) - - class JobRunSerializer(serializers.Serializer): def __init__(self, *args, **kwargs): ex = kwargs.pop('exporter') @@ -102,59 +66,7 @@ class JobRunSerializer(serializers.Serializer): many=True ) for k, v in ex.export_form_fields.items(): - for m_from, m_to, m_kwargs in simple_mappings: - if isinstance(v, m_from): - self.fields[k] = m_to( - required=v.required, - allow_null=not v.required, - validators=v.validators, - **{kwarg: getattr(v, kwargs, None) for kwarg in m_kwargs} - ) - break - - if isinstance(v, forms.NullBooleanField): - self.fields[k] = serializers.BooleanField( - required=v.required, - allow_null=True, - validators=v.validators, - ) - if isinstance(v, forms.ModelMultipleChoiceField): - self.fields[k] = PrimaryKeyRelatedField( - queryset=v.queryset, - required=v.required, - allow_empty=not v.required, - validators=v.validators, - many=True - ) - elif isinstance(v, forms.ModelChoiceField): - self.fields[k] = PrimaryKeyRelatedField( - queryset=v.queryset, - required=v.required, - allow_null=not v.required, - validators=v.validators, - ) - elif isinstance(v, forms.MultipleChoiceField): - self.fields[k] = serializers.MultipleChoiceField( - choices=v.choices, - required=v.required, - allow_empty=not v.required, - validators=v.validators, - ) - elif isinstance(v, forms.ChoiceField): - self.fields[k] = serializers.ChoiceField( - choices=v.choices, - required=v.required, - allow_null=not v.required, - validators=v.validators, - ) - elif isinstance(v, DateFrameField): - self.fields[k] = SerializerDateFrameField( - required=v.required, - allow_null=not v.required, - validators=v.validators, - ) - else: - self.fields[k] = FormFieldWrapperField(form_field=v, required=v.required, allow_null=not v.required) + self.fields[k] = form_field_to_serializer_field(v) def to_internal_value(self, data): if isinstance(data, QueryDict): diff --git a/src/pretix/api/serializers/fields.py b/src/pretix/api/serializers/fields.py index ebb6272f2..db8858a22 100644 --- a/src/pretix/api/serializers/fields.py +++ b/src/pretix/api/serializers/fields.py @@ -109,3 +109,19 @@ class UploadedFileField(serializers.Field): return None request = self.context['request'] return request.build_absolute_uri(url) + + +class PluginsField(serializers.Field): + + def to_representation(self, obj): + from pretix.base.plugins import get_all_plugins + + return sorted([ + p.module for p in get_all_plugins() + if not p.name.startswith('.') and getattr(p, 'visible', True) and p.module in obj.get_plugins() + ]) + + def to_internal_value(self, data): + return { + 'plugins': data + } diff --git a/src/pretix/api/serializers/forms.py b/src/pretix/api/serializers/forms.py new file mode 100644 index 000000000..a7817471c --- /dev/null +++ b/src/pretix/api/serializers/forms.py @@ -0,0 +1,115 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from django import forms +from rest_framework import serializers + +from pretix.base.timeframes import DateFrameField, SerializerDateFrameField + +simple_mappings = ( + (forms.DateField, serializers.DateField, ()), + (forms.TimeField, serializers.TimeField, ()), + (forms.SplitDateTimeField, serializers.DateTimeField, ()), + (forms.DateTimeField, serializers.DateTimeField, ()), + (forms.DecimalField, serializers.DecimalField, ('max_digits', 'decimal_places', 'min_value', 'max_value')), + (forms.FloatField, serializers.FloatField, ()), + (forms.IntegerField, serializers.IntegerField, ()), + (forms.EmailField, serializers.EmailField, ()), + (forms.UUIDField, serializers.UUIDField, ()), + (forms.URLField, serializers.URLField, ()), + (forms.BooleanField, serializers.BooleanField, ()), +) + + +class PrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField): + def to_representation(self, value): + if isinstance(value, int): + return value + return super().to_representation(value) + + +class FormFieldWrapperField(serializers.Field): + def __init__(self, *args, **kwargs): + self.form_field = kwargs.pop('form_field') + super().__init__(*args, **kwargs) + + def to_representation(self, value): + return self.form_field.widget.format_value(value) + + def to_internal_value(self, data): + d = self.form_field.widget.value_from_datadict({'name': data}, {}, 'name') + d = self.form_field.clean(d) + return d + + +def form_field_to_serializer_field(field): + for m_from, m_to, m_kwargs in simple_mappings: + if isinstance(field, m_from): + return m_to( + required=field.required, + allow_null=not field.required, + validators=field.validators, + **{kwarg: getattr(field, kwarg, None) for kwarg in m_kwargs} + ) + + if isinstance(field, forms.NullBooleanField): + return serializers.BooleanField( + required=field.required, + allow_null=True, + validators=field.validators, + ) + if isinstance(field, forms.ModelMultipleChoiceField): + return PrimaryKeyRelatedField( + queryset=field.queryset, + required=field.required, + allow_empty=not field.required, + validators=field.validators, + many=True + ) + elif isinstance(field, forms.ModelChoiceField): + return PrimaryKeyRelatedField( + queryset=field.queryset, + required=field.required, + allow_null=not field.required, + validators=field.validators, + ) + elif isinstance(field, forms.MultipleChoiceField): + return serializers.MultipleChoiceField( + choices=field.choices, + required=field.required, + allow_empty=not field.required, + validators=field.validators, + ) + elif isinstance(field, forms.ChoiceField): + return serializers.ChoiceField( + choices=field.choices, + required=field.required, + allow_null=not field.required, + validators=field.validators, + ) + elif isinstance(field, DateFrameField): + return SerializerDateFrameField( + required=field.required, + allow_null=not field.required, + validators=field.validators, + ) + else: + return FormFieldWrapperField(form_field=field, required=field.required, allow_null=not field.required) diff --git a/src/pretix/api/serializers/item.py b/src/pretix/api/serializers/item.py index d565abb55..1c40eb13c 100644 --- a/src/pretix/api/serializers/item.py +++ b/src/pretix/api/serializers/item.py @@ -582,7 +582,7 @@ class QuotaSerializer(I18nAwareModelSerializer): class Meta: model = Quota fields = ('id', 'name', 'size', 'items', 'variations', 'subevent', 'closed', 'close_when_sold_out', - 'release_after_exit', 'available', 'available_number') + 'release_after_exit', 'available', 'available_number', 'ignore_for_event_availability') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index 6cdec4b96..68c7f7e9f 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -42,6 +42,7 @@ from rest_framework.reverse import reverse from pretix.api.serializers import CompatibleJSONField from pretix.api.serializers.event import SubEventSerializer +from pretix.api.serializers.forms import form_field_to_serializer_field from pretix.api.serializers.i18n import I18nAwareModelSerializer from pretix.api.serializers.item import ( InlineItemVariationSerializer, ItemSerializer, QuestionSerializer, @@ -49,6 +50,7 @@ from pretix.api.serializers.item import ( from pretix.api.signals import order_api_details, orderposition_api_details from pretix.base.decimal import round_decimal from pretix.base.i18n import language +from pretix.base.invoicing.transmission import get_transmission_types from pretix.base.models import ( CachedFile, Checkin, Customer, Invoice, InvoiceAddress, InvoiceLine, Item, ItemVariation, Order, OrderPosition, Question, QuestionAnswer, @@ -56,7 +58,7 @@ from pretix.base.models import ( ) from pretix.base.models.orders import ( BlockedTicketSecret, CartPosition, OrderFee, OrderPayment, OrderRefund, - PrintLog, RevokedTicketSecret, + PrintLog, RevokedTicketSecret, Transaction, ) from pretix.base.pdf import get_images, get_variables from pretix.base.services.cart import error_messages @@ -102,6 +104,13 @@ class CountryField(serializers.Field): return str(src) if src else None +class TransmissionInfoSerializer(serializers.Serializer): + def __init__(self, *args, transmission_type, **kwargs): + super().__init__(*args, **kwargs) + for k, v in transmission_type.invoice_address_form_fields.items(): + self.fields[k] = form_field_to_serializer_field(v) + + class InvoiceAddressSerializer(I18nAwareModelSerializer): country = CompatibleCountryField(source='*') name = serializers.CharField(required=False) @@ -109,7 +118,8 @@ class InvoiceAddressSerializer(I18nAwareModelSerializer): class Meta: model = InvoiceAddress fields = ('last_modified', 'is_business', 'company', 'name', 'name_parts', 'street', 'zipcode', 'city', 'country', - 'state', 'vat_id', 'vat_id_validated', 'custom_field', 'internal_reference') + 'state', 'vat_id', 'vat_id_validated', 'custom_field', 'internal_reference', 'transmission_type', + 'transmission_info') read_only_fields = ('last_modified',) def __init__(self, *args, **kwargs): @@ -147,6 +157,48 @@ class InvoiceAddressSerializer(I18nAwareModelSerializer): {'state': ['"{}" is not a known subdivision of the country "{}".'.format(data.get('state'), cc)]} ) + if data.get("transmission_type"): + for t in get_transmission_types(): + if data.get("transmission_type") == t.identifier: + if not t.is_available(self.context["request"].event, data.get("country"), data.get("is_business")): + raise ValidationError({ + "transmission_type": "The selected transmission type is not available for this country or address type." + }) + + ts = TransmissionInfoSerializer(transmission_type=t, data=data.get("transmission_info", {})) + try: + ts.is_valid(raise_exception=True) + except ValidationError as e: + raise ValidationError( + {"transmission_info": e.detail} + ) + data["transmission_info"] = ts.validated_data + + required_fields = t.invoice_address_form_fields_required(data.get("country"), data.get("is_business")) + for r in required_fields: + if r in self.fields: + if not data.get(r): + raise ValidationError( + {r: "This field is required for the selected type of invoice transmission."} + ) + else: + if not ts.validated_data.get(r): + raise ValidationError( + {"transmission_info": {r: "This field is required for the selected type of invoice transmission."}} + ) + break # do not call else branch of for loop + elif t.exclusive: + if t.is_available(self.context["request"].event, data.get("country"), data.get("is_business")): + raise ValidationError({ + "transmission_type": "The transmission type '%s' must be used for this country or address type." % ( + t.identifier, + ) + }) + else: + raise ValidationError( + {"transmission_type": "Unknown transmission type."} + ) + return data @@ -1725,12 +1777,13 @@ class InvoiceSerializer(I18nAwareModelSerializer): model = Invoice fields = ('event', 'order', 'number', 'is_cancellation', 'invoice_from', 'invoice_from_name', 'invoice_from_zipcode', 'invoice_from_city', 'invoice_from_country', 'invoice_from_tax_id', 'invoice_from_vat_id', - 'invoice_to', 'invoice_to_company', 'invoice_to_name', 'invoice_to_street', 'invoice_to_zipcode', - 'invoice_to_city', 'invoice_to_state', 'invoice_to_country', 'invoice_to_vat_id', 'invoice_to_beneficiary', - 'custom_field', 'date', 'refers', 'locale', + 'invoice_to', 'invoice_to_is_business', 'invoice_to_company', 'invoice_to_name', 'invoice_to_street', + 'invoice_to_zipcode', 'invoice_to_city', 'invoice_to_state', 'invoice_to_country', 'invoice_to_vat_id', + 'invoice_to_beneficiary', 'invoice_to_transmission_info', 'custom_field', 'date', 'refers', 'locale', 'introductory_text', 'additional_text', 'payment_provider_text', 'payment_provider_stamp', 'footer_text', 'lines', 'foreign_currency_display', 'foreign_currency_rate', - 'foreign_currency_rate_date', 'internal_reference') + 'foreign_currency_rate_date', 'internal_reference', 'transmission_type', 'transmission_provider', + 'transmission_status', 'transmission_date') class OrderPaymentCreateSerializer(I18nAwareModelSerializer): @@ -1783,3 +1836,23 @@ class BlockedTicketSecretSerializer(I18nAwareModelSerializer): class Meta: model = BlockedTicketSecret fields = ('id', 'secret', 'updated', 'blocked') + + +class TransactionSerializer(I18nAwareModelSerializer): + order = serializers.SlugRelatedField(slug_field="code", read_only=True) + + class Meta: + model = Transaction + fields = ( + "id", "order", "created", "datetime", "positionid", "count", "item", "variation", + "subevent", "price", "tax_rate", "tax_rule", "tax_code", "tax_value", "fee_type", + "internal_type" + ) + + +class OrganizerTransactionSerializer(TransactionSerializer): + event = serializers.SlugRelatedField(source="order.event", slug_field="slug", read_only=True) + + class Meta: + model = Transaction + fields = TransactionSerializer.Meta.fields + ("event",) diff --git a/src/pretix/api/serializers/orderchange.py b/src/pretix/api/serializers/orderchange.py index 8c3cb896a..e8fb7820d 100644 --- a/src/pretix/api/serializers/orderchange.py +++ b/src/pretix/api/serializers/orderchange.py @@ -83,6 +83,7 @@ class OrderPositionCreateForExistingOrderSerializer(OrderPositionCreateSerialize def create(self, validated_data): ocm = self.context['ocm'] + check_quotas = self.context.get('check_quotas', True) try: ocm.add_position( @@ -96,7 +97,7 @@ class OrderPositionCreateForExistingOrderSerializer(OrderPositionCreateSerialize valid_until=validated_data.get('valid_until'), ) if self.context.get('commit', True): - ocm.commit() + ocm.commit(check_quotas=check_quotas) return validated_data['order'].positions.order_by('-positionid').first() else: return OrderPosition() # fake to appease DRF @@ -310,6 +311,7 @@ class OrderPositionChangeSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): ocm = self.context['ocm'] + check_quotas = self.context.get('check_quotas', True) current_seat = {'seat_guid': instance.seat.seat_guid} if instance.seat else None item = validated_data.get('item', instance.item) variation = validated_data.get('variation', instance.variation) @@ -356,7 +358,7 @@ class OrderPositionChangeSerializer(serializers.ModelSerializer): ocm.change_ticket_secret(instance, secret) if self.context.get('commit', True): - ocm.commit() + ocm.commit(check_quotas=check_quotas) instance.refresh_from_db() except OrderError as e: raise ValidationError(str(e)) diff --git a/src/pretix/api/serializers/organizer.py b/src/pretix/api/serializers/organizer.py index acff75904..b2ead9594 100644 --- a/src/pretix/api/serializers/organizer.py +++ b/src/pretix/api/serializers/organizer.py @@ -24,6 +24,7 @@ from decimal import Decimal from django.conf import settings from django.core.exceptions import ObjectDoesNotExist +from django.db import transaction from django.db.models import Q from django.utils.crypto import get_random_string from django.utils.translation import gettext_lazy as _ @@ -32,6 +33,7 @@ from rest_framework.exceptions import ValidationError from pretix.api.auth.devicesecurity import get_all_security_profiles from pretix.api.serializers import AsymmetricField +from pretix.api.serializers.fields import PluginsField from pretix.api.serializers.i18n import I18nAwareModelSerializer from pretix.api.serializers.order import CompatibleJSONField from pretix.api.serializers.settings import SettingsSerializer @@ -43,6 +45,10 @@ from pretix.base.models import ( SalesChannel, SeatingPlan, Team, TeamAPIToken, TeamInvite, User, ) from pretix.base.models.seating import SeatingPlanLayoutValidator +from pretix.base.plugins import ( + PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, + PLUGIN_LEVEL_ORGANIZER, +) from pretix.base.services.mail import SendMailException, mail from pretix.base.settings import validate_organizer_settings from pretix.helpers.urls import build_absolute_uri as build_global_uri @@ -53,13 +59,47 @@ logger = logging.getLogger(__name__) class OrganizerSerializer(I18nAwareModelSerializer): public_url = serializers.SerializerMethodField('get_organizer_url', read_only=True) + plugins = PluginsField(required=False, source='*') + name = serializers.CharField(read_only=True) + slug = serializers.CharField(read_only=True) def get_organizer_url(self, organizer): return build_absolute_uri(organizer, 'presale:organizer.index') class Meta: model = Organizer - fields = ('name', 'slug', 'public_url') + fields = ('name', 'slug', 'public_url', 'plugins') + + def validate_plugins(self, value): + from pretix.base.plugins import get_all_plugins + + plugins_available = { + p.module: p for p in get_all_plugins(organizer=self.instance) + if not p.name.startswith('.') and getattr(p, 'visible', True) + } + settings_holder = self.instance + + allowed_levels = (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID) + for plugin in value.get('plugins'): + if plugin not in plugins_available: + raise ValidationError(_('Unknown plugin: \'{name}\'.').format(name=plugin)) + if getattr(plugins_available[plugin], 'restricted', False): + if plugin not in settings_holder.settings.allowed_restricted_plugins: + raise ValidationError(_('Restricted plugin: \'{name}\'.').format(name=plugin)) + if getattr(plugins_available[plugin], 'level', PLUGIN_LEVEL_EVENT) not in allowed_levels: + raise ValidationError('Plugin cannot be enabled on this level: \'{name}\'.'.format(name=plugin)) + + return value + + @transaction.atomic + def update(self, instance, validated_data): + plugins = validated_data.pop('plugins', None) + organizer = super().update(instance, validated_data) + # Plugins + if plugins is not None: + organizer.set_active_plugins(plugins) + organizer.save() + return organizer class SeatingPlanSerializer(I18nAwareModelSerializer): diff --git a/src/pretix/api/serializers/voucher.py b/src/pretix/api/serializers/voucher.py index 9c06db0ae..425df1eb8 100644 --- a/src/pretix/api/serializers/voucher.py +++ b/src/pretix/api/serializers/voucher.py @@ -19,6 +19,8 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # +from decimal import Decimal + from rest_framework import serializers from rest_framework.exceptions import ValidationError @@ -64,14 +66,15 @@ class SeatGuidField(serializers.CharField): class VoucherSerializer(I18nAwareModelSerializer): seat = SeatGuidField(allow_null=True, required=False) + budget_used = serializers.DecimalField(read_only=True, max_digits=13, decimal_places=2, min_value=Decimal('0.00')) class Meta: model = Voucher - fields = ('id', 'code', 'max_usages', 'redeemed', 'min_usages', 'valid_until', 'block_quota', + fields = ('id', 'created', 'code', 'max_usages', 'redeemed', 'min_usages', 'valid_until', 'block_quota', 'allow_ignore_quota', 'price_mode', 'value', 'item', 'variation', 'quota', 'tag', 'comment', 'subevent', 'show_hidden_items', 'seat', 'all_addons_included', - 'all_bundles_included') - read_only_fields = ('id', 'redeemed') + 'all_bundles_included', 'budget', 'budget_used') + read_only_fields = ('id', 'redeemed', 'budget_used') list_serializer_class = VoucherListSerializer def validate(self, data): diff --git a/src/pretix/api/signals.py b/src/pretix/api/signals.py index 22cdd82ee..1f69fad60 100644 --- a/src/pretix/api/signals.py +++ b/src/pretix/api/signals.py @@ -21,22 +21,22 @@ # from datetime import timedelta -from django.dispatch import Signal, receiver +from django.dispatch import receiver from django.utils.timezone import now from django_scopes import scopes_disabled from pretix.api.models import ApiCall, WebHookCall -from pretix.base.signals import EventPluginSignal, periodic_task +from pretix.base.signals import EventPluginSignal, GlobalSignal, periodic_task from pretix.helpers.periodic import minimum_interval -register_webhook_events = Signal() +register_webhook_events = GlobalSignal() """ This signal is sent out to get all known webhook events. Receivers should return an instance of a subclass of ``pretix.api.webhooks.WebhookEvent`` or a list of such instances. """ -register_device_security_profile = Signal() +register_device_security_profile = GlobalSignal() """ This signal is sent out to get all known device security_profiles. Receivers should return an instance of a subclass of ``pretix.api.auth.devicesecurity.BaseSecurityProfile`` diff --git a/src/pretix/api/urls.py b/src/pretix/api/urls.py index d853fa1dc..b1cb10edd 100644 --- a/src/pretix/api/urls.py +++ b/src/pretix/api/urls.py @@ -66,6 +66,7 @@ orga_router.register(r'orders', order.OrganizerOrderViewSet) orga_router.register(r'invoices', order.InvoiceViewSet) orga_router.register(r'scheduled_exports', exporters.ScheduledOrganizerExportViewSet) orga_router.register(r'exporters', exporters.OrganizerExportersViewSet, basename='exporters') +orga_router.register(r'transactions', order.OrganizerTransactionViewSet) team_router = routers.DefaultRouter() team_router.register(r'members', organizer.TeamMemberViewSet) @@ -83,6 +84,7 @@ event_router.register(r'quotas', item.QuotaViewSet) event_router.register(r'vouchers', voucher.VoucherViewSet) event_router.register(r'orders', order.EventOrderViewSet) event_router.register(r'orderpositions', order.OrderPositionViewSet) +event_router.register(r'transactions', order.TransactionViewSet) event_router.register(r'invoices', order.InvoiceViewSet) event_router.register(r'revokedsecrets', order.RevokedSecretViewSet, basename='revokedsecrets') event_router.register(r'blockedsecrets', order.BlockedSecretViewSet, basename='blockedsecrets') @@ -130,6 +132,8 @@ urlpatterns = [ name="checkinrpc.redeem"), re_path(r'^organizers/(?P[^/]+)/checkinrpc/search/$', checkin.CheckinRPCSearchView.as_view(), name="checkinrpc.search"), + re_path(r'^organizers/(?P[^/]+)/checkinrpc/annul/$', checkin.CheckinRPCAnnulView.as_view(), + name="checkinrpc.annul"), re_path(r'^organizers/(?P[^/]+)/settings/$', organizer.OrganizerSettingsView.as_view(), name="organizer.settings"), re_path(r'^organizers/(?P[^/]+)/giftcards/(?P[^/]+)/', include(giftcard_router.urls)), diff --git a/src/pretix/api/views/checkin.py b/src/pretix/api/views/checkin.py index 521687caa..ec31e3b50 100644 --- a/src/pretix/api/views/checkin.py +++ b/src/pretix/api/views/checkin.py @@ -20,12 +20,13 @@ # . # import operator +from datetime import timedelta from functools import reduce import django_filters from django.conf import settings from django.core.exceptions import ValidationError as BaseValidationError -from django.db import transaction +from django.db import connection, transaction from django.db.models import ( Count, Exists, F, Max, OrderBy, OuterRef, Prefetch, Q, Subquery, prefetch_related_objects, @@ -39,17 +40,19 @@ from django.utils.translation import gettext from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_scopes import scopes_disabled from packaging.version import parse -from rest_framework import views, viewsets +from rest_framework import status, views, viewsets from rest_framework.decorators import action -from rest_framework.exceptions import PermissionDenied, ValidationError +from rest_framework.exceptions import ( + NotFound, PermissionDenied, ValidationError, +) from rest_framework.fields import DateTimeField from rest_framework.generics import ListAPIView from rest_framework.permissions import SAFE_METHODS from rest_framework.response import Response from pretix.api.serializers.checkin import ( - CheckinListSerializer, CheckinRPCRedeemInputSerializer, - MiniCheckinListSerializer, + CheckinListSerializer, CheckinRPCAnnulInputSerializer, + CheckinRPCRedeemInputSerializer, MiniCheckinListSerializer, ) from pretix.api.serializers.item import QuestionSerializer from pretix.api.serializers.order import ( @@ -66,6 +69,8 @@ from pretix.base.models.orders import PrintLog from pretix.base.services.checkin import ( CheckInError, RequiredQuestionsError, SQLLogic, perform_checkin, ) +from pretix.base.signals import checkin_annulled +from pretix.helpers import OF_SELF with scopes_disabled(): class CheckinListFilter(FilterSet): @@ -813,7 +818,7 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet): ctx = super().get_serializer_context() ctx['event'] = self.request.event ctx['expand'] = self.request.query_params.getlist('expand') - ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false') == 'true' + ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false').lower() == 'true' return ctx def get_filterset_kwargs(self): @@ -832,9 +837,9 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet): def get_queryset(self, ignore_status=False, ignore_products=False): qs = _checkin_list_position_queryset( [self.checkinlist], - ignore_status=self.request.query_params.get('ignore_status', 'false') == 'true' or ignore_status, + ignore_status=self.request.query_params.get('ignore_status', 'false').lower() == 'true' or ignore_status, ignore_products=ignore_products, - pdf_data=self.request.query_params.get('pdf_data', 'false') == 'true', + pdf_data=self.request.query_params.get('pdf_data', 'false').lower() == 'true', expand=self.request.query_params.getlist('expand'), ) @@ -876,7 +881,7 @@ class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet): user=self.request.user, auth=self.request.auth, expand=self.request.query_params.getlist('expand'), - pdf_data=self.request.query_params.get('pdf_data', 'false') == 'true', + pdf_data=self.request.query_params.get('pdf_data', 'false').lower() == 'true', questions_supported=self.request.data.get('questions_supported', True), canceled_supported=self.request.data.get('canceled_supported', False), request=self.request, # this is not clean, but we need it in the serializers for URL generation @@ -911,7 +916,7 @@ class CheckinRPCRedeemView(views.APIView): user=self.request.user, auth=self.request.auth, expand=self.request.query_params.getlist('expand'), - pdf_data=self.request.query_params.get('pdf_data', 'false') == 'true', + pdf_data=self.request.query_params.get('pdf_data', 'false').lower() == 'true', questions_supported=s.validated_data['questions_supported'], use_order_locale=s.validated_data['use_order_locale'], canceled_supported=True, @@ -989,9 +994,9 @@ class CheckinRPCSearchView(ListAPIView): def get_queryset(self, ignore_status=False, ignore_products=False): qs = _checkin_list_position_queryset( self.lists, - ignore_status=self.request.query_params.get('ignore_status', 'false') == 'true' or ignore_status, + ignore_status=self.request.query_params.get('ignore_status', 'false').lower() == 'true' or ignore_status, ignore_products=ignore_products, - pdf_data=self.request.query_params.get('pdf_data', 'false') == 'true', + pdf_data=self.request.query_params.get('pdf_data', 'false').lower() == 'true', expand=self.request.query_params.getlist('expand'), ) @@ -999,3 +1004,79 @@ class CheckinRPCSearchView(ListAPIView): qs = qs.none() return qs + + +class CheckinRPCAnnulView(views.APIView): + def post(self, request, *args, **kwargs): + if isinstance(self.request.auth, (TeamAPIToken, Device)): + events = self.request.auth.get_events_with_permission(('can_change_orders', 'can_checkin_orders')) + elif self.request.user.is_authenticated: + events = self.request.user.get_events_with_permission(('can_change_orders', 'can_checkin_orders'), self.request).filter( + organizer=self.request.organizer + ) + else: + raise ValueError("unknown authentication method") + + s = CheckinRPCAnnulInputSerializer(data=request.data, context={'events': events}) + s.is_valid(raise_exception=True) + + with transaction.atomic(): + try: + qs = Checkin.all.all() + if isinstance(request.auth, Device): + qs = qs.filter(device=request.auth) + ci = qs.select_for_update( + of=OF_SELF, + ).select_related("position", "position__order", "position__order__event").get( + list__in=s.validated_data['lists'], + nonce=s.validated_data['nonce'], + ) + if connection.features.has_select_for_update_of and ci.position_id: + # Lock position as well, can't do it with of= above because relation is nullable + OrderPosition.objects.select_for_update(of=OF_SELF).get(pk=ci.position_id) + + if not ci.successful or not ci.position: + raise ValidationError("Cannot annul an unsuccessful checkin") + except Checkin.DoesNotExist: + raise NotFound("No check-in found based on nonce") + except Checkin.MultipleObjectsReturned: + raise ValidationError("Multiple check-ins found based on nonce") + + annulment_time = s.validated_data.get("datetime") or now() + + if annulment_time - ci.datetime > timedelta(minutes=15): + # Compare to sent datetime, which makes this cheatable, but allows offline annulment of checkins + ci.position.order.log_action('pretix.event.checkin.annulment.ignored', data={ + 'checkin': ci.pk, + 'position': ci.position.id, + 'positionid': ci.position.positionid, + 'datetime': annulment_time, + 'error_explanation': s.validated_data.get("error_explanation"), + 'type': ci.type, + 'list': ci.list_id, + }, user=request.user, auth=request.auth) + return Response({ + "non_field_errors": ["Annulment is not allowed more than 15 minutes after check-in"] + }, status=status.HTTP_400_BAD_REQUEST) + + if ci.device and ci.device != request.auth: + return Response({ + "non_field_errors": ["Annulment is only allowed from the same device"] + }, status=status.HTTP_400_BAD_REQUEST) + + ci.successful = False + ci.error_reason = Checkin.REASON_ANNULLED + ci.error_explanation = s.validated_data.get("error_explanation") + ci.save(update_fields=["successful", "error_reason", "error_explanation"]) + ci.position.order.log_action('pretix.event.checkin.annulled', data={ + 'checkin': ci.pk, + 'position': ci.position.id, + 'positionid': ci.position.positionid, + 'datetime': annulment_time, + 'error_explanation': s.validated_data.get("error_explanation"), + 'type': ci.type, + 'list': ci.list_id, + }, user=request.user, auth=request.auth) + checkin_annulled.send(ci.position.order.event, checkin=ci) + + return Response({"status": "ok"}, status=status.HTTP_200_OK) diff --git a/src/pretix/api/views/event.py b/src/pretix/api/views/event.py index 659d41e3c..19b2fb7d2 100644 --- a/src/pretix/api/views/event.py +++ b/src/pretix/api/views/event.py @@ -580,6 +580,11 @@ class TaxRuleViewSet(ConditionalListView, viewsets.ModelViewSet): ) super().perform_destroy(instance) + def get_serializer_context(self): + ctx = super().get_serializer_context() + ctx["event"] = self.request.event + return ctx + class ItemMetaPropertiesViewSet(viewsets.ModelViewSet): serializer_class = ItemMetaPropertiesSerializer diff --git a/src/pretix/api/views/order.py b/src/pretix/api/views/order.py index 2ed339a6e..faded5bec 100644 --- a/src/pretix/api/views/order.py +++ b/src/pretix/api/views/order.py @@ -57,9 +57,9 @@ from pretix.api.serializers.order import ( BlockedTicketSecretSerializer, InvoiceSerializer, OrderCreateSerializer, OrderPaymentCreateSerializer, OrderPaymentSerializer, OrderPositionSerializer, OrderRefundCreateSerializer, - OrderRefundSerializer, OrderSerializer, PriceCalcSerializer, - PrintLogSerializer, RevokedTicketSecretSerializer, - SimulatedOrderSerializer, + OrderRefundSerializer, OrderSerializer, OrganizerTransactionSerializer, + PriceCalcSerializer, PrintLogSerializer, RevokedTicketSecretSerializer, + SimulatedOrderSerializer, TransactionSerializer, ) from pretix.api.serializers.orderchange import ( BlockNameSerializer, OrderChangeOperationSerializer, @@ -80,6 +80,7 @@ from pretix.base.models import ( ) from pretix.base.models.orders import ( BlockedTicketSecret, PrintLog, QuestionAnswer, RevokedTicketSecret, + Transaction, ) from pretix.base.payment import PaymentException from pretix.base.pdf import get_images @@ -87,7 +88,7 @@ from pretix.base.secrets import assign_ticket_secret from pretix.base.services import tickets from pretix.base.services.invoices import ( generate_cancellation, generate_invoice, invoice_pdf, invoice_qualified, - regenerate_invoice, + regenerate_invoice, transmit_invoice, ) from pretix.base.services.mail import SendMailException from pretix.base.services.orders import ( @@ -227,7 +228,7 @@ class OrderViewSetMixin: def get_queryset(self): qs = self.get_base_queryset() if 'fees' not in self.request.GET.getlist('exclude'): - if self.request.query_params.get('include_canceled_fees', 'false') == 'true': + if self.request.query_params.get('include_canceled_fees', 'false').lower() == 'true': fqs = OrderFee.all else: fqs = OrderFee.objects @@ -245,11 +246,11 @@ class OrderViewSetMixin: return qs def _positions_prefetch(self, request): - if request.query_params.get('include_canceled_positions', 'false') == 'true': + if request.query_params.get('include_canceled_positions', 'false').lower() == 'true': opq = OrderPosition.all else: opq = OrderPosition.objects - if request.query_params.get('pdf_data', 'false') == 'true' and getattr(request, 'event', None): + if request.query_params.get('pdf_data', 'false').lower() == 'true' and getattr(request, 'event', None): prefetch_related_objects([request.organizer], 'meta_properties') prefetch_related_objects( [request.event], @@ -343,7 +344,7 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet): def get_serializer_context(self): ctx = super().get_serializer_context() ctx['event'] = self.request.event - ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false') == 'true' + ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false').lower() == 'true' return ctx def get_base_queryset(self): @@ -942,6 +943,7 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet): @action(detail=True, methods=['POST']) def change(self, request, **kwargs): order = self.get_object() + check_quotas = self.request.query_params.get('check_quotas', 'true').lower() == 'true' serializer = OrderChangeOperationSerializer( context={'order': order, **self.get_serializer_context()}, @@ -1007,7 +1009,7 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet): elif serializer.validated_data.get('recalculate_taxes') == 'keep_gross': ocm.recalculate_taxes(keep='gross') - ocm.commit() + ocm.commit(check_quotas=check_quotas) except OrderError as e: raise ValidationError(str(e)) @@ -1085,17 +1087,18 @@ class OrderPositionViewSet(viewsets.ModelViewSet): def get_serializer_context(self): ctx = super().get_serializer_context() ctx['event'] = self.request.event - ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false') == 'true' + ctx['pdf_data'] = self.request.query_params.get('pdf_data', 'false').lower() == 'true' + ctx['check_quotas'] = self.request.query_params.get('check_quotas', 'true').lower() == 'true' return ctx def get_queryset(self): - if self.request.query_params.get('include_canceled_positions', 'false') == 'true': + if self.request.query_params.get('include_canceled_positions', 'false').lower() == 'true': qs = OrderPosition.all else: qs = OrderPosition.objects qs = qs.filter(order__event=self.request.event) - if self.request.query_params.get('pdf_data', 'false') == 'true': + if self.request.query_params.get('pdf_data', 'false').lower() == 'true': prefetch_related_objects([self.request.organizer], 'meta_properties') prefetch_related_objects( [self.request.event], @@ -1888,6 +1891,12 @@ class RetryException(APIException): default_code = 'retry_later' +class CurrentlyInflightException(APIException): + status_code = 409 + default_detail = 'The requested action is already in progress.' + default_code = 'currently_inflight' + + class InvoiceViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = InvoiceSerializer queryset = Invoice.objects.none() @@ -1936,13 +1945,52 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet): resp['Content-Disposition'] = 'attachment; filename="{}.pdf"'.format(invoice.number) return resp + @action(detail=True, methods=['POST']) + def transmit(self, request, **kwargs): + invoice = self.get_object() + if invoice.shredded: + raise PermissionDenied('The invoice file is no longer stored on the server.') + + if invoice.transmission_status != Invoice.TRANSMISSION_STATUS_PENDING: + raise PermissionDenied('The invoice is not in pending state.') + + transmit_invoice.apply_async(args=(self.request.event.pk, invoice.pk, False)) + return Response(status=204) + + @action(detail=True, methods=['POST']) + def retransmit(self, request, **kwargs): + invoice = self.get_object() + if invoice.shredded: + raise PermissionDenied('The invoice file is no longer stored on the server.') + + with transaction.atomic(durable=True): + invoice = Invoice.objects.select_for_update(of=OF_SELF).get(pk=invoice.pk) + + if invoice.transmission_status == Invoice.TRANSMISSION_STATUS_INFLIGHT: + raise CurrentlyInflightException() + + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_PENDING + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + invoice.order.log_action( + 'pretix.event.order.invoice.retransmitted', + user=self.request.user, + auth=self.request.auth, + data={ + 'invoice': invoice.pk, + 'full_invoice_no': invoice.full_invoice_no, + } + ) + transmit_invoice.apply_async(args=(self.request.event.pk, invoice.pk, True)) + return Response(status=204) + @action(detail=True, methods=['POST']) def regenerate(self, request, **kwargs): inv = self.get_object() if inv.canceled: raise ValidationError('The invoice has already been canceled.') - if not inv.event.settings.invoice_regenerate_allowed: - raise PermissionDenied('Invoices may not be changed after they are created.') + if not inv.regenerate_allowed: + raise PermissionDenied('Invoice may not be regenerated.') elif inv.shredded: raise PermissionDenied('The invoice file is no longer stored on the server.') elif inv.sent_to_organizer: @@ -2030,3 +2078,61 @@ class BlockedSecretViewSet(viewsets.ReadOnlyModelViewSet): def get_queryset(self): return BlockedTicketSecret.objects.filter(event=self.request.event) + + +with scopes_disabled(): + class TransactionFilter(FilterSet): + order = django_filters.CharFilter(field_name='order', lookup_expr='code__iexact') + event = django_filters.CharFilter(field_name='order__event', lookup_expr='slug__iexact') + datetime_since = django_filters.IsoDateTimeFilter(field_name='datetime', lookup_expr='gte') + datetime_before = django_filters.IsoDateTimeFilter(field_name='datetime', lookup_expr='lt') + created_since = django_filters.IsoDateTimeFilter(field_name='created', lookup_expr='gte') + created_before = django_filters.IsoDateTimeFilter(field_name='created', lookup_expr='lt') + + class Meta: + model = Transaction + fields = { + 'item': ['exact', 'in'], + 'variation': ['exact', 'in'], + 'subevent': ['exact', 'in'], + 'tax_rule': ['exact', 'in'], + 'tax_code': ['exact', 'in'], + 'tax_rate': ['exact', 'in'], + 'fee_type': ['exact', 'in'], + } + + +class TransactionViewSet(viewsets.ReadOnlyModelViewSet): + serializer_class = TransactionSerializer + queryset = Transaction.objects.none() + filter_backends = (DjangoFilterBackend, TotalOrderingFilter) + ordering = ('datetime', 'pk') + ordering_fields = ('datetime', 'created', 'id',) + filterset_class = TransactionFilter + permission = 'can_view_orders' + + def get_queryset(self): + return Transaction.objects.filter(order__event=self.request.event).select_related("order") + + +class OrganizerTransactionViewSet(TransactionViewSet): + serializer_class = OrganizerTransactionSerializer + permission = None + + def get_queryset(self): + qs = Transaction.objects.filter( + order__event__organizer=self.request.organizer + ).select_related("order", "order__event") + + if isinstance(self.request.auth, (TeamAPIToken, Device)): + qs = qs.filter( + order__event__in=self.request.auth.get_events_with_permission("can_view_orders"), + ) + elif self.request.user.is_authenticated: + qs = qs.filter( + order__event__in=self.request.user.get_events_with_permission("can_view_orders", request=self.request) + ) + else: + raise PermissionDenied("Unknown authentication scheme") + + return qs diff --git a/src/pretix/api/views/organizer.py b/src/pretix/api/views/organizer.py index e8f948b69..3bfe0e57a 100644 --- a/src/pretix/api/views/organizer.py +++ b/src/pretix/api/views/organizer.py @@ -19,7 +19,9 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # +import operator from decimal import Decimal +from functools import reduce import django_filters from django.contrib.auth.hashers import make_password @@ -48,15 +50,18 @@ from pretix.api.serializers.organizer import ( TeamInviteSerializer, TeamMemberSerializer, TeamSerializer, ) from pretix.base.models import ( - Customer, Device, GiftCard, GiftCardTransaction, Membership, - MembershipType, Organizer, SalesChannel, SeatingPlan, Team, TeamAPIToken, - TeamInvite, User, + Customer, Device, Event, GiftCard, GiftCardTransaction, LogEntry, + Membership, MembershipType, Organizer, SalesChannel, SeatingPlan, Team, + TeamAPIToken, TeamInvite, User, +) +from pretix.base.plugins import ( + PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, ) from pretix.helpers import OF_SELF from pretix.helpers.dicts import merge_dicts -class OrganizerViewSet(viewsets.ReadOnlyModelViewSet): +class OrganizerViewSet(mixins.UpdateModelMixin, viewsets.ReadOnlyModelViewSet): serializer_class = OrganizerSerializer queryset = Organizer.objects.none() lookup_field = 'slug' @@ -65,6 +70,7 @@ class OrganizerViewSet(viewsets.ReadOnlyModelViewSet): filter_backends = (TotalOrderingFilter,) ordering = ('slug',) ordering_fields = ('name', 'slug') + write_permission = "can_change_organizer_settings" def get_queryset(self): if self.request.user.is_authenticated: @@ -83,6 +89,67 @@ class OrganizerViewSet(viewsets.ReadOnlyModelViewSet): else: return Organizer.objects.filter(pk=self.request.auth.team.organizer_id) + @transaction.atomic() + def perform_update(self, serializer): + from pretix.base.plugins import get_all_plugins + + original_data = self.get_serializer(instance=serializer.instance).data + + current_plugins_value = serializer.instance.get_plugins() + updated_plugins_value = serializer.validated_data.get('plugins', None) + + super().perform_update(serializer) + + if serializer.data == original_data: + # Performance optimization: If nothing was changed, we do not need to save or log anything. + # This costs us a few cycles on save, but avoids thousands of lines in our log. + return + + if updated_plugins_value is not None and set(updated_plugins_value) != set(current_plugins_value): + enabled = {m: 'enabled' for m in updated_plugins_value if m not in current_plugins_value} + disabled = {m: 'disabled' for m in current_plugins_value if m not in updated_plugins_value} + changed = merge_dicts(enabled, disabled) + + plugins_available = { + p.module: p + for p in get_all_plugins(organizer=serializer.instance) + if not p.name.startswith('.') and getattr(p, 'visible', True) + } + qs = [] + for module in disabled: + pluginmeta = plugins_available[module] + level = getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT) + if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID: + qs.append(Q(plugins__regex='(^|,)' + module + '(,|$)')) + + if qs: + events_to_disable = set(self.request.organizer.events.filter( + reduce(operator.or_, qs) + ).values_list("pk", flat=True)) + logentries_to_save = [] + events_to_save = [] + + for e in self.request.organizer.events.filter(pk__in=events_to_disable): + for module in disabled: + if module in e.get_plugins(): + logentries_to_save.append( + e.log_action('pretix.event.plugins.disabled', user=self.request.user, auth=self.request.auth, + data={'plugin': module}, save=False) + ) + e.disable_plugin(module) + events_to_save.append(e) + + Event.objects.bulk_update(events_to_save, fields=["plugins"]) + LogEntry.objects.bulk_create(logentries_to_save) + + for module, operation in changed.items(): + serializer.instance.log_action( + 'pretix.organizer.plugins.' + operation, + user=self.request.user, + auth=self.request.auth, + data={'plugin': module} + ) + class SeatingPlanViewSet(viewsets.ModelViewSet): serializer_class = SeatingPlanSerializer diff --git a/src/pretix/api/webhooks.py b/src/pretix/api/webhooks.py index 927f0f885..2dcf525e9 100644 --- a/src/pretix/api/webhooks.py +++ b/src/pretix/api/webhooks.py @@ -78,6 +78,13 @@ class WebhookEvent: """ raise NotImplementedError() # NOQA + @property + def help_text(self) -> str: + """ + A human-readable description + """ + return "" + def get_all_webhook_events(): global _ALL_EVENTS @@ -97,9 +104,10 @@ def get_all_webhook_events(): class ParametrizedWebhookEvent(WebhookEvent): - def __init__(self, action_type, verbose_name): + def __init__(self, action_type, verbose_name, help_text=""): self._action_type = action_type self._verbose_name = verbose_name + self._help_text = help_text super().__init__() @property @@ -110,6 +118,10 @@ class ParametrizedWebhookEvent(WebhookEvent): def verbose_name(self): return self._verbose_name + @property + def help_text(self): + return self._help_text + class ParametrizedOrderWebhookEvent(ParametrizedWebhookEvent): def build_payload(self, logentry: LogEntry): @@ -161,6 +173,19 @@ class ParametrizedEventWebhookEvent(ParametrizedWebhookEvent): } +class ParametrizedVoucherWebhookEvent(ParametrizedWebhookEvent): + + def build_payload(self, logentry: LogEntry): + # do not use content_object, this is also called in deletion + return { + 'notification_id': logentry.pk, + 'organizer': logentry.event.organizer.slug, + 'event': logentry.event.slug, + 'voucher': logentry.object_id, + 'action': logentry.action_type, + } + + class ParametrizedSubEventWebhookEvent(ParametrizedWebhookEvent): def build_payload(self, logentry: LogEntry): @@ -346,8 +371,9 @@ def register_default_webhook_events(sender, **kwargs): ), ParametrizedItemWebhookEvent( 'pretix.event.item.*', - _('Product changed (including product added or deleted and including changes to nested objects like ' - 'variations or bundles)'), + _('Product changed'), + _('This includes product added or deleted and changes to nested objects like ' + 'variations or bundles.'), ), ParametrizedEventWebhookEvent( 'pretix.event.live.activated', @@ -381,6 +407,19 @@ def register_default_webhook_events(sender, **kwargs): 'pretix.event.orders.waitinglist.voucher_assigned', _('Waiting list entry received voucher'), ), + ParametrizedVoucherWebhookEvent( + 'pretix.voucher.added', + _('Voucher added'), + ), + ParametrizedVoucherWebhookEvent( + 'pretix.voucher.changed', + _('Voucher changed'), + _('Only includes explicit changes to the voucher, not e.g. an increase of the number of redemptions.') + ), + ParametrizedVoucherWebhookEvent( + 'pretix.voucher.deleted', + _('Voucher deleted'), + ), ParametrizedCustomerWebhookEvent( 'pretix.customer.created', _('Customer account created'), diff --git a/src/pretix/base/apps.py b/src/pretix/base/apps.py index dd5d08f70..66baca9ab 100644 --- a/src/pretix/base/apps.py +++ b/src/pretix/base/apps.py @@ -43,10 +43,10 @@ class PretixBaseConfig(AppConfig): from . import exporter # NOQA from . import payment # NOQA from . import exporters # NOQA - from . import invoice # NOQA + from .invoicing import pdf, transmission, email, peppol, national # NOQA from . import notifications # NOQA from . import email # NOQA - from .services import auth, checkin, currencies, export, mail, tickets, cart, modelimport, orders, invoices, cleanup, update_check, quotas, notifications, vouchers # NOQA + from .services import auth, checkin, currencies, datasync, export, mail, tickets, cart, modelimport, orders, invoices, cleanup, update_check, quotas, notifications, vouchers # NOQA from .models import _transactions # NOQA from django.conf import settings diff --git a/src/pretix/base/customersso/oidc.py b/src/pretix/base/customersso/oidc.py index 71e64e1d6..3e20d0ffd 100644 --- a/src/pretix/base/customersso/oidc.py +++ b/src/pretix/base/customersso/oidc.py @@ -199,6 +199,7 @@ def oidc_validate_authorization(provider, code, redirect_uri, pkce_code_verifier params['client_id'] = provider.configuration['client_id'] params['client_secret'] = provider.configuration['client_secret'] + resp = None try: resp = requests.post( endpoint, @@ -214,7 +215,10 @@ def oidc_validate_authorization(provider, code, redirect_uri, pkce_code_verifier resp.raise_for_status() data = resp.json() except RequestException: - logger.exception('Could not retrieve authorization token') + if resp: + logger.exception(f'Could not retrieve authorization token. Response: {resp.text}') + else: + logger.exception('Could not retrieve authorization token') raise ValidationError( _('Login was not successful. Error message: "{error}".').format( error='could not reach login provider', @@ -222,6 +226,7 @@ def oidc_validate_authorization(provider, code, redirect_uri, pkce_code_verifier ) if 'access_token' not in data: + logger.error(f'Could not find access token. Response: {data}') raise ValidationError( _('Login was not successful. Error message: "{error}".').format( error='access token missing', @@ -229,6 +234,7 @@ def oidc_validate_authorization(provider, code, redirect_uri, pkce_code_verifier ) endpoint = provider.configuration['provider_config']['userinfo_endpoint'] + resp = None try: # https://openid.net/specs/openid-connect-core-1_0.html#UserInfo resp = requests.get( @@ -240,7 +246,10 @@ def oidc_validate_authorization(provider, code, redirect_uri, pkce_code_verifier resp.raise_for_status() userinfo = resp.json() except RequestException: - logger.exception('Could not retrieve user info') + if resp: + logger.exception(f'Could not retrieve user info. Response: {resp.text}') + else: + logger.exception('Could not retrieve user info') raise ValidationError( _('Login was not successful. Error message: "{error}".').format( error='could not fetch user info', diff --git a/src/pretix/base/datasync/__init__.py b/src/pretix/base/datasync/__init__.py new file mode 100644 index 000000000..9fd5bdc50 --- /dev/null +++ b/src/pretix/base/datasync/__init__.py @@ -0,0 +1,21 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# diff --git a/src/pretix/base/datasync/datasync.py b/src/pretix/base/datasync/datasync.py new file mode 100644 index 000000000..4bee7fbe1 --- /dev/null +++ b/src/pretix/base/datasync/datasync.py @@ -0,0 +1,436 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +import json +import logging +from collections import namedtuple +from datetime import timedelta +from functools import cached_property +from typing import List, Optional, Protocol + +import sentry_sdk +from django.db import DatabaseError, transaction +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ + +from pretix.base.datasync.sourcefields import ( + EVENT, EVENT_OR_SUBEVENT, ORDER, ORDER_POSITION, get_data_fields, +) +from pretix.base.i18n import language +from pretix.base.logentrytype_registry import make_link +from pretix.base.models.datasync import OrderSyncQueue, OrderSyncResult +from pretix.base.signals import PluginAwareRegistry +from pretix.helpers import OF_SELF + +logger = logging.getLogger(__name__) + + +datasync_providers = PluginAwareRegistry({"identifier": lambda o: o.identifier}) + + +class BaseSyncError(Exception): + def __init__(self, messages, full_message=None): + self.messages = messages + self.full_message = full_message + + +class UnrecoverableSyncError(BaseSyncError): + """ + A SyncProvider encountered a permanent problem, where a retry will not be successful. + """ + failure_mode = "permanent" + + +class SyncConfigError(UnrecoverableSyncError): + """ + A SyncProvider is misconfigured in a way where a retry without configuration change will + not be successful. + """ + failure_mode = "config" + + +class RecoverableSyncError(BaseSyncError): + """ + A SyncProvider has encountered a temporary problem, and the sync should be retried + at a later time. + """ + pass + + +class ObjectMapping(Protocol): + id: int + pretix_model: str + external_object_type: str + pretix_id_field: str + external_id_field: str + property_mappings: str + + +StaticMapping = namedtuple('StaticMapping', ('id', 'pretix_model', 'external_object_type', 'pretix_id_field', 'external_id_field', 'property_mappings')) + + +class OutboundSyncProvider: + max_attempts = 5 + + def __init__(self, event): + self.event = event + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + + @classmethod + @property + def display_name(cls): + return str(cls.identifier) + + @classmethod + def enqueue_order(cls, order, triggered_by, not_before=None): + """ + Adds an order to the sync queue. May only be called on derived classes which define an ``identifier`` attribute. + + Should be called in the appropriate signal receivers, e.g.:: + + @receiver(order_placed, dispatch_uid="mysync_order_placed") + def on_order_placed(sender, order, **kwargs): + MySyncProvider.enqueue_order(order, "order_placed") + + :param order: the Order that should be synced + :param triggered_by: the reason why the order should be synced, e.g. name of the signal + (currently only used internally for logging) + """ + if not hasattr(cls, 'identifier'): + raise TypeError('Call this method on a derived class that defines an "identifier" attribute.') + OrderSyncQueue.objects.update_or_create( + order=order, + sync_provider=cls.identifier, + in_flight=False, + defaults={ + "event": order.event, + "triggered_by": triggered_by, + "not_before": not_before or now(), + "need_manual_retry": None, + }, + ) + + @classmethod + def get_external_link_info(cls, event, external_link_href, external_link_display_name): + return { + "href": external_link_href, + "val": external_link_display_name, + } + + @classmethod + def get_external_link_html(cls, event, external_link_href, external_link_display_name): + info = cls.get_external_link_info(event, external_link_href, external_link_display_name) + return make_link(info, '{val}') + + def next_retry_date(self, sq): + """ + Optionally override to configure a different retry backoff behavior + """ + return now() + timedelta(hours=1) + + def should_sync_order(self, order): + """ + Optionally override this method to exclude certain orders from sync by returning ``False`` + """ + return True + + @property + def mappings(self): + """ + Implementations must override this property to provide the data mappings as a list of objects. + + They can return instances of the ``StaticMapping`` `namedtuple` defined above, or create their own + class (e.g. a Django model). + + :return: The returned objects must have at least the following properties: + + - `id`: Unique identifier for this mapping. If the mappings are Django models, the database primary key + should be used. This may be referenced in other mappings, to establish relations between objects. + - `pretix_model`: Which pretix model to use as data source in this mapping. Possible values are + the keys of ``sourcefields.AVAILABLE_MODELS`` + - `external_object_type`: Destination object type in the target system. opaque string of maximum 128 characters. + - `pretix_id_field`: Which pretix data field should be used to identify the mapped object. Any ``DataFieldInfo.key`` + returned by ``sourcefields.get_data_fields()`` for the combination of ``Event`` and ``pretix_model``. + - `external_id_field`: Destination identifier field in the target system. + - `property_mappings`: Mapping configuration as generated by ``PropertyMappingFormSet.to_property_mappings_list()``. + """ + raise NotImplementedError + + def sync_queued_orders(self, queued_orders): + """ + This method should catch all Exceptions and handle them appropriately. It should never throw + an Exception, as that may block the entire queue. + """ + for queue_item in queued_orders: + with transaction.atomic(): + try: + sq = ( + OrderSyncQueue.objects + .select_for_update(of=OF_SELF, nowait=True) + .select_related("order") + .get(pk=queue_item.pk) + ) + if sq.in_flight: + continue + sq.in_flight = True + sq.in_flight_since = now() + sq.save() + except DatabaseError: + # Either select_for_update failed to lock the row, or we couldn't set in_flight + # as this order is already in flight (UNIQUE violation). In either case, we ignore + # this order for now. + continue + + try: + mapped_objects = self.sync_order(sq.order) + if not all(all(not res or res.sync_info.get("action", "") == "nothing_to_do" for res in res_list) for res_list in mapped_objects.values()): + sq.order.log_action("pretix.event.order.data_sync.success", { + "provider": self.identifier, + "objects": { + mapping_id: [osr and osr.to_result_dict() for osr in results] + for mapping_id, results in mapped_objects.items() + }, + }) + sq.delete() + except UnrecoverableSyncError as e: + sq.set_sync_error(e.failure_mode, e.messages, e.full_message) + except RecoverableSyncError as e: + sq.failed_attempts += 1 + sq.not_before = self.next_retry_date(sq) + # model changes saved by set_sync_error / clear_in_flight calls below + if sq.failed_attempts >= self.max_attempts: + logger.exception('Failed to sync order (max attempts exceeded)') + sentry_sdk.capture_exception(e) + sq.set_sync_error("exceeded", e.messages, e.full_message) + else: + logger.info( + f"Could not sync order {sq.order.code} to {type(self).__name__} " + f"(transient error, attempt #{sq.failed_attempts}, next {sq.not_before})", + exc_info=True, + ) + sq.clear_in_flight() + except Exception as e: + logger.exception('Failed to sync order (unhandled exception)') + sentry_sdk.capture_exception(e) + sq.set_sync_error("internal", [], str(e)) + + @cached_property + def data_fields(self): + return { + f.key: f + for f in get_data_fields(self.event) + } + + def get_field_value(self, inputs, mapping_entry): + key = mapping_entry["pretix_field"] + try: + field = self.data_fields[key] + except KeyError: + with language(self.event.settings.locale): + raise SyncConfigError([_( + 'Field "{field_name}" is not valid for {available_inputs}. Please check your {provider_name} settings.' + ).format(key=key, available_inputs="/".join(inputs.keys()), provider_name=self.display_name)]) + input = inputs[field.required_input] + val = field.getter(input) + if isinstance(val, list): + if field.enum_opts and mapping_entry.get("value_map"): + map = json.loads(mapping_entry["value_map"]) + try: + val = [map[el] for el in val] + except KeyError: + with language(self.event.settings.locale): + raise SyncConfigError([_( + 'Please update value mapping for field "{field_name}" - option "{val}" not assigned' + ).format(field_name=key, val=val)]) + + val = ",".join(val) + return val + + def get_properties(self, inputs: dict, property_mappings: List[dict]): + return [ + (m["external_field"], self.get_field_value(inputs, m), m["overwrite"]) + for m in property_mappings + ] + + def sync_object_with_properties( + self, + external_id_field: str, + id_value, + properties: list, + inputs: dict, + mapping: ObjectMapping, + mapped_objects: dict, + **kwargs, + ) -> Optional[dict]: + """ + This method is called for each object that needs to be created/updated in the external system -- which these are is + determined by the implementation of the `mapping` property. + + :param external_id_field: Identifier field in the external system as provided in ``mapping.external_identifier`` + :param id_value: Identifier contents as retrieved from the property specified by ``mapping.pretix_identifier`` of the model + specified by ``mapping.pretix_model`` + :param properties: All properties defined in ``mapping.property_mappings``, as list of three-tuples + ``(external_field, value, overwrite)`` + :param inputs: All pretix model instances from which data can be retrieved for this mapping. + Dictionary mapping from sourcefields.ORDER_POSITION, .ORDER, .EVENT, .EVENT_OR_SUBEVENT to the + relevant Django model. + Most providers don't need to use this parameter directly, as `properties` and `id_value` + already contain the values as evaluated from the available inputs. + :param mapping: The mapping object as returned by ``self.mappings`` + :param mapped_objects: Information about objects that were synced in the same sync run, by mapping definitions + *before* the current one in order of ``self.mappings``. + Type is a dictionary ``{mapping.id: [list of OrderSyncResult objects]}`` + Useful to create associations between objects in the target system. + + Example code to create return value:: + + return { + # optional: + "action": "nothing_to_do", # to inform that no action was taken, because the data was already up-to-date. + # other values for action (e.g. create, update) currently have no special + # meaning, but are visible for debugging purposes to admins. + + # optional: + "external_link_href": "https://external-system.example.com/backend/link/to/contact/123/", + "external_link_display_name": "Contact #123 - Jane Doe", + "...optionally further values you need in mapped_objects for association": 123456789, + } + + The return value needs to be a JSON serializable dict, or None. + + Return None only in case you decide this object should not be synced at all in this mapping. Do not return None in + case the object is already up-to-date in the target system (return "action": "nothing_to_do" instead). + + This method needs to be idempotent, i.e. calling it multiple times with the same input values should create + only a single object in the target system. + + Subsequent calls with the same mapping and id_value should update the existing object, instead of creating a new one. + In a SQL database, you might use an `INSERT OR UPDATE` or `UPSERT` statement; many REST APIs provide an equivalent API call. + """ + raise NotImplementedError() + + def sync_object( + self, + inputs: dict, + mapping, + mapped_objects: dict, + ): + logger.debug("Syncing object %r, %r, %r", inputs, mapping, mapped_objects) + properties = self.get_properties(inputs, mapping.property_mappings) + logger.debug("Properties: %r", properties) + + id_value = self.get_field_value(inputs, {"pretix_field": mapping.pretix_id_field}) + if not id_value: + return None + + info = self.sync_object_with_properties( + external_id_field=mapping.external_id_field, + id_value=id_value, + properties=properties, + inputs=inputs, + mapping=mapping, + mapped_objects=mapped_objects, + ) + if not info: + return None + external_link_href = info.pop('external_link_href', None) + external_link_display_name = info.pop('external_link_display_name', None) + obj, created = OrderSyncResult.objects.update_or_create( + order=inputs.get(ORDER), order_position=inputs.get(ORDER_POSITION), sync_provider=self.identifier, + mapping_id=mapping.id, + defaults=dict( + external_object_type=mapping.external_object_type, + external_id_field=mapping.external_id_field, + id_value=id_value, + external_link_href=external_link_href, + external_link_display_name=external_link_display_name, + sync_info=info, + transmitted=now(), + ) + ) + return obj + + def sync_order(self, order): + if not self.should_sync_order(order): + logger.debug("Skipping order %r", order) + return + + logger.debug("Syncing order %r", order) + positions = list( + order.all_positions + .prefetch_related("answers", "answers__question") + .select_related( + "voucher", + ) + ) + order_inputs = {ORDER: order, EVENT: self.event} + mapped_objects = {} + for mapping in self.mappings: + if mapping.pretix_model == 'Order': + mapped_objects[mapping.id] = [ + self.sync_object(order_inputs, mapping, mapped_objects) + ] + elif mapping.pretix_model == 'OrderPosition': + mapped_objects[mapping.id] = [ + self.sync_object({ + **order_inputs, EVENT_OR_SUBEVENT: op.subevent or self.event, ORDER_POSITION: op + }, mapping, mapped_objects) + for op in positions + ] + else: + raise SyncConfigError("Invalid pretix model '{}'".format(mapping.pretix_model)) + self.finalize_sync_order(order) + return mapped_objects + + def filter_mapped_objects(self, mapped_objects, inputs): + """ + For order positions, only + """ + if ORDER_POSITION in inputs: + return { + mapping_id: [ + osr for osr in results + if osr and (osr.order_position_id is None or osr.order_position_id == inputs[ORDER_POSITION].id) + ] + for mapping_id, results in mapped_objects.items() + } + else: + return mapped_objects + + def finalize_sync_order(self, order): + """ + Called after ``sync_object`` has been called successfully for all objects of a specific order. Can + be used for saving bulk information per order. + """ + pass + + def close(self): + """ + Called after all orders of an event have been synced. Can be used for clean-up tasks (e.g. closing + a session). + """ + pass diff --git a/src/pretix/base/datasync/sourcefields.py b/src/pretix/base/datasync/sourcefields.py new file mode 100644 index 000000000..816f9d5cb --- /dev/null +++ b/src/pretix/base/datasync/sourcefields.py @@ -0,0 +1,659 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +from collections import namedtuple +from functools import partial + +from django.db.models import Max, Q +from django.utils.translation import gettext_lazy as _, pgettext_lazy + +from pretix.base.models import Checkin, InvoiceAddress, Order, Question +from pretix.base.settings import PERSON_NAME_SCHEMES +from pretix.multidomain.urlreverse import build_absolute_uri + + +def get_answer(op, question_identifier=None): + a = None + if op.addon_to: + if "answers" in getattr(op.addon_to, "_prefetched_objects_cache", {}): + try: + a = [ + a + for a in op.addon_to.answers.all() + if a.question.identifier == question_identifier + ][0] + except IndexError: + pass + else: + a = op.addon_to.answers.filter( + question__identifier=question_identifier + ).first() + + if "answers" in getattr(op, "_prefetched_objects_cache", {}): + try: + a = [ + a + for a in op.answers.all() + if a.question.identifier == question_identifier + ][0] + except IndexError: + pass + else: + a = op.answers.filter(question__identifier=question_identifier).first() + + if not a: + return "" + else: + if a.question.type in (Question.TYPE_CHOICE, Question.TYPE_CHOICE_MULTIPLE): + return [str(o.identifier) for o in a.options.all()] + if a.question.type == Question.TYPE_BOOLEAN: + return a.answer == "True" + return a.answer + + +def get_payment_date(order): + if order.status == Order.STATUS_PENDING: + return None + + return isoformat_or_none(order.payments.aggregate(m=Max("payment_date"))["m"]) + + +def isoformat_or_none(dt): + return dt and dt.isoformat() + + +def first_checkin_on_list(list_pk, position): + checkin = position.checkins.filter( + list__pk=list_pk, type=Checkin.TYPE_ENTRY + ).first() + if checkin: + return isoformat_or_none(checkin.datetime) + + +def split_name_on_last_space(name, part): + name_parts = name.rsplit(" ", 1) + return name_parts[part] if len(name_parts) > part else "" + + +def normalize_email(email): + if email: + local, host = email.split("@") + host = host.encode("idna").decode() + return f"{local}@{host}" + else: + return None + + +def get_email_domain(email): + if email: + local, host = email.split("@") + return host + else: + return None + + +ORDER_POSITION = 'position' +ORDER = 'order' +EVENT = 'event' +EVENT_OR_SUBEVENT = 'event_or_subevent' +AVAILABLE_MODELS = { + 'OrderPosition': (ORDER_POSITION, ORDER, EVENT_OR_SUBEVENT, EVENT), + 'Order': (ORDER, EVENT), +} + +DataFieldCategory = namedtuple( + 'DataFieldCategory', + field_names=('sort_index', 'label',), +) + +CAT_ORDER_POSITION = DataFieldCategory(10, _('Order position details')) +CAT_ATTENDEE = DataFieldCategory(11, _('Attendee details')) +CAT_QUESTIONS = DataFieldCategory(12, _('Questions')) +CAT_PRODUCT = DataFieldCategory(20, _('Product details')) +CAT_ORDER = DataFieldCategory(21, _('Order details')) +CAT_INVOICE_ADDRESS = DataFieldCategory(22, _('Invoice address')) +CAT_EVENT = DataFieldCategory(30, _('Event information')) +CAT_EVENT_OR_SUBEVENT = DataFieldCategory(31, pgettext_lazy('subevent', 'Event or date information')) + +DataFieldInfo = namedtuple( + 'DataFieldInfo', + field_names=('required_input', 'category', 'key', 'label', 'type', 'enum_opts', 'getter', 'deprecated'), + defaults=[False] +) + + +def get_invoice_address_or_empty(order): + try: + return order.invoice_address + except InvoiceAddress.DoesNotExist: + return InvoiceAddress() + + +def get_data_fields(event, for_model=None): + """ + Returns tuple of (required_input, key, label, type, enum_opts, getter) + + Type is one of the Question types as defined in Question.TYPE_CHOICES. + + The data type of the return value of `getter` depends on `type`: + - TYPE_CHOICE_MULTIPLE: list of strings + - TYPE_CHOICE: list, containing zero or one strings + - TYPE_BOOLEAN: boolean + - all other (including TYPE_NUMBER): string + """ + name_scheme = PERSON_NAME_SCHEMES[event.settings.name_scheme] + name_headers = [] + if name_scheme and len(name_scheme["fields"]) > 1: + for k, label, w in name_scheme["fields"]: + name_headers.append(label) + + src_fields = ( + [ + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_name", + _("Attendee name"), + Question.TYPE_STRING, + None, + lambda position: position.attendee_name + or (position.addon_to.attendee_name if position.addon_to else None), + ), + ] + + [ + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_name_" + k, + _("Attendee") + ": " + label, + Question.TYPE_STRING, + None, + partial( + lambda k, position: ( + position.attendee_name_parts + or (position.addon_to.attendee_name_parts if position.addon_to else {}) + or {} + ).get(k, ""), + k, + ), + deprecated=len(name_scheme["fields"]) == 1, + ) + for k, label, w in name_scheme["fields"] + ] + + [ + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_email", + _("Attendee email"), + Question.TYPE_STRING, + None, + lambda position: normalize_email( + position.attendee_email + or (position.addon_to.attendee_email if position.addon_to else None) + ), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_or_order_email", + _("Attendee or order email"), + Question.TYPE_STRING, + None, + lambda position: normalize_email( + position.attendee_email + or (position.addon_to.attendee_email if position.addon_to else None) + or position.order.email + ), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_company", + _("Attendee company"), + Question.TYPE_STRING, + None, + lambda position: position.company or (position.addon_to.company if position.addon_to else None), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_street", + _("Attendee address street"), + Question.TYPE_STRING, + None, + lambda position: position.street or (position.addon_to.street if position.addon_to else None), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_zipcode", + _("Attendee address ZIP code"), + Question.TYPE_STRING, + None, + lambda position: position.zipcode or (position.addon_to.zipcode if position.addon_to else None), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_city", + _("Attendee address city"), + Question.TYPE_STRING, + None, + lambda position: position.city or (position.addon_to.city if position.addon_to else None), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_country", + _("Attendee address country"), + Question.TYPE_COUNTRYCODE, + None, + lambda position: str( + position.country or (position.addon_to.attendee_name if position.addon_to else "") + ), + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_company", + _("Invoice address company"), + Question.TYPE_STRING, + None, + lambda order: get_invoice_address_or_empty(order).company, + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_name", + _("Invoice address name"), + Question.TYPE_STRING, + None, + lambda order: get_invoice_address_or_empty(order).name, + ), + ] + + [ + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_name_" + k, + _("Invoice address") + ": " + label, + Question.TYPE_STRING, + None, + partial( + lambda k, order: (get_invoice_address_or_empty(order).name_parts or {}).get( + k, "" + ), + k, + ), + deprecated=len(name_scheme["fields"]) == 1, + ) + for k, label, w in name_scheme["fields"] + ] + + [ + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_street", + _("Invoice address street"), + Question.TYPE_STRING, + None, + lambda order: get_invoice_address_or_empty(order).street, + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_zipcode", + _("Invoice address ZIP code"), + Question.TYPE_STRING, + None, + lambda order: get_invoice_address_or_empty(order).zipcode, + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_city", + _("Invoice address city"), + Question.TYPE_STRING, + None, + lambda order: get_invoice_address_or_empty(order).city, + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_country", + _("Invoice address country"), + Question.TYPE_COUNTRYCODE, + None, + lambda order: str(get_invoice_address_or_empty(order).country), + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "email", + _("Order email"), + Question.TYPE_STRING, + None, + lambda order: normalize_email(order.email), + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "email_domain", + _("Order email domain"), + Question.TYPE_STRING, + None, + lambda order: get_email_domain(normalize_email(order.email)), + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "order_code", + _("Order code"), + Question.TYPE_STRING, + None, + lambda order: order.code, + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "event_order_code", + _("Event and order code"), + Question.TYPE_STRING, + None, + lambda order: order.full_code, + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "order_total", + _("Order total"), + Question.TYPE_NUMBER, + None, + lambda order: str(order.total), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_PRODUCT, + "product", + _("Product and variation name"), + Question.TYPE_STRING, + None, + lambda position: str( + str(position.item.internal_name or position.item.name) + + ((" – " + str(position.variation.value)) if position.variation else "") + ), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_PRODUCT, + "product_id", + _("Product ID"), + Question.TYPE_NUMBER, + None, + lambda position: str(position.item.pk), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_PRODUCT, + "product_is_admission", + _("Product is admission product"), + Question.TYPE_BOOLEAN, + None, + lambda position: bool(position.item.admission), + ), + DataFieldInfo( + EVENT, + CAT_EVENT, + "event_slug", + _("Event short form"), + Question.TYPE_STRING, + None, + lambda event: str(event.slug), + ), + DataFieldInfo( + EVENT, + CAT_EVENT, + "event_name", + _("Event name"), + Question.TYPE_STRING, + None, + lambda event: str(event.name), + ), + DataFieldInfo( + EVENT_OR_SUBEVENT, + CAT_EVENT_OR_SUBEVENT, + "event_date_from", + _("Event start date"), + Question.TYPE_DATETIME, + None, + lambda event_or_subevent: isoformat_or_none(event_or_subevent.date_from), + ), + DataFieldInfo( + EVENT_OR_SUBEVENT, + CAT_EVENT_OR_SUBEVENT, + "event_date_to", + _("Event end date"), + Question.TYPE_DATETIME, + None, + lambda event_or_subevent: isoformat_or_none(event_or_subevent.date_to), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "voucher_code", + _("Voucher code"), + Question.TYPE_STRING, + None, + lambda position: position.voucher.code if position.voucher_id else "", + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "ticket_id", + _("Order code and position number"), + Question.TYPE_STRING, + None, + lambda position: position.code, + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "ticket_price", + _("Ticket price"), + Question.TYPE_NUMBER, + None, + lambda position: str(position.price), + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "order_status", + _("Order status"), + Question.TYPE_CHOICE, + Order.STATUS_CHOICE, + lambda order: [order.status], + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "ticket_status", + _("Ticket status"), + Question.TYPE_CHOICE, + Order.STATUS_CHOICE, + lambda position: [Order.STATUS_CANCELED if position.canceled else position.order.status], + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "order_date", + _("Order date and time"), + Question.TYPE_DATETIME, + None, + lambda order: order.datetime.isoformat(), + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "payment_date", + _("Payment date and time"), + Question.TYPE_DATETIME, + None, + get_payment_date, + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "order_locale", + _("Order locale"), + Question.TYPE_CHOICE, + [(lc, lc) for lc in event.settings.locales], + lambda order: [order.locale], + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "position_id", + _("Order position ID"), + Question.TYPE_NUMBER, + None, + lambda op: str(op.pk), + ), + DataFieldInfo( + ORDER, + CAT_ORDER, + "presale_order_url", + _("Order link"), + Question.TYPE_STRING, + None, + lambda order: build_absolute_uri( + event, + 'presale:event.order', kwargs={ + 'order': order.code, + 'secret': order.secret, + } + ), + ), + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "presale_ticket_url", + _("Ticket link"), + Question.TYPE_STRING, + None, + lambda op: build_absolute_uri( + event, + 'presale:event.order.position', kwargs={ + 'order': op.order.code, + 'secret': op.web_secret, + 'position': op.positionid + } + ), + ), + ] + + [ + DataFieldInfo( + ORDER_POSITION, + CAT_ORDER_POSITION, + "checkin_date_" + str(cl.pk), + _("Check-in datetime on list {}").format(cl.name), + Question.TYPE_DATETIME, + None, + partial(first_checkin_on_list, cl.pk), + ) + for cl in event.checkin_lists.all() + ] + + [ + DataFieldInfo( + ORDER_POSITION, + CAT_QUESTIONS, + "question_" + q.identifier, + _("Question: {name}").format(name=str(q.question)), + q.type, + get_enum_opts(q), + partial(lambda qq, position: get_answer(position, qq.identifier), q), + ) + for q in event.questions.filter(~Q(type=Question.TYPE_FILE)).prefetch_related("options") + ] + ) + if not any(field_name == "given_name" for field_name, label, weight in name_scheme["fields"]): + src_fields += [ + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_name_given_name", + _("Attendee") + ": " + _("Given name") + " (⚠️ auto-generated, not recommended)", + Question.TYPE_STRING, + None, + lambda position: split_name_on_last_space(position.attendee_name, part=0), + deprecated=True, + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_name_given_name", + _("Invoice address") + ": " + _("Given name") + " (⚠️ auto-generated, not recommended)", + Question.TYPE_STRING, + None, + lambda order: split_name_on_last_space(get_invoice_address_or_empty(order).name, part=0), + deprecated=True, + ), + ] + + if not any(field_name == "family_name" for field_name, label, weight in name_scheme["fields"]): + src_fields += [ + DataFieldInfo( + ORDER_POSITION, + CAT_ATTENDEE, + "attendee_name_family_name", + _("Attendee") + ": " + _("Family name") + " (⚠️ auto-generated, not recommended)", + Question.TYPE_STRING, + None, + lambda position: split_name_on_last_space(position.attendee_name, part=1), + deprecated=True, + ), + DataFieldInfo( + ORDER, + CAT_INVOICE_ADDRESS, + "invoice_address_name_family_name", + _("Invoice address") + ": " + _("Family name") + " (⚠️ auto-generated, not recommended)", + Question.TYPE_STRING, + None, + lambda order: split_name_on_last_space(get_invoice_address_or_empty(order).name, part=1), + deprecated=True, + ), + ] + + if for_model: + available_inputs = AVAILABLE_MODELS[for_model] + return [ + f for f in src_fields if f.required_input in available_inputs + ] + else: + return src_fields + + +def get_enum_opts(q): + if q.type in (Question.TYPE_CHOICE, Question.TYPE_CHOICE_MULTIPLE): + return [(opt.identifier, opt.answer) for opt in q.options.all()] + else: + return None diff --git a/src/pretix/base/datasync/utils.py b/src/pretix/base/datasync/utils.py new file mode 100644 index 000000000..05aab054a --- /dev/null +++ b/src/pretix/base/datasync/utils.py @@ -0,0 +1,123 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from typing import List, Tuple + +from pretix.base.datasync.datasync import SyncConfigError +from pretix.base.models.datasync import ( + MODE_APPEND_LIST, MODE_OVERWRITE, MODE_SET_IF_EMPTY, MODE_SET_IF_NEW, +) + + +def assign_properties( + new_values: List[Tuple[str, str, str]], old_values: dict, is_new, list_sep +): + """ + Generates a dictionary mapping property keys to new values, handling conditional overwrites and list updates + according to an update mode specified per property. + + Supported update modes are: + - `MODE_OVERWRITE`: Replaces the existing value with the new value. + - `MODE_SET_IF_NEW`: Only sets the property if `is_new` is True. + - `MODE_SET_IF_EMPTY`: Only sets the property if the field is empty or missing in old_values. + - `MODE_APPEND_LIST`: Appends the new value to the list from old_values (or the empty list if missing), + using `list_sep` as a separator. + + :param new_values: List of tuples, where each tuple contains (field_name, new_value, update_mode). + :param old_values: Dictionary, current property values in the external system. + :param is_new: Boolean, whether the object will be newly created in the external system. + :param list_sep: If string, used as a separator for MODE_APPEND_LIST. If None, native lists are used. + :raises SyncConfigError: If an invalid update mode is specified. + :returns: A dictionary containing the properties that need to be updated in the external system. + """ + + out = {} + + for field_name, new_value, update_mode in new_values: + if update_mode == MODE_OVERWRITE: + out[field_name] = new_value + continue + elif update_mode == MODE_SET_IF_NEW and not is_new: + continue + if not new_value: + continue + + current_value = old_values.get(field_name, out.get(field_name, "")) + if update_mode in (MODE_SET_IF_EMPTY, MODE_SET_IF_NEW): + if not current_value: + out[field_name] = new_value + elif update_mode == MODE_APPEND_LIST: + _add_to_list(out, field_name, current_value, new_value, list_sep) + else: + raise SyncConfigError(["Invalid update mode " + update_mode]) + return out + + +def _add_to_list(out, field_name, current_value, new_item, list_sep): + new_item = str(new_item) + if list_sep is not None: + new_item = new_item.replace(list_sep, "") + current_value = current_value.split(list_sep) if current_value else [] + elif not isinstance(current_value, (list, tuple)): + current_value = [str(current_value)] + if new_item not in current_value: + new_list = current_value + [new_item] + if list_sep is not None: + new_list = list_sep.join(new_list) + out[field_name] = new_list + + +def translate_property_mappings(property_mappings, checkin_list_map): + """ + To properly handle copied events, users of data fields as provided by get_data_fields need to register to the + event_copy_data signal and translate all stored references to those fields using this method. + + For example, if you store your mappings in a custom Django model with a ForeignKey to Event: + + .. code-block:: python + + @receiver(signal=event_copy_data, dispatch_uid="my_sync_event_copy_data") + def event_copy_data_receiver(sender, other, checkin_list_map, **kwargs): + object_mappings = other.my_object_mappings.all() + object_mapping_map = {} + for om in object_mappings: + om = copy.copy(om) + object_mapping_map[om.pk] = om + om.pk = None + om.event = sender + om.property_mappings = translate_property_mappings(om.property_mappings, checkin_list_map) + om.save() + + """ + mappings = [] + + for mapping in property_mappings: + pretix_field = mapping["pretix_field"] + if pretix_field.startswith("checkin_date_"): + old_id = int(pretix_field[len("checkin_date_"):]) + if old_id not in checkin_list_map: + # old_id might not be in checkin_list_map, because copying of an event series only copies check-in + # lists covering the whole series, not individual dates. + pretix_field = "_invalid_" + pretix_field + else: + pretix_field = "checkin_date_%d" % checkin_list_map[old_id].pk + mappings.append({**mapping, "pretix_field": pretix_field}) + return mappings diff --git a/src/pretix/base/exporters/orderlist.py b/src/pretix/base/exporters/orderlist.py index c1d90c8cf..77501780f 100644 --- a/src/pretix/base/exporters/orderlist.py +++ b/src/pretix/base/exporters/orderlist.py @@ -68,6 +68,7 @@ from ...control.forms.filter import get_all_payment_providers from ...helpers import GroupConcat from ...helpers.iter import chunked_iterable from ...helpers.safe_openpyxl import remove_invalid_excel_chars +from ...multidomain.urlreverse import build_absolute_uri from ..exporter import ( ListExporter, MultiSheetListExporter, OrganizerLevelExportMixin, ) @@ -287,6 +288,7 @@ class OrderListExporter(MultiSheetListExporter): headers.append(_('Email address verified')) headers.append(_('External customer ID')) headers.append(_('Payment providers')) + headers.append(_('Order link')) if form_data.get('include_payment_amounts'): payment_methods = self._get_all_payment_methods(qs) for id, vn in payment_methods: @@ -402,6 +404,13 @@ class OrderListExporter(MultiSheetListExporter): if p and p != 'free' ])) + row.append( + build_absolute_uri(order.event, 'presale:event.order', kwargs={ + 'order': order.code, + 'secret': order.secret, + }) + ) + if form_data.get('include_payment_amounts'): payment_methods = self._get_all_payment_methods(qs) for id, vn in payment_methods: @@ -659,6 +668,7 @@ class OrderListExporter(MultiSheetListExporter): _('External customer ID'), _('Check-in lists'), _('Payment providers'), + _('Position order link') ] # get meta_data labels from first cached event @@ -803,6 +813,14 @@ class OrderListExporter(MultiSheetListExporter): if p and p != 'free' ])) + row.append( + build_absolute_uri(order.event, 'presale:event.order.position', kwargs={ + 'order': order.code, + 'secret': op.web_secret, + 'position': op.positionid + }) + ) + if has_subevents: if op.subevent: row += op.subevent.meta_data.values() diff --git a/src/pretix/base/forms/questions.py b/src/pretix/base/forms/questions.py index 2a50588ac..be8811d34 100644 --- a/src/pretix/base/forms/questions.py +++ b/src/pretix/base/forms/questions.py @@ -54,7 +54,6 @@ from django.core.validators import ( from django.db.models import QuerySet from django.forms import Select, widgets from django.forms.widgets import FILE_INPUT_CONTRADICTION -from django.urls import reverse from django.utils.formats import date_format from django.utils.html import escape from django.utils.safestring import mark_safe @@ -78,6 +77,7 @@ from pretix.base.forms.widgets import ( from pretix.base.i18n import ( get_babel_locale, get_language_without_region, language, ) +from pretix.base.invoicing.transmission import get_transmission_types from pretix.base.models import InvoiceAddress, Item, Question, QuestionOption from pretix.base.models.tax import ask_for_vat_id from pretix.base.services.tax import ( @@ -736,7 +736,7 @@ class BaseQuestionsForm(forms.Form): initial=country, widget=forms.Select(attrs={ 'autocomplete': 'country', - 'data-country-information-url': reverse('js_helpers.states'), + 'data-trigger-address-info': 'on', }), ) c = [('', '---')] @@ -1142,11 +1142,19 @@ class BaseInvoiceAddressForm(forms.ModelForm): if (not kwargs.get('instance') or not kwargs['instance'].country) and not kwargs["initial"].get("country"): kwargs['initial']['country'] = guess_country_from_request(self.request, self.event) + if kwargs.get('instance'): + kwargs['initial'].update(kwargs['instance'].transmission_info or {}) + kwargs['initial']['transmission_type'] = kwargs['instance'].transmission_type + super().__init__(*args, **kwargs) + # Individuals do not have a company name or VAT ID self.fields["company"].widget.attrs["data-display-dependency"] = f'input[name="{self.add_prefix("is_business")}"][value="business"]' self.fields["vat_id"].widget.attrs["data-display-dependency"] = f'input[name="{self.add_prefix("is_business")}"][value="business"]' + # The internal reference is a very business-specific field and might confuse non-business users + self.fields["internal_reference"].widget.attrs["data-display-dependency"] = f'input[name="{self.add_prefix("is_business")}"][value="business"]' + if not self.ask_vat_id: del self.fields['vat_id'] elif self.validate_vat_id: @@ -1162,8 +1170,17 @@ class BaseInvoiceAddressForm(forms.ModelForm): str(_('If you are registered in Switzerland, you can enter your UID instead.')), ]) + transmission_type_choices = [ + (t.identifier, t.public_name) for t in get_transmission_types() + ] + if not self.address_required or self.all_optional: + transmission_type_choices.insert(0, ("-", _("No invoice requested"))) + self.fields['transmission_type'] = forms.ChoiceField( + label=_('Invoice transmission method'), + choices=transmission_type_choices + ) + self.fields['country'].choices = CachedCountries() - self.fields['country'].widget.attrs['data-country-information-url'] = reverse('js_helpers.states') c = [('', '---')] fprefix = self.prefix + '-' if self.prefix else '' @@ -1242,6 +1259,44 @@ class BaseInvoiceAddressForm(forms.ModelForm): else: del self.fields['custom_field'] + # Add transmission type specific fields + for transmission_type in get_transmission_types(): + for k, f in transmission_type.invoice_address_form_fields.items(): + if ( + transmission_type.identifier == "email" and + k in ("transmission_email_other", "transmission_email_address") and + ( + event.settings.invoice_generate == "False" or + not event.settings.invoice_email_attachment + ) + ): + # This looks like a very unclean hack (and probably really is one), but hear me out: + # With pretix 2025.7, we introduced invoice transmission types and added the "send to another email" + # feature for the email provider. This feature was previously part of the bank transfer payment + # provider and opt-in. With this change, this feature becomes available for all pretix shops, which + # we think is a good thing in the long run as it is an useful feature for every business customer. + # However, there's two scenarios where it might be bad that we add it without opt-in: + # - When the organizer has turned off invoice generation in pretix and is collecting invoice information + # only for other reasons or to later create invoices with a separate software. In this case it + # would be very bad for the user to be able to ask for the invoice to be sent somewhere else, and + # that information then be ignored because the organizer has not updated their process. + # - When the organizer has intentionally turned off invoices being attached to emails, because that + # would somehow be a contradiction. + # Now, the obvious solution would be to make the TransmissionType.invoice_address_form_fields property + # a function that depends on the event as an input. However, I believe this is the wrong approach + # over the long term. As a generalized concept, we DO want invoice address collection to be + # *independent* of event settings, in order to (later) e.g. implement invoice address editing within + # customer accounts. Hence, this hack directly in the form to provide (some) backwards compatibility + # only for the default transmission type "email". + continue + + self.fields[k] = f + f._required = f.required + f.required = False + f.widget.is_required = False + if 'required' in f.widget.attrs: + del f.widget.attrs['required'] + for k, v in self.fields.items(): if v.widget.attrs.get('autocomplete') or k == 'name_parts': autocomplete = v.widget.attrs.get('autocomplete', '') @@ -1250,6 +1305,10 @@ class BaseInvoiceAddressForm(forms.ModelForm): else: v.widget.attrs['autocomplete'] = 'section-invoice billing ' + autocomplete + self.fields['country'].widget.attrs['data-trigger-address-info'] = 'on' + self.fields['is_business'].widget.attrs['data-trigger-address-info'] = 'on' + self.fields['transmission_type'].widget.attrs['data-trigger-address-info'] = 'on' + def clean(self): from pretix.base.addressvalidation import \ validate_address # local import to prevent impact on startup time @@ -1277,11 +1336,23 @@ class BaseInvoiceAddressForm(forms.ModelForm): self.instance.name_parts = data.get('name_parts') - if all( - not v for k, v in data.items() if k not in ('is_business', 'country', 'name_parts') - ) and name_parts_is_empty(data.get('name_parts', {})): + form_is_empty = all( + not v for k, v in data.items() + if k not in ('is_business', 'country', 'name_parts', 'transmission_type') and not k.startswith("transmission_") + ) and name_parts_is_empty(data.get('name_parts', {})) + + if form_is_empty: # Do not save the country if it is the only field set -- we don't know the user even checked it! self.cleaned_data['country'] = '' + if data.get('transmission_type') == "-": + data['transmission_type'] = 'email' # our actual default for now, we can revisit this later + + else: + if data.get('transmission_type') == "-": + raise ValidationError( + {"transmission_type": _("If you enter an invoice address, you also need to select an invoice " + "transmission method.")} + ) if self.validate_vat_id and self.instance.vat_id_validated and 'vat_id' not in self.changed_data: pass @@ -1303,6 +1374,37 @@ class BaseInvoiceAddressForm(forms.ModelForm): else: self.instance.vat_id_validated = False + for transmission_type in get_transmission_types(): + if transmission_type.identifier == data.get("transmission_type"): + if not transmission_type.is_available(self.event, data.get("country"), data.get("is_business")): + raise ValidationError({ + "transmission_type": _("The selected transmission type is not available in your country or for " + "your type of address.") + }) + + required_fields = transmission_type.invoice_address_form_fields_required(data.get("country"), data.get("is_business")) + for r in required_fields: + if r not in self.fields: + logger.info(f"Transmission type {transmission_type.identifier} required field {r} which is not available.") + raise ValidationError( + _("The selected type of invoice transmission requires a field that is currently not " + "available, please reach out to the organizer.") + ) + if not data.get(r): + raise ValidationError({r: _("This field is required for the selected type of invoice transmission.")}) + + self.instance.transmission_type = transmission_type.identifier + self.instance.transmission_info = { + k: data.get(k) for k in transmission_type.invoice_address_form_fields + } + elif transmission_type.exclusive: + if transmission_type.is_available(self.event, data.get("country"), data.get("is_business")): + raise ValidationError({ + "transmission_type": "The transmission type '%s' must be used for this country or address type." % ( + transmission_type.public_name, + ) + }) + class BaseInvoiceNameForm(BaseInvoiceAddressForm): def __init__(self, *args, **kwargs): diff --git a/src/pretix/base/invoice.py b/src/pretix/base/invoice.py index 84c7d32af..5efbee054 100644 --- a/src/pretix/base/invoice.py +++ b/src/pretix/base/invoice.py @@ -19,1072 +19,20 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # -import logging -import re -import unicodedata -from collections import defaultdict -from decimal import Decimal -from io import BytesIO -from itertools import groupby -from typing import Tuple - -import bleach -import vat_moss.exchange_rates -from bidi import get_display -from django.contrib.staticfiles import finders -from django.db.models import Sum -from django.dispatch import receiver -from django.utils.formats import date_format, localize -from django.utils.translation import ( - get_language, gettext, gettext_lazy, pgettext, -) -from reportlab.lib import colors, pagesizes -from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT -from reportlab.lib.styles import ParagraphStyle, StyleSheet1 -from reportlab.lib.units import mm -from reportlab.pdfbase import pdfmetrics -from reportlab.pdfbase.pdfmetrics import stringWidth -from reportlab.pdfbase.ttfonts import TTFont -from reportlab.pdfgen.canvas import Canvas -from reportlab.platypus import ( - BaseDocTemplate, Flowable, Frame, KeepTogether, NextPageTemplate, - PageTemplate, Paragraph, Spacer, Table, TableStyle, +from .invoicing.pdf import ( + BaseInvoiceRenderer, BaseReportlabInvoiceRenderer, ClassicInvoiceRenderer, + Modern1Renderer, Modern1SimplifiedRenderer, NumberedCanvas, + ThumbnailingImageReader, addon_aware_groupby, ) -from pretix.base.decimal import round_decimal -from pretix.base.models import Event, Invoice, Order, OrderPayment -from pretix.base.services.currencies import SOURCE_NAMES -from pretix.base.signals import register_invoice_renderers -from pretix.base.templatetags.money import money_filter -from pretix.helpers.reportlab import ThumbnailingImageReader, reshaper -from pretix.presale.style import get_fonts - -logger = logging.getLogger(__name__) - - -def addon_aware_groupby(iterable, key, is_addon): - """ - We use groupby() to visually group identical lines on an invoice. For example, instead of - - Product 1 5.00 EUR - Product 1 5.00 EUR - Product 1 5.00 EUR - Product 2 7.00 EUR - - We want to print - - 3x Product 1 5.00 EUR = 15.00 EUR - Product 2 7.00 EUR - - However, this fails for setups with addon-products since groupby() only groups consecutive - lines with the same identity. So in - - Product 1 5.00 EUR - + Addon 1 2.00 EUR - Product 1 5.00 EUR - + Addon 1 2.00 EUR - Product 1 5.00 EUR - + Addon 2 3.00 EUR - - There is no consecutive repetition of the same entity. This function provides a specialised groupby which - understands the product/addon relationship and packs groups of these addons together if they are, in fact, - identical groups: - - 2x Product 1 5.00 EUR = 10.00 EUR - + 2x Addon 1 2.00 EUR = 4.00 EUR - Product 1 5.00 EUR - + Addon 2 3.00 EUR - """ - packed_groups = [] - - for i in iterable: - if is_addon(i): - packed_groups[-1].append(i) - else: - packed_groups.append([i]) - # Each packed_groups element contains a list with the parent product as first element, and any addon products following - - def _reorder(packed_groups): - # Emit the products as individual products again, reordered by "all parent products, then all addon products" - # within each group. - for _, repeated_groups in groupby(packed_groups, key=lambda g: tuple(key(a) for a in g)): - for repeated_items in zip(*repeated_groups): - yield from repeated_items - - return groupby(_reorder(packed_groups), key) - - -class NumberedCanvas(Canvas): - def __init__(self, *args, **kwargs): - self.font_regular = kwargs.pop('font_regular') - super().__init__(*args, **kwargs) - self._saved_page_states = [] - - def showPage(self): - self._saved_page_states.append(dict(self.__dict__)) - self._startPage() - - def save(self): - num_pages = len(self._saved_page_states) - for state in self._saved_page_states: - self.__dict__.update(state) - self.draw_page_number(num_pages) - Canvas.showPage(self) - Canvas.save(self) - - def draw_page_number(self, page_count): - self.saveState() - self.setFont(self.font_regular, 8) - text = pgettext("invoice", "Page %d of %d") % (self._pageNumber, page_count,) - try: - text = get_display(reshaper.reshape(text)) - except: - logger.exception('Reshaping/Bidi fixes failed on string {}'.format(repr(text))) - self.drawRightString(self._pagesize[0] - 20 * mm, 10 * mm, text) - self.restoreState() - - -class BaseInvoiceRenderer: - """ - This is the base class for all invoice renderers. - """ - - def __init__(self, event: Event): - self.event = event - - def __str__(self): - return self.identifier - - def generate(self, invoice: Invoice) -> Tuple[str, str, str]: - """ - This method should generate the invoice file and return a tuple consisting of a - filename, a file type and file content. The extension will be taken from the filename - which is otherwise ignored. - """ - raise NotImplementedError() - - @property - def verbose_name(self) -> str: - """ - A human-readable name for this renderer. This should be short but - self-explanatory. Good examples include 'German DIN 5008' or 'Italian invoice'. - """ - raise NotImplementedError() # NOQA - - @property - def identifier(self) -> str: - """ - A short and unique identifier for this renderer. - This should only contain lowercase letters and in most - cases will be the same as your package name. - """ - raise NotImplementedError() # NOQA - - -class BaseReportlabInvoiceRenderer(BaseInvoiceRenderer): - """ - This is a convenience class to avoid duplicate code when implementing invoice renderers - that are based on reportlab. - """ - pagesize = pagesizes.A4 - left_margin = 25 * mm - right_margin = 20 * mm - top_margin = 20 * mm - bottom_margin = 15 * mm - doc_template_class = BaseDocTemplate - canvas_class = Canvas - font_regular = 'OpenSans' - font_bold = 'OpenSansBd' - - def _init(self): - """ - Initialize the renderer. By default, this registers fonts and sets ``self.stylesheet``. - """ - self._register_fonts() - self.stylesheet = self._get_stylesheet() - - def _get_stylesheet(self): - """ - Get a stylesheet. By default, this contains the "Normal" and "Heading1" styles. - """ - stylesheet = StyleSheet1() - stylesheet.add(ParagraphStyle(name='Normal', fontName=self.font_regular, fontSize=10, leading=12)) - stylesheet.add(ParagraphStyle(name='Bold', fontName=self.font_bold, fontSize=10, leading=12)) - stylesheet.add(ParagraphStyle(name='BoldRight', fontName=self.font_bold, fontSize=10, leading=12, alignment=TA_RIGHT)) - stylesheet.add(ParagraphStyle(name='BoldRightNoSplit', fontName=self.font_bold, fontSize=10, leading=12, alignment=TA_RIGHT, - splitLongWords=False)) - stylesheet.add(ParagraphStyle(name='NormalRight', fontName=self.font_regular, fontSize=10, leading=12, alignment=TA_RIGHT)) - stylesheet.add(ParagraphStyle(name='BoldInverseCenter', fontName=self.font_bold, fontSize=10, leading=12, - textColor=colors.white, alignment=TA_CENTER)) - stylesheet.add(ParagraphStyle(name='InvoiceFrom', parent=stylesheet['Normal'])) - stylesheet.add(ParagraphStyle(name='Heading1', fontName=self.font_bold, fontSize=15, leading=15 * 1.2)) - stylesheet.add(ParagraphStyle(name='FineprintHeading', fontName=self.font_bold, fontSize=8, leading=12)) - stylesheet.add(ParagraphStyle(name='Fineprint', fontName=self.font_regular, fontSize=8, leading=10)) - stylesheet.add(ParagraphStyle(name='FineprintRight', fontName=self.font_regular, fontSize=8, leading=10, alignment=TA_RIGHT)) - return stylesheet - - def _register_fonts(self): - """ - Register fonts with reportlab. By default, this registers the OpenSans font family - """ - pdfmetrics.registerFont(TTFont('OpenSans', finders.find('fonts/OpenSans-Regular.ttf'))) - pdfmetrics.registerFont(TTFont('OpenSansIt', finders.find('fonts/OpenSans-Italic.ttf'))) - pdfmetrics.registerFont(TTFont('OpenSansBd', finders.find('fonts/OpenSans-Bold.ttf'))) - pdfmetrics.registerFont(TTFont('OpenSansBI', finders.find('fonts/OpenSans-BoldItalic.ttf'))) - pdfmetrics.registerFontFamily('OpenSans', normal='OpenSans', bold='OpenSansBd', - italic='OpenSansIt', boldItalic='OpenSansBI') - - for family, styles in get_fonts(event=self.event, pdf_support_required=True).items(): - if family == self.event.settings.invoice_renderer_font: - pdfmetrics.registerFont(TTFont(family, finders.find(styles['regular']['truetype']))) - self.font_regular = family - if 'italic' in styles: - pdfmetrics.registerFont(TTFont(family + ' I', finders.find(styles['italic']['truetype']))) - if 'bold' in styles: - pdfmetrics.registerFont(TTFont(family + ' B', finders.find(styles['bold']['truetype']))) - self.font_bold = family + ' B' - if 'bolditalic' in styles: - pdfmetrics.registerFont(TTFont(family + ' B I', finders.find(styles['bolditalic']['truetype']))) - - def _normalize(self, text): - # reportlab does not support unicode combination characters - # It's important we do this before we use ArabicReshaper - text = unicodedata.normalize("NFKC", text) - - # reportlab does not support RTL, ligature-heavy scripts like Arabic. Therefore, we use ArabicReshaper - # to resolve all ligatures and python-bidi to switch RTL texts. - try: - text = "
".join(get_display(reshaper.reshape(l)) for l in re.split("
", text)) - except: - logger.exception('Reshaping/Bidi fixes failed on string {}'.format(repr(text))) - - return text - - def _upper(self, val): - # We uppercase labels, but not in every language - if get_language().startswith('el'): - return val - return val.upper() - - def _on_other_page(self, canvas: Canvas, doc): - """ - Called when a new page is rendered that is *not* the first page. - """ - pass - - def _on_first_page(self, canvas: Canvas, doc): - """ - Called when a new page is rendered that is the first page. - """ - pass - - def _get_story(self, doc): - """ - Called to create the story to be inserted into the main frames. - """ - raise NotImplementedError() - - def _get_first_page_frames(self, doc): - """ - Called to create a list of frames for the first page. - """ - return [ - Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - 75 * mm, - leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, - id='normal') - ] - - def _get_other_page_frames(self, doc): - """ - Called to create a list of frames for the other pages. - """ - return [ - Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, - leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, - id='normal') - ] - - def _build_doc(self, fhandle): - """ - Build a PDF document in a given file handle - """ - self._init() - doc = self.doc_template_class(fhandle, pagesize=self.pagesize, - leftMargin=self.left_margin, rightMargin=self.right_margin, - topMargin=self.top_margin, bottomMargin=self.bottom_margin) - - doc.addPageTemplates([ - PageTemplate( - id='FirstPage', - frames=self._get_first_page_frames(doc), - onPage=self._on_first_page, - pagesize=self.pagesize - ), - PageTemplate( - id='OtherPages', - frames=self._get_other_page_frames(doc), - onPage=self._on_other_page, - pagesize=self.pagesize - ) - ]) - story = self._get_story(doc) - doc.build(story, canvasmaker=self.canvas_class) - return doc - - def generate(self, invoice: Invoice): - self.invoice = invoice - buffer = BytesIO() - self._build_doc(buffer) - buffer.seek(0) - return 'invoice.pdf', 'application/pdf', buffer.read() - - def _clean_text(self, text, tags=None): - return self._normalize(bleach.clean( - text, - tags=set(tags) if tags else set() - ).strip().replace('
', '
').replace('\n', '
\n')) - - -class PaidMarker(Flowable): - def __init__(self, text='paid', color=None, font='OpenSansBd', size=20): - super().__init__() - self.text = text - self.color = color - self.font = font - self.size = size - self._showBoundary = True - - def wrap(self, availwidth, availheight): - # Fake a size, we don't care if we exceed the table - return 10, self.size / 2 - - def draw(self): - self.canv.translate(0, - self.size / 2) - self.canv.rotate(2) - self.canv.setFont(self.font, self.size) - self.canv.setFillColor(self.color) - width = self.canv.stringWidth(self.text, self.font, self.size) - self.canv.drawRightString(0, 0, self.text) - - self.canv.setStrokeColor(self.color) - self.canv.roundRect(-width - self.size / 2, -self.size / 4, width + self.size, self.size + self.size / 4, 3) - - -class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer): - identifier = 'classic' - verbose_name = pgettext('invoice', 'Classic renderer (pretix 1.0)') - - def canvas_class(self, *args, **kwargs): - kwargs['font_regular'] = self.font_regular - return NumberedCanvas(*args, **kwargs) - - def _on_other_page(self, canvas: Canvas, doc): - canvas.saveState() - canvas.setFont(self.font_regular, 8) - - for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): - canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, self._normalize(line.strip())) - - canvas.restoreState() - - invoice_to_width = 85 * mm - invoice_to_height = 50 * mm - invoice_to_left = 25 * mm - invoice_to_top = 52 * mm - - def _draw_invoice_to(self, canvas): - p = Paragraph(self._clean_text(self.invoice.address_invoice_to), - style=self.stylesheet['Normal']) - p.wrapOn(canvas, self.invoice_to_width, self.invoice_to_height) - p_size = p.wrap(self.invoice_to_width, self.invoice_to_height) - p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - p_size[1] - self.invoice_to_top) - - invoice_from_width = 70 * mm - invoice_from_height = 50 * mm - invoice_from_left = 25 * mm - invoice_from_top = 17 * mm - - def _draw_invoice_from(self, canvas): - p = Paragraph( - self._clean_text(self.invoice.full_invoice_from), - style=self.stylesheet['InvoiceFrom'] - ) - p.wrapOn(canvas, self.invoice_from_width, self.invoice_from_height) - p_size = p.wrap(self.invoice_from_width, self.invoice_from_height) - p.drawOn(canvas, self.invoice_from_left, self.pagesize[1] - p_size[1] - self.invoice_from_top) - - def _draw_invoice_from_label(self, canvas): - textobject = canvas.beginText(25 * mm, (297 - 15) * mm) - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice from')))) - canvas.drawText(textobject) - - def _draw_invoice_to_label(self, canvas): - textobject = canvas.beginText(25 * mm, (297 - 50) * mm) - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice to')))) - canvas.drawText(textobject) - - logo_width = 25 * mm - logo_height = 25 * mm - logo_left = 95 * mm - logo_top = 13 * mm - logo_anchor = 'n' - - def _draw_logo(self, canvas): - if self.invoice.event.settings.invoice_logo_image: - logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True) - ir = ThumbnailingImageReader(logo_file) - try: - ir.resize(self.logo_width, self.logo_height, 300) - except: - logger.exception("Can not resize image") - pass - try: - # Valid ZUGFeRD invoices must be compliant with PDF/A-3. pretix-zugferd ensures this by passing them - # through ghost script. Unfortunately, if the logo contains transparency, this will still fail. - # I was unable to figure out a way to fix this in GhostScript, so the easy fix is to remove the - # transparency, as our invoices always have a white background anyways. - ir.remove_transparency() - except: - logger.exception("Can not remove transparency from logo") - pass - canvas.drawImage(ir, - self.logo_left, - self.pagesize[1] - self.logo_height - self.logo_top, - width=self.logo_width, height=self.logo_height, - preserveAspectRatio=True, anchor=self.logo_anchor, - mask='auto') - - def _draw_metadata(self, canvas): - textobject = canvas.beginText(125 * mm, (297 - 38) * mm) - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Order code')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(self.invoice.order.full_code)) - canvas.drawText(textobject) - - textobject = canvas.beginText(125 * mm, (297 - 50) * mm) - textobject.setFont(self.font_bold, 8) - if self.invoice.is_cancellation: - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Cancellation number')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(self.invoice.number)) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Original invoice')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(self.invoice.refers.number)) - else: - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice number')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(self.invoice.number)) - textobject.moveCursor(0, 5) - - if self.invoice.is_cancellation: - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Cancellation date')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(date_format(self.invoice.date, "DATE_FORMAT"))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Original invoice date')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(date_format(self.invoice.refers.date, "DATE_FORMAT"))) - textobject.moveCursor(0, 5) - else: - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice date')))) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_regular, 10) - textobject.textLine(self._normalize(date_format(self.invoice.date, "DATE_FORMAT"))) - textobject.moveCursor(0, 5) - - canvas.drawText(textobject) - - event_left = 125 * mm - event_top = 17 * mm - event_width = 65 * mm - event_height = 50 * mm - - def _draw_event_label(self, canvas): - textobject = canvas.beginText(125 * mm, (297 - 15) * mm) - textobject.setFont(self.font_bold, 8) - textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Event')))) - canvas.drawText(textobject) - - def _draw_event(self, canvas): - def shorten(txt): - txt = str(txt) - txt = bleach.clean(txt, tags=set()).strip() - p = Paragraph(self._normalize(txt.strip().replace('\n', '
\n')), style=self.stylesheet['Normal']) - p_size = p.wrap(self.event_width, self.event_height) - - while p_size[1] > 2 * self.stylesheet['Normal'].leading: - txt = ' '.join(txt.replace('…', '').split()[:-1]) + '…' - p = Paragraph(self._normalize(txt.strip().replace('\n', '
\n')), style=self.stylesheet['Normal']) - p_size = p.wrap(self.event_width, self.event_height) - return txt - - if not self.invoice.event.has_subevents and self.invoice.event.settings.show_dates_on_frontpage: - tz = self.invoice.event.timezone - show_end_date = ( - self.invoice.event.settings.show_date_to and - self.invoice.event.date_to and - self.invoice.event.date_to.astimezone(tz).date() != self.invoice.event.date_from.astimezone(tz).date() - ) - if show_end_date: - p_str = ( - shorten(self.invoice.event.name) + '\n' + - pgettext('invoice', '{from_date}\nuntil {to_date}').format( - from_date=self.invoice.event.get_date_from_display(show_times=False), - to_date=self.invoice.event.get_date_to_display(show_times=False) - ) - ) - else: - p_str = ( - shorten(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display(show_times=False) - ) - else: - p_str = shorten(self.invoice.event.name) - - p = Paragraph(self._normalize(p_str.strip().replace('\n', '
\n')), style=self.stylesheet['Normal']) - p.wrapOn(canvas, self.event_width, self.event_height) - p_size = p.wrap(self.event_width, self.event_height) - p.drawOn(canvas, self.event_left, self.pagesize[1] - self.event_top - p_size[1]) - self._draw_event_label(canvas) - - def _draw_footer(self, canvas): - canvas.setFont(self.font_regular, 8) - for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): - canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, self._normalize(line.strip())) - - def _draw_testmode(self, canvas): - if self.invoice.order.testmode: - canvas.saveState() - canvas.setFont(self.font_bold, 30) - canvas.setFillColorRGB(32, 0, 0) - canvas.drawRightString(self.pagesize[0] - 20 * mm, (297 - 100) * mm, self._normalize(gettext('TEST MODE'))) - canvas.restoreState() - - def _on_first_page(self, canvas: Canvas, doc): - canvas.setCreator('pretix.eu') - canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) - - canvas.saveState() - self._draw_footer(canvas) - self._draw_testmode(canvas) - self._draw_invoice_from_label(canvas) - self._draw_invoice_from(canvas) - self._draw_invoice_to_label(canvas) - self._draw_invoice_to(canvas) - self._draw_metadata(canvas) - self._draw_logo(canvas) - self._draw_event(canvas) - canvas.restoreState() - - def _get_first_page_frames(self, doc): - footer_length = 3.5 * len(self.invoice.footer_text.split('\n')) * mm - return [ - Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - 75 * mm, - leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=footer_length, - id='normal') - ] - - def _get_other_page_frames(self, doc): - footer_length = 3.5 * len(self.invoice.footer_text.split('\n')) * mm - return [ - Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, - leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=footer_length, - id='normal') - ] - - def _get_intro(self): - story = [] - if self.invoice.custom_field: - story.append(Paragraph( - '{}: {}'.format( - self._clean_text(str(self.invoice.event.settings.invoice_address_custom_field)), - self._clean_text(self.invoice.custom_field), - ), - self.stylesheet['Normal'] - )) - - if self.invoice.internal_reference: - story.append(Paragraph( - self._normalize(pgettext('invoice', 'Customer reference: {reference}').format( - reference=self._clean_text(self.invoice.internal_reference), - )), - self.stylesheet['Normal'] - )) - - if self.invoice.invoice_to_vat_id: - story.append(Paragraph( - self._normalize(pgettext('invoice', 'Customer VAT ID')) + ': ' + - self._clean_text(self.invoice.invoice_to_vat_id), - self.stylesheet['Normal'] - )) - - if self.invoice.invoice_to_beneficiary: - story.append(Paragraph( - self._normalize(pgettext('invoice', 'Beneficiary')) + ':
' + - self._clean_text(self.invoice.invoice_to_beneficiary), - self.stylesheet['Normal'] - )) - - if self.invoice.introductory_text: - story.append(Paragraph( - self._clean_text(self.invoice.introductory_text, tags=['br']), - self.stylesheet['Normal'] - )) - story.append(Spacer(1, 10 * mm)) - - return story - - def _get_story(self, doc): - has_taxes = any(il.tax_value for il in self.invoice.lines.all()) or self.invoice.reverse_charge - - story = [ - NextPageTemplate('FirstPage'), - Paragraph( - self._normalize( - pgettext('invoice', 'Tax Invoice') if str(self.invoice.invoice_from_country) == 'AU' - else pgettext('invoice', 'Invoice') - ) if not self.invoice.is_cancellation else self._normalize(pgettext('invoice', 'Cancellation')), - self.stylesheet['Heading1'] - ), - Spacer(1, 5 * mm), - NextPageTemplate('OtherPages'), - ] - story += self._get_intro() - - taxvalue_map = defaultdict(Decimal) - grossvalue_map = defaultdict(Decimal) - - tstyledata = [ - ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), - ('VALIGN', (0, 0), (-1, -1), 'TOP'), - ('FONTNAME', (0, 0), (-1, -1), self.font_regular), - ('FONTNAME', (0, 0), (-1, 0), self.font_bold), - ('FONTNAME', (0, -1), (-1, -1), self.font_bold), - ('LEFTPADDING', (0, 0), (0, -1), 0), - ('RIGHTPADDING', (-1, 0), (-1, -1), 0), - ] - if has_taxes: - tdata = [( - Paragraph(self._normalize(pgettext('invoice', 'Description')), self.stylesheet['Bold']), - Paragraph(self._normalize(pgettext('invoice', 'Qty')), self.stylesheet['BoldRightNoSplit']), - Paragraph(self._normalize(pgettext('invoice', 'Tax rate')), self.stylesheet['BoldRightNoSplit']), - Paragraph(self._normalize(pgettext('invoice', 'Net')), self.stylesheet['BoldRightNoSplit']), - Paragraph(self._normalize(pgettext('invoice', 'Gross')), self.stylesheet['BoldRightNoSplit']), - )] - else: - tdata = [( - Paragraph(self._normalize(pgettext('invoice', 'Description')), self.stylesheet['Bold']), - Paragraph(self._normalize(pgettext('invoice', 'Qty')), self.stylesheet['BoldRightNoSplit']), - Paragraph(self._normalize(pgettext('invoice', 'Amount')), self.stylesheet['BoldRightNoSplit']), - )] - - def _group_key(line): - return (line.description, line.tax_rate, line.tax_name, line.net_value, line.gross_value, line.subevent_id, - line.event_date_from, line.event_date_to) - - total = Decimal('0.00') - for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in addon_aware_groupby( - self.invoice.lines.all(), - key=_group_key, - is_addon=lambda l: l.description.startswith(" +"), - ): - lines = list(lines) - if has_taxes: - if len(lines) > 1: - single_price_line = pgettext('invoice', 'Single price: {net_price} net / {gross_price} gross').format( - net_price=money_filter(net_value, self.invoice.event.currency), - gross_price=money_filter(gross_value, self.invoice.event.currency), - ) - description = description + "\n" + single_price_line - tdata.append(( - Paragraph( - self._clean_text(description, tags=['br']), - self.stylesheet['Normal'] - ), - str(len(lines)), - localize(tax_rate) + " %", - Paragraph(money_filter(net_value * len(lines), self.invoice.event.currency).replace('\xa0', ' '), self.stylesheet['NormalRight']), - Paragraph(money_filter(gross_value * len(lines), self.invoice.event.currency).replace('\xa0', ' '), self.stylesheet['NormalRight']), - )) - else: - if len(lines) > 1: - single_price_line = pgettext('invoice', 'Single price: {price}').format( - price=money_filter(gross_value, self.invoice.event.currency), - ) - description = description + "\n" + single_price_line - tdata.append(( - Paragraph( - self._clean_text(description, tags=['br']), - self.stylesheet['Normal'] - ), - str(len(lines)), - Paragraph(money_filter(gross_value * len(lines), self.invoice.event.currency).replace('\xa0', ' '), self.stylesheet['NormalRight']), - )) - taxvalue_map[tax_rate, tax_name] += (gross_value - net_value) * len(lines) - grossvalue_map[tax_rate, tax_name] += gross_value * len(lines) - total += gross_value * len(lines) - - if has_taxes: - tdata.append([ - Paragraph(self._normalize(pgettext('invoice', 'Invoice total')), self.stylesheet['Bold']), '', '', '', - money_filter(total, self.invoice.event.currency) - ]) - colwidths = [a * doc.width for a in (.50, .05, .15, .15, .15)] - else: - tdata.append([ - Paragraph(self._normalize(pgettext('invoice', 'Invoice total')), self.stylesheet['Bold']), '', - money_filter(total, self.invoice.event.currency) - ]) - colwidths = [a * doc.width for a in (.65, .20, .15)] - - if not self.invoice.is_cancellation: - if self.invoice.event.settings.invoice_show_payments and self.invoice.order.status == Order.STATUS_PENDING: - pending_sum = self.invoice.order.pending_sum - if pending_sum != total: - tdata.append( - [Paragraph(self._normalize(pgettext('invoice', 'Received payments')), self.stylesheet['Normal'])] + - (['', '', ''] if has_taxes else ['']) + - [money_filter(pending_sum - total, self.invoice.event.currency)] - ) - tdata.append( - [Paragraph(self._normalize(pgettext('invoice', 'Outstanding payments')), self.stylesheet['Bold'])] + - (['', '', ''] if has_taxes else ['']) + - [money_filter(pending_sum, self.invoice.event.currency)] - ) - tstyledata += [ - ('FONTNAME', (0, len(tdata) - 3), (-1, len(tdata) - 3), self.font_bold), - ] - elif self.invoice.event.settings.invoice_show_payments and self.invoice.order.payments.filter( - state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED), provider='giftcard' - ).exists(): - giftcard_sum = self.invoice.order.payments.filter( - state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED), - provider='giftcard' - ).aggregate( - s=Sum('amount') - )['s'] or Decimal('0.00') - tdata.append( - [Paragraph(self._normalize(pgettext('invoice', 'Paid by gift card')), self.stylesheet['Normal'])] + - (['', '', ''] if has_taxes else ['']) + - [money_filter(giftcard_sum, self.invoice.event.currency)] - ) - tdata.append( - [Paragraph(self._normalize(pgettext('invoice', 'Remaining amount')), self.stylesheet['Bold'])] + - (['', '', ''] if has_taxes else ['']) + - [money_filter(total - giftcard_sum, self.invoice.event.currency)] - ) - tstyledata += [ - ('FONTNAME', (0, len(tdata) - 3), (-1, len(tdata) - 3), self.font_bold), - ] - elif self.invoice.payment_provider_stamp: - pm = PaidMarker( - text=self._normalize(self.invoice.payment_provider_stamp), - color=colors.HexColor(self.event.settings.theme_color_success), - font=self.font_bold, - size=16 - ) - tdata[-1][-2] = pm - - table = Table(tdata, colWidths=colwidths, repeatRows=1) - table.setStyle(TableStyle(tstyledata)) - story.append(table) - - story.append(Spacer(1, 10 * mm)) - - if self.invoice.payment_provider_text: - story.append(Paragraph( - self._normalize(self.invoice.payment_provider_text), - self.stylesheet['Normal'] - )) - - if self.invoice.payment_provider_text and self.invoice.additional_text: - story.append(Spacer(1, 3 * mm)) - - if self.invoice.additional_text: - story.append(Paragraph( - self._clean_text(self.invoice.additional_text, tags=['br']), - self.stylesheet['Normal'] - )) - story.append(Spacer(1, 5 * mm)) - - tstyledata = [ - ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), - ('LEFTPADDING', (0, 0), (0, -1), 0), - ('RIGHTPADDING', (-1, 0), (-1, -1), 0), - ('TOPPADDING', (0, 0), (-1, -1), 1), - ('BOTTOMPADDING', (0, 0), (-1, -1), 1), - ('FONTSIZE', (0, 0), (-1, -1), 8), - ('FONTNAME', (0, 0), (-1, -1), self.font_regular), - ] - thead = [ - Paragraph(self._normalize(pgettext('invoice', 'Tax rate')), self.stylesheet['Fineprint']), - Paragraph(self._normalize(pgettext('invoice', 'Net value')), self.stylesheet['FineprintRight']), - Paragraph(self._normalize(pgettext('invoice', 'Gross value')), self.stylesheet['FineprintRight']), - Paragraph(self._normalize(pgettext('invoice', 'Tax')), self.stylesheet['FineprintRight']), - '' - ] - tdata = [thead] - - for idx, gross in grossvalue_map.items(): - rate, name = idx - if rate == 0 and gross == 0: - continue - tax = taxvalue_map[idx] - tdata.append([ - Paragraph(self._normalize(localize(rate) + " % " + name), self.stylesheet['Fineprint']), - money_filter(gross - tax, self.invoice.event.currency), - money_filter(gross, self.invoice.event.currency), - money_filter(tax, self.invoice.event.currency), - '' - ]) - - def fmt(val): - try: - return vat_moss.exchange_rates.format(val, self.invoice.foreign_currency_display) - except ValueError: - return localize(val) + ' ' + self.invoice.foreign_currency_display - - if any(rate != 0 and gross != 0 for (rate, name), gross in grossvalue_map.items()) and has_taxes: - colwidths = [a * doc.width for a in (.25, .15, .15, .15, .3)] - table = Table(tdata, colWidths=colwidths, repeatRows=2, hAlign=TA_LEFT) - table.setStyle(TableStyle(tstyledata)) - story.append(Spacer(5 * mm, 5 * mm)) - story.append(KeepTogether([ - Paragraph(self._normalize(pgettext('invoice', 'Included taxes')), self.stylesheet['FineprintHeading']), - table - ])) - - if self.invoice.foreign_currency_display and self.invoice.foreign_currency_rate: - tdata = [thead] - - for idx, gross in grossvalue_map.items(): - rate, name = idx - if rate == 0: - continue - tax = taxvalue_map[idx] - gross = round_decimal(gross * self.invoice.foreign_currency_rate) - tax = round_decimal(tax * self.invoice.foreign_currency_rate) - net = gross - tax - - tdata.append([ - Paragraph(self._normalize(localize(rate) + " % " + name), self.stylesheet['Fineprint']), - fmt(net), fmt(gross), fmt(tax), '' - ]) - - table = Table(tdata, colWidths=colwidths, repeatRows=2, hAlign=TA_LEFT) - table.setStyle(TableStyle(tstyledata)) - - story.append(KeepTogether([ - Spacer(1, height=2 * mm), - Paragraph( - self._normalize(pgettext( - 'invoice', 'Using the conversion rate of 1:{rate} as published by the {authority} on ' - '{date}, this corresponds to:' - ).format(rate=localize(self.invoice.foreign_currency_rate), - authority=SOURCE_NAMES.get(self.invoice.foreign_currency_source, "?"), - date=date_format(self.invoice.foreign_currency_rate_date, "SHORT_DATE_FORMAT"))), - self.stylesheet['Fineprint'] - ), - Spacer(1, height=3 * mm), - table - ])) - elif self.invoice.foreign_currency_display and self.invoice.foreign_currency_rate: - foreign_total = round_decimal(total * self.invoice.foreign_currency_rate) - story.append(Spacer(1, 5 * mm)) - story.append(Paragraph(self._normalize( - pgettext( - 'invoice', 'Using the conversion rate of 1:{rate} as published by the {authority} on ' - '{date}, the invoice total corresponds to {total}.' - ).format(rate=localize(self.invoice.foreign_currency_rate), - date=date_format(self.invoice.foreign_currency_rate_date, "SHORT_DATE_FORMAT"), - authority=SOURCE_NAMES.get(self.invoice.foreign_currency_source, "?"), - total=fmt(foreign_total))), - self.stylesheet['Fineprint'] - )) - - return story - - -class Modern1Renderer(ClassicInvoiceRenderer): - identifier = 'modern1' - verbose_name = gettext_lazy('Default invoice renderer (European-style letter)') - bottom_margin = 16.9 * mm - top_margin = 16.9 * mm - right_margin = 20 * mm - invoice_to_height = 27.3 * mm - invoice_to_width = 80 * mm - invoice_to_left = 25 * mm - invoice_to_top = (40 + 17.7) * mm - invoice_from_left = 125 * mm - invoice_from_top = 50 * mm - invoice_from_width = pagesizes.A4[0] - invoice_from_left - right_margin - invoice_from_height = 50 * mm - - logo_width = 75 * mm - logo_height = 25 * mm - logo_left = pagesizes.A4[0] - logo_width - right_margin - logo_top = top_margin - logo_anchor = 'e' - - event_left = 25 * mm - event_top = top_margin - event_width = 80 * mm - event_height = 25 * mm - - def _get_stylesheet(self): - stylesheet = super()._get_stylesheet() - stylesheet.add(ParagraphStyle(name='Sender', fontName=self.font_regular, fontSize=8, leading=10)) - stylesheet['InvoiceFrom'].alignment = TA_RIGHT - return stylesheet - - def _draw_invoice_from(self, canvas): - if not self.invoice.invoice_from: - return - c = [ - self._clean_text(l) - for l in self.invoice.address_invoice_from.strip().split('\n') - ] - p = Paragraph(self._normalize(' · '.join(c)), style=self.stylesheet['Sender']) - p.wrapOn(canvas, self.invoice_to_width, 15.7 * mm) - p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - self.invoice_to_top + 2 * mm) - super()._draw_invoice_from(canvas) - - def _draw_invoice_to_label(self, canvas): - pass - - def _draw_invoice_from_label(self, canvas): - pass - - def _draw_event_label(self, canvas): - pass - - def _get_first_page_frames(self, doc): - footer_length = 3.5 * len(self.invoice.footer_text.split('\n')) * mm - if self.event.settings.invoice_renderer_highlight_order_code: - margin_top = 100 * mm - else: - margin_top = 95 * mm - return [ - Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - margin_top, - leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=footer_length, - id='normal') - ] - - def _draw_metadata(self, canvas): - # Draws the "invoice number -- date" line. This has gotten a little more complicated since we - # encountered some events with very long invoice numbers. In this case, we automatically reduce - # the font size until it fits. - begin_top = 100 * mm - - def _draw(label, value, value_size, x, width, bold=False, sublabel=None): - if canvas.stringWidth(value, self.font_regular, value_size) > width and value_size > 6: - return False - textobject = canvas.beginText(x, self.pagesize[1] - begin_top) - textobject.setFont(self.font_regular, 8) - textobject.textLine(self._normalize(label)) - textobject.moveCursor(0, 5) - textobject.setFont(self.font_bold if bold else self.font_regular, value_size) - textobject.textLine(self._normalize(value)) - - if sublabel: - textobject.moveCursor(0, 1) - textobject.setFont(self.font_regular, 8) - textobject.textLine(self._normalize(sublabel)) - - return textobject - - value_size = 10 - while value_size >= 5: - if self.event.settings.invoice_renderer_highlight_order_code: - kwargs = dict(bold=True, sublabel=pgettext('invoice', '(Please quote at all times.)')) - else: - kwargs = {} - objects = [ - _draw(pgettext('invoice', 'Order code'), self.invoice.order.full_code, value_size, self.left_margin, 45 * mm, **kwargs) - ] - - p = Paragraph( - self._normalize(date_format(self.invoice.date, "DATE_FORMAT")), - style=ParagraphStyle(name=f'Normal{value_size}', fontName=self.font_regular, fontSize=value_size, leading=value_size * 1.2) - ) - w = stringWidth(p.text, p.frags[0].fontName, p.frags[0].fontSize) - p.wrapOn(canvas, w, 15 * mm) - date_x = self.pagesize[0] - w - self.right_margin - - if self.invoice.is_cancellation: - objects += [ - _draw(pgettext('invoice', 'Cancellation number'), self.invoice.number, - value_size, self.left_margin + 50 * mm, 45 * mm), - _draw(pgettext('invoice', 'Original invoice'), self.invoice.refers.number, - value_size, self.left_margin + 100 * mm, date_x - self.left_margin - 100 * mm - 5 * mm), - ] - else: - objects += [ - _draw(pgettext('invoice', 'Invoice number'), self.invoice.number, - value_size, self.left_margin + 70 * mm, date_x - self.left_margin - 70 * mm - 5 * mm), - ] - - if all(objects): - for o in objects: - canvas.drawText(o) - break - value_size -= 1 - - p.drawOn(canvas, date_x, self.pagesize[1] - begin_top - 10 - 6) - - textobject = canvas.beginText(date_x, self.pagesize[1] - begin_top) - textobject.setFont(self.font_regular, 8) - if self.invoice.is_cancellation: - textobject.textLine(self._normalize(pgettext('invoice', 'Cancellation date'))) - else: - textobject.textLine(self._normalize(pgettext('invoice', 'Invoice date'))) - canvas.drawText(textobject) - - -class Modern1SimplifiedRenderer(Modern1Renderer): - identifier = 'modern1simplified' - verbose_name = gettext_lazy('Simplified invoice renderer') - - logo_left = Modern1Renderer.left_margin - logo_width = pagesizes.A4[0] - Modern1Renderer.right_margin - logo_left - logo_height = 25 * mm - logo_top = 13 * mm - logo_anchor = 'nw' - - def _draw_invoice_from(self, canvas): - super(Modern1Renderer, self)._draw_invoice_from(canvas) - - def _draw_event(self, canvas): - pass - - def _get_intro(self): - i = [] - - if not self.invoice.event.has_subevents and self.invoice.event.settings.show_dates_on_frontpage: - i.append(Paragraph( - pgettext('invoice', 'Event date: {date_range}').format( - date_range=self.invoice.event.get_date_range_display(), - ), - self.stylesheet['Normal'], - )) - i.append(Spacer(2 * mm, 2 * mm)) - - return i + super()._get_intro() - - -@receiver(register_invoice_renderers, dispatch_uid="invoice_renderer_classic") -def recv_classic(sender, **kwargs): - return [ClassicInvoiceRenderer, Modern1Renderer, Modern1SimplifiedRenderer] +# This module consists for backwards compatibility of imports from plugins. +__all__ = [ + "addon_aware_groupby", + "NumberedCanvas", + "BaseInvoiceRenderer", + "BaseReportlabInvoiceRenderer", + "ClassicInvoiceRenderer", + "Modern1Renderer", + "Modern1SimplifiedRenderer", + "ThumbnailingImageReader", +] diff --git a/src/pretix/base/invoicing/__init__.py b/src/pretix/base/invoicing/__init__.py new file mode 100644 index 000000000..9fd5bdc50 --- /dev/null +++ b/src/pretix/base/invoicing/__init__.py @@ -0,0 +1,21 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# diff --git a/src/pretix/base/invoicing/email.py b/src/pretix/base/invoicing/email.py new file mode 100644 index 000000000..97d47d96f --- /dev/null +++ b/src/pretix/base/invoicing/email.py @@ -0,0 +1,173 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +from django import forms +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ +from django_countries.fields import Country +from i18nfield.strings import LazyI18nString + +from pretix.base.email import get_email_context +from pretix.base.i18n import language +from pretix.base.invoicing.transmission import ( + TransmissionProvider, TransmissionType, transmission_providers, + transmission_types, +) +from pretix.base.models import Invoice, InvoiceAddress +from pretix.base.services.mail import SendMailException, mail, render_mail +from pretix.helpers.format import format_map + + +@transmission_types.new() +class EmailTransmissionType(TransmissionType): + identifier = "email" + verbose_name = _("Email") + priority = 1000 + + @property + def invoice_address_form_fields(self) -> dict: + return { + "transmission_email_other": forms.BooleanField( + label=_("Email invoice directly to accounting department"), + help_text=_("If not selected, the invoice will be sent to you using the email address listed above."), + required=False, + ), + "transmission_email_address": forms.EmailField( + label=_("Email address for invoice"), + widget=forms.EmailInput( + attrs={"data-display-dependency": "#id_transmission_email_other"} + ) + ) + } + + def invoice_address_form_fields_visible(self, country: Country, is_business: bool): + if is_business: + # We don't want ask non-business users if they have an accounting department ;) + return {"transmission_email_other", "transmission_email_address"} + return set() + + def is_available(self, event, country: Country, is_business: bool): + # Skip availability check since provider is always available and we do not want to end up without invoice + # transmission type + return True + + def transmission_info_to_form_data(self, transmission_info: dict) -> dict: + return { + "transmission_email_other": bool(transmission_info.get("transmission_email_address")), + "transmission_email_address": transmission_info.get("transmission_email_address"), + } + + def form_data_to_transmission_info(self, form_data: dict) -> dict: + if form_data.get("transmission_email_other") and form_data.get("transmission_email_address"): + return { + "transmission_email_address": form_data["transmission_email_address"], + } + return {} + + +@transmission_providers.new() +class EmailTransmissionProvider(TransmissionProvider): + identifier = "email_pdf" + type = "email" + verbose_name = _("PDF via email") + priority = 1000 + testmode_supported = True + + def is_ready(self, event) -> bool: + return True + + def is_available(self, event, country: Country, is_business: bool) -> bool: + return True + + def transmit(self, invoice: Invoice): + info = (invoice.invoice_to_transmission_info or {}) + if info.get("transmission_email_address"): + recipient = info["transmission_email_address"] + else: + recipient = invoice.order.email + + if not recipient: + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_FAILED + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + invoice.order.log_action( + "pretix.event.order.invoice.sending_failed", + data={ + "full_invoice_no": invoice.full_invoice_no, + "transmission_provider": "email_pdf", + "transmission_type": "email", + "data": { + "reason": "no_recipient", + }, + } + ) + return + + with language(invoice.order.locale, invoice.order.event.settings.region): + context = get_email_context( + event=invoice.order.event, + order=invoice.order, + invoice=invoice, + event_or_subevent=invoice.order.event, + invoice_address=getattr(invoice.order, 'invoice_address', None) or InvoiceAddress() + ) + template = invoice.order.event.settings.get('mail_text_order_invoice', as_type=LazyI18nString) + subject = invoice.order.event.settings.get('mail_subject_order_invoice', as_type=LazyI18nString) + + try: + # Do not set to completed because that is done by the email sending task + subject = format_map(subject, context) + email_content = render_mail(template, context) + mail( + [recipient], + subject, + template, + context=context, + event=invoice.order.event, + locale=invoice.order.locale, + order=invoice.order, + invoices=[invoice], + attach_tickets=False, + auto_email=True, + attach_ical=False, + plain_text_only=True, + no_order_links=True, + ) + except SendMailException: + raise + else: + invoice.order.log_action( + 'pretix.event.order.email.invoice', + user=None, + auth=None, + data={ + 'subject': subject, + 'message': email_content, + 'position': None, + 'recipient': recipient, + 'invoices': [invoice.pk], + 'attach_tickets': False, + 'attach_ical': False, + 'attach_other_files': [], + 'attach_cached_files': [], + } + ) diff --git a/src/pretix/base/invoicing/national.py b/src/pretix/base/invoicing/national.py new file mode 100644 index 000000000..d8fe76e55 --- /dev/null +++ b/src/pretix/base/invoicing/national.py @@ -0,0 +1,75 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +from django import forms +from django.core.validators import RegexValidator +from django.utils.translation import pgettext_lazy +from django_countries.fields import Country +from localflavor.it.forms import ITSocialSecurityNumberField + +from pretix.base.invoicing.transmission import ( + TransmissionType, transmission_types, +) + + +@transmission_types.new() +class ItalianSdITransmissionType(TransmissionType): + identifier = "it_sdi" + verbose_name = pgettext_lazy("italian_invoice", "Italian Exchange System (SdI)") + public_name = pgettext_lazy("italian_invoice", "Exchange System (SdI)") + exclusive = True + enforce_transmission = True + + def is_available(self, event, country: Country, is_business: bool): + return str(country) == "IT" and super().is_available(event, country, is_business) + + @property + def invoice_address_form_fields(self) -> dict: + return { + "transmission_it_sdi_codice_fiscale": ITSocialSecurityNumberField( + label=pgettext_lazy("italian_invoice", "Fiscal code"), + required=False, + ), + "transmission_it_sdi_pec": forms.EmailField( + label=pgettext_lazy("italian_invoice", "Address for certified electronic mail"), + widget=forms.EmailInput() + ), + "transmission_it_sdi_recipient_code": forms.CharField( + label=pgettext_lazy("italian_invoice", "Recipient code"), + validators=[ + RegexValidator("^[A-Z0-9]{6,7}$") + ] + ), + } + + def invoice_address_form_fields_visible(self, country: Country, is_business: bool): + if is_business: + return {"transmission_it_sdi_codice_fiscale", "transmission_it_sdi_pec", "transmission_it_sdi_recipient_code"} + return {"transmission_it_sdi_codice_fiscale", "transmission_it_sdi_pec"} + + def invoice_address_form_fields_required(self, country: Country, is_business: bool): + base = { + "street", "zipcode", "city", "state", "country", + } + if is_business: + return base | {"company", "vat_id", "transmission_it_sdi_pec", "transmission_it_sdi_recipient_code"} + return base | {"transmission_it_sdi_codice_fiscale"} diff --git a/src/pretix/base/invoicing/pdf.py b/src/pretix/base/invoicing/pdf.py new file mode 100644 index 000000000..843e21bcd --- /dev/null +++ b/src/pretix/base/invoicing/pdf.py @@ -0,0 +1,1107 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +import logging +import re +import unicodedata +from collections import defaultdict +from decimal import Decimal +from io import BytesIO +from itertools import groupby +from typing import Tuple + +import bleach +import vat_moss.exchange_rates +from bidi import get_display +from django.contrib.staticfiles import finders +from django.db.models import Sum +from django.dispatch import receiver +from django.utils.formats import date_format, localize +from django.utils.translation import ( + get_language, gettext, gettext_lazy, pgettext, +) +from reportlab.lib import colors, pagesizes +from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT +from reportlab.lib.styles import ParagraphStyle, StyleSheet1 +from reportlab.lib.units import mm +from reportlab.pdfbase import pdfmetrics +from reportlab.pdfbase.pdfmetrics import stringWidth +from reportlab.pdfbase.ttfonts import TTFont +from reportlab.pdfgen.canvas import Canvas +from reportlab.platypus import ( + BaseDocTemplate, Flowable, Frame, KeepTogether, NextPageTemplate, + PageTemplate, Spacer, Table, TableStyle, +) + +from pretix.base.decimal import round_decimal +from pretix.base.models import Event, Invoice, Order, OrderPayment +from pretix.base.services.currencies import SOURCE_NAMES +from pretix.base.signals import register_invoice_renderers +from pretix.base.templatetags.money import money_filter +from pretix.helpers.reportlab import ( + FontFallbackParagraph, ThumbnailingImageReader, reshaper, +) +from pretix.presale.style import get_fonts + +logger = logging.getLogger(__name__) + + +def addon_aware_groupby(iterable, key, is_addon): + """ + We use groupby() to visually group identical lines on an invoice. For example, instead of + + Product 1 5.00 EUR + Product 1 5.00 EUR + Product 1 5.00 EUR + Product 2 7.00 EUR + + We want to print + + 3x Product 1 5.00 EUR = 15.00 EUR + Product 2 7.00 EUR + + However, this fails for setups with addon-products since groupby() only groups consecutive + lines with the same identity. So in + + Product 1 5.00 EUR + + Addon 1 2.00 EUR + Product 1 5.00 EUR + + Addon 1 2.00 EUR + Product 1 5.00 EUR + + Addon 2 3.00 EUR + + There is no consecutive repetition of the same entity. This function provides a specialised groupby which + understands the product/addon relationship and packs groups of these addons together if they are, in fact, + identical groups: + + 2x Product 1 5.00 EUR = 10.00 EUR + + 2x Addon 1 2.00 EUR = 4.00 EUR + Product 1 5.00 EUR + + Addon 2 3.00 EUR + """ + packed_groups = [] + + for i in iterable: + if is_addon(i): + packed_groups[-1].append(i) + else: + packed_groups.append([i]) + # Each packed_groups element contains a list with the parent product as first element, and any addon products following + + def _reorder(packed_groups): + # Emit the products as individual products again, reordered by "all parent products, then all addon products" + # within each group. + for _, repeated_groups in groupby(packed_groups, key=lambda g: tuple(key(a) for a in g)): + for repeated_items in zip(*repeated_groups): + yield from repeated_items + + return groupby(_reorder(packed_groups), key) + + +class NumberedCanvas(Canvas): + def __init__(self, *args, **kwargs): + self.font_regular = kwargs.pop('font_regular') + super().__init__(*args, **kwargs) + self._saved_page_states = [] + + def showPage(self): + self._saved_page_states.append(dict(self.__dict__)) + self._startPage() + + def save(self): + num_pages = len(self._saved_page_states) + for state in self._saved_page_states: + self.__dict__.update(state) + self.draw_page_number(num_pages) + Canvas.showPage(self) + Canvas.save(self) + + def draw_page_number(self, page_count): + self.saveState() + self.setFont(self.font_regular, 8) + text = pgettext("invoice", "Page %d of %d") % (self._pageNumber, page_count,) + try: + text = get_display(reshaper.reshape(text)) + except: + logger.exception('Reshaping/Bidi fixes failed on string {}'.format(repr(text))) + self.drawRightString(self._pagesize[0] - 20 * mm, 10 * mm, text) + self.restoreState() + + +class BaseInvoiceRenderer: + """ + This is the base class for all invoice renderers. + """ + + def __init__(self, event: Event): + self.event = event + + def __str__(self): + return self.identifier + + def generate(self, invoice: Invoice) -> Tuple[str, str, str]: + """ + This method should generate the invoice file and return a tuple consisting of a + filename, a file type and file content. The extension will be taken from the filename + which is otherwise ignored. + """ + raise NotImplementedError() + + @property + def verbose_name(self) -> str: + """ + A human-readable name for this renderer. This should be short but + self-explanatory. Good examples include 'German DIN 5008' or 'Italian invoice'. + """ + raise NotImplementedError() # NOQA + + @property + def identifier(self) -> str: + """ + A short and unique identifier for this renderer. + This should only contain lowercase letters and in most + cases will be the same as your package name. + """ + raise NotImplementedError() # NOQA + + +class BaseReportlabInvoiceRenderer(BaseInvoiceRenderer): + """ + This is a convenience class to avoid duplicate code when implementing invoice renderers + that are based on reportlab. + """ + pagesize = pagesizes.A4 + left_margin = 25 * mm + right_margin = 20 * mm + top_margin = 20 * mm + bottom_margin = 15 * mm + doc_template_class = BaseDocTemplate + canvas_class = Canvas + font_regular = 'OpenSans' + font_bold = 'OpenSansBd' + + def _init(self): + """ + Initialize the renderer. By default, this registers fonts and sets ``self.stylesheet``. + """ + self._register_fonts() + self.stylesheet = self._get_stylesheet() + + def _get_stylesheet(self): + """ + Get a stylesheet. By default, this contains the "Normal" and "Heading1" styles. + """ + stylesheet = StyleSheet1() + stylesheet.add(ParagraphStyle(name='Normal', fontName=self.font_regular, fontSize=10, leading=12)) + stylesheet.add(ParagraphStyle(name='Bold', fontName=self.font_bold, fontSize=10, leading=12)) + stylesheet.add(ParagraphStyle(name='BoldRight', fontName=self.font_bold, fontSize=10, leading=12, alignment=TA_RIGHT)) + stylesheet.add(ParagraphStyle(name='BoldRightNoSplit', fontName=self.font_bold, fontSize=10, leading=12, alignment=TA_RIGHT, + splitLongWords=False)) + stylesheet.add(ParagraphStyle(name='NormalRight', fontName=self.font_regular, fontSize=10, leading=12, alignment=TA_RIGHT)) + stylesheet.add(ParagraphStyle(name='BoldInverseCenter', fontName=self.font_bold, fontSize=10, leading=12, + textColor=colors.white, alignment=TA_CENTER)) + stylesheet.add(ParagraphStyle(name='InvoiceFrom', parent=stylesheet['Normal'])) + stylesheet.add(ParagraphStyle(name='Heading1', fontName=self.font_bold, fontSize=15, leading=15 * 1.2)) + stylesheet.add(ParagraphStyle(name='FineprintHeading', fontName=self.font_bold, fontSize=8, leading=12)) + stylesheet.add(ParagraphStyle(name='Fineprint', fontName=self.font_regular, fontSize=8, leading=10)) + stylesheet.add(ParagraphStyle(name='FineprintRight', fontName=self.font_regular, fontSize=8, leading=10, alignment=TA_RIGHT)) + return stylesheet + + def _register_fonts(self): + """ + Register fonts with reportlab. By default, this registers the OpenSans font family + """ + pdfmetrics.registerFont(TTFont('OpenSans', finders.find('fonts/OpenSans-Regular.ttf'))) + pdfmetrics.registerFont(TTFont('OpenSansIt', finders.find('fonts/OpenSans-Italic.ttf'))) + pdfmetrics.registerFont(TTFont('OpenSansBd', finders.find('fonts/OpenSans-Bold.ttf'))) + pdfmetrics.registerFont(TTFont('OpenSansBI', finders.find('fonts/OpenSans-BoldItalic.ttf'))) + pdfmetrics.registerFontFamily('OpenSans', normal='OpenSans', bold='OpenSansBd', + italic='OpenSansIt', boldItalic='OpenSansBI') + + for family, styles in get_fonts(event=self.event, pdf_support_required=True).items(): + pdfmetrics.registerFont(TTFont(family, finders.find(styles['regular']['truetype']))) + if family == self.event.settings.invoice_renderer_font: + self.font_regular = family + if 'bold' in styles: + self.font_bold = family + ' B' + if 'italic' in styles: + pdfmetrics.registerFont(TTFont(family + ' I', finders.find(styles['italic']['truetype']))) + if 'bold' in styles: + pdfmetrics.registerFont(TTFont(family + ' B', finders.find(styles['bold']['truetype']))) + if 'bolditalic' in styles: + pdfmetrics.registerFont(TTFont(family + ' B I', finders.find(styles['bolditalic']['truetype']))) + + def _normalize(self, text): + # reportlab does not support unicode combination characters + # It's important we do this before we use ArabicReshaper + text = unicodedata.normalize("NFKC", text) + + # reportlab does not support RTL, ligature-heavy scripts like Arabic. Therefore, we use ArabicReshaper + # to resolve all ligatures and python-bidi to switch RTL texts. + try: + text = "
".join(get_display(reshaper.reshape(l)) for l in re.split("
", text)) + except: + logger.exception('Reshaping/Bidi fixes failed on string {}'.format(repr(text))) + + return text + + def _upper(self, val): + # We uppercase labels, but not in every language + if get_language().startswith('el'): + return val + return val.upper() + + def _on_other_page(self, canvas: Canvas, doc): + """ + Called when a new page is rendered that is *not* the first page. + """ + pass + + def _on_first_page(self, canvas: Canvas, doc): + """ + Called when a new page is rendered that is the first page. + """ + pass + + def _get_story(self, doc): + """ + Called to create the story to be inserted into the main frames. + """ + raise NotImplementedError() + + def _get_first_page_frames(self, doc): + """ + Called to create a list of frames for the first page. + """ + return [ + Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - 75 * mm, + leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, + id='normal') + ] + + def _get_other_page_frames(self, doc): + """ + Called to create a list of frames for the other pages. + """ + return [ + Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, + leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=0, + id='normal') + ] + + def _build_doc(self, fhandle): + """ + Build a PDF document in a given file handle + """ + self._init() + doc = self.doc_template_class(fhandle, pagesize=self.pagesize, + leftMargin=self.left_margin, rightMargin=self.right_margin, + topMargin=self.top_margin, bottomMargin=self.bottom_margin) + + doc.addPageTemplates([ + PageTemplate( + id='FirstPage', + frames=self._get_first_page_frames(doc), + onPage=self._on_first_page, + pagesize=self.pagesize + ), + PageTemplate( + id='OtherPages', + frames=self._get_other_page_frames(doc), + onPage=self._on_other_page, + pagesize=self.pagesize + ) + ]) + story = self._get_story(doc) + doc.build(story, canvasmaker=self.canvas_class) + return doc + + def generate(self, invoice: Invoice): + self.invoice = invoice + buffer = BytesIO() + self._build_doc(buffer) + buffer.seek(0) + return 'invoice.pdf', 'application/pdf', buffer.read() + + def _clean_text(self, text, tags=None): + return self._normalize(bleach.clean( + text, + tags=set(tags) if tags else set() + ).strip().replace('
', '
').replace('\n', '
\n')) + + +class PaidMarker(Flowable): + def __init__(self, text='paid', color=None, font='OpenSansBd', size=20): + super().__init__() + self.text = text + self.color = color + self.font = font + self.size = size + self._showBoundary = True + + def wrap(self, availwidth, availheight): + # Fake a size, we don't care if we exceed the table + return 10, self.size / 2 + + def draw(self): + self.canv.translate(0, - self.size / 2) + self.canv.rotate(2) + self.canv.setFont(self.font, self.size) + self.canv.setFillColor(self.color) + width = self.canv.stringWidth(self.text, self.font, self.size) + self.canv.drawRightString(0, 0, self.text) + + self.canv.setStrokeColor(self.color) + self.canv.roundRect(-width - self.size / 2, -self.size / 4, width + self.size, self.size + self.size / 4, 3) + + +class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer): + identifier = 'classic' + verbose_name = pgettext('invoice', 'Classic renderer (pretix 1.0)') + + def canvas_class(self, *args, **kwargs): + kwargs['font_regular'] = self.font_regular + return NumberedCanvas(*args, **kwargs) + + def _on_other_page(self, canvas: Canvas, doc): + canvas.saveState() + canvas.setFont(self.font_regular, 8) + + for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): + canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, self._normalize(line.strip())) + + canvas.restoreState() + + invoice_to_width = 85 * mm + invoice_to_height = 50 * mm + invoice_to_left = 25 * mm + invoice_to_top = 52 * mm + + def _draw_invoice_to(self, canvas): + p = FontFallbackParagraph(self._clean_text(self.invoice.address_invoice_to), + style=self.stylesheet['Normal']) + p.wrapOn(canvas, self.invoice_to_width, self.invoice_to_height) + p_size = p.wrap(self.invoice_to_width, self.invoice_to_height) + p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - p_size[1] - self.invoice_to_top) + + invoice_from_width = 70 * mm + invoice_from_height = 50 * mm + invoice_from_left = 25 * mm + invoice_from_top = 17 * mm + + def _draw_invoice_from(self, canvas): + p = FontFallbackParagraph( + self._clean_text(self.invoice.full_invoice_from), + style=self.stylesheet['InvoiceFrom'] + ) + p.wrapOn(canvas, self.invoice_from_width, self.invoice_from_height) + p_size = p.wrap(self.invoice_from_width, self.invoice_from_height) + p.drawOn(canvas, self.invoice_from_left, self.pagesize[1] - p_size[1] - self.invoice_from_top) + + def _draw_invoice_from_label(self, canvas): + textobject = canvas.beginText(25 * mm, (297 - 15) * mm) + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice from')))) + canvas.drawText(textobject) + + def _draw_invoice_to_label(self, canvas): + textobject = canvas.beginText(25 * mm, (297 - 50) * mm) + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice to')))) + canvas.drawText(textobject) + + logo_width = 25 * mm + logo_height = 25 * mm + logo_left = 95 * mm + logo_top = 13 * mm + logo_anchor = 'n' + + def _draw_logo(self, canvas): + if self.invoice.event.settings.invoice_logo_image: + logo_file = self.invoice.event.settings.get('invoice_logo_image', binary_file=True) + ir = ThumbnailingImageReader(logo_file) + try: + ir.resize(self.logo_width, self.logo_height, 300) + except: + logger.exception("Can not resize image") + pass + try: + # Valid ZUGFeRD invoices must be compliant with PDF/A-3. pretix-zugferd ensures this by passing them + # through ghost script. Unfortunately, if the logo contains transparency, this will still fail. + # I was unable to figure out a way to fix this in GhostScript, so the easy fix is to remove the + # transparency, as our invoices always have a white background anyways. + ir.remove_transparency() + except: + logger.exception("Can not remove transparency from logo") + pass + canvas.drawImage(ir, + self.logo_left, + self.pagesize[1] - self.logo_height - self.logo_top, + width=self.logo_width, height=self.logo_height, + preserveAspectRatio=True, anchor=self.logo_anchor, + mask='auto') + + def _draw_metadata(self, canvas): + textobject = canvas.beginText(125 * mm, (297 - 38) * mm) + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Order code')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(self.invoice.order.full_code)) + canvas.drawText(textobject) + + textobject = canvas.beginText(125 * mm, (297 - 50) * mm) + textobject.setFont(self.font_bold, 8) + if self.invoice.is_cancellation: + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Cancellation number')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(self.invoice.number)) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Original invoice')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(self.invoice.refers.number)) + else: + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice number')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(self.invoice.number)) + textobject.moveCursor(0, 5) + + if self.invoice.is_cancellation: + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Cancellation date')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(date_format(self.invoice.date, "DATE_FORMAT"))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Original invoice date')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(date_format(self.invoice.refers.date, "DATE_FORMAT"))) + textobject.moveCursor(0, 5) + else: + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Invoice date')))) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_regular, 10) + textobject.textLine(self._normalize(date_format(self.invoice.date, "DATE_FORMAT"))) + textobject.moveCursor(0, 5) + + canvas.drawText(textobject) + + event_left = 125 * mm + event_top = 17 * mm + event_width = 65 * mm + event_height = 50 * mm + + def _draw_event_label(self, canvas): + textobject = canvas.beginText(125 * mm, (297 - 15) * mm) + textobject.setFont(self.font_bold, 8) + textobject.textLine(self._normalize(self._upper(pgettext('invoice', 'Event')))) + canvas.drawText(textobject) + + def _draw_event(self, canvas): + def shorten(txt): + txt = str(txt) + txt = bleach.clean(txt, tags=set()).strip() + p = FontFallbackParagraph(self._normalize(txt.strip().replace('\n', '
\n')), style=self.stylesheet['Normal']) + p_size = p.wrap(self.event_width, self.event_height) + + while p_size[1] > 2 * self.stylesheet['Normal'].leading: + txt = ' '.join(txt.replace('…', '').split()[:-1]) + '…' + p = FontFallbackParagraph(self._normalize(txt.strip().replace('\n', '
\n')), style=self.stylesheet['Normal']) + p_size = p.wrap(self.event_width, self.event_height) + return txt + + if not self.invoice.event.has_subevents and self.invoice.event.settings.show_dates_on_frontpage: + tz = self.invoice.event.timezone + show_end_date = ( + self.invoice.event.settings.show_date_to and + self.invoice.event.date_to and + self.invoice.event.date_to.astimezone(tz).date() != self.invoice.event.date_from.astimezone(tz).date() + ) + if show_end_date: + p_str = ( + shorten(self.invoice.event.name) + '\n' + + pgettext('invoice', '{from_date}\nuntil {to_date}').format( + from_date=self.invoice.event.get_date_from_display(show_times=False), + to_date=self.invoice.event.get_date_to_display(show_times=False) + ) + ) + else: + p_str = ( + shorten(self.invoice.event.name) + '\n' + self.invoice.event.get_date_from_display(show_times=False) + ) + else: + p_str = shorten(self.invoice.event.name) + + p = FontFallbackParagraph(self._normalize(p_str.strip().replace('\n', '
\n')), style=self.stylesheet['Normal']) + p.wrapOn(canvas, self.event_width, self.event_height) + p_size = p.wrap(self.event_width, self.event_height) + p.drawOn(canvas, self.event_left, self.pagesize[1] - self.event_top - p_size[1]) + self._draw_event_label(canvas) + + def _draw_footer(self, canvas): + canvas.setFont(self.font_regular, 8) + for i, line in enumerate(self.invoice.footer_text.split('\n')[::-1]): + canvas.drawCentredString(self.pagesize[0] / 2, 25 + (3.5 * i) * mm, self._normalize(line.strip())) + + def _draw_testmode(self, canvas): + if self.invoice.order.testmode: + canvas.saveState() + canvas.setFont(self.font_bold, 30) + canvas.setFillColorRGB(32, 0, 0) + canvas.drawRightString(self.pagesize[0] - 20 * mm, (297 - 100) * mm, self._normalize(gettext('TEST MODE'))) + canvas.restoreState() + + def _on_first_page(self, canvas: Canvas, doc): + canvas.setCreator('pretix.eu') + canvas.setTitle(pgettext('invoice', 'Invoice {num}').format(num=self.invoice.number)) + + canvas.saveState() + self._draw_footer(canvas) + self._draw_testmode(canvas) + self._draw_invoice_from_label(canvas) + self._draw_invoice_from(canvas) + self._draw_invoice_to_label(canvas) + self._draw_invoice_to(canvas) + self._draw_metadata(canvas) + self._draw_logo(canvas) + self._draw_event(canvas) + canvas.restoreState() + + def _get_first_page_frames(self, doc): + footer_length = 3.5 * len(self.invoice.footer_text.split('\n')) * mm + return [ + Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - 75 * mm, + leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=footer_length, + id='normal') + ] + + def _get_other_page_frames(self, doc): + footer_length = 3.5 * len(self.invoice.footer_text.split('\n')) * mm + return [ + Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, + leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=footer_length, + id='normal') + ] + + def _get_intro(self): + story = [] + if self.invoice.custom_field: + story.append(FontFallbackParagraph( + '{}: {}'.format( + self._clean_text(str(self.invoice.event.settings.invoice_address_custom_field)), + self._clean_text(self.invoice.custom_field), + ), + self.stylesheet['Normal'] + )) + + if self.invoice.internal_reference: + story.append(FontFallbackParagraph( + self._normalize(pgettext('invoice', 'Customer reference: {reference}').format( + reference=self._clean_text(self.invoice.internal_reference), + )), + self.stylesheet['Normal'] + )) + + if self.invoice.invoice_to_vat_id: + story.append(FontFallbackParagraph( + self._normalize(pgettext('invoice', 'Customer VAT ID')) + ': ' + + self._clean_text(self.invoice.invoice_to_vat_id), + self.stylesheet['Normal'] + )) + + if self.invoice.invoice_to_beneficiary: + story.append(FontFallbackParagraph( + self._normalize(pgettext('invoice', 'Beneficiary')) + ':
' + + self._clean_text(self.invoice.invoice_to_beneficiary), + self.stylesheet['Normal'] + )) + + if self.invoice.introductory_text: + # While all intro fields are appended without any blank lines; we do want one before the optional intro + # text. However, if there are no prior intro fields, adding an additional spacer will waste space. + if story: + story.append(Spacer(1, 5 * mm)) + + story.append(FontFallbackParagraph( + self._clean_text(self.invoice.introductory_text, tags=['br']), + self.stylesheet['Normal'] + )) + story.append(Spacer(1, 5 * mm)) + + return story + + def _get_story(self, doc): + has_taxes = any(il.tax_value for il in self.invoice.lines.all()) or self.invoice.reverse_charge + + story = [ + NextPageTemplate('FirstPage'), + FontFallbackParagraph( + self._normalize( + pgettext('invoice', 'Tax Invoice') if str(self.invoice.invoice_from_country) == 'AU' + else pgettext('invoice', 'Invoice') + ) if not self.invoice.is_cancellation else self._normalize(pgettext('invoice', 'Cancellation')), + self.stylesheet['Heading1'] + ), + Spacer(1, 5 * mm), + NextPageTemplate('OtherPages'), + ] + story += self._get_intro() + + taxvalue_map = defaultdict(Decimal) + grossvalue_map = defaultdict(Decimal) + + tstyledata = [ + ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), + ('VALIGN', (0, 0), (-1, -1), 'TOP'), + ('FONTNAME', (0, 0), (-1, -1), self.font_regular), + ('FONTNAME', (0, 0), (-1, 0), self.font_bold), + ('FONTNAME', (0, -1), (-1, -1), self.font_bold), + ('LEFTPADDING', (0, 0), (0, -1), 0), + ('RIGHTPADDING', (-1, 0), (-1, -1), 0), + ] + if has_taxes: + tdata = [( + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Description')), self.stylesheet['Bold']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Qty')), self.stylesheet['BoldRightNoSplit']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Tax rate')), self.stylesheet['BoldRightNoSplit']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Net')), self.stylesheet['BoldRightNoSplit']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Gross')), self.stylesheet['BoldRightNoSplit']), + )] + else: + tdata = [( + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Description')), self.stylesheet['Bold']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Qty')), self.stylesheet['BoldRightNoSplit']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Amount')), self.stylesheet['BoldRightNoSplit']), + )] + + def _group_key(line): + return (line.description, line.tax_rate, line.tax_name, line.net_value, line.gross_value, line.subevent_id, + line.event_date_from, line.event_date_to) + + total = Decimal('0.00') + for (description, tax_rate, tax_name, net_value, gross_value, *ignored), lines in addon_aware_groupby( + self.invoice.lines.all(), + key=_group_key, + is_addon=lambda l: l.description.startswith(" +"), + ): + lines = list(lines) + if has_taxes: + if len(lines) > 1: + single_price_line = pgettext('invoice', 'Single price: {net_price} net / {gross_price} gross').format( + net_price=money_filter(net_value, self.invoice.event.currency), + gross_price=money_filter(gross_value, self.invoice.event.currency), + ) + description = description + "\n" + single_price_line + tdata.append(( + FontFallbackParagraph( + self._clean_text(description, tags=['br']), + self.stylesheet['Normal'] + ), + str(len(lines)), + localize(tax_rate) + " %", + FontFallbackParagraph( + money_filter(net_value * len(lines), self.invoice.event.currency).replace('\xa0', ' '), + self.stylesheet['NormalRight'] + ), + FontFallbackParagraph( + money_filter(gross_value * len(lines), self.invoice.event.currency).replace('\xa0', ' '), + self.stylesheet['NormalRight'] + ), + )) + else: + if len(lines) > 1: + single_price_line = pgettext('invoice', 'Single price: {price}').format( + price=money_filter(gross_value, self.invoice.event.currency), + ) + description = description + "\n" + single_price_line + tdata.append(( + FontFallbackParagraph( + self._clean_text(description, tags=['br']), + self.stylesheet['Normal'] + ), + str(len(lines)), + FontFallbackParagraph( + money_filter(gross_value * len(lines), self.invoice.event.currency).replace('\xa0', ' '), + self.stylesheet['NormalRight'] + ), + )) + taxvalue_map[tax_rate, tax_name] += (gross_value - net_value) * len(lines) + grossvalue_map[tax_rate, tax_name] += gross_value * len(lines) + total += gross_value * len(lines) + + if has_taxes: + tdata.append([ + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Invoice total')), self.stylesheet['Bold']), '', '', '', + money_filter(total, self.invoice.event.currency) + ]) + colwidths = [a * doc.width for a in (.50, .05, .15, .15, .15)] + else: + tdata.append([ + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Invoice total')), self.stylesheet['Bold']), '', + money_filter(total, self.invoice.event.currency) + ]) + colwidths = [a * doc.width for a in (.65, .20, .15)] + + if not self.invoice.is_cancellation: + if self.invoice.event.settings.invoice_show_payments and self.invoice.order.status == Order.STATUS_PENDING: + pending_sum = self.invoice.order.pending_sum + if pending_sum != total: + tdata.append( + [FontFallbackParagraph(self._normalize(pgettext('invoice', 'Received payments')), self.stylesheet['Normal'])] + + (['', '', ''] if has_taxes else ['']) + + [money_filter(pending_sum - total, self.invoice.event.currency)] + ) + tdata.append( + [FontFallbackParagraph(self._normalize(pgettext('invoice', 'Outstanding payments')), self.stylesheet['Bold'])] + + (['', '', ''] if has_taxes else ['']) + + [money_filter(pending_sum, self.invoice.event.currency)] + ) + tstyledata += [ + ('FONTNAME', (0, len(tdata) - 3), (-1, len(tdata) - 3), self.font_bold), + ] + elif self.invoice.event.settings.invoice_show_payments and self.invoice.order.payments.filter( + state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED), provider='giftcard' + ).exists(): + giftcard_sum = self.invoice.order.payments.filter( + state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED), + provider='giftcard' + ).aggregate( + s=Sum('amount') + )['s'] or Decimal('0.00') + tdata.append( + [FontFallbackParagraph(self._normalize(pgettext('invoice', 'Paid by gift card')), self.stylesheet['Normal'])] + + (['', '', ''] if has_taxes else ['']) + + [money_filter(giftcard_sum, self.invoice.event.currency)] + ) + tdata.append( + [FontFallbackParagraph(self._normalize(pgettext('invoice', 'Remaining amount')), self.stylesheet['Bold'])] + + (['', '', ''] if has_taxes else ['']) + + [money_filter(total - giftcard_sum, self.invoice.event.currency)] + ) + tstyledata += [ + ('FONTNAME', (0, len(tdata) - 3), (-1, len(tdata) - 3), self.font_bold), + ] + elif self.invoice.payment_provider_stamp: + pm = PaidMarker( + text=self._normalize(self.invoice.payment_provider_stamp), + color=colors.HexColor(self.event.settings.theme_color_success), + font=self.font_bold, + size=16 + ) + tdata[-1][-2] = pm + + table = Table(tdata, colWidths=colwidths, repeatRows=1) + table.setStyle(TableStyle(tstyledata)) + story.append(table) + + story.append(Spacer(1, 10 * mm)) + + if self.invoice.payment_provider_text: + story.append(FontFallbackParagraph( + self._normalize(self.invoice.payment_provider_text), + self.stylesheet['Normal'] + )) + + if self.invoice.payment_provider_text and self.invoice.additional_text: + story.append(Spacer(1, 3 * mm)) + + if self.invoice.additional_text: + story.append(FontFallbackParagraph( + self._clean_text(self.invoice.additional_text, tags=['br']), + self.stylesheet['Normal'] + )) + story.append(Spacer(1, 5 * mm)) + + tstyledata = [ + ('ALIGN', (1, 0), (-1, -1), 'RIGHT'), + ('LEFTPADDING', (0, 0), (0, -1), 0), + ('RIGHTPADDING', (-1, 0), (-1, -1), 0), + ('TOPPADDING', (0, 0), (-1, -1), 1), + ('BOTTOMPADDING', (0, 0), (-1, -1), 1), + ('FONTSIZE', (0, 0), (-1, -1), 8), + ('FONTNAME', (0, 0), (-1, -1), self.font_regular), + ] + thead = [ + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Tax rate')), self.stylesheet['Fineprint']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Net value')), self.stylesheet['FineprintRight']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Gross value')), self.stylesheet['FineprintRight']), + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Tax')), self.stylesheet['FineprintRight']), + '' + ] + tdata = [thead] + + for idx, gross in grossvalue_map.items(): + rate, name = idx + if rate == 0 and gross == 0: + continue + tax = taxvalue_map[idx] + tdata.append([ + FontFallbackParagraph(self._normalize(localize(rate) + " % " + name), self.stylesheet['Fineprint']), + money_filter(gross - tax, self.invoice.event.currency), + money_filter(gross, self.invoice.event.currency), + money_filter(tax, self.invoice.event.currency), + '' + ]) + + def fmt(val): + try: + return vat_moss.exchange_rates.format(val, self.invoice.foreign_currency_display) + except ValueError: + return localize(val) + ' ' + self.invoice.foreign_currency_display + + if any(rate != 0 and gross != 0 for (rate, name), gross in grossvalue_map.items()) and has_taxes: + colwidths = [a * doc.width for a in (.25, .15, .15, .15, .3)] + table = Table(tdata, colWidths=colwidths, repeatRows=2, hAlign=TA_LEFT) + table.setStyle(TableStyle(tstyledata)) + story.append(Spacer(5 * mm, 5 * mm)) + story.append(KeepTogether([ + FontFallbackParagraph(self._normalize(pgettext('invoice', 'Included taxes')), self.stylesheet['FineprintHeading']), + table + ])) + + if self.invoice.foreign_currency_display and self.invoice.foreign_currency_rate: + tdata = [thead] + + for idx, gross in grossvalue_map.items(): + rate, name = idx + if rate == 0: + continue + tax = taxvalue_map[idx] + gross = round_decimal(gross * self.invoice.foreign_currency_rate) + tax = round_decimal(tax * self.invoice.foreign_currency_rate) + net = gross - tax + + tdata.append([ + FontFallbackParagraph(self._normalize(localize(rate) + " % " + name), self.stylesheet['Fineprint']), + fmt(net), fmt(gross), fmt(tax), '' + ]) + + table = Table(tdata, colWidths=colwidths, repeatRows=2, hAlign=TA_LEFT) + table.setStyle(TableStyle(tstyledata)) + + story.append(KeepTogether([ + Spacer(1, height=2 * mm), + FontFallbackParagraph( + self._normalize(pgettext( + 'invoice', 'Using the conversion rate of 1:{rate} as published by the {authority} on ' + '{date}, this corresponds to:' + ).format(rate=localize(self.invoice.foreign_currency_rate), + authority=SOURCE_NAMES.get(self.invoice.foreign_currency_source, "?"), + date=date_format(self.invoice.foreign_currency_rate_date, "SHORT_DATE_FORMAT"))), + self.stylesheet['Fineprint'] + ), + Spacer(1, height=3 * mm), + table + ])) + elif self.invoice.foreign_currency_display and self.invoice.foreign_currency_rate: + foreign_total = round_decimal(total * self.invoice.foreign_currency_rate) + story.append(Spacer(1, 5 * mm)) + story.append(FontFallbackParagraph(self._normalize( + pgettext( + 'invoice', 'Using the conversion rate of 1:{rate} as published by the {authority} on ' + '{date}, the invoice total corresponds to {total}.' + ).format(rate=localize(self.invoice.foreign_currency_rate), + date=date_format(self.invoice.foreign_currency_rate_date, "SHORT_DATE_FORMAT"), + authority=SOURCE_NAMES.get(self.invoice.foreign_currency_source, "?"), + total=fmt(foreign_total))), + self.stylesheet['Fineprint'] + )) + + return story + + +class Modern1Renderer(ClassicInvoiceRenderer): + identifier = 'modern1' + verbose_name = gettext_lazy('Default invoice renderer (European-style letter)') + bottom_margin = 16.9 * mm + top_margin = 16.9 * mm + right_margin = 20 * mm + invoice_to_height = 27.3 * mm + invoice_to_width = 80 * mm + invoice_to_left = 25 * mm + invoice_to_top = (40 + 17.7) * mm + invoice_from_left = 125 * mm + invoice_from_top = 50 * mm + invoice_from_width = pagesizes.A4[0] - invoice_from_left - right_margin + invoice_from_height = 50 * mm + + logo_width = 75 * mm + logo_height = 25 * mm + logo_left = pagesizes.A4[0] - logo_width - right_margin + logo_top = top_margin + logo_anchor = 'e' + + event_left = 25 * mm + event_top = top_margin + event_width = 80 * mm + event_height = 25 * mm + + def _get_stylesheet(self): + stylesheet = super()._get_stylesheet() + stylesheet.add(ParagraphStyle(name='Sender', fontName=self.font_regular, fontSize=8, leading=10)) + stylesheet['InvoiceFrom'].alignment = TA_RIGHT + return stylesheet + + def _draw_invoice_from(self, canvas): + if not self.invoice.invoice_from: + return + c = [ + self._clean_text(l) + for l in self.invoice.address_invoice_from.strip().split('\n') + ] + p = FontFallbackParagraph(self._normalize(' · '.join(c)), style=self.stylesheet['Sender']) + p.wrapOn(canvas, self.invoice_to_width, 15.7 * mm) + p.drawOn(canvas, self.invoice_to_left, self.pagesize[1] - self.invoice_to_top + 2 * mm) + super()._draw_invoice_from(canvas) + + def _draw_invoice_to_label(self, canvas): + pass + + def _draw_invoice_from_label(self, canvas): + pass + + def _draw_event_label(self, canvas): + pass + + def _get_first_page_frames(self, doc): + footer_length = 3.5 * len(self.invoice.footer_text.split('\n')) * mm + if self.event.settings.invoice_renderer_highlight_order_code: + margin_top = 100 * mm + else: + margin_top = 95 * mm + return [ + Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height - margin_top, + leftPadding=0, rightPadding=0, topPadding=0, bottomPadding=footer_length, + id='normal') + ] + + def _draw_metadata(self, canvas): + # Draws the "invoice number -- date" line. This has gotten a little more complicated since we + # encountered some events with very long invoice numbers. In this case, we automatically reduce + # the font size until it fits. + begin_top = 100 * mm + + def _draw(label, value, value_size, x, width, bold=False, sublabel=None): + if canvas.stringWidth(value, self.font_regular, value_size) > width and value_size > 6: + return False + textobject = canvas.beginText(x, self.pagesize[1] - begin_top) + textobject.setFont(self.font_regular, 8) + textobject.textLine(self._normalize(label)) + textobject.moveCursor(0, 5) + textobject.setFont(self.font_bold if bold else self.font_regular, value_size) + textobject.textLine(self._normalize(value)) + + if sublabel: + textobject.moveCursor(0, 1) + textobject.setFont(self.font_regular, 8) + textobject.textLine(self._normalize(sublabel)) + + return textobject + + value_size = 10 + while value_size >= 5: + if self.event.settings.invoice_renderer_highlight_order_code: + kwargs = dict(bold=True, sublabel=pgettext('invoice', '(Please quote at all times.)')) + else: + kwargs = {} + objects = [ + _draw(pgettext('invoice', 'Order code'), self.invoice.order.full_code, value_size, self.left_margin, 45 * mm, **kwargs) + ] + + p = FontFallbackParagraph( + self._normalize(date_format(self.invoice.date, "DATE_FORMAT")), + style=ParagraphStyle(name=f'Normal{value_size}', fontName=self.font_regular, fontSize=value_size, leading=value_size * 1.2) + ) + w = stringWidth(p.text, p.frags[0].fontName, p.frags[0].fontSize) + p.wrapOn(canvas, w, 15 * mm) + date_x = self.pagesize[0] - w - self.right_margin + + if self.invoice.is_cancellation: + objects += [ + _draw(pgettext('invoice', 'Cancellation number'), self.invoice.number, + value_size, self.left_margin + 50 * mm, 45 * mm), + _draw(pgettext('invoice', 'Original invoice'), self.invoice.refers.number, + value_size, self.left_margin + 100 * mm, date_x - self.left_margin - 100 * mm - 5 * mm), + ] + else: + objects += [ + _draw(pgettext('invoice', 'Invoice number'), self.invoice.number, + value_size, self.left_margin + 70 * mm, date_x - self.left_margin - 70 * mm - 5 * mm), + ] + + if all(objects): + for o in objects: + canvas.drawText(o) + break + value_size -= 1 + + p.drawOn(canvas, date_x, self.pagesize[1] - begin_top - 10 - 6) + + textobject = canvas.beginText(date_x, self.pagesize[1] - begin_top) + textobject.setFont(self.font_regular, 8) + if self.invoice.is_cancellation: + textobject.textLine(self._normalize(pgettext('invoice', 'Cancellation date'))) + else: + textobject.textLine(self._normalize(pgettext('invoice', 'Invoice date'))) + canvas.drawText(textobject) + + +class Modern1SimplifiedRenderer(Modern1Renderer): + identifier = 'modern1simplified' + verbose_name = gettext_lazy('Simplified invoice renderer') + + logo_left = Modern1Renderer.left_margin + logo_width = pagesizes.A4[0] - Modern1Renderer.right_margin - logo_left + logo_height = 25 * mm + logo_top = 13 * mm + logo_anchor = 'nw' + + def _draw_invoice_from(self, canvas): + super(Modern1Renderer, self)._draw_invoice_from(canvas) + + def _draw_event(self, canvas): + pass + + def _get_intro(self): + i = [] + + if not self.invoice.event.has_subevents and self.invoice.event.settings.show_dates_on_frontpage: + i.append(FontFallbackParagraph( + pgettext('invoice', 'Event date: {date_range}').format( + date_range=self.invoice.event.get_date_range_display(), + ), + self.stylesheet['Normal'], + )) + i.append(Spacer(2 * mm, 2 * mm)) + + return i + super()._get_intro() + + +@receiver(register_invoice_renderers, dispatch_uid="invoice_renderer_classic") +def recv_classic(sender, **kwargs): + return [ClassicInvoiceRenderer, Modern1Renderer, Modern1SimplifiedRenderer] diff --git a/src/pretix/base/invoicing/peppol.py b/src/pretix/base/invoicing/peppol.py new file mode 100644 index 000000000..805080590 --- /dev/null +++ b/src/pretix/base/invoicing/peppol.py @@ -0,0 +1,167 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +import re + +from django import forms +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ +from django_countries.fields import Country + +from pretix.base.invoicing.transmission import ( + TransmissionType, transmission_types, +) + + +class PeppolIdValidator: + regex_rules = { + # Source: https://docs.peppol.eu/edelivery/codelists/old/v8.5/Peppol%20Code%20Lists%20-%20Participant%20identifier%20schemes%20v8.5.html + "0002": "[0-9]{9}([0-9]{5})?", + "0007": "[0-9]{10}", + "0009": "[0-9]{14}", + "0037": "(0037)?[0-9]{7}-?[0-9][0-9A-Z]{0,5}", + "0060": "[0-9]{9}", + "0088": "[0-9]{13}", + "0096": "[0-9]{17}", + "0097": "[0-9]{11,16}", + "0106": "[0-9]{17}", + "0130": ".*", + "0135": ".*", + "0142": ".*", + "0151": "[0-9]{11}", + "0183": "CHE[0-9]{9}", + "0184": "DK[0-9]{8}([0-9]{2})?", + "0188": ".*", + "0190": "[0-9]{20}", + "0191": "[1789][0-9]{7}", + "0192": "[0-9]{9}", + "0193": ".{4,50}", + "0195": "[a-z]{2}[a-z]{3}([0-9]{8}|[0-9]{9}|[RST][0-9]{2}[a-z]{2}[0-9]{4})[0-9a-z]", + "0196": "[0-9]{10}", + "0198": "DK[0-9]{8}", + "0199": "[A-Z0-9]{18}[0-9]{2}", + "0020": "[0-9]{9}", + "0201": "[0-9a-zA-Z]{6}", + "0204": "[0-9]{2,12}(-[0-9A-Z]{0,30})?-[0-9]{2}", + "0208": "0[0-9]{9}", + "0209": ".*", + "0210": "[A-Z0-9]+", + "0211": "IT[0-9]{11}", + "0212": "[0-9]{7}-[0-9]", + "0213": "FI[0-9]{8}", + "0205": "[A-Z0-9]+", + "0221": "T[0-9]{13}", + "0230": ".*", + "9901": ".*", + "9902": "[1-9][0-9]{7}", + "9904": "DK[0-9]{8}", + "9909": "NO[0-9]{9}MVA", + "9910": "HU[0-9]{8}", + "9912": "[A-Z]{2}[A-Z0-9]{,20}", + "9913": ".*", + "9914": "ATU[0-9]*", + "9915": "[A-Z][A-Z0-9]*", + "9916": ".*", + "9917": "[0-9]{10}", + "9918": "[A-Z]{2}[0-9]{2}[A-Z-0-9]{11,30}", + "9919": "[A-Z][0-9]{3}[A-Z][0-9]{3}[A-Z]", + "9920": ".*", + "9921": ".*", + "9922": ".*", + "9923": ".*", + "9924": ".*", + "9925": ".*", + "9926": ".*", + "9927": ".*", + "9928": ".*", + "9929": ".*", + "9930": ".*", + "9931": ".*", + "9932": ".*", + "9933": ".*", + "9934": ".*", + "9935": ".*", + "9936": ".*", + "9937": ".*", + "9938": ".*", + "9939": ".*", + "9940": ".*", + "9941": ".*", + "9942": ".*", + "9943": ".*", + "9944": ".*", + "9945": ".*", + "9946": ".*", + "9947": ".*", + "9948": ".*", + "9949": ".*", + "9950": ".*", + "9951": ".*", + "9952": ".*", + "9953": ".*", + "9954": ".*", + "9956": "0[0-9]{9}", + "9957": ".*", + "9959": ".*", + } + + def __call__(self, value): + if ":" not in value: + raise ValidationError(_("A PEPPOL participant ID always starts with a prefix, followed by a colon (:).")) + + prefix, second = value.split(":", 1) + if prefix not in self.regex_rules: + raise ValidationError(_("The PEPPOL participant ID prefix %(number)s is not known to our system. Please " + "reach out to us if you are sure this ID is correct."), params={"number": prefix}) + + if not re.match(self.regex_rules[prefix], second): + raise ValidationError(_("The PEPPOL participant ID does not match the validation rules for the prefix " + "%(number)s. Please reach out to us if you are sure this ID is correct."), + params={"number": prefix}) + return value + + +@transmission_types.new() +class PeppolTransmissionType(TransmissionType): + identifier = "peppol" + verbose_name = "PEPPOL" + priority = 250 + enforce_transmission = True + + def is_available(self, event, country: Country, is_business: bool): + return is_business and super().is_available(event, country, is_business) + + @property + def invoice_address_form_fields(self) -> dict: + return { + "transmission_peppol_participant_id": forms.CharField( + label=_("PEPPOL participant ID"), + validators=[ + PeppolIdValidator(), + ] + ), + } + + def invoice_address_form_fields_required(self, country: Country, is_business: bool): + base = { + "company", "street", "zipcode", "city", "country", + } + return base | {"transmission_peppol_participant_id"} diff --git a/src/pretix/base/invoicing/transmission.py b/src/pretix/base/invoicing/transmission.py new file mode 100644 index 000000000..fd3133569 --- /dev/null +++ b/src/pretix/base/invoicing/transmission.py @@ -0,0 +1,246 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from typing import Optional + +from django_countries.fields import Country + +from pretix.base.models import Invoice, InvoiceAddress +from pretix.base.signals import EventPluginRegistry, Registry + + +class TransmissionType: + @property + def identifier(self) -> str: + """ + A short and unique identifier for this transmission type. + """ + raise NotImplementedError + + @property + def verbose_name(self) -> str: + """ + A human-readable name for this transmission type to be shown internally in the backend. + """ + raise NotImplementedError + + @property + def public_name(self) -> str: + """ + A human-readable name for this transmission type to be shown to the public. + By default, this is the same as ``verbose_name`` + """ + return self.verbose_name + + @property + def priority(self) -> int: + """ + Returns a priority that is used for sorting transmission type. Higher priority means higher up in the list. + Default to 100. Providers with same priority are sorted alphabetically. + """ + return 100 + + @property + def exclusive(self) -> bool: + """ + If a transmission type is exclusive, no other type can be chosen if this type is + available. Use e.g. if a certain transmission type is legally required in a certain + jurisdiction. + """ + return False + + @property + def enforce_transmission(self) -> bool: + """ + If a transmission type enforces transmission, every invoice created with this type will be transferred. + If not, the backend user is in some cases trusted to decide whether or not to transmit it. + """ + return False + + def is_available(self, event, country: Country, is_business: bool) -> bool: + providers = transmission_providers.filter(type=self.identifier, active_in=event) + return any( + provider.is_available(event, country, is_business) + for provider, _ in providers + ) + + def invoice_address_form_fields_required(self, country: Country, is_business: bool): + return set() + + def invoice_address_form_fields_visible(self, country: Country, is_business: bool) -> set: + return set(self.invoice_address_form_fields.keys()) + + def validate_address(self, ia: InvoiceAddress): + pass + + @property + def invoice_address_form_fields(self) -> dict: + """ + Return a set of form fields that **must** be prefixed with ``transmission__``. + """ + return {} + + def form_data_to_transmission_info(self, form_data: dict) -> dict: + return form_data + + def transmission_info_to_form_data(self, transmission_info: dict) -> dict: + return transmission_info + + +class TransmissionProvider: + """ + Base class for a transmission provider. Should NOT hold internal state as the class is only + instantiated once and then shared between events and organizers. + """ + + @property + def identifier(self): + """ + A short and unique identifier for this transmission provider. + This should only contain lowercase letters and underscores. + """ + raise NotImplementedError + + @property + def type(self): + """ + Identifier of the transmission type this provider provides. + """ + raise NotImplementedError + + @property + def verbose_name(self): + """ + A human-readable name for this transmission provider (can be localized). + """ + raise NotImplementedError + + @property + def testmode_supported(self) -> bool: + """ + Whether testmode invoices may be passed to this provider. + """ + return False + + def is_ready(self, event) -> bool: + """ + Return whether this provider has all required configuration to be used in this event. + """ + raise NotImplementedError + + def is_available(self, event, country: Country, is_business: bool) -> bool: + """ + Return whether this provider may be used for an invoice for the given recipient country and address type. + """ + raise NotImplementedError + + def transmit(self, invoice: Invoice): + """ + Transmit the invoice. The invoice passed as a parameter will be in status ``TRANSMISSION_STATUS_INFLIGHT``. + Invoices that stay in this state for more than 24h will be retried automatically. Implementations are expected to: + + - Send the invoice. + + - Update the ``transmission_status`` to `TRANSMISSION_STATUS_COMPLETED` or `TRANSMISSION_STATUS_FAILED` + after sending, as well as ``transmission_info`` with provider-specific data, and ``transmission_date`` to + the date and time of completion. + + - Create a log entry of action type ``pretix.event.order.invoice.sent`` or + ``pretix.event.order.invoice.sending_failed`` with the fields ``full_invoice_no``, ``transmission_provider``, + ``transmission_type`` and a provider-specific ``data`` field. + + Make sure to either handle ``invoice.order.testmode`` properly or set ``testmode_supported`` to ``False``. + """ + raise NotImplementedError + + @property + def priority(self) -> int: + """ + Returns a priority that is used for sorting transmission providers. Higher priority will be chosen over + lower priority for transmission. Default to 100. + """ + return 100 + + def settings_url(self, event) -> Optional[str]: + """ + Return a URL to the settings page of this provider (if any). + """ + return None + + +class TransmissionProviderRegistry(EventPluginRegistry): + def __init__(self): + super().__init__({ + 'identifier': lambda o: getattr(o, 'identifier'), + 'type': lambda o: getattr(o, 'type'), + }) + + def register(self, *objs): + for obj in objs: + if not isinstance(obj, TransmissionProvider): + raise TypeError('Entries must be derived from TransmissionProvider') + + if obj.type == "email" and not obj.__module__.startswith('pretix.base.'): + raise TypeError('No custom providers for email allowed') + + return super().register(*objs) + + +class TransmissionTypeRegistry(Registry): + def __init__(self): + super().__init__({ + 'identifier': lambda o: getattr(o, 'identifier'), + }) + + def register(self, *objs): + for obj in objs: + if not isinstance(obj, TransmissionType): + raise TypeError('Entries must be derived from TransmissionType') + + if not obj.__module__.startswith('pretix.base.'): + raise TypeError('Plugins are currently not allowed to add transmission types') + + return super().register(*objs) + + +""" +Registry for transmission providers. + +Each entry in this registry should be an instance of a subclass of ``TransmissionProvider``. +They are annotated with their ``identifier``, ``type``, and the defining ``plugin``. +""" +transmission_providers = TransmissionProviderRegistry() + + +""" +Registry for transmission types. + +Each entry in this registry should be an instance of a subclass of ``TransmissionType``. +They are annotated with their ``identifier``. +""" +transmission_types = TransmissionTypeRegistry() + + +def get_transmission_types(): + return sorted( + transmission_types.registered_entries.keys(), + key=lambda t: (-t.priority, str(t.public_name)), + ) diff --git a/src/pretix/base/logentrytype_registry.py b/src/pretix/base/logentrytype_registry.py index dd434063b..696ff24b6 100644 --- a/src/pretix/base/logentrytype_registry.py +++ b/src/pretix/base/logentrytype_registry.py @@ -26,7 +26,7 @@ from django.urls import reverse from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ -from pretix.base.signals import EventPluginRegistry +from pretix.base.signals import PluginAwareRegistry def make_link(a_map, wrapper, is_active=True, event=None, plugin_name=None): @@ -55,7 +55,7 @@ def make_link(a_map, wrapper, is_active=True, event=None, plugin_name=None): return format_html(wrapper, **a_map) -class LogEntryTypeRegistry(EventPluginRegistry): +class LogEntryTypeRegistry(PluginAwareRegistry): def __init__(self): super().__init__({'action_type': lambda o: getattr(o, 'action_type')}) diff --git a/src/pretix/base/management/commands/makemessages.py b/src/pretix/base/management/commands/makemessages.py new file mode 100644 index 000000000..bcbc67389 --- /dev/null +++ b/src/pretix/base/management/commands/makemessages.py @@ -0,0 +1,35 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +import re + +from django.core.management.commands import makemessages + + +def is_valid_locale(locale): + return re.match(r"^[a-z]+$", locale) or re.match(r"^[a-z]+_[A-Z0-9].*$", locale) + + +makemessages.is_valid_locale = is_valid_locale + + +class Command(makemessages.Command): + pass diff --git a/src/pretix/base/management/commands/runperiodic.py b/src/pretix/base/management/commands/runperiodic.py index cd07aad83..639b9b69b 100644 --- a/src/pretix/base/management/commands/runperiodic.py +++ b/src/pretix/base/management/commands/runperiodic.py @@ -38,6 +38,7 @@ import traceback from django.conf import settings from django.core.cache import cache from django.core.management.base import BaseCommand +from django.db import close_old_connections from django.dispatch.dispatcher import NO_RECEIVERS from pretix.helpers.periodic import SKIPPED @@ -79,6 +80,8 @@ class Command(BaseCommand): self.stdout.write(f'INFO Running {name}…') t0 = time.time() try: + # Check if the DB connection is still good, it might be closed if the previous task took too long. + close_old_connections() r = receiver(signal=periodic_task, sender=self) except Exception as err: if isinstance(err, KeyboardInterrupt): diff --git a/src/pretix/base/migrations/0282_taxrule_default.py b/src/pretix/base/migrations/0282_taxrule_default.py new file mode 100644 index 000000000..bfda92921 --- /dev/null +++ b/src/pretix/base/migrations/0282_taxrule_default.py @@ -0,0 +1,24 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("pretixbase", "0281_event_is_remote"), + ] + + operations = [ + migrations.AddField( + model_name="taxrule", + name="default", + field=models.BooleanField(default=False), + ), + migrations.AddConstraint( + model_name="taxrule", + constraint=models.UniqueConstraint( + condition=models.Q(("default", True)), + fields=("event",), + name="one_default_per_event", + ), + ), + ] diff --git a/src/pretix/base/migrations/0283_taxrule_default_taxrule_backfill.py b/src/pretix/base/migrations/0283_taxrule_default_taxrule_backfill.py new file mode 100644 index 000000000..05cd50e43 --- /dev/null +++ b/src/pretix/base/migrations/0283_taxrule_default_taxrule_backfill.py @@ -0,0 +1,60 @@ +# Generated by Django 4.2.17 on 2025-03-28 09:19 +from django.core.cache import cache +from django.db import migrations, models +from django.db.models import Count, Exists, OuterRef + + +def set_default_tax_rate(app, schema_editor): + Event = app.get_model('pretixbase', 'Event') + Event_SettingsStore = app.get_model('pretixbase', 'Event_SettingsStore') + TaxRule = app.get_model('pretixbase', 'TaxRule') + + # Handling of events with tax_rate_default set + for s in Event_SettingsStore.objects.filter(key="tax_rate_default").iterator(): + updated = TaxRule.objects.filter(pk=s.value, event_id=s.object_id).update(default=True) + if updated: + # Delete deprecated settings key + s.delete() + + # The default for new events is tax_rule_cancellation=none, but since we do not change behaviour + # for existing events without warning, we create a settings entry that matches the old behaviour. + Event_SettingsStore.objects.get_or_create( + object_id=s.object_id, + key="tax_rule_cancellation", + defaults={"value": "default"}, + ) + + # We do not need to set tax_rule_payment here since "default" is the default + + cache.delete('hierarkey_{}_{}'.format('event', s.object_id)) + + # Handling of events with tax_rate_default not set + for e in Event.objects.only("pk").exclude(Exists(TaxRule.objects.filter(default=True, event_id=OuterRef("pk")))).iterator(): + fav_tax_rules = e.tax_rules.annotate(c=Count("item")).order_by("-c", "pk")[:1] + if fav_tax_rules: + fav_tax_rules[0].default = True + fav_tax_rules[0].save() + + # Previously, no tax rule was set for payments, so keep it this way + Event_SettingsStore.objects.get_or_create( + object=e, + key="tax_rule_payment", + defaults={"value": "none"}, + ) + cache.delete('hierarkey_{}_{}'.format('event', e.pk)) + + # We do not need to set tax_rule_cancellation, as "none" is the new system default + + +class Migration(migrations.Migration): + + dependencies = [ + ("pretixbase", "0282_taxrule_default"), + ] + + operations = [ + migrations.RunPython( + set_default_tax_rate, + migrations.RunPython.noop, + ), + ] diff --git a/src/pretix/base/migrations/0284_ordersyncresult_ordersyncqueue.py b/src/pretix/base/migrations/0284_ordersyncresult_ordersyncqueue.py new file mode 100644 index 000000000..0968715f5 --- /dev/null +++ b/src/pretix/base/migrations/0284_ordersyncresult_ordersyncqueue.py @@ -0,0 +1,54 @@ +# Generated by Django 4.2.21 on 2025-06-27 13:32 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0283_taxrule_default_taxrule_backfill'), + ] + + operations = [ + migrations.CreateModel( + name='OrderSyncResult', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('sync_provider', models.CharField(max_length=128)), + ('mapping_id', models.IntegerField()), + ('external_object_type', models.CharField(max_length=128)), + ('external_id_field', models.CharField(max_length=128)), + ('id_value', models.CharField(max_length=128)), + ('external_link_href', models.CharField(max_length=255, null=True)), + ('external_link_display_name', models.CharField(max_length=255, null=True)), + ('transmitted', models.DateTimeField(auto_now_add=True)), + ('sync_info', models.JSONField()), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sync_results', to='pretixbase.order')), + ('order_position', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sync_results', to='pretixbase.orderposition')), + ], + options={ + 'indexes': [models.Index(fields=['order', 'sync_provider'], name='pretixbase__order_i_3e3c84_idx')], + }, + ), + migrations.CreateModel( + name='OrderSyncQueue', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)), + ('sync_provider', models.CharField(max_length=128)), + ('triggered_by', models.CharField(max_length=128)), + ('triggered', models.DateTimeField(auto_now_add=True)), + ('failed_attempts', models.PositiveIntegerField(default=0)), + ('not_before', models.DateTimeField(db_index=True)), + ('need_manual_retry', models.CharField(null=True, max_length=20)), + ('in_flight', models.BooleanField(default=False)), + ('in_flight_since', models.DateTimeField(blank=True, null=True)), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='queued_sync_jobs', to='pretixbase.event')), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='queued_sync_jobs', to='pretixbase.order')), + ], + options={ + 'ordering': ('triggered',), + 'unique_together': {('order', 'sync_provider', 'in_flight')}, + }, + ), + ] diff --git a/src/pretix/base/migrations/0285_voucher_created.py b/src/pretix/base/migrations/0285_voucher_created.py new file mode 100644 index 000000000..7b9e44aab --- /dev/null +++ b/src/pretix/base/migrations/0285_voucher_created.py @@ -0,0 +1,46 @@ +# Generated by Django 4.2.16 on 2025-08-08 09:13 + +from django.db import migrations, models +from django.db.models import Min +from django.utils.timezone import now + + +def backfill_voucher_created(apps, schema_editor): + Voucher = apps.get_model("pretixbase", "Voucher") + LogEntry = apps.get_model("pretixbase", "LogEntry") + ContentType = apps.get_model("contenttypes", "ContentType") + ct = None + + for v in Voucher.objects.filter(created__isnull=True).iterator(): + if not ct: + # "Lazy-loading" to prevent this to be executed on new DBs where the content type does not yet + # exist -- but also no vouchers do + ct = ContentType.objects.get(app_label='pretixbase', model='voucher') + v.created = LogEntry.objects.filter( + content_type=ct, + object_id=v.pk, + ).aggregate(m=Min("datetime"))["m"] or now() + v.save(update_fields=["created"]) + + +class Migration(migrations.Migration): + dependencies = [ + ("pretixbase", "0284_ordersyncresult_ordersyncqueue"), + ] + + operations = [ + migrations.AddField( + model_name="voucher", + name="created", + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.RunPython( + backfill_voucher_created, + migrations.RunPython.noop, + ), + migrations.AlterField( + model_name="voucher", + name="created", + field=models.DateTimeField(auto_now_add=True), + ), + ] diff --git a/src/pretix/base/migrations/0286_settingsstore_unique.py b/src/pretix/base/migrations/0286_settingsstore_unique.py new file mode 100644 index 000000000..eb93adeac --- /dev/null +++ b/src/pretix/base/migrations/0286_settingsstore_unique.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.16 on 2025-08-14 09:40 + +from django.db import migrations +from hierarkey.utils import CleanHierarkeyDuplicates + + +class Migration(migrations.Migration): + dependencies = [ + ("pretixbase", "0285_voucher_created"), + ] + + operations = [ + CleanHierarkeyDuplicates("GlobalSettingsObject_SettingsStore"), + CleanHierarkeyDuplicates("Organizer_SettingsStore"), + CleanHierarkeyDuplicates("Event_SettingsStore"), + migrations.AlterUniqueTogether( + name="event_settingsstore", + unique_together={("object", "key")}, + ), + migrations.AlterUniqueTogether( + name="globalsettingsobject_settingsstore", + unique_together={("key",)}, + ), + migrations.AlterUniqueTogether( + name="organizer_settingsstore", + unique_together={("object", "key")}, + ), + ] diff --git a/src/pretix/base/migrations/0287_organizer_plugins.py b/src/pretix/base/migrations/0287_organizer_plugins.py new file mode 100644 index 000000000..32a6c408e --- /dev/null +++ b/src/pretix/base/migrations/0287_organizer_plugins.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.17 on 2025-07-12 09:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("pretixbase", "0286_settingsstore_unique"), + ] + + operations = [ + migrations.AddField( + model_name="organizer", + name="plugins", + field=models.TextField(default=""), + ), + ] diff --git a/src/pretix/base/migrations/0288_invoice_transmission.py b/src/pretix/base/migrations/0288_invoice_transmission.py new file mode 100644 index 000000000..adc4569d9 --- /dev/null +++ b/src/pretix/base/migrations/0288_invoice_transmission.py @@ -0,0 +1,75 @@ +# Generated by Django 4.2.17 on 2025-04-21 11:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("pretixbase", "0287_organizer_plugins"), + ] + + operations = [ + migrations.RenameField( + model_name="invoice", + old_name="sent_to_customer", + new_name="transmission_date", + ), + migrations.AddField( + model_name="invoice", + name="invoice_to_transmission_info", + field=models.JSONField(null=True), + ), + migrations.AddField( + model_name="invoice", + name="transmission_info", + field=models.JSONField(null=True), + ), + migrations.AddField( + model_name="invoice", + name="transmission_provider", + field=models.CharField(max_length=255, null=True), + ), + migrations.AddField( + model_name="invoice", + name="transmission_status", + field=models.CharField(default="unknown", max_length=255), + ), + migrations.AddField( + model_name="invoice", + name="created", + field=models.DateTimeField(auto_now_add=True, null=True), + ), + migrations.AddField( + model_name="invoice", + name="invoice_to_is_business", + field=models.BooleanField(null=True), + ), + migrations.RunSQL( + "UPDATE pretixbase_invoice SET transmission_status = 'completed' WHERE transmission_date IS NOT NULL", + migrations.RunSQL.noop, + ), + migrations.AddField( + model_name="invoice", + name="transmission_type", + field=models.CharField(default="email", max_length=255), + ), + migrations.AddField( + model_name="invoiceaddress", + name="transmission_info", + field=models.JSONField(null=True), + ), + migrations.AddField( + model_name="invoiceaddress", + name="transmission_type", + field=models.CharField(default="email", max_length=255), + ), + migrations.RunSQL( + "UPDATE pretixbase_event_settingsstore SET key = 'mail_text_order_invoice' WHERE key = 'payment_banktransfer_invoice_email_text'", + "UPDATE pretixbase_event_settingsstore SET key = 'payment_banktransfer_invoice_email_text' WHERE key = 'mail_text_order_invoice'", + ), + migrations.RunSQL( + "UPDATE pretixbase_event_settingsstore SET key = 'mail_subject_order_invoice' WHERE key = 'payment_banktransfer_invoice_email_subject'", + "UPDATE pretixbase_event_settingsstore SET key = 'payment_banktransfer_invoice_email_subject' WHERE key = 'mail_subject_order_invoice'", + ), + ] diff --git a/src/pretix/base/modelimport.py b/src/pretix/base/modelimport.py index acf25c373..f700c349f 100644 --- a/src/pretix/base/modelimport.py +++ b/src/pretix/base/modelimport.py @@ -111,6 +111,13 @@ class ImportColumn: """ return gettext_lazy('Keep empty') + @property + def help_text(self): + """ + Additional description of the column + """ + return None + def __init__(self, event): self.event = event diff --git a/src/pretix/base/modelimport_orders.py b/src/pretix/base/modelimport_orders.py index b273cb0de..f87a24f2d 100644 --- a/src/pretix/base/modelimport_orders.py +++ b/src/pretix/base/modelimport_orders.py @@ -57,6 +57,7 @@ from pretix.base.signals import order_import_columns class EmailColumn(ImportColumn): identifier = 'email' verbose_name = gettext_lazy('Email address') + order_level = True def clean(self, value, previous_values): if value: @@ -67,9 +68,24 @@ class EmailColumn(ImportColumn): order.email = value +class GroupingColumn(ImportColumn): + identifier = 'grouping' + verbose_name = gettext_lazy('Grouping') + help_text = gettext_lazy( + 'Only applicable when "Import mode" is set to "Group multiple lines together...". Lines with the same grouping ' + 'value will be put in the same order, but MUST be consecutive lines of the input file.' + ) + order_level = True + default_label = "---" + + def assign(self, value, order, position, invoice_address, **kwargs): + pass + + class PhoneColumn(ImportColumn): identifier = 'phone' verbose_name = gettext_lazy('Phone number') + order_level = True def clean(self, value, previous_values): if value: @@ -94,6 +110,10 @@ class SubeventColumn(SubeventColumnMixin, ImportColumn): identifier = 'subevent' verbose_name = pgettext_lazy('subevents', 'Date') default_value = None + help_text = pgettext_lazy( + 'subevents', 'The date can be specified through its full name, full date and time, or internal ID, provided ' + 'only one date in the system matches the input.' + ) def clean(self, value, previous_values): if not value: @@ -108,6 +128,7 @@ class ItemColumn(ImportColumn): identifier = 'item' verbose_name = gettext_lazy('Product') default_value = None + help_text = gettext_lazy('The product can be specified by its internal ID, full name or internal name.') @cached_property def items(self): @@ -137,6 +158,7 @@ class ItemColumn(ImportColumn): class Variation(ImportColumn): identifier = 'variation' verbose_name = gettext_lazy('Product variation') + help_text = gettext_lazy('The variation can be specified by its internal ID or full name.') @cached_property def items(self): @@ -170,6 +192,7 @@ class Variation(ImportColumn): class InvoiceAddressCompany(ImportColumn): identifier = 'invoice_address_company' + order_level = True @property def verbose_name(self): @@ -181,6 +204,8 @@ class InvoiceAddressCompany(ImportColumn): class InvoiceAddressNamePart(ImportColumn): + order_level = True + def __init__(self, event, key, label): self.key = key self.label = label @@ -200,6 +225,7 @@ class InvoiceAddressNamePart(ImportColumn): class InvoiceAddressStreet(ImportColumn): identifier = 'invoice_address_street' + order_level = True @property def verbose_name(self): @@ -211,6 +237,7 @@ class InvoiceAddressStreet(ImportColumn): class InvoiceAddressZip(ImportColumn): identifier = 'invoice_address_zipcode' + order_level = True @property def verbose_name(self): @@ -222,6 +249,7 @@ class InvoiceAddressZip(ImportColumn): class InvoiceAddressCity(ImportColumn): identifier = 'invoice_address_city' + order_level = True @property def verbose_name(self): @@ -234,6 +262,8 @@ class InvoiceAddressCity(ImportColumn): class InvoiceAddressCountry(ImportColumn): identifier = 'invoice_address_country' default_value = None + help_text = gettext_lazy('The country needs to be specified using a two-letter country code.') + order_level = True @property def initial(self): @@ -257,6 +287,8 @@ class InvoiceAddressCountry(ImportColumn): class InvoiceAddressState(ImportColumn): identifier = 'invoice_address_state' + help_text = gettext_lazy('The state can be specified by its short form or full name.') + order_level = True @property def verbose_name(self): @@ -282,6 +314,7 @@ class InvoiceAddressState(ImportColumn): class InvoiceAddressVATID(ImportColumn): identifier = 'invoice_address_vat_id' + order_level = True @property def verbose_name(self): @@ -293,6 +326,7 @@ class InvoiceAddressVATID(ImportColumn): class InvoiceAddressReference(ImportColumn): identifier = 'invoice_address_internal_reference' + order_level = True @property def verbose_name(self): @@ -380,6 +414,7 @@ class AttendeeCity(ImportColumn): class AttendeeCountry(ImportColumn): identifier = 'attendee_country' default_value = None + help_text = gettext_lazy('The country needs to be specified using a two-letter country code.') @property def initial(self): @@ -403,6 +438,7 @@ class AttendeeCountry(ImportColumn): class AttendeeState(ImportColumn): identifier = 'attendee_state' + help_text = gettext_lazy('The state can be specified by its short form or full name.') @property def verbose_name(self): @@ -471,6 +507,7 @@ class Locale(ImportColumn): identifier = 'locale' verbose_name = gettext_lazy('Order locale') default_value = None + order_level = True @property def initial(self): @@ -514,6 +551,7 @@ class ValidUntil(DatetimeColumnMixin, ImportColumn): class Expires(DatetimeColumnMixin, ImportColumn): identifier = 'expires' verbose_name = gettext_lazy('Expiry date') + order_level = True def clean(self, value, previous_values): if not value: @@ -540,6 +578,8 @@ class Saleschannel(ImportColumn): verbose_name = gettext_lazy('Sales channel') default_value = None initial = 'static:web' + help_text = gettext_lazy('The sales channel can be specified by it\'s internal identifier or its full name.') + order_level = True @cached_property def channels(self): @@ -568,6 +608,7 @@ class Saleschannel(ImportColumn): class SeatColumn(ImportColumn): identifier = 'seat' verbose_name = gettext_lazy('Seat ID') + help_text = gettext_lazy('The seat needs to be specified by its internal ID.') def __init__(self, *args): self._cached = set() @@ -599,7 +640,8 @@ class SeatColumn(ImportColumn): class Comment(ImportColumn): identifier = 'comment' - verbose_name = gettext_lazy('Comment') + verbose_name = gettext_lazy('Order comment') + order_level = True def assign(self, value, order, position, invoice_address, **kwargs): order.comment = value or '' @@ -608,6 +650,7 @@ class Comment(ImportColumn): class CheckinAttentionColumn(BooleanColumnMixin, ImportColumn): identifier = 'checkin_attention' verbose_name = gettext_lazy('Requires special attention') + order_level = True def assign(self, value, order, position, invoice_address, **kwargs): order.checkin_attention = value @@ -616,6 +659,7 @@ class CheckinAttentionColumn(BooleanColumnMixin, ImportColumn): class CheckinTextColumn(ImportColumn): identifier = 'checkin_text' verbose_name = gettext_lazy('Check-in text') + order_level = True def assign(self, value, order, position, invoice_address, **kwargs): order.checkin_text = value @@ -696,6 +740,7 @@ class QuestionColumn(ImportColumn): class CustomerColumn(ImportColumn): identifier = 'customer' verbose_name = gettext_lazy('Customer') + order_level = True def clean(self, value, previous_values): if value: @@ -720,6 +765,7 @@ def get_order_import_columns(event): if event.has_subevents: default.append(SubeventColumn(event)) default += [ + GroupingColumn(event), EmailColumn(event), PhoneColumn(event), ItemColumn(event), diff --git a/src/pretix/base/models/checkin.py b/src/pretix/base/models/checkin.py index 9f42a9844..e9e160d4b 100644 --- a/src/pretix/base/models/checkin.py +++ b/src/pretix/base/models/checkin.py @@ -350,6 +350,7 @@ class Checkin(models.Model): REASON_BLOCKED = 'blocked' REASON_UNAPPROVED = 'unapproved' REASON_INVALID_TIME = 'invalid_time' + REASON_ANNULLED = 'annulled' REASONS = ( (REASON_CANCELED, _('Order canceled')), (REASON_INVALID, _('Unknown ticket')), @@ -364,6 +365,7 @@ class Checkin(models.Model): (REASON_BLOCKED, _('Ticket blocked')), (REASON_UNAPPROVED, _('Order not approved')), (REASON_INVALID_TIME, _('Ticket not valid at this time')), + (REASON_ANNULLED, _('Check-in annulled')), ) successful = models.BooleanField( diff --git a/src/pretix/base/models/datasync.py b/src/pretix/base/models/datasync.py new file mode 100644 index 000000000..065832403 --- /dev/null +++ b/src/pretix/base/models/datasync.py @@ -0,0 +1,149 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +import logging +from functools import cached_property + +from django.db import IntegrityError, models +from django.utils.translation import gettext as _ + +from pretix.base.models import Event, Order, OrderPosition + +logger = logging.getLogger(__name__) + + +MODE_OVERWRITE = "overwrite" +MODE_SET_IF_NEW = "if_new" +MODE_SET_IF_EMPTY = "if_empty" +MODE_APPEND_LIST = "append" + + +class OrderSyncQueue(models.Model): + order = models.ForeignKey( + Order, on_delete=models.CASCADE, related_name="queued_sync_jobs" + ) + event = models.ForeignKey( + Event, on_delete=models.CASCADE, related_name="queued_sync_jobs" + ) + sync_provider = models.CharField(blank=False, null=False, max_length=128) + triggered_by = models.CharField(blank=False, null=False, max_length=128) + triggered = models.DateTimeField(blank=False, null=False, auto_now_add=True) + failed_attempts = models.PositiveIntegerField(default=0) + not_before = models.DateTimeField(blank=False, null=False, db_index=True) + need_manual_retry = models.CharField(blank=True, null=True, max_length=20, choices=[ + ('exceeded', _('Temporary error, auto-retry limit exceeded')), + ('permanent', _('Provider reported a permanent error')), + ('config', _('Misconfiguration, please check provider settings')), + ('internal', _('System error, needs manual intervention')), + ('timeout', _('System error, needs manual intervention')), + ]) + in_flight = models.BooleanField(default=False) + in_flight_since = models.DateTimeField(blank=True, null=True) + + class Meta: + unique_together = (("order", "sync_provider", "in_flight"),) + ordering = ("triggered",) + + @cached_property + def _provider_class_info(self): + from pretix.base.datasync.datasync import datasync_providers + return datasync_providers.get(identifier=self.sync_provider) + + @property + def provider_class(self): + return self._provider_class_info[0] + + @property + def provider_display_name(self): + return self.provider_class.display_name + + @property + def is_provider_active(self): + return self._provider_class_info[1] + + @property + def max_retry_attempts(self): + return self.provider_class.max_attempts + + def set_sync_error(self, failure_mode, messages, full_message): + logger.exception( + f"Could not sync order {self.order.code} to {type(self).__name__} ({failure_mode})" + ) + self.order.log_action(f"pretix.event.order.data_sync.failed.{failure_mode}", { + "provider": self.sync_provider, + "error": messages, + "full_message": full_message, + }) + self.need_manual_retry = failure_mode + self.clear_in_flight() + + def clear_in_flight(self): + self.in_flight = False + self.in_flight_since = None + try: + self.save() + except IntegrityError: + # if setting in_flight=False fails due to UNIQUE constraint, just delete the current instance + self.delete() + + +class OrderSyncResult(models.Model): + order = models.ForeignKey( + Order, on_delete=models.CASCADE, related_name="sync_results" + ) + sync_provider = models.CharField(blank=False, null=False, max_length=128) + order_position = models.ForeignKey( + OrderPosition, on_delete=models.CASCADE, related_name="sync_results", blank=True, null=True, + ) + mapping_id = models.IntegerField(blank=False, null=False) + external_object_type = models.CharField(blank=False, null=False, max_length=128) + external_id_field = models.CharField(blank=False, null=False, max_length=128) + id_value = models.CharField(blank=False, null=False, max_length=128) + external_link_href = models.CharField(blank=True, null=True, max_length=255) + external_link_display_name = models.CharField(blank=True, null=True, max_length=255) + transmitted = models.DateTimeField(blank=False, null=False, auto_now_add=True) + sync_info = models.JSONField() + + class Meta: + indexes = [ + models.Index(fields=("order", "sync_provider")), + ] + + def external_link_html(self): + if not self.external_link_display_name: + return None + + from pretix.base.datasync.datasync import datasync_providers + prov, meta = datasync_providers.get(identifier=self.sync_provider) + if prov: + return prov.get_external_link_html(self.order.event, self.external_link_href, self.external_link_display_name) + + def to_result_dict(self): + return { + "position": self.order_position_id, + "object_type": self.external_object_type, + "external_id_field": self.external_id_field, + "id_value": self.id_value, + "external_link_href": self.external_link_href, + "external_link_display_name": self.external_link_display_name, + **self.sync_info, + } diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 97e0c1ec5..c12c5913d 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -551,8 +551,7 @@ class Event(EventMixin, LoggedModel): :type presale_end: datetime :param location: venue :type location: str - :param plugins: A comma-separated list of plugin names that are active for this - event. + :param plugins: A comma-separated list of plugin names that are active for this event. :type plugins: str :param has_subevents: Enable event series functionality :type has_subevents: bool @@ -1085,7 +1084,7 @@ class Event(EventMixin, LoggedModel): s.save(force_insert=True) valid_sales_channel_identifers = set(self.organizer.sales_channels.values_list("identifier", flat=True)) - skip_settings = ( + skip_settings = { 'ticket_secrets_pretix_sig1_pubkey', 'ticket_secrets_pretix_sig1_privkey', # no longer used, but we still don't need to copy them @@ -1093,7 +1092,10 @@ class Event(EventMixin, LoggedModel): 'presale_css_checksum', 'presale_widget_css_file', 'presale_widget_css_checksum', - ) + } | { + # Some settings might already exist due to e.g. the timezone being special in the API + s.key for s in self.settings._objects.all() + } settings_to_save = [] for s in other.settings._objects.all(): if s.key in skip_settings: @@ -1113,13 +1115,6 @@ class Event(EventMixin, LoggedModel): newname = default_storage.save(fname, fi) s.value = 'file://' + newname settings_to_save.append(s) - elif s.key == 'tax_rate_default': - try: - if int(s.value) in tax_map: - s.value = tax_map.get(int(s.value)).pk - settings_to_save.append(s) - except ValueError: - pass elif s.key.startswith('payment_') and s.key.endswith('__restrict_to_sales_channels'): data = other.settings._unserialize(s.value, as_type=list) data = [ident for ident in data if ident in valid_sales_channel_identifers] @@ -1198,6 +1193,10 @@ class Event(EventMixin, LoggedModel): renderers[pp.identifier] = pp return renderers + @cached_property + def cached_default_tax_rule(self): + return self.tax_rules.filter(default=True).first() + @cached_property def ticket_secret_generators(self) -> dict: """ @@ -1393,7 +1392,7 @@ class Event(EventMixin, LoggedModel): from pretix.base.plugins import get_all_plugins return { - p.module: p for p in get_all_plugins(self) + p.module: p for p in get_all_plugins(event=self) if not p.name.startswith('.') and getattr(p, 'visible', True) } @@ -1412,12 +1411,20 @@ class Event(EventMixin, LoggedModel): self.plugins = ",".join(modules) def enable_plugin(self, module, allow_restricted=frozenset()): + """ + Adds a plugin to the list of plugins, calling its ``installed`` hook (if available). + It is the caller's responsibility to save the event object. + """ plugins_active = self.get_plugins() if module not in plugins_active: plugins_active.append(module) self.set_active_plugins(plugins_active, allow_restricted=allow_restricted) def disable_plugin(self, module): + """ + Adds a plugin to the list of plugins, calling its ``uninstalled`` hook (if available). + It is the caller's responsibility to save the event object. + """ plugins_active = self.get_plugins() if module in plugins_active: plugins_active.remove(module) diff --git a/src/pretix/base/models/invoices.py b/src/pretix/base/models/invoices.py index 6919f44e0..5f4de4b8b 100644 --- a/src/pretix/base/models/invoices.py +++ b/src/pretix/base/models/invoices.py @@ -42,7 +42,7 @@ from django.db.models.functions import Cast from django.utils import timezone from django.utils.crypto import get_random_string from django.utils.functional import cached_property -from django.utils.translation import pgettext +from django.utils.translation import gettext_lazy as _, pgettext from django_scopes import ScopedManager from pretix.base.settings import COUNTRIES_WITH_STATE_IN_ADDRESS @@ -110,6 +110,21 @@ class Invoice(models.Model): :param file: The filename of the rendered invoice :type file: File """ + TRANSMISSION_STATUS_PENDING = "pending" + TRANSMISSION_STATUS_INFLIGHT = "inflight" + TRANSMISSION_STATUS_COMPLETED = "completed" + TRANSMISSION_STATUS_FAILED = "failed" + TRANSMISSION_STATUS_UNKNOWN = "unknown" + TRANSMISSION_STATUS_TESTMODE_IGNORED = "testmode_ignored" + TRANSMISSION_STATUS_CHOICES = ( + (TRANSMISSION_STATUS_PENDING, _("pending transmission")), + (TRANSMISSION_STATUS_INFLIGHT, _("currently being transmitted")), + (TRANSMISSION_STATUS_COMPLETED, _("transmitted")), + (TRANSMISSION_STATUS_FAILED, _("failed")), + (TRANSMISSION_STATUS_UNKNOWN, _("unknown")), + (TRANSMISSION_STATUS_TESTMODE_IGNORED, _("not transmitted due to test mode")), + ) + order = models.ForeignKey('Order', related_name='invoices', db_index=True, on_delete=models.CASCADE) organizer = models.ForeignKey('Organizer', related_name='invoices', db_index=True, on_delete=models.PROTECT) event = models.ForeignKey('Event', related_name='invoices', db_index=True, on_delete=models.CASCADE) @@ -131,6 +146,7 @@ class Invoice(models.Model): invoice_to = models.TextField() invoice_to_company = models.TextField(null=True) + invoice_to_is_business = models.BooleanField(null=True) invoice_to_name = models.TextField(null=True) invoice_to_street = models.TextField(null=True) invoice_to_zipcode = models.CharField(max_length=190, null=True) @@ -139,9 +155,11 @@ class Invoice(models.Model): invoice_to_country = FastCountryField(null=True) invoice_to_vat_id = models.TextField(null=True) invoice_to_beneficiary = models.TextField(null=True) + invoice_to_transmission_info = models.JSONField(null=True, blank=True) internal_reference = models.TextField(blank=True) custom_field = models.CharField(max_length=255, null=True) + created = models.DateTimeField(auto_now_add=True, null=True) # null for backwards compatibility date = models.DateField(default=today) locale = models.CharField(max_length=50, default='en') introductory_text = models.TextField(blank=True) @@ -158,14 +176,28 @@ class Invoice(models.Model): shredded = models.BooleanField(default=False) - # The field sent_to_organizer records whether this invocie was already sent to the organizer by a configured + # The field sent_to_organizer records whether this invoice was already sent to the organizer by a configured # mechanism such as email. # NULL: The cronjob that handles sending did not yet run. # True: The invoice was sent. # False: The invoice wasn't sent and never will, because sending was not configured at the time of the check. sent_to_organizer = models.BooleanField(null=True, blank=True) - sent_to_customer = models.DateTimeField(null=True, blank=True) + transmission_type = models.CharField( + max_length=255, + default="email", + ) + transmission_provider = models.CharField( + max_length=255, + null=True, blank=True, + ) + transmission_status = models.CharField( + max_length=255, + choices=TRANSMISSION_STATUS_CHOICES, + default=TRANSMISSION_STATUS_UNKNOWN, + ) + transmission_date = models.DateTimeField(null=True, blank=True) + transmission_info = models.JSONField(null=True, blank=True) file = models.FileField(null=True, blank=True, upload_to=invoice_filename, max_length=255) @@ -323,6 +355,19 @@ class Invoice(models.Model): def __str__(self): return self.full_invoice_no + @property + def regenerate_allowed(self): + return self.transmission_status in ( + Invoice.TRANSMISSION_STATUS_UNKNOWN, + Invoice.TRANSMISSION_STATUS_PENDING, + Invoice.TRANSMISSION_STATUS_FAILED, + ) and self.event.settings.invoice_regenerate_allowed + + @property + def transmission_type_instance(self): + from pretix.base.invoicing.transmission import transmission_types + return transmission_types.get(identifier=self.transmission_type)[0] + class InvoiceLine(models.Model): """ diff --git a/src/pretix/base/models/log.py b/src/pretix/base/models/log.py index ecb55e2af..368bd99f1 100644 --- a/src/pretix/base/models/log.py +++ b/src/pretix/base/models/log.py @@ -40,9 +40,6 @@ from django.contrib.contenttypes.models import ContentType from django.db import connections, models from django.utils.functional import cached_property -from pretix.base.logentrytype_registry import log_entry_types, make_link -from pretix.base.signals import is_app_active, logentry_object_link - class VisibleOnlyManager(models.Manager): def get_queryset(self): @@ -91,6 +88,8 @@ class LogEntry(models.Model): indexes = [models.Index(fields=["datetime", "id"])] def display(self): + from pretix.base.logentrytype_registry import log_entry_types + log_entry_type, meta = log_entry_types.get(action_type=self.action_type) if log_entry_type: return log_entry_type.display(self, self.parsed_data) @@ -128,6 +127,11 @@ class LogEntry(models.Model): @cached_property def display_object(self): + from pretix.base.logentrytype_registry import ( + log_entry_types, make_link, + ) + from pretix.base.signals import is_app_active, logentry_object_link + from . import ( Discount, Event, Item, Order, Question, Quota, SubEvent, Voucher, ) diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 9db278422..f48e7dd63 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -1821,7 +1821,7 @@ class OrderPayment(models.Model): def fail(self, info=None, user=None, auth=None, log_data=None, send_mail=True): """ - Marks the order as failed and sets info to ``info``, but only if the order is in ``created`` or ``pending`` + Marks the order as failed and sets info to ``info``, but only if the order is in ``created``, ``pending`` or ``canceled`` state. This is equivalent to setting ``state`` to ``OrderPayment.PAYMENT_STATE_FAILED`` and logging a failure, but it adds strong database locking since we do not want to report a failure for an order that has just been marked as paid. @@ -1829,7 +1829,11 @@ class OrderPayment(models.Model): """ with transaction.atomic(): locked_instance = OrderPayment.objects.select_for_update(of=OF_SELF).get(pk=self.pk) - if locked_instance.state not in (OrderPayment.PAYMENT_STATE_CREATED, OrderPayment.PAYMENT_STATE_PENDING): + if locked_instance.state in ( + OrderPayment.PAYMENT_STATE_CONFIRMED, + OrderPayment.PAYMENT_STATE_FAILED, + OrderPayment.PAYMENT_STATE_REFUNDED + ): # Race condition detected, this payment is already confirmed logger.info('Failed payment {} but ignored due to likely race condition.'.format( self.full_id, @@ -1935,6 +1939,7 @@ class OrderPayment(models.Model): ignore_date=False, lock=True, payment_refund_sum=0, allow_generate_invoice=True): from pretix.base.services.invoices import ( generate_cancellation, generate_invoice, invoice_qualified, + invoice_transmission_separately, transmit_invoice, ) from pretix.base.services.locking import LOCK_TRUST_WINDOW @@ -1965,13 +1970,19 @@ class OrderPayment(models.Model): trigger_pdf=not send_mail or not self.order.event.settings.invoice_email_attachment ) + transmit_invoice_task = invoice_transmission_separately(invoice) + transmit_invoice_mail = not transmit_invoice_task and self.order.event.settings.invoice_email_attachment and self.order.email + if send_mail and self.order.sales_channel.identifier in self.order.event.settings.mail_sales_channel_placed_paid: - self._send_paid_mail(invoice, user, mail_text) + self._send_paid_mail(invoice if transmit_invoice_mail else None, user, mail_text) if self.order.event.settings.mail_send_order_paid_attendee: for p in self.order.positions.all(): if p.addon_to_id is None and p.attendee_email and p.attendee_email != self.order.email: self._send_paid_mail_attendee(p, user) + if invoice and not transmit_invoice_mail: + transmit_invoice.apply_async(args=(self.order.event_id, invoice.pk, False)) + def _send_paid_mail_attendee(self, position, user): from pretix.base.services.mail import SendMailException @@ -2001,7 +2012,7 @@ class OrderPayment(models.Model): self.order.send_mail( email_subject, email_template, email_context, 'pretix.event.order.email.order_paid', user, - invoices=[invoice] if invoice and self.order.event.settings.invoice_email_attachment else [], + invoices=[invoice] if invoice else [], attach_tickets=True, attach_ical=self.order.event.settings.mail_attach_ical ) @@ -2373,17 +2384,17 @@ class OrderFee(models.Model): self.fee_type, self.value ) - def _calculate_tax(self, tax_rule=None): + def _calculate_tax(self, tax_rule=None, invoice_address=None): if tax_rule: self.tax_rule = tax_rule try: - ia = self.order.invoice_address + ia = invoice_address or self.order.invoice_address except InvoiceAddress.DoesNotExist: ia = None - if not self.tax_rule and self.fee_type == "payment" and self.order.event.settings.tax_rate_default: - self.tax_rule = self.order.event.settings.tax_rate_default + if not self.tax_rule and self.fee_type == "payment" and self.order.event.settings.tax_rule_payment == "default": + self.tax_rule = self.order.event.cached_default_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) @@ -3289,6 +3300,9 @@ class InvoiceAddress(models.Model): blank=True ) + transmission_type = models.CharField(max_length=255, default="email") + transmission_info = models.JSONField(null=True, blank=True) + objects = ScopedManager(organizer='order__event__organizer') profiles = ScopedManager(organizer='customer__organizer') @@ -3310,6 +3324,24 @@ class InvoiceAddress(models.Model): kwargs['update_fields'] = {'name_cached', 'name_parts'}.union(kwargs['update_fields']) super().save(**kwargs) + def clear(self, except_name=False): + self.is_business = False + if not except_name: + self.name_cached = "" + self.name_parts = {} + self.company = "" + self.street = "" + self.zipcode = "" + self.city = "" + self.country_old = "" + self.country = "" + self.state = "" + self.vat_id = "" + self.vat_id_validated = False + self.custom_field = None + self.internal_reference = "" + self.beneficiary = "" + def describe(self): parts = [ self.company, @@ -3322,6 +3354,7 @@ class InvoiceAddress(models.Model): self.internal_reference, (_('Beneficiary') + ': ' + self.beneficiary) if self.beneficiary else '', ] + parts += [f'{k}: {v}' for k, v in self.describe_transmission()] return '\n'.join([str(p).strip() for p in parts if p and str(p).strip()]) @property @@ -3376,9 +3409,28 @@ class InvoiceAddress(models.Model): 'custom_field': self.custom_field, 'internal_reference': self.internal_reference, 'beneficiary': self.beneficiary, + 'transmission_type': self.transmission_type, + **(self.transmission_info or {}), }) return d + def describe_transmission(self): + from pretix.base.invoicing.transmission import transmission_types + data = [] + + t, __ = transmission_types.get(identifier=self.transmission_type) + data.append((_("Transmission type"), t.public_name)) + form_data = t.transmission_info_to_form_data(self.transmission_info or {}) + for k, f in t.invoice_address_form_fields.items(): + v = form_data.get(k) + if v is True: + v = _("Yes") + elif v is False: + v = _("No") + if v: + data.append((f.label, v)) + return data + def cachedticket_name(instance, filename: str) -> str: secret = get_random_string(length=16, allowed_chars=string.ascii_letters + string.digits) diff --git a/src/pretix/base/models/organizer.py b/src/pretix/base/models/organizer.py index c9e0ee3ba..95d92aaf8 100644 --- a/src/pretix/base/models/organizer.py +++ b/src/pretix/base/models/organizer.py @@ -68,6 +68,8 @@ class Organizer(LoggedModel): :param slug: A globally unique, short name for this organizer, to be used in URLs and similar places. :type slug: str + :param plugins: A comma-separated list of plugin names that are active for this organizer. + :type plugins: str """ settings_namespace = 'organizer' @@ -91,6 +93,10 @@ class Organizer(LoggedModel): verbose_name=_("Short form"), unique=True ) + plugins = models.TextField( + verbose_name=_("Plugins"), + null=False, blank=True, default="", + ) class Meta: verbose_name = _("Organizer") @@ -119,6 +125,11 @@ class Organizer(LoggedModel): """ self.settings.cookie_consent = True + plugins = [p for p in settings.PRETIX_PLUGINS_ORGANIZER_DEFAULT.split(",") if p] + if plugins: + self.set_active_plugins(plugins, allow_restricted=plugins) + self.save() + def get_cache(self): """ Returns an :py:class:`ObjectRelatedCache` object. This behaves equivalent to @@ -143,6 +154,61 @@ class Organizer(LoggedModel): return ObjectRelatedCache(self) + def get_plugins(self): + """ + Returns the names of the plugins activated for this organizer as a list. + """ + if not self.plugins: + return [] + return self.plugins.split(",") + + def get_available_plugins(self): + from pretix.base.plugins import get_all_plugins + + return { + p.module: p for p in get_all_plugins(organizer=self) + if not p.name.startswith('.') and getattr(p, 'visible', True) + } + + def set_active_plugins(self, modules, allow_restricted=frozenset()): + plugins_active = self.get_plugins() + plugins_available = self.get_available_plugins() + + enable = [m for m in modules if m not in plugins_active and m in plugins_available] + + for module in enable: + if getattr(plugins_available[module].app, 'restricted', False) and module not in allow_restricted: + modules.remove(module) + elif hasattr(plugins_available[module].app, 'installed'): + getattr(plugins_available[module].app, 'installed')(self) + + self.plugins = ",".join(modules) + + def enable_plugin(self, module, allow_restricted=frozenset()): + """ + Adds a plugin to the list of plugins, calling its ``installed`` hook (if available). + It is the caller's responsibility to save the organizer object. + """ + plugins_active = self.get_plugins() + if module not in plugins_active: + plugins_active.append(module) + self.set_active_plugins(plugins_active, allow_restricted=allow_restricted) + + def disable_plugin(self, module): + """ + Removes a plugin from the list of plugins, calling its ``uninstalled`` hook (if available). + It is the caller's responsibility to save the organizer object and, in case of a hybrid organizer-event plugin, + to remove it from all events. + """ + plugins_active = self.get_plugins() + if module in plugins_active: + plugins_active.remove(module) + self.set_active_plugins(plugins_active) + + plugins_available = self.get_available_plugins() + if module in plugins_available and hasattr(plugins_available[module].app, 'uninstalled'): + getattr(plugins_available[module].app, 'uninstalled')(self) + @property def timezone(self): return pytz_deprecation_shim.timezone(self.settings.timezone) diff --git a/src/pretix/base/models/tax.py b/src/pretix/base/models/tax.py index af4c5ed48..1058934cd 100644 --- a/src/pretix/base/models/tax.py +++ b/src/pretix/base/models/tax.py @@ -377,9 +377,20 @@ class TaxRule(LoggedModel): 'if configured above.'), ) custom_rules = models.TextField(blank=True, null=True) + default = models.BooleanField( + verbose_name=_('Default'), + default=False, + ) class Meta: ordering = ('event', 'rate', 'id') + constraints = [ + models.UniqueConstraint( + fields=["event"], + condition=models.Q(default=True), + name="one_default_per_event", + ), + ] class SaleNotAllowed(Exception): pass @@ -394,7 +405,7 @@ class TaxRule(LoggedModel): and not OrderFee.objects.filter(tax_rule=self, order__event=self.event).exists() and not OrderPosition.all.filter(tax_rule=self, order__event=self.event).exists() and not self.event.items.filter(tax_rule=self).exists() - and self.event.settings.tax_rate_default != self + and not (self.default and self.event.tax_rules.filter(~models.Q(pk=self.pk)).exists()) ) @classmethod diff --git a/src/pretix/base/models/vouchers.py b/src/pretix/base/models/vouchers.py index cd6c4bafa..9dc8afe3d 100644 --- a/src/pretix/base/models/vouchers.py +++ b/src/pretix/base/models/vouchers.py @@ -174,6 +174,9 @@ class Voucher(LoggedModel): ('percent', _('Reduce product price by (%)')), ) + created = models.DateTimeField( + auto_now_add=True, + ) event = models.ForeignKey( Event, on_delete=models.CASCADE, diff --git a/src/pretix/base/models/waitinglist.py b/src/pretix/base/models/waitinglist.py index 38f50de50..f7cf0ff8e 100644 --- a/src/pretix/base/models/waitinglist.py +++ b/src/pretix/base/models/waitinglist.py @@ -207,16 +207,19 @@ class WaitingListEntry(LoggedModel): block_quota=True, subevent=self.subevent, ) - v.log_action('pretix.voucher.added.waitinglist', { + v.log_action('pretix.voucher.added', { 'item': self.item.pk, 'variation': self.variation.pk if self.variation else None, 'tag': 'waiting-list', 'block_quota': True, 'valid_until': v.valid_until.isoformat(), 'max_usages': 1, + 'subevent': self.subevent.pk if self.subevent else None, + 'source': 'waitinglist', + }, user=user, auth=auth) + v.log_action('pretix.voucher.added.waitinglist', { 'email': self.email, 'waitinglistentry': self.pk, - 'subevent': self.subevent.pk if self.subevent else None, }, user=user, auth=auth) self.voucher = v self.save() diff --git a/src/pretix/base/pdf.py b/src/pretix/base/pdf.py index dd1541d26..f9a2429c5 100644 --- a/src/pretix/base/pdf.py +++ b/src/pretix/base/pdf.py @@ -159,8 +159,17 @@ DEFAULT_VARIABLES = OrderedDict(( "editor_sample": _("123.45 EUR"), "evaluate": lambda op, order, event: money_filter(op.price, event.currency) }), + ("price_with_bundled", { + "label": _("Price including bundled products"), + "editor_sample": _("123.45 EUR"), + "evaluate": lambda op, order, event: money_filter(op.price + sum( + p.price + for p in op.addons.all() + if not p.canceled and p.is_bundled + ), event.currency) + }), ("price_with_addons", { - "label": _("Price including add-ons"), + "label": _("Price including add-ons and bundled products"), "editor_sample": _("123.45 EUR"), "evaluate": lambda op, order, event: money_filter(op.price + sum( p.price diff --git a/src/pretix/base/plugins.py b/src/pretix/base/plugins.py index 79e6d23a9..f26eb7747 100644 --- a/src/pretix/base/plugins.py +++ b/src/pretix/base/plugins.py @@ -28,8 +28,13 @@ import importlib_metadata as metadata from django.apps import AppConfig, apps from django.conf import settings from django.core.exceptions import ImproperlyConfigured +from django.utils.translation import gettext_lazy as _ from packaging.requirements import Requirement +PLUGIN_LEVEL_EVENT = 'event' +PLUGIN_LEVEL_ORGANIZER = 'organizer' +PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID = 'event_organizer' + class PluginType(Enum): """ @@ -43,11 +48,14 @@ class PluginType(Enum): EXPORT = 4 -def get_all_plugins(event=None) -> List[type]: +def get_all_plugins(*, event=None, organizer=None) -> List[type]: """ Returns the PretixPluginMeta classes of all plugins found in the installed Django apps. """ + assert not event or not organizer plugins = [] + event_fallback = None + event_fallback_used = False for app in apps.get_app_configs(): if hasattr(app, 'PretixPluginMeta'): meta = app.PretixPluginMeta @@ -56,8 +64,26 @@ def get_all_plugins(event=None) -> List[type]: if app.name in settings.PRETIX_PLUGINS_EXCLUDE: continue - if hasattr(app, 'is_available') and event: - if not app.is_available(event): + level = getattr(app, "level", PLUGIN_LEVEL_EVENT) + if level == PLUGIN_LEVEL_EVENT: + if event and hasattr(app, 'is_available'): + if not app.is_available(event): + continue + elif organizer and hasattr(app, 'is_available'): + if not event_fallback_used: + event_fallback = organizer.events.first() + event_fallback_used = True + if not event_fallback or not app.is_available(event_fallback): + continue + elif level == PLUGIN_LEVEL_ORGANIZER: + if organizer and hasattr(app, 'is_available'): + if not app.is_available(organizer): + continue + elif event and hasattr(app, 'is_available'): + if not app.is_available(event.organizer): + continue + elif level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID and (event or organizer) and hasattr(app, 'is_available'): + if not app.is_available(event or organizer): continue plugins.append(meta) @@ -91,3 +117,26 @@ class PluginConfig(AppConfig, metaclass=PluginConfigMeta): self.name, req, requirement_version )) sys.exit(1) + + if not hasattr(self.PretixPluginMeta, 'level'): + self.PretixPluginMeta.level = PLUGIN_LEVEL_EVENT + if self.PretixPluginMeta.level not in (PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID): + raise ImproperlyConfigured(f"Unknown plugin level '{self.PretixPluginMeta.level}'") + + +CATEGORY_ORDER = [ + 'FEATURE', + 'PAYMENT', + 'INTEGRATION', + 'CUSTOMIZATION', + 'FORMAT', + 'API', +] +CATEGORY_LABELS = { + 'FEATURE': _('Features'), + 'PAYMENT': _('Payment providers'), + 'INTEGRATION': _('Integrations'), + 'CUSTOMIZATION': _('Customizations'), + 'FORMAT': _('Output and export formats'), + 'API': _('API features'), +} diff --git a/src/pretix/base/reldate.py b/src/pretix/base/reldate.py index aeb9cd703..79d49b82f 100644 --- a/src/pretix/base/reldate.py +++ b/src/pretix/base/reldate.py @@ -28,6 +28,9 @@ from dateutil import parser from django import forms from django.core.exceptions import ValidationError from django.db import models +from django.utils.formats import get_format +from django.utils.functional import lazy +from django.utils.timezone import now from django.utils.translation import gettext_lazy as _ from rest_framework import serializers @@ -206,14 +209,27 @@ class RelativeDateTimeWidget(forms.MultiWidget): def __init__(self, *args, **kwargs): self.status_choices = kwargs.pop('status_choices') base_choices = kwargs.pop('base_choices') + + def placeholder_datetime_format(): + df = get_format('DATETIME_INPUT_FORMATS')[0] + return now().replace( + year=2000, month=12, day=31, hour=18, minute=0, second=0, microsecond=0 + ).strftime(df) + + def placeholder_time_format(): + tf = get_format('TIME_INPUT_FORMATS')[0] + return datetime.time(8, 30, 0).strftime(tf) + widgets = reldatetimeparts( status=forms.RadioSelect(choices=self.status_choices), absolute=forms.DateTimeInput( - attrs={'class': 'datetimepicker'} + attrs={'placeholder': lazy(placeholder_datetime_format, str), 'class': 'datetimepicker'} ), rel_days_number=forms.NumberInput(), rel_mins_relationto=forms.Select(choices=base_choices), - rel_days_timeofday=forms.TimeInput(attrs={'placeholder': _('Time'), 'class': 'timepickerfield'}), + rel_days_timeofday=forms.TimeInput( + attrs={'placeholder': lazy(placeholder_time_format, str), 'class': 'timepickerfield'} + ), rel_mins_number=forms.NumberInput(), rel_days_relationto=forms.Select(choices=base_choices), rel_mins_relation=forms.Select(choices=BEFORE_AFTER_CHOICE), diff --git a/src/pretix/base/services/cancelevent.py b/src/pretix/base/services/cancelevent.py index 1211412e7..3f14c91dc 100644 --- a/src/pretix/base/services/cancelevent.py +++ b/src/pretix/base/services/cancelevent.py @@ -32,7 +32,7 @@ from pretix.base.email import get_email_context from pretix.base.i18n import language from pretix.base.models import ( Event, InvoiceAddress, Order, OrderFee, OrderPosition, OrderRefund, - SubEvent, User, WaitingListEntry, + SubEvent, TaxRule, User, WaitingListEntry, ) from pretix.base.services.locking import LockTimeoutException from pretix.base.services.mail import SendMailException, mail @@ -40,6 +40,7 @@ from pretix.base.services.orders import ( OrderChangeManager, OrderError, _cancel_order, _try_auto_refund, ) from pretix.base.services.tasks import ProfiledEventTask +from pretix.base.services.tax import split_fee_for_taxes from pretix.celery_app import app from pretix.helpers import OF_SELF from pretix.helpers.format import format_map @@ -268,14 +269,34 @@ def cancel_event(self, event: Event, subevent: int, auto_refund: bool, fee += Decimal(keep_fee_percentage) / Decimal('100.00') * total fee = round_decimal(min(fee, o.payment_refund_sum), event.currency) if fee: - f = OrderFee( - fee_type=OrderFee.FEE_TYPE_CANCELLATION, - value=fee, - order=o, - tax_rule=o.event.settings.tax_rate_default, - ) - f._calculate_tax() - ocm.add_fee(f) + tax_rule_zero = TaxRule.zero() + if event.settings.tax_rule_cancellation == "default": + fee_values = [(event.cached_default_tax_rule or tax_rule_zero, fee)] + elif event.settings.tax_rule_cancellation == "split": + fee_values = split_fee_for_taxes(positions, fee, event) + else: + fee_values = [(tax_rule_zero, fee)] + + try: + ia = o.invoice_address + except InvoiceAddress.DoesNotExist: + ia = None + + for tax_rule, price in fee_values: + tax_rule = tax_rule or tax_rule_zero + tax = tax_rule.tax( + price, invoice_address=ia, base_price_is="gross" + ) + f = OrderFee( + fee_type=OrderFee.FEE_TYPE_CANCELLATION, + value=price, + order=o, + tax_rate=tax.rate, + tax_code=tax.code, + tax_value=tax.tax, + tax_rule=tax_rule, + ) + ocm.add_fee(f) ocm.commit() refund_amount = o.payment_refund_sum - o.total diff --git a/src/pretix/base/services/cart.py b/src/pretix/base/services/cart.py index 5212b1307..3b256bd62 100644 --- a/src/pretix/base/services/cart.py +++ b/src/pretix/base/services/cart.py @@ -1534,7 +1534,10 @@ def get_fees(event, request, total, invoice_address, payments, positions): total_remaining -= to_pay if payment_fee: - payment_fee_tax_rule = event.settings.tax_rate_default or TaxRule.zero() + if event.settings.tax_rule_payment == "default": + payment_fee_tax_rule = event.cached_default_tax_rule or TaxRule.zero() + else: + payment_fee_tax_rule = TaxRule.zero() payment_fee_tax = payment_fee_tax_rule.tax(payment_fee, base_price_is='gross', invoice_address=invoice_address) fees.append(OrderFee( fee_type=OrderFee.FEE_TYPE_PAYMENT, diff --git a/src/pretix/base/services/datasync.py b/src/pretix/base/services/datasync.py new file mode 100644 index 000000000..c4d48da7e --- /dev/null +++ b/src/pretix/base/services/datasync.py @@ -0,0 +1,105 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +import logging +from datetime import timedelta +from itertools import groupby + +from django.db.models import F, Window +from django.db.models.functions import RowNumber +from django.dispatch import receiver +from django.utils.timezone import now +from django_scopes import scope, scopes_disabled + +from pretix.base.datasync.datasync import datasync_providers +from pretix.base.models.datasync import OrderSyncQueue +from pretix.base.signals import periodic_task +from pretix.celery_app import app + +logger = logging.getLogger(__name__) + + +@receiver(periodic_task, dispatch_uid="data_sync_periodic_sync_all") +def periodic_sync_all(sender, **kwargs): + sync_all.apply_async() + + +@receiver(periodic_task, dispatch_uid="data_sync_periodic_reset_in_flight") +def periodic_reset_in_flight(sender, **kwargs): + for sq in OrderSyncQueue.objects.filter( + in_flight=True, + in_flight_since__lt=now() - timedelta(minutes=20), + ): + sq.set_sync_error('timeout', [], 'Timeout') + + +def run_sync(queue): + grouped = groupby(sorted(queue, key=lambda q: (q.sync_provider, q.event.pk)), lambda q: (q.sync_provider, q.event)) + for (target, event), queued_orders in grouped: + target_cls, meta = datasync_providers.get(identifier=target, active_in=event) + + if not target_cls: + # sync plugin not found (plugin deactivated or uninstalled) -> drop outstanding jobs + num_deleted, _ = OrderSyncQueue.objects.filter(pk__in=[sq.pk for sq in queued_orders]).delete() + logger.info("Deleted %d queue entries from %r because plugin %s inactive", num_deleted, event, target) + continue + + with scope(organizer=event.organizer): + with target_cls(event=event) as p: + p.sync_queued_orders(queued_orders) + + +@app.task() +def sync_all(): + with scopes_disabled(): + queue = ( + OrderSyncQueue.objects + .filter( + in_flight=False, + not_before__lt=now(), + need_manual_retry__isnull=True, + ) + .order_by(Window( + expression=RowNumber(), + partition_by=[F("event_id")], + order_by="not_before", + )) + .prefetch_related("event") + [:1000] + ) + run_sync(queue) + + +@app.task() +def sync_single(queue_item_id: int): + with scopes_disabled(): + queue = ( + OrderSyncQueue.objects + .filter( + pk=queue_item_id, + in_flight=False, + not_before__lt=now(), + need_manual_retry__isnull=True, + ) + .prefetch_related("event") + ) + run_sync(queue) diff --git a/src/pretix/base/services/invoices.py b/src/pretix/base/services/invoices.py index ce612003c..85a69e9e7 100644 --- a/src/pretix/base/services/invoices.py +++ b/src/pretix/base/services/invoices.py @@ -51,11 +51,16 @@ from django_scopes import scope, scopes_disabled from i18nfield.strings import LazyI18nString from pretix.base.i18n import language +from pretix.base.invoicing.transmission import ( + get_transmission_types, transmission_providers, +) from pretix.base.models import ( ExchangeRate, Invoice, InvoiceAddress, InvoiceLine, Order, OrderFee, ) from pretix.base.models.tax import EU_CURRENCIES -from pretix.base.services.tasks import TransactionAwareTask +from pretix.base.services.tasks import ( + TransactionAwareProfiledEventTask, TransactionAwareTask, +) from pretix.base.signals import invoice_line_text, periodic_task from pretix.celery_app import app from pretix.helpers.database import OF_SELF, rolledback_transaction @@ -71,12 +76,13 @@ def _location_oneliner(loc): @transaction.atomic def build_invoice(invoice: Invoice) -> Invoice: invoice.locale = invoice.event.settings.get('invoice_language', invoice.event.settings.locale) + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_PENDING if invoice.locale == '__user__': invoice.locale = invoice.order.locale or invoice.event.settings.locale lp = invoice.order.payments.last() - with language(invoice.locale, invoice.event.settings.region): + with (language(invoice.locale, invoice.event.settings.region)): invoice.invoice_from = invoice.event.settings.get('invoice_address_from') invoice.invoice_from_name = invoice.event.settings.get('invoice_address_from_name') invoice.invoice_from_zipcode = invoice.event.settings.get('invoice_address_from_zipcode') @@ -127,6 +133,7 @@ def build_invoice(invoice: Invoice) -> Invoice: invoice.internal_reference = ia.internal_reference invoice.custom_field = ia.custom_field invoice.invoice_to_company = ia.company + invoice.invoice_to_is_business = ia.is_business invoice.invoice_to_name = ia.name invoice.invoice_to_street = ia.street invoice.invoice_to_zipcode = ia.zipcode @@ -134,6 +141,8 @@ def build_invoice(invoice: Invoice) -> Invoice: invoice.invoice_to_country = ia.country invoice.invoice_to_state = ia.state invoice.invoice_to_beneficiary = ia.beneficiary + invoice.invoice_to_transmission_info = ia.transmission_info or {} + invoice.transmission_type = ia.transmission_type if ia.vat_id: invoice.invoice_to += "\n" + pgettext("invoice", "VAT-ID: %s") % ia.vat_id @@ -356,7 +365,9 @@ def generate_cancellation(invoice: Invoice, trigger_pdf=True): cancellation.payment_provider_stamp = '' cancellation.file = None cancellation.sent_to_organizer = None - cancellation.sent_to_customer = None + cancellation.transmission_provider = None + cancellation.transmission_status = Invoice.TRANSMISSION_STATUS_PENDING + cancellation.transmission_date = None with language(invoice.locale, invoice.event.settings.region): cancellation.invoice_from = invoice.event.settings.get('invoice_address_from') cancellation.invoice_from_name = invoice.event.settings.get('invoice_address_from_name') @@ -512,6 +523,36 @@ def build_preview_invoice_pdf(event): return event.invoice_renderer.generate(invoice) +def order_invoice_transmission_separately(order): + try: + info = order.invoice_address.transmission_info or {} + return ( + order.invoice_address.transmission_type != "email" or + ( + info.get("transmission_email_address") and + order.email != info["transmission_email_address"] + ) + ) + except InvoiceAddress.DoesNotExist: + return False + + +def invoice_transmission_separately(invoice): + if not invoice: + return False + try: + info = invoice.invoice_to_transmission_info or {} + return ( + invoice.transmission_type != "email" or + ( + info.get("transmission_email_address") and + invoice.order.email != info["transmission_email_address"] + ) + ) + except InvoiceAddress.DoesNotExist: + return False + + @receiver(signal=periodic_task) @scopes_disabled() def send_invoices_to_organizer(sender, **kwargs): @@ -551,3 +592,124 @@ def send_invoices_to_organizer(sender, **kwargs): else: i.sent_to_organizer = False i.save(update_fields=['sent_to_organizer']) + + +@receiver(signal=periodic_task) +@scopes_disabled() +def retry_stuck_invoices(sender, **kwargs): + with transaction.atomic(): + qs = Invoice.objects.filter( + transmission_status=Invoice.TRANSMISSION_STATUS_INFLIGHT, + transmission_date__lte=now() - timedelta(hours=24), + ).select_for_update( + of=OF_SELF, skip_locked=connection.features.has_select_for_update_skip_locked + ) + batch_size = 5000 + for invoice in qs[:batch_size]: + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_PENDING + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + transmit_invoice.apply_async(args=(invoice.event_id, invoice.pk, True)) + + +@receiver(signal=periodic_task) +@scopes_disabled() +def send_pending_invoices(sender, **kwargs): + with transaction.atomic(): + # Transmit all invoices that have not been transmitted by another process if the provider enforces + # transmission + types = [ + tt.identifier for tt in get_transmission_types() + if tt.enforce_transmission + ] + qs = Invoice.objects.filter( + transmission_type__in=types, + transmission_status=Invoice.TRANSMISSION_STATUS_PENDING, + created__lte=now() - timedelta(minutes=15), + ).select_for_update( + of=OF_SELF, skip_locked=connection.features.has_select_for_update_skip_locked + ) + batch_size = 5000 + for invoice in qs[:batch_size]: + transmit_invoice.apply_async(args=(invoice.event_id, invoice.pk, False)) + + +@app.task(base=TransactionAwareProfiledEventTask) +def transmit_invoice(sender, invoice_id, allow_retransmission=True, **kwargs): + with transaction.atomic(durable='tests.testdummy' not in settings.INSTALLED_APPS): + # We need durable=True for transactional correctness, but can't have it during tests + invoice = Invoice.objects.select_for_update(of=OF_SELF).get(pk=invoice_id) + + if invoice.transmission_status == Invoice.TRANSMISSION_STATUS_INFLIGHT: + logger.info(f"Did not transmit invoice {invoice.pk} due to being in inflight state.") + return + + if invoice.transmission_status != Invoice.TRANSMISSION_STATUS_PENDING and not allow_retransmission: + logger.info(f"Did not transmit invoice {invoice.pk} due to status being {invoice.transmission_status}.") + return + + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_INFLIGHT + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + + providers = sorted([ + provider + for provider, __ in transmission_providers.filter(type=invoice.transmission_type, active_in=sender) + ], key=lambda p: (-p.priority, p.identifier)) + + provider = None + for p in providers: + if p.is_available(sender, invoice.invoice_to_country, invoice.invoice_to_is_business): + provider = p + break + + if not provider: + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_FAILED + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + invoice.order.log_action( + "pretix.event.order.invoice.sending_failed", + data={ + "full_invoice_no": invoice.full_invoice_no, + "transmission_provider": None, + "transmission_type": invoice.transmission_type, + "data": { + "reason": "no_provider", + }, + } + ) + return + + if invoice.order.testmode and not provider.testmode_supported: + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_TESTMODE_IGNORED + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + invoice.order.log_action( + "pretix.event.order.invoice.testmode_ignored", + data={ + "full_invoice_no": invoice.full_invoice_no, + "transmission_provider": None, + "transmission_type": invoice.transmission_type, + } + ) + return + + try: + provider.transmit(invoice) + except Exception as e: + logger.exception(f"Transmission of invoice {invoice.pk} failed with exception.") + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_FAILED + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + invoice.order.log_action( + "pretix.event.order.invoice.sending_failed", + data={ + "full_invoice_no": invoice.full_invoice_no, + "transmission_provider": None, + "transmission_type": invoice.transmission_type, + "data": { + "reason": "exception", + "exception": str(e), + }, + } + ) diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index 73cfedbbd..6561651d2 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -658,8 +658,55 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st raise SendMailException('Failed to send an email to {}.'.format(to)) else: for i in invoices_sent: - i.sent_to_customer = now() - i.save(update_fields=['sent_to_customer']) + if i.transmission_type == "email": + # Mark invoice as sent when it was sent to the requested address *either* at the time of invoice + # creation *or* as of right now. + expected_recipients = [ + (i.invoice_to_transmission_info or {}).get("transmission_email_address") or i.order.email, + ] + try: + expected_recipients.append((i.order.invoice_address.transmission_info or {}).get("transmission_email_address") or i.order.email) + except InvoiceAddress.DoesNotExist: + pass + if not any(t in expected_recipients for t in to): + continue + if i.transmission_status != Invoice.TRANSMISSION_STATUS_COMPLETED: + i.transmission_date = now() + i.transmission_status = Invoice.TRANSMISSION_STATUS_COMPLETED + i.transmission_provider = "email_pdf" + i.transmission_info = { + "sent": [ + { + "recipients": to, + "datetime": now().isoformat(), + } + ] + } + i.save(update_fields=[ + "transmission_date", "transmission_provider", "transmission_status", + "transmission_info" + ]) + elif i.transmission_provider == "email_pdf": + i.transmission_info["sent"].append( + { + "recipients": to, + "datetime": now().isoformat(), + } + ) + i.save(update_fields=[ + "transmission_info" + ]) + i.order.log_action( + "pretix.event.order.invoice.sent", + data={ + "full_invoice_no": i.full_invoice_no, + "transmission_provider": "email_pdf", + "transmission_type": "email", + "data": { + "recipients": [to], + }, + } + ) def mail_send(*args, **kwargs): diff --git a/src/pretix/base/services/modelimport.py b/src/pretix/base/services/modelimport.py index c029e0510..4c37a6c99 100644 --- a/src/pretix/base/services/modelimport.py +++ b/src/pretix/base/services/modelimport.py @@ -89,6 +89,9 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user, _('Orders cannot have more than %(max)s positions.') % {'max': django_settings.PRETIX_MAX_ORDER_SIZE} ) + used_groupers = set() + current_grouper = [] + current_order_level_data = {} orders = [] order = None @@ -97,7 +100,28 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user, lock_seats = [] for i, record in enumerate(data): try: - if order is None or settings['orders'] == 'many': + create_new_order = ( + order is None or + settings['orders'] == 'many' or + (settings['orders'] == 'mixed' and record["grouping"] != current_grouper) + ) + + if create_new_order: + if settings['orders'] == 'mixed': + if record["grouping"] in used_groupers: + raise DataImportError( + _('The grouping "%(value)s" occurs on non-consecutive lines (seen again on line %(row)s).') % { + "value": record["grouping"], + "row": i + 1, + } + ) + current_grouper = record["grouping"] + used_groupers.add(current_grouper) + + current_order_level_data = { + c.identifier: record.get(c.identifier) + for c in cols if getattr(c, "order_level", False) + } order = Order( event=event, testmode=settings['testmode'], @@ -108,6 +132,12 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user, order._address.name_parts = {'_scheme': event.settings.name_scheme} orders.append(order) + if settings['orders'] == 'mixed' and len(order._positions) >= django_settings.PRETIX_MAX_ORDER_SIZE: + raise DataImportError( + _('Orders cannot have more than %(max)s positions.') % { + 'max': django_settings.PRETIX_MAX_ORDER_SIZE} + ) + position = OrderPosition(positionid=len(order._positions) + 1) position.attendee_name_parts = {'_scheme': event.settings.name_scheme} position.meta_info = {} @@ -115,13 +145,24 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user, position.assign_pseudonymization_id() for c in cols: - c.assign(record.get(c.identifier), order, position, order._address) + value = record.get(c.identifier) + if getattr(c, "order_level", False) and value != current_order_level_data.get(c.identifier): + raise DataImportError( + _('Inconsistent data in row {row}: Column {col} contains value "{val_line}", but ' + 'for this order, the value has already been set to "{val_order}".').format( + row=i + 1, + col=c.verbose_name, + val_line=value, + val_order=current_order_level_data.get(c.identifier) or "", + ) + ) + c.assign(value, order, position, order._address) if position.seat is not None: lock_seats.append((order.sales_channel, position.seat)) except (ValidationError, ImportError) as e: raise DataImportError( - _('Invalid data in row {row}: {message}').format(row=i, message=str(e)) + _('Invalid data in row {row}: {message}').format(row=i + 1, message=str(e)) ) try: diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index 32d14da3e..319084816 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -62,6 +62,7 @@ from django.utils.translation import gettext as _, gettext_lazy, ngettext_lazy from django_scopes import scopes_disabled from pretix.api.models import OAuthApplication +from pretix.base.decimal import round_decimal from pretix.base.email import get_email_context from pretix.base.i18n import get_language_without_region, language from pretix.base.media import MEDIA_TYPES @@ -83,6 +84,8 @@ from pretix.base.secrets import assign_ticket_secret from pretix.base.services import tickets from pretix.base.services.invoices import ( generate_cancellation, generate_invoice, invoice_qualified, + invoice_transmission_separately, order_invoice_transmission_separately, + transmit_invoice, ) from pretix.base.services.locking import ( LOCK_TRUST_WINDOW, LockTimeoutException, lock_objects, @@ -96,6 +99,7 @@ from pretix.base.services.pricing import ( ) from pretix.base.services.quotas import QuotaAvailability from pretix.base.services.tasks import ProfiledEventTask, ProfiledTask +from pretix.base.services.tax import split_fee_for_taxes from pretix.base.signals import ( order_approved, order_canceled, order_changed, order_denied, order_expired, order_expiry_changed, order_fee_calculation, order_paid, order_placed, @@ -387,13 +391,19 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False order_approved.send(order.event, order=order) invoice = order.invoices.last() # Might be generated by plugin already + + transmit_invoice_task = order_invoice_transmission_separately(order) + transmit_invoice_mail = not transmit_invoice_task and order.event.settings.invoice_email_attachment and order.email + if order.event.settings.get('invoice_generate') == 'True' and invoice_qualified(order): if not invoice: invoice = generate_invoice( order, - trigger_pdf=not order.event.settings.invoice_email_attachment or not order.email + # send_mail will trigger PDF generation later + trigger_pdf=not transmit_invoice_mail ) - # send_mail will trigger PDF generation later + if transmit_invoice_task: + transmit_invoice.apply_async(args=(order.event_id, invoice.pk, False)) if send_mail: with language(order.locale, order.event.settings.region): @@ -421,7 +431,7 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False order.total == Decimal('0.00') or order.valid_if_pending ), - invoices=[invoice] if invoice and order.event.settings.invoice_email_attachment else [] + invoices=[invoice] if invoice and transmit_invoice_mail else [] ) except SendMailException: logger.exception('Order approved email could not be sent') @@ -486,7 +496,7 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None): def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device=None, oauth_application=None, - cancellation_fee=None, keep_fees=None, cancel_invoice=True, comment=None): + cancellation_fee=None, keep_fees=None, cancel_invoice=True, comment=None, tax_mode=None): """ Mark this order as canceled :param order: The order to change @@ -506,6 +516,10 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device oauth_application = OAuthApplication.objects.get(pk=oauth_application) if isinstance(cancellation_fee, str): cancellation_fee = Decimal(cancellation_fee) + elif isinstance(cancellation_fee, (float, int)): + cancellation_fee = round_decimal(cancellation_fee, order.event.currency) + + tax_mode = tax_mode or order.event.settings.tax_rule_cancellation if not order.cancel_allowed(): raise OrderError(_('You cannot cancel this order.')) @@ -533,7 +547,9 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device m.save() if cancellation_fee: + positions = [] for position in order.positions.all(): + positions.append(position) if position.voucher: Voucher.objects.filter(pk=position.voucher.pk).update(redeemed=Greatest(0, F('redeemed') - 1)) position.canceled = True @@ -546,18 +562,39 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device if keep_fees and fee in keep_fees: new_fee -= fee.value else: + positions.append(fee) fee.canceled = True fee.save(update_fields=['canceled']) if new_fee: - f = OrderFee( - fee_type=OrderFee.FEE_TYPE_CANCELLATION, - value=new_fee, - tax_rule=order.event.settings.tax_rate_default, - order=order, - ) - f._calculate_tax() - f.save() + tax_rule_zero = TaxRule.zero() + if tax_mode == "default": + fee_values = [(order.event.cached_default_tax_rule or tax_rule_zero, new_fee)] + elif tax_mode == "split": + fee_values = split_fee_for_taxes(positions, new_fee, order.event) + else: + fee_values = [(tax_rule_zero, new_fee)] + + try: + ia = order.invoice_address + except InvoiceAddress.DoesNotExist: + ia = None + + for tax_rule, price in fee_values: + tax_rule = tax_rule or tax_rule_zero + tax = tax_rule.tax( + price, invoice_address=ia, base_price_is="gross" + ) + f = OrderFee( + fee_type=OrderFee.FEE_TYPE_CANCELLATION, + value=price, + order=order, + tax_rate=tax.rate, + tax_code=tax.code, + tax_value=tax.tax, + tax_rule=tax_rule, + ) + f.save() if cancellation_fee > order.total: raise OrderError(_('The cancellation fee cannot be higher than the total amount of this order.')) @@ -590,6 +627,11 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device order.create_transactions() + transmit_invoices_task = [i for i in invoices if invoice_transmission_separately(i)] + transmit_invoices_mail = [i for i in invoices if i not in transmit_invoices_task and order.event.settings.invoice_email_attachment] + for i in transmit_invoices_task: + transmit_invoice.apply_async(args=(order.event_id, i.pk, False)) + if send_mail: with language(order.locale, order.event.settings.region): email_template = order.event.settings.mail_text_order_canceled @@ -599,7 +641,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device order.send_mail( email_subject, email_template, email_context, 'pretix.event.order.email.order_canceled', user, - invoices=invoices if order.event.settings.invoice_email_attachment else [] + invoices=transmit_invoices_mail, ) except SendMailException: logger.exception('Order canceled email could not be sent') @@ -1056,11 +1098,12 @@ def _create_order(event: Event, *, email: str, positions: List[CartPosition], no def _order_placed_email(event: Event, order: Order, email_template, subject_template, log_entry: str, invoice, payments: List[OrderPayment], is_free=False): email_context = get_email_context(event=event, order=order, payments=payments) + try: order.send_mail( subject_template, email_template, email_context, log_entry, - invoices=[invoice] if invoice and event.settings.invoice_email_attachment else [], + invoices=[invoice] if invoice else [], attach_tickets=True, attach_ical=event.settings.mail_attach_ical and ( not event.settings.mail_attach_ical_paid_only or @@ -1249,6 +1292,9 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis not order.require_approval ) + transmit_invoice_task = order_invoice_transmission_separately(order) + transmit_invoice_mail = not transmit_invoice_task and order.event.settings.invoice_email_attachment and order.email + invoice = order.invoices.last() # Might be generated by plugin already if not invoice and invoice_qualified(order): invoice_required = ( @@ -1262,9 +1308,11 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis if invoice_required: invoice = generate_invoice( order, - trigger_pdf=not event.settings.invoice_email_attachment or not order.email + # send_mail will trigger PDF generation later + trigger_pdf=not transmit_invoice_mail ) - # send_mail will trigger PDF generation later + if transmit_invoice_task: + transmit_invoice.apply_async(args=(event.pk, invoice.pk, False)) if order.email: if order.require_approval: @@ -1291,8 +1339,16 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis subject_attendees_template = event.settings.mail_subject_order_placed_attendee if sales_channel.identifier in event.settings.mail_sales_channel_placed_paid: - _order_placed_email(event, order, email_template, subject_template, log_entry, invoice, payment_objs, - is_free=free_order_flow) + _order_placed_email( + event, + order, + email_template, + subject_template, + log_entry, + invoice if transmit_invoice_mail else None, + payment_objs, + is_free=free_order_flow + ) if email_attendees: for p in order.positions.all(): if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email: @@ -2895,17 +2951,36 @@ class OrderChangeManager: if self.split_order: self.split_order.create_transactions() + transmit_invoices_task = [i for i in self._invoices if invoice_transmission_separately(i)] + transmit_invoices_mail = [ + i for i in self._invoices + if i not in transmit_invoices_task and self.event.settings.invoice_email_attachment and self.order.email + ] + + if self.split_order: + split_invoices = list(self.split_order.invoices.all()) + transmit_invoices_task += [ + i for i in split_invoices if invoice_transmission_separately(i) + ] + split_transmit_invoices_mail = [ + i for i in split_invoices + if i not in transmit_invoices_task and self.event.settings.invoice_email_attachment and self.order.email + ] + if self.notify: notify_user_changed_order( self.order, self.user, self.auth, - self._invoices if self.event.settings.invoice_email_attachment else [] + transmit_invoices_mail, ) if self.split_order: notify_user_changed_order( self.split_order, self.user, self.auth, - list(self.split_order.invoices.all()) if self.event.settings.invoice_email_attachment else [] + split_transmit_invoices_mail, ) + for i in transmit_invoices_task: + transmit_invoice.apply_async(args=(self.event.pk, i.pk, False)) + order_changed.send(self.order.event, order=self.order) def _clear_tickets_cache(self): diff --git a/src/pretix/base/services/tax.py b/src/pretix/base/services/tax.py index 5d442c504..e4eb37a10 100644 --- a/src/pretix/base/services/tax.py +++ b/src/pretix/base/services/tax.py @@ -22,6 +22,8 @@ import logging import os import re +from collections import defaultdict +from decimal import Decimal from xml.etree import ElementTree import requests @@ -32,7 +34,9 @@ from zeep import Client, Transport from zeep.cache import SqliteCache from zeep.exceptions import Fault -from pretix.base.models.tax import cc_to_vat_prefix, is_eu_country +from pretix.base.decimal import round_decimal +from pretix.base.models import CartPosition, Event, OrderFee +from pretix.base.models.tax import TaxRule, cc_to_vat_prefix, is_eu_country logger = logging.getLogger(__name__) error_messages = { @@ -229,3 +233,64 @@ def validate_vat_id(vat_id, country_code): return _validate_vat_id_NO(vat_id, country_code) raise VATIDTemporaryError(f'VAT ID should not be entered for country {country_code}') + + +def split_fee_for_taxes(positions: list, fee_value: Decimal, event: Event): + """ + Given a list of either OrderPosition, OrderFee or CartPosition objects and the total value + of a fee, this will return a list of [(tax_rule, fee_value)] tuples that distributes the + taxes over the same tax rules as the positions with a value representative to the value + the tax rule. + + Since the input fee_value is a gross value, we also split it by the gross percentages of + positions. This will lead to the same result as if we split the net value by net percentages, + but is easier to compute. + """ + d = defaultdict(lambda: Decimal("0.00")) + tax_rule_zero = TaxRule.zero() + trs = {} + for p in positions: + if isinstance(p, CartPosition): + tr = p.item.tax_rule + v = p.price + elif isinstance(p, OrderFee): + tr = p.tax_rule + v = p.value + else: + tr = p.tax_rule + v = p.price + if not tr: + tr = tax_rule_zero + # use tr.pk as key as tax_rule_zero is not hashable + d[tr.pk] += v + trs[tr.pk] = tr + + base_values = sorted([(trs[key], value) for key, value in d.items()], key=lambda t: t[0].rate) + sum_base = sum(value for key, value in base_values) + if sum_base: + fee_values = [ + (key, round_decimal(fee_value * value / sum_base, event.currency)) + for key, value in base_values + ] + sum_fee = sum(value for key, value in fee_values) + + # If there are rounding differences, we fix them up, but always leaning to the benefit of the tax + # authorities + if sum_fee > fee_value: + fee_values[0] = ( + fee_values[0][0], + fee_values[0][1] + (fee_value - sum_fee), + ) + elif sum_fee < fee_value: + fee_values[-1] = ( + fee_values[-1][0], + fee_values[-1][1] + (fee_value - sum_fee), + ) + elif len(d) == 1: + # Rare edge case: All positions are 0-valued, but have a common tax rate. Could happen e.g. with a discount + # that reduces all positions to 0, but not the shipping fees. Let's use that tax rate! + fee_values = [(list(trs.values())[0], fee_value)] + else: + # All positions are zero-valued, and we have no clear tax rate, so we use the default tax rate. + fee_values = [(event.cached_default_tax_rule or tax_rule_zero, fee_value)] + return fee_values diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index d9d93ea3c..fbc52b31a 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -66,7 +66,7 @@ from pretix.api.serializers.fields import ( ) from pretix.api.serializers.i18n import I18nURLField 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 from pretix.base.reldate import ( RelativeDateField, RelativeDateTimeField, RelativeDateWrapper, SerializerRelativeDateField, SerializerRelativeDateTimeField, @@ -114,7 +114,7 @@ def restricted_plugin_kwargs(): from pretix.base.plugins import get_all_plugins plugins_available = [ - (p.module, p.name) for p in get_all_plugins(None) + (p.module, p.name) for p in get_all_plugins() if ( not p.name.startswith('.') and getattr(p, 'restricted', False) and @@ -1027,9 +1027,47 @@ DEFAULTS = { widget=forms.CheckboxInput, ) }, - 'tax_rate_default': { - 'default': None, - 'type': TaxRule + 'tax_rule_payment': { + 'default': 'default', + 'type': str, + 'form_class': forms.ChoiceField, + 'serializer_class': serializers.ChoiceField, + 'serializer_kwargs': dict( + choices=( + ('default', _('Use default tax rate')), + ('none', _('Charge no taxes')), + ), + ), + 'form_kwargs': dict( + label=_("Tax handling on payment fees"), + widget=forms.RadioSelect, + choices=( + ('default', _('Use default tax rate')), + ('none', _('Charge no taxes')), + ), + ) + }, + 'tax_rule_cancellation': { + 'default': 'none', + 'type': str, + 'form_class': forms.ChoiceField, + 'serializer_class': serializers.ChoiceField, + 'serializer_kwargs': dict( + choices=( + ('none', _('Charge no taxes')), + ('split', _('Use same taxes as order positions (split according to net prices)')), + ('default', _('Use default tax rate')), + ), + ), + 'form_kwargs': dict( + label=_("Tax handling on cancellation fees"), + widget=forms.RadioSelect, + choices=( + ('none', _('Charge no taxes')), + ('split', _('Use same taxes as order positions (split according to net prices)')), + ('default', _('Use default tax rate')), + ), + ) }, 'invoice_generate': { 'default': 'False', @@ -2657,6 +2695,20 @@ You can change your order details and view the status of your order at {url} Best regards, +Your {event} team""")) # noqa: W291 + }, + 'mail_subject_order_invoice': { + 'type': LazyI18nString, + 'default': LazyI18nString.from_gettext(gettext_noop("Invoice {invoice_number}")), + }, + 'mail_text_order_invoice': { + 'type': LazyI18nString, + 'default': LazyI18nString.from_gettext(gettext_noop("""Hello, + +please find attached a new invoice for order {code} for {event}. This order has been placed by {order_email}. + +Best regards, + Your {event} team""")) # noqa: W291 }, 'mail_days_download_reminder': { diff --git a/src/pretix/base/shredder.py b/src/pretix/base/shredder.py index bc0ea800a..b1d22a014 100644 --- a/src/pretix/base/shredder.py +++ b/src/pretix/base/shredder.py @@ -524,8 +524,11 @@ class InvoiceAddressShredder(BaseDataShredder): d = le.parsed_data if 'invoice_data' in d and not isinstance(d['invoice_data'], bool): for field in d['invoice_data']: - if d['invoice_data'][field]: - d['invoice_data'][field] = '█' + if d['invoice_data'][field] and field != "transmission_type": + if field == "transmission_info": + d['invoice_data'][field] = {"_shredded": True} + else: + d['invoice_data'][field] = '█' le.data = json.dumps(d) le.shredded = True le.save(update_fields=['data', 'shredded']) @@ -600,6 +603,7 @@ class InvoiceShredder(BaseDataShredder): i.additional_text = "█" i.invoice_to = "█" i.payment_provider_text = "█" + i.transmission_info = {"_shredded": True} i.save() i.lines.update(description="█") diff --git a/src/pretix/base/signals.py b/src/pretix/base/signals.py index 7b996cffe..2b17fccf6 100644 --- a/src/pretix/base/signals.py +++ b/src/pretix/base/signals.py @@ -33,16 +33,23 @@ # License for the specific language governing permissions and limitations under the License. import warnings -from typing import Any, Callable, List, Tuple +from typing import Any, Callable, Generic, List, Tuple, TypeVar import django.dispatch from django.apps import apps from django.conf import settings +from django.core.exceptions import ImproperlyConfigured from django.dispatch.dispatcher import NO_RECEIVERS -from .models import Event +from .models.event import Event +from .models.organizer import Organizer +from .plugins import ( + PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, + PLUGIN_LEVEL_ORGANIZER, +) app_cache = {} +T = TypeVar('T') def _populate_app_cache(): @@ -56,6 +63,9 @@ def get_defining_app(o): if "sentry" in o.__module__: o = o.__wrapped__ + if hasattr(o, "__mocked_app"): + return o.__mocked_app + # Find the Django application this belongs to searchpath = o.__module__ @@ -74,43 +84,71 @@ def get_defining_app(o): return app -def is_app_active(sender, app): +def is_app_active(sender, app, allow_legacy_plugins=False): if app == 'CORE': return True excluded = settings.PRETIX_PLUGINS_EXCLUDE - if sender and app and app.name in sender.get_plugins() and app.name not in excluded: + if not sender or not app or app.name in excluded: + return False + + level = getattr(app.PretixPluginMeta, "level", PLUGIN_LEVEL_EVENT) + if level == PLUGIN_LEVEL_EVENT: + if isinstance(sender, Event): + enabled = app.name in sender.get_plugins() + elif isinstance(sender, Organizer) and allow_legacy_plugins: + # Deprecated behaviour: Event plugins that are registered on organizer level are considered active for + # all organizers in the context of signals that used to be global signals before the introduction of + # organizer-level plugin. A deprecation warning is emitted at .connect() time. + enabled = True + else: + raise ImproperlyConfigured(f"Cannot check if event-level plugin is active on {type(sender)}") + elif level == PLUGIN_LEVEL_ORGANIZER: + if isinstance(sender, Organizer): + enabled = app.name in sender.get_plugins() + elif isinstance(sender, Event): + enabled = app.name in sender.organizer.get_plugins() + else: + raise ImproperlyConfigured(f"Cannot check if organizer-level plugin is active on {type(sender)}") + elif level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID: + if isinstance(sender, Organizer): + enabled = app.name in sender.get_plugins() + elif isinstance(sender, Event): + enabled = app.name in sender.get_plugins() and app.name in sender.organizer.get_plugins() + else: + raise ImproperlyConfigured(f"Cannot check if hybrid event/organizer-level plugin is active on {type(sender)}") + else: + raise ImproperlyConfigured("Unknown plugin level") + + if enabled: if not hasattr(app, 'compatibility_errors') or not app.compatibility_errors: return True return False -def is_receiver_active(sender, receiver): +def is_receiver_active(sender, receiver, allow_legacy_plugins=False): if sender is None: # Send to all events! return True app = get_defining_app(receiver) - return is_app_active(sender, app) + return is_app_active(sender, app, allow_legacy_plugins) -class EventPluginSignal(django.dispatch.Signal): - """ - This is an extension to Django's built-in signals which differs in a way that it sends - out it's events only to receivers which belong to plugins that are enabled for the given - Event. - """ +class PluginSignal(Generic[T], django.dispatch.Signal): + type = None - def send(self, sender: Event, **named) -> List[Tuple[Callable, Any]]: + def _is_receiver_active(self, sender, receiver): + return is_receiver_active(sender, receiver) + + def send(self, sender: T, **named) -> List[Tuple[Callable, Any]]: """ Send signal from sender to all connected receivers that belong to - plugins enabled for the given Event. - - sender is required to be an instance of ``pretix.base.models.Event``. + plugins enabled for the given event / organizer. """ - if sender and not isinstance(sender, Event): - raise ValueError("Sender needs to be an event.") + if sender and not isinstance(sender, self.type): + raise ValueError(f"Sender needs to be of type {self.type}.") responses = [] if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS: @@ -120,20 +158,18 @@ class EventPluginSignal(django.dispatch.Signal): _populate_app_cache() for receiver in self._sorted_receivers(sender): - if is_receiver_active(sender, receiver): + if self._is_receiver_active(sender, receiver): response = receiver(signal=self, sender=sender, **named) responses.append((receiver, response)) return responses - def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]: + def send_chained(self, sender: T, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]: """ Send signal from sender to all connected receivers. The return value of the first receiver will be used as the keyword argument specified by ``chain_kwarg_name`` in the input to the second receiver and so on. The return value of the last receiver is returned by this method. - - sender is required to be an instance of ``pretix.base.models.Event``. """ - if sender and not isinstance(sender, Event): + if sender and not isinstance(sender, self.type): raise ValueError("Sender needs to be an event.") response = named.get(chain_kwarg_name) @@ -144,20 +180,18 @@ class EventPluginSignal(django.dispatch.Signal): _populate_app_cache() for receiver in self._sorted_receivers(sender): - if is_receiver_active(sender, receiver): + if self._is_receiver_active(sender, receiver): named[chain_kwarg_name] = response response = receiver(signal=self, sender=sender, **named) return response - def send_robust(self, sender: Event, **named) -> List[Tuple[Callable, Any]]: + def send_robust(self, sender: T, **named) -> List[Tuple[Callable, Any]]: """ Send signal from sender to all connected receivers. If a receiver raises an exception instead of returning a value, the exception is included as the result instead of stopping the response chain at the offending receiver. - - sender is required to be an instance of ``pretix.base.models.Event``. """ - if sender and not isinstance(sender, Event): + if sender and not isinstance(sender, self.type): raise ValueError("Sender needs to be an event.") responses = [] @@ -171,7 +205,7 @@ class EventPluginSignal(django.dispatch.Signal): _populate_app_cache() for receiver in self._sorted_receivers(sender): - if is_receiver_active(sender, receiver): + if self._is_receiver_active(sender, receiver): try: response = receiver(signal=self, sender=sender, **named) except Exception as err: @@ -193,6 +227,67 @@ class EventPluginSignal(django.dispatch.Signal): return sorted_list +class EventPluginSignal(PluginSignal[Event]): + """ + This is an extension to Django's built-in signals which differs in a way that it sends + out it's events only to receivers which belong to plugins that are enabled for the given + Event. + """ + type = Event + + def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): + app = get_defining_app(receiver) + if app != "CORE": + if not hasattr(app, "PretixPluginMeta"): + raise ImproperlyConfigured( + f"{app} uses an EventPluginSignal but is not a pretix plugin" + ) + allowed_levels = (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, PLUGIN_LEVEL_EVENT) + if getattr(app.PretixPluginMeta, "level", PLUGIN_LEVEL_EVENT) not in allowed_levels: + # This check is redundant for now, but will be useful if we ever add other levels + raise ImproperlyConfigured( + f"{app} uses an EventPluginSignal but is not a plugin that can be active on event or organizer level" + ) + return super().connect(receiver, sender, weak, dispatch_uid) + + +class OrganizerPluginSignal(PluginSignal[Organizer]): + """ + This is an extension to Django's built-in signals which differs in a way that it sends + out it's events only to receivers which belong to plugins that are enabled for the given + Organizer. + """ + type = Organizer + + def __init__(self, allow_legacy_plugins=False): + self.allow_legacy_plugins = allow_legacy_plugins + super().__init__() + + def _is_receiver_active(self, sender, receiver): + return is_receiver_active(sender, receiver, allow_legacy_plugins=self.allow_legacy_plugins) + + def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): + app = get_defining_app(receiver) + if app != "CORE": + if not hasattr(app, "PretixPluginMeta"): + raise ImproperlyConfigured( + f"{app} uses an OrganizerPluginSignal but is not a pretix plugin" + ) + allowed_levels = (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID) + if getattr(app.PretixPluginMeta, "level", PLUGIN_LEVEL_EVENT) not in allowed_levels: + if getattr(app.PretixPluginMeta, "level", PLUGIN_LEVEL_EVENT) == PLUGIN_LEVEL_EVENT and self.allow_legacy_plugins: + warnings.warn( + 'This signal will soon be only available for plugins that declare to be organizer-level', + stacklevel=3, + category=DeprecationWarning, + ) + else: + raise ImproperlyConfigured( + f"{app} uses an OrganizerPluginSignal but is not a plugin that can be active on organizer level" + ) + return super().connect(receiver, sender, weak, dispatch_uid) + + class GlobalSignal(django.dispatch.Signal): def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]: """ @@ -211,10 +306,14 @@ class GlobalSignal(django.dispatch.Signal): return response -class DeprecatedSignal(django.dispatch.Signal): +class DeprecatedSignal(GlobalSignal): def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): - warnings.warn('This signal is deprecated and will soon be removed', stacklevel=3) + warnings.warn( + 'This signal is deprecated and will soon be removed', + stacklevel=3, + category=DeprecationWarning, + ) super().connect(receiver, sender=None, weak=True, dispatch_uid=None) @@ -257,8 +356,14 @@ class Registry: When a new entry is registered, all accessor functions are called with the new entry as parameter. Their return value is stored as the metadata value for that key. """ - self.registered_entries = dict() self.keys = keys + self.clear() + + def clear(self): + """ + Removes all entries from the registry. + """ + self.registered_entries = dict() self.by_key = {key: {} for key in self.keys.keys()} def register(self, *objs): @@ -318,20 +423,59 @@ class Registry: ) -class EventPluginRegistry(Registry): +class PluginAwareRegistry(Registry): """ A Registry which automatically annotates entries with a "plugin" key, specifying which plugin the entry is defined in. This allows the consumer of entries to determine whether an entry is - enabled for a given event, or filter only for entries defined by enabled plugins. + enabled for a given event or organizer, or filter only for entries defined by enabled plugins. .. code-block:: python logtype, meta = my_registry.find(action_type="foo.bar.baz") # meta["plugin"] contains the django app name of the defining plugin """ + allowed_levels = [ + PLUGIN_LEVEL_EVENT, + PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, + PLUGIN_LEVEL_ORGANIZER, + ] def __init__(self, keys): - super().__init__({"plugin": lambda o: get_defining_app(o), **keys}) + def get_plugin(o): + app = get_defining_app(o) + if app != "CORE": + if not hasattr(app, "PretixPluginMeta"): + raise ImproperlyConfigured( + f"{app} uses an PluginAwareRegistry but is not a pretix plugin" + ) + level = getattr(app.PretixPluginMeta, "level", PLUGIN_LEVEL_EVENT) + if level not in self.allowed_levels: + raise ImproperlyConfigured( + f"{app} has level {level} but should have one of {self.allowed_levels} to use this registry" + ) + return app + + super().__init__({"plugin": get_plugin, **keys}) + + def filter(self, active_in=None, **kwargs): + result = super().filter(**kwargs) + if active_in is not None: + result = ( + (entry, meta) + for entry, meta in result + if is_app_active(active_in, meta['plugin']) + ) + return result + + def get(self, active_in=None, **kwargs): + item, meta = super().get(**kwargs) + if meta and active_in is not None: + if not is_app_active(active_in, meta['plugin']): + return None, None + return item, meta + + +EventPluginRegistry = PluginAwareRegistry # for backwards compatibility event_live_issues = EventPluginSignal() @@ -426,7 +570,7 @@ This signal is sent out when a notification is sent. As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ -register_sales_channel_types = django.dispatch.Signal() +register_sales_channel_types = GlobalSignal() """ This signal is sent out to get all known sales channels types. Receivers should return an instance of a subclass of ``pretix.base.channels.SalesChannelType`` or a list of such @@ -444,10 +588,8 @@ subclass of pretix.base.exporter.BaseExporter As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ -register_multievent_data_exporters = django.dispatch.Signal() +register_multievent_data_exporters = OrganizerPluginSignal(allow_legacy_plugins=True) """ -Arguments: ``event`` - This signal is sent out to get all known data exporters, which support exporting data for multiple events. Receivers should return a subclass of pretix.base.exporter.BaseExporter @@ -645,6 +787,16 @@ For backwards compatibility reasons, this signal is only sent when a **successfu As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ +checkin_annulled = EventPluginSignal() +""" +Arguments: ``checkin`` + +This signal is sent out every time a check-in is annulled (i.e. changed to unsuccessful after it +already was successful). + +As with all event-plugin signals, the ``sender`` keyword argument will contain the event. +""" + logentry_display = EventPluginSignal() """ Arguments: ``logentry`` @@ -709,7 +861,7 @@ The ``sender`` keyword argument will contain the event. The ``target`` will cont copy to, the ``source`` keyword argument will contain the product to **copy from**. """ -periodic_task = django.dispatch.Signal() +periodic_task = GlobalSignal() """ This is a regular django signal (no pretix event signal) that we send out every time the periodic task cronjob runs. This interval is not sharply defined, it can @@ -718,13 +870,13 @@ idempotent, i.e. it should not make a difference if this is sent out more often than expected. """ -register_global_settings = django.dispatch.Signal() +register_global_settings = GlobalSignal() """ All plugins that are installed may send fields for the global settings form, as an OrderedDict of (setting name, form field). """ -gift_card_transaction_display = django.dispatch.Signal() +gift_card_transaction_display = GlobalSignal() # todo: replace with OrganizerPluginSignal? """ Arguments: ``transaction``, ``customer_facing`` @@ -936,7 +1088,7 @@ return a dictionary mapping names of attributes in the settings store to DRF ser As with all event-plugin signals, the ``sender`` keyword argument will contain the event. """ -customer_created = GlobalSignal() +customer_created = OrganizerPluginSignal(allow_legacy_plugins=True) """ Arguments: ``customer`` @@ -946,7 +1098,7 @@ object is given as the first argument. The ``sender`` keyword argument will contain the organizer. """ -customer_signed_in = GlobalSignal() +customer_signed_in = OrganizerPluginSignal(allow_legacy_plugins=True) """ Arguments: ``customer`` @@ -956,7 +1108,7 @@ is given as the first argument. The ``sender`` keyword argument will contain the organizer. """ -device_info_updated = django.dispatch.Signal() +device_info_updated = GlobalSignal() # todo: replace with OrganizerPluginSignal? """ Arguments: ``old_device``, ``new_device`` diff --git a/src/pretix/base/templates/pretixbase/email/order_details.html b/src/pretix/base/templates/pretixbase/email/order_details.html index 77f5f556c..4824cd9fe 100644 --- a/src/pretix/base/templates/pretixbase/email/order_details.html +++ b/src/pretix/base/templates/pretixbase/email/order_details.html @@ -60,11 +60,17 @@ {{ event.name }} - {% if not event.has_subevents and event.settings.show_dates_on_frontpage %} -
- {{ event.get_date_range_display }} - {% if event.settings.show_times %} - {{ event.date_from|date:"TIME_FORMAT" }} + {% if not event.has_subevents %} + {% if event.settings.show_dates_on_frontpage %} +
+ {{ event.get_date_range_display }} + {% if event.settings.show_times %} + {{ event.date_from|date:"TIME_FORMAT" }} + {% endif %} + {% endif %} + {% if event.location %} +
+ {{ event.location|oneline }} {% endif %} {% endif %} diff --git a/src/pretix/base/views/js_helpers.py b/src/pretix/base/views/js_helpers.py index 303578ec7..693dc0b71 100644 --- a/src/pretix/base/views/js_helpers.py +++ b/src/pretix/base/views/js_helpers.py @@ -21,38 +21,107 @@ # import pycountry from django.http import JsonResponse +from django.shortcuts import get_object_or_404 from django.utils.translation import pgettext +from django_countries.fields import Country +from django_scopes import scope from pretix.base.addressvalidation import ( COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED, ) +from pretix.base.invoicing.transmission import get_transmission_types +from pretix.base.models import Organizer from pretix.base.models.tax import VAT_ID_COUNTRIES from pretix.base.settings import ( COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL, ) -def states(request): - cc = request.GET.get("country", "DE") +def _info(cc): info = { - 'street': {'required': True}, - 'zipcode': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED}, - 'city': {'required': cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED}, + 'street': {'required': 'if_any'}, + 'zipcode': {'required': 'if_any' if cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED else False}, + 'city': {'required': 'if_any' if cc in COUNTRIES_WITH_STREET_ZIPCODE_AND_CITY_REQUIRED else False}, 'state': { 'visible': cc in COUNTRIES_WITH_STATE_IN_ADDRESS, - 'required': cc in COUNTRIES_WITH_STATE_IN_ADDRESS, + 'required': 'if_any' if cc in COUNTRIES_WITH_STATE_IN_ADDRESS else False, 'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')), }, 'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False}, } if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS: - return JsonResponse({'data': [], **info, }) + return {'data': [], **info} types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc] statelist = [s for s in pycountry.subdivisions.get(country_code=cc) if s.type in types] - return JsonResponse({ + return { 'data': [ {'name': s.name, 'code': s.code[3:]} for s in sorted(statelist, key=lambda s: s.name) ], **info, - }) + } + + +def address_form(request): + cc = request.GET.get("country", "DE") + info = _info(cc) + + if request.GET.get("invoice") == "true": + # Do not consider live=True, as this does not expose sensitive information and we also want it accessible + # from e.g. the backend when the event is not yet life. + organizer = get_object_or_404(Organizer, slug=request.GET.get("organizer")) + with (scope(organizer=organizer)): + event = get_object_or_404(organizer.events, slug=request.GET.get("event")) + country = Country(cc) + is_business = request.GET.get("is_business") == "business" + selected_transmission_type = request.GET.get("transmission_type") + transmission_type_required = request.GET.get("transmission_type_required") == "true" + + info["transmission_types"] = [] + + for t in get_transmission_types(): + if t.is_available(event=event, country=country, is_business=is_business): + result = {"name": str(t.public_name), "code": t.identifier} + if t.exclusive: + info["transmission_types"] = [result] + break + else: + info["transmission_types"].append(result) + + info["transmission_type"] = { + # Hide transmission type if email is the only type since that's basically the backwards-compatible + # option + "visible": [t["code"] for t in info["transmission_types"]] != ["email"], + } + if selected_transmission_type not in [t["code"] for t in info["transmission_types"]]: + if transmission_type_required: + # The previously selected transmission type is no longer selectable, e.g. because + # of a country change. To avoid a second roundtrip to this endpoint, let's show + # the fields as if the first remaining option were selected (which is what the client + # side will now do). + selected_transmission_type = info["transmission_types"][0]["code"] + else: + selected_transmission_type = "-" + + for transmission_type in get_transmission_types(): + required = transmission_type.invoice_address_form_fields_required( + country=country, + is_business=is_business + ) + visible = transmission_type.invoice_address_form_fields_visible( + country=country, + is_business=is_business + ) + if transmission_type.identifier == selected_transmission_type: + for k, v in info.items(): + if k in required: + v["required"] = True + if k in visible: + v["visible"] = True + for k, f in transmission_type.invoice_address_form_fields.items(): + info[k] = { + "visible": transmission_type.identifier == selected_transmission_type and k in visible, + "required": transmission_type.identifier == selected_transmission_type and k in required + } + + return JsonResponse(info) diff --git a/src/pretix/base/views/webmanifest.py b/src/pretix/base/views/webmanifest.py new file mode 100644 index 000000000..22a31699a --- /dev/null +++ b/src/pretix/base/views/webmanifest.py @@ -0,0 +1,52 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from django.http import HttpResponse +from django.templatetags.static import static +from django.views.decorators.cache import cache_page + + +@cache_page(3600) +def webmanifest(request): + return HttpResponse( + """{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "%s", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "%s", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#3b1c4a", + "background_color": "#3b1c4a", + "display": "standalone" +}""" % ( + static('pretixbase/img/icons/android-chrome-192x192.png'), + static('pretixbase/img/icons/android-chrome-512x512.png'), + ), content_type='text/json' + ) diff --git a/src/pretix/control/apps.py b/src/pretix/control/apps.py index 1b2148618..05c626b6a 100644 --- a/src/pretix/control/apps.py +++ b/src/pretix/control/apps.py @@ -42,3 +42,4 @@ class PretixControlConfig(AppConfig): def ready(self): from .views import dashboards # noqa from . import logdisplay # noqa + from .views import datasync # noqa diff --git a/src/pretix/control/forms/checkin.py b/src/pretix/control/forms/checkin.py index 207a3d78c..32d4021e3 100644 --- a/src/pretix/control/forms/checkin.py +++ b/src/pretix/control/forms/checkin.py @@ -215,3 +215,9 @@ class CheckinListSimulatorForm(forms.Form): ) self.fields['gate'].widget.choices = self.fields['gate'].choices self.fields['gate'].label = _('Gate') + + +class CheckinResetForm(forms.Form): + ok = forms.BooleanField( + label=_("I am sure that the check-in state of the entire event should be reset.") + ) diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 38772fde7..1b4f6cdc9 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -113,7 +113,6 @@ class EventWizardFoundationForm(forms.Form): attrs={ 'data-model-select2': 'generic', 'data-select2-url': reverse('control:organizers.select2') + '?can_create=1', - 'data-placeholder': _('Organizer') } ), empty_label=None, @@ -761,6 +760,7 @@ class CancelSettingsForm(SettingsForm): 'change_allow_user_addons', 'change_allow_user_if_checked_in', 'change_allow_attendee', + 'tax_rule_cancellation', ] def __init__(self, *args, **kwargs): @@ -783,14 +783,8 @@ class PaymentSettingsForm(EventSettingsValidationMixin, SettingsForm): 'payment_term_accept_late', 'payment_pending_hidden', 'payment_explanation', + 'tax_rule_payment', ] - tax_rate_default = forms.ModelChoiceField( - queryset=TaxRule.objects.none(), - label=_('Tax rule for payment fees'), - required=False, - help_text=_("The tax rule that applies for additional fees you configured for single payment methods. This " - "will set the tax rate and reverse charge rules, other settings of the tax rule are ignored.") - ) def clean_payment_term_days(self): value = self.cleaned_data.get('payment_term_days') @@ -804,10 +798,6 @@ class PaymentSettingsForm(EventSettingsValidationMixin, SettingsForm): raise ValidationError(_("This field is required.")) return value - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields['tax_rate_default'].queryset = self.obj.tax_rules.all() - class ProviderForm(SettingsForm): """ @@ -993,7 +983,10 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm): mail_bcc = forms.CharField( label=_("Bcc address"), - help_text=_("All emails will be sent to this address as a Bcc copy"), + help_text=' '.join([ + str(_("All emails will be sent to this address as a Bcc copy.")), + str(_("You can specify multiple recipients separated by commas.")), + ]), validators=[multimail_validate], required=False, max_length=255 @@ -1206,6 +1199,20 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm): required=False, widget=I18nMarkdownTextarea, ) + mail_subject_order_invoice = I18nFormField( + label=_("Subject"), + required=False, + widget=I18nTextInput, + help_text=_("This will only be used if the invoice is sent to a different email address or at a different time " + "than the order confirmation."), + ) + mail_text_order_invoice = I18nFormField( + label=_("Text"), + required=False, + widget=I18nMarkdownTextarea, + help_text=_("This will only be used if the invoice is sent to a different email address or at a different time " + "than the order confirmation."), + ) mail_subject_download_reminder = I18nFormField( label=_("Subject sent to order contact address"), required=False, @@ -1357,6 +1364,8 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm): 'mail_text_order_payment_failed': ['event', 'order'], 'mail_subject_order_payment_failed': ['event', 'order'], 'mail_text_order_custom_mail': ['event', 'order'], + 'mail_text_order_invoice': ['event', 'order', 'invoice'], + 'mail_subject_order_invoice': ['event', 'order', 'invoice'], 'mail_text_download_reminder': ['event', 'order'], 'mail_subject_download_reminder': ['event', 'order'], 'mail_text_download_reminder_attendee': ['event', 'order', 'position'], diff --git a/src/pretix/control/forms/filter.py b/src/pretix/control/forms/filter.py index 1c3a71195..abb66f03f 100644 --- a/src/pretix/control/forms/filter.py +++ b/src/pretix/control/forms/filter.py @@ -1246,9 +1246,7 @@ class SubEventFilterForm(FilterForm): ) query = forms.CharField( label=_('Event name'), - widget=forms.TextInput(attrs={ - 'placeholder': _('Event name'), - }), + widget=forms.TextInput(), required=False ) @@ -1693,9 +1691,7 @@ class EventFilterForm(FilterForm): ) query = forms.CharField( label=_('Event name'), - widget=forms.TextInput(attrs={ - 'placeholder': _('Event name'), - }), + widget=forms.TextInput(), required=False ) date_from = forms.DateField( @@ -2448,7 +2444,7 @@ class CheckinFilterForm(FilterForm): 'event': self.event.slug, 'organizer': self.event.organizer.slug, }), - 'data-placeholder': _('Check-in list'), + 'data-placeholder': _('All check-in lists'), } ) self.fields['checkin_list'].widget.choices = self.fields['checkin_list'].choices diff --git a/src/pretix/control/forms/item.py b/src/pretix/control/forms/item.py index 083e7f8b0..06aa2496b 100644 --- a/src/pretix/control/forms/item.py +++ b/src/pretix/control/forms/item.py @@ -47,9 +47,7 @@ from django.urls import reverse from django.utils.functional import cached_property from django.utils.html import escape, format_html from django.utils.safestring import mark_safe -from django.utils.translation import ( - gettext as __, gettext_lazy as _, pgettext_lazy, -) +from django.utils.translation import gettext as __, gettext_lazy as _ from django_scopes.forms import ( SafeModelChoiceField, SafeModelMultipleChoiceField, ) @@ -330,7 +328,6 @@ class QuotaForm(I18nModelForm): 'event': self.event.slug, 'organizer': self.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices @@ -352,6 +349,9 @@ class QuotaForm(I18nModelForm): field_classes = { 'subevent': SafeModelChoiceField, } + widgets = { + 'size': forms.NumberInput(attrs={'placeholder': _('Unlimited')}) + } def save(self, *args, **kwargs): creating = not self.instance.pk @@ -406,7 +406,6 @@ class ItemCreateForm(I18nModelForm): self.fields['tax_rule'].queryset = self.instance.event.tax_rules.all() change_decimal_field(self.fields['default_price'], self.instance.event.currency) - self.fields['tax_rule'].empty_label = _('No taxation') self.fields['copy_from'] = forms.ModelChoiceField( label=_("Copy product information"), queryset=self.event.items.all(), @@ -416,6 +415,8 @@ class ItemCreateForm(I18nModelForm): ) if self.event.tax_rules.exists(): self.fields['tax_rule'].required = True + else: + self.fields['tax_rule'].empty_label = _('No taxation') if not self.event.has_subevents: choices = [ diff --git a/src/pretix/control/forms/mapping.py b/src/pretix/control/forms/mapping.py new file mode 100644 index 000000000..1da418688 --- /dev/null +++ b/src/pretix/control/forms/mapping.py @@ -0,0 +1,130 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from itertools import groupby + +from django import forms +from django.forms import formset_factory +from django.utils.translation import gettext_lazy as _ + +from pretix.base.models import Question +from pretix.base.models.datasync import ( + MODE_APPEND_LIST, MODE_OVERWRITE, MODE_SET_IF_EMPTY, MODE_SET_IF_NEW, +) + + +class PropertyMappingForm(forms.Form): + pretix_field = forms.CharField() + external_field = forms.CharField() + value_map = forms.CharField(required=False) + overwrite = forms.ChoiceField( + choices=[ + (MODE_OVERWRITE, _("Overwrite")), + (MODE_SET_IF_NEW, _("Fill if new")), + (MODE_SET_IF_EMPTY, _("Fill if empty")), + (MODE_APPEND_LIST, _("Add to list")), + ] + ) + + def __init__(self, pretix_fields, external_fields_id, available_modes, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields["pretix_field"] = forms.ChoiceField( + label=_("pretix field"), + choices=pretix_fields_choices(pretix_fields, kwargs.get("initial", {}).get("pretix_field")), + required=False, + ) + if external_fields_id: + self.fields["external_field"] = forms.ChoiceField( + widget=forms.Select( + attrs={ + "data-model-select2": "json_script", + "data-select2-src": "#" + external_fields_id, + }, + ), + ) + self.fields["external_field"].choices = [ + (self["external_field"].value(), self["external_field"].value()), + ] + self.fields["overwrite"].choices = [ + (key, label) for (key, label) in self.fields["overwrite"].choices if key in available_modes + ] + + +class PropertyMappingFormSet(formset_factory( + PropertyMappingForm, + can_order=True, + can_delete=True, + extra=0, +)): + template_name = "pretixcontrol/datasync/property_mappings_formset.html" + + def __init__(self, pretix_fields, external_fields, available_modes, prefix, *args, **kwargs): + super().__init__( + form_kwargs={ + "pretix_fields": pretix_fields, + "external_fields_id": prefix + "external-fields" if external_fields else None, + "available_modes": available_modes, + }, + prefix=prefix, + *args, **kwargs) + self.external_fields = external_fields + + def get_context(self): + ctx = super().get_context() + ctx["external_fields"] = self.external_fields + ctx["external_fields_id"] = self.prefix + "external-fields" + return ctx + + def to_property_mappings_list(self): + """ + Returns a property mapping configuration as a JSON-serializable list of dictionaries. + + Each entry specifies how to transfer data from one pretix field to one field in the external system: + + - `pretix_field`: Name of a pretix data source field as declared in `pretix.base.datasync.sourcefields.get_data_fields`. + - `external_field`: Name of the target field in the external system. Implementation-defined by the sync provider. + - `value_map`: Dictionary mapping pretix value to external value. Only used for enumeration-type fields. + - `overwrite`: Mode of operation if the object already exists in the target system. + + - `MODE_OVERWRITE` (`"overwrite"`) to always overwrite existing value. + - `MODE_SET_IF_NEW` (`"if_new"`) to only set the value if object does not exist in target system yet. + - `MODE_SET_IF_EMPTY` (`"if_empty"`) to only set the value if object does not exist in target system, + or the field is currently empty in target system. + - `MODE_APPEND_LIST` (`"append"`) if the field is an array or a multi-select: add the value to the list. + """ + mappings = [f.cleaned_data for f in self.ordered_forms] + return mappings + + +QUESTION_TYPE_LABELS = dict(Question.TYPE_CHOICES) + + +def pretix_fields_choices(pretix_fields, initial_choice): + pretix_fields = sorted(pretix_fields, key=lambda f: f.category) + grouped_fields = groupby(pretix_fields, lambda f: f.category) + return [ + (f"{cat}", [ + (f.key, f.label + " [" + QUESTION_TYPE_LABELS[f.type] + "]") + for f in fields + if not f.deprecated or f.key == initial_choice + ]) + for ((idx, cat), fields) in grouped_fields + ] diff --git a/src/pretix/control/forms/modelimport.py b/src/pretix/control/forms/modelimport.py index 565c48f7e..c96cf29c4 100644 --- a/src/pretix/control/forms/modelimport.py +++ b/src/pretix/control/forms/modelimport.py @@ -20,6 +20,7 @@ # . # from django import forms +from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from pretix.base.modelimport_orders import get_order_import_columns @@ -62,7 +63,8 @@ class ProcessForm(forms.Form): choices=choices, widget=forms.Select( attrs={'data-static': 'true'} - ) + ), + help_text=c.help_text, ) def get_columns(self): @@ -75,14 +77,17 @@ class OrdersProcessForm(ProcessForm): choices=( ('many', _('Create a separate order for each line')), ('one', _('Create one order with one position per line')), - ) + ('mixed', _('Group multiple lines together into the same order based on a grouping column')), + ), + widget=forms.RadioSelect, ) status = forms.ChoiceField( label=_('Order status'), choices=( ('paid', _('Create orders as fully paid')), ('pending', _('Create orders as pending and still require payment')), - ) + ), + widget=forms.RadioSelect, ) testmode = forms.BooleanField( label=_('Create orders as test mode orders'), @@ -99,6 +104,17 @@ class OrdersProcessForm(ProcessForm): def get_columns(self): return get_order_import_columns(self.event) + def clean(self): + data = super().clean() + + grouping = data.get("grouping") and data.get("grouping") != "empty" + if data.get("orders") != "mixed" and grouping: + raise ValidationError({"grouping": [_("A grouping cannot be specified for this import mode.")]}) + if data.get("orders") == "mixed" and not grouping: + raise ValidationError({"grouping": [_("A grouping needs to be specified for this import mode.")]}) + + return data + class VouchersProcessForm(ProcessForm): diff --git a/src/pretix/control/forms/orders.py b/src/pretix/control/forms/orders.py index 77625386f..881920fca 100644 --- a/src/pretix/control/forms/orders.py +++ b/src/pretix/control/forms/orders.py @@ -174,8 +174,7 @@ class CancelForm(forms.Form): label=_('Keep a cancellation fee of'), help_text=_('If you keep a fee, all positions within this order will be canceled and the order will be reduced ' 'to a cancellation fee. Payment and shipping fees will be canceled as well, so include them ' - 'in your cancellation fee if you want to keep them. Please always enter a gross value, ' - 'tax will be calculated automatically.'), + 'in your cancellation fee if you want to keep them.'), ) cancel_invoice = forms.BooleanField( label=_('Generate cancellation for invoice'), @@ -200,6 +199,19 @@ class CancelForm(forms.Form): self.fields['cancellation_fee'].max_value = self.instance.total if not self.instance.invoices.exists(): del self.fields['cancel_invoice'] + if self.instance.event.settings.tax_rule_cancellation == 'split': + self.fields['cancellation_fee'].help_text = str(self.fields['cancellation_fee'].help_text) + ' ' + _( + 'Please enter a gross amount. As per your event settings, the taxes will be split the same way as the ' + 'order positions.' + ) + elif self.instance.event.settings.tax_rule_cancellation == 'default': + self.fields['cancellation_fee'].help_text = str(self.fields['cancellation_fee'].help_text) + ' ' + _( + 'Please enter a gross amount. As per your event settings, the default tax rate will be charged.' + ) + elif self.instance.event.settings.tax_rule_cancellation == 'none': + self.fields['cancellation_fee'].help_text = str(self.fields['cancellation_fee'].help_text) + ' ' + _( + 'As per your event settings, no tax will be charged.' + ) def clean_cancellation_fee(self): val = self.cleaned_data['cancellation_fee'] or Decimal('0.00') @@ -397,7 +409,6 @@ class OrderPositionAddForm(forms.Form): 'event': order.event.slug, 'organizer': order.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices @@ -693,7 +704,6 @@ class OrderContactForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.customers.select2', kwargs={ 'organizer': self.instance.event.organizer.slug, }), - 'data-placeholder': _('Customer') } ) self.fields['customer'].widget.choices = self.fields['customer'].choices diff --git a/src/pretix/control/forms/organizer.py b/src/pretix/control/forms/organizer.py index 688f66629..e3226c776 100644 --- a/src/pretix/control/forms/organizer.py +++ b/src/pretix/control/forms/organizer.py @@ -43,7 +43,7 @@ from django.forms import formset_factory, inlineformset_factory from django.forms.utils import ErrorDict from django.urls import reverse from django.utils.crypto import get_random_string -from django.utils.html import conditional_escape +from django.utils.html import conditional_escape, format_html from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _, pgettext_lazy from django_scopes.forms import SafeModelChoiceField @@ -70,9 +70,9 @@ from pretix.base.forms.widgets import ( SplitDateTimePickerWidget, format_placeholders_help_text, ) from pretix.base.models import ( - Customer, Device, EventMetaProperty, Gate, GiftCard, GiftCardAcceptance, - Membership, MembershipType, OrderPosition, Organizer, ReusableMedium, - SalesChannel, Team, + Customer, Device, Event, EventMetaProperty, Gate, GiftCard, + GiftCardAcceptance, Membership, MembershipType, OrderPosition, Organizer, + ReusableMedium, SalesChannel, Team, ) from pretix.base.models.customers import CustomerSSOClient, CustomerSSOProvider from pretix.base.models.organizer import OrganizerFooterLink @@ -581,7 +581,10 @@ class MailSettingsForm(SettingsForm): mail_bcc = forms.CharField( label=_("Bcc address"), - help_text=_("All emails will be sent to this address as a Bcc copy"), + help_text=''.join([ + str(_("All emails will be sent to this address as a Bcc copy.")), + str(_("You can specify multiple recipients separated by commas.")), + ]), validators=[multimail_validate], required=False, max_length=255 @@ -692,7 +695,9 @@ class WebHookForm(forms.ModelForm): self.fields['events'].choices = [ ( a.action_type, - mark_safe('{} – {}'.format(a.verbose_name, a.action_type)) + format_html('{} – {}
{}', a.verbose_name, a.action_type, a.help_text) + if a.help_text else + format_html('{} – {}', a.verbose_name, a.action_type) ) for a in get_all_webhook_events().values() ] if self.instance and self.instance.pk: @@ -778,7 +783,6 @@ class GiftCardUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.ticket_select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Ticket') } ) self.fields['owner_ticket'].widget.choices = self.fields['owner_ticket'].choices @@ -814,7 +818,6 @@ class ReusableMediumUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.ticket_select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Ticket') } ) self.fields['linked_orderposition'].widget.choices = self.fields['linked_orderposition'].choices @@ -827,7 +830,6 @@ class ReusableMediumUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.giftcards.select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Gift card') } ) self.fields['linked_giftcard'].widget.choices = self.fields['linked_giftcard'].choices @@ -841,7 +843,6 @@ class ReusableMediumUpdateForm(forms.ModelForm): 'data-select2-url': reverse('control:organizer.customers.select2', kwargs={ 'organizer': organizer.slug, }), - 'data-placeholder': _('Customer') } ) self.fields['customer'].widget.choices = self.fields['customer'].choices @@ -1205,3 +1206,19 @@ class SalesChannelForm(I18nModelForm): ) return d + + +class OrganizerPluginEventsForm(forms.Form): + events = SafeEventMultipleChoiceField( + queryset=Event.objects.none(), + widget=forms.CheckboxSelectMultiple(attrs={ + 'class': 'scrolling-multiple-choice scrolling-multiple-choice-large', + }), + label=_("Events with active plugin"), + required=False, + ) + + def __init__(self, *args, **kwargs): + events = kwargs.pop('events') + super().__init__(*args, **kwargs) + self.fields['events'].queryset = events diff --git a/src/pretix/control/forms/subevents.py b/src/pretix/control/forms/subevents.py index 1329a1bc8..c0fcc6f29 100644 --- a/src/pretix/control/forms/subevents.py +++ b/src/pretix/control/forms/subevents.py @@ -133,16 +133,12 @@ class SubEventBulkEditForm(I18nModelForm): # i18n fields if k in self.mixed_values: self.fields[k].widget.attrs['placeholder'] = '[{}]'.format(_('Selection contains various values')) - else: - self.fields[k].widget.attrs['placeholder'] = '' self.fields[k].one_required = False for k in ('geo_lat', 'geo_lon', 'comment'): # scalar fields if k in self.mixed_values: self.fields[k].widget.attrs['placeholder'] = '[{}]'.format(_('Selection contains various values')) - else: - self.fields[k].widget.attrs['placeholder'] = '' self.fields[k].widget.is_required = False self.fields[k].required = False diff --git a/src/pretix/control/forms/vouchers.py b/src/pretix/control/forms/vouchers.py index 3b7498594..669926afc 100644 --- a/src/pretix/control/forms/vouchers.py +++ b/src/pretix/control/forms/vouchers.py @@ -41,7 +41,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.validators import EmailValidator from django.db.models.functions import Upper from django.urls import reverse -from django.utils.translation import gettext_lazy as _, pgettext_lazy +from django.utils.translation import gettext_lazy as _ from django_scopes.forms import SafeModelChoiceField from pretix.base.email import get_available_placeholders @@ -115,7 +115,6 @@ class VoucherForm(I18nModelForm): 'event': instance.event.slug, 'organizer': instance.event.organizer.slug, }), - 'data-placeholder': pgettext_lazy('subevent', 'Date') } ) self.fields['subevent'].widget.choices = self.fields['subevent'].choices @@ -208,12 +207,15 @@ class VoucherForm(I18nModelForm): if self.instance and self.instance.pk: cnt -= self.instance.redeemed # these do not need quota any more - Voucher.clean_item_properties( - data, self.instance.event, - self.instance.quota, self.instance.item, self.instance.variation, - seats_given=data.get('seat') or data.get('seats'), - block_quota=data.get('block_quota') - ) + try: + Voucher.clean_item_properties( + data, self.instance.event, + self.instance.quota, self.instance.item, self.instance.variation, + seats_given=data.get('seat') or data.get('seats'), + block_quota=data.get('block_quota') + ) + except ValidationError as e: + raise ValidationError({"itemvar": e.message}) if not data.get('show_hidden_items') and ( (self.instance.quota and all(i.hide_without_voucher for i in self.instance.quota.items.all())) or (self.instance.item and self.instance.item.hide_without_voucher) @@ -224,10 +226,17 @@ class VoucherForm(I18nModelForm): 'them.') ] }) - Voucher.clean_subevent( - data, self.instance.event - ) - Voucher.clean_max_usages(data, self.instance.redeemed) + + try: + Voucher.clean_subevent( + data, self.instance.event + ) + except ValidationError as e: + raise ValidationError({"subevent": e.message}) + try: + Voucher.clean_max_usages(data, self.instance.redeemed) + except ValidationError as e: + raise ValidationError({"max_usages": e.message}) check_quota = Voucher.clean_quota_needs_checking( data, self.initial_instance_data, item_changed=data.get('itemvar') != self.initial.get('itemvar'), @@ -294,7 +303,7 @@ class VoucherBulkForm(VoucherForm): }), required=False, help_text=_('You can either supply a list of email addresses with one email address per line, or the contents ' - 'of a CSV file with a title column and one or more of the columns "email", "number", "name", ' + 'of a CSV file with a title row and one or more of the columns "email", "number", "name", ' 'or "tag".') ) Recipient = namedtuple('Recipient', 'email number name tag') diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py index 58001cb36..7cf4f1ee5 100644 --- a/src/pretix/control/logdisplay.py +++ b/src/pretix/control/logdisplay.py @@ -43,9 +43,11 @@ from django.dispatch import receiver from django.urls import reverse from django.utils.formats import date_format from django.utils.html import escape, format_html +from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _, pgettext_lazy from i18nfield.strings import LazyI18nString +from pretix.base.datasync.datasync import datasync_providers from pretix.base.logentrytypes import ( DiscountLogEntryType, EventLogEntryType, ItemCategoryLogEntryType, ItemLogEntryType, LogEntryType, OrderLogEntryType, QuestionLogEntryType, @@ -319,6 +321,14 @@ class OrderChangedSplitFrom(OrderLogEntryType): _('Denied scan of position #{posid} at {datetime} for list "{list}", type "{type}", error code "{errorcode}".'), _('Denied scan of position #{posid} for list "{list}", type "{type}", error code "{errorcode}".'), ), + 'pretix.event.checkin.annulled': ( + _('Annulled scan of position #{posid} at {datetime} for list "{list}", type "{type}".'), + _('Annulled scan of position #{posid} for list "{list}", type "{type}".'), + ), + 'pretix.event.checkin.annulment.ignored': ( + _('Ignored annulment of position #{posid} at {datetime} for list "{list}", type "{type}".'), + _('Ignored annulment of position #{posid} for list "{list}", type "{type}".'), + ), 'pretix.control.views.checkin.reverted': _('The check-in of position #{posid} on list "{list}" has been reverted.'), 'pretix.event.checkin.reverted': _('The check-in of position #{posid} on list "{list}" has been reverted.'), }) @@ -421,6 +431,51 @@ class OrderPrintLogEntryType(OrderLogEntryType): ) +class OrderDataSyncLogEntryType(OrderLogEntryType): + def display(self, logentry, data): + try: + from pretix.base.datasync.datasync import datasync_providers + provider_class, meta = datasync_providers.get(identifier=data['provider']) + data['provider_display_name'] = provider_class.display_name + except (KeyError, AttributeError): + data['provider_display_name'] = data.get('provider') + return super().display(logentry, data) + + +@log_entry_types.new_from_dict({ + "pretix.event.order.data_sync.success": _("Data successfully transferred to {provider_display_name}."), +}) +class OrderDataSyncSuccessLogEntryType(OrderDataSyncLogEntryType): + def display(self, logentry, data): + links = [] + if data.get('provider') and data.get('objects'): + prov, meta = datasync_providers.get(identifier=data['provider']) + if prov: + for objs in data['objects'].values(): + links.append(", ".join( + prov.get_external_link_html(logentry.event, obj['external_link_href'], obj['external_link_display_name']) + for obj in objs + if obj and 'external_link_href' in obj and 'external_link_display_name' in obj + )) + + return mark_safe(escape(super().display(logentry, data)) + "".join("

" + link + "

" for link in links)) + + +@log_entry_types.new_from_dict({ + "pretix.event.order.data_sync.failed.config": _("Transferring data to {provider_display_name} failed due to invalid configuration:"), + "pretix.event.order.data_sync.failed.exceeded": _("Maximum number of retries exceeded while transferring data to {provider_display_name}:"), + "pretix.event.order.data_sync.failed.permanent": _("Error while transferring data to {provider_display_name}:"), + "pretix.event.order.data_sync.failed.internal": _("Internal error while transferring data to {provider_display_name}."), + "pretix.event.order.data_sync.failed.timeout": _("Internal error while transferring data to {provider_display_name}."), +}) +class OrderDataSyncErrorLogEntryType(OrderDataSyncLogEntryType): + def display(self, logentry, data): + errmes = data["error"] + if not isinstance(errmes, list): + errmes = [errmes] + return mark_safe(escape(super().display(logentry, data)) + "".join("

" + escape(msg) + "

" for msg in errmes)) + + @receiver(signal=logentry_display, dispatch_uid="pretixcontrol_logentry_display") def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs): @@ -469,6 +524,11 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl 'pretix.event.order.invoice.generated': _('The invoice has been generated.'), 'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'), 'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'), + 'pretix.event.order.invoice.sent': _('The invoice {full_invoice_no} has been sent.'), + 'pretix.event.order.invoice.sending_failed': _('The transmission of invoice {full_invoice_no} has failed.'), + 'pretix.event.order.invoice.testmode_ignored': _('Invoice {full_invoice_no} has not been transmitted because ' + 'the transmission provider does not support test mode invoices.'), + 'pretix.event.order.invoice.retransmitted': _('The invoice {full_invoice_no} has been scheduled for retransmission.'), 'pretix.event.order.comment': _('The order\'s internal comment has been updated.'), 'pretix.event.order.custom_followup_at': _('The order\'s follow-up date has been updated.'), 'pretix.event.order.checkin_attention': _('The order\'s flag to require attention at check-in has been ' @@ -481,6 +541,7 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl 'pretix.event.order.email.error': _('Sending of an email has failed.'), 'pretix.event.order.email.attachments.skipped': _('The email has been sent without attached tickets since they ' 'would have been too large to be likely to arrive.'), + 'pretix.event.order.email.invoice': _('An invoice email has been sent.'), 'pretix.event.order.email.custom_sent': _('A custom email has been sent.'), 'pretix.event.order.position.email.custom_sent': _('A custom email has been sent to an attendee.'), 'pretix.event.order.email.download_reminder_sent': _('An email has been sent with a reminder that the ticket ' @@ -516,11 +577,11 @@ class CoreOrderLogEntryType(OrderLogEntryType): @log_entry_types.new_from_dict({ 'pretix.voucher.added': _('The voucher has been created.'), 'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'), - 'pretix.voucher.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'), 'pretix.voucher.expired.waitinglist': _( 'The voucher has been set to expire because the recipient removed themselves from the waiting list.'), 'pretix.voucher.changed': _('The voucher has been changed.'), 'pretix.voucher.deleted': _('The voucher has been deleted.'), + 'pretix.voucher.added.waitinglist': _('The voucher has been sent to {email} through the waiting list.'), }) class CoreVoucherLogEntryType(VoucherLogEntryType): pass @@ -722,11 +783,31 @@ class CoreUserImpersonatedLogEntryType(UserImpersonatedLogEntryType): 'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'), 'pretix.team.token.created': _('The token "{name}" has been created.'), 'pretix.team.token.deleted': _('The token "{name}" has been revoked.'), + 'pretix.event.checkin.reset': _('The check-in and print log state has been reset.') }) class CoreLogEntryType(LogEntryType): pass +@log_entry_types.new_from_dict({ + 'pretix.organizer.plugins.enabled': _('The plugin has been enabled.'), + 'pretix.organizer.plugins.disabled': _('The plugin has been disabled.'), +}) +class OrganizerPluginStateLogEntryType(LogEntryType): + object_link_wrapper = _('Plugin {val}') + + def get_object_link_info(self, logentry) -> Optional[dict]: + if 'plugin' in logentry.parsed_data: + app = app_cache.get(logentry.parsed_data['plugin']) + if app and hasattr(app, 'PretixPluginMeta'): + return { + 'href': reverse('control:organizer.settings.plugins', kwargs={ + 'organizer': logentry.event.organizer.slug, + }) + '#plugin_' + logentry.parsed_data['plugin'], + 'val': app.PretixPluginMeta.name + } + + @log_entry_types.new_from_dict({ 'pretix.event.item_meta_property.added': _('A meta property has been added to this event.'), 'pretix.event.item_meta_property.deleted': _('A meta property has been removed from this event.'), diff --git a/src/pretix/control/navigation.py b/src/pretix/control/navigation.py index bfd5aef7c..67bccaccd 100644 --- a/src/pretix/control/navigation.py +++ b/src/pretix/control/navigation.py @@ -451,6 +451,11 @@ def get_global_navigation(request): 'url': reverse('control:global.sysreport'), 'active': (url.url_name == 'global.sysreport'), }, + { + 'label': _('Data sync problems'), + 'url': reverse('control:global.datasync.failedjobs'), + 'active': (url.url_name == 'global.datasync.failedjobs'), + }, ] }) @@ -490,6 +495,13 @@ def get_organizer_navigation(request): }), 'active': url.url_name == 'organizer.edit', }, + { + 'label': _('Plugins'), + 'url': reverse('control:organizer.settings.plugins', kwargs={ + 'organizer': request.organizer.slug, + }), + 'active': url.url_name == 'organizer.settings.plugins' or url.url_name == 'organizer.settings.plugin-events', + }, { 'label': _('Event metadata'), 'url': reverse('control:organizer.properties', kwargs={ @@ -655,6 +667,18 @@ def get_organizer_navigation(request): 'icon': 'download', }) + if 'can_change_organizer_settings' in request.orgapermset: + merge_in(nav, [{ + 'parent': reverse('control:organizer.export', kwargs={ + 'organizer': request.organizer.slug, + }), + 'label': _('Data sync problems'), + 'url': reverse('control:organizer.datasync.failedjobs', kwargs={ + 'organizer': request.organizer.slug, + }), + 'active': (url.url_name == 'organizer.datasync.failedjobs'), + }]) + merge_in(nav, sorted( sum((list(a[1]) for a in nav_organizer.send(request.organizer, request=request, organizer=request.organizer)), []), diff --git a/src/pretix/control/signals.py b/src/pretix/control/signals.py index a7e27ef6e..5e1b6b76a 100644 --- a/src/pretix/control/signals.py +++ b/src/pretix/control/signals.py @@ -32,11 +32,11 @@ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under the License. -from django.dispatch import Signal +from pretix.base.signals import ( + DeprecatedSignal, EventPluginSignal, GlobalSignal, OrganizerPluginSignal, +) -from pretix.base.signals import DeprecatedSignal, EventPluginSignal - -html_page_start = Signal() +html_page_start = GlobalSignal() """ This signal allows you to put code in the beginning of the main page for every page in the backend. You are expected to return HTML. @@ -80,7 +80,7 @@ in pretix. As with all plugin signals, the ``sender`` keyword argument will contain the event. """ -nav_topbar = Signal() +nav_topbar = GlobalSignal() """ Arguments: ``request`` @@ -99,7 +99,7 @@ This is no ``EventPluginSignal``, so you do not get the event in the ``sender`` and you may get the signal regardless of whether your plugin is active. """ -nav_global = Signal() +nav_global = GlobalSignal() """ Arguments: ``request`` @@ -150,7 +150,7 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve An additional keyword argument ``subevent`` *can* contain a sub-event. """ -user_dashboard_widgets = Signal() +user_dashboard_widgets = GlobalSignal() """ Arguments: 'user' @@ -221,7 +221,7 @@ Deprecated signal, no longer works. We just keep the definition so old plugins d break the installation. """ -nav_organizer = Signal() +nav_organizer = OrganizerPluginSignal(allow_legacy_plugins=True) """ Arguments: 'organizer', 'request' @@ -350,14 +350,14 @@ will be passed a ``form`` variable with your form. As with all plugin signals, the ``sender`` keyword argument will contain the event. """ -oauth_application_registered = Signal() +oauth_application_registered = GlobalSignal() """ Arguments: ``user``, ``application`` This signal will be called whenever a user registers a new OAuth application. """ -order_search_filter_q = Signal() +order_search_filter_q = GlobalSignal() """ Arguments: ``query`` diff --git a/src/pretix/control/templates/pretixcontrol/auth/base.html b/src/pretix/control/templates/pretixcontrol/auth/base.html index 6956d60e6..a01d0bbf2 100644 --- a/src/pretix/control/templates/pretixcontrol/auth/base.html +++ b/src/pretix/control/templates/pretixcontrol/auth/base.html @@ -20,10 +20,8 @@ {% endif %} - + - - diff --git a/src/pretix/control/templates/pretixcontrol/base.html b/src/pretix/control/templates/pretixcontrol/base.html index 576f6e410..f5d1834c5 100644 --- a/src/pretix/control/templates/pretixcontrol/base.html +++ b/src/pretix/control/templates/pretixcontrol/base.html @@ -79,10 +79,8 @@ {% endif %} - + - - @@ -200,7 +198,7 @@ {% elif request.user.is_staff and staff_session %}
  • - + {% trans "End admin session" %}
  • diff --git a/src/pretix/control/templates/pretixcontrol/checkin/lists.html b/src/pretix/control/templates/pretixcontrol/checkin/lists.html index 4a96b051f..220458244 100644 --- a/src/pretix/control/templates/pretixcontrol/checkin/lists.html +++ b/src/pretix/control/templates/pretixcontrol/checkin/lists.html @@ -83,6 +83,13 @@ {% trans "Connected devices" %} {% endif %} + {% if "can_change_orders" in request.eventpermset %} + + + {% trans "Reset check-in" %} + + {% endif %}

    diff --git a/src/pretix/control/templates/pretixcontrol/checkin/reset.html b/src/pretix/control/templates/pretixcontrol/checkin/reset.html new file mode 100644 index 000000000..7ced9ce74 --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/checkin/reset.html @@ -0,0 +1,50 @@ +{% extends "pretixcontrol/items/base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% block title %}{% trans "Reset check-in" %}{% endblock %} +{% block inside %} +

    {% trans "Reset check-in" %}

    + + {% csrf_token %} +

    + {% blocktrans trimmed %} + With this feature, you can reset the entire check-in state of the event. + This will delete all check-in records as well as all records of printed tickets or badges. + We recommend to use this feature after testing your hardware setup but only before your + event started, and you admitted any real attendees or printed any real badges or tickets. + {% endblocktrans %} +

    +

    + {% blocktrans trimmed count count=checkins %} + This will permanently delete 1 check-in. + {% plural %} + This will permanently delete {{ count }} check-ins. + {% endblocktrans %} + {% blocktrans trimmed count count=printlogs %} + Additionally, 1 print log will be deleted. + {% plural %} + Additionally, {{ count }} print logs will be deleted. + {% endblocktrans %} +
    + + {% trans "This cannot be reverted!" %} + +

    +

    + {% blocktrans trimmed %} + The deleted entries will still show up in the "Order history" section, but for all other + purposes the system will behave as if they never existed. + {% endblocktrans %} +

    + {% bootstrap_form form layout="inline" %} +
    + + {% trans "Cancel" %} + + +
    + +{% endblock %} diff --git a/src/pretix/control/templates/pretixcontrol/datasync/control_order_info.html b/src/pretix/control/templates/pretixcontrol/datasync/control_order_info.html new file mode 100644 index 000000000..156143733 --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/datasync/control_order_info.html @@ -0,0 +1,74 @@ +{% load i18n %} +{% load eventurl %} +{% load bootstrap3 %} +{% load escapejson %} +
    +
    +

    + {% trans "Data transfer to external systems" %} +

    +
    +
      + {% for identifier, display_name, pending, objects in providers %} +
    • +
      + {% csrf_token %} + {% if pending %} + {% if pending.not_before > now or pending.need_manual_retry %} + + {% endif %} + + {% else %} + + + {% endif %} + +

      {{ display_name }}

      + {% if pending %} +

      + {% if pending.need_manual_retry %} + + {% trans "Error" %}: {{ pending.get_need_manual_retry_display }} + {% elif pending.failed_attempts %} + + {% blocktrans trimmed with num=pending.failed_attempts max=pending.max_retry_attempts %} + Error. Retry {{ num }} of {{ max }}. + {% endblocktrans %} + {% if pending.not_before %} + {% blocktrans trimmed with datetime=pending.not_before|date:"SHORT_DATETIME_FORMAT" %} + Waiting until {{ datetime }} + {% endblocktrans %} + {% endif %} + {% elif pending.not_before > now %} + {% blocktrans trimmed with datetime=pending.not_before|date:"SHORT_DATETIME_FORMAT" %} + Waiting until {{ datetime }} + {% endblocktrans %} + {% else %} + {% trans "Pending" %} + {% endif %} + ({% blocktrans trimmed with datetime=pending.triggered|date:"SHORT_DATETIME_FORMAT" %}triggered at {{ datetime }} + {% endblocktrans %}) + +

      + {% endif %} + +
        + {% for obj in objects %} +
      • + {% if obj.external_link_html %} + {{ obj.external_link_html }} + {% else %} + {{ obj.external_object_type }} + {% trans "identified by" %} {{ obj.external_id_field }} + {{ obj.id_value }} + {% endif %} +   +
      • + {% empty %} +
      • {% trans "No data transmitted." %}
      • + {% endfor %} +
      +
    • + {% endfor %} +
    +
    diff --git a/src/pretix/control/templates/pretixcontrol/datasync/failed_jobs.html b/src/pretix/control/templates/pretixcontrol/datasync/failed_jobs.html new file mode 100644 index 000000000..1562dcb0c --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/datasync/failed_jobs.html @@ -0,0 +1,86 @@ +{% extends "pretixcontrol/event/base.html" %} +{% load i18n %} + +{% block content %} +

    {% trans "Sync problems" %}

    +

    + {% blocktrans trimmed %} + On this page, we provide a list of orders where data synchronization to an external system has failed. + You can start another attempt to sync them manually. + {% endblocktrans %} +

    + + {% csrf_token %} +
    + + + + + + + + {% if staff_session %} + + {% endif %} + + + + {% for item in queue_items %} + + + + + + + {% if staff_session %} + + {% endif %} + + {% empty %} + + + {% if staff_session %} + + {% endif %} + + {% endfor %} + + {% if queue_items %} + + + + {% if staff_session %} + + {% endif %} + + + {% endif %} +
    + {% if queue_items %} + + {% endif %} + {% trans "Order" %}{% trans "Sync provider" %}{% trans "Date" %}{% trans "Failure mode" %}in_flightretry
    + {% if staff_session %}{{ item.order.event.organizer.slug }} -{% endif %} + + {{ item.order.full_code }} + + {{ item.provider_display_name }} + {{ item.triggered }} + {% if staff_session %}({{ item.triggered_by }}){% endif %} + + {% if item.need_manual_retry %} + {{ item.get_need_manual_retry_display }} + {% else %} + {% blocktrans trimmed with datetime=item.not_before|date:"SHORT_DATETIME_FORMAT" %} + Temporary error, will retry after {{ datetime }} + {% endblocktrans %} + {% endif %} + {% if staff_session %}({{ item.need_manual_retry }}){% endif %} + {{ item.in_flight }} ({{ item.in_flight_since }}){{ item.failed_attempts }} / {{ item.max_retry_attempts }} ({{ item.not_before }})
    {% trans "No problems." %}
    + + +
    + + {% include "pretixcontrol/pagination.html" %} +{% endblock %} diff --git a/src/pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html b/src/pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html new file mode 100644 index 000000000..cba86405c --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html @@ -0,0 +1,81 @@ +{% load i18n %} +{% load bootstrap3 %} +{% load escapejson %} +{% load formset_tags %} +
    + {{ formset.management_form }} + {% bootstrap_formset_errors formset %} +
    + {% for f in formset %} + {% bootstrap_form_errors f %} +
    +
    + {{ f.id }} + {% bootstrap_field f.DELETE form_group_class="" layout="inline" %} + {% bootstrap_field f.ORDER form_group_class="" layout="inline" %} +
    +
    + {% bootstrap_field f.pretix_field layout='inline' form_group_class="" %} +
    +
    + {% bootstrap_field f.external_field layout='inline' form_group_class="" %} +
    +
    + {% bootstrap_field f.overwrite layout='inline' form_group_class="" %} +
    + {{ f.value_map.as_hidden }} +
    + + + + + + +
    +
    + {% endfor %} +
    + +

    + +

    +
    +{% if external_fields %} + {{ external_fields|json_script:external_fields_id }} +{% endif %} diff --git a/src/pretix/control/templates/pretixcontrol/event/cancel.html b/src/pretix/control/templates/pretixcontrol/event/cancel.html index 7a206c706..8ad8e6d81 100644 --- a/src/pretix/control/templates/pretixcontrol/event/cancel.html +++ b/src/pretix/control/templates/pretixcontrol/event/cancel.html @@ -26,6 +26,7 @@ {% bootstrap_field form.cancel_allow_user_paid_keep layout="control" %} {% bootstrap_field form.cancel_allow_user_paid_keep_percentage layout="control" %} {% bootstrap_field form.cancel_allow_user_paid_keep_fees layout="control" %} + {% bootstrap_field form.tax_rule_cancellation layout="control" %} {% bootstrap_field form.cancel_allow_user_paid_until layout="control" %} {% bootstrap_field form.cancel_allow_user_paid_adjust_fees layout="control" %}
    diff --git a/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html b/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html index c36a4de90..62664abe1 100644 --- a/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html +++ b/src/pretix/control/templates/pretixcontrol/event/fragment_geodata.html @@ -15,7 +15,7 @@ {% trans "Optional" %}
    - {% bootstrap_field form.geo_lat layout="inline" %} + {% bootstrap_field form.geo_lat layout="inline" placeholder=_("Latitude") %} {% if global_settings.opencagedata_apikey %}

    @@ -25,7 +25,7 @@ {% endif %}

    - {% bootstrap_field form.geo_lon layout="inline" %} + {% bootstrap_field form.geo_lon layout="inline" placeholder=_("Longitude") %}
    diff --git a/src/pretix/control/templates/pretixcontrol/event/index.html b/src/pretix/control/templates/pretixcontrol/event/index.html index d89bb08ef..78aeb4f9a 100644 --- a/src/pretix/control/templates/pretixcontrol/event/index.html +++ b/src/pretix/control/templates/pretixcontrol/event/index.html @@ -79,6 +79,15 @@ class="btn btn-primary">{% trans "Show affected orders" %}
    {% endif %} + {% if has_sync_problems %} +
    + {% blocktrans trimmed %} + Orders in this event could not be synced to an external system as configured. + {% endblocktrans %} + {% trans "Show sync problems" %} +
    + {% endif %} {% eventsignal request.event "pretix.control.signals.event_dashboard_top" request=request %} {% if request.event.has_subevents %} diff --git a/src/pretix/control/templates/pretixcontrol/event/invoicing.html b/src/pretix/control/templates/pretixcontrol/event/invoicing.html index a3f8b8996..d2b21e70e 100644 --- a/src/pretix/control/templates/pretixcontrol/event/invoicing.html +++ b/src/pretix/control/templates/pretixcontrol/event/invoicing.html @@ -1,6 +1,7 @@ {% extends "pretixcontrol/event/settings_base.html" %} {% load i18n %} {% load bootstrap3 %} +{% load getitem %} {% block inside %}

    {% trans "Invoice settings" %}

    @@ -59,6 +60,99 @@ {% bootstrap_field form.invoice_renderer_highlight_order_code layout="control" %} {% bootstrap_field form.invoice_eu_currencies layout="control" %} +
    + {% trans "Invoice transmission" %} +

    + {% blocktrans trimmed %} + pretix can transmit invoices using different transmission methods. Different transmission methods + might be required depending on country and industry. By default, sending invoices as PDF files + via email is always available. Other types of transmission can be added by plugins. + {% endblocktrans %} +

    +

    + {% blocktrans trimmed %} + Whether a transmission method listed here is actually selectable for customers may depend on + the country of the customer or whether the customer is entering a business address. + {% endblocktrans %} +

    +
    + + + + + + + + + {% for t in transmission_types %} + {% if transmission_providers|getitem:t.identifier %} + + + + + + + + + {% for p, is_ready, settings_url in transmission_providers|getitem:t.identifier %} + + + + + + {% endfor %} + + {% endif %} + {% endfor %} +
    {% trans "Transmission method" %}{% trans "Status" %}
    + {{ t.verbose_name }} + + {% if ready|getitem:t.identifier %} + + + {% trans "Available" %} + {% if t.exclusive %} + + {% trans "(exclusive)" %} + + {% endif %} + + {% else %} + + + {% trans "Unavailable" %} + + {% endif %} +
    + {{ p.verbose_name }} + + {% if is_ready %} + + + {% trans "Available" %} + + {% else %} + + + {% trans "Not configured" %} + + {% endif %} + + {% if settings_url %} + + + {% trans "Settings" %} + + {% endif %} +
    +
    +

    + {% url "control:event.settings.plugins" event=request.event.slug organizer=request.organizer.slug as plugin_settings_url %} + + {% trans "Enable additional invoice transmission plugins" %} + +

    +
    + {% if plugin.level == "organizer" %} + + + {% trans "Open in organizer settings" %} + + {% else %} + + {% endif %}
    {% else %} -
    - -
    + {% if plugin.level == "organizer" %} +

    + + {% trans "This plugin can only be enabled for the entire organizer account." %} +

    + + {% else %} + {% if plugin.level == "event_organizer" and not plugin.module in request.organizer.get_plugins %} +

    + + {% trans "Enabling this plugin will enable some of its functionality for the entire organizer account." %} +

    + {% endif %} +
    + +
    + {% endif %} {% endif %} {% if plugin.featured %} diff --git a/src/pretix/control/templates/pretixcontrol/event/tax_delete.html b/src/pretix/control/templates/pretixcontrol/event/tax_delete.html index 2f4cd0a5a..db5d0bb31 100644 --- a/src/pretix/control/templates/pretixcontrol/event/tax_delete.html +++ b/src/pretix/control/templates/pretixcontrol/event/tax_delete.html @@ -9,11 +9,10 @@ {% if possible %}

    {% blocktrans %}Are you sure you want to delete the tax rule {{ taxrule }}?{% endblocktrans %}

    {% else %} -

    {% blocktrans %}You cannot delete a tax rule that is in use for a product or has been in use for any existing orders.{% endblocktrans %}

    +

    {% blocktrans %}You cannot delete a tax rule that is in use for a product, has been in use for any existing orders, or is the default tax rule of the event.{% endblocktrans %}

    {% endif %}
    - + {% trans "Cancel" %} {% if possible %} diff --git a/src/pretix/control/templates/pretixcontrol/event/tax_index.html b/src/pretix/control/templates/pretixcontrol/event/tax_index.html index ec15dc525..19123adb1 100644 --- a/src/pretix/control/templates/pretixcontrol/event/tax_index.html +++ b/src/pretix/control/templates/pretixcontrol/event/tax_index.html @@ -24,6 +24,7 @@ {% trans "Name" %} + {% trans "Default" %} {% trans "Rate" %} @@ -36,6 +37,22 @@ {{ tr.internal_name|default:tr.name }} + + {% if tr.default %} + + + {% trans "Default" %} + + {% else %} + + {% csrf_token %} + + + {% endif %} + {% if tr.price_includes_tax %} {% blocktrans with rate=tr.rate%}incl. {{ rate }} %{% endblocktrans %} diff --git a/src/pretix/control/templates/pretixcontrol/events/create_base.html b/src/pretix/control/templates/pretixcontrol/events/create_base.html index 7c45b5f5e..17e273f2a 100644 --- a/src/pretix/control/templates/pretixcontrol/events/create_base.html +++ b/src/pretix/control/templates/pretixcontrol/events/create_base.html @@ -31,7 +31,7 @@ {% trans "Every event needs to be created as part of an organizer account. Currently, you do not have access to any organizer accounts." %}
    {% if staff_session %} - + {% trans "Create a new organizer" %} {% endif %} diff --git a/src/pretix/control/templates/pretixcontrol/events/create_basics.html b/src/pretix/control/templates/pretixcontrol/events/create_basics.html index faa8c0099..de40188f3 100644 --- a/src/pretix/control/templates/pretixcontrol/events/create_basics.html +++ b/src/pretix/control/templates/pretixcontrol/events/create_basics.html @@ -6,7 +6,7 @@
    {% trans "General information" %} {% bootstrap_field form.name layout="control" %} -
    +
    + {% endif %} {% if not i.canceled %} - {% if request.event.settings.invoice_regenerate_allowed %} + {% if i.regenerate_allowed %}
    {% csrf_token %} @@ -320,12 +366,6 @@
    {% endif %} {% endfor %} - {% if invoices_send_link %} -
    - - {% trans "Email invoices" %} - - {% endif %} {% if can_generate_invoice and 'can_change_orders' in request.eventpermset %}
    {% endif %} + {% if staff_session %} + + {% endif %} {% if line.issued_gift_cards %}
    {% for gc in line.issued_gift_cards.all %} @@ -788,7 +840,7 @@ {{ p.html_info|safe }} {% if staff_session %}

    - + {% trans "Inspect" %} @@ -800,7 +852,7 @@ - + {% trans "Inspect" %} @@ -904,7 +956,7 @@ {% endif %} {% if staff_session %}

    - {% trans "Inspect" %} @@ -977,8 +1029,14 @@

    {{ request.event.settings.invoice_address_custom_field }}
    {{ order.invoice_address.custom_field }}
    {% endif %} -
    {% trans "Internal reference" %}
    -
    {{ order.invoice_address.internal_reference }}
    + {% if order.invoice_address.internal_reference %} +
    {% trans "Internal reference" %}
    +
    {{ order.invoice_address.internal_reference }}
    + {% endif %} + {% for k, v in order.invoice_address.describe_transmission %} +
    {{ k }}
    +
    {{ v }}
    + {% endfor %}
    diff --git a/src/pretix/control/templates/pretixcontrol/organizers/device_connect.html b/src/pretix/control/templates/pretixcontrol/organizers/device_connect.html index 9fb687cbe..63ba0d201 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/device_connect.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/device_connect.html @@ -21,8 +21,17 @@
    {% trans "If your app/device does not support scanning a QR code, you can also enter the following information:" %}
    - {% trans "System URL:" %} {{ settings.SITE_URL }}
    - {% trans "Token:" %} {{ device.initialization_token }} + {% trans "System URL:" %} {{ settings.SITE_URL }} + +
    + {% trans "Token:" %} {{ device.initialization_token }} +
    diff --git a/src/pretix/control/templates/pretixcontrol/organizers/device_logs.html b/src/pretix/control/templates/pretixcontrol/organizers/device_logs.html index 322dd1fb0..0e526f3c0 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/device_logs.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/device_logs.html @@ -37,7 +37,7 @@
    {{ log.display }} {% if staff_session %} - + {% trans "Inspect" %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/edit.html b/src/pretix/control/templates/pretixcontrol/organizers/edit.html index acc04a27d..8697304a7 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/edit.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/edit.html @@ -12,7 +12,7 @@ {% blocktrans with name=organizer.name %}Organizer settings{% endblocktrans %} {% if request.user.is_staff and staff_session %} + class="btn btn-danger hidden-print admin-only"> {% endif %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/giftcard.html b/src/pretix/control/templates/pretixcontrol/organizers/giftcard.html index 13aa41507..271780abe 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/giftcard.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/giftcard.html @@ -89,7 +89,7 @@ {% endif %} {% if staff_session and t.info %} -
    {{ t.info|pprint }}
    +
    {{ t.info|pprint }}
    {% endif %} {% if t.acceptor and t.acceptor != request.organizer %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/index.html b/src/pretix/control/templates/pretixcontrol/organizers/index.html index 0660d1fc6..942524b64 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/index.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/index.html @@ -29,7 +29,7 @@
    {% if staff_session %}

    - + {% trans "Create a new organizer" %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/logs.html b/src/pretix/control/templates/pretixcontrol/organizers/logs.html index d849570e6..aa3f32a63 100644 --- a/src/pretix/control/templates/pretixcontrol/organizers/logs.html +++ b/src/pretix/control/templates/pretixcontrol/organizers/logs.html @@ -67,7 +67,7 @@

    {{ log.display }} {% if staff_session %} - + {% trans "Inspect" %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/plugin_events.html b/src/pretix/control/templates/pretixcontrol/organizers/plugin_events.html new file mode 100644 index 000000000..6a4e4b093 --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/organizers/plugin_events.html @@ -0,0 +1,45 @@ +{% extends "pretixcontrol/organizers/base.html" %} +{% load i18n %} +{% load bootstrap3 %} +{% load money %} +{% block title %} + {% blocktrans trimmed with name=plugin.name %} + Events with plugin {{ name }} + {% endblocktrans %} +{% endblock %} +{% block inner %} +

    + {% blocktrans trimmed with name=plugin.name %} + Events with plugin {{ name }} + {% endblocktrans %} +

    + {% if plugin.level == "event" %} +

    + {% blocktrans trimmed with name=plugin.name %} + The plugin "{{ name }}" can be enabled or disabled for every event individually. + {% endblocktrans %} +

    + {% elif plugin.level == "event_organizer" %} +

    + {% blocktrans trimmed with name=plugin.name %} + The plugin "{{ name }}" is enabled for your organizer account, but also needs to be enabled for the + specific events you want to use it with. + {% endblocktrans %} +

    + {% endif %} +

    + {% blocktrans trimmed %} + Using this form, you can quickly enable or disable it for many events. Note that it might still + be necessary to configure the plugin for each event individually. + {% endblocktrans %} +

    + + {% csrf_token %} + {% bootstrap_form form layout="control" %} +
    + +
    + +{% endblock %} diff --git a/src/pretix/control/templates/pretixcontrol/organizers/plugins.html b/src/pretix/control/templates/pretixcontrol/organizers/plugins.html new file mode 100644 index 000000000..de4ec952d --- /dev/null +++ b/src/pretix/control/templates/pretixcontrol/organizers/plugins.html @@ -0,0 +1,195 @@ +{% extends "pretixcontrol/organizers/base.html" %} +{% load i18n %} +{% load static %} +{% load bootstrap3 %} +{% block content %} +

    {% trans "Available plugins" %}

    +

    + {% blocktrans trimmed %} + On this page, you can choose plugins you want to enable for your organizer account. Plugins might bring additional + software functionality, connect your events to third-party services, or apply other forms of customizations. + {% endblocktrans %} +

    + {% if "success" in request.GET %} +
    + {% trans "Your changes have been saved." %} +
    + {% endif %} +
    +
    +

    +
    +
    +

    + + +

    +
    +
    +
    + {% csrf_token %} +
    +
    + + {% trans "Search results" %} +
    +
    +
    +
    +
    +
    + {% for cat, catlabel, plist, has_pictures in plugins %} +
    + {{ catlabel }} +
    + {% for plugin, is_active, settings_links, navigation_links, events_counter in plist %} +
    + {% if plugin.featured %} +
    +
    + {% endif %} +
    + {% if plugin.featured or plugin.experimental %} +

    + {% if plugin.featured %} + + {% trans "Top recommendation" %} + {% endif %} + {% if plugin.experimental %} + + {% trans "Experimental feature" %} + {% endif %} +

    + {% endif %} + {% if plugin.picture %} +

    + {% endif %} +

    + {{ plugin.name }} + {% if show_meta %} + {{ plugin.version }} + {% endif %} + {% if is_active or plugin.level == "event" %} + {% if plugin.level == "organizer" %} + + + {% trans "Active" %} + + {% elif events_total and events_counter == events_total %} + + + {% trans "Active (all events)" %} + + {% elif events_counter %} + + + {% blocktrans trimmed count count=events_counter %} + Active ({{ count }} event) + {% plural %} + Active ({{ count }} events) + {% endblocktrans %} + + {% elif level == "event_organizer" %} + + + {% blocktrans trimmed count count=0 %} + Active ({{ count }} event) + {% plural %} + Active ({{ count }} events) + {% endblocktrans %} + + {% endif %} + {% endif %} +

    + {% include "pretixcontrol/event/fragment_plugin_description.html" with plugin=plugin %} +
    + {% if plugin.app.compatibility_errors %} +
    + {% trans "Incompatible" %} +
    + {% elif plugin.restricted and plugin.module not in request.organizer.settings.allowed_restricted_plugins %} +
    + {% trans "Not available" %} +
    + {% elif is_active %} + {% if plugin.level == "event_organizer" %} +

    + + {% trans "Parts of this plugin can be enabled or disabled for events individually." %} +

    + {% endif %} +
    + {% if navigation_links %} +
    + + +
    + {% endif %} + {% if settings_links %} +
    + + +
    + {% endif %} + + {% if plugin.level == "event_organizer" %} + + {% trans "Manage events" %} + + {% endif %} +
    + {% else %} + {% if plugin.level == "organizer" %} +
    + +
    + {% elif not plugin.level or plugin.level == "event" %} +

    + + {% trans "This plugin can be enabled or disabled for events individually." %} +

    + + {% elif plugin.level == "event_organizer" %} +

    + + {% trans "Parts of this plugin can be enabled or disabled for events individually." %} +

    +
    + +
    + {% endif %} + {% endif %} + {% if plugin.featured %} +
    +
    + {% endif %} +
    + {% endfor %} +
    +
    + {% endfor %} +
    +
    + +{% endblock %} diff --git a/src/pretix/control/templates/pretixcontrol/pdf/index.html b/src/pretix/control/templates/pretixcontrol/pdf/index.html index 413bb2807..f7fc78526 100644 --- a/src/pretix/control/templates/pretixcontrol/pdf/index.html +++ b/src/pretix/control/templates/pretixcontrol/pdf/index.html @@ -1,5 +1,6 @@ {% extends "pretixcontrol/event/base.html" %} {% load i18n %} +{% load icon %} {% load static %} {% load compress %} {% block title %}{% trans "PDF Editor" %}{% endblock %} @@ -25,27 +26,102 @@
    -
    +
    + {% csrf_token %} + + +
    - - - -
    + +
    +
    + + + +
    +
    + + +
    +
    + +
    - {% trans "Editor" %}
    {% trans "Timeline" %} - {% bootstrap_field form.rel_presale_start layout="control" %} - {% bootstrap_field form.rel_presale_end layout="control" %} + {% bootstrap_field form.rel_presale_start layout="control" placeholder=datetime_sample %} + {% bootstrap_field form.rel_presale_end layout="control" placeholder=datetime_sample %}
    {% trans "Quotas" %} diff --git a/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html b/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html index e6c989895..8770301c5 100644 --- a/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html +++ b/src/pretix/control/templates/pretixcontrol/subevents/bulk_edit.html @@ -51,7 +51,7 @@
    - {% bootstrap_field form.geo_lat layout="inline" %} + {% bootstrap_field form.geo_lat layout="inline" placeholder=_("Latitude") %} {% if global_settings.opencagedata_apikey %}

    @@ -61,7 +61,7 @@ {% endif %}

    - {% bootstrap_field form.geo_lon layout="inline" %} + {% bootstrap_field form.geo_lon layout="inline" placeholder=_("Longitude") %}
    diff --git a/src/pretix/control/urls.py b/src/pretix/control/urls.py index c31878be8..4243ad2d5 100644 --- a/src/pretix/control/urls.py +++ b/src/pretix/control/urls.py @@ -37,9 +37,9 @@ from django.urls import include, re_path from django.views.generic.base import RedirectView from pretix.control.views import ( - auth, checkin, dashboards, discounts, event, geo, global_settings, item, - main, modelimport, oauth, orders, organizer, pdf, search, shredder, - subevents, typeahead, user, users, vouchers, waitinglist, + auth, checkin, dashboards, datasync, discounts, event, geo, + global_settings, item, main, modelimport, oauth, orders, organizer, pdf, + search, shredder, subevents, typeahead, user, users, vouchers, waitinglist, ) urlpatterns = [ @@ -58,6 +58,7 @@ urlpatterns = [ re_path(r'^global/license/$', global_settings.LicenseCheckView.as_view(), name='global.license'), re_path(r'^global/sysreport/$', global_settings.SysReportView.as_view(), name='global.sysreport'), re_path(r'^global/message/$', global_settings.MessageView.as_view(), name='global.message'), + re_path(r'^global/datasync/failedjobs/$', datasync.GlobalFailedSyncJobsView.as_view(), name='global.datasync.failedjobs'), re_path(r'^logdetail/$', global_settings.LogDetailView.as_view(), name='global.logdetail'), re_path(r'^logdetail/payment/$', global_settings.PaymentDetailView.as_view(), name='global.paymentdetail'), re_path(r'^logdetail/refund/$', global_settings.RefundDetailView.as_view(), name='global.refunddetail'), @@ -114,6 +115,10 @@ urlpatterns = [ re_path(r'^organizers/select2$', typeahead.organizer_select2, name='organizers.select2'), re_path(r'^organizer/(?P[^/]+)/$', organizer.OrganizerDetail.as_view(), name='organizer'), re_path(r'^organizer/(?P[^/]+)/edit$', organizer.OrganizerUpdate.as_view(), name='organizer.edit'), + re_path(r'^organizer/(?P[^/]+)/settings/plugins$', + organizer.OrganizerPlugins.as_view(), name='organizer.settings.plugins'), + re_path(r'^organizer/(?P[^/]+)/settings/plugins/(?P[^/]+)/events$', + organizer.OrganizerPluginEvents.as_view(), name='organizer.settings.plugin-events'), re_path(r'^organizer/(?P[^/]+)/settings/email$', organizer.OrganizerMailSettings.as_view(), name='organizer.settings.mail'), re_path(r'^organizer/(?P[^/]+)/settings/email/setup$', @@ -248,6 +253,7 @@ urlpatterns = [ re_path(r'^organizer/(?P[^/]+)/export/(?P[^/]+)/delete$', organizer.DeleteScheduledExportView.as_view(), name='organizer.export.scheduled.delete'), re_path(r'^organizer/(?P[^/]+)/ticket_select2$', typeahead.ticket_select2, name='organizer.ticket_select2'), + re_path(r'^organizer/(?P[^/]+)/datasync/failedjobs/$', datasync.OrganizerFailedSyncJobsView.as_view(), name='organizer.datasync.failedjobs'), re_path(r'^nav/typeahead/$', typeahead.nav_context_list, name='nav.typeahead'), re_path(r'^events/$', main.EventList.as_view(), name='events'), re_path(r'^events/add$', main.EventWizard.as_view(), name='events.add'), @@ -288,6 +294,7 @@ urlpatterns = [ re_path(r'^settings/tax/(?P\d+)/$', event.TaxUpdate.as_view(), name='event.settings.tax.edit'), re_path(r'^settings/tax/add$', event.TaxCreate.as_view(), name='event.settings.tax.add'), re_path(r'^settings/tax/(?P\d+)/delete$', event.TaxDelete.as_view(), name='event.settings.tax.delete'), + re_path(r'^settings/tax/(?P\d+)/default$', event.TaxDefault.as_view(), name='event.settings.tax.default'), re_path(r'^settings/widget$', event.WidgetSettings.as_view(), name='event.settings.widget'), re_path(r'^pdf/editor/webfonts.css', pdf.FontsCSSView.as_view(), name='pdf.css'), re_path(r'^pdf/editor/(?P[^/]+).pdf$', pdf.PdfView.as_view(), name='pdf.background'), @@ -376,6 +383,8 @@ urlpatterns = [ name='event.order.geninvoice'), re_path(r'^orders/(?P[0-9A-Z]+)/invoices/(?P\d+)/regenerate$', orders.OrderInvoiceRegenerate.as_view(), name='event.order.regeninvoice'), + re_path(r'^orders/(?P[0-9A-Z]+)/invoices/(?P\d+)/retransmit$', orders.OrderInvoiceRetransmit.as_view(), + name='event.order.retransmitinvoice'), re_path(r'^orders/(?P[0-9A-Z]+)/invoices/(?P\d+)/reissue$', orders.OrderInvoiceReissue.as_view(), name='event.order.reissueinvoice'), re_path(r'^orders/(?P[0-9A-Z]+)/download/(?P\d+)/(?P[^/]+)/$', @@ -427,6 +436,8 @@ urlpatterns = [ re_path(r'^orders/(?P[0-9A-Z]+)/cancellationrequests/(?P\d+)/delete$', orders.OrderCancellationRequestDelete.as_view(), name='event.order.cancellationrequests.delete'), + re_path(r'^orders/(?P[0-9A-Z]+)/sync_job/(?P[^/]+)/$', datasync.ControlSyncJob.as_view(), + name='event.order.sync_job'), re_path(r'^orders/(?P[0-9A-Z]+)/transactions/$', orders.OrderTransactions.as_view(), name='event.order.transactions'), re_path(r'^orders/(?P[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'), re_path(r'^invoice/(?P[^/]+)$', orders.InvoiceDownload.as_view(), @@ -463,6 +474,7 @@ urlpatterns = [ re_path(r'^checkins/$', checkin.CheckinListView.as_view(), name='event.orders.checkins'), re_path(r'^checkinlists/$', checkin.CheckinListList.as_view(), name='event.orders.checkinlists'), re_path(r'^checkinlists/add$', checkin.CheckinListCreate.as_view(), name='event.orders.checkinlists.add'), + re_path(r'^checkinlists/reset$', checkin.CheckInResetView.as_view(), name='event.orders.checkinlists.reset'), re_path(r'^checkinlists/select2$', typeahead.checkinlist_select2, name='event.orders.checkinlists.select2'), re_path(r'^checkinlists/(?P\d+)/$', checkin.CheckInListShow.as_view(), name='event.orders.checkinlists.show'), re_path(r'^checkinlists/(?P\d+)/simulator$', checkin.CheckInListSimulator.as_view(), name='event.orders.checkinlists.simulator'), @@ -472,6 +484,7 @@ urlpatterns = [ name='event.orders.checkinlists.edit'), re_path(r'^checkinlists/(?P\d+)/delete$', checkin.CheckinListDelete.as_view(), name='event.orders.checkinlists.delete'), + re_path(r'^datasync/failedjobs/$', datasync.EventFailedSyncJobsView.as_view(), name='event.datasync.failedjobs'), ])), re_path(r'^event/(?P[^/]+)/$', RedirectView.as_view(pattern_name='control:organizer'), name='event.organizerredirect'), ] diff --git a/src/pretix/control/views/checkin.py b/src/pretix/control/views/checkin.py index d24ed7a50..26ff3e488 100644 --- a/src/pretix/control/views/checkin.py +++ b/src/pretix/control/views/checkin.py @@ -50,15 +50,16 @@ from i18nfield.strings import LazyI18nString from pretix.api.views.checkin import _redeem_process from pretix.base.media import MEDIA_TYPES -from pretix.base.models import Checkin, Order, OrderPosition +from pretix.base.models import Checkin, LogEntry, Order, OrderPosition from pretix.base.models.checkin import CheckinList +from pretix.base.models.orders import PrintLog from pretix.base.services.checkin import ( LazyRuleVars, _logic_annotate_for_graphic_explain, ) from pretix.base.signals import checkin_created -from pretix.base.views.tasks import AsyncPostView +from pretix.base.views.tasks import AsyncFormView, AsyncPostView from pretix.control.forms.checkin import ( - CheckinListForm, CheckinListSimulatorForm, + CheckinListForm, CheckinListSimulatorForm, CheckinResetForm, ) from pretix.control.forms.filter import ( CheckinFilterForm, CheckinListAttendeeFilterForm, CheckinListFilterForm, @@ -570,3 +571,55 @@ class CheckInListSimulator(EventPermissionRequiredMixin, FormView): for q in self.result["questions"]: q["question"] = LazyI18nString(q["question"]) return self.get(self.request, self.args, self.kwargs) + + +class CheckInResetView(CheckInListQueryMixin, EventPermissionRequiredMixin, AsyncFormView): + form_class = CheckinResetForm + permission = "can_change_orders" + template_name = "pretixcontrol/checkin/reset.html" + + def get_error_url(self, *args): + return reverse( + "control:event.orders.checkinlists", + kwargs={ + "event": self.request.event.slug, + "organizer": self.request.organizer.slug, + }, + ) + + def get_success_url(self, *args): + return reverse( + "control:event.orders.checkinlists", + kwargs={ + "event": self.request.event.slug, + "organizer": self.request.organizer.slug, + }, + ) + + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + ctx['checkins'] = Checkin.all.filter(list__event=self.request.event).count() + ctx['printlogs'] = PrintLog.objects.filter(position__order__event=self.request.event).count() + return ctx + + def async_form_valid(self, task, form): + with transaction.atomic(): + qs = Checkin.all.filter(list__event=self.request.event).select_related("position", "position__order") + logentries = [] + for ci in qs: + if ci.position: + logentries.append(ci.position.order.log_action('pretix.event.checkin.reverted', data={ + 'position': ci.position.id, + 'positionid': ci.position.positionid, + 'list': ci.list_id, + 'web': True + }, user=self.request.user, save=False)) + + Order.objects.filter(pk__in=qs.values_list("position__order_id", flat=True)).update(last_modified=now()) + qs.delete() + LogEntry.objects.bulk_create(logentries) + + pl = PrintLog.objects.filter(position__order__event=self.request.event) + pl.delete() + self.request.event.log_action('pretix.event.checkin.reset', user=self.request.user) + self.request.event.cache.clear() diff --git a/src/pretix/control/views/dashboards.py b/src/pretix/control/views/dashboards.py index 8b5b47e2a..35932ceaf 100644 --- a/src/pretix/control/views/dashboards.py +++ b/src/pretix/control/views/dashboards.py @@ -383,6 +383,10 @@ def event_index(request, organizer, event): ctx['has_cancellation_requests'] = can_view_orders and CancellationRequest.objects.filter( order__event=request.event ).exists() + ctx['has_sync_problems'] = can_change_event_settings and request.event.queued_sync_jobs.filter( + Q(need_manual_retry__isnull=False) + | Q(failed_attempts__gt=0) + ).exists() ctx['timeline'] = [ { diff --git a/src/pretix/control/views/datasync.py b/src/pretix/control/views/datasync.py new file mode 100644 index 000000000..6a8e3fcb2 --- /dev/null +++ b/src/pretix/control/views/datasync.py @@ -0,0 +1,163 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# + +from itertools import groupby + +from django.contrib import messages +from django.db import transaction +from django.db.models import Q +from django.dispatch import receiver +from django.http import HttpResponseNotAllowed +from django.shortcuts import redirect +from django.template.loader import get_template +from django.utils.timezone import now +from django.utils.translation import gettext_lazy as _ +from django.views.generic import ListView + +from pretix.base.datasync.datasync import datasync_providers +from pretix.base.models import Event, Order +from pretix.base.models.datasync import OrderSyncQueue +from pretix.base.services.datasync import sync_single +from pretix.control.permissions import ( + AdministratorPermissionRequiredMixin, EventPermissionRequiredMixin, + OrganizerPermissionRequiredMixin, +) +from pretix.control.signals import order_info +from pretix.control.views.orders import OrderView +from pretix.helpers import OF_SELF + + +@receiver(order_info, dispatch_uid="datasync_control_order_info") +def on_control_order_info(sender: Event, request, order: Order, **kwargs): + providers = [provider for provider, meta in datasync_providers.filter(active_in=sender)] + if not providers: + return "" + + queued = {p.sync_provider: p for p in order.queued_sync_jobs.all()} + objects = { + provider: list(objects) + for (provider, objects) + in groupby(order.sync_results.order_by('sync_provider').all(), key=lambda o: o.sync_provider) + } + providers = [(provider.identifier, provider.display_name, queued.get(provider.identifier), objects.get(provider.identifier)) for provider in providers] + + template = get_template("pretixcontrol/datasync/control_order_info.html") + ctx = { + "order": order, + "request": request, + "event": sender, + "providers": providers, + "now": now(), + } + return template.render(ctx, request=request) + + +class ControlSyncJob(OrderView): + permission = 'can_change_orders' + + def post(self, request, provider, *args, **kwargs): + prov, meta = datasync_providers.get(active_in=self.request.event, identifier=provider) + + if self.request.POST.get("queue_sync") == "true": + prov.enqueue_order(self.order, 'user') + messages.success(self.request, _('The sync job has been enqueued and will run in the next minutes.')) + elif self.request.POST.get("cancel_job"): + with transaction.atomic(): + job = self.order.queued_sync_jobs.select_for_update(of=OF_SELF).get( + pk=self.request.POST.get("cancel_job") + ) + if job.in_flight: + messages.warning(self.request, _('The sync job is already in progress.')) + else: + job.delete() + messages.success(self.request, _('The sync job has been canceled.')) + elif self.request.POST.get("run_job_now"): + with transaction.atomic(): + job = self.order.queued_sync_jobs.select_for_update(of=OF_SELF).get( + pk=self.request.POST.get("run_job_now") + ) + if job.in_flight: + messages.success(self.request, _('The sync job is already in progress.')) + else: + job.not_before = now() + job.need_manual_retry = None + job.save() + sync_single.apply_async(args=(job.pk,)) + messages.success(self.request, _('The sync job has been set to run as soon as possible.')) + + return redirect(self.get_order_url()) + + def get(self, *args, **kwargs): + return HttpResponseNotAllowed(['POST']) + + +class FailedSyncJobsView(ListView): + template_name = 'pretixcontrol/datasync/failed_jobs.html' + model = OrderSyncQueue + context_object_name = 'queue_items' + paginate_by = 100 + ordering = ('triggered',) + + def get_queryset(self): + return super().get_queryset().filter( + Q(need_manual_retry__isnull=False) + | Q(failed_attempts__gt=0) + ).select_related( + 'order' + ) + + def post(self, request, *args, **kwargs): + items = self.get_queryset().filter(pk__in=request.POST.getlist('idlist')) + + if self.request.POST.get("action") == "retry": + for item in items: + item.not_before = now() + item.need_manual_retry = None + item.save() + messages.success(self.request, _('The selected jobs have been set to run as soon as possible.')) + elif self.request.POST.get("action") == "cancel": + items.delete() + messages.success(self.request, _('The selected jobs have been canceled.')) + + return redirect(request.get_full_path()) + + +class GlobalFailedSyncJobsView(AdministratorPermissionRequiredMixin, FailedSyncJobsView): + pass + + +class OrganizerFailedSyncJobsView(OrganizerPermissionRequiredMixin, FailedSyncJobsView): + permission = "can_change_organizer_settings" + + def get_queryset(self): + return super().get_queryset().filter( + event__organizer=self.request.organizer + ) + + +class EventFailedSyncJobsView(EventPermissionRequiredMixin, FailedSyncJobsView): + permission = "can_change_event_settings" + + def get_queryset(self): + return super().get_queryset().filter( + event=self.request.event + ) diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index 9ffb76eac..038fd7403 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -37,7 +37,7 @@ import json import logging import operator import re -from collections import OrderedDict +from collections import OrderedDict, defaultdict from decimal import Decimal from io import BytesIO from itertools import groupby @@ -61,14 +61,14 @@ from django.http import ( JsonResponse, ) from django.shortcuts import get_object_or_404, redirect -from django.urls import reverse +from django.urls import NoReverseMatch, reverse from django.utils.functional import cached_property from django.utils.html import conditional_escape, format_html from django.utils.http import url_has_allowed_host_and_scheme from django.utils.safestring import mark_safe from django.utils.timezone import now from django.utils.translation import gettext, gettext_lazy as _, gettext_noop -from django.views.generic import FormView, ListView +from django.views.generic import DetailView, FormView, ListView from django.views.generic.base import TemplateView, View from django.views.generic.detail import SingleObjectMixin from i18nfield.strings import LazyI18nString @@ -76,6 +76,9 @@ from i18nfield.utils import I18nJSONEncoder from pretix.base.email import get_available_placeholders from pretix.base.forms import PlaceholderValidator +from pretix.base.invoicing.transmission import ( + get_transmission_types, transmission_providers, +) from pretix.base.models import Event, LogEntry, Order, TaxRule, Voucher from pretix.base.models.event import EventMetaValue from pretix.base.services import tickets @@ -104,6 +107,10 @@ from ...base.i18n import language from ...base.models.items import ( Item, ItemCategory, ItemMetaProperty, Question, Quota, ) +from ...base.plugins import ( + PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, + PLUGIN_LEVEL_ORGANIZER, +) from ...base.services.mail import prefix_subject from ...base.services.placeholders import get_sample_context from ...base.settings import LazyI18nStringList @@ -349,43 +356,36 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat def available_plugins(self, event): from pretix.base.plugins import get_all_plugins - return (p for p in get_all_plugins(event) if not p.name.startswith('.') + return (p for p in get_all_plugins(event=event) if not p.name.startswith('.') and getattr(p, 'visible', True)) def prepare_links(self, pluginmeta, key): links = getattr(pluginmeta, key, []) try: - return [ - ( - reverse(urlname, kwargs={"organizer": self.request.organizer.slug, "event": self.request.event.slug, **kwargs}), - " > ".join(map(str, linktext)) if isinstance(linktext, tuple) else linktext, - ) for linktext, urlname, kwargs in links - ] + result = [] + for linktext, urlname, kwargs in links: + try: + result.append(( + reverse(urlname, kwargs={"organizer": self.request.organizer.slug, "event": self.request.event.slug, **kwargs}), + " > ".join(map(str, linktext)) if isinstance(linktext, tuple) else linktext, + )) + except NoReverseMatch: + if pluginmeta.level != PLUGIN_LEVEL_EVENT: + # Ignore, link might be for another level + pass + else: + raise + return result except: logger.exception('Failed to resolve settings links.') return [] def get_context_data(self, *args, **kwargs) -> dict: + from pretix.base.plugins import CATEGORY_LABELS, CATEGORY_ORDER + context = super().get_context_data(*args, **kwargs) plugins = list(self.available_plugins(self.object)) - order = [ - 'FEATURE', - 'PAYMENT', - 'INTEGRATION', - 'CUSTOMIZATION', - 'FORMAT', - 'API', - ] - labels = { - 'FEATURE': _('Features'), - 'PAYMENT': _('Payment providers'), - 'INTEGRATION': _('Integrations'), - 'CUSTOMIZATION': _('Customizations'), - 'FORMAT': _('Output and export formats'), - 'API': _('API features'), - } - plugins_grouped = groupby( sorted( plugins, @@ -400,17 +400,24 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat plugins_grouped = [(c, list(plist)) for c, plist in plugins_grouped] active_plugins = self.object.get_plugins() + organizer_active_plugins = self.request.organizer.get_plugins() def plugin_details(plugin): is_active = plugin.module in active_plugins + if getattr(plugin, "level", PLUGIN_LEVEL_EVENT) == PLUGIN_LEVEL_ORGANIZER: + is_active = plugin.module in organizer_active_plugins + if getattr(plugin, "level", PLUGIN_LEVEL_EVENT) == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID: + is_active = is_active and plugin.module in organizer_active_plugins + settings_links = self.prepare_links(plugin, 'settings_links') if is_active else None navigation_links = self.prepare_links(plugin, 'navigation_links') if is_active else None - return (plugin, is_active, settings_links, navigation_links) + return plugin, is_active, settings_links, navigation_links + context['plugins'] = sorted([ - (c, labels.get(c, c), map(plugin_details, plist), any(getattr(p, 'picture', None) for p in plist)) + (c, CATEGORY_LABELS.get(c, c), map(plugin_details, plist), any(getattr(p, 'picture', None) for p in plist)) for c, plist in plugins_grouped - ], key=lambda c: (order.index(c[0]), c[1]) if c[0] in order else (999, str(c[1]))) + ], key=lambda c: (CATEGORY_ORDER.index(c[0]), c[1]) if c[0] in CATEGORY_ORDER else (999, str(c[1]))) context['show_meta'] = settings.PRETIX_PLUGINS_SHOW_META return context @@ -427,6 +434,7 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat } with transaction.atomic(): + save_organizer = False for key, value in request.POST.items(): if key.startswith("plugin:"): module = key.split(":")[1] @@ -436,8 +444,26 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat if module not in request.event.settings.allowed_restricted_plugins: continue - self.request.event.log_action('pretix.event.plugins.enabled', user=self.request.user, - data={'plugin': module}) + if getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT) not in (PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID): + continue + + if getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT) == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID: + if not request.user.has_organizer_permission(request.organizer, "can_change_organizer_settings", request): + messages.error( + request, + _("You do not have sufficient permission to enable plugins that need to be enabled " + "for the entire organizer account.") + ) + continue + + if module not in self.object.organizer.get_plugins(): + self.object.organizer.log_action('pretix.organizer.plugins.enabled', user=self.request.user, + data={'plugin': module}) + self.object.organizer.enable_plugin(module, allow_restricted=request.event.settings.allowed_restricted_plugins) + save_organizer = True + + self.object.log_action('pretix.event.plugins.enabled', user=self.request.user, + data={'plugin': module}) self.object.enable_plugin(module, allow_restricted=request.event.settings.allowed_restricted_plugins) links = self.prepare_links(pluginmeta, 'settings_links') @@ -463,12 +489,14 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat self.object.disable_plugin(module) messages.success(self.request, _('The plugin has been disabled.')) self.object.save() + if save_organizer: + self.object.organizer.save() return redirect(self.get_success_url()) def get_success_url(self) -> str: return reverse('control:event.settings.plugins', kwargs={ - 'organizer': self.get_object().organizer.slug, - 'event': self.get_object().slug, + 'organizer': self.request.organizer.slug, + 'event': self.request.event.slug, }) @@ -626,6 +654,22 @@ class InvoiceSettings(EventSettingsViewMixin, EventSettingsFormView): template_name = 'pretixcontrol/event/invoicing.html' permission = 'can_change_event_settings' + def get_context_data(self, **kwargs): + types = get_transmission_types() + providers = defaultdict(list) + ready = defaultdict(lambda: False) + for p, __ in transmission_providers.filter(active_in=self.request.event): + is_ready_result = p.is_ready(self.request.event) + providers[p.type].append((p, is_ready_result, p.settings_url(self.request.event))) + ready[p.type] = ready[p.type] or is_ready_result + for k, v in providers.items(): + v.sort(key=lambda p: (-p[0].priority, p[0].identifier)) + return super().get_context_data( + transmission_providers=providers, + transmission_types=types, + ready=ready, + ) + def get_success_url(self) -> str: if 'preview' in self.request.POST: return reverse('control:event.settings.invoice.preview', kwargs={ @@ -1274,6 +1318,8 @@ class TaxCreate(EventSettingsViewMixin, EventPermissionRequiredMixin, CreateView @transaction.atomic def form_valid(self, form): + if not self.request.event.tax_rules.exists(): + form.instance.default = True form.instance.event = self.request.event form.instance.custom_rules = json.dumps([ f.cleaned_data for f in self.formset.ordered_forms if f not in self.formset.deleted_forms @@ -1354,6 +1400,50 @@ class TaxUpdate(EventSettingsViewMixin, EventPermissionRequiredMixin, UpdateView return super().form_invalid(form) +class TaxDefault(EventSettingsViewMixin, EventPermissionRequiredMixin, DetailView): + model = TaxRule + permission = 'can_change_event_settings' + + def get_object(self, queryset=None) -> TaxRule: + try: + return self.request.event.tax_rules.get( + id=self.kwargs['rule'] + ) + except TaxRule.DoesNotExist: + raise Http404(_("The requested tax rule does not exist.")) + + def get(self, request, *args, **kwargs): + return self.http_method_not_allowed(request, *args, **kwargs) + + @transaction.atomic + def post(self, request, *args, **kwargs): + messages.success(self.request, _('Your changes have been saved.')) + obj = self.get_object() + if not obj.default: + for tr in self.request.event.tax_rules.filter(default=True): + tr.log_action( + 'pretix.event.taxrule.changed', user=self.request.user, data={ + 'default': False, + } + ) + tr.default = False + tr.save(update_fields=['default']) + obj.log_action( + 'pretix.event.taxrule.changed', user=self.request.user, data={ + 'default': True, + } + ) + obj.default = True + obj.save(update_fields=['default']) + return redirect(self.get_success_url()) + + def get_success_url(self) -> str: + return reverse('control:event.settings.tax', kwargs={ + 'organizer': self.request.event.organizer.slug, + 'event': self.request.event.slug, + }) + + class TaxDelete(EventSettingsViewMixin, EventPermissionRequiredMixin, CompatDeleteView): model = TaxRule template_name = 'pretixcontrol/event/tax_delete.html' diff --git a/src/pretix/control/views/main.py b/src/pretix/control/views/main.py index 1f1b24caf..6501aea34 100644 --- a/src/pretix/control/views/main.py +++ b/src/pretix/control/views/main.py @@ -181,8 +181,9 @@ class EventWizard(SafeSessionWizardView): initial['location'] = self.clone_from.location initial['timezone'] = self.clone_from.settings.timezone initial['locale'] = self.clone_from.settings.locale - if self.clone_from.settings.tax_rate_default: - initial['tax_rate'] = self.clone_from.settings.tax_rate_default.rate + tax_rule = self.clone_from.cached_default_tax_rule + if tax_rule: + initial['tax_rate'] = tax_rule.rate if 'organizer' in self.request.GET: if step == 'foundation': try: @@ -325,10 +326,17 @@ class EventWizard(SafeSessionWizardView): event.set_defaults() if basics_data['tax_rate'] is not None: - if not event.settings.tax_rate_default or event.settings.tax_rate_default.rate != basics_data['tax_rate']: - event.settings.tax_rate_default = event.tax_rules.create( + if self.clone_from: + default_tax_rule = self.clone_from.cached_default_tax_rule + elif copy_data and copy_data['copy_from_event']: + default_tax_rule = from_event.cached_default_tax_rule + else: + default_tax_rule = None + if not default_tax_rule or default_tax_rule.rate != basics_data['tax_rate']: + event.tax_rules.create( name=LazyI18nString.from_gettext(gettext('VAT')), - rate=basics_data['tax_rate'] + rate=basics_data['tax_rate'], + default=not default_tax_rule, ) event.settings.set('timezone', basics_data['timezone']) diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index e1658b787..8785f5bd7 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -66,7 +66,7 @@ from django.utils.html import conditional_escape, escape from django.utils.http import url_has_allowed_host_and_scheme from django.utils.safestring import mark_safe from django.utils.timezone import make_aware, now -from django.utils.translation import gettext, gettext_lazy as _, ngettext +from django.utils.translation import gettext, gettext_lazy as _ from django.views.generic import ( DetailView, FormView, ListView, TemplateView, View, ) @@ -83,6 +83,7 @@ from pretix.base.models import ( ) from pretix.base.models.orders import ( CancellationRequest, OrderFee, OrderPayment, OrderPosition, OrderRefund, + PrintLog, ) from pretix.base.models.tax import ask_for_vat_id from pretix.base.payment import PaymentException @@ -92,7 +93,7 @@ from pretix.base.services.cancelevent import cancel_event from pretix.base.services.export import export, scheduled_event_export from pretix.base.services.invoices import ( generate_cancellation, generate_invoice, invoice_pdf, invoice_pdf_task, - invoice_qualified, regenerate_invoice, + invoice_qualified, regenerate_invoice, transmit_invoice, ) from pretix.base.services.locking import LockTimeoutException from pretix.base.services.mail import ( @@ -372,6 +373,10 @@ class OrderOverpaidRefundBulkActionView(BaseOrderBulkActionView): comment=_("Refund for overpayment"), provider=payment.provider ) + instance.log_action('pretix.event.order.refund.created', { + 'local_id': refund.local_id, + 'provider': refund.provider, + }, user=self.request.user) payment.payment_provider.execute_refund(refund) return True except (ValueError, PaymentException): @@ -546,27 +551,6 @@ class OrderDetail(OrderView): ctx['payment_refund_sum'] = self.order.payment_refund_sum ctx['pending_sum'] = self.order.pending_sum - unsent_invoices = [ii.pk for ii in ctx['invoices'] if not ii.sent_to_customer] - if unsent_invoices: - with language(self.order.locale): - ctx['invoices_send_link'] = reverse('control:event.order.sendmail', kwargs={ - 'event': self.request.event.slug, - 'organizer': self.request.event.organizer.slug, - 'code': self.order.code - }) + '?' + urlencode({ - 'subject': ngettext('Your invoice', 'Your invoices', len(unsent_invoices)), - 'message': ngettext( - 'Hello,\n\nplease find your invoice attached to this email.\n\n' - 'Your {event} team', - 'Hello,\n\nplease find your invoices attached to this email.\n\n' - 'Your {event} team', - len(unsent_invoices) - ).format( - event="{event}", - ), - 'attach_invoices': unsent_invoices - }, doseq=True) - return ctx @cached_property @@ -597,6 +581,7 @@ class OrderDetail(OrderView): 'item__questions', 'issued_gift_cards', 'owned_gift_cards', 'linked_media', Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options').select_related('question')), Prefetch('all_checkins', queryset=Checkin.all.select_related('list').order_by('datetime')), + Prefetch('print_logs', queryset=PrintLog.objects.select_related('device').order_by('datetime')), ).order_by('positionid') positions = [] @@ -1456,8 +1441,11 @@ class OrderTransition(OrderView): } ) + @transaction.atomic() def post(self, request, *args, **kwargs): to = self.request.POST.get('status', '') + self.order = Order.objects.select_for_update(of=OF_SELF).get(pk=self.order.pk) + if self.order.status in (Order.STATUS_PENDING, Order.STATUS_EXPIRED) and to == 'p' and self.mark_paid_form.is_valid(): ps = self.mark_paid_form.cleaned_data['amount'] @@ -1487,13 +1475,12 @@ class OrderTransition(OrderView): for p in self.order.payments.filter(state__in=(OrderPayment.PAYMENT_STATE_PENDING, OrderPayment.PAYMENT_STATE_CREATED)): try: - with transaction.atomic(): - if p.payment_provider: - p.payment_provider.cancel_payment(p) - self.order.log_action('pretix.event.order.payment.canceled', { - 'local_id': p.local_id, - 'provider': p.provider, - }, user=self.request.user if self.request.user.is_authenticated else None) + if p.payment_provider: + p.payment_provider.cancel_payment(p) + self.order.log_action('pretix.event.order.payment.canceled', { + 'local_id': p.local_id, + 'provider': p.provider, + }, user=self.request.user if self.request.user.is_authenticated else None) except PaymentException as e: self.order.log_action( 'pretix.event.order.payment.canceled.failed', @@ -1673,6 +1660,8 @@ class OrderInvoiceRegenerate(OrderView): else: if not inv.event.settings.invoice_regenerate_allowed: messages.error(self.request, _('Invoices may not be changed after they are created.')) + elif not inv.regenerate_allowed: + messages.error(self.request, _('Invoices may not be changed after they are transmitted.')) if inv.canceled: messages.error(self.request, _('The invoice has already been canceled.')) elif inv.sent_to_organizer: @@ -1693,6 +1682,37 @@ class OrderInvoiceRegenerate(OrderView): return HttpResponseNotAllowed(['POST']) +class OrderInvoiceRetransmit(OrderView): + permission = 'can_change_orders' + + def post(self, *args, **kwargs): + with transaction.atomic(durable=True): + try: + invoice = self.order.invoices.select_for_update(of=OF_SELF).get(pk=kwargs.get("id")) + except Invoice.DoesNotExist: + messages.error(self.request, _('Unknown invoice.')) + return redirect(self.get_order_url()) + + if invoice.transmission_status == Invoice.TRANSMISSION_STATUS_INFLIGHT: + messages.error(self.request, _('The invoice is currently being transmitted. You can start a new attempt after ' + 'the current one has been completed.')) + return redirect(self.get_order_url()) + + invoice.transmission_status = Invoice.TRANSMISSION_STATUS_PENDING + invoice.transmission_date = now() + invoice.save(update_fields=["transmission_status", "transmission_date"]) + messages.success(self.request, _('The invoice has been scheduled for retransmission.')) + self.order.log_action('pretix.event.order.invoice.retransmitted', user=self.request.user, data={ + 'invoice': invoice.pk, + 'full_invoice_no': invoice.full_invoice_no, + }) + transmit_invoice.apply_async(args=(self.request.event.pk, invoice.pk, True)) + return redirect(self.get_order_url()) + + def get(self, *args, **kwargs): # NOQA + return HttpResponseNotAllowed(['POST']) + + class OrderInvoiceReissue(OrderView): permission = 'can_change_orders' diff --git a/src/pretix/control/views/organizer.py b/src/pretix/control/views/organizer.py index dba56b546..d0fe7a6ff 100644 --- a/src/pretix/control/views/organizer.py +++ b/src/pretix/control/views/organizer.py @@ -33,10 +33,13 @@ # License for the specific language governing permissions and limitations under the License. import json +import logging import re +from collections import Counter from datetime import time, timedelta from decimal import Decimal from hashlib import sha1 +from itertools import groupby from json import JSONDecodeError import bleach @@ -59,9 +62,11 @@ from django.http import ( Http404, HttpResponse, HttpResponseBadRequest, JsonResponse, ) from django.shortcuts import get_object_or_404, redirect, render -from django.urls import reverse +from django.urls import NoReverseMatch, reverse from django.utils.formats import date_format from django.utils.functional import cached_property +from django.utils.html import format_html +from django.utils.safestring import mark_safe from django.utils.timezone import get_current_timezone, now from django.utils.translation import gettext, gettext_lazy as _ from django.views import View @@ -69,6 +74,7 @@ from django.views.decorators.http import require_http_methods from django.views.generic import ( CreateView, DetailView, FormView, ListView, TemplateView, UpdateView, ) +from django.views.generic.detail import SingleObjectMixin from pretix.api.models import ApiCall, WebHook from pretix.api.webhooks import manually_retry_all_calls @@ -91,6 +97,10 @@ from pretix.base.models.giftcards import ( from pretix.base.models.orders import CancellationRequest from pretix.base.models.organizer import SalesChannel, TeamAPIToken from pretix.base.payment import PaymentException +from pretix.base.plugins import ( + PLUGIN_LEVEL_EVENT, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID, + PLUGIN_LEVEL_ORGANIZER, +) from pretix.base.services.export import multiexport, scheduled_organizer_export from pretix.base.services.mail import SendMailException, mail, prefix_subject from pretix.base.signals import register_multievent_data_exporters @@ -108,9 +118,9 @@ from pretix.control.forms.organizer import ( GiftCardAcceptanceInviteForm, GiftCardCreateForm, GiftCardUpdateForm, KnownDomainFormset, MailSettingsForm, MembershipTypeForm, MembershipUpdateForm, OrganizerDeleteForm, OrganizerFooterLinkFormset, - OrganizerForm, OrganizerSettingsForm, OrganizerUpdateForm, - ReusableMediumCreateForm, ReusableMediumUpdateForm, SalesChannelForm, - SSOClientForm, SSOProviderForm, TeamForm, WebHookForm, + OrganizerForm, OrganizerPluginEventsForm, OrganizerSettingsForm, + OrganizerUpdateForm, ReusableMediumCreateForm, ReusableMediumUpdateForm, + SalesChannelForm, SSOClientForm, SSOProviderForm, TeamForm, WebHookForm, ) from pretix.control.forms.rrule import RRuleForm from pretix.control.logdisplay import OVERVIEW_BANLIST @@ -129,6 +139,8 @@ from pretix.helpers.urls import build_absolute_uri as build_global_uri from pretix.multidomain.urlreverse import build_absolute_uri from pretix.presale.forms.customer import TokenGenerator +logger = logging.getLogger(__name__) + class OrganizerList(PaginationMixin, ListView): model = Organizer @@ -582,6 +594,263 @@ class OrganizerCreate(CreateView): }) +class OrganizerPlugins(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, TemplateView, SingleObjectMixin): + model = Organizer + context_object_name = 'organizer' + permission = 'can_change_organizer_settings' + template_name = 'pretixcontrol/organizers/plugins.html' + + def get_object(self, queryset=None) -> Organizer: + return self.request.organizer + + def available_plugins(self, organizer): + from pretix.base.plugins import get_all_plugins + + return (p for p in get_all_plugins(organizer=organizer) if not p.name.startswith('.') + and getattr(p, 'visible', True)) + + def prepare_links(self, pluginmeta, key): + links = getattr(pluginmeta, key, []) + try: + result = [] + for linktext, urlname, kwargs in links: + try: + result.append(( + reverse(urlname, kwargs={"organizer": self.request.organizer.slug}), + " > ".join(map(str, linktext)) if isinstance(linktext, tuple) else linktext, + )) + except NoReverseMatch: + if pluginmeta.level != PLUGIN_LEVEL_ORGANIZER: + # Ignore, link might be for another level + pass + else: + raise + return result + except: + logger.exception('Failed to resolve settings links.') + return [] + + def get_context_data(self, *args, **kwargs) -> dict: + from pretix.base.plugins import CATEGORY_LABELS, CATEGORY_ORDER + + context = super().get_context_data(*args, **kwargs) + plugins = list(self.available_plugins(self.object)) + + active_counter = Counter() + events_total = 0 + for e in self.object.events.only("plugins").iterator(): + events_total += 1 + for p in e.get_plugins(): + active_counter[p] += 1 + plugins_grouped = groupby( + sorted( + plugins, + key=lambda p: ( + str(getattr(p, 'category', _('Other'))), + (0 if getattr(p, 'featured', False) else 1), + str(p.name).lower().replace('pretix ', '') + ), + ), + lambda p: str(getattr(p, 'category', _('Other'))) + ) + plugins_grouped = [(c, list(plist)) for c, plist in plugins_grouped] + + active_plugins = self.object.get_plugins() + + def plugin_details(plugin): + is_active = plugin.module in active_plugins + events_counter = active_counter[plugin.module] + settings_links = self.prepare_links(plugin, 'settings_links') if is_active else None + navigation_links = self.prepare_links(plugin, 'navigation_links') if is_active else None + return plugin, is_active, settings_links, navigation_links, events_counter + + context['plugins'] = sorted([ + (c, CATEGORY_LABELS.get(c, c), map(plugin_details, plist), any(getattr(p, 'picture', None) for p in plist)) + for c, plist + in plugins_grouped + ], key=lambda c: (CATEGORY_ORDER.index(c[0]), c[1]) if c[0] in CATEGORY_ORDER else (999, str(c[1]))) + context['show_meta'] = settings.PRETIX_PLUGINS_SHOW_META + context['events_total'] = events_total + return context + + def get(self, request, *args, **kwargs): + self.object = self.get_object() + context = self.get_context_data(object=self.object) + return self.render_to_response(context) + + def post(self, request, *args, **kwargs): + self.object = self.get_object() + + plugins_available = { + p.module: p for p in self.available_plugins(self.object) + } + choose_events_next = False + with transaction.atomic(): + for key, value in request.POST.items(): + if key.startswith("plugin:"): + module = key.split(":")[1] + if value == "enable" and module in plugins_available: + pluginmeta = plugins_available[module] + if getattr(pluginmeta, 'restricted', False): + if module not in request.organizer.settings.allowed_restricted_plugins: + continue + + level = getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT) + if level not in (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID): + continue + + if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID: + choose_events_next = module + + self.object.log_action('pretix.organizer.plugins.enabled', user=self.request.user, + data={'plugin': module}) + self.object.enable_plugin(module, allow_restricted=request.organizer.settings.allowed_restricted_plugins) + + links = self.prepare_links(pluginmeta, 'settings_links') + if links: + info = [ + '

    ', + format_html(_('The plugin {} is now active, you can configure it here:'), + format_html("{}", pluginmeta.name)), + '

    '] + else: + info = [ + format_html(_('The plugin {} is now active.'), + format_html("{}", pluginmeta.name)), + ] + messages.success(self.request, mark_safe("".join(info))) + elif value == "disable" and module in plugins_available: + pluginmeta = plugins_available[module] + level = getattr(pluginmeta, 'level', PLUGIN_LEVEL_EVENT) + if level not in (PLUGIN_LEVEL_ORGANIZER, PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID): + continue + + if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID: + events_to_disable = set(self.request.organizer.events.filter( + plugins__regex='(^|,)' + module + '(,|$)' + ).values_list("pk", flat=True)) + logentries_to_save = [] + events_to_save = [] + + for e in self.request.organizer.events.filter(pk__in=events_to_disable): + logentries_to_save.append( + e.log_action('pretix.event.plugins.disabled', user=self.request.user, + data={'plugin': module}, save=False) + ) + e.disable_plugin(module) + events_to_save.append(e) + + Event.objects.bulk_update(events_to_save, fields=["plugins"]) + LogEntry.objects.bulk_create(logentries_to_save) + + self.object.log_action('pretix.organizer.plugins.disabled', user=self.request.user, + data={'plugin': module}) + self.object.disable_plugin(module) + messages.success(self.request, _('The plugin has been disabled.')) + self.object.save() + if choose_events_next: + return redirect(reverse('control:organizer.settings.plugin-events', kwargs={ + 'organizer': self.request.organizer.slug, + 'plugin': choose_events_next, + })) + else: + return redirect(self.get_success_url()) + + def get_success_url(self) -> str: + return reverse('control:organizer.settings.plugins', kwargs={ + 'organizer': self.request.organizer.slug, + }) + + +class OrganizerPluginEvents(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, FormView): + model = Organizer + context_object_name = 'organizer' + permission = 'can_change_organizer_settings' + template_name = 'pretixcontrol/organizers/plugin_events.html' + form_class = OrganizerPluginEventsForm + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs["events"] = self.request.user.get_events_with_permission( + "can_change_event_settings", request=self.request + ).filter(organizer=self.request.organizer) + kwargs["initial"] = { + "events": self.request.organizer.events.filter(plugins__regex='(^|,)' + self.plugin.module + '(,|$)') + } + return kwargs + + def available_plugins(self, organizer): + from pretix.base.plugins import get_all_plugins + + return (p for p in get_all_plugins(organizer=organizer) if not p.name.startswith('.') + and getattr(p, 'visible', True)) + + def get_context_data(self, **kwargs): + return super().get_context_data( + plugin=self.plugin, + **kwargs + ) + + def dispatch(self, request, *args, **kwargs): + plugins_available = { + p.module: p for p in self.available_plugins(self.request.organizer) + } + if kwargs["plugin"] not in plugins_available: + raise Http404(_("Unknown plugin.")) + self.plugin = plugins_available[kwargs["plugin"]] + level = getattr(self.plugin, "level", PLUGIN_LEVEL_EVENT) + if level == PLUGIN_LEVEL_ORGANIZER: + raise Http404(_("This plugin can only be enabled for the entire organizer account.")) + if level == PLUGIN_LEVEL_EVENT_ORGANIZER_HYBRID and self.plugin.module not in self.request.organizer.get_plugins(): + raise Http404(_("This plugin is currently not active on the organizer account.")) + + if getattr(self.plugin, 'restricted', False): + if self.plugin.module not in request.organizer.settings.allowed_restricted_plugins: + raise Http404(_("This plugin is currently not allowed for this organizer account.")) + + return super().dispatch(request, *args, **kwargs) + + def get_success_url(self) -> str: + return reverse('control:organizer.settings.plugins', kwargs={ + 'organizer': self.request.organizer.slug, + }) + + @transaction.atomic() + def form_valid(self, form): + enabled_events_before = set( + self.request.organizer.events.filter(plugins__regex='(^|,)' + self.plugin.module + '(,|$)').values_list("pk", flat=True) + ) + enabled_events_now = {e.pk for e in form.cleaned_data["events"]} + + events_to_enable = enabled_events_now - enabled_events_before + events_to_disable = enabled_events_before - enabled_events_now + events_to_save = [] + logentries_to_save = [] + + for e in self.request.organizer.events.filter(pk__in=events_to_enable): + logentries_to_save.append( + e.log_action('pretix.event.plugins.enabled', user=self.request.user, data={'plugin': self.plugin.module}, save=False) + ) + e.enable_plugin(self.plugin.module, allow_restricted=self.request.organizer.settings.allowed_restricted_plugins) + events_to_save.append(e) + + for e in self.request.organizer.events.filter(pk__in=events_to_disable): + logentries_to_save.append( + e.log_action('pretix.event.plugins.disabled', user=self.request.user, data={'plugin': self.plugin.module}, save=False) + ) + e.disable_plugin(self.plugin.module) + events_to_save.append(e) + + Event.objects.bulk_update(events_to_save, fields=["plugins"]) + LogEntry.objects.bulk_create(logentries_to_save) + messages.success(self.request, _("Your changes have been saved.")) + return super().form_valid(form) + + class TeamListView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin, PaginationMixin, ListView): model = Team template_name = 'pretixcontrol/organizers/teams.html' diff --git a/src/pretix/control/views/subevents.py b/src/pretix/control/views/subevents.py index 6c6b043f6..e047f5f30 100644 --- a/src/pretix/control/views/subevents.py +++ b/src/pretix/control/views/subevents.py @@ -49,7 +49,7 @@ from django.shortcuts import redirect, render from django.urls import reverse from django.utils.formats import get_format from django.utils.functional import cached_property -from django.utils.timezone import make_aware +from django.utils.timezone import make_aware, now from django.utils.translation import gettext_lazy as _, pgettext_lazy from django.views import View from django.views.generic import CreateView, FormView, ListView, UpdateView @@ -768,8 +768,15 @@ class SubEventBulkCreate(SubEventEditorMixin, EventPermissionRequiredMixin, Asyn ctx['time_formset'] = self.time_formset tf = get_format('TIME_INPUT_FORMATS')[0] + ctx['time_admission_sample'] = time(8, 30, 0).strftime(tf) ctx['time_begin_sample'] = time(9, 0, 0).strftime(tf) ctx['time_end_sample'] = time(18, 0, 0).strftime(tf) + + df = get_format('DATETIME_INPUT_FORMATS')[0] + ctx['datetime_sample'] = now().replace( + year=2000, month=12, day=31, hour=18, minute=0, second=0, microsecond=0 + ).strftime(df) + return ctx @cached_property diff --git a/src/pretix/control/views/vouchers.py b/src/pretix/control/views/vouchers.py index 9990039cb..bee6db27e 100644 --- a/src/pretix/control/views/vouchers.py +++ b/src/pretix/control/views/vouchers.py @@ -380,7 +380,7 @@ class VoucherCreate(EventPermissionRequiredMixin, CreateView): messages.success(self.request, mark_safe(_('The new voucher has been created: {code}').format( code=format_html('{code}', url=url, code=self.object.code) ))) - form.instance.log_action('pretix.voucher.added', data=dict(form.cleaned_data), user=self.request.user) + form.instance.log_action('pretix.voucher.added', data={**dict(form.cleaned_data), "source": "control"}, user=self.request.user) return ret @transaction.atomic @@ -475,7 +475,7 @@ class VoucherBulkCreate(EventPermissionRequiredMixin, AsyncFormView): data['bulk'] = True del data['codes'] log_entries.append( - v.log_action('pretix.voucher.added', data=data, user=self.request.user, save=False) + v.log_action('pretix.voucher.added', data={**data, "source": "control_bulk"}, user=self.request.user, save=False) ) LogEntry.bulk_create_and_postprocess(log_entries) form.post_bulk_save(batch_vouchers) diff --git a/src/pretix/helpers/countries.py b/src/pretix/helpers/countries.py index 64c14d3e4..cb02e4599 100644 --- a/src/pretix/helpers/countries.py +++ b/src/pretix/helpers/countries.py @@ -22,6 +22,7 @@ from babel.core import Locale from django.core.cache import cache from django.utils import translation +from django.utils.translation import gettext_noop from django_countries import Countries, collator from django_countries.fields import CountryField from phonenumbers.data import _COUNTRY_CODE_TO_REGION_CODE @@ -118,3 +119,14 @@ def get_phone_prefixes_sorted_and_localized(): _cached_phone_prefixes[cache_key] = val cache.set(cache_key, val, 3600 * 24 * 30) return val + + +custom_translations = [ + # Hotfix to allow pretix to provide custom translations until + # https://github.com/SmileyChris/django-countries/pull/471 + # is merged + gettext_noop("Belarus"), + gettext_noop("French Guiana"), + gettext_noop("North Macedonia"), + gettext_noop("Macao"), +] diff --git a/src/pretix/helpers/i18n.py b/src/pretix/helpers/i18n.py index 42c91b50e..ef30c0c57 100644 --- a/src/pretix/helpers/i18n.py +++ b/src/pretix/helpers/i18n.py @@ -32,7 +32,6 @@ from django.conf import settings from django.utils import translation from django.utils.formats import get_format from django.utils.translation import to_locale -from django.utils.translation.trans_real import TranslationCatalog date_conversion_to_moment = { '%a': 'ddd', @@ -175,7 +174,7 @@ def get_language_score(locale): Note that there is no valid score for "en", since it's technically not "translated". """ - catalog = None + catalog = {} app_configs = reversed(apps.get_app_configs()) for app in app_configs: @@ -198,10 +197,15 @@ def get_language_score(locale): ) except: continue - if catalog is None: - catalog = TranslationCatalog(translation) - else: - catalog.update(translation) + + catalog.update(translation._catalog.copy()) + + # Also add fallback catalog (e.g. es for es-419, de for de-informal, …) + while translation._fallback: + if not locale.startswith(translation._fallback.info().get("language", "XX")): + break + translation = translation._fallback + catalog.update(translation._catalog.copy()) # Add pretix' main translation folder as well as installation-specific translation folders for localedir in reversed(settings.LOCALE_PATHS): @@ -214,10 +218,13 @@ def get_language_score(locale): ) except: continue - if catalog is None: - catalog = TranslationCatalog(translation) - else: - catalog.update(translation) + catalog.update(translation._catalog.copy()) + + while translation._fallback: + if not locale.startswith(translation._fallback.info().get("language", "XX")): + break + translation = translation._fallback + catalog.update(translation._catalog.copy()) if not catalog: score = 1 diff --git a/src/pretix/helpers/reportlab.py b/src/pretix/helpers/reportlab.py index 275d0205c..574bf9696 100644 --- a/src/pretix/helpers/reportlab.py +++ b/src/pretix/helpers/reportlab.py @@ -19,11 +19,20 @@ # You should have received a copy of the GNU Affero General Public License along with this program. If not, see # . # +import logging + from arabic_reshaper import ArabicReshaper from django.conf import settings from django.utils.functional import SimpleLazyObject from PIL import Image +from reportlab.lib.styles import ParagraphStyle from reportlab.lib.utils import ImageReader +from reportlab.pdfbase import pdfmetrics +from reportlab.platypus import Paragraph + +from pretix.presale.style import get_fonts + +logger = logging.getLogger(__name__) class ThumbnailingImageReader(ImageReader): @@ -59,3 +68,35 @@ reshaper = SimpleLazyObject(lambda: ArabicReshaper(configuration={ 'delete_harakat': True, 'support_ligatures': False, })) + + +class FontFallbackParagraph(Paragraph): + def __init__(self, text, style=None, *args, **kwargs): + if style is None: + style = ParagraphStyle(name='paragraphImplicitDefaultStyle') + + if not self._font_supports_text(text, style.fontName): + newFont = self._find_font(text, style.fontName) + if newFont: + logger.debug(f"replacing {style.fontName} with {newFont} for {text!r}") + style = style.clone(name=style.name + '_' + newFont, fontName=newFont) + + super().__init__(text, style, *args, **kwargs) + + def _font_supports_text(self, text, font_name): + if not text: + return True + font = pdfmetrics.getFont(font_name) + return all( + ord(c) in font.face.charToGlyph or not c.isprintable() + for c in text + ) + + def _find_font(self, text, original_font): + for family, styles in get_fonts(pdf_support_required=True).items(): + if self._font_supports_text(text, family): + if (original_font.endswith("It") or original_font.endswith(" I")) and "italic" in styles: + return family + " I" + if (original_font.endswith("Bd") or original_font.endswith(" B")) and "bold" in styles: + return family + " B" + return family diff --git a/src/pretix/locale/ang/LC_MESSAGES/django.po b/src/pretix/locale/ang/LC_MESSAGES/django.po index ee4913bf9..7f8543644 100644 --- a/src/pretix/locale/ang/LC_MESSAGES/django.po +++ b/src/pretix/locale/ang/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-06-26 09:09+0000\n" +"POT-Creation-Date: 2025-08-19 16:35+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -142,10 +142,14 @@ msgid "Spanish" msgstr "" #: pretix/_base_settings.py:118 -msgid "Turkish" +msgid "Spanish (Latin America)" msgstr "" #: pretix/_base_settings.py:119 +msgid "Turkish" +msgstr "" + +#: pretix/_base_settings.py:120 msgid "Ukrainian" msgstr "" @@ -184,7 +188,7 @@ msgid "Allowed Post Logout URIs list, space separated" msgstr "" #: pretix/api/models.py:51 pretix/base/models/customers.py:406 -#: pretix/plugins/paypal/payment.py:113 pretix/plugins/paypal2/payment.py:110 +#: pretix/plugins/paypal/payment.py:114 pretix/plugins/paypal2/payment.py:111 msgid "Client ID" msgstr "" @@ -202,66 +206,66 @@ msgid "Target URL" msgstr "" #: pretix/api/models.py:118 pretix/base/models/devices.py:122 -#: pretix/base/models/organizer.py:286 +#: pretix/base/models/organizer.py:352 msgid "All events (including newly created ones)" msgstr "" #: pretix/api/models.py:119 pretix/base/models/devices.py:123 -#: pretix/base/models/organizer.py:287 +#: pretix/base/models/organizer.py:353 msgid "Limit to events" msgstr "" -#: pretix/api/models.py:120 pretix/base/exporters/orderlist.py:284 -#: pretix/base/exporters/orderlist.py:1077 -#: pretix/base/modelimport_orders.py:602 +#: pretix/api/models.py:120 pretix/base/exporters/orderlist.py:285 +#: pretix/base/exporters/orderlist.py:1095 #: pretix/base/modelimport_vouchers.py:326 pretix/base/models/orders.py:272 -#: pretix/base/models/vouchers.py:292 pretix/control/forms/filter.py:557 -#: pretix/control/templates/pretixcontrol/order/index.html:898 +#: pretix/base/models/vouchers.py:295 pretix/control/forms/filter.py:557 +#: pretix/control/templates/pretixcontrol/order/index.html:950 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:38 #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:21 #: pretix/control/views/vouchers.py:121 #: pretix/plugins/banktransfer/refund_export.py:46 -#: pretix/plugins/checkinlists/exporters.py:523 +#: pretix/plugins/checkinlists/exporters.py:524 msgid "Comment" msgstr "" -#: pretix/api/serializers/cart.py:168 pretix/api/serializers/order.py:1414 +#: pretix/api/serializers/cart.py:168 pretix/api/serializers/order.py:1466 +#, python-brace-format msgid "The product \"{}\" is not assigned to a quota." msgstr "" -#: pretix/api/serializers/checkin.py:65 pretix/base/models/event.py:1691 +#: pretix/api/serializers/checkin.py:65 pretix/base/models/event.py:1698 #: pretix/base/models/items.py:1917 pretix/base/models/items.py:2203 msgid "One or more items do not belong to this event." msgstr "" #: pretix/api/serializers/checkin.py:69 pretix/api/serializers/checkin.py:72 #: pretix/base/models/items.py:2214 pretix/base/models/items.py:2217 -#: pretix/base/models/waitinglist.py:307 pretix/base/models/waitinglist.py:310 +#: pretix/base/models/waitinglist.py:310 pretix/base/models/waitinglist.py:313 msgid "The subevent does not belong to this event." msgstr "" -#: pretix/api/serializers/event.py:231 +#: pretix/api/serializers/event.py:219 msgid "" "Events cannot be created as 'live'. Quotas and payment must be added to the " "event before sales can go live." msgstr "" -#: pretix/api/serializers/event.py:246 pretix/api/serializers/event.py:555 +#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554 #, python-brace-format msgid "Meta data property '{name}' does not exist." msgstr "" -#: pretix/api/serializers/event.py:249 pretix/api/serializers/event.py:558 +#: pretix/api/serializers/event.py:237 pretix/api/serializers/event.py:557 #, python-brace-format msgid "Meta data property '{name}' does not allow value '{value}'." msgstr "" -#: pretix/api/serializers/event.py:293 +#: pretix/api/serializers/event.py:283 pretix/api/serializers/organizer.py:85 #, python-brace-format msgid "Unknown plugin: '{name}'." msgstr "" -#: pretix/api/serializers/event.py:296 +#: pretix/api/serializers/event.py:286 pretix/api/serializers/organizer.py:88 #, python-brace-format msgid "Restricted plugin: '{name}'." msgstr "" @@ -272,11 +276,11 @@ msgstr "" msgid "Item meta data property '{name}' does not exist." msgstr "" -#: pretix/api/serializers/item.py:207 pretix/control/forms/item.py:1273 +#: pretix/api/serializers/item.py:207 pretix/control/forms/item.py:1274 msgid "The bundled item must not be the same item as the bundling one." msgstr "" -#: pretix/api/serializers/item.py:210 pretix/control/forms/item.py:1275 +#: pretix/api/serializers/item.py:210 pretix/control/forms/item.py:1276 msgid "The bundled item must not have bundles on its own." msgstr "" @@ -296,7 +300,7 @@ msgid "" "sales tax will be applied when the gift card is redeemed." msgstr "" -#: pretix/api/serializers/item.py:322 pretix/control/forms/item.py:780 +#: pretix/api/serializers/item.py:322 pretix/control/forms/item.py:781 msgid "Gift card products should not be admission products at the same time." msgstr "" @@ -306,19 +310,19 @@ msgid "" "nested endpoint." msgstr "" -#: pretix/api/serializers/item.py:538 pretix/control/forms/item.py:178 +#: pretix/api/serializers/item.py:538 pretix/control/forms/item.py:176 msgid "Question cannot depend on a question asked during check-in." msgstr "" -#: pretix/api/serializers/item.py:543 pretix/control/forms/item.py:183 +#: pretix/api/serializers/item.py:543 pretix/control/forms/item.py:181 msgid "Circular dependency between questions detected." msgstr "" -#: pretix/api/serializers/item.py:548 pretix/control/forms/item.py:192 +#: pretix/api/serializers/item.py:548 pretix/control/forms/item.py:190 msgid "This type of question cannot be asked during check-in." msgstr "" -#: pretix/api/serializers/item.py:551 pretix/control/forms/item.py:200 +#: pretix/api/serializers/item.py:551 pretix/control/forms/item.py:198 msgid "This type of question cannot be shown during check-in." msgstr "" @@ -328,50 +332,52 @@ msgid "" "account." msgstr "" -#: pretix/api/serializers/order.py:79 +#: pretix/api/serializers/order.py:81 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "" -#: pretix/api/serializers/order.py:1375 pretix/api/views/cart.py:224 -#: pretix/base/services/orders.py:1533 +#: pretix/api/serializers/order.py:1427 pretix/api/views/cart.py:224 +#: pretix/base/services/orders.py:1589 #, python-brace-format msgid "The selected seat \"{seat}\" is not available." msgstr "" -#: pretix/api/serializers/order.py:1401 pretix/api/serializers/order.py:1408 +#: pretix/api/serializers/order.py:1453 pretix/api/serializers/order.py:1460 +#, python-brace-format msgid "The product \"{}\" is not available on this date." msgstr "" -#: pretix/api/serializers/order.py:1423 pretix/api/views/cart.py:200 +#: pretix/api/serializers/order.py:1475 pretix/api/views/cart.py:200 +#, python-brace-format msgid "" "There is not enough quota available on quota \"{}\" to perform the operation." msgstr "" -#: pretix/api/serializers/organizer.py:105 -#: pretix/control/forms/organizer.py:892 pretix/presale/forms/customer.py:458 +#: pretix/api/serializers/organizer.py:145 +#: pretix/control/forms/organizer.py:893 pretix/presale/forms/customer.py:458 msgid "An account with this email address is already registered." msgstr "" -#: pretix/api/serializers/organizer.py:238 -#: pretix/control/forms/organizer.py:741 +#: pretix/api/serializers/organizer.py:278 +#: pretix/control/forms/organizer.py:746 msgid "" "A gift card with the same secret already exists in your or an affiliated " "organizer account." msgstr "" -#: pretix/api/serializers/organizer.py:329 -#: pretix/control/views/organizer.py:773 +#: pretix/api/serializers/organizer.py:369 +#: pretix/control/views/organizer.py:1042 msgid "pretix account invitation" msgstr "" -#: pretix/api/serializers/organizer.py:351 -#: pretix/control/views/organizer.py:872 +#: pretix/api/serializers/organizer.py:391 +#: pretix/control/views/organizer.py:1141 msgid "This user already has been invited for this team." msgstr "" -#: pretix/api/serializers/organizer.py:367 -#: pretix/control/views/organizer.py:889 +#: pretix/api/serializers/organizer.py:407 +#: pretix/control/views/organizer.py:1158 msgid "This user already has permissions for this team." msgstr "" @@ -380,215 +386,237 @@ msgid "" "The specified voucher has already been used the maximum number of times." msgstr "" -#: pretix/api/views/checkin.py:611 pretix/api/views/checkin.py:618 +#: pretix/api/views/checkin.py:616 pretix/api/views/checkin.py:623 msgid "Medium connected to other event" msgstr "" -#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:692 +#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:753 #, python-brace-format msgid "" "The application \"{application_name}\" has been authorized to access your " "account." msgstr "" -#: pretix/api/views/order.py:607 pretix/control/views/orders.py:1610 +#: pretix/api/views/order.py:608 pretix/control/views/orders.py:1597 #: pretix/presale/views/order.py:733 pretix/presale/views/order.py:806 msgid "You cannot generate an invoice for this order." msgstr "" -#: pretix/api/views/order.py:612 pretix/control/views/orders.py:1612 +#: pretix/api/views/order.py:613 pretix/control/views/orders.py:1599 #: pretix/presale/views/order.py:735 pretix/presale/views/order.py:808 msgid "An invoice for this order already exists." msgstr "" -#: pretix/api/views/order.py:638 pretix/control/views/orders.py:1738 +#: pretix/api/views/order.py:639 pretix/control/views/orders.py:1758 #: pretix/control/views/users.py:145 msgid "There was an error sending the mail. Please try again later." msgstr "" -#: pretix/api/views/order.py:718 pretix/base/services/cart.py:216 -#: pretix/base/services/orders.py:187 pretix/presale/views/order.py:790 +#: pretix/api/views/order.py:719 pretix/base/services/cart.py:216 +#: pretix/base/services/orders.py:191 pretix/presale/views/order.py:790 msgid "One of the selected products is not available in the selected country." msgstr "" -#: pretix/api/webhooks.py:237 pretix/base/notifications.py:233 +#: pretix/api/webhooks.py:262 pretix/base/notifications.py:233 msgid "New order placed" msgstr "" -#: pretix/api/webhooks.py:241 pretix/base/notifications.py:239 +#: pretix/api/webhooks.py:266 pretix/base/notifications.py:239 msgid "New order requires approval" msgstr "" -#: pretix/api/webhooks.py:245 pretix/base/notifications.py:245 +#: pretix/api/webhooks.py:270 pretix/base/notifications.py:245 msgid "Order marked as paid" msgstr "" -#: pretix/api/webhooks.py:249 pretix/base/models/checkin.py:354 +#: pretix/api/webhooks.py:274 pretix/base/models/checkin.py:355 #: pretix/base/notifications.py:251 #: pretix/control/templates/pretixcontrol/event/mail.html:114 -#: pretix/control/views/orders.py:1571 +#: pretix/control/views/orders.py:1558 msgid "Order canceled" msgstr "" -#: pretix/api/webhooks.py:253 pretix/base/notifications.py:257 +#: pretix/api/webhooks.py:278 pretix/base/notifications.py:257 msgid "Order reactivated" msgstr "" -#: pretix/api/webhooks.py:257 pretix/base/notifications.py:263 +#: pretix/api/webhooks.py:282 pretix/base/notifications.py:263 msgid "Order expired" msgstr "" -#: pretix/api/webhooks.py:261 +#: pretix/api/webhooks.py:286 msgid "Order expiry date changed" msgstr "" -#: pretix/api/webhooks.py:265 pretix/base/notifications.py:269 +#: pretix/api/webhooks.py:290 pretix/base/notifications.py:269 msgid "Order information changed" msgstr "" -#: pretix/api/webhooks.py:269 pretix/base/notifications.py:275 +#: pretix/api/webhooks.py:294 pretix/base/notifications.py:275 msgid "Order contact address changed" msgstr "" -#: pretix/api/webhooks.py:273 pretix/base/notifications.py:281 +#: pretix/api/webhooks.py:298 pretix/base/notifications.py:281 #: pretix/control/templates/pretixcontrol/event/mail.html:102 msgid "Order changed" msgstr "" -#: pretix/api/webhooks.py:277 +#: pretix/api/webhooks.py:302 msgid "Refund of payment created" msgstr "" -#: pretix/api/webhooks.py:281 pretix/base/notifications.py:293 +#: pretix/api/webhooks.py:306 pretix/base/notifications.py:293 msgid "External refund of payment" msgstr "" -#: pretix/api/webhooks.py:285 +#: pretix/api/webhooks.py:310 msgid "Refund of payment requested by customer" msgstr "" -#: pretix/api/webhooks.py:289 +#: pretix/api/webhooks.py:314 msgid "Refund of payment completed" msgstr "" -#: pretix/api/webhooks.py:293 +#: pretix/api/webhooks.py:318 msgid "Refund of payment canceled" msgstr "" -#: pretix/api/webhooks.py:297 +#: pretix/api/webhooks.py:322 msgid "Refund of payment failed" msgstr "" -#: pretix/api/webhooks.py:301 +#: pretix/api/webhooks.py:326 msgid "Payment confirmed" msgstr "" -#: pretix/api/webhooks.py:305 +#: pretix/api/webhooks.py:330 msgid "Order approved" msgstr "" -#: pretix/api/webhooks.py:309 +#: pretix/api/webhooks.py:334 msgid "Order denied" msgstr "" -#: pretix/api/webhooks.py:313 +#: pretix/api/webhooks.py:338 msgid "Order deleted" msgstr "" -#: pretix/api/webhooks.py:317 +#: pretix/api/webhooks.py:342 msgid "Ticket checked in" msgstr "" -#: pretix/api/webhooks.py:321 +#: pretix/api/webhooks.py:346 msgid "Ticket check-in reverted" msgstr "" -#: pretix/api/webhooks.py:325 +#: pretix/api/webhooks.py:350 msgid "Event created" msgstr "" -#: pretix/api/webhooks.py:329 +#: pretix/api/webhooks.py:354 msgid "Event details changed" msgstr "" -#: pretix/api/webhooks.py:333 +#: pretix/api/webhooks.py:358 msgid "Event deleted" msgstr "" -#: pretix/api/webhooks.py:337 +#: pretix/api/webhooks.py:362 msgctxt "subevent" msgid "Event series date added" msgstr "" -#: pretix/api/webhooks.py:341 +#: pretix/api/webhooks.py:366 msgctxt "subevent" msgid "Event series date changed" msgstr "" -#: pretix/api/webhooks.py:345 +#: pretix/api/webhooks.py:370 msgctxt "subevent" msgid "Event series date deleted" msgstr "" -#: pretix/api/webhooks.py:349 -msgid "" -"Product changed (including product added or deleted and including changes to " -"nested objects like variations or bundles)" +#: pretix/api/webhooks.py:374 +msgid "Product changed" msgstr "" -#: pretix/api/webhooks.py:354 +#: pretix/api/webhooks.py:375 +msgid "" +"This includes product added or deleted and changes to nested objects like " +"variations or bundles." +msgstr "" + +#: pretix/api/webhooks.py:380 msgid "Shop taken live" msgstr "" -#: pretix/api/webhooks.py:358 +#: pretix/api/webhooks.py:384 msgid "Shop taken offline" msgstr "" -#: pretix/api/webhooks.py:362 +#: pretix/api/webhooks.py:388 msgid "Test-Mode of shop has been activated" msgstr "" -#: pretix/api/webhooks.py:366 +#: pretix/api/webhooks.py:392 msgid "Test-Mode of shop has been deactivated" msgstr "" -#: pretix/api/webhooks.py:370 +#: pretix/api/webhooks.py:396 msgid "Waiting list entry added" msgstr "" -#: pretix/api/webhooks.py:374 +#: pretix/api/webhooks.py:400 msgid "Waiting list entry changed" msgstr "" -#: pretix/api/webhooks.py:378 +#: pretix/api/webhooks.py:404 msgid "Waiting list entry deleted" msgstr "" -#: pretix/api/webhooks.py:382 +#: pretix/api/webhooks.py:408 msgid "Waiting list entry received voucher" msgstr "" -#: pretix/api/webhooks.py:386 +#: pretix/api/webhooks.py:412 +msgid "Voucher added" +msgstr "" + +#: pretix/api/webhooks.py:416 +msgid "Voucher changed" +msgstr "" + +#: pretix/api/webhooks.py:417 +msgid "" +"Only includes explicit changes to the voucher, not e.g. an increase of the " +"number of redemptions." +msgstr "" + +#: pretix/api/webhooks.py:421 +msgid "Voucher deleted" +msgstr "" + +#: pretix/api/webhooks.py:425 msgid "Customer account created" msgstr "" -#: pretix/api/webhooks.py:390 +#: pretix/api/webhooks.py:429 msgid "Customer account changed" msgstr "" -#: pretix/api/webhooks.py:394 +#: pretix/api/webhooks.py:433 msgid "Customer account anonymized" msgstr "" #: pretix/base/addressvalidation.py:100 pretix/base/addressvalidation.py:103 #: pretix/base/addressvalidation.py:108 pretix/base/forms/questions.py:1046 -#: pretix/base/forms/questions.py:1077 pretix/base/forms/questions.py:1270 -#: pretix/base/payment.py:96 pretix/control/forms/event.py:798 -#: pretix/control/forms/event.py:804 pretix/control/forms/event.py:848 -#: pretix/control/forms/event.py:1445 pretix/control/forms/mailsetup.py:87 -#: pretix/control/forms/mailsetup.py:129 pretix/control/forms/subevents.py:185 -#: pretix/plugins/banktransfer/payment.py:673 -#: pretix/plugins/banktransfer/payment.py:679 +#: pretix/base/forms/questions.py:1077 pretix/base/forms/questions.py:1328 +#: pretix/base/payment.py:96 pretix/control/forms/event.py:792 +#: pretix/control/forms/event.py:798 pretix/control/forms/event.py:838 +#: pretix/control/forms/event.py:1454 pretix/control/forms/mailsetup.py:87 +#: pretix/control/forms/mailsetup.py:129 pretix/control/forms/subevents.py:181 +#: pretix/plugins/banktransfer/payment.py:506 +#: pretix/plugins/banktransfer/payment.py:512 #: pretix/presale/forms/customer.py:152 msgid "This field is required." msgstr "" @@ -607,26 +635,26 @@ msgid "{system} User" msgstr "" #: pretix/base/auth.py:155 pretix/base/exporters/customers.py:67 -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:444 -#: pretix/base/exporters/orderlist.py:577 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:453 +#: pretix/base/exporters/orderlist.py:586 #: pretix/base/exporters/waitinglist.py:109 pretix/base/forms/auth.py:257 -#: pretix/base/models/auth.py:244 pretix/base/models/customers.py:94 -#: pretix/base/models/notifications.py:46 pretix/base/models/orders.py:246 -#: pretix/base/pdf.py:325 pretix/control/navigation.py:81 -#: pretix/control/navigation.py:501 +#: pretix/base/invoicing/email.py:43 pretix/base/models/auth.py:244 +#: pretix/base/models/customers.py:94 pretix/base/models/notifications.py:46 +#: pretix/base/models/orders.py:246 pretix/base/pdf.py:334 +#: pretix/control/navigation.py:81 pretix/control/navigation.py:513 #: pretix/control/templates/pretixcontrol/checkin/index.html:107 #: pretix/control/templates/pretixcontrol/event/settings.html:71 #: pretix/control/templates/pretixcontrol/orders/fragment_export_schedule_form.html:108 #: pretix/control/templates/pretixcontrol/organizers/customer.html:49 #: pretix/control/templates/pretixcontrol/organizers/customers.html:59 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:161 -#: pretix/plugins/checkinlists/exporters.py:507 -#: pretix/presale/checkoutflow.py:1532 pretix/presale/forms/checkout.py:57 +#: pretix/plugins/checkinlists/exporters.py:508 +#: pretix/presale/checkoutflow.py:1542 pretix/presale/forms/checkout.py:57 #: pretix/presale/forms/customer.py:57 pretix/presale/forms/customer.py:142 #: pretix/presale/forms/customer.py:298 pretix/presale/forms/customer.py:344 #: pretix/presale/forms/customer.py:388 pretix/presale/forms/user.py:40 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:30 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:31 #: pretix/presale/templates/pretixpresale/event/order.html:300 msgid "Email" msgstr "" @@ -721,24 +749,368 @@ msgid "" "{fields}." msgstr "" -#: pretix/base/customersso/oidc.py:219 pretix/base/customersso/oidc.py:226 -#: pretix/base/customersso/oidc.py:245 pretix/base/customersso/oidc.py:262 -#: pretix/base/customersso/oidc.py:269 pretix/presale/views/customer.py:743 +#: pretix/base/customersso/oidc.py:223 pretix/base/customersso/oidc.py:231 +#: pretix/base/customersso/oidc.py:254 pretix/base/customersso/oidc.py:271 +#: pretix/base/customersso/oidc.py:278 pretix/presale/views/customer.py:743 #: pretix/presale/views/customer.py:753 pretix/presale/views/customer.py:792 #: pretix/presale/views/customer.py:866 #, python-brace-format msgid "Login was not successful. Error message: \"{error}\"." msgstr "" -#: pretix/base/customersso/oidc.py:252 +#: pretix/base/customersso/oidc.py:261 msgid "" "The email address on this account is not yet verified. Please first confirm " "the email address in your customer account." msgstr "" +#: pretix/base/datasync/datasync.py:255 +#, python-brace-format +msgid "" +"Field \"{field_name}\" is not valid for {available_inputs}. Please check " +"your {provider_name} settings." +msgstr "" + +#: pretix/base/datasync/datasync.py:267 +#, python-brace-format +msgid "" +"Please update value mapping for field \"{field_name}\" - option \"{val}\" " +"not assigned" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:128 +msgid "Order position details" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:129 +msgid "Attendee details" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:130 pretix/base/exporters/answers.py:66 +#: pretix/base/models/items.py:1767 pretix/control/navigation.py:172 +#: pretix/control/templates/pretixcontrol/items/questions.html:3 +#: pretix/control/templates/pretixcontrol/items/questions.html:5 +msgid "Questions" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:131 +msgid "Product details" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:132 +#: pretix/control/templates/pretixcontrol/event/settings.html:280 +#: pretix/control/templates/pretixcontrol/order/index.html:176 +#: pretix/presale/templates/pretixpresale/event/order.html:22 +msgid "Order details" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:133 +#: pretix/base/datasync/sourcefields.py:299 +#: pretix/base/datasync/sourcefields.py:614 +#: pretix/base/datasync/sourcefields.py:638 +#: pretix/base/modelimport_orders.py:199 pretix/base/modelimport_orders.py:216 +#: pretix/base/modelimport_orders.py:232 pretix/base/modelimport_orders.py:244 +#: pretix/base/modelimport_orders.py:256 pretix/base/modelimport_orders.py:274 +#: pretix/base/modelimport_orders.py:295 pretix/base/modelimport_orders.py:321 +#: pretix/base/modelimport_orders.py:333 pretix/control/forms/filter.py:621 +#: pretix/control/forms/filter.py:625 pretix/control/forms/filter.py:629 +#: pretix/control/forms/filter.py:633 pretix/control/forms/filter.py:638 +#: pretix/control/forms/filter.py:643 +msgid "Invoice address" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:134 +msgid "Event information" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:135 +msgctxt "subevent" +msgid "Event or date information" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:175 +#: pretix/base/exporters/orderlist.py:604 +#: pretix/base/exporters/orderlist.py:609 pretix/base/forms/questions.py:679 +#: pretix/base/modelimport_orders.py:347 pretix/base/models/customers.py:300 +#: pretix/base/models/orders.py:1504 pretix/base/pdf.py:181 +#: pretix/control/forms/filter.py:648 pretix/control/forms/organizer.py:987 +#: pretix/control/templates/pretixcontrol/order/index.html:566 +#: pretix/control/templates/pretixcontrol/organizers/customer.html:120 +#: pretix/control/views/item.py:442 pretix/plugins/badges/exporters.py:495 +#: pretix/plugins/checkinlists/exporters.py:121 +#: pretix/plugins/checkinlists/exporters.py:494 +#: pretix/plugins/ticketoutputpdf/exporters.py:94 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:162 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:165 +#: pretix/presale/templates/pretixpresale/event/fragment_change_form.html:38 +#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:50 +#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:36 +msgid "Attendee name" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:187 +#: pretix/base/datasync/sourcefields.py:604 +#: pretix/base/datasync/sourcefields.py:628 +msgid "Attendee" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:207 +#: pretix/base/exporters/orderlist.py:611 pretix/base/forms/questions.py:685 +#: pretix/base/models/customers.py:307 pretix/base/models/orders.py:1512 +#: pretix/base/pdf.py:223 +#: pretix/control/templates/pretixcontrol/order/index.html:571 +#: pretix/control/views/item.py:454 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:172 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:175 +msgid "Attendee email" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:219 +msgid "Attendee or order email" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:232 pretix/base/pdf.py:186 +#: pretix/control/templates/pretixcontrol/order/index.html:595 +#: pretix/plugins/badges/exporters.py:496 +#: pretix/plugins/ticketoutputpdf/exporters.py:95 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:182 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:185 +msgid "Attendee company" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:241 +msgid "Attendee address street" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:250 +msgid "Attendee address ZIP code" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:259 +msgid "Attendee address city" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:268 +msgid "Attendee address country" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:279 pretix/base/pdf.py:344 +msgid "Invoice address company" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:288 +#: pretix/base/exporters/orderlist.py:464 +#: pretix/base/exporters/orderlist.py:469 +#: pretix/base/exporters/orderlist.py:653 +#: pretix/base/exporters/orderlist.py:657 pretix/base/pdf.py:339 +msgid "Invoice address name" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:317 +#: pretix/base/exporters/orderlist.py:659 pretix/base/pdf.py:349 +msgid "Invoice address street" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:326 +#: pretix/base/exporters/orderlist.py:659 pretix/base/pdf.py:354 +msgid "Invoice address ZIP code" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:335 +#: pretix/base/exporters/orderlist.py:659 pretix/base/pdf.py:359 +msgid "Invoice address city" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:344 +#: pretix/base/exporters/orderlist.py:660 pretix/base/pdf.py:369 +msgid "Invoice address country" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:353 +msgid "Order email" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:362 +msgid "Order email domain" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:371 +#: pretix/base/exporters/invoices.py:201 pretix/base/exporters/invoices.py:328 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:451 +#: pretix/base/exporters/orderlist.py:583 +#: pretix/base/exporters/orderlist.py:897 pretix/base/models/orders.py:210 +#: pretix/base/notifications.py:199 pretix/base/pdf.py:103 +#: pretix/control/templates/pretixcontrol/checkin/index.html:95 +#: pretix/control/templates/pretixcontrol/order/index.html:181 +#: pretix/control/templates/pretixcontrol/order/refund_choose.html:116 +#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:22 +#: pretix/control/templates/pretixcontrol/orders/index.html:47 +#: pretix/control/templates/pretixcontrol/orders/index.html:131 +#: pretix/control/templates/pretixcontrol/organizers/customer.html:204 +#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:41 +#: pretix/control/templates/pretixcontrol/search/orders.html:48 +#: pretix/plugins/badges/exporters.py:497 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:29 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:41 +#: pretix/plugins/checkinlists/exporters.py:122 +#: pretix/plugins/checkinlists/exporters.py:493 +#: pretix/plugins/checkinlists/exporters.py:757 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:895 +#: pretix/plugins/ticketoutputpdf/exporters.py:96 +msgid "Order code" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:380 +msgid "Event and order code" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:389 +#: pretix/base/exporters/orderlist.py:262 pretix/base/notifications.py:201 +#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:25 +#: pretix/control/templates/pretixcontrol/search/orders.html:60 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:897 +msgid "Order total" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:398 +msgid "Product and variation name" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:410 pretix/base/exporters/items.py:57 +#: pretix/base/exporters/orderlist.py:597 +#: pretix/base/exporters/orderlist.py:908 +#: pretix/base/exporters/waitinglist.py:112 +msgid "Product ID" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:419 +msgid "Product is admission product" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:428 +msgid "Event short form" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:437 pretix/base/exporters/events.py:57 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:450 +#: pretix/base/exporters/orderlist.py:582 +#: pretix/base/exporters/waitinglist.py:116 pretix/base/models/event.py:571 +#: pretix/base/pdf.py:233 pretix/control/forms/filter.py:1248 +#: pretix/control/forms/filter.py:1693 +#: pretix/control/templates/pretixcontrol/events/index.html:68 +#: pretix/control/templates/pretixcontrol/organizers/detail.html:64 +msgid "Event name" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:446 +#: pretix/base/exporters/invoices.py:326 +msgid "Event start date" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:455 +#: pretix/base/exporters/invoices.py:350 pretix/base/pdf.py:287 +msgid "Event end date" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:464 +#: pretix/base/exporters/waitinglist.py:123 +#: pretix/base/modelimport_vouchers.py:39 pretix/base/models/vouchers.py:193 +#: pretix/control/templates/pretixcontrol/vouchers/index.html:18 +#: pretix/control/templates/pretixcontrol/vouchers/index.html:114 +#: pretix/control/views/vouchers.py:119 pretix/control/views/waitinglist.py:314 +#: pretix/plugins/checkinlists/exporters.py:520 +#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:74 +#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:76 +#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:12 +#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:20 +msgid "Voucher code" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:473 pretix/base/pdf.py:116 +msgid "Order code and position number" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:482 +msgid "Ticket price" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:491 pretix/base/notifications.py:204 +#: pretix/control/forms/filter.py:211 pretix/control/forms/modelimport.py:85 +msgid "Order status" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:500 +msgid "Ticket status" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:509 +msgid "Order date and time" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:518 +msgid "Payment date and time" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:527 +#: pretix/base/exporters/orderlist.py:271 +#: pretix/base/exporters/orderlist.py:666 pretix/base/modelimport_orders.py:508 +#: pretix/control/templates/pretixcontrol/order/index.html:193 +#: pretix/control/templates/pretixcontrol/pdf/index.html:249 +msgid "Order locale" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:536 +msgid "Order position ID" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:545 +#: pretix/base/exporters/orderlist.py:291 +msgid "Order link" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:560 +msgid "Ticket link" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:578 +#, python-brace-format +msgid "Check-in datetime on list {}" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:590 +#, python-brace-format +msgid "Question: {name}" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:604 +#: pretix/base/datasync/sourcefields.py:614 pretix/base/settings.py:3559 +#: pretix/base/settings.py:3572 pretix/base/settings.py:3588 +#: pretix/base/settings.py:3638 pretix/base/settings.py:3651 +#: pretix/base/settings.py:3665 pretix/base/settings.py:3718 +#: pretix/base/settings.py:3739 pretix/base/settings.py:3761 +msgid "Given name" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:628 +#: pretix/base/datasync/sourcefields.py:638 pretix/base/settings.py:3560 +#: pretix/base/settings.py:3573 pretix/base/settings.py:3589 +#: pretix/base/settings.py:3605 pretix/base/settings.py:3622 +#: pretix/base/settings.py:3637 pretix/base/settings.py:3652 +#: pretix/base/settings.py:3666 pretix/base/settings.py:3719 +#: pretix/base/settings.py:3740 pretix/base/settings.py:3762 +msgid "Family name" +msgstr "" + #: pretix/base/email.py:203 pretix/base/exporters/items.py:157 -#: pretix/base/exporters/items.py:205 pretix/control/views/main.py:322 -#: pretix/plugins/badges/apps.py:50 pretix/plugins/badges/models.py:48 +#: pretix/base/exporters/items.py:205 pretix/base/models/tax.py:381 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:27 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:44 +#: pretix/control/views/main.py:323 pretix/plugins/badges/apps.py:50 +#: pretix/plugins/badges/models.py:48 #: pretix/plugins/badges/templates/pretixplugins/badges/index.html:35 #: pretix/plugins/badges/templates/pretixplugins/badges/index.html:55 #: pretix/plugins/ticketoutputpdf/models.py:328 @@ -780,12 +1152,12 @@ msgid "Question answer file uploads" msgstr "" #: pretix/base/exporters/answers.py:55 pretix/base/exporters/json.py:52 -#: pretix/base/exporters/mail.py:53 pretix/base/exporters/orderlist.py:87 -#: pretix/base/exporters/orderlist.py:823 -#: pretix/base/exporters/orderlist.py:1002 -#: pretix/base/exporters/orderlist.py:1241 -#: pretix/plugins/reports/exporters.py:478 -#: pretix/plugins/reports/exporters.py:651 +#: pretix/base/exporters/mail.py:53 pretix/base/exporters/orderlist.py:88 +#: pretix/base/exporters/orderlist.py:841 +#: pretix/base/exporters/orderlist.py:1020 +#: pretix/base/exporters/orderlist.py:1259 +#: pretix/plugins/reports/exporters.py:489 +#: pretix/plugins/reports/exporters.py:662 msgctxt "export_category" msgid "Order data" msgstr "" @@ -796,26 +1168,17 @@ msgid "" "customers while creating an order." msgstr "" -#: pretix/base/exporters/answers.py:66 pretix/base/models/items.py:1767 -#: pretix/control/navigation.py:172 -#: pretix/control/templates/pretixcontrol/items/questions.html:3 -#: pretix/control/templates/pretixcontrol/items/questions.html:5 -msgid "Questions" -msgstr "" - -#: pretix/base/exporters/answers.py:76 pretix/base/exporters/orderlist.py:583 -#: pretix/base/exporters/orderlist.py:898 -#: pretix/base/exporters/orderlist.py:1138 pretix/base/models/checkin.py:58 +#: pretix/base/exporters/answers.py:76 pretix/base/exporters/orderlist.py:592 +#: pretix/base/exporters/orderlist.py:916 +#: pretix/base/exporters/orderlist.py:1156 pretix/base/models/checkin.py:58 #: pretix/base/models/items.py:2067 pretix/base/models/orders.py:1485 -#: pretix/base/models/orders.py:2999 pretix/base/models/vouchers.py:187 -#: pretix/base/models/waitinglist.py:61 pretix/control/forms/event.py:1610 -#: pretix/control/forms/filter.py:425 pretix/control/forms/filter.py:1901 -#: pretix/control/forms/filter.py:2123 pretix/control/forms/filter.py:2238 -#: pretix/control/forms/filter.py:2320 pretix/control/forms/filter.py:2537 -#: pretix/control/forms/item.py:333 pretix/control/forms/orders.py:348 -#: pretix/control/forms/orders.py:400 pretix/control/forms/orders.py:839 -#: pretix/control/forms/vouchers.py:118 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:99 +#: pretix/base/models/orders.py:3010 pretix/base/models/vouchers.py:190 +#: pretix/base/models/waitinglist.py:61 pretix/control/forms/event.py:1619 +#: pretix/control/forms/filter.py:425 pretix/control/forms/filter.py:1897 +#: pretix/control/forms/filter.py:2119 pretix/control/forms/filter.py:2234 +#: pretix/control/forms/filter.py:2316 pretix/control/forms/filter.py:2533 +#: pretix/control/forms/orders.py:360 pretix/control/forms/orders.py:849 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:106 #: pretix/control/templates/pretixcontrol/items/quotas.html:51 #: pretix/control/templates/pretixcontrol/order/change.html:108 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:43 @@ -825,37 +1188,36 @@ msgstr "" #: pretix/control/templates/pretixcontrol/vouchers/index.html:140 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:167 #: pretix/control/views/waitinglist.py:318 -#: pretix/plugins/checkinlists/exporters.py:511 -#: pretix/plugins/checkinlists/exporters.py:700 -#: pretix/plugins/sendmail/forms.py:137 pretix/plugins/sendmail/forms.py:282 -#: pretix/plugins/sendmail/forms.py:363 +#: pretix/plugins/checkinlists/exporters.py:512 +#: pretix/plugins/checkinlists/exporters.py:701 +#: pretix/plugins/sendmail/forms.py:137 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:32 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:48 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:125 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:127 #: pretix/presale/templates/pretixpresale/event/fragment_change_form.html:20 msgctxt "subevent" msgid "Date" msgstr "" #: pretix/base/exporters/answers.py:79 pretix/base/exporters/answers.py:88 -#: pretix/control/forms/checkin.py:83 pretix/control/forms/event.py:1611 +#: pretix/control/forms/checkin.py:83 pretix/control/forms/event.py:1620 #: pretix/control/forms/filter.py:428 pretix/control/forms/filter.py:455 -#: pretix/control/forms/filter.py:1904 pretix/control/forms/filter.py:1937 -#: pretix/control/forms/filter.py:2126 pretix/control/forms/filter.py:2146 -#: pretix/control/forms/filter.py:2241 pretix/control/forms/filter.py:2257 -#: pretix/control/forms/filter.py:2323 pretix/control/forms/filter.py:2358 -#: pretix/control/forms/filter.py:2540 pretix/control/forms/filter.py:2555 -#: pretix/control/forms/orders.py:841 pretix/control/forms/orders.py:1003 +#: pretix/control/forms/filter.py:1900 pretix/control/forms/filter.py:1933 +#: pretix/control/forms/filter.py:2122 pretix/control/forms/filter.py:2142 +#: pretix/control/forms/filter.py:2237 pretix/control/forms/filter.py:2253 +#: pretix/control/forms/filter.py:2319 pretix/control/forms/filter.py:2354 +#: pretix/control/forms/filter.py:2536 pretix/control/forms/filter.py:2551 +#: pretix/control/forms/orders.py:851 pretix/control/forms/orders.py:1013 #: pretix/control/templates/pretixcontrol/event/fragment_subevent_choice_simple.html:5 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:67 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:129 #: pretix/plugins/sendmail/forms.py:99 pretix/plugins/sendmail/forms.py:173 -#: pretix/plugins/sendmail/forms.py:351 +#: pretix/plugins/sendmail/forms.py:350 msgctxt "subevent" msgid "All dates" msgstr "" -#: pretix/base/exporters/customers.py:49 pretix/control/navigation.py:606 +#: pretix/base/exporters/customers.py:49 pretix/control/navigation.py:618 #: pretix/control/templates/pretixcontrol/organizers/edit.html:132 msgid "Customer accounts" msgstr "" @@ -872,7 +1234,7 @@ msgstr "" #: pretix/base/exporters/customers.py:64 pretix/base/models/customers.py:82 #: pretix/control/templates/pretixcontrol/organizers/customer.html:29 #: pretix/control/templates/pretixcontrol/organizers/customers.html:54 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:36 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:37 #: pretix/presale/templates/pretixpresale/organizers/customer_base.html:37 msgid "Customer ID" msgstr "" @@ -889,50 +1251,50 @@ msgstr "" msgid "External identifier" msgstr "" -#: pretix/base/exporters/customers.py:68 pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:445 -#: pretix/base/exporters/orderlist.py:578 +#: pretix/base/exporters/customers.py:68 pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:454 +#: pretix/base/exporters/orderlist.py:587 #: pretix/base/exporters/waitinglist.py:110 -#: pretix/base/modelimport_orders.py:72 pretix/base/models/customers.py:95 +#: pretix/base/modelimport_orders.py:87 pretix/base/models/customers.py:95 #: pretix/base/models/customers.py:396 pretix/base/models/items.py:1659 #: pretix/base/models/orders.py:250 pretix/base/models/waitinglist.py:80 -#: pretix/base/pdf.py:320 +#: pretix/base/pdf.py:329 #: pretix/control/templates/pretixcontrol/order/index.html:257 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:163 #: pretix/control/views/waitinglist.py:314 -#: pretix/plugins/checkinlists/exporters.py:508 -#: pretix/presale/checkoutflow.py:1538 pretix/presale/forms/checkout.py:84 +#: pretix/plugins/checkinlists/exporters.py:509 +#: pretix/presale/checkoutflow.py:1548 pretix/presale/forms/checkout.py:84 #: pretix/presale/forms/waitinglist.py:80 #: pretix/presale/templates/pretixpresale/event/order.html:304 msgid "Phone number" msgstr "" #: pretix/base/exporters/customers.py:69 pretix/base/models/auth.py:246 -#: pretix/base/models/customers.py:97 pretix/base/models/orders.py:3270 -#: pretix/base/settings.py:3640 pretix/base/settings.py:3652 +#: pretix/base/models/customers.py:97 pretix/base/models/orders.py:3281 +#: pretix/base/settings.py:3692 pretix/base/settings.py:3704 #: pretix/control/templates/pretixcontrol/users/index.html:47 msgid "Full name" msgstr "" #: pretix/base/exporters/customers.py:74 pretix/base/exporters/invoices.py:206 #: pretix/base/exporters/invoices.py:214 pretix/base/exporters/invoices.py:332 -#: pretix/base/exporters/invoices.py:340 pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/waitinglist.py:108 pretix/base/forms/questions.py:1227 +#: pretix/base/exporters/invoices.py:340 pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/waitinglist.py:108 pretix/base/forms/questions.py:1247 #: pretix/base/models/devices.py:65 pretix/base/models/devices.py:127 -#: pretix/base/models/event.py:1493 pretix/base/models/event.py:1735 +#: pretix/base/models/event.py:1500 pretix/base/models/event.py:1742 #: pretix/base/models/items.py:2071 pretix/base/models/items.py:2244 -#: pretix/base/models/memberships.py:41 pretix/base/models/organizer.py:75 -#: pretix/base/models/organizer.py:535 pretix/base/models/seating.py:85 -#: pretix/base/models/waitinglist.py:69 pretix/base/settings.py:3265 -#: pretix/base/settings.py:3275 pretix/base/settings.py:3629 -#: pretix/control/forms/filter.py:625 pretix/control/forms/item.py:445 -#: pretix/control/forms/organizer.py:917 +#: pretix/base/models/memberships.py:41 pretix/base/models/organizer.py:77 +#: pretix/base/models/organizer.py:601 pretix/base/models/seating.py:85 +#: pretix/base/models/waitinglist.py:69 pretix/base/settings.py:3317 +#: pretix/base/settings.py:3327 pretix/base/settings.py:3681 +#: pretix/control/forms/filter.py:625 pretix/control/forms/item.py:446 +#: pretix/control/forms/organizer.py:918 #: pretix/control/templates/pretixcontrol/checkin/index.html:109 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:92 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:99 #: pretix/control/templates/pretixcontrol/event/tax_index.html:26 #: pretix/control/templates/pretixcontrol/oauth/app_list.html:12 #: pretix/control/templates/pretixcontrol/oauth/authorized.html:17 -#: pretix/control/templates/pretixcontrol/order/index.html:947 +#: pretix/control/templates/pretixcontrol/order/index.html:999 #: pretix/control/templates/pretixcontrol/organizers/customer.html:58 #: pretix/control/templates/pretixcontrol/organizers/customers.html:62 #: pretix/control/templates/pretixcontrol/organizers/devices.html:77 @@ -944,16 +1306,16 @@ msgstr "" #: pretix/control/templates/pretixcontrol/waitinglist/index.html:159 #: pretix/control/views/waitinglist.py:314 pretix/plugins/badges/models.py:53 #: pretix/plugins/badges/templates/pretixplugins/badges/index.html:34 -#: pretix/plugins/checkinlists/exporters.py:375 -#: pretix/plugins/checkinlists/exporters.py:760 -#: pretix/plugins/reports/exporters.py:885 +#: pretix/plugins/checkinlists/exporters.py:376 +#: pretix/plugins/checkinlists/exporters.py:761 +#: pretix/plugins/reports/exporters.py:896 #: pretix/plugins/ticketoutputpdf/models.py:333 #: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:32 #: pretix/presale/forms/customer.py:179 pretix/presale/forms/customer.py:483 #: pretix/presale/forms/waitinglist.py:68 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:87 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:139 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:34 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:86 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:142 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:35 #: pretix/presale/templates/pretixpresale/event/order.html:312 msgid "Name" msgstr "" @@ -979,7 +1341,7 @@ msgstr "" #: pretix/base/exporters/customers.py:81 pretix/base/exporters/invoices.py:205 #: pretix/base/exporters/waitinglist.py:120 pretix/base/models/auth.py:258 #: pretix/base/models/customers.py:106 pretix/base/models/exports.py:54 -#: pretix/control/forms/event.py:1616 pretix/control/forms/exports.py:49 +#: pretix/control/forms/event.py:1625 pretix/control/forms/exports.py:49 #: pretix/control/forms/exports.py:88 pretix/control/views/waitinglist.py:315 msgid "Language" msgstr "" @@ -1009,49 +1371,51 @@ msgstr "" #: pretix/base/exporters/items.py:213 pretix/base/exporters/items.py:214 #: pretix/base/exporters/items.py:215 pretix/base/exporters/items.py:218 #: pretix/base/exporters/items.py:221 pretix/base/exporters/items.py:222 -#: pretix/base/exporters/items.py:223 pretix/base/exporters/orderlist.py:393 -#: pretix/base/exporters/orderlist.py:398 -#: pretix/base/exporters/orderlist.py:742 -#: pretix/base/exporters/orderlist.py:765 -#: pretix/base/exporters/orderlist.py:797 -#: pretix/base/exporters/orderlist.py:1381 -#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:187 -#: pretix/base/modelimport.py:194 pretix/base/models/orders.py:1401 -#: pretix/control/forms/filter.py:172 pretix/control/forms/filter.py:520 -#: pretix/control/forms/filter.py:707 pretix/control/forms/item.py:614 -#: pretix/control/forms/subevents.py:119 pretix/control/views/item.py:733 -#: pretix/control/views/vouchers.py:139 pretix/control/views/vouchers.py:140 -#: pretix/plugins/checkinlists/exporters.py:600 -#: pretix/plugins/checkinlists/exporters.py:603 -#: pretix/plugins/checkinlists/exporters.py:630 -#: pretix/plugins/checkinlists/exporters.py:646 -#: pretix/plugins/checkinlists/exporters.py:715 -#: pretix/plugins/checkinlists/exporters.py:822 +#: pretix/base/exporters/items.py:223 pretix/base/exporters/orderlist.py:395 +#: pretix/base/exporters/orderlist.py:400 +#: pretix/base/exporters/orderlist.py:752 +#: pretix/base/exporters/orderlist.py:775 +#: pretix/base/exporters/orderlist.py:807 +#: pretix/base/exporters/orderlist.py:1399 +#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:194 +#: pretix/base/modelimport.py:201 pretix/base/models/orders.py:1401 +#: pretix/base/models/orders.py:3427 pretix/control/forms/filter.py:172 +#: pretix/control/forms/filter.py:520 pretix/control/forms/filter.py:707 +#: pretix/control/forms/item.py:615 pretix/control/forms/subevents.py:119 +#: pretix/control/views/item.py:733 pretix/control/views/vouchers.py:139 +#: pretix/control/views/vouchers.py:140 +#: pretix/plugins/checkinlists/exporters.py:601 +#: pretix/plugins/checkinlists/exporters.py:604 +#: pretix/plugins/checkinlists/exporters.py:631 +#: pretix/plugins/checkinlists/exporters.py:647 +#: pretix/plugins/checkinlists/exporters.py:716 #: pretix/plugins/checkinlists/exporters.py:823 #: pretix/plugins/checkinlists/exporters.py:824 +#: pretix/plugins/checkinlists/exporters.py:825 msgid "Yes" msgstr "" #: pretix/base/exporters/customers.py:100 #: pretix/base/exporters/customers.py:101 pretix/base/exporters/events.py:83 -#: pretix/base/exporters/invoices.py:305 pretix/base/exporters/orderlist.py:393 -#: pretix/base/exporters/orderlist.py:398 -#: pretix/base/exporters/orderlist.py:765 -#: pretix/base/exporters/orderlist.py:797 -#: pretix/base/exporters/orderlist.py:1381 -#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:186 -#: pretix/base/modelimport.py:196 pretix/base/models/orders.py:1403 -#: pretix/control/forms/filter.py:172 pretix/control/forms/filter.py:521 -#: pretix/control/forms/filter.py:708 pretix/control/forms/item.py:615 -#: pretix/control/forms/subevents.py:120 pretix/control/views/item.py:733 -#: pretix/control/views/vouchers.py:139 pretix/control/views/vouchers.py:140 -#: pretix/plugins/checkinlists/exporters.py:600 -#: pretix/plugins/checkinlists/exporters.py:603 -#: pretix/plugins/checkinlists/exporters.py:630 -#: pretix/plugins/checkinlists/exporters.py:715 -#: pretix/plugins/checkinlists/exporters.py:822 +#: pretix/base/exporters/invoices.py:305 pretix/base/exporters/orderlist.py:395 +#: pretix/base/exporters/orderlist.py:400 +#: pretix/base/exporters/orderlist.py:775 +#: pretix/base/exporters/orderlist.py:807 +#: pretix/base/exporters/orderlist.py:1399 +#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:193 +#: pretix/base/modelimport.py:203 pretix/base/models/orders.py:1403 +#: pretix/base/models/orders.py:3429 pretix/control/forms/filter.py:172 +#: pretix/control/forms/filter.py:521 pretix/control/forms/filter.py:708 +#: pretix/control/forms/item.py:616 pretix/control/forms/subevents.py:120 +#: pretix/control/views/item.py:733 pretix/control/views/vouchers.py:139 +#: pretix/control/views/vouchers.py:140 +#: pretix/plugins/checkinlists/exporters.py:601 +#: pretix/plugins/checkinlists/exporters.py:604 +#: pretix/plugins/checkinlists/exporters.py:631 +#: pretix/plugins/checkinlists/exporters.py:716 #: pretix/plugins/checkinlists/exporters.py:823 #: pretix/plugins/checkinlists/exporters.py:824 +#: pretix/plugins/checkinlists/exporters.py:825 msgid "No" msgstr "" @@ -1072,14 +1436,14 @@ msgid "Event ticket {event}-{code}" msgstr "" #: pretix/base/exporters/dekodi.py:234 pretix/base/exporters/invoices.py:74 -#: pretix/base/exporters/orderlist.py:128 -#: pretix/base/exporters/orderlist.py:837 -#: pretix/base/exporters/orderlist.py:1191 -#: pretix/plugins/checkinlists/exporters.py:88 -#: pretix/plugins/checkinlists/exporters.py:864 -#: pretix/plugins/reports/accountingreport.py:74 -#: pretix/plugins/reports/exporters.py:461 -#: pretix/plugins/reports/exporters.py:698 +#: pretix/base/exporters/orderlist.py:129 +#: pretix/base/exporters/orderlist.py:855 +#: pretix/base/exporters/orderlist.py:1209 +#: pretix/plugins/checkinlists/exporters.py:89 +#: pretix/plugins/checkinlists/exporters.py:865 +#: pretix/plugins/reports/accountingreport.py:75 +#: pretix/plugins/reports/exporters.py:472 +#: pretix/plugins/reports/exporters.py:709 #: pretix/plugins/ticketoutputpdf/exporters.py:85 msgid "Date range" msgstr "" @@ -1105,29 +1469,17 @@ msgid "" "account." msgstr "" -#: pretix/base/exporters/events.py:57 pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:441 -#: pretix/base/exporters/orderlist.py:573 -#: pretix/base/exporters/waitinglist.py:116 pretix/base/models/event.py:572 -#: pretix/base/pdf.py:224 pretix/control/forms/filter.py:1248 -#: pretix/control/forms/filter.py:1250 pretix/control/forms/filter.py:1695 -#: pretix/control/forms/filter.py:1697 -#: pretix/control/templates/pretixcontrol/events/index.html:68 -#: pretix/control/templates/pretixcontrol/organizers/detail.html:64 -msgid "Event name" -msgstr "" - -#: pretix/base/exporters/events.py:58 pretix/base/models/event.py:588 -#: pretix/base/models/organizer.py:91 +#: pretix/base/exporters/events.py:58 pretix/base/models/event.py:587 +#: pretix/base/models/organizer.py:93 #: pretix/control/templates/pretixcontrol/organizers/index.html:47 msgid "Short form" msgstr "" -#: pretix/base/exporters/events.py:59 pretix/base/models/event.py:590 +#: pretix/base/exporters/events.py:59 pretix/base/models/event.py:589 msgid "Shop is live" msgstr "" -#: pretix/base/exporters/events.py:60 pretix/base/models/event.py:592 +#: pretix/base/exporters/events.py:60 pretix/base/models/event.py:591 msgid "Event currency" msgstr "" @@ -1136,61 +1488,65 @@ msgstr "" msgid "Timezone" msgstr "" -#: pretix/base/exporters/events.py:62 pretix/base/models/event.py:595 -#: pretix/base/models/event.py:1495 pretix/base/settings.py:3263 -#: pretix/base/settings.py:3273 pretix/control/forms/subevents.py:487 +#: pretix/base/exporters/events.py:62 pretix/base/models/event.py:594 +#: pretix/base/models/event.py:1502 pretix/base/settings.py:3315 +#: pretix/base/settings.py:3325 pretix/control/forms/subevents.py:483 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:268 msgid "Event start time" msgstr "" -#: pretix/base/exporters/events.py:63 pretix/base/models/event.py:597 -#: pretix/base/models/event.py:1497 pretix/base/pdf.py:286 -#: pretix/control/forms/subevents.py:492 +#: pretix/base/exporters/events.py:63 pretix/base/models/event.py:596 +#: pretix/base/models/event.py:1504 pretix/base/pdf.py:295 +#: pretix/control/forms/subevents.py:488 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:270 msgid "Event end time" msgstr "" -#: pretix/base/exporters/events.py:64 pretix/base/models/event.py:599 -#: pretix/base/models/event.py:1499 pretix/control/forms/subevents.py:497 +#: pretix/base/exporters/events.py:64 pretix/base/models/event.py:598 +#: pretix/base/models/event.py:1506 pretix/control/forms/subevents.py:493 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:274 msgid "Admission time" msgstr "" -#: pretix/base/exporters/events.py:65 pretix/base/models/event.py:611 -#: pretix/base/models/event.py:1508 pretix/control/forms/subevents.py:93 +#: pretix/base/exporters/events.py:65 pretix/base/models/event.py:610 +#: pretix/base/models/event.py:1515 pretix/control/forms/subevents.py:93 msgid "Start of presale" msgstr "" -#: pretix/base/exporters/events.py:66 pretix/base/models/event.py:605 -#: pretix/base/models/event.py:1502 pretix/control/forms/subevents.py:99 +#: pretix/base/exporters/events.py:66 pretix/base/models/event.py:604 +#: pretix/base/models/event.py:1509 pretix/control/forms/subevents.py:99 msgid "End of presale" msgstr "" #: pretix/base/exporters/events.py:67 pretix/base/exporters/invoices.py:351 -#: pretix/base/models/event.py:617 pretix/base/models/event.py:1514 +#: pretix/base/models/event.py:616 pretix/base/models/event.py:1521 msgid "Location" msgstr "" -#: pretix/base/exporters/events.py:68 pretix/base/models/event.py:625 -#: pretix/base/models/event.py:1517 +#: pretix/base/exporters/events.py:68 pretix/base/models/event.py:624 +#: pretix/base/models/event.py:1524 +#: pretix/control/templates/pretixcontrol/event/fragment_geodata.html:18 +#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:54 msgid "Latitude" msgstr "" -#: pretix/base/exporters/events.py:69 pretix/base/models/event.py:633 -#: pretix/base/models/event.py:1525 +#: pretix/base/exporters/events.py:69 pretix/base/models/event.py:632 +#: pretix/base/models/event.py:1532 +#: pretix/control/templates/pretixcontrol/event/fragment_geodata.html:28 +#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:64 msgid "Longitude" msgstr "" -#: pretix/base/exporters/events.py:70 pretix/base/models/event.py:645 -#: pretix/base/models/event.py:1540 -#: pretix/control/templates/pretixcontrol/event/index.html:128 -#: pretix/control/templates/pretixcontrol/order/index.html:991 +#: pretix/base/exporters/events.py:70 pretix/base/models/event.py:644 +#: pretix/base/models/event.py:1547 +#: pretix/control/templates/pretixcontrol/event/index.html:137 +#: pretix/control/templates/pretixcontrol/order/index.html:1049 msgid "Internal comment" msgstr "" #: pretix/base/exporters/invoices.py:82 pretix/base/models/orders.py:1753 -#: pretix/base/models/orders.py:2162 pretix/control/forms/filter.py:204 -#: pretix/control/forms/filter.py:1024 pretix/control/forms/filter.py:2278 +#: pretix/base/models/orders.py:2173 pretix/control/forms/filter.py:204 +#: pretix/control/forms/filter.py:1024 pretix/control/forms/filter.py:2274 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:9 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:14 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:44 @@ -1205,7 +1561,7 @@ msgstr "" #: pretix/base/exporters/invoices.py:84 pretix/base/exporters/invoices.py:86 #: pretix/control/forms/filter.py:206 pretix/control/forms/filter.py:1026 -#: pretix/control/forms/filter.py:2280 +#: pretix/control/forms/filter.py:2276 msgid "All payment providers" msgstr "" @@ -1235,9 +1591,9 @@ msgid "" "one with a line for every position of every invoice." msgstr "" -#: pretix/base/exporters/invoices.py:191 pretix/base/shredder.py:576 +#: pretix/base/exporters/invoices.py:191 pretix/base/shredder.py:579 #: pretix/control/templates/pretixcontrol/order/index.html:268 -#: pretix/control/templates/pretixcontrol/order/index.html:341 +#: pretix/control/templates/pretixcontrol/order/index.html:381 #: pretix/control/templates/pretixcontrol/organizers/edit.html:312 #: pretix/presale/templates/pretixpresale/event/order.html:236 #: pretix/presale/templates/pretixpresale/event/order.html:257 @@ -1253,55 +1609,28 @@ msgid "Invoice number" msgstr "" #: pretix/base/exporters/invoices.py:200 pretix/base/exporters/invoices.py:327 -#: pretix/base/exporters/orderlist.py:1214 -#: pretix/base/exporters/orderlist.py:1259 +#: pretix/base/exporters/orderlist.py:1232 +#: pretix/base/exporters/orderlist.py:1277 #: pretix/base/exporters/waitinglist.py:107 pretix/base/forms/widgets.py:213 #: pretix/base/models/items.py:1655 pretix/base/models/orders.py:259 -#: pretix/base/models/orders.py:2974 pretix/base/models/orders.py:3094 +#: pretix/base/models/orders.py:2985 pretix/base/models/orders.py:3105 +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:25 #: pretix/control/templates/pretixcontrol/order/transactions.html:19 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:72 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:17 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:11 -#: pretix/plugins/checkinlists/exporters.py:752 +#: pretix/plugins/checkinlists/exporters.py:753 #: pretix/presale/templates/pretixpresale/event/fragment_giftcard_history.html:6 #: pretix/presale/templates/pretixpresale/organizers/calendar_day.html:58 msgid "Date" msgstr "" -#: pretix/base/exporters/invoices.py:201 pretix/base/exporters/invoices.py:328 -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:442 -#: pretix/base/exporters/orderlist.py:574 -#: pretix/base/exporters/orderlist.py:879 pretix/base/models/orders.py:210 -#: pretix/base/notifications.py:199 pretix/base/pdf.py:103 -#: pretix/control/templates/pretixcontrol/checkin/index.html:95 -#: pretix/control/templates/pretixcontrol/order/index.html:181 -#: pretix/control/templates/pretixcontrol/order/refund_choose.html:116 -#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:22 -#: pretix/control/templates/pretixcontrol/orders/index.html:47 -#: pretix/control/templates/pretixcontrol/orders/index.html:131 -#: pretix/control/templates/pretixcontrol/organizers/customer.html:204 -#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:41 -#: pretix/control/templates/pretixcontrol/search/orders.html:48 -#: pretix/plugins/badges/exporters.py:497 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:29 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:41 -#: pretix/plugins/checkinlists/exporters.py:121 -#: pretix/plugins/checkinlists/exporters.py:492 -#: pretix/plugins/checkinlists/exporters.py:756 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:884 -#: pretix/plugins/ticketoutputpdf/exporters.py:96 -msgid "Order code" -msgstr "" - #: pretix/base/exporters/invoices.py:202 pretix/base/exporters/invoices.py:329 #: pretix/base/forms/auth.py:160 pretix/base/modelimport_orders.py:59 #: pretix/base/models/customers.py:395 pretix/base/models/waitinglist.py:76 #: pretix/control/forms/filter.py:553 #: pretix/control/templates/pretixcontrol/users/index.html:42 #: pretix/control/views/waitinglist.py:314 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:163 msgid "Email address" msgstr "" @@ -1324,68 +1653,68 @@ msgid "Invoice sender:" msgstr "" #: pretix/base/exporters/invoices.py:207 pretix/base/exporters/invoices.py:333 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:604 pretix/base/forms/questions.py:704 -#: pretix/base/modelimport_orders.py:206 pretix/base/modelimport_orders.py:352 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:613 pretix/base/forms/questions.py:704 +#: pretix/base/modelimport_orders.py:232 pretix/base/modelimport_orders.py:386 #: pretix/base/models/customers.py:311 pretix/base/models/orders.py:1539 -#: pretix/base/models/orders.py:3272 pretix/control/forms/filter.py:629 +#: pretix/base/models/orders.py:3283 pretix/control/forms/filter.py:629 #: pretix/control/forms/filter.py:660 -#: pretix/control/templates/pretixcontrol/order/index.html:949 -#: pretix/plugins/checkinlists/exporters.py:534 -#: pretix/plugins/reports/exporters.py:840 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:89 +#: pretix/control/templates/pretixcontrol/order/index.html:1001 +#: pretix/plugins/checkinlists/exporters.py:535 +#: pretix/plugins/reports/exporters.py:851 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:88 #: pretix/presale/templates/pretixpresale/event/order.html:316 msgid "Address" msgstr "" #: pretix/base/exporters/invoices.py:208 pretix/base/exporters/invoices.py:216 #: pretix/base/exporters/invoices.py:334 pretix/base/exporters/invoices.py:342 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:605 pretix/base/forms/questions.py:715 -#: pretix/base/modelimport_orders.py:217 pretix/base/modelimport_orders.py:363 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:614 pretix/base/forms/questions.py:715 +#: pretix/base/modelimport_orders.py:244 pretix/base/modelimport_orders.py:397 #: pretix/base/models/customers.py:312 pretix/base/models/orders.py:1540 -#: pretix/base/models/orders.py:3273 pretix/base/settings.py:1124 +#: pretix/base/models/orders.py:3284 pretix/base/settings.py:1162 #: pretix/control/forms/filter.py:633 pretix/control/forms/filter.py:664 #: pretix/control/views/item.py:488 -#: pretix/plugins/checkinlists/exporters.py:535 -#: pretix/plugins/reports/exporters.py:841 +#: pretix/plugins/checkinlists/exporters.py:536 +#: pretix/plugins/reports/exporters.py:852 msgid "ZIP code" msgstr "" #: pretix/base/exporters/invoices.py:209 pretix/base/exporters/invoices.py:217 #: pretix/base/exporters/invoices.py:335 pretix/base/exporters/invoices.py:343 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:606 pretix/base/forms/questions.py:723 -#: pretix/base/modelimport_orders.py:228 pretix/base/modelimport_orders.py:374 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:615 pretix/base/forms/questions.py:723 +#: pretix/base/modelimport_orders.py:256 pretix/base/modelimport_orders.py:408 #: pretix/base/models/customers.py:313 pretix/base/models/orders.py:1541 -#: pretix/base/models/orders.py:3274 pretix/base/settings.py:1136 +#: pretix/base/models/orders.py:3285 pretix/base/settings.py:1174 #: pretix/control/forms/filter.py:638 pretix/control/forms/filter.py:669 #: pretix/control/views/item.py:498 -#: pretix/plugins/checkinlists/exporters.py:536 -#: pretix/plugins/reports/exporters.py:842 +#: pretix/plugins/checkinlists/exporters.py:537 +#: pretix/plugins/reports/exporters.py:853 msgid "City" msgstr "" #: pretix/base/exporters/invoices.py:210 pretix/base/exporters/invoices.py:218 #: pretix/base/exporters/invoices.py:336 pretix/base/exporters/invoices.py:344 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:607 pretix/base/forms/questions.py:735 -#: pretix/base/modelimport_orders.py:244 pretix/base/modelimport_orders.py:390 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:616 pretix/base/forms/questions.py:735 +#: pretix/base/modelimport_orders.py:274 pretix/base/modelimport_orders.py:425 #: pretix/base/models/customers.py:314 pretix/base/models/orders.py:1542 -#: pretix/base/models/orders.py:3275 pretix/base/models/orders.py:3276 -#: pretix/base/settings.py:1145 pretix/control/forms/filter.py:643 +#: pretix/base/models/orders.py:3286 pretix/base/models/orders.py:3287 +#: pretix/base/settings.py:1183 pretix/control/forms/filter.py:643 #: pretix/control/forms/filter.py:674 -#: pretix/control/templates/pretixcontrol/order/index.html:953 +#: pretix/control/templates/pretixcontrol/order/index.html:1005 #: pretix/control/views/item.py:508 -#: pretix/plugins/checkinlists/exporters.py:537 -#: pretix/plugins/reports/exporters.py:792 -#: pretix/plugins/reports/exporters.py:837 -#: pretix/plugins/reports/exporters.py:886 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:93 +#: pretix/plugins/checkinlists/exporters.py:538 +#: pretix/plugins/reports/exporters.py:803 +#: pretix/plugins/reports/exporters.py:848 +#: pretix/plugins/reports/exporters.py:897 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:92 #: pretix/presale/templates/pretixpresale/event/order.html:320 msgid "Country" msgstr "" @@ -1396,14 +1725,14 @@ msgstr "" #: pretix/base/exporters/invoices.py:212 pretix/base/exporters/invoices.py:220 #: pretix/base/exporters/invoices.py:338 pretix/base/exporters/invoices.py:346 -#: pretix/base/exporters/orderlist.py:270 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:653 pretix/base/modelimport_orders.py:288 -#: pretix/base/models/orders.py:3279 -#: pretix/control/templates/pretixcontrol/order/index.html:960 -#: pretix/plugins/reports/exporters.py:844 -#: pretix/plugins/reports/exporters.py:886 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:100 +#: pretix/base/exporters/orderlist.py:271 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:662 pretix/base/modelimport_orders.py:321 +#: pretix/base/models/orders.py:3290 +#: pretix/control/templates/pretixcontrol/order/index.html:1012 +#: pretix/plugins/reports/exporters.py:855 +#: pretix/plugins/reports/exporters.py:897 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:99 #: pretix/presale/templates/pretixpresale/event/order.html:327 msgid "VAT ID" msgstr "" @@ -1422,18 +1751,18 @@ msgid "Invoice recipient:" msgstr "" #: pretix/base/exporters/invoices.py:213 pretix/base/exporters/invoices.py:339 -#: pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:454 -#: pretix/base/exporters/orderlist.py:603 -#: pretix/base/exporters/orderlist.py:643 pretix/base/forms/questions.py:696 -#: pretix/base/modelimport_orders.py:176 pretix/base/modelimport_orders.py:341 +#: pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:463 +#: pretix/base/exporters/orderlist.py:612 +#: pretix/base/exporters/orderlist.py:652 pretix/base/forms/questions.py:696 +#: pretix/base/modelimport_orders.py:199 pretix/base/modelimport_orders.py:375 #: pretix/control/forms/filter.py:621 pretix/control/forms/filter.py:656 -#: pretix/control/templates/pretixcontrol/order/index.html:945 +#: pretix/control/templates/pretixcontrol/order/index.html:997 #: pretix/control/views/item.py:466 -#: pretix/plugins/checkinlists/exporters.py:518 -#: pretix/plugins/reports/exporters.py:839 -#: pretix/plugins/reports/exporters.py:885 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:84 +#: pretix/plugins/checkinlists/exporters.py:519 +#: pretix/plugins/reports/exporters.py:850 +#: pretix/plugins/reports/exporters.py:896 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:83 #: pretix/presale/templates/pretixpresale/event/order.html:308 msgid "Company" msgstr "" @@ -1443,36 +1772,36 @@ msgid "Street address" msgstr "" #: pretix/base/exporters/invoices.py:219 pretix/base/exporters/invoices.py:345 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:608 pretix/base/forms/questions.py:760 -#: pretix/base/forms/questions.py:1177 pretix/base/modelimport_orders.py:263 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:617 pretix/base/forms/questions.py:760 +#: pretix/base/forms/questions.py:1197 pretix/base/modelimport_orders.py:295 #: pretix/base/models/customers.py:315 pretix/base/models/orders.py:1543 -#: pretix/base/models/orders.py:3278 pretix/base/views/js_helpers.py:44 -#: pretix/control/templates/pretixcontrol/order/index.html:956 -#: pretix/plugins/checkinlists/exporters.py:538 -#: pretix/plugins/reports/exporters.py:843 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:96 +#: pretix/base/models/orders.py:3289 pretix/base/views/js_helpers.py:48 +#: pretix/control/templates/pretixcontrol/order/index.html:1008 +#: pretix/plugins/checkinlists/exporters.py:539 +#: pretix/plugins/reports/exporters.py:854 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:95 #: pretix/presale/templates/pretixpresale/event/order.html:323 msgctxt "address" msgid "State" msgstr "" #: pretix/base/exporters/invoices.py:221 pretix/base/exporters/invoices.py:347 -#: pretix/base/models/orders.py:3288 pretix/base/models/orders.py:3323 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:104 +#: pretix/base/models/orders.py:3299 pretix/base/models/orders.py:3355 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:103 msgid "Beneficiary" msgstr "" #: pretix/base/exporters/invoices.py:222 pretix/base/exporters/invoices.py:348 -#: pretix/base/modelimport_orders.py:299 pretix/base/models/orders.py:3283 -#: pretix/control/templates/pretixcontrol/order/index.html:980 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:112 +#: pretix/base/modelimport_orders.py:333 pretix/base/models/orders.py:3294 +#: pretix/control/templates/pretixcontrol/order/index.html:1033 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:111 msgid "Internal reference" msgstr "" #: pretix/base/exporters/invoices.py:223 pretix/base/models/tax.py:162 -#: pretix/control/forms/event.py:1506 +#: pretix/control/forms/event.py:1515 msgid "Reverse charge" msgstr "" @@ -1497,11 +1826,10 @@ msgid "Payment matching IDs" msgstr "" #: pretix/base/exporters/invoices.py:229 pretix/base/exporters/invoices.py:349 -#: pretix/base/exporters/orderlist.py:289 -#: pretix/base/exporters/orderlist.py:466 -#: pretix/base/exporters/orderlist.py:661 +#: pretix/base/exporters/orderlist.py:290 +#: pretix/base/exporters/orderlist.py:475 +#: pretix/base/exporters/orderlist.py:670 pretix/base/plugins.py:137 #: pretix/control/templates/pretixcontrol/event/payment.html:11 -#: pretix/control/views/event.py:382 msgid "Payment providers" msgstr "" @@ -1510,6 +1838,7 @@ msgid "Cancellation" msgstr "" #: pretix/base/exporters/invoices.py:285 pretix/base/exporters/invoices.py:388 +#: pretix/control/templates/pretixcontrol/event/mail.html:120 #: pretix/control/templates/pretixcontrol/order/index.html:272 #: pretix/control/templates/pretixcontrol/order/mail_history.html:70 #: pretix/presale/templates/pretixpresale/event/order.html:244 @@ -1520,13 +1849,13 @@ msgstr "" msgid "Line number" msgstr "" -#: pretix/base/exporters/invoices.py:320 pretix/base/exporters/orderlist.py:449 +#: pretix/base/exporters/invoices.py:320 pretix/base/exporters/orderlist.py:458 #: pretix/base/models/items.py:492 pretix/base/models/items.py:1155 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:32 msgid "Description" msgstr "" -#: pretix/base/exporters/invoices.py:321 pretix/control/forms/orders.py:343 +#: pretix/base/exporters/invoices.py:321 pretix/control/forms/orders.py:355 msgid "Gross price" msgstr "" @@ -1534,22 +1863,22 @@ msgstr "" msgid "Net price" msgstr "" -#: pretix/base/exporters/invoices.py:323 pretix/base/exporters/orderlist.py:453 -#: pretix/base/exporters/orderlist.py:594 -#: pretix/base/exporters/orderlist.py:904 pretix/base/models/orders.py:2326 -#: pretix/base/models/orders.py:2498 pretix/base/models/orders.py:3020 +#: pretix/base/exporters/invoices.py:323 pretix/base/exporters/orderlist.py:462 +#: pretix/base/exporters/orderlist.py:603 +#: pretix/base/exporters/orderlist.py:922 pretix/base/models/orders.py:2337 +#: pretix/base/models/orders.py:2509 pretix/base/models/orders.py:3031 msgid "Tax value" msgstr "" -#: pretix/base/exporters/invoices.py:324 pretix/base/exporters/orderlist.py:451 -#: pretix/base/exporters/orderlist.py:592 -#: pretix/base/exporters/orderlist.py:901 pretix/base/models/orders.py:2313 -#: pretix/base/models/orders.py:2485 pretix/base/models/orders.py:3007 -#: pretix/base/models/orders.py:3107 pretix/base/models/tax.py:348 +#: pretix/base/exporters/invoices.py:324 pretix/base/exporters/orderlist.py:460 +#: pretix/base/exporters/orderlist.py:601 +#: pretix/base/exporters/orderlist.py:919 pretix/base/models/orders.py:2324 +#: pretix/base/models/orders.py:2496 pretix/base/models/orders.py:3018 +#: pretix/base/models/orders.py:3118 pretix/base/models/tax.py:348 #: pretix/control/templates/pretixcontrol/order/transactions.html:21 -#: pretix/plugins/reports/accountingreport.py:315 -#: pretix/plugins/reports/exporters.py:793 -#: pretix/plugins/reports/exporters.py:838 +#: pretix/plugins/reports/accountingreport.py:316 +#: pretix/plugins/reports/exporters.py:804 +#: pretix/plugins/reports/exporters.py:849 msgid "Tax rate" msgstr "" @@ -1557,19 +1886,11 @@ msgstr "" msgid "Tax name" msgstr "" -#: pretix/base/exporters/invoices.py:326 -msgid "Event start date" -msgstr "" - -#: pretix/base/exporters/invoices.py:350 pretix/base/pdf.py:278 -msgid "Event end date" -msgstr "" - #: pretix/base/exporters/items.py:49 msgid "Product data" msgstr "" -#: pretix/base/exporters/items.py:50 pretix/base/exporters/orderlist.py:1128 +#: pretix/base/exporters/items.py:50 pretix/base/exporters/orderlist.py:1146 msgctxt "export_category" msgid "Product data" msgstr "" @@ -1578,14 +1899,8 @@ msgstr "" msgid "Download a spreadsheet with details about all products and variations." msgstr "" -#: pretix/base/exporters/items.py:57 pretix/base/exporters/orderlist.py:588 -#: pretix/base/exporters/orderlist.py:890 -#: pretix/base/exporters/waitinglist.py:112 -msgid "Product ID" -msgstr "" - -#: pretix/base/exporters/items.py:58 pretix/base/exporters/orderlist.py:590 -#: pretix/base/exporters/orderlist.py:892 +#: pretix/base/exporters/items.py:58 pretix/base/exporters/orderlist.py:599 +#: pretix/base/exporters/orderlist.py:910 #: pretix/base/exporters/waitinglist.py:114 msgid "Variation ID" msgstr "" @@ -1608,29 +1923,31 @@ msgstr "" msgid "Item name" msgstr "" -#: pretix/base/exporters/items.py:68 pretix/base/exporters/orderlist.py:589 -#: pretix/base/exporters/orderlist.py:893 +#: pretix/base/exporters/items.py:68 pretix/base/exporters/orderlist.py:598 +#: pretix/base/exporters/orderlist.py:911 #: pretix/base/exporters/waitinglist.py:113 pretix/base/models/items.py:1148 -#: pretix/base/models/orders.py:1495 pretix/base/models/orders.py:2992 -#: pretix/plugins/checkinlists/exporters.py:695 +#: pretix/base/models/orders.py:1495 pretix/base/models/orders.py:3003 +#: pretix/plugins/checkinlists/exporters.py:696 msgid "Variation" msgstr "" #: pretix/base/exporters/items.py:71 pretix/base/exporters/reusablemedia.py:48 #: pretix/base/models/customers.py:57 pretix/base/models/customers.py:403 -#: pretix/base/models/discount.py:60 pretix/base/models/event.py:1484 +#: pretix/base/models/discount.py:60 pretix/base/models/event.py:1491 #: pretix/base/models/items.py:489 pretix/base/models/items.py:1152 #: pretix/base/models/media.py:77 pretix/base/settings.py:204 #: pretix/base/settings.py:239 pretix/base/settings.py:270 -#: pretix/control/forms/filter.py:1201 pretix/control/forms/filter.py:2010 +#: pretix/control/forms/filter.py:1201 pretix/control/forms/filter.py:2006 #: pretix/control/templates/pretixcontrol/event/plugins.html:25 #: pretix/control/templates/pretixcontrol/event/plugins.html:75 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:25 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:75 #: pretix/control/templates/pretixcontrol/users/index.html:51 msgid "Active" msgstr "" #: pretix/base/exporters/items.py:72 pretix/base/models/discount.py:77 -#: pretix/control/forms/event.py:986 pretix/control/navigation.py:508 +#: pretix/control/forms/event.py:976 pretix/control/navigation.py:520 #: pretix/control/templates/pretixcontrol/organizers/channels.html:6 #: pretix/plugins/autocheckin/models.py:64 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:30 @@ -1666,9 +1983,9 @@ msgstr "" msgid "Generate tickets" msgstr "" -#: pretix/base/exporters/items.py:79 pretix/base/exporters/orderlist.py:1135 +#: pretix/base/exporters/items.py:79 pretix/base/exporters/orderlist.py:1153 #: pretix/base/exporters/waitinglist.py:41 pretix/base/shredder.py:367 -#: pretix/control/forms/event.py:1686 pretix/control/navigation.py:237 +#: pretix/control/forms/event.py:1695 pretix/control/navigation.py:237 #: pretix/control/templates/pretixcontrol/event/settings.html:363 #: pretix/control/templates/pretixcontrol/orders/cancel.html:62 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:6 @@ -1676,9 +1993,9 @@ msgstr "" #: pretix/plugins/sendmail/views.py:448 #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:31 #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:44 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:91 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:98 -#: pretix/presale/templates/pretixpresale/event/index.html:201 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:93 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:100 +#: pretix/presale/templates/pretixpresale/event/index.html:200 #: pretix/presale/templates/pretixpresale/event/waitinglist.html:3 #: pretix/presale/templates/pretixpresale/event/waitinglist_remove.html:3 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:97 @@ -1692,8 +2009,8 @@ msgstr "" #: pretix/base/exporters/items.py:80 pretix/base/models/discount.py:82 #: pretix/base/models/items.py:224 pretix/base/models/items.py:280 #: pretix/base/models/items.py:562 pretix/base/models/items.py:1205 -#: pretix/base/payment.py:392 pretix/control/forms/subevents.py:327 -#: pretix/control/forms/subevents.py:349 +#: pretix/base/payment.py:392 pretix/control/forms/subevents.py:323 +#: pretix/control/forms/subevents.py:345 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:506 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:172 #: pretix/control/templates/pretixcontrol/subevents/detail.html:149 @@ -1703,7 +2020,7 @@ msgstr "" #: pretix/base/exporters/items.py:81 pretix/base/models/discount.py:87 #: pretix/base/models/items.py:229 pretix/base/models/items.py:285 #: pretix/base/models/items.py:572 pretix/base/models/items.py:1215 -#: pretix/base/payment.py:398 pretix/control/forms/subevents.py:332 +#: pretix/base/payment.py:398 pretix/control/forms/subevents.py:328 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:511 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:177 #: pretix/control/templates/pretixcontrol/subevents/detail.html:154 @@ -1740,17 +2057,17 @@ msgstr "" msgid "Maximum amount per order" msgstr "" -#: pretix/base/exporters/items.py:89 pretix/base/exporters/orderlist.py:282 -#: pretix/base/modelimport_orders.py:610 pretix/base/models/items.py:656 +#: pretix/base/exporters/items.py:89 pretix/base/exporters/orderlist.py:283 +#: pretix/base/modelimport_orders.py:652 pretix/base/models/items.py:656 #: pretix/base/models/items.py:1242 pretix/base/models/orders.py:282 -#: pretix/plugins/checkinlists/exporters.py:522 +#: pretix/plugins/checkinlists/exporters.py:523 msgid "Requires special attention" msgstr "" -#: pretix/base/exporters/items.py:90 pretix/base/exporters/orderlist.py:283 -#: pretix/base/modelimport_orders.py:618 pretix/base/models/items.py:663 +#: pretix/base/exporters/items.py:90 pretix/base/exporters/orderlist.py:284 +#: pretix/base/modelimport_orders.py:661 pretix/base/models/items.py:663 #: pretix/base/models/items.py:1249 pretix/base/models/orders.py:289 -#: pretix/plugins/checkinlists/exporters.py:524 +#: pretix/plugins/checkinlists/exporters.py:525 msgid "Check-in text" msgstr "" @@ -1775,7 +2092,7 @@ msgstr "" msgid "Hide without a valid membership" msgstr "" -#: pretix/base/exporters/json.py:51 pretix/base/exporters/orderlist.py:86 +#: pretix/base/exporters/json.py:51 pretix/base/exporters/orderlist.py:87 msgid "Order data" msgstr "" @@ -1795,107 +2112,100 @@ msgid "" "or from ticket holders." msgstr "" -#: pretix/base/exporters/mail.py:76 pretix/plugins/reports/exporters.py:487 -#: pretix/plugins/reports/exporters.py:669 +#: pretix/base/exporters/mail.py:76 pretix/plugins/reports/exporters.py:498 +#: pretix/plugins/reports/exporters.py:680 msgid "Filter by status" msgstr "" -#: pretix/base/exporters/orderlist.py:88 +#: pretix/base/exporters/orderlist.py:89 msgid "" "Download a spreadsheet of all orders. The spreadsheet will include three " "sheets, one with a line for every order, one with a line for every order " "position, and one with a line for every additional fee charged in an order." msgstr "" -#: pretix/base/exporters/orderlist.py:100 pretix/base/models/orders.py:332 +#: pretix/base/exporters/orderlist.py:101 pretix/base/models/orders.py:332 #: pretix/control/navigation.py:255 pretix/control/navigation.py:362 #: pretix/control/templates/pretixcontrol/orders/index.html:8 #: pretix/control/templates/pretixcontrol/orders/index.html:10 #: pretix/control/templates/pretixcontrol/organizers/customer.html:198 -#: pretix/plugins/reports/accountingreport.py:670 -#: pretix/plugins/reports/accountingreport.py:862 -#: pretix/plugins/reports/exporters.py:657 pretix/plugins/statistics/apps.py:39 +#: pretix/plugins/reports/accountingreport.py:671 +#: pretix/plugins/reports/accountingreport.py:863 +#: pretix/plugins/reports/exporters.py:668 pretix/plugins/statistics/apps.py:39 #: pretix/presale/templates/pretixpresale/organizers/customer_orders.html:13 #: pretix/presale/views/customer.py:360 msgid "Orders" msgstr "" -#: pretix/base/exporters/orderlist.py:101 pretix/base/models/orders.py:2547 +#: pretix/base/exporters/orderlist.py:102 pretix/base/models/orders.py:2558 #: pretix/base/notifications.py:205 msgid "Order positions" msgstr "" -#: pretix/base/exporters/orderlist.py:102 +#: pretix/base/exporters/orderlist.py:103 msgid "Order fees" msgstr "" -#: pretix/base/exporters/orderlist.py:110 +#: pretix/base/exporters/orderlist.py:111 msgid "Only paid orders" msgstr "" -#: pretix/base/exporters/orderlist.py:116 +#: pretix/base/exporters/orderlist.py:117 msgid "Include payment amounts" msgstr "" -#: pretix/base/exporters/orderlist.py:122 +#: pretix/base/exporters/orderlist.py:123 msgid "Show multiple choice answers grouped in one column" msgstr "" -#: pretix/base/exporters/orderlist.py:131 -#: pretix/plugins/reports/exporters.py:701 +#: pretix/base/exporters/orderlist.py:132 +#: pretix/plugins/reports/exporters.py:712 msgid "Only include orders created within this date range." msgstr "" -#: pretix/base/exporters/orderlist.py:135 pretix/base/notifications.py:194 -#: pretix/base/pdf.py:234 pretix/plugins/badges/exporters.py:499 -#: pretix/plugins/reports/exporters.py:305 -#: pretix/plugins/reports/exporters.py:454 +#: pretix/base/exporters/orderlist.py:136 pretix/base/notifications.py:194 +#: pretix/base/pdf.py:243 pretix/plugins/badges/exporters.py:499 +#: pretix/plugins/reports/exporters.py:316 +#: pretix/plugins/reports/exporters.py:465 #: pretix/plugins/ticketoutputpdf/exporters.py:97 msgid "Event date" msgstr "" -#: pretix/base/exporters/orderlist.py:138 +#: pretix/base/exporters/orderlist.py:139 msgid "" "Only include orders including at least one ticket for a date in this range. " "Will also include other dates in case of mixed orders!" msgstr "" -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:440 -#: pretix/base/exporters/orderlist.py:572 -#: pretix/base/exporters/orderlist.py:876 -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1259 -#: pretix/base/exporters/waitinglist.py:115 pretix/control/forms/event.py:1662 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:449 +#: pretix/base/exporters/orderlist.py:581 +#: pretix/base/exporters/orderlist.py:894 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1277 +#: pretix/base/exporters/waitinglist.py:115 pretix/control/forms/event.py:1671 #: pretix/control/forms/organizer.py:116 msgid "Event slug" msgstr "" -#: pretix/base/exporters/orderlist.py:261 pretix/base/notifications.py:201 -#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:25 -#: pretix/control/templates/pretixcontrol/search/orders.html:60 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:886 -msgid "Order total" -msgstr "" - -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:443 -#: pretix/base/exporters/orderlist.py:576 -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1312 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:452 +#: pretix/base/exporters/orderlist.py:585 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1330 #: pretix/base/exporters/waitinglist.py:122 #: pretix/base/exporters/waitinglist.py:172 pretix/base/models/orders.py:216 #: pretix/control/forms/filter.py:1019 pretix/control/forms/filter.py:1198 -#: pretix/control/forms/filter.py:1426 pretix/control/forms/filter.py:1495 -#: pretix/control/forms/filter.py:1567 pretix/control/forms/filter.py:1667 -#: pretix/control/forms/filter.py:2007 pretix/control/forms/filter.py:2087 -#: pretix/control/forms/filter.py:2368 +#: pretix/control/forms/filter.py:1424 pretix/control/forms/filter.py:1493 +#: pretix/control/forms/filter.py:1565 pretix/control/forms/filter.py:1665 +#: pretix/control/forms/filter.py:2003 pretix/control/forms/filter.py:2083 +#: pretix/control/forms/filter.py:2364 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:52 #: pretix/control/templates/pretixcontrol/checkin/index.html:112 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:83 #: pretix/control/templates/pretixcontrol/events/index.html:90 -#: pretix/control/templates/pretixcontrol/order/index.html:743 -#: pretix/control/templates/pretixcontrol/order/index.html:839 +#: pretix/control/templates/pretixcontrol/order/index.html:795 +#: pretix/control/templates/pretixcontrol/order/index.html:891 #: pretix/control/templates/pretixcontrol/orders/bulk_action.html:26 #: pretix/control/templates/pretixcontrol/orders/index.html:151 #: pretix/control/templates/pretixcontrol/orders/refunds.html:65 @@ -1912,18 +2222,18 @@ msgstr "" #: pretix/control/templates/pretixcontrol/waitinglist/index.html:170 #: pretix/control/views/waitinglist.py:314 #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:9 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:886 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:897 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:34 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:79 msgid "Status" msgstr "" -#: pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:446 -#: pretix/base/exporters/orderlist.py:579 -#: pretix/base/exporters/orderlist.py:880 pretix/base/notifications.py:203 -#: pretix/control/forms/filter.py:2329 +#: pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:455 +#: pretix/base/exporters/orderlist.py:588 +#: pretix/base/exporters/orderlist.py:898 pretix/base/notifications.py:203 +#: pretix/control/forms/filter.py:2325 #: pretix/control/templates/pretixcontrol/order/index.html:183 #: pretix/control/templates/pretixcontrol/orders/bulk_action.html:24 #: pretix/control/templates/pretixcontrol/orders/index.html:140 @@ -1931,186 +2241,172 @@ msgstr "" #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:45 #: pretix/control/templates/pretixcontrol/search/orders.html:57 #: pretix/plugins/badges/exporters.py:498 -#: pretix/plugins/checkinlists/exporters.py:122 -#: pretix/plugins/checkinlists/exporters.py:520 -#: pretix/plugins/reports/exporters.py:498 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:680 +#: pretix/plugins/checkinlists/exporters.py:123 +#: pretix/plugins/checkinlists/exporters.py:521 +#: pretix/plugins/reports/exporters.py:509 +#: pretix/plugins/reports/exporters.py:572 #: pretix/plugins/reports/exporters.py:691 -#: pretix/plugins/reports/exporters.py:884 +#: pretix/plugins/reports/exporters.py:702 +#: pretix/plugins/reports/exporters.py:895 msgid "Order date" msgstr "" -#: pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:447 -#: pretix/base/exporters/orderlist.py:580 -#: pretix/base/exporters/orderlist.py:881 -#: pretix/plugins/checkinlists/exporters.py:521 +#: pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:456 +#: pretix/base/exporters/orderlist.py:589 +#: pretix/base/exporters/orderlist.py:899 +#: pretix/plugins/checkinlists/exporters.py:522 msgid "Order time" msgstr "" -#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:271 msgid "Custom address field" msgstr "" -#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:271 msgid "Date of last payment" msgstr "" -#: pretix/base/exporters/orderlist.py:270 pretix/base/services/stats.py:237 +#: pretix/base/exporters/orderlist.py:271 pretix/base/services/stats.py:237 msgid "Fees" msgstr "" -#: pretix/base/exporters/orderlist.py:270 -#: pretix/base/exporters/orderlist.py:657 pretix/base/modelimport_orders.py:472 -#: pretix/control/templates/pretixcontrol/order/index.html:193 -#: pretix/control/templates/pretixcontrol/pdf/index.html:189 -msgid "Order locale" -msgstr "" - -#: pretix/base/exporters/orderlist.py:275 -#, python-brace-format -msgid "Gross at {rate} % tax" -msgstr "" - #: pretix/base/exporters/orderlist.py:276 #, python-brace-format -msgid "Net at {rate} % tax" +msgid "Gross at {rate} % tax" msgstr "" #: pretix/base/exporters/orderlist.py:277 #, python-brace-format +msgid "Net at {rate} % tax" +msgstr "" + +#: pretix/base/exporters/orderlist.py:278 +#, python-brace-format msgid "Tax value at {rate} % tax" msgstr "" -#: pretix/base/exporters/orderlist.py:280 +#: pretix/base/exporters/orderlist.py:281 msgid "Invoice numbers" msgstr "" -#: pretix/base/exporters/orderlist.py:281 -#: pretix/base/exporters/orderlist.py:656 pretix/base/modelimport_orders.py:540 +#: pretix/base/exporters/orderlist.py:282 +#: pretix/base/exporters/orderlist.py:665 pretix/base/modelimport_orders.py:578 #: pretix/control/forms/filter.py:585 #: pretix/control/templates/pretixcontrol/order/index.html:190 msgid "Sales channel" msgstr "" -#: pretix/base/exporters/orderlist.py:285 -#: pretix/base/exporters/orderlist.py:621 pretix/base/models/orders.py:277 +#: pretix/base/exporters/orderlist.py:286 +#: pretix/base/exporters/orderlist.py:630 pretix/base/models/orders.py:277 #: pretix/control/forms/filter.py:240 msgid "Follow-up date" msgstr "" -#: pretix/base/exporters/orderlist.py:286 +#: pretix/base/exporters/orderlist.py:287 #: pretix/control/templates/pretixcontrol/orders/index.html:150 #: pretix/control/templates/pretixcontrol/organizers/customer.html:208 msgid "Positions" msgstr "" -#: pretix/base/exporters/orderlist.py:287 -#: pretix/base/exporters/orderlist.py:658 pretix/base/models/orders.py:321 +#: pretix/base/exporters/orderlist.py:288 +#: pretix/base/exporters/orderlist.py:667 pretix/base/models/orders.py:321 #: pretix/control/forms/filter.py:567 msgid "Email address verified" msgstr "" -#: pretix/base/exporters/orderlist.py:288 -#: pretix/base/exporters/orderlist.py:465 -#: pretix/base/exporters/orderlist.py:659 +#: pretix/base/exporters/orderlist.py:289 +#: pretix/base/exporters/orderlist.py:474 +#: pretix/base/exporters/orderlist.py:668 msgid "External customer ID" msgstr "" -#: pretix/base/exporters/orderlist.py:293 +#: pretix/base/exporters/orderlist.py:295 #, python-brace-format msgid "Paid by {method}" msgstr "" -#: pretix/base/exporters/orderlist.py:448 -#: pretix/base/exporters/orderlist.py:894 +#: pretix/base/exporters/orderlist.py:457 +#: pretix/base/exporters/orderlist.py:912 msgid "Fee type" msgstr "" -#: pretix/base/exporters/orderlist.py:450 -#: pretix/base/exporters/orderlist.py:591 -#: pretix/base/exporters/orderlist.py:900 pretix/base/modelimport_orders.py:431 -#: pretix/base/models/orders.py:1500 pretix/base/models/orders.py:3003 -#: pretix/base/pdf.py:158 pretix/control/forms/orders.py:627 +#: pretix/base/exporters/orderlist.py:459 +#: pretix/base/exporters/orderlist.py:600 +#: pretix/base/exporters/orderlist.py:918 pretix/base/modelimport_orders.py:467 +#: pretix/base/models/orders.py:1500 pretix/base/models/orders.py:3014 +#: pretix/base/pdf.py:158 pretix/control/forms/orders.py:638 #: pretix/control/templates/pretixcontrol/item/index.html:146 #: pretix/control/templates/pretixcontrol/order/change.html:194 #: pretix/control/templates/pretixcontrol/order/change.html:418 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:496 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:162 #: pretix/control/templates/pretixcontrol/subevents/detail.html:139 -#: pretix/plugins/checkinlists/exporters.py:376 -#: pretix/plugins/checkinlists/exporters.py:499 -#: pretix/plugins/reports/accountingreport.py:314 +#: pretix/plugins/checkinlists/exporters.py:377 +#: pretix/plugins/checkinlists/exporters.py:500 +#: pretix/plugins/reports/accountingreport.py:315 msgid "Price" msgstr "" -#: pretix/base/exporters/orderlist.py:452 -#: pretix/base/exporters/orderlist.py:593 -#: pretix/base/exporters/orderlist.py:903 +#: pretix/base/exporters/orderlist.py:461 +#: pretix/base/exporters/orderlist.py:602 +#: pretix/base/exporters/orderlist.py:921 #: pretix/control/templates/pretixcontrol/event/tax_edit.html:9 #: pretix/control/templates/pretixcontrol/event/tax_edit.html:16 #: pretix/control/templates/pretixcontrol/order/change.html:165 msgid "Tax rule" msgstr "" -#: pretix/base/exporters/orderlist.py:455 -#: pretix/base/exporters/orderlist.py:460 -#: pretix/base/exporters/orderlist.py:644 -#: pretix/base/exporters/orderlist.py:648 pretix/base/pdf.py:330 -msgid "Invoice address name" -msgstr "" - -#: pretix/base/exporters/orderlist.py:480 -#: pretix/base/exporters/orderlist.py:683 pretix/base/models/orders.py:205 +#: pretix/base/exporters/orderlist.py:489 +#: pretix/base/exporters/orderlist.py:693 pretix/base/models/orders.py:205 msgid "canceled" msgstr "" -#: pretix/base/exporters/orderlist.py:575 -#: pretix/base/exporters/orderlist.py:887 -#: pretix/plugins/checkinlists/exporters.py:757 +#: pretix/base/exporters/orderlist.py:584 +#: pretix/base/exporters/orderlist.py:905 +#: pretix/plugins/checkinlists/exporters.py:758 msgid "Position ID" msgstr "" -#: pretix/base/exporters/orderlist.py:584 -#: pretix/base/exporters/orderlist.py:1139 +#: pretix/base/exporters/orderlist.py:593 +#: pretix/base/exporters/orderlist.py:1157 #: pretix/base/exporters/waitinglist.py:118 pretix/base/forms/questions.py:650 #: pretix/base/forms/questions.py:659 pretix/base/models/memberships.py:145 #: pretix/control/forms/rrule.py:49 #: pretix/control/templates/pretixcontrol/events/index.html:78 -#: pretix/control/templates/pretixcontrol/order/index.html:740 -#: pretix/control/templates/pretixcontrol/order/index.html:834 +#: pretix/control/templates/pretixcontrol/order/index.html:792 +#: pretix/control/templates/pretixcontrol/order/index.html:886 #: pretix/control/templates/pretixcontrol/orders/refunds.html:55 #: pretix/control/templates/pretixcontrol/organizers/detail.html:66 #: pretix/control/templates/pretixcontrol/search/payments.html:83 #: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:19 #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:18 -#: pretix/plugins/checkinlists/exporters.py:512 -#: pretix/plugins/checkinlists/exporters.py:701 +#: pretix/plugins/checkinlists/exporters.py:513 +#: pretix/plugins/checkinlists/exporters.py:702 msgid "Start date" msgstr "" -#: pretix/base/exporters/orderlist.py:585 -#: pretix/base/exporters/orderlist.py:1140 +#: pretix/base/exporters/orderlist.py:594 +#: pretix/base/exporters/orderlist.py:1158 #: pretix/base/exporters/waitinglist.py:119 #: pretix/base/models/memberships.py:148 #: pretix/control/templates/pretixcontrol/events/index.html:82 #: pretix/control/templates/pretixcontrol/organizers/detail.html:68 #: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:21 #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:20 -#: pretix/plugins/checkinlists/exporters.py:513 -#: pretix/plugins/checkinlists/exporters.py:702 +#: pretix/plugins/checkinlists/exporters.py:514 +#: pretix/plugins/checkinlists/exporters.py:703 msgid "End date" msgstr "" -#: pretix/base/exporters/orderlist.py:587 -#: pretix/base/exporters/orderlist.py:891 +#: pretix/base/exporters/orderlist.py:596 +#: pretix/base/exporters/orderlist.py:909 #: pretix/base/exporters/waitinglist.py:111 -#: pretix/base/modelimport_orders.py:109 +#: pretix/base/modelimport_orders.py:129 #: pretix/base/modelimport_vouchers.py:174 pretix/base/models/items.py:794 -#: pretix/base/models/vouchers.py:250 pretix/base/models/waitinglist.py:91 -#: pretix/control/forms/filter.py:2129 pretix/control/forms/filter.py:2384 -#: pretix/control/forms/orders.py:323 pretix/control/forms/vouchers.py:67 +#: pretix/base/models/vouchers.py:253 pretix/base/models/waitinglist.py:91 +#: pretix/control/forms/filter.py:2125 pretix/control/forms/filter.py:2380 +#: pretix/control/forms/orders.py:335 pretix/control/forms/vouchers.py:67 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:66 #: pretix/control/templates/pretixcontrol/item/base.html:3 #: pretix/control/templates/pretixcontrol/order/change.html:139 @@ -2120,12 +2416,12 @@ msgstr "" #: pretix/control/templates/pretixcontrol/vouchers/index.html:134 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:165 #: pretix/control/views/vouchers.py:119 pretix/control/views/waitinglist.py:314 -#: pretix/plugins/checkinlists/exporters.py:376 -#: pretix/plugins/checkinlists/exporters.py:499 -#: pretix/plugins/checkinlists/exporters.py:694 -#: pretix/plugins/checkinlists/exporters.py:759 -#: pretix/plugins/reports/accountingreport.py:270 -#: pretix/plugins/reports/exporters.py:375 +#: pretix/plugins/checkinlists/exporters.py:377 +#: pretix/plugins/checkinlists/exporters.py:500 +#: pretix/plugins/checkinlists/exporters.py:695 +#: pretix/plugins/checkinlists/exporters.py:760 +#: pretix/plugins/reports/accountingreport.py:271 +#: pretix/plugins/reports/exporters.py:386 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:100 #: pretix/presale/forms/order.py:36 pretix/presale/forms/waitinglist.py:54 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:12 @@ -2133,36 +2429,7 @@ msgstr "" msgid "Product" msgstr "" -#: pretix/base/exporters/orderlist.py:595 -#: pretix/base/exporters/orderlist.py:600 pretix/base/forms/questions.py:679 -#: pretix/base/modelimport_orders.py:313 pretix/base/models/customers.py:300 -#: pretix/base/models/orders.py:1504 pretix/base/pdf.py:172 -#: pretix/control/forms/filter.py:648 pretix/control/forms/organizer.py:986 -#: pretix/control/templates/pretixcontrol/order/index.html:514 -#: pretix/control/templates/pretixcontrol/organizers/customer.html:120 -#: pretix/control/views/item.py:442 pretix/plugins/badges/exporters.py:495 -#: pretix/plugins/checkinlists/exporters.py:120 -#: pretix/plugins/checkinlists/exporters.py:493 -#: pretix/plugins/ticketoutputpdf/exporters.py:94 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:162 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:165 -#: pretix/presale/templates/pretixpresale/event/fragment_change_form.html:38 -#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:50 -#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:36 -msgid "Attendee name" -msgstr "" - -#: pretix/base/exporters/orderlist.py:602 pretix/base/forms/questions.py:685 -#: pretix/base/models/customers.py:307 pretix/base/models/orders.py:1512 -#: pretix/base/pdf.py:214 -#: pretix/control/templates/pretixcontrol/order/index.html:519 -#: pretix/control/views/item.py:454 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:172 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:175 -msgid "Attendee email" -msgstr "" - -#: pretix/base/exporters/orderlist.py:609 pretix/base/models/vouchers.py:312 +#: pretix/base/exporters/orderlist.py:618 pretix/base/models/vouchers.py:315 #: pretix/control/templates/pretixcontrol/vouchers/bulk.html:5 #: pretix/control/templates/pretixcontrol/vouchers/detail.html:6 #: pretix/control/templates/pretixcontrol/vouchers/detail.html:8 @@ -2170,102 +2437,86 @@ msgstr "" msgid "Voucher" msgstr "" -#: pretix/base/exporters/orderlist.py:610 +#: pretix/base/exporters/orderlist.py:619 msgid "Pseudonymization ID" msgstr "" -#: pretix/base/exporters/orderlist.py:611 pretix/control/forms/filter.py:678 +#: pretix/base/exporters/orderlist.py:620 pretix/control/forms/filter.py:678 #: pretix/control/templates/pretixcontrol/order/change.html:280 msgid "Ticket secret" msgstr "" -#: pretix/base/exporters/orderlist.py:612 pretix/base/modelimport_orders.py:570 +#: pretix/base/exporters/orderlist.py:621 pretix/base/modelimport_orders.py:610 #: pretix/base/modelimport_vouchers.py:272 -#: pretix/plugins/checkinlists/exporters.py:525 +#: pretix/plugins/checkinlists/exporters.py:526 msgid "Seat ID" msgstr "" -#: pretix/base/exporters/orderlist.py:613 -#: pretix/plugins/checkinlists/exporters.py:526 +#: pretix/base/exporters/orderlist.py:622 +#: pretix/plugins/checkinlists/exporters.py:527 msgid "Seat name" msgstr "" -#: pretix/base/exporters/orderlist.py:614 -#: pretix/plugins/checkinlists/exporters.py:527 +#: pretix/base/exporters/orderlist.py:623 +#: pretix/plugins/checkinlists/exporters.py:528 msgid "Seat zone" msgstr "" -#: pretix/base/exporters/orderlist.py:615 -#: pretix/plugins/checkinlists/exporters.py:528 +#: pretix/base/exporters/orderlist.py:624 +#: pretix/plugins/checkinlists/exporters.py:529 msgid "Seat row" msgstr "" -#: pretix/base/exporters/orderlist.py:616 -#: pretix/plugins/checkinlists/exporters.py:529 +#: pretix/base/exporters/orderlist.py:625 +#: pretix/plugins/checkinlists/exporters.py:530 msgid "Seat number" msgstr "" -#: pretix/base/exporters/orderlist.py:617 +#: pretix/base/exporters/orderlist.py:626 #: pretix/control/templates/pretixcontrol/order/change.html:224 -#: pretix/plugins/checkinlists/exporters.py:428 -#: pretix/plugins/checkinlists/exporters.py:530 +#: pretix/plugins/checkinlists/exporters.py:429 +#: pretix/plugins/checkinlists/exporters.py:531 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:108 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:110 msgid "Blocked" msgstr "" -#: pretix/base/exporters/orderlist.py:618 pretix/base/modelimport_orders.py:500 -#: pretix/base/models/orders.py:2514 +#: pretix/base/exporters/orderlist.py:627 pretix/base/modelimport_orders.py:537 +#: pretix/base/models/orders.py:2525 #: pretix/control/templates/pretixcontrol/organizers/customer.html:117 -#: pretix/plugins/checkinlists/exporters.py:531 -#: pretix/plugins/checkinlists/exporters.py:704 +#: pretix/plugins/checkinlists/exporters.py:532 +#: pretix/plugins/checkinlists/exporters.py:705 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:46 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:54 msgid "Valid from" msgstr "" -#: pretix/base/exporters/orderlist.py:619 pretix/base/modelimport_orders.py:508 -#: pretix/base/modelimport_vouchers.py:111 pretix/base/models/orders.py:2519 -#: pretix/base/models/vouchers.py:221 +#: pretix/base/exporters/orderlist.py:628 pretix/base/modelimport_orders.py:545 +#: pretix/base/modelimport_vouchers.py:111 pretix/base/models/orders.py:2530 +#: pretix/base/models/vouchers.py:224 #: pretix/control/templates/pretixcontrol/organizers/customer.html:118 #: pretix/control/views/vouchers.py:119 -#: pretix/plugins/checkinlists/exporters.py:532 -#: pretix/plugins/checkinlists/exporters.py:705 +#: pretix/plugins/checkinlists/exporters.py:533 +#: pretix/plugins/checkinlists/exporters.py:706 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:48 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:60 msgid "Valid until" msgstr "" -#: pretix/base/exporters/orderlist.py:620 +#: pretix/base/exporters/orderlist.py:629 pretix/base/modelimport_orders.py:643 msgid "Order comment" msgstr "" -#: pretix/base/exporters/orderlist.py:622 +#: pretix/base/exporters/orderlist.py:631 msgid "Add-on to position ID" msgstr "" -#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:340 -msgid "Invoice address street" -msgstr "" - -#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:345 -msgid "Invoice address ZIP code" -msgstr "" - -#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:350 -msgid "Invoice address city" -msgstr "" - -#: pretix/base/exporters/orderlist.py:651 pretix/base/pdf.py:360 -msgid "Invoice address country" -msgstr "" - -#: pretix/base/exporters/orderlist.py:652 +#: pretix/base/exporters/orderlist.py:661 msgctxt "address" msgid "Invoice address state" msgstr "" -#: pretix/base/exporters/orderlist.py:660 pretix/control/navigation.py:305 +#: pretix/base/exporters/orderlist.py:669 pretix/control/navigation.py:305 #: pretix/control/templates/pretixcontrol/checkin/lists.html:6 #: pretix/control/templates/pretixcontrol/checkin/lists.html:8 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:519 @@ -2275,40 +2526,44 @@ msgstr "" msgid "Check-in lists" msgstr "" -#: pretix/base/exporters/orderlist.py:822 +#: pretix/base/exporters/orderlist.py:671 +msgid "Position order link" +msgstr "" + +#: pretix/base/exporters/orderlist.py:840 msgid "Order transaction data" msgstr "" -#: pretix/base/exporters/orderlist.py:824 +#: pretix/base/exporters/orderlist.py:842 msgid "" "Download a spreadsheet of all substantial changes to orders, i.e. all " "changes to products, prices or tax rates. The information is only accurate " "for changes made with pretix versions released after October 2021." msgstr "" -#: pretix/base/exporters/orderlist.py:840 +#: pretix/base/exporters/orderlist.py:858 msgid "Only include transactions created within this date range." msgstr "" -#: pretix/base/exporters/orderlist.py:875 pretix/base/models/event.py:672 +#: pretix/base/exporters/orderlist.py:893 pretix/base/models/event.py:671 #: pretix/base/models/items.py:468 pretix/base/models/items.py:2060 -#: pretix/base/models/orders.py:233 pretix/base/models/orders.py:3086 -#: pretix/base/models/vouchers.py:181 pretix/base/models/waitinglist.py:55 +#: pretix/base/models/orders.py:233 pretix/base/models/orders.py:3097 +#: pretix/base/models/vouchers.py:184 pretix/base/models/waitinglist.py:55 #: pretix/base/notifications.py:187 pretix/control/forms/filter.py:994 #: pretix/control/templates/pretixcontrol/organizers/customer.html:205 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:42 #: pretix/control/templates/pretixcontrol/search/orders.html:51 #: pretix/multidomain/models.py:65 -#: pretix/plugins/reports/accountingreport.py:111 -#: pretix/plugins/reports/accountingreport.py:270 +#: pretix/plugins/reports/accountingreport.py:112 +#: pretix/plugins/reports/accountingreport.py:271 #: pretix/presale/templates/pretixpresale/event/waitinglist.html:11 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:95 msgid "Event" msgstr "" -#: pretix/base/exporters/orderlist.py:877 -#: pretix/base/exporters/orderlist.py:1216 -#: pretix/base/exporters/orderlist.py:1360 +#: pretix/base/exporters/orderlist.py:895 +#: pretix/base/exporters/orderlist.py:1234 +#: pretix/base/exporters/orderlist.py:1378 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:50 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:34 #: pretix/plugins/banktransfer/refund_export.py:46 @@ -2320,260 +2575,260 @@ msgstr "" msgid "Currency" msgstr "" -#: pretix/base/exporters/orderlist.py:883 +#: pretix/base/exporters/orderlist.py:901 msgid "Transaction date" msgstr "" -#: pretix/base/exporters/orderlist.py:884 +#: pretix/base/exporters/orderlist.py:902 msgid "Transaction time" msgstr "" -#: pretix/base/exporters/orderlist.py:885 +#: pretix/base/exporters/orderlist.py:903 msgid "Old data" msgstr "" -#: pretix/base/exporters/orderlist.py:888 pretix/base/models/items.py:1555 +#: pretix/base/exporters/orderlist.py:906 pretix/base/models/items.py:1555 #: pretix/control/templates/pretixcontrol/order/transactions.html:23 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:207 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:353 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:16 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:223 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:375 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:225 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:377 #: pretix/presale/templates/pretixpresale/event/voucher.html:234 #: pretix/presale/templates/pretixpresale/event/voucher.html:389 msgid "Quantity" msgstr "" -#: pretix/base/exporters/orderlist.py:895 +#: pretix/base/exporters/orderlist.py:913 msgid "Internal fee type" msgstr "" -#: pretix/base/exporters/orderlist.py:897 +#: pretix/base/exporters/orderlist.py:915 msgctxt "subevent" msgid "Date ID" msgstr "" -#: pretix/base/exporters/orderlist.py:902 +#: pretix/base/exporters/orderlist.py:920 msgid "Tax rule ID" msgstr "" -#: pretix/base/exporters/orderlist.py:905 -#: pretix/plugins/reports/accountingreport.py:319 +#: pretix/base/exporters/orderlist.py:923 +#: pretix/plugins/reports/accountingreport.py:320 msgid "Gross total" msgstr "" -#: pretix/base/exporters/orderlist.py:906 -#: pretix/plugins/reports/accountingreport.py:318 +#: pretix/base/exporters/orderlist.py:924 +#: pretix/plugins/reports/accountingreport.py:319 msgid "Tax total" msgstr "" -#: pretix/base/exporters/orderlist.py:916 +#: pretix/base/exporters/orderlist.py:934 msgid "" "This value is supplied for informational purposes, it is not part of the " "original transaction data and might have changed since the transaction." msgstr "" -#: pretix/base/exporters/orderlist.py:939 +#: pretix/base/exporters/orderlist.py:957 msgid "Converted from legacy version" msgstr "" -#: pretix/base/exporters/orderlist.py:1001 +#: pretix/base/exporters/orderlist.py:1019 msgid "Payments and refunds" msgstr "" -#: pretix/base/exporters/orderlist.py:1003 +#: pretix/base/exporters/orderlist.py:1021 msgid "Download a spreadsheet of all payments or refunds of every order." msgstr "" -#: pretix/base/exporters/orderlist.py:1012 +#: pretix/base/exporters/orderlist.py:1030 msgid "Date range (payment date)" msgstr "" -#: pretix/base/exporters/orderlist.py:1015 +#: pretix/base/exporters/orderlist.py:1033 msgid "" "Note that using this will exclude any non-confirmed payments or non-" "completed refunds." msgstr "" -#: pretix/base/exporters/orderlist.py:1019 +#: pretix/base/exporters/orderlist.py:1037 msgid "Date range (start of transaction)" msgstr "" -#: pretix/base/exporters/orderlist.py:1025 +#: pretix/base/exporters/orderlist.py:1043 msgid "Payment states" msgstr "" -#: pretix/base/exporters/orderlist.py:1033 +#: pretix/base/exporters/orderlist.py:1051 msgid "Refund states" msgstr "" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1217 -#: pretix/base/exporters/orderlist.py:1259 pretix/base/models/orders.py:331 -#: pretix/base/models/orders.py:1740 pretix/base/models/orders.py:2143 -#: pretix/base/models/orders.py:2302 pretix/base/models/orders.py:2474 -#: pretix/base/models/orders.py:2965 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1235 +#: pretix/base/exporters/orderlist.py:1277 pretix/base/models/orders.py:331 +#: pretix/base/models/orders.py:1740 pretix/base/models/orders.py:2154 +#: pretix/base/models/orders.py:2313 pretix/base/models/orders.py:2485 +#: pretix/base/models/orders.py:2976 +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:23 #: pretix/control/templates/pretixcontrol/organizers/customer.html:119 #: pretix/control/templates/pretixcontrol/search/payments.html:78 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:15 -#: pretix/plugins/checkinlists/exporters.py:374 +#: pretix/plugins/checkinlists/exporters.py:375 #: pretix/presale/templates/pretixpresale/event/order.html:67 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:70 msgid "Order" msgstr "" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1259 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1277 #: pretix/control/templates/pretixcontrol/search/payments.html:75 #: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html:5 #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html:5 msgid "Payment ID" msgstr "" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1357 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1375 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:30 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:59 msgid "Creation date" msgstr "" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/control/templates/pretixcontrol/order/index.html:835 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/control/templates/pretixcontrol/order/index.html:887 msgid "Completion date" msgstr "" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 msgid "Status code" msgstr "" -#: pretix/base/exporters/orderlist.py:1077 -#: pretix/base/exporters/orderlist.py:1215 -#: pretix/base/exporters/orderlist.py:1259 pretix/base/models/orders.py:1736 -#: pretix/base/models/orders.py:2139 pretix/control/forms/filter.py:1051 +#: pretix/base/exporters/orderlist.py:1095 +#: pretix/base/exporters/orderlist.py:1233 +#: pretix/base/exporters/orderlist.py:1277 pretix/base/models/orders.py:1736 +#: pretix/base/models/orders.py:2150 pretix/control/forms/filter.py:1051 #: pretix/control/forms/filter.py:1054 -#: pretix/control/templates/pretixcontrol/order/index.html:744 -#: pretix/control/templates/pretixcontrol/order/index.html:840 +#: pretix/control/templates/pretixcontrol/order/index.html:796 +#: pretix/control/templates/pretixcontrol/order/index.html:892 #: pretix/control/templates/pretixcontrol/orders/refunds.html:70 #: pretix/control/templates/pretixcontrol/search/payments.html:98 -#: pretix/plugins/banktransfer/payment.py:464 -#: pretix/plugins/banktransfer/payment.py:473 +#: pretix/plugins/banktransfer/payment.py:298 +#: pretix/plugins/banktransfer/payment.py:307 #: pretix/plugins/banktransfer/refund_export.py:46 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:25 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13 msgid "Amount" msgstr "" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:102 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:115 -#: pretix/control/templates/pretixcontrol/order/index.html:742 -#: pretix/control/templates/pretixcontrol/order/index.html:837 +#: pretix/control/templates/pretixcontrol/order/index.html:794 +#: pretix/control/templates/pretixcontrol/order/index.html:889 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:85 -#: pretix/plugins/reports/accountingreport.py:495 +#: pretix/plugins/reports/accountingreport.py:496 #: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_confirm.html:29 msgid "Payment method" msgstr "" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 msgid "Matching ID" msgstr "" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:38 msgid "Payment details" msgstr "" -#: pretix/base/exporters/orderlist.py:1127 +#: pretix/base/exporters/orderlist.py:1145 msgid "Quota availabilities" msgstr "" -#: pretix/base/exporters/orderlist.py:1129 +#: pretix/base/exporters/orderlist.py:1147 msgid "" "Download a spreadsheet of all quotas including their current availability." msgstr "" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 #: pretix/control/templates/pretixcontrol/items/quotas.html:45 msgid "Quota name" msgstr "" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 #: pretix/control/templates/pretixcontrol/items/quota.html:56 msgid "Total quota" msgstr "" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 #: pretix/control/templates/pretixcontrol/event/cancel.html:20 #: pretix/control/views/item.py:970 msgid "Paid orders" msgstr "" -#: pretix/base/exporters/orderlist.py:1134 pretix/control/views/item.py:975 +#: pretix/base/exporters/orderlist.py:1152 pretix/control/views/item.py:975 msgid "Pending orders" msgstr "" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 msgid "Blocking vouchers" msgstr "" -#: pretix/base/exporters/orderlist.py:1135 pretix/control/views/item.py:994 +#: pretix/base/exporters/orderlist.py:1153 pretix/control/views/item.py:994 msgid "Current user's carts" msgstr "" -#: pretix/base/exporters/orderlist.py:1135 +#: pretix/base/exporters/orderlist.py:1153 msgid "Exited orders" msgstr "" -#: pretix/base/exporters/orderlist.py:1135 +#: pretix/base/exporters/orderlist.py:1153 msgid "Current availability" msgstr "" -#: pretix/base/exporters/orderlist.py:1152 -#: pretix/base/exporters/orderlist.py:1159 +#: pretix/base/exporters/orderlist.py:1170 +#: pretix/base/exporters/orderlist.py:1177 #: pretix/control/templates/pretixcontrol/items/quota.html:58 #: pretix/control/views/item.py:1001 msgid "Infinite" msgstr "" -#: pretix/base/exporters/orderlist.py:1181 +#: pretix/base/exporters/orderlist.py:1199 msgid "Gift card transactions" msgstr "" -#: pretix/base/exporters/orderlist.py:1183 -#: pretix/base/exporters/orderlist.py:1288 +#: pretix/base/exporters/orderlist.py:1201 +#: pretix/base/exporters/orderlist.py:1306 msgctxt "export_category" msgid "Gift cards" msgstr "" -#: pretix/base/exporters/orderlist.py:1184 +#: pretix/base/exporters/orderlist.py:1202 msgid "Download a spreadsheet of all gift card transactions." msgstr "" -#: pretix/base/exporters/orderlist.py:1212 -#: pretix/base/exporters/orderlist.py:1259 -#: pretix/base/exporters/orderlist.py:1355 pretix/base/models/giftcards.py:89 +#: pretix/base/exporters/orderlist.py:1230 +#: pretix/base/exporters/orderlist.py:1277 +#: pretix/base/exporters/orderlist.py:1373 pretix/base/models/giftcards.py:89 #: pretix/base/payment.py:1454 #: pretix/control/templates/pretixcontrol/giftcards/payment.html:4 -#: pretix/control/templates/pretixcontrol/order/index.html:506 +#: pretix/control/templates/pretixcontrol/order/index.html:558 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:28 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:56 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:152 msgid "Gift card code" msgstr "" -#: pretix/base/exporters/orderlist.py:1213 -#: pretix/base/exporters/orderlist.py:1302 -#: pretix/base/exporters/orderlist.py:1305 +#: pretix/base/exporters/orderlist.py:1231 +#: pretix/base/exporters/orderlist.py:1320 +#: pretix/base/exporters/orderlist.py:1323 #: pretix/base/models/memberships.py:120 pretix/control/forms/filter.py:244 -#: pretix/control/forms/filter.py:1417 pretix/control/forms/filter.py:1420 +#: pretix/control/forms/filter.py:1415 pretix/control/forms/filter.py:1418 #: pretix/control/templates/pretixcontrol/event/live.html:75 msgid "Test mode" msgstr "" -#: pretix/base/exporters/orderlist.py:1218 pretix/base/models/organizer.py:96 -#: pretix/control/forms/event.py:110 pretix/control/forms/event.py:116 -#: pretix/control/forms/filter.py:888 pretix/control/forms/filter.py:1006 -#: pretix/control/forms/filter.py:1682 +#: pretix/base/exporters/orderlist.py:1236 pretix/base/models/organizer.py:102 +#: pretix/control/forms/event.py:110 pretix/control/forms/filter.py:888 +#: pretix/control/forms/filter.py:1006 pretix/control/forms/filter.py:1680 #: pretix/control/templates/pretixcontrol/email_setup.html:6 #: pretix/control/templates/pretixcontrol/email_setup_simple.html:6 #: pretix/control/templates/pretixcontrol/email_setup_smtp.html:6 @@ -2586,8 +2841,8 @@ msgstr "" msgid "Organizer" msgstr "" -#: pretix/base/exporters/orderlist.py:1225 pretix/base/invoice.py:573 -#: pretix/control/templates/pretixcontrol/base.html:283 +#: pretix/base/exporters/orderlist.py:1243 pretix/base/invoicing/pdf.py:576 +#: pretix/control/templates/pretixcontrol/base.html:281 #: pretix/control/templates/pretixcontrol/checkin/index.html:145 #: pretix/control/templates/pretixcontrol/order/index.html:25 #: pretix/control/templates/pretixcontrol/orders/bulk_action.html:38 @@ -2614,106 +2869,107 @@ msgstr "" msgid "TEST MODE" msgstr "" -#: pretix/base/exporters/orderlist.py:1240 +#: pretix/base/exporters/orderlist.py:1258 msgid "Gift card redemptions" msgstr "" -#: pretix/base/exporters/orderlist.py:1242 +#: pretix/base/exporters/orderlist.py:1260 msgid "" "Download a spreadsheet of all payments or refunds that involve gift cards." msgstr "" -#: pretix/base/exporters/orderlist.py:1259 +#: pretix/base/exporters/orderlist.py:1277 #: pretix/control/templates/pretixcontrol/giftcards/payment.html:16 msgid "Issuer" msgstr "" -#: pretix/base/exporters/orderlist.py:1286 pretix/control/navigation.py:538 -#: pretix/control/navigation.py:556 +#: pretix/base/exporters/orderlist.py:1304 pretix/control/navigation.py:550 +#: pretix/control/navigation.py:568 #: pretix/control/templates/pretixcontrol/organizers/edit.html:156 -#: pretix/plugins/reports/accountingreport.py:898 +#: pretix/plugins/reports/accountingreport.py:899 msgid "Gift cards" msgstr "" -#: pretix/base/exporters/orderlist.py:1289 +#: pretix/base/exporters/orderlist.py:1307 msgid "Download a spreadsheet of all gift cards including their current value." msgstr "" -#: pretix/base/exporters/orderlist.py:1296 +#: pretix/base/exporters/orderlist.py:1314 msgid "Show value at" msgstr "" -#: pretix/base/exporters/orderlist.py:1299 +#: pretix/base/exporters/orderlist.py:1317 msgid "Defaults to the time of report." msgstr "" -#: pretix/base/exporters/orderlist.py:1304 -#: pretix/base/exporters/orderlist.py:1314 pretix/control/forms/filter.py:519 -#: pretix/control/forms/filter.py:1200 pretix/control/forms/filter.py:1419 -#: pretix/control/forms/filter.py:1428 pretix/control/forms/filter.py:1498 -#: pretix/control/forms/filter.py:1508 pretix/control/forms/filter.py:1570 -#: pretix/control/forms/filter.py:2009 pretix/control/forms/filter.py:2018 -#: pretix/control/forms/filter.py:2089 pretix/control/forms/filter.py:2102 -#: pretix/control/forms/filter.py:2608 pretix/control/forms/filter.py:2627 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:134 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:140 +#: pretix/base/exporters/orderlist.py:1322 +#: pretix/base/exporters/orderlist.py:1332 pretix/control/forms/filter.py:519 +#: pretix/control/forms/filter.py:1200 pretix/control/forms/filter.py:1417 +#: pretix/control/forms/filter.py:1426 pretix/control/forms/filter.py:1496 +#: pretix/control/forms/filter.py:1506 pretix/control/forms/filter.py:1568 +#: pretix/control/forms/filter.py:2005 pretix/control/forms/filter.py:2014 +#: pretix/control/forms/filter.py:2085 pretix/control/forms/filter.py:2098 +#: pretix/control/forms/filter.py:2604 pretix/control/forms/filter.py:2623 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:141 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:147 #: pretix/control/templates/pretixcontrol/event/plugins.html:24 #: pretix/control/templates/pretixcontrol/items/discounts.html:113 #: pretix/control/templates/pretixcontrol/organizers/devices.html:147 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:24 #: pretix/control/templates/pretixcontrol/organizers/teams.html:61 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:52 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:43 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:62 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:76 -#: pretix/plugins/reports/accountingreport.py:104 +#: pretix/plugins/reports/accountingreport.py:105 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:67 msgid "All" msgstr "" -#: pretix/base/exporters/orderlist.py:1306 pretix/control/forms/filter.py:1421 +#: pretix/base/exporters/orderlist.py:1324 pretix/control/forms/filter.py:1419 msgid "Live" msgstr "" -#: pretix/base/exporters/orderlist.py:1315 pretix/control/forms/filter.py:1429 -#: pretix/control/templates/pretixcontrol/pdf/index.html:265 +#: pretix/base/exporters/orderlist.py:1333 pretix/control/forms/filter.py:1427 +#: pretix/control/templates/pretixcontrol/pdf/index.html:325 msgid "Empty" msgstr "" -#: pretix/base/exporters/orderlist.py:1316 pretix/control/forms/filter.py:1430 +#: pretix/base/exporters/orderlist.py:1334 pretix/control/forms/filter.py:1428 msgid "Valid and with value" msgstr "" -#: pretix/base/exporters/orderlist.py:1317 pretix/control/forms/filter.py:1431 +#: pretix/base/exporters/orderlist.py:1335 pretix/control/forms/filter.py:1429 msgid "Expired and with value" msgstr "" -#: pretix/base/exporters/orderlist.py:1318 pretix/control/forms/filter.py:227 -#: pretix/control/forms/filter.py:1432 pretix/control/forms/filter.py:2094 +#: pretix/base/exporters/orderlist.py:1336 pretix/control/forms/filter.py:227 +#: pretix/control/forms/filter.py:1430 pretix/control/forms/filter.py:2090 #: pretix/control/templates/pretixcontrol/items/question.html:31 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:37 #: pretix/control/templates/pretixcontrol/orders/overview.html:78 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:84 -#: pretix/plugins/reports/exporters.py:378 +#: pretix/plugins/reports/exporters.py:389 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:26 msgid "Expired" msgstr "" -#: pretix/base/exporters/orderlist.py:1356 pretix/base/models/giftcards.py:98 +#: pretix/base/exporters/orderlist.py:1374 pretix/base/models/giftcards.py:98 msgid "Test mode card" msgstr "" -#: pretix/base/exporters/orderlist.py:1358 -#: pretix/base/modelimport_orders.py:516 pretix/base/models/giftcards.py:102 +#: pretix/base/exporters/orderlist.py:1376 +#: pretix/base/modelimport_orders.py:553 pretix/base/models/giftcards.py:102 #: pretix/control/templates/pretixcontrol/order/index.html:203 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:62 msgid "Expiry date" msgstr "" -#: pretix/base/exporters/orderlist.py:1359 pretix/control/forms/orders.py:892 +#: pretix/base/exporters/orderlist.py:1377 pretix/control/forms/orders.py:902 msgid "Special terms and conditions" msgstr "" -#: pretix/base/exporters/orderlist.py:1361 +#: pretix/base/exporters/orderlist.py:1379 #: pretix/control/templates/pretixcontrol/order/change.html:98 #: pretix/control/templates/pretixcontrol/order/change.html:410 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:32 @@ -2721,19 +2977,19 @@ msgstr "" msgid "Current value" msgstr "" -#: pretix/base/exporters/orderlist.py:1362 +#: pretix/base/exporters/orderlist.py:1380 msgid "Created in order" msgstr "" -#: pretix/base/exporters/orderlist.py:1363 +#: pretix/base/exporters/orderlist.py:1381 msgid "Last invoice number of order" msgstr "" -#: pretix/base/exporters/orderlist.py:1364 +#: pretix/base/exporters/orderlist.py:1382 msgid "Last invoice date of order" msgstr "" -#: pretix/base/exporters/reusablemedia.py:34 pretix/control/navigation.py:616 +#: pretix/base/exporters/reusablemedia.py:34 pretix/control/navigation.py:628 #: pretix/control/templates/pretixcontrol/organizers/edit.html:222 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:35 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:114 @@ -2763,7 +3019,7 @@ msgid "Identifier" msgstr "" #: pretix/base/exporters/reusablemedia.py:49 pretix/base/models/media.py:81 -#: pretix/base/models/orders.py:265 pretix/base/models/orders.py:3098 +#: pretix/base/models/orders.py:265 pretix/base/models/orders.py:3109 #: pretix/control/forms/orders.py:78 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:138 msgid "Expiration date" @@ -2771,7 +3027,8 @@ msgstr "" #: pretix/base/exporters/reusablemedia.py:50 pretix/base/models/media.py:90 #: pretix/control/templates/pretixcontrol/order/index.html:216 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:133 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:136 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:8 msgid "Customer account" msgstr "" @@ -2828,7 +3085,7 @@ msgid "Voucher expired" msgstr "" #: pretix/base/exporters/waitinglist.py:117 -#: pretix/base/modelimport_orders.py:95 pretix/base/modelimport_vouchers.py:60 +#: pretix/base/modelimport_orders.py:111 pretix/base/modelimport_vouchers.py:60 #: pretix/control/templates/pretixcontrol/checkin/index.html:100 msgctxt "subevents" msgid "Date" @@ -2839,19 +3096,6 @@ msgstr "" msgid "Priority" msgstr "" -#: pretix/base/exporters/waitinglist.py:123 -#: pretix/base/modelimport_vouchers.py:39 pretix/base/models/vouchers.py:190 -#: pretix/control/templates/pretixcontrol/vouchers/index.html:18 -#: pretix/control/templates/pretixcontrol/vouchers/index.html:114 -#: pretix/control/views/vouchers.py:119 pretix/control/views/waitinglist.py:314 -#: pretix/plugins/checkinlists/exporters.py:519 -#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:74 -#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:76 -#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:12 -#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:20 -msgid "Voucher code" -msgstr "" - #: pretix/base/forms/__init__.py:95 pretix/base/forms/__init__.py:106 #: pretix/base/forms/__init__.py:118 #, python-brace-format @@ -2953,30 +3197,60 @@ msgstr "" msgid "Street and Number" msgstr "" -#: pretix/base/forms/questions.py:1154 +#: pretix/base/forms/questions.py:1162 msgid "" "Optional, but depending on the country you reside in we might need to charge " "you additional taxes if you do not enter it." msgstr "" -#: pretix/base/forms/questions.py:1156 pretix/base/forms/questions.py:1162 +#: pretix/base/forms/questions.py:1164 pretix/base/forms/questions.py:1170 msgid "If you are registered in Switzerland, you can enter your UID instead." msgstr "" -#: pretix/base/forms/questions.py:1160 +#: pretix/base/forms/questions.py:1168 msgid "" "Optional, but it might be required for you to claim tax benefits on your " "invoice depending on your and the seller’s country of residence." msgstr "" -#: pretix/base/forms/questions.py:1266 +#: pretix/base/forms/questions.py:1177 +msgid "No invoice requested" +msgstr "" + +#: pretix/base/forms/questions.py:1179 +msgid "Invoice transmission method" +msgstr "" + +#: pretix/base/forms/questions.py:1324 msgid "You need to provide a company name." msgstr "" -#: pretix/base/forms/questions.py:1268 +#: pretix/base/forms/questions.py:1326 msgid "You need to provide your name." msgstr "" +#: pretix/base/forms/questions.py:1352 +msgid "" +"If you enter an invoice address, you also need to select an invoice " +"transmission method." +msgstr "" + +#: pretix/base/forms/questions.py:1380 +msgid "" +"The selected transmission type is not available in your country or for your " +"type of address." +msgstr "" + +#: pretix/base/forms/questions.py:1389 +msgid "" +"The selected type of invoice transmission requires a field that is currently " +"not available, please reach out to the organizer." +msgstr "" + +#: pretix/base/forms/questions.py:1393 +msgid "This field is required for the selected type of invoice transmission." +msgstr "" + #: pretix/base/forms/user.py:51 pretix/control/forms/users.py:43 msgid "" "There already is an account associated with this email address. Please " @@ -3047,7 +3321,7 @@ msgid "" "\"{{\" and \"}}\"." msgstr "" -#: pretix/base/forms/validators.py:72 pretix/control/views/event.py:807 +#: pretix/base/forms/validators.py:72 pretix/control/views/event.py:851 #, python-format msgid "Invalid placeholder: {%(value)s}" msgstr "" @@ -3063,7 +3337,7 @@ msgid "Available placeholders: {list}" msgstr "" #: pretix/base/forms/widgets.py:214 pretix/base/models/items.py:1656 -#: pretix/base/reldate.py:216 pretix/plugins/checkinlists/exporters.py:753 +#: pretix/plugins/checkinlists/exporters.py:754 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:40 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:54 msgid "Time" @@ -3077,68 +3351,111 @@ msgstr "" msgid "Individual customer" msgstr "" -#: pretix/base/invoice.py:138 +#: pretix/base/invoicing/email.py:50 +msgid "Email invoice directly to accounting department" +msgstr "" + +#: pretix/base/invoicing/email.py:51 +msgid "" +"If not selected, the invoice will be sent to you using the email address " +"listed above." +msgstr "" + +#: pretix/base/invoicing/email.py:55 +msgid "Email address for invoice" +msgstr "" + +#: pretix/base/invoicing/email.py:91 +msgid "PDF via email" +msgstr "" + +#: pretix/base/invoicing/national.py:37 +msgctxt "italian_invoice" +msgid "Italian Exchange System (SdI)" +msgstr "" + +#: pretix/base/invoicing/national.py:38 +msgctxt "italian_invoice" +msgid "Exchange System (SdI)" +msgstr "" + +#: pretix/base/invoicing/national.py:49 +msgctxt "italian_invoice" +msgid "Fiscal code" +msgstr "" + +#: pretix/base/invoicing/national.py:53 +msgctxt "italian_invoice" +msgid "Address for certified electronic mail" +msgstr "" + +#: pretix/base/invoicing/national.py:57 +msgctxt "italian_invoice" +msgid "Recipient code" +msgstr "" + +#: pretix/base/invoicing/pdf.py:140 #, python-format msgctxt "invoice" msgid "Page %d of %d" msgstr "" -#: pretix/base/invoice.py:375 +#: pretix/base/invoicing/pdf.py:378 msgctxt "invoice" msgid "Classic renderer (pretix 1.0)" msgstr "" -#: pretix/base/invoice.py:419 +#: pretix/base/invoicing/pdf.py:422 msgctxt "invoice" msgid "Invoice from" msgstr "" -#: pretix/base/invoice.py:425 +#: pretix/base/invoicing/pdf.py:428 msgctxt "invoice" msgid "Invoice to" msgstr "" -#: pretix/base/invoice.py:462 pretix/base/invoice.py:1016 +#: pretix/base/invoicing/pdf.py:465 pretix/base/invoicing/pdf.py:1033 msgctxt "invoice" msgid "Order code" msgstr "" -#: pretix/base/invoice.py:471 pretix/base/invoice.py:1029 +#: pretix/base/invoicing/pdf.py:474 pretix/base/invoicing/pdf.py:1046 msgctxt "invoice" msgid "Cancellation number" msgstr "" -#: pretix/base/invoice.py:477 pretix/base/invoice.py:1031 +#: pretix/base/invoicing/pdf.py:480 pretix/base/invoicing/pdf.py:1048 msgctxt "invoice" msgid "Original invoice" msgstr "" -#: pretix/base/invoice.py:482 pretix/base/invoice.py:1036 +#: pretix/base/invoicing/pdf.py:485 pretix/base/invoicing/pdf.py:1053 msgctxt "invoice" msgid "Invoice number" msgstr "" -#: pretix/base/invoice.py:490 pretix/base/invoice.py:1051 +#: pretix/base/invoicing/pdf.py:493 pretix/base/invoicing/pdf.py:1068 msgctxt "invoice" msgid "Cancellation date" msgstr "" -#: pretix/base/invoice.py:496 +#: pretix/base/invoicing/pdf.py:499 msgctxt "invoice" msgid "Original invoice date" msgstr "" -#: pretix/base/invoice.py:503 pretix/base/invoice.py:1053 +#: pretix/base/invoicing/pdf.py:506 pretix/base/invoicing/pdf.py:1070 msgctxt "invoice" msgid "Invoice date" msgstr "" -#: pretix/base/invoice.py:519 +#: pretix/base/invoicing/pdf.py:522 msgctxt "invoice" msgid "Event" msgstr "" -#: pretix/base/invoice.py:545 +#: pretix/base/invoicing/pdf.py:548 #, python-brace-format msgctxt "invoice" msgid "" @@ -3146,39 +3463,39 @@ msgid "" "until {to_date}" msgstr "" -#: pretix/base/invoice.py:578 pretix/base/services/mail.py:502 +#: pretix/base/invoicing/pdf.py:581 pretix/base/services/mail.py:502 #, python-brace-format msgctxt "invoice" msgid "Invoice {num}" msgstr "" -#: pretix/base/invoice.py:621 +#: pretix/base/invoicing/pdf.py:624 #, python-brace-format msgctxt "invoice" msgid "Customer reference: {reference}" msgstr "" -#: pretix/base/invoice.py:629 +#: pretix/base/invoicing/pdf.py:632 msgctxt "invoice" msgid "Customer VAT ID" msgstr "" -#: pretix/base/invoice.py:636 +#: pretix/base/invoicing/pdf.py:639 msgctxt "invoice" msgid "Beneficiary" msgstr "" -#: pretix/base/invoice.py:657 +#: pretix/base/invoicing/pdf.py:665 msgctxt "invoice" msgid "Tax Invoice" msgstr "" -#: pretix/base/invoice.py:658 +#: pretix/base/invoicing/pdf.py:666 msgctxt "invoice" msgid "Invoice" msgstr "" -#: pretix/base/invoice.py:659 +#: pretix/base/invoicing/pdf.py:667 #: pretix/control/templates/pretixcontrol/order/index.html:272 #: pretix/control/templates/pretixcontrol/order/mail_history.html:70 #: pretix/presale/templates/pretixpresale/event/order.html:244 @@ -3186,94 +3503,94 @@ msgctxt "invoice" msgid "Cancellation" msgstr "" -#: pretix/base/invoice.py:681 pretix/base/invoice.py:689 +#: pretix/base/invoicing/pdf.py:689 pretix/base/invoicing/pdf.py:697 msgctxt "invoice" msgid "Description" msgstr "" -#: pretix/base/invoice.py:682 pretix/base/invoice.py:690 +#: pretix/base/invoicing/pdf.py:690 pretix/base/invoicing/pdf.py:698 msgctxt "invoice" msgid "Qty" msgstr "" -#: pretix/base/invoice.py:683 pretix/base/invoice.py:833 +#: pretix/base/invoicing/pdf.py:691 pretix/base/invoicing/pdf.py:850 msgctxt "invoice" msgid "Tax rate" msgstr "" -#: pretix/base/invoice.py:684 +#: pretix/base/invoicing/pdf.py:692 msgctxt "invoice" msgid "Net" msgstr "" -#: pretix/base/invoice.py:685 +#: pretix/base/invoicing/pdf.py:693 msgctxt "invoice" msgid "Gross" msgstr "" -#: pretix/base/invoice.py:691 +#: pretix/base/invoicing/pdf.py:699 msgctxt "invoice" msgid "Amount" msgstr "" -#: pretix/base/invoice.py:707 +#: pretix/base/invoicing/pdf.py:715 #, python-brace-format msgctxt "invoice" msgid "Single price: {net_price} net / {gross_price} gross" msgstr "" -#: pretix/base/invoice.py:724 +#: pretix/base/invoicing/pdf.py:738 #, python-brace-format msgctxt "invoice" msgid "Single price: {price}" msgstr "" -#: pretix/base/invoice.py:742 pretix/base/invoice.py:748 +#: pretix/base/invoicing/pdf.py:759 pretix/base/invoicing/pdf.py:765 msgctxt "invoice" msgid "Invoice total" msgstr "" -#: pretix/base/invoice.py:758 +#: pretix/base/invoicing/pdf.py:775 msgctxt "invoice" msgid "Received payments" msgstr "" -#: pretix/base/invoice.py:763 +#: pretix/base/invoicing/pdf.py:780 msgctxt "invoice" msgid "Outstanding payments" msgstr "" -#: pretix/base/invoice.py:780 +#: pretix/base/invoicing/pdf.py:797 msgctxt "invoice" msgid "Paid by gift card" msgstr "" -#: pretix/base/invoice.py:785 +#: pretix/base/invoicing/pdf.py:802 msgctxt "invoice" msgid "Remaining amount" msgstr "" -#: pretix/base/invoice.py:834 +#: pretix/base/invoicing/pdf.py:851 msgctxt "invoice" msgid "Net value" msgstr "" -#: pretix/base/invoice.py:835 +#: pretix/base/invoicing/pdf.py:852 msgctxt "invoice" msgid "Gross value" msgstr "" -#: pretix/base/invoice.py:836 +#: pretix/base/invoicing/pdf.py:853 msgctxt "invoice" msgid "Tax" msgstr "" -#: pretix/base/invoice.py:866 +#: pretix/base/invoicing/pdf.py:883 msgctxt "invoice" msgid "Included taxes" msgstr "" -#: pretix/base/invoice.py:894 +#: pretix/base/invoicing/pdf.py:911 #, python-brace-format msgctxt "invoice" msgid "" @@ -3281,7 +3598,7 @@ msgid "" "{date}, this corresponds to:" msgstr "" -#: pretix/base/invoice.py:909 +#: pretix/base/invoicing/pdf.py:926 #, python-brace-format msgctxt "invoice" msgid "" @@ -3289,25 +3606,48 @@ msgid "" "{date}, the invoice total corresponds to {total}." msgstr "" -#: pretix/base/invoice.py:923 +#: pretix/base/invoicing/pdf.py:940 msgid "Default invoice renderer (European-style letter)" msgstr "" -#: pretix/base/invoice.py:1012 +#: pretix/base/invoicing/pdf.py:1029 msgctxt "invoice" msgid "(Please quote at all times.)" msgstr "" -#: pretix/base/invoice.py:1059 +#: pretix/base/invoicing/pdf.py:1076 msgid "Simplified invoice renderer" msgstr "" -#: pretix/base/invoice.py:1078 +#: pretix/base/invoicing/pdf.py:1095 #, python-brace-format msgctxt "invoice" msgid "Event date: {date_range}" msgstr "" +#: pretix/base/invoicing/peppol.py:128 +msgid "" +"A PEPPOL participant ID always starts with a prefix, followed by a colon (:)." +msgstr "" + +#: pretix/base/invoicing/peppol.py:132 +#, python-format +msgid "" +"The PEPPOL participant ID prefix %(number)s is not known to our system. " +"Please reach out to us if you are sure this ID is correct." +msgstr "" + +#: pretix/base/invoicing/peppol.py:136 +#, python-format +msgid "" +"The PEPPOL participant ID does not match the validation rules for the prefix " +"%(number)s. Please reach out to us if you are sure this ID is correct." +msgstr "" + +#: pretix/base/invoicing/peppol.py:156 +msgid "PEPPOL participant ID" +msgstr "" + #: pretix/base/logentrytype_registry.py:43 msgid "" "The relevant plugin is currently not active. To activate it, click here to " @@ -3368,11 +3708,6 @@ msgstr "" msgid "Tax rule {val}" msgstr "" -#: pretix/base/logentrytypes.py:151 -#, python-brace-format -msgid "{val}" -msgstr "" - #: pretix/base/media.py:71 msgid "Barcode / QR-Code" msgstr "" @@ -3391,201 +3726,234 @@ msgstr "" msgid "Keep empty" msgstr "" -#: pretix/base/modelimport.py:139 +#: pretix/base/modelimport.py:146 #, python-brace-format msgid "Invalid setting for column \"{header}\"." msgstr "" -#: pretix/base/modelimport.py:199 +#: pretix/base/modelimport.py:206 #, python-brace-format msgid "Could not parse {value} as a yes/no value." msgstr "" -#: pretix/base/modelimport.py:222 +#: pretix/base/modelimport.py:229 #, python-brace-format msgid "Could not parse {value} as a date and time." msgstr "" -#: pretix/base/modelimport.py:232 pretix/control/views/orders.py:1184 -#: pretix/control/views/orders.py:1213 pretix/control/views/orders.py:1257 -#: pretix/control/views/orders.py:1292 pretix/control/views/orders.py:1315 +#: pretix/base/modelimport.py:239 pretix/control/views/orders.py:1169 +#: pretix/control/views/orders.py:1198 pretix/control/views/orders.py:1242 +#: pretix/control/views/orders.py:1277 pretix/control/views/orders.py:1300 msgid "You entered an invalid number." msgstr "" -#: pretix/base/modelimport.py:279 pretix/base/modelimport.py:291 +#: pretix/base/modelimport.py:286 pretix/base/modelimport.py:298 msgctxt "subevent" msgid "No matching date was found." msgstr "" -#: pretix/base/modelimport.py:281 pretix/base/modelimport.py:293 +#: pretix/base/modelimport.py:288 pretix/base/modelimport.py:300 msgctxt "subevent" msgid "Multiple matching dates were found." msgstr "" -#: pretix/base/modelimport_orders.py:85 +#: pretix/base/modelimport_orders.py:73 +msgid "Grouping" +msgstr "" + +#: pretix/base/modelimport_orders.py:75 +msgid "" +"Only applicable when \"Import mode\" is set to \"Group multiple lines " +"together...\". Lines with the same grouping value will be put in the same " +"order, but MUST be consecutive lines of the input file." +msgstr "" + +#: pretix/base/modelimport_orders.py:101 msgid "Enter a valid phone number." msgstr "" -#: pretix/base/modelimport_orders.py:100 pretix/presale/views/waiting.py:157 +#: pretix/base/modelimport_orders.py:114 +msgctxt "subevents" +msgid "" +"The date can be specified through its full name, full date and time, or " +"internal ID, provided only one date in the system matches the input." +msgstr "" + +#: pretix/base/modelimport_orders.py:120 pretix/presale/views/waiting.py:157 msgctxt "subevent" msgid "You need to select a date." msgstr "" -#: pretix/base/modelimport_orders.py:128 +#: pretix/base/modelimport_orders.py:131 +msgid "" +"The product can be specified by its internal ID, full name or internal name." +msgstr "" + +#: pretix/base/modelimport_orders.py:149 #: pretix/base/modelimport_vouchers.py:194 msgid "No matching product was found." msgstr "" -#: pretix/base/modelimport_orders.py:130 +#: pretix/base/modelimport_orders.py:151 #: pretix/base/modelimport_vouchers.py:196 msgid "Multiple matching products were found." msgstr "" -#: pretix/base/modelimport_orders.py:139 +#: pretix/base/modelimport_orders.py:160 #: pretix/base/modelimport_vouchers.py:205 pretix/base/models/items.py:1257 -#: pretix/base/models/vouchers.py:263 pretix/base/models/waitinglist.py:99 +#: pretix/base/models/vouchers.py:266 pretix/base/models/waitinglist.py:99 msgid "Product variation" msgstr "" -#: pretix/base/modelimport_orders.py:159 +#: pretix/base/modelimport_orders.py:161 +msgid "The variation can be specified by its internal ID or full name." +msgstr "" + +#: pretix/base/modelimport_orders.py:181 #: pretix/base/modelimport_vouchers.py:225 #: pretix/base/modelimport_vouchers.py:259 msgid "No matching variation was found." msgstr "" -#: pretix/base/modelimport_orders.py:161 +#: pretix/base/modelimport_orders.py:183 #: pretix/base/modelimport_vouchers.py:227 #: pretix/base/modelimport_vouchers.py:261 msgid "Multiple matching variations were found." msgstr "" -#: pretix/base/modelimport_orders.py:164 +#: pretix/base/modelimport_orders.py:186 msgid "You need to select a variation for this product." msgstr "" -#: pretix/base/modelimport_orders.py:176 pretix/base/modelimport_orders.py:191 -#: pretix/base/modelimport_orders.py:206 pretix/base/modelimport_orders.py:217 -#: pretix/base/modelimport_orders.py:228 pretix/base/modelimport_orders.py:244 -#: pretix/base/modelimport_orders.py:263 pretix/base/modelimport_orders.py:288 -#: pretix/base/modelimport_orders.py:299 pretix/control/forms/filter.py:621 -#: pretix/control/forms/filter.py:625 pretix/control/forms/filter.py:629 -#: pretix/control/forms/filter.py:633 pretix/control/forms/filter.py:638 -#: pretix/control/forms/filter.py:643 -msgid "Invoice address" +#: pretix/base/modelimport_orders.py:265 pretix/base/modelimport_orders.py:417 +msgid "The country needs to be specified using a two-letter country code." msgstr "" -#: pretix/base/modelimport_orders.py:251 pretix/base/modelimport_orders.py:397 +#: pretix/base/modelimport_orders.py:281 pretix/base/modelimport_orders.py:432 msgid "Please enter a valid country code." msgstr "" -#: pretix/base/modelimport_orders.py:268 pretix/base/modelimport_orders.py:414 +#: pretix/base/modelimport_orders.py:290 pretix/base/modelimport_orders.py:441 +msgid "The state can be specified by its short form or full name." +msgstr "" + +#: pretix/base/modelimport_orders.py:300 pretix/base/modelimport_orders.py:450 msgid "States are not supported for this country." msgstr "" -#: pretix/base/modelimport_orders.py:276 pretix/base/modelimport_orders.py:422 +#: pretix/base/modelimport_orders.py:308 pretix/base/modelimport_orders.py:458 msgid "Please enter a valid state." msgstr "" -#: pretix/base/modelimport_orders.py:325 pretix/control/forms/filter.py:652 +#: pretix/base/modelimport_orders.py:359 pretix/control/forms/filter.py:652 msgid "Attendee email address" msgstr "" -#: pretix/base/modelimport_orders.py:341 pretix/base/modelimport_orders.py:352 -#: pretix/base/modelimport_orders.py:363 pretix/base/modelimport_orders.py:374 -#: pretix/base/modelimport_orders.py:390 pretix/base/modelimport_orders.py:409 +#: pretix/base/modelimport_orders.py:375 pretix/base/modelimport_orders.py:386 +#: pretix/base/modelimport_orders.py:397 pretix/base/modelimport_orders.py:408 +#: pretix/base/modelimport_orders.py:425 pretix/base/modelimport_orders.py:445 #: pretix/control/forms/filter.py:656 pretix/control/forms/filter.py:660 #: pretix/control/forms/filter.py:664 pretix/control/forms/filter.py:669 #: pretix/control/forms/filter.py:674 -#: pretix/control/templates/pretixcontrol/order/index.html:551 +#: pretix/control/templates/pretixcontrol/order/index.html:603 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:193 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:196 msgid "Attendee address" msgstr "" -#: pretix/base/modelimport_orders.py:409 +#: pretix/base/modelimport_orders.py:445 msgid "State" msgstr "" -#: pretix/base/modelimport_orders.py:432 +#: pretix/base/modelimport_orders.py:468 msgid "Calculate from product" msgstr "" -#: pretix/base/modelimport_orders.py:450 +#: pretix/base/modelimport_orders.py:486 #: pretix/control/templates/pretixcontrol/checkin/index.html:111 -#: pretix/control/templates/pretixcontrol/order/index.html:491 +#: pretix/control/templates/pretixcontrol/order/index.html:531 msgid "Ticket code" msgstr "" -#: pretix/base/modelimport_orders.py:451 +#: pretix/base/modelimport_orders.py:487 msgid "Generate automatically" msgstr "" -#: pretix/base/modelimport_orders.py:460 +#: pretix/base/modelimport_orders.py:496 msgid "You cannot assign a position secret that already exists." msgstr "" -#: pretix/base/modelimport_orders.py:491 +#: pretix/base/modelimport_orders.py:528 msgid "Please enter a valid language code." msgstr "" -#: pretix/base/modelimport_orders.py:559 pretix/base/modelimport_orders.py:561 +#: pretix/base/modelimport_orders.py:581 +msgid "" +"The sales channel can be specified by it's internal identifier or its full " +"name." +msgstr "" + +#: pretix/base/modelimport_orders.py:599 pretix/base/modelimport_orders.py:601 msgid "Please enter a valid sales channel." msgstr "" -#: pretix/base/modelimport_orders.py:585 +#: pretix/base/modelimport_orders.py:611 +msgid "The seat needs to be specified by its internal ID." +msgstr "" + +#: pretix/base/modelimport_orders.py:626 #: pretix/base/modelimport_vouchers.py:291 msgid "Multiple matching seats were found." msgstr "" -#: pretix/base/modelimport_orders.py:587 +#: pretix/base/modelimport_orders.py:628 #: pretix/base/modelimport_vouchers.py:293 msgid "No matching seat was found." msgstr "" -#: pretix/base/modelimport_orders.py:590 +#: pretix/base/modelimport_orders.py:631 #: pretix/base/modelimport_vouchers.py:296 pretix/base/services/cart.py:213 -#: pretix/base/services/modelimport.py:134 -#: pretix/base/services/modelimport.py:246 +#: pretix/base/services/modelimport.py:175 +#: pretix/base/services/modelimport.py:287 msgid "" "The seat you selected has already been taken. Please select a different seat." msgstr "" -#: pretix/base/modelimport_orders.py:593 pretix/base/services/cart.py:210 +#: pretix/base/modelimport_orders.py:634 pretix/base/services/cart.py:210 msgid "You need to select a specific seat." msgstr "" -#: pretix/base/modelimport_orders.py:647 pretix/base/models/items.py:1671 -#: pretix/base/models/items.py:1766 pretix/control/forms/item.py:149 +#: pretix/base/modelimport_orders.py:691 pretix/base/models/items.py:1671 +#: pretix/base/models/items.py:1766 pretix/control/forms/item.py:147 #: pretix/control/templates/pretixcontrol/items/question_edit.html:10 #: pretix/control/templates/pretixcontrol/items/question_edit.html:17 #: pretix/control/templates/pretixcontrol/items/questions.html:21 msgid "Question" msgstr "" -#: pretix/base/modelimport_orders.py:657 pretix/base/modelimport_orders.py:665 +#: pretix/base/modelimport_orders.py:701 pretix/base/modelimport_orders.py:709 #: pretix/base/models/items.py:1830 pretix/base/models/items.py:1848 msgid "Invalid option selected." msgstr "" -#: pretix/base/modelimport_orders.py:659 pretix/base/modelimport_orders.py:667 +#: pretix/base/modelimport_orders.py:703 pretix/base/modelimport_orders.py:711 msgid "Ambiguous option selected." msgstr "" -#: pretix/base/modelimport_orders.py:698 pretix/base/models/orders.py:239 -#: pretix/control/forms/orders.py:696 pretix/control/forms/organizer.py:844 +#: pretix/base/modelimport_orders.py:742 pretix/base/models/orders.py:239 msgid "Customer" msgstr "" -#: pretix/base/modelimport_orders.py:711 +#: pretix/base/modelimport_orders.py:756 msgid "No matching customer was found." msgstr "" -#: pretix/base/modelimport_vouchers.py:50 pretix/base/models/vouchers.py:488 +#: pretix/base/modelimport_vouchers.py:50 pretix/base/models/vouchers.py:491 msgid "A voucher with this code already exists." msgstr "" #: pretix/base/modelimport_vouchers.py:68 pretix/base/models/memberships.py:57 -#: pretix/base/models/vouchers.py:196 pretix/control/views/vouchers.py:120 +#: pretix/base/models/vouchers.py:199 pretix/control/views/vouchers.py:120 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:52 msgid "Maximum usages" msgstr "" @@ -3594,24 +3962,24 @@ msgstr "" msgid "The maximum number of usages must be set." msgstr "" -#: pretix/base/modelimport_vouchers.py:88 pretix/base/models/vouchers.py:205 +#: pretix/base/modelimport_vouchers.py:88 pretix/base/models/vouchers.py:208 msgid "Minimum usages" msgstr "" -#: pretix/base/modelimport_vouchers.py:103 pretix/base/models/vouchers.py:213 +#: pretix/base/modelimport_vouchers.py:103 pretix/base/models/vouchers.py:216 msgid "Maximum discount budget" msgstr "" -#: pretix/base/modelimport_vouchers.py:119 pretix/base/models/vouchers.py:225 -#: pretix/control/forms/filter.py:2103 +#: pretix/base/modelimport_vouchers.py:119 pretix/base/models/vouchers.py:228 +#: pretix/control/forms/filter.py:2099 msgid "Reserve ticket from quota" msgstr "" -#: pretix/base/modelimport_vouchers.py:127 pretix/base/models/vouchers.py:233 +#: pretix/base/modelimport_vouchers.py:127 pretix/base/models/vouchers.py:236 msgid "Allow to bypass quota" msgstr "" -#: pretix/base/modelimport_vouchers.py:135 pretix/base/models/vouchers.py:239 +#: pretix/base/modelimport_vouchers.py:135 pretix/base/models/vouchers.py:242 msgid "Price mode" msgstr "" @@ -3620,7 +3988,7 @@ msgstr "" msgid "Could not parse {value} as a price mode, use one of {options}." msgstr "" -#: pretix/base/modelimport_vouchers.py:160 pretix/base/models/vouchers.py:245 +#: pretix/base/modelimport_vouchers.py:160 pretix/base/models/vouchers.py:248 msgid "Voucher value" msgstr "" @@ -3629,7 +3997,7 @@ msgid "It is pointless to set a value without a price mode." msgstr "" #: pretix/base/modelimport_vouchers.py:237 pretix/base/models/items.py:2121 -#: pretix/base/models/vouchers.py:272 +#: pretix/base/models/vouchers.py:275 #: pretix/control/templates/pretixcontrol/items/quota_edit.html:8 #: pretix/control/templates/pretixcontrol/items/quota_edit.html:15 msgid "Quota" @@ -3639,39 +4007,39 @@ msgstr "" msgid "You cannot specify a quota if you specified a product." msgstr "" -#: pretix/base/modelimport_vouchers.py:282 pretix/base/models/vouchers.py:495 +#: pretix/base/modelimport_vouchers.py:282 pretix/base/models/vouchers.py:498 msgid "You need to choose a date if you select a seat." msgstr "" -#: pretix/base/modelimport_vouchers.py:299 pretix/base/models/vouchers.py:513 +#: pretix/base/modelimport_vouchers.py:299 pretix/base/models/vouchers.py:516 msgid "You need to choose a specific product if you select a seat." msgstr "" -#: pretix/base/modelimport_vouchers.py:302 pretix/base/models/vouchers.py:516 +#: pretix/base/modelimport_vouchers.py:302 pretix/base/models/vouchers.py:519 msgid "Seat-specific vouchers can only be used once." msgstr "" -#: pretix/base/modelimport_vouchers.py:306 pretix/base/models/vouchers.py:519 +#: pretix/base/modelimport_vouchers.py:306 pretix/base/models/vouchers.py:522 #, python-brace-format msgid "You need to choose the product \"{prod}\" for this seat." msgstr "" -#: pretix/base/modelimport_vouchers.py:318 pretix/base/models/vouchers.py:285 +#: pretix/base/modelimport_vouchers.py:318 pretix/base/models/vouchers.py:288 #: pretix/control/templates/pretixcontrol/vouchers/index.html:129 #: pretix/control/templates/pretixcontrol/vouchers/tags.html:42 #: pretix/control/views/vouchers.py:120 msgid "Tag" msgstr "" -#: pretix/base/modelimport_vouchers.py:334 pretix/base/models/vouchers.py:297 +#: pretix/base/modelimport_vouchers.py:334 pretix/base/models/vouchers.py:300 msgid "Shows hidden products that match this voucher" msgstr "" -#: pretix/base/modelimport_vouchers.py:343 pretix/base/models/vouchers.py:301 +#: pretix/base/modelimport_vouchers.py:343 pretix/base/models/vouchers.py:304 msgid "Offer all add-on products for free when redeeming this voucher" msgstr "" -#: pretix/base/modelimport_vouchers.py:351 pretix/base/models/vouchers.py:305 +#: pretix/base/modelimport_vouchers.py:351 pretix/base/models/vouchers.py:308 msgid "" "Include all bundled products without a designated price when redeeming this " "voucher" @@ -3713,7 +4081,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:15 #: pretix/control/templates/pretixcontrol/users/form.html:4 #: pretix/control/templates/pretixcontrol/users/form.html:6 -#: pretix/control/views/organizer.py:158 tests/base/test_mail.py:149 +#: pretix/control/views/organizer.py:170 tests/base/test_mail.py:149 msgid "User" msgstr "" @@ -3737,7 +4105,7 @@ msgid "All products (including newly created ones)" msgstr "" #: pretix/base/models/checkin.py:56 pretix/plugins/badges/exporters.py:436 -#: pretix/plugins/checkinlists/exporters.py:850 +#: pretix/plugins/checkinlists/exporters.py:851 msgid "Limit to products" msgstr "" @@ -3786,7 +4154,7 @@ msgid "" "rejected.." msgstr "" -#: pretix/base/models/checkin.py:85 pretix/control/navigation.py:640 +#: pretix/base/models/checkin.py:85 pretix/control/navigation.py:652 #: pretix/control/templates/pretixcontrol/organizers/gates.html:5 msgid "Gates" msgstr "" @@ -3822,54 +4190,58 @@ msgstr "" msgid "Exit" msgstr "" -#: pretix/base/models/checkin.py:355 +#: pretix/base/models/checkin.py:356 msgid "Unknown ticket" msgstr "" -#: pretix/base/models/checkin.py:356 +#: pretix/base/models/checkin.py:357 msgid "Ticket not paid" msgstr "" -#: pretix/base/models/checkin.py:357 +#: pretix/base/models/checkin.py:358 msgid "Forbidden by custom rule" msgstr "" -#: pretix/base/models/checkin.py:358 +#: pretix/base/models/checkin.py:359 msgid "Ticket code revoked/changed" msgstr "" -#: pretix/base/models/checkin.py:359 +#: pretix/base/models/checkin.py:360 msgid "Information required" msgstr "" -#: pretix/base/models/checkin.py:360 +#: pretix/base/models/checkin.py:361 msgid "Ticket already used" msgstr "" -#: pretix/base/models/checkin.py:361 +#: pretix/base/models/checkin.py:362 msgid "Ticket type not allowed here" msgstr "" -#: pretix/base/models/checkin.py:362 +#: pretix/base/models/checkin.py:363 msgid "Ticket code is ambiguous on list" msgstr "" -#: pretix/base/models/checkin.py:363 +#: pretix/base/models/checkin.py:364 msgid "Server error" msgstr "" -#: pretix/base/models/checkin.py:364 +#: pretix/base/models/checkin.py:365 msgid "Ticket blocked" msgstr "" -#: pretix/base/models/checkin.py:365 +#: pretix/base/models/checkin.py:366 msgid "Order not approved" msgstr "" -#: pretix/base/models/checkin.py:366 +#: pretix/base/models/checkin.py:367 msgid "Ticket not valid at this time" msgstr "" +#: pretix/base/models/checkin.py:368 +msgid "Check-in annulled" +msgstr "" + #: pretix/base/models/customers.py:55 msgid "Provider name" msgstr "" @@ -3895,8 +4267,8 @@ msgid "" "underscores. It must start and end with a letter or number." msgstr "" -#: pretix/base/models/customers.py:195 pretix/control/forms/filter.py:1500 -#: pretix/control/forms/filter.py:1572 +#: pretix/base/models/customers.py:195 pretix/control/forms/filter.py:1498 +#: pretix/control/forms/filter.py:1570 #: pretix/control/templates/pretixcontrol/organizers/customer.html:42 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:56 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:135 @@ -3905,12 +4277,12 @@ msgid "disabled" msgstr "" #: pretix/base/models/customers.py:310 pretix/base/models/orders.py:1538 -#: pretix/base/models/orders.py:3269 pretix/base/settings.py:1112 +#: pretix/base/models/orders.py:3280 pretix/base/settings.py:1150 msgid "Company name" msgstr "" #: pretix/base/models/customers.py:314 pretix/base/models/orders.py:1542 -#: pretix/base/models/orders.py:3276 pretix/base/settings.py:83 +#: pretix/base/models/orders.py:3287 pretix/base/settings.py:83 #: pretix/plugins/stripe/payment.py:272 msgid "Select country" msgstr "" @@ -3963,6 +4335,22 @@ msgstr "" msgid "Separate multiple values with spaces" msgstr "" +#: pretix/base/models/datasync.py:53 +msgid "Temporary error, auto-retry limit exceeded" +msgstr "" + +#: pretix/base/models/datasync.py:54 +msgid "Provider reported a permanent error" +msgstr "" + +#: pretix/base/models/datasync.py:55 +msgid "Misconfiguration, please check provider settings" +msgstr "" + +#: pretix/base/models/datasync.py:56 pretix/base/models/datasync.py:57 +msgid "System error, needs manual intervention" +msgstr "" + #: pretix/base/models/devices.py:70 pretix/base/models/items.py:1675 msgid "Internal identifier" msgstr "" @@ -3972,11 +4360,11 @@ msgid "This identifier is already used for a different question." msgstr "" #: pretix/base/models/devices.py:113 pretix/control/forms/checkin.py:196 -#: pretix/control/forms/checkin.py:217 pretix/control/forms/filter.py:2394 -#: pretix/control/forms/filter.py:2441 pretix/control/forms/filter.py:2601 +#: pretix/control/forms/checkin.py:217 pretix/control/forms/filter.py:2390 +#: pretix/control/forms/filter.py:2437 pretix/control/forms/filter.py:2597 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:67 #: pretix/control/templates/pretixcontrol/organizers/gates.html:16 -#: pretix/plugins/checkinlists/exporters.py:765 +#: pretix/plugins/checkinlists/exporters.py:766 msgid "Gate" msgstr "" @@ -4006,7 +4394,7 @@ msgstr "" #: pretix/base/models/discount.py:69 pretix/base/models/items.py:1161 #: pretix/base/models/items.py:1481 pretix/base/models/items.py:1708 -#: pretix/base/models/organizer.py:553 +#: pretix/base/models/organizer.py:619 msgid "Position" msgstr "" @@ -4147,7 +4535,7 @@ msgstr "" msgid "The end of the event has to be later than its start." msgstr "" -#: pretix/base/models/event.py:577 +#: pretix/base/models/event.py:576 msgid "" "Should be short, only contain lowercase letters, numbers, dots, and dashes, " "and must be unique among your events. We recommend some kind of abbreviation " @@ -4156,227 +4544,228 @@ msgid "" "codes, invoice numbers, and bank transfer references." msgstr "" -#: pretix/base/models/event.py:584 pretix/base/models/organizer.py:87 +#: pretix/base/models/event.py:583 pretix/base/models/organizer.py:89 msgid "The slug may only contain letters, numbers, dots and dashes." msgstr "" -#: pretix/base/models/event.py:601 pretix/base/models/event.py:1488 +#: pretix/base/models/event.py:600 pretix/base/models/event.py:1495 msgid "Show in lists" msgstr "" -#: pretix/base/models/event.py:602 +#: pretix/base/models/event.py:601 msgid "" "If selected, this event will show up publicly on the list of events for your " "organizer account." msgstr "" -#: pretix/base/models/event.py:606 pretix/base/models/event.py:1503 +#: pretix/base/models/event.py:605 pretix/base/models/event.py:1510 #: pretix/control/forms/subevents.py:100 msgid "" "Optional. No products will be sold after this date. If you do not set this " "value, the presale will end after the end date of your event." msgstr "" -#: pretix/base/models/event.py:612 pretix/base/models/event.py:1509 +#: pretix/base/models/event.py:611 pretix/base/models/event.py:1516 #: pretix/control/forms/subevents.py:94 msgid "Optional. No products will be sold before this date." msgstr "" -#: pretix/base/models/event.py:621 +#: pretix/base/models/event.py:620 msgid "This event is remote or partially remote." msgstr "" -#: pretix/base/models/event.py:622 +#: pretix/base/models/event.py:621 msgid "" "This will be used to let users know if the event is in a different timezone " "and let’s us calculate users’ local times." msgstr "" -#: pretix/base/models/event.py:642 pretix/control/navigation.py:65 +#: pretix/base/models/event.py:641 pretix/base/models/organizer.py:97 +#: pretix/control/navigation.py:65 pretix/control/navigation.py:499 msgid "Plugins" msgstr "" -#: pretix/base/models/event.py:649 pretix/base/pdf.py:229 -#: pretix/control/forms/event.py:274 pretix/control/forms/filter.py:1677 +#: pretix/base/models/event.py:648 pretix/base/pdf.py:238 +#: pretix/control/forms/event.py:273 pretix/control/forms/filter.py:1675 #: pretix/control/templates/pretixcontrol/event/index.html:13 #: pretix/control/templates/pretixcontrol/events/index.html:114 #: pretix/control/templates/pretixcontrol/organizers/detail.html:90 -#: pretix/control/views/dashboards.py:543 +#: pretix/control/views/dashboards.py:547 #: pretix/presale/templates/pretixpresale/event/index.html:33 #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:7 #: pretix/presale/views/widget.py:700 msgid "Event series" msgstr "" -#: pretix/base/models/event.py:653 pretix/base/models/event.py:1537 +#: pretix/base/models/event.py:652 pretix/base/models/event.py:1544 msgid "Seating plan" msgstr "" -#: pretix/base/models/event.py:660 pretix/base/models/items.py:675 +#: pretix/base/models/event.py:659 pretix/base/models/items.py:675 msgid "Sell on all sales channels" msgstr "" -#: pretix/base/models/event.py:665 pretix/base/models/items.py:680 +#: pretix/base/models/event.py:664 pretix/base/models/items.py:680 #: pretix/base/models/items.py:1230 pretix/base/payment.py:474 msgid "Restrict to specific sales channels" msgstr "" -#: pretix/base/models/event.py:673 pretix/control/navigation.py:344 -#: pretix/control/navigation.py:470 +#: pretix/base/models/event.py:672 pretix/control/navigation.py:344 +#: pretix/control/navigation.py:475 #: pretix/control/templates/pretixcontrol/events/index.html:5 #: pretix/control/templates/pretixcontrol/events/index.html:7 #: pretix/control/templates/pretixcontrol/organizers/devices.html:88 #: pretix/control/templates/pretixcontrol/organizers/teams.html:39 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:37 -#: pretix/control/views/organizer.py:1725 -#: pretix/plugins/reports/accountingreport.py:104 -#: pretix/plugins/reports/accountingreport.py:107 +#: pretix/control/views/organizer.py:1994 +#: pretix/plugins/reports/accountingreport.py:105 +#: pretix/plugins/reports/accountingreport.py:108 msgid "Events" msgstr "" -#: pretix/base/models/event.py:1316 +#: pretix/base/models/event.py:1315 msgid "" "You have configured at least one paid product but have not enabled any " "payment methods." msgstr "" -#: pretix/base/models/event.py:1319 +#: pretix/base/models/event.py:1318 msgid "" "You have configured at least one paid product but have not configured a " "currency." msgstr "" -#: pretix/base/models/event.py:1322 +#: pretix/base/models/event.py:1321 msgid "You need to configure at least one quota to sell anything." msgstr "" -#: pretix/base/models/event.py:1327 +#: pretix/base/models/event.py:1326 #, python-brace-format msgid "You need to fill the meta parameter \"{property}\"." msgstr "" -#: pretix/base/models/event.py:1434 +#: pretix/base/models/event.py:1441 msgid "" "Once created an event cannot change between an series and a single event." msgstr "" -#: pretix/base/models/event.py:1440 +#: pretix/base/models/event.py:1447 msgid "The event slug cannot be changed." msgstr "" -#: pretix/base/models/event.py:1443 +#: pretix/base/models/event.py:1450 msgid "This slug has already been used for a different event." msgstr "" -#: pretix/base/models/event.py:1449 +#: pretix/base/models/event.py:1456 msgid "The event cannot end before it starts." msgstr "" -#: pretix/base/models/event.py:1455 +#: pretix/base/models/event.py:1462 msgid "The event's presale cannot end before it starts." msgstr "" -#: pretix/base/models/event.py:1485 +#: pretix/base/models/event.py:1492 msgid "" "Only with this checkbox enabled, this date is visible in the frontend to " "users." msgstr "" -#: pretix/base/models/event.py:1489 +#: pretix/base/models/event.py:1496 msgid "" "If selected, this event will show up publicly on the list of dates for your " "event." msgstr "" -#: pretix/base/models/event.py:1534 pretix/base/settings.py:3064 +#: pretix/base/models/event.py:1541 pretix/base/settings.py:3116 msgid "Frontpage text" msgstr "" -#: pretix/base/models/event.py:1551 +#: pretix/base/models/event.py:1558 msgid "Date in event series" msgstr "" -#: pretix/base/models/event.py:1552 +#: pretix/base/models/event.py:1559 msgid "Dates in event series" msgstr "" -#: pretix/base/models/event.py:1697 +#: pretix/base/models/event.py:1704 msgid "One or more variations do not belong to this event." msgstr "" -#: pretix/base/models/event.py:1727 pretix/base/models/items.py:2236 +#: pretix/base/models/event.py:1734 pretix/base/models/items.py:2236 msgid "Can not contain spaces or special characters except underscores" msgstr "" -#: pretix/base/models/event.py:1732 pretix/base/models/items.py:2241 +#: pretix/base/models/event.py:1739 pretix/base/models/items.py:2241 msgid "The property name may only contain letters, numbers and underscores." msgstr "" -#: pretix/base/models/event.py:1737 +#: pretix/base/models/event.py:1744 msgid "Default value" msgstr "" -#: pretix/base/models/event.py:1739 +#: pretix/base/models/event.py:1746 #: pretix/control/templates/pretixcontrol/organizers/properties.html:50 msgid "Can only be changed by organizer-level administrators" msgstr "" -#: pretix/base/models/event.py:1741 +#: pretix/base/models/event.py:1748 msgid "Required for events" msgstr "" -#: pretix/base/models/event.py:1742 +#: pretix/base/models/event.py:1749 msgid "" "If checked, an event can only be taken live if the property is set. In event " "series, its always optional to set a value for individual dates" msgstr "" -#: pretix/base/models/event.py:1748 pretix/base/models/items.py:2253 +#: pretix/base/models/event.py:1755 pretix/base/models/items.py:2253 msgid "Valid values" msgstr "" -#: pretix/base/models/event.py:1751 +#: pretix/base/models/event.py:1758 #: pretix/control/templates/pretixcontrol/organizers/properties.html:45 msgid "Show filter option to customers" msgstr "" -#: pretix/base/models/event.py:1752 +#: pretix/base/models/event.py:1759 msgid "" "This field will be shown to filter events in the public event list and " "calendar." msgstr "" -#: pretix/base/models/event.py:1755 pretix/control/forms/organizer.py:269 +#: pretix/base/models/event.py:1762 pretix/control/forms/organizer.py:269 #: pretix/control/forms/organizer.py:273 msgid "Public name" msgstr "" -#: pretix/base/models/event.py:1759 +#: pretix/base/models/event.py:1766 #: pretix/control/templates/pretixcontrol/organizers/properties.html:40 msgid "Can be used for filtering" msgstr "" -#: pretix/base/models/event.py:1760 +#: pretix/base/models/event.py:1767 msgid "" "This field will be shown to filter events or reports in the backend, and it " "can also be used for hidden filter parameters in the frontend (e.g. using " "the widget)." msgstr "" -#: pretix/base/models/event.py:1770 +#: pretix/base/models/event.py:1777 msgid "A property can either be required or have a default value, not both." msgstr "" -#: pretix/base/models/event.py:1850 pretix/base/models/organizer.py:516 +#: pretix/base/models/event.py:1857 pretix/base/models/organizer.py:582 msgid "Link text" msgstr "" -#: pretix/base/models/event.py:1853 pretix/base/models/organizer.py:519 +#: pretix/base/models/event.py:1860 pretix/base/models/organizer.py:585 msgid "Link URL" msgstr "" #: pretix/base/models/exports.py:42 pretix/control/navigation.py:229 -#: pretix/control/navigation.py:650 +#: pretix/control/navigation.py:662 msgid "Export" msgstr "" @@ -4385,7 +4774,8 @@ msgid "Additional recipients" msgstr "" #: pretix/base/models/exports.py:61 pretix/base/models/exports.py:66 -#: pretix/base/models/exports.py:71 +#: pretix/base/models/exports.py:71 pretix/control/forms/event.py:988 +#: pretix/control/forms/organizer.py:586 msgid "You can specify multiple recipients separated by commas." msgstr "" @@ -4397,20 +4787,20 @@ msgstr "" msgid "Additional recipients (Bcc)" msgstr "" -#: pretix/base/models/exports.py:74 pretix/control/forms/event.py:1101 -#: pretix/control/forms/event.py:1175 pretix/control/forms/event.py:1185 -#: pretix/control/forms/event.py:1195 pretix/control/forms/orders.py:720 -#: pretix/control/forms/orders.py:942 pretix/control/forms/orders.py:969 -#: pretix/control/forms/organizer.py:604 pretix/control/forms/organizer.py:614 -#: pretix/control/forms/organizer.py:624 pretix/control/forms/vouchers.py:273 -#: pretix/plugins/sendmail/forms.py:57 pretix/plugins/sendmail/forms.py:73 -#: pretix/plugins/sendmail/models.py:248 +#: pretix/base/models/exports.py:74 pretix/control/forms/event.py:1094 +#: pretix/control/forms/event.py:1168 pretix/control/forms/event.py:1178 +#: pretix/control/forms/event.py:1188 pretix/control/forms/event.py:1203 +#: pretix/control/forms/orders.py:730 pretix/control/forms/orders.py:952 +#: pretix/control/forms/orders.py:979 pretix/control/forms/organizer.py:607 +#: pretix/control/forms/organizer.py:617 pretix/control/forms/organizer.py:627 +#: pretix/control/forms/vouchers.py:282 pretix/plugins/sendmail/forms.py:57 +#: pretix/plugins/sendmail/forms.py:73 pretix/plugins/sendmail/models.py:248 msgid "Subject" msgstr "" -#: pretix/base/models/exports.py:78 pretix/control/forms/orders.py:759 -#: pretix/control/forms/orders.py:782 pretix/control/forms/orders.py:950 -#: pretix/control/forms/orders.py:977 pretix/control/forms/vouchers.py:279 +#: pretix/base/models/exports.py:78 pretix/control/forms/orders.py:769 +#: pretix/control/forms/orders.py:792 pretix/control/forms/orders.py:960 +#: pretix/control/forms/orders.py:987 pretix/control/forms/vouchers.py:288 #: pretix/plugins/sendmail/forms.py:58 pretix/plugins/sendmail/forms.py:78 #: pretix/plugins/sendmail/models.py:249 msgid "Message" @@ -4447,13 +4837,38 @@ msgstr "" msgid "Manual transaction" msgstr "" -#: pretix/base/models/invoices.py:185 +#: pretix/base/models/invoices.py:120 +msgid "pending transmission" +msgstr "" + +#: pretix/base/models/invoices.py:121 +msgid "currently being transmitted" +msgstr "" + +#: pretix/base/models/invoices.py:122 +msgid "transmitted" +msgstr "" + +#: pretix/base/models/invoices.py:123 pretix/plugins/sendmail/models.py:52 +msgid "failed" +msgstr "" + +#: pretix/base/models/invoices.py:124 +#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:56 +msgid "unknown" +msgstr "" + +#: pretix/base/models/invoices.py:125 +msgid "not transmitted due to test mode" +msgstr "" + +#: pretix/base/models/invoices.py:217 #, python-format msgctxt "invoice" msgid "Tax ID: %s" msgstr "" -#: pretix/base/models/invoices.py:191 pretix/base/services/invoices.py:139 +#: pretix/base/models/invoices.py:223 pretix/base/services/invoices.py:148 #, python-format msgctxt "invoice" msgid "VAT-ID: %s" @@ -4484,15 +4899,15 @@ msgid "" msgstr "" #: pretix/base/models/items.py:114 pretix/base/models/items.py:159 -#: pretix/control/forms/item.py:99 +#: pretix/control/forms/item.py:97 msgid "Normal category" msgstr "" -#: pretix/base/models/items.py:115 pretix/control/forms/item.py:112 +#: pretix/base/models/items.py:115 pretix/control/forms/item.py:110 msgid "Normal + cross-selling category" msgstr "" -#: pretix/base/models/items.py:116 pretix/control/forms/item.py:107 +#: pretix/base/models/items.py:116 pretix/control/forms/item.py:105 msgid "Cross-selling category" msgstr "" @@ -4559,12 +4974,12 @@ msgstr "" msgid "Dynamic validity" msgstr "" -#: pretix/base/models/items.py:444 pretix/control/forms/item.py:667 +#: pretix/base/models/items.py:444 pretix/control/forms/item.py:668 #: pretix/control/templates/pretixcontrol/subevents/fragment_unavail_mode_indicator.html:3 msgid "Hide product if unavailable" msgstr "" -#: pretix/base/models/items.py:445 pretix/control/forms/item.py:668 +#: pretix/base/models/items.py:445 pretix/control/forms/item.py:669 #: pretix/control/templates/pretixcontrol/subevents/fragment_unavail_mode_indicator.html:5 msgid "Show product with info on why it’s unavailable" msgstr "" @@ -4647,8 +5062,8 @@ msgstr "" msgid "This will only work if waiting lists are enabled for this event." msgstr "" -#: pretix/base/models/items.py:548 pretix/base/settings.py:1360 -#: pretix/control/forms/event.py:1681 +#: pretix/base/models/items.py:548 pretix/base/settings.py:1398 +#: pretix/control/forms/event.py:1690 msgid "Show number of tickets left" msgstr "" @@ -4656,7 +5071,7 @@ msgstr "" msgid "Publicly show how many tickets are still available." msgstr "" -#: pretix/base/models/items.py:556 pretix/control/forms/item.py:632 +#: pretix/base/models/items.py:556 pretix/control/forms/item.py:633 msgid "Product picture" msgstr "" @@ -4812,7 +5227,7 @@ msgid "" "change but keep their current validity." msgstr "" -#: pretix/base/models/items.py:738 pretix/control/forms/item.py:735 +#: pretix/base/models/items.py:738 pretix/control/forms/item.py:736 msgid "Start of validity" msgstr "" @@ -4878,10 +5293,10 @@ msgid "" msgstr "" #: pretix/base/models/items.py:795 pretix/base/models/items.py:1702 -#: pretix/control/forms/filter.py:421 pretix/control/forms/filter.py:1895 -#: pretix/control/forms/item.py:278 pretix/control/navigation.py:138 +#: pretix/control/forms/filter.py:421 pretix/control/forms/filter.py:1891 +#: pretix/control/forms/item.py:276 pretix/control/navigation.py:138 #: pretix/control/navigation.py:147 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:104 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:111 #: pretix/control/templates/pretixcontrol/items/base.html:3 #: pretix/control/templates/pretixcontrol/items/discounts.html:60 #: pretix/control/templates/pretixcontrol/items/index.html:5 @@ -4892,6 +5307,7 @@ msgstr "" #: pretix/plugins/autocheckin/models.py:72 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:31 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:32 +#: pretix/presale/templates/pretixpresale/event/index.html:221 msgid "Products" msgstr "" @@ -4955,7 +5371,7 @@ msgid "" "only available to specific groups." msgstr "" -#: pretix/base/models/items.py:1195 pretix/control/navigation.py:579 +#: pretix/base/models/items.py:1195 pretix/control/navigation.py:591 #: pretix/control/templates/pretixcontrol/organizers/membershiptypes.html:4 #: pretix/control/templates/pretixcontrol/organizers/membershiptypes.html:6 msgid "Membership types" @@ -5111,7 +5527,7 @@ msgid "Country code (ISO 3166-1 alpha-2)" msgstr "" #: pretix/base/models/items.py:1681 pretix/base/models/items.py:1957 -#: pretix/base/models/organizer.py:543 +#: pretix/base/models/organizer.py:609 msgid "" "The identifier may only contain letters, numbers, dots, dashes, and " "underscores." @@ -5259,6 +5675,7 @@ msgid "Answer" msgstr "" #: pretix/base/models/items.py:1985 +#, python-brace-format msgid "The identifier \"{}\" is already used for a different option." msgstr "" @@ -5270,22 +5687,22 @@ msgstr "" msgid "Question options" msgstr "" -#: pretix/base/models/items.py:2074 pretix/control/forms/event.py:1715 +#: pretix/base/models/items.py:2074 pretix/control/forms/event.py:1724 #: pretix/control/templates/pretixcontrol/items/quotas.html:56 msgid "Total capacity" msgstr "" -#: pretix/base/models/items.py:2076 pretix/control/forms/item.py:455 +#: pretix/base/models/items.py:2076 pretix/control/forms/item.py:456 msgid "Leave empty for an unlimited number of tickets." msgstr "" #: pretix/base/models/items.py:2080 pretix/base/models/orders.py:1489 -#: pretix/base/models/orders.py:2986 +#: pretix/base/models/orders.py:2997 #: pretix/control/templates/pretixcontrol/checkin/index.html:97 msgid "Item" msgstr "" -#: pretix/base/models/items.py:2088 pretix/control/forms/item.py:914 +#: pretix/base/models/items.py:2088 pretix/control/forms/item.py:915 #: pretix/plugins/autocheckin/models.py:74 msgid "Variations" msgstr "" @@ -5347,7 +5764,7 @@ msgid "" "list." msgstr "" -#: pretix/base/models/items.py:2212 pretix/base/models/waitinglist.py:305 +#: pretix/base/models/items.py:2212 pretix/base/models/waitinglist.py:308 msgid "Subevent cannot be null for event series." msgstr "" @@ -5400,7 +5817,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:41 #: pretix/control/templates/pretixcontrol/orders/overview.html:77 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:78 -#: pretix/plugins/reports/exporters.py:376 +#: pretix/plugins/reports/exporters.py:387 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:28 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:34 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:44 @@ -5418,11 +5835,11 @@ msgid "pending" msgstr "" #: pretix/base/models/orders.py:203 pretix/base/payment.py:568 -#: pretix/base/services/invoices.py:475 +#: pretix/base/services/invoices.py:486 msgid "paid" msgstr "" -#: pretix/base/models/orders.py:204 pretix/control/forms/filter.py:1573 +#: pretix/base/models/orders.py:204 pretix/control/forms/filter.py:1571 #: pretix/control/templates/pretixcontrol/organizers/reusable_medium.html:37 msgid "expired" msgstr "" @@ -5437,7 +5854,7 @@ msgstr "" msgid "Total amount" msgstr "" -#: pretix/base/models/orders.py:273 pretix/base/models/vouchers.py:293 +#: pretix/base/models/orders.py:273 pretix/base/models/vouchers.py:296 msgid "" "The text entered in this field will not be visible to the user and is " "available for your convenience." @@ -5470,7 +5887,7 @@ msgid "API meta information" msgstr "" #: pretix/base/models/orders.py:414 pretix/plugins/sendmail/forms.py:236 -#: pretix/plugins/sendmail/forms.py:391 pretix/plugins/sendmail/views.py:269 +#: pretix/plugins/sendmail/forms.py:389 pretix/plugins/sendmail/views.py:269 msgid "approval pending" msgstr "" @@ -5557,100 +5974,99 @@ msgctxt "payment_state" msgid "refunded" msgstr "" -#: pretix/base/models/orders.py:1756 pretix/base/models/orders.py:2170 -#: pretix/base/shredder.py:629 +#: pretix/base/models/orders.py:1756 pretix/base/models/orders.py:2181 +#: pretix/base/shredder.py:633 msgid "Payment information" msgstr "" -#: pretix/base/models/orders.py:2111 +#: pretix/base/models/orders.py:2122 msgctxt "refund_state" msgid "started externally" msgstr "" -#: pretix/base/models/orders.py:2112 +#: pretix/base/models/orders.py:2123 msgctxt "refund_state" msgid "created" msgstr "" -#: pretix/base/models/orders.py:2113 +#: pretix/base/models/orders.py:2124 msgctxt "refund_state" msgid "in transit" msgstr "" -#: pretix/base/models/orders.py:2114 +#: pretix/base/models/orders.py:2125 msgctxt "refund_state" msgid "done" msgstr "" -#: pretix/base/models/orders.py:2115 +#: pretix/base/models/orders.py:2126 msgctxt "refund_state" msgid "failed" msgstr "" -#: pretix/base/models/orders.py:2117 +#: pretix/base/models/orders.py:2128 msgctxt "refund_state" msgid "canceled" msgstr "" -#: pretix/base/models/orders.py:2125 +#: pretix/base/models/orders.py:2136 msgctxt "refund_source" msgid "Organizer" msgstr "" -#: pretix/base/models/orders.py:2126 +#: pretix/base/models/orders.py:2137 msgctxt "refund_source" msgid "Customer" msgstr "" -#: pretix/base/models/orders.py:2127 +#: pretix/base/models/orders.py:2138 msgctxt "refund_source" msgid "External" msgstr "" -#: pretix/base/models/orders.py:2165 +#: pretix/base/models/orders.py:2176 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:198 msgid "Refund reason" msgstr "" -#: pretix/base/models/orders.py:2166 +#: pretix/base/models/orders.py:2177 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:199 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:201 msgid "" "May be shown to the end user or used e.g. as part of a payment reference." msgstr "" -#: pretix/base/models/orders.py:2286 +#: pretix/base/models/orders.py:2297 msgid "Service fee" msgstr "" -#: pretix/base/models/orders.py:2287 +#: pretix/base/models/orders.py:2298 msgid "Payment fee" msgstr "" -#: pretix/base/models/orders.py:2288 +#: pretix/base/models/orders.py:2299 msgid "Shipping fee" msgstr "" -#: pretix/base/models/orders.py:2289 +#: pretix/base/models/orders.py:2300 #: pretix/control/templates/pretixcontrol/order/index.html:157 msgid "Cancellation fee" msgstr "" -#: pretix/base/models/orders.py:2290 +#: pretix/base/models/orders.py:2301 msgid "Insurance fee" msgstr "" -#: pretix/base/models/orders.py:2291 +#: pretix/base/models/orders.py:2302 msgid "Late fee" msgstr "" -#: pretix/base/models/orders.py:2292 +#: pretix/base/models/orders.py:2303 msgid "Other fees" msgstr "" -#: pretix/base/models/orders.py:2293 pretix/base/payment.py:1372 +#: pretix/base/models/orders.py:2304 pretix/base/payment.py:1372 #: pretix/base/payment.py:1419 pretix/base/settings.py:992 -#: pretix/control/forms/organizer.py:830 #: pretix/control/templates/pretixcontrol/items/index.html:107 #: pretix/control/templates/pretixcontrol/order/index.html:152 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:383 @@ -5659,7 +6075,7 @@ msgstr "" msgid "Gift card" msgstr "" -#: pretix/base/models/orders.py:2298 +#: pretix/base/models/orders.py:2309 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:74 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:115 #: pretix/control/views/vouchers.py:120 @@ -5667,192 +6083,197 @@ msgstr "" msgid "Value" msgstr "" -#: pretix/base/models/orders.py:2546 +#: pretix/base/models/orders.py:2557 msgid "Order position" msgstr "" -#: pretix/base/models/orders.py:3091 +#: pretix/base/models/orders.py:3102 msgid "Cart ID (e.g. session key)" msgstr "" -#: pretix/base/models/orders.py:3102 +#: pretix/base/models/orders.py:3113 msgid "Limit for extending expiration date" msgstr "" -#: pretix/base/models/orders.py:3131 +#: pretix/base/models/orders.py:3142 msgid "Cart position" msgstr "" -#: pretix/base/models/orders.py:3132 +#: pretix/base/models/orders.py:3143 msgid "Cart positions" msgstr "" -#: pretix/base/models/orders.py:3268 +#: pretix/base/models/orders.py:3279 msgid "Business customer" msgstr "" -#: pretix/base/models/orders.py:3284 +#: pretix/base/models/orders.py:3295 msgid "This reference will be printed on your invoice for your convenience." msgstr "" -#: pretix/base/models/orders.py:3468 +#: pretix/base/models/orders.py:3422 +msgid "Transmission type" +msgstr "" + +#: pretix/base/models/orders.py:3520 #: pretix/plugins/badges/templates/pretixplugins/badges/control_order_position_buttons.html:9 msgid "Badge" msgstr "" -#: pretix/base/models/orders.py:3469 pretix/base/pdf.py:1113 -#: pretix/control/forms/organizer.py:781 pretix/control/forms/organizer.py:817 +#: pretix/base/models/orders.py:3521 pretix/base/pdf.py:1122 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:66 #: pretix/plugins/ticketoutputpdf/ticketoutput.py:113 msgid "Ticket" msgstr "" -#: pretix/base/models/orders.py:3470 +#: pretix/base/models/orders.py:3522 msgid "Certificate" msgstr "" -#: pretix/base/models/orders.py:3471 pretix/control/views/event.py:393 -#: pretix/control/views/event.py:398 +#: pretix/base/models/orders.py:3523 pretix/control/views/event.py:393 +#: pretix/control/views/event.py:398 pretix/control/views/organizer.py:649 +#: pretix/control/views/organizer.py:654 msgid "Other" msgstr "" -#: pretix/base/models/organizer.py:79 +#: pretix/base/models/organizer.py:81 msgid "" "Should be short, only contain lowercase letters, numbers, dots, and dashes. " "Every slug can only be used once. This is being used in URLs to refer to " "your organizer accounts and your events." msgstr "" -#: pretix/base/models/organizer.py:97 pretix/control/navigation.py:350 +#: pretix/base/models/organizer.py:103 pretix/control/navigation.py:350 #: pretix/control/templates/pretixcontrol/oauth/authorized.html:19 #: pretix/control/templates/pretixcontrol/organizers/index.html:6 #: pretix/control/templates/pretixcontrol/organizers/index.html:8 msgid "Organizers" msgstr "" -#: pretix/base/models/organizer.py:284 +#: pretix/base/models/organizer.py:350 #: pretix/control/templates/pretixcontrol/organizers/teams.html:35 msgid "Team name" msgstr "" -#: pretix/base/models/organizer.py:285 +#: pretix/base/models/organizer.py:351 #: pretix/control/templates/pretixcontrol/organizers/team_members.html:13 msgid "Team members" msgstr "" -#: pretix/base/models/organizer.py:289 +#: pretix/base/models/organizer.py:355 msgid "Require all members of this team to use two-factor authentication" msgstr "" -#: pretix/base/models/organizer.py:290 +#: pretix/base/models/organizer.py:356 msgid "" "If you turn this on, all members of the team will be required to either set " "up two-factor authentication or leave the team. The setting may take a few " "minutes to become effective for all users." msgstr "" -#: pretix/base/models/organizer.py:297 +#: pretix/base/models/organizer.py:363 msgid "Can create events" msgstr "" -#: pretix/base/models/organizer.py:301 +#: pretix/base/models/organizer.py:367 msgid "Can change teams and permissions" msgstr "" -#: pretix/base/models/organizer.py:305 +#: pretix/base/models/organizer.py:371 msgid "Can change organizer settings" msgstr "" -#: pretix/base/models/organizer.py:306 +#: pretix/base/models/organizer.py:372 msgid "" "Someone with this setting can get access to most data of all of your events, " "i.e. via privacy reports, so be careful who you add to this team!" msgstr "" -#: pretix/base/models/organizer.py:311 +#: pretix/base/models/organizer.py:377 msgid "Can manage customer accounts" msgstr "" -#: pretix/base/models/organizer.py:315 +#: pretix/base/models/organizer.py:381 msgid "Can manage reusable media" msgstr "" -#: pretix/base/models/organizer.py:319 +#: pretix/base/models/organizer.py:385 msgid "Can manage gift cards" msgstr "" -#: pretix/base/models/organizer.py:323 +#: pretix/base/models/organizer.py:389 msgid "Can change event settings" msgstr "" -#: pretix/base/models/organizer.py:327 +#: pretix/base/models/organizer.py:393 msgid "Can change product settings" msgstr "" -#: pretix/base/models/organizer.py:331 +#: pretix/base/models/organizer.py:397 msgid "Can view orders" msgstr "" -#: pretix/base/models/organizer.py:335 +#: pretix/base/models/organizer.py:401 msgid "Can change orders" msgstr "" -#: pretix/base/models/organizer.py:339 +#: pretix/base/models/organizer.py:405 msgid "Can perform check-ins" msgstr "" -#: pretix/base/models/organizer.py:340 +#: pretix/base/models/organizer.py:406 msgid "" "This includes searching for attendees, which can be used to obtain personal " "information about attendees. Users with \"can change orders\" can also " "perform check-ins." msgstr "" -#: pretix/base/models/organizer.py:345 +#: pretix/base/models/organizer.py:411 msgid "Can view vouchers" msgstr "" -#: pretix/base/models/organizer.py:349 +#: pretix/base/models/organizer.py:415 msgid "Can change vouchers" msgstr "" -#: pretix/base/models/organizer.py:353 +#: pretix/base/models/organizer.py:419 #, python-format msgid "%(name)s on %(object)s" msgstr "" -#: pretix/base/models/organizer.py:385 -#: pretix/control/templates/pretixcontrol/events/create_basics.html:64 +#: pretix/base/models/organizer.py:451 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:67 msgid "Team" msgstr "" -#: pretix/base/models/organizer.py:386 pretix/control/navigation.py:527 +#: pretix/base/models/organizer.py:452 pretix/control/navigation.py:539 #: pretix/control/templates/pretixcontrol/organizers/teams.html:6 msgid "Teams" msgstr "" -#: pretix/base/models/organizer.py:406 +#: pretix/base/models/organizer.py:472 #, python-brace-format msgid "Invite to team '{team}' for '{email}'" msgstr "" -#: pretix/base/models/organizer.py:538 +#: pretix/base/models/organizer.py:604 #: pretix/control/templates/pretixcontrol/organizers/channels.html:23 msgid "Identifier" msgstr "" -#: pretix/base/models/organizer.py:548 +#: pretix/base/models/organizer.py:614 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:54 #: pretix/control/templates/pretixcontrol/items/questions.html:22 msgid "Type" msgstr "" #: pretix/base/models/seating.py:45 pretix/base/models/tax.py:305 -#: pretix/base/pdf.py:1269 +#: pretix/base/pdf.py:1278 msgid "Your layout file is not a valid JSON file." msgstr "" #: pretix/base/models/seating.py:54 pretix/base/models/seating.py:78 +#, python-brace-format msgid "Your layout file is not a valid seating plan. Error message: {}" msgstr "" @@ -6013,6 +6434,7 @@ msgid "" msgstr "" #: pretix/base/models/tax.py:314 +#, python-brace-format msgid "Your set of rules is not valid. Error message: {}" msgstr "" @@ -6024,7 +6446,7 @@ msgstr "" msgid "Should be short, e.g. \"VAT\"" msgstr "" -#: pretix/base/models/tax.py:330 pretix/control/forms/event.py:1513 +#: pretix/base/models/tax.py:330 pretix/control/forms/event.py:1522 #: pretix/control/templates/pretixcontrol/order/transactions.html:22 msgid "Tax code" msgstr "" @@ -6080,43 +6502,43 @@ msgid "" "will not apply in, if configured above." msgstr "" -#: pretix/base/models/tax.py:412 +#: pretix/base/models/tax.py:423 msgid "You need to set your home country to use the reverse charge feature." msgstr "" -#: pretix/base/models/tax.py:416 pretix/control/forms/event.py:1560 +#: pretix/base/models/tax.py:427 pretix/control/forms/event.py:1569 msgid "" "A combination of this tax code with a non-zero tax rate does not make sense." msgstr "" -#: pretix/base/models/tax.py:421 pretix/control/forms/event.py:1564 +#: pretix/base/models/tax.py:432 pretix/control/forms/event.py:1573 msgid "" "A combination of this tax code with a zero tax rate does not make sense." msgstr "" -#: pretix/base/models/tax.py:426 +#: pretix/base/models/tax.py:437 #, python-brace-format msgid "incl. {rate}% {name}" msgstr "" -#: pretix/base/models/tax.py:428 +#: pretix/base/models/tax.py:439 #, python-brace-format msgid "plus {rate}% {name}" msgstr "" -#: pretix/base/models/tax.py:430 -#: pretix/control/templates/pretixcontrol/event/tax_index.html:46 +#: pretix/base/models/tax.py:441 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:63 msgid "reverse charge enabled" msgstr "" -#: pretix/base/models/tax.py:568 +#: pretix/base/models/tax.py:579 msgctxt "invoice" msgid "" "Reverse Charge: According to Article 194, 196 of Council Directive 2006/112/" "EEC, VAT liability rests with the service recipient." msgstr "" -#: pretix/base/models/tax.py:574 +#: pretix/base/models/tax.py:585 msgctxt "invoice" msgid "VAT liability rests with the service recipient." msgstr "" @@ -6137,15 +6559,15 @@ msgstr "" msgid "Reduce product price by (%)" msgstr "" -#: pretix/base/models/vouchers.py:197 +#: pretix/base/models/vouchers.py:200 msgid "Number of times this voucher can be redeemed." msgstr "" -#: pretix/base/models/vouchers.py:201 pretix/control/views/vouchers.py:120 +#: pretix/base/models/vouchers.py:204 pretix/control/views/vouchers.py:120 msgid "Redeemed" msgstr "" -#: pretix/base/models/vouchers.py:206 +#: pretix/base/models/vouchers.py:209 msgid "" "If set to more than one, the voucher must be redeemed for this many products " "when it is used for the first time. On later usages, it can also be used for " @@ -6154,132 +6576,132 @@ msgid "" "cancellations." msgstr "" -#: pretix/base/models/vouchers.py:214 +#: pretix/base/models/vouchers.py:217 msgid "" "This is the maximum monetary amount that will be discounted using this " "voucher across all usages. If this is sum reached, the voucher can no longer " "be used." msgstr "" -#: pretix/base/models/vouchers.py:227 +#: pretix/base/models/vouchers.py:230 msgid "" "If activated, this voucher will be substracted from the affected product's " "quotas, such that it is guaranteed that anyone with this voucher code does " "receive a ticket." msgstr "" -#: pretix/base/models/vouchers.py:235 +#: pretix/base/models/vouchers.py:238 msgid "" "If activated, a holder of this voucher code can buy tickets, even if there " "are none left." msgstr "" -#: pretix/base/models/vouchers.py:254 pretix/control/forms/vouchers.py:69 +#: pretix/base/models/vouchers.py:257 pretix/control/forms/vouchers.py:69 msgid "" "This product is added to the user's cart if the voucher is redeemed. Instead " "of a specific product, you can also select a quota. In this case, all " "products assigned to this quota can be selected." msgstr "" -#: pretix/base/models/vouchers.py:265 +#: pretix/base/models/vouchers.py:268 msgid "This variation of the product select above is being used." msgstr "" -#: pretix/base/models/vouchers.py:274 +#: pretix/base/models/vouchers.py:277 msgid "" "If enabled, the voucher is valid for any product affected by this quota." msgstr "" -#: pretix/base/models/vouchers.py:281 +#: pretix/base/models/vouchers.py:284 msgid "Specific seat" msgstr "" -#: pretix/base/models/vouchers.py:288 +#: pretix/base/models/vouchers.py:291 msgid "" "You can use this field to group multiple vouchers together. If you enter the " "same value for multiple vouchers, you can get statistics on how many of them " "have been redeemed etc." msgstr "" -#: pretix/base/models/vouchers.py:313 pretix/control/navigation.py:267 +#: pretix/base/models/vouchers.py:316 pretix/control/navigation.py:267 #: pretix/control/templates/pretixcontrol/vouchers/index.html:6 #: pretix/control/templates/pretixcontrol/vouchers/index.html:8 msgid "Vouchers" msgstr "" -#: pretix/base/models/vouchers.py:339 +#: pretix/base/models/vouchers.py:342 msgid "You cannot select a quota that belongs to a different event." msgstr "" -#: pretix/base/models/vouchers.py:341 +#: pretix/base/models/vouchers.py:344 msgid "You cannot select a quota and a specific product at the same time." msgstr "" -#: pretix/base/models/vouchers.py:344 +#: pretix/base/models/vouchers.py:347 msgid "" "You cannot select a product that is only available as an add-on product or " "as part of a bundle, since vouchers cannot be applied to add-on products or " "bundled products." msgstr "" -#: pretix/base/models/vouchers.py:348 +#: pretix/base/models/vouchers.py:351 msgid "You cannot select a product that belongs to a different event." msgstr "" -#: pretix/base/models/vouchers.py:350 pretix/base/models/vouchers.py:360 +#: pretix/base/models/vouchers.py:353 pretix/base/models/vouchers.py:363 msgid "" "You cannot select a variation without having selected a product that " "provides variations." msgstr "" -#: pretix/base/models/vouchers.py:353 +#: pretix/base/models/vouchers.py:356 msgid "This variation does not belong to this product." msgstr "" -#: pretix/base/models/vouchers.py:355 +#: pretix/base/models/vouchers.py:358 msgid "It is currently not possible to create vouchers for add-on products." msgstr "" -#: pretix/base/models/vouchers.py:357 pretix/base/models/vouchers.py:469 +#: pretix/base/models/vouchers.py:360 pretix/base/models/vouchers.py:472 msgid "" "You need to select a specific product or quota if this voucher should " "reserve tickets." msgstr "" -#: pretix/base/models/vouchers.py:367 +#: pretix/base/models/vouchers.py:370 #, python-format msgid "" "This voucher has already been redeemed %(redeemed)s times. You cannot reduce " "the maximum number of usages below this number." msgstr "" -#: pretix/base/models/vouchers.py:376 +#: pretix/base/models/vouchers.py:379 msgid "" "The maximum number of usages may not be lower than the minimum number of " "usages." msgstr "" -#: pretix/base/models/vouchers.py:382 pretix/base/models/vouchers.py:451 +#: pretix/base/models/vouchers.py:385 pretix/base/models/vouchers.py:454 msgid "" "If you want this voucher to block quota, you need to select a specific date." msgstr "" -#: pretix/base/models/vouchers.py:384 +#: pretix/base/models/vouchers.py:387 msgid "You can not select a subevent if your event is not an event series." msgstr "" -#: pretix/base/models/vouchers.py:482 +#: pretix/base/models/vouchers.py:485 msgid "" "You cannot create a voucher that blocks quota as the selected product or " "quota is currently sold out or completely reserved." msgstr "" -#: pretix/base/models/vouchers.py:504 +#: pretix/base/models/vouchers.py:507 #, python-brace-format msgid "The specified seat ID \"{id}\" does not exist for this event." msgstr "" -#: pretix/base/models/vouchers.py:508 +#: pretix/base/models/vouchers.py:511 #, python-brace-format msgid "" "The seat \"{id}\" is currently unavailable (blocked, already sold or a " @@ -6331,15 +6753,15 @@ msgstr "" msgid "Automatically created from waiting list entry for {email}" msgstr "" -#: pretix/base/models/waitinglist.py:297 +#: pretix/base/models/waitinglist.py:300 msgid "The selected item does not belong to this event." msgstr "" -#: pretix/base/models/waitinglist.py:299 +#: pretix/base/models/waitinglist.py:302 msgid "Please select a specific variation of this product." msgstr "" -#: pretix/base/models/waitinglist.py:317 +#: pretix/base/models/waitinglist.py:320 msgid "" "You are already on this waiting list! We will notify you as soon as we have " "a ticket available for you." @@ -6354,8 +6776,8 @@ msgid "Dates" msgstr "" #: pretix/base/notifications.py:200 -#: pretix/control/templates/pretixcontrol/order/index.html:678 -#: pretix/plugins/reports/accountingreport.py:317 +#: pretix/control/templates/pretixcontrol/order/index.html:730 +#: pretix/plugins/reports/accountingreport.py:318 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:442 msgid "Net total" msgstr "" @@ -6364,18 +6786,13 @@ msgstr "" msgid "Pending amount" msgstr "" -#: pretix/base/notifications.py:204 pretix/control/forms/filter.py:211 -#: pretix/control/forms/modelimport.py:81 -msgid "Order status" -msgstr "" - #: pretix/base/notifications.py:222 msgid "Purchased products" msgstr "" #: pretix/base/notifications.py:223 pretix/base/services/placeholders.py:384 #: pretix/base/services/placeholders.py:393 -#: pretix/base/templates/pretixbase/email/order_details.html:141 +#: pretix/base/templates/pretixbase/email/order_details.html:147 msgid "View order details" msgstr "" @@ -6659,14 +7076,14 @@ msgstr "" msgid "Manual payment" msgstr "" -#: pretix/base/payment.py:1219 pretix/plugins/banktransfer/payment.py:202 +#: pretix/base/payment.py:1219 pretix/plugins/banktransfer/payment.py:195 msgid "" "In test mode, you can just manually mark this order as paid in the backend " "after it has been created." msgstr "" #: pretix/base/payment.py:1240 pretix/base/payment.py:1427 -#: pretix/plugins/banktransfer/payment.py:156 +#: pretix/plugins/banktransfer/payment.py:149 msgid "Payment method name" msgstr "" @@ -6705,7 +7122,7 @@ msgid "" "the placeholders {order}, {amount}, {currency} and {amount_with_currency}." msgstr "" -#: pretix/base/payment.py:1267 pretix/plugins/banktransfer/payment.py:151 +#: pretix/base/payment.py:1267 pretix/plugins/banktransfer/payment.py:144 msgid "" "Create an invoice for orders using bank transfer immediately if the event is " "otherwise configured to create invoices after payment is completed." @@ -6715,7 +7132,7 @@ msgstr "" msgid "Offsetting" msgstr "" -#: pretix/base/payment.py:1332 pretix/control/views/orders.py:1266 +#: pretix/base/payment.py:1332 pretix/control/views/orders.py:1251 msgid "You entered an order that could not be found." msgstr "" @@ -6748,17 +7165,13 @@ msgstr "" msgid "Order position number" msgstr "" -#: pretix/base/pdf.py:116 -msgid "Order code and position number" -msgstr "" - -#: pretix/base/pdf.py:121 pretix/control/forms/event.py:1768 +#: pretix/base/pdf.py:121 pretix/control/forms/event.py:1777 #: pretix/control/templates/pretixcontrol/items/index.html:38 msgid "Product name" msgstr "" #: pretix/base/pdf.py:122 pretix/base/services/tickets.py:101 -#: pretix/control/views/event.py:844 pretix/control/views/pdf.py:94 +#: pretix/control/views/event.py:888 pretix/control/views/pdf.py:94 msgid "Sample product" msgstr "" @@ -6775,7 +7188,7 @@ msgid "Product description" msgstr "" #: pretix/base/pdf.py:132 pretix/base/services/tickets.py:102 -#: pretix/control/views/event.py:845 pretix/control/views/pdf.py:95 +#: pretix/control/views/event.py:889 pretix/control/views/pdf.py:95 msgid "Sample product description" msgstr "" @@ -6799,44 +7212,39 @@ msgstr "" msgid "Ticket category" msgstr "" -#: pretix/base/pdf.py:159 pretix/base/pdf.py:164 +#: pretix/base/pdf.py:159 pretix/base/pdf.py:164 pretix/base/pdf.py:173 msgid "123.45 EUR" msgstr "" #: pretix/base/pdf.py:163 -msgid "Price including add-ons" +msgid "Price including bundled products" msgstr "" -#: pretix/base/pdf.py:173 pretix/base/pdf.py:331 -#: pretix/base/services/invoices.py:476 +#: pretix/base/pdf.py:172 +msgid "Price including add-ons and bundled products" +msgstr "" + +#: pretix/base/pdf.py:182 pretix/base/pdf.py:340 +#: pretix/base/services/invoices.py:487 #: pretix/base/services/placeholders.py:571 #: pretix/base/services/placeholders.py:653 #: pretix/base/services/placeholders.py:669 -#: pretix/base/services/placeholders.py:678 pretix/control/views/event.py:846 +#: pretix/base/services/placeholders.py:678 pretix/control/views/event.py:890 msgid "John Doe" msgstr "" -#: pretix/base/pdf.py:177 -#: pretix/control/templates/pretixcontrol/order/index.html:543 -#: pretix/plugins/badges/exporters.py:496 -#: pretix/plugins/ticketoutputpdf/exporters.py:95 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:182 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:185 -msgid "Attendee company" -msgstr "" - -#: pretix/base/pdf.py:178 pretix/base/pdf.py:336 +#: pretix/base/pdf.py:187 pretix/base/pdf.py:345 #: pretix/base/services/tickets.py:119 pretix/control/views/pdf.py:110 #: pretix/control/views/pdf.py:116 pretix/control/views/pdf.py:123 #: pretix/control/views/pdf.py:128 msgid "Sample company" msgstr "" -#: pretix/base/pdf.py:182 +#: pretix/base/pdf.py:191 msgid "Full attendee address" msgstr "" -#: pretix/base/pdf.py:183 +#: pretix/base/pdf.py:192 msgid "" "John Doe\n" "Sample company\n" @@ -6845,361 +7253,379 @@ msgid "" "Atlantis" msgstr "" -#: pretix/base/pdf.py:187 +#: pretix/base/pdf.py:196 msgid "Attendee street" msgstr "" -#: pretix/base/pdf.py:192 +#: pretix/base/pdf.py:201 msgid "Attendee ZIP code" msgstr "" -#: pretix/base/pdf.py:197 +#: pretix/base/pdf.py:206 msgid "Attendee city" msgstr "" -#: pretix/base/pdf.py:202 +#: pretix/base/pdf.py:211 msgid "Attendee state" msgstr "" -#: pretix/base/pdf.py:207 +#: pretix/base/pdf.py:216 msgid "Attendee country" msgstr "" -#: pretix/base/pdf.py:219 +#: pretix/base/pdf.py:228 msgid "Pseudonymization ID (lead scanning)" msgstr "" -#: pretix/base/pdf.py:225 pretix/base/pdf.py:230 +#: pretix/base/pdf.py:234 pretix/base/pdf.py:239 msgid "Sample event name" msgstr "" -#: pretix/base/pdf.py:235 +#: pretix/base/pdf.py:244 msgid "May 31st, 2017" msgstr "" -#: pretix/base/pdf.py:239 +#: pretix/base/pdf.py:248 msgid "Event date range" msgstr "" -#: pretix/base/pdf.py:240 +#: pretix/base/pdf.py:249 msgid "May 31st – June 4th, 2017" msgstr "" -#: pretix/base/pdf.py:244 +#: pretix/base/pdf.py:253 msgid "Event begin date and time" msgstr "" -#: pretix/base/pdf.py:245 +#: pretix/base/pdf.py:254 msgid "2017-05-31 20:00" msgstr "" -#: pretix/base/pdf.py:252 +#: pretix/base/pdf.py:261 msgid "Event begin date" msgstr "" -#: pretix/base/pdf.py:253 pretix/base/pdf.py:279 pretix/base/pdf.py:388 -#: pretix/base/pdf.py:412 pretix/base/pdf.py:436 pretix/base/pdf.py:460 -#: pretix/base/pdf.py:517 pretix/base/pdf.py:522 +#: pretix/base/pdf.py:262 pretix/base/pdf.py:288 pretix/base/pdf.py:397 +#: pretix/base/pdf.py:421 pretix/base/pdf.py:445 pretix/base/pdf.py:469 +#: pretix/base/pdf.py:526 pretix/base/pdf.py:531 msgid "2017-05-31" msgstr "" -#: pretix/base/pdf.py:260 +#: pretix/base/pdf.py:269 msgid "Event begin time" msgstr "" -#: pretix/base/pdf.py:261 +#: pretix/base/pdf.py:270 msgid "20:00" msgstr "" -#: pretix/base/pdf.py:265 +#: pretix/base/pdf.py:274 msgid "Event begin weekday" msgstr "" -#: pretix/base/pdf.py:266 pretix/base/pdf.py:295 +#: pretix/base/pdf.py:275 pretix/base/pdf.py:304 #: pretix/base/services/checkin.py:362 pretix/control/forms/filter.py:1240 msgid "Friday" msgstr "" -#: pretix/base/pdf.py:270 +#: pretix/base/pdf.py:279 msgid "Event end date and time" msgstr "" -#: pretix/base/pdf.py:271 +#: pretix/base/pdf.py:280 msgid "2017-05-31 22:00" msgstr "" -#: pretix/base/pdf.py:287 +#: pretix/base/pdf.py:296 msgid "22:00" msgstr "" -#: pretix/base/pdf.py:294 +#: pretix/base/pdf.py:303 msgid "Event end weekday" msgstr "" -#: pretix/base/pdf.py:299 +#: pretix/base/pdf.py:308 msgid "Event admission date and time" msgstr "" -#: pretix/base/pdf.py:300 pretix/base/pdf.py:396 pretix/base/pdf.py:420 -#: pretix/base/pdf.py:444 pretix/base/pdf.py:468 pretix/base/pdf.py:511 +#: pretix/base/pdf.py:309 pretix/base/pdf.py:405 pretix/base/pdf.py:429 +#: pretix/base/pdf.py:453 pretix/base/pdf.py:477 pretix/base/pdf.py:520 msgid "2017-05-31 19:00" msgstr "" -#: pretix/base/pdf.py:307 +#: pretix/base/pdf.py:316 msgid "Event admission time" msgstr "" -#: pretix/base/pdf.py:308 pretix/base/pdf.py:404 pretix/base/pdf.py:428 -#: pretix/base/pdf.py:452 pretix/base/pdf.py:476 +#: pretix/base/pdf.py:317 pretix/base/pdf.py:413 pretix/base/pdf.py:437 +#: pretix/base/pdf.py:461 pretix/base/pdf.py:485 msgid "19:00" msgstr "" -#: pretix/base/pdf.py:315 +#: pretix/base/pdf.py:324 msgid "Event location" msgstr "" -#: pretix/base/pdf.py:316 pretix/base/settings.py:1134 +#: pretix/base/pdf.py:325 pretix/base/settings.py:1172 msgid "Random City" msgstr "" -#: pretix/base/pdf.py:335 -msgid "Invoice address company" -msgstr "" - -#: pretix/base/pdf.py:341 +#: pretix/base/pdf.py:350 msgid "Sesame Street 42" msgstr "" -#: pretix/base/pdf.py:346 +#: pretix/base/pdf.py:355 msgid "12345" msgstr "" -#: pretix/base/pdf.py:351 pretix/base/services/invoices.py:479 +#: pretix/base/pdf.py:360 pretix/base/services/invoices.py:490 msgid "Sample city" msgstr "" -#: pretix/base/pdf.py:355 +#: pretix/base/pdf.py:364 msgid "Invoice address state" msgstr "" -#: pretix/base/pdf.py:356 +#: pretix/base/pdf.py:365 msgid "Sample State" msgstr "" -#: pretix/base/pdf.py:361 +#: pretix/base/pdf.py:370 msgid "Atlantis" msgstr "" -#: pretix/base/pdf.py:365 +#: pretix/base/pdf.py:374 msgid "List of Add-Ons" msgstr "" -#: pretix/base/pdf.py:366 +#: pretix/base/pdf.py:375 msgid "" "Add-on 1\n" "2x Add-on 2" msgstr "" -#: pretix/base/pdf.py:372 pretix/control/forms/filter.py:1380 -#: pretix/control/forms/filter.py:1382 +#: pretix/base/pdf.py:381 pretix/control/forms/filter.py:1378 +#: pretix/control/forms/filter.py:1380 #: pretix/control/templates/pretixcontrol/organizers/index.html:42 msgid "Organizer name" msgstr "" -#: pretix/base/pdf.py:373 +#: pretix/base/pdf.py:382 msgid "Event organizer company" msgstr "" -#: pretix/base/pdf.py:377 +#: pretix/base/pdf.py:386 msgid "Organizer info text" msgstr "" -#: pretix/base/pdf.py:378 +#: pretix/base/pdf.py:387 msgid "Event organizer info text" msgstr "" -#: pretix/base/pdf.py:382 pretix/base/pdf.py:383 +#: pretix/base/pdf.py:391 pretix/base/pdf.py:392 msgid "Event info text" msgstr "" -#: pretix/base/pdf.py:387 +#: pretix/base/pdf.py:396 msgid "Printing date" msgstr "" -#: pretix/base/pdf.py:395 +#: pretix/base/pdf.py:404 msgid "Printing date and time" msgstr "" -#: pretix/base/pdf.py:403 +#: pretix/base/pdf.py:412 msgid "Printing time" msgstr "" -#: pretix/base/pdf.py:411 pretix/control/forms/item.py:737 +#: pretix/base/pdf.py:420 pretix/control/forms/item.py:738 msgid "Purchase date" msgstr "" -#: pretix/base/pdf.py:419 +#: pretix/base/pdf.py:428 msgid "Purchase date and time" msgstr "" -#: pretix/base/pdf.py:427 +#: pretix/base/pdf.py:436 msgid "Purchase time" msgstr "" -#: pretix/base/pdf.py:435 +#: pretix/base/pdf.py:444 msgid "Validity start date" msgstr "" -#: pretix/base/pdf.py:443 +#: pretix/base/pdf.py:452 msgid "Validity start date and time" msgstr "" -#: pretix/base/pdf.py:451 +#: pretix/base/pdf.py:460 msgid "Validity start time" msgstr "" -#: pretix/base/pdf.py:459 +#: pretix/base/pdf.py:468 msgid "Validity end date" msgstr "" -#: pretix/base/pdf.py:467 +#: pretix/base/pdf.py:476 msgid "Validity end date and time" msgstr "" -#: pretix/base/pdf.py:475 +#: pretix/base/pdf.py:484 msgid "Validity end time" msgstr "" -#: pretix/base/pdf.py:483 +#: pretix/base/pdf.py:492 msgid "Reusable Medium ID" msgstr "" -#: pretix/base/pdf.py:488 +#: pretix/base/pdf.py:497 msgid "Seat: Full name" msgstr "" -#: pretix/base/pdf.py:489 +#: pretix/base/pdf.py:498 msgid "Ground floor, Row 3, Seat 4" msgstr "" -#: pretix/base/pdf.py:491 pretix/base/pdf.py:497 -#: pretix/control/forms/orders.py:332 +#: pretix/base/pdf.py:500 pretix/base/pdf.py:506 +#: pretix/control/forms/orders.py:344 msgid "General admission" msgstr "" -#: pretix/base/pdf.py:494 +#: pretix/base/pdf.py:503 msgid "Seat: zone" msgstr "" -#: pretix/base/pdf.py:495 +#: pretix/base/pdf.py:504 msgid "Ground floor" msgstr "" -#: pretix/base/pdf.py:500 +#: pretix/base/pdf.py:509 msgid "Seat: row" msgstr "" -#: pretix/base/pdf.py:505 +#: pretix/base/pdf.py:514 msgid "Seat: seat number" msgstr "" -#: pretix/base/pdf.py:510 +#: pretix/base/pdf.py:519 msgid "Date and time of first scan" msgstr "" -#: pretix/base/pdf.py:516 +#: pretix/base/pdf.py:525 msgid "Gift card: Issuance date" msgstr "" -#: pretix/base/pdf.py:521 +#: pretix/base/pdf.py:530 msgid "Gift card: Expiration date" msgstr "" -#: pretix/base/pdf.py:562 pretix/base/pdf.py:600 pretix/base/pdf.py:606 +#: pretix/base/pdf.py:571 pretix/base/pdf.py:609 pretix/base/pdf.py:615 #: pretix/plugins/badges/exporters.py:504 #: pretix/plugins/ticketoutputpdf/exporters.py:102 #, python-brace-format msgid "Question: {question}" msgstr "" -#: pretix/base/pdf.py:601 pretix/base/pdf.py:607 +#: pretix/base/pdf.py:610 pretix/base/pdf.py:616 #, python-brace-format msgid "" msgstr "" -#: pretix/base/pdf.py:648 +#: pretix/base/pdf.py:657 msgid "Attendee name for salutation" msgstr "" -#: pretix/base/pdf.py:649 pretix/base/pdf.py:672 +#: pretix/base/pdf.py:658 pretix/base/pdf.py:681 #: pretix/base/services/placeholders.py:696 -#: pretix/control/forms/organizer.py:661 +#: pretix/control/forms/organizer.py:664 msgid "Mr Doe" msgstr "" -#: pretix/base/pdf.py:655 pretix/base/pdf.py:662 +#: pretix/base/pdf.py:664 pretix/base/pdf.py:671 #: pretix/plugins/badges/exporters.py:501 -#: pretix/plugins/checkinlists/exporters.py:124 -#: pretix/plugins/checkinlists/exporters.py:497 +#: pretix/plugins/checkinlists/exporters.py:125 +#: pretix/plugins/checkinlists/exporters.py:498 #: pretix/plugins/ticketoutputpdf/exporters.py:99 #, python-brace-format msgid "Attendee name: {part}" msgstr "" -#: pretix/base/pdf.py:671 +#: pretix/base/pdf.py:680 msgid "Invoice address name for salutation" msgstr "" -#: pretix/base/pdf.py:678 +#: pretix/base/pdf.py:687 #, python-brace-format msgid "Invoice address name: {part}" msgstr "" -#: pretix/base/pdf.py:1278 +#: pretix/base/pdf.py:1287 +#, python-brace-format msgid "Your layout file is not a valid layout. Error message: {}" msgstr "" -#: pretix/base/reldate.py:35 -msgid "Event start" +#: pretix/base/plugins.py:136 +#: pretix/control/templates/pretixcontrol/event/quick_setup.html:132 +msgid "Features" msgstr "" -#: pretix/base/reldate.py:36 -msgid "Event end" +#: pretix/base/plugins.py:138 +msgid "Integrations" msgstr "" -#: pretix/base/reldate.py:37 -msgid "Event admission" +#: pretix/base/plugins.py:139 +msgid "Customizations" +msgstr "" + +#: pretix/base/plugins.py:140 +msgid "Output and export formats" +msgstr "" + +#: pretix/base/plugins.py:141 +msgid "API features" msgstr "" #: pretix/base/reldate.py:38 -msgid "Presale start" +msgid "Event start" msgstr "" #: pretix/base/reldate.py:39 +msgid "Event end" +msgstr "" + +#: pretix/base/reldate.py:40 +msgid "Event admission" +msgstr "" + +#: pretix/base/reldate.py:41 +msgid "Presale start" +msgstr "" + +#: pretix/base/reldate.py:42 msgid "Presale end" msgstr "" -#: pretix/base/reldate.py:183 +#: pretix/base/reldate.py:186 msgid "before" msgstr "" -#: pretix/base/reldate.py:184 +#: pretix/base/reldate.py:187 msgid "after" msgstr "" -#: pretix/base/reldate.py:292 pretix/base/reldate.py:456 +#: pretix/base/reldate.py:308 pretix/base/reldate.py:472 msgid "Fixed date:" msgstr "" -#: pretix/base/reldate.py:293 pretix/base/reldate.py:457 +#: pretix/base/reldate.py:309 pretix/base/reldate.py:473 msgid "Relative date:" msgstr "" -#: pretix/base/reldate.py:294 +#: pretix/base/reldate.py:310 msgid "Relative time:" msgstr "" -#: pretix/base/reldate.py:302 pretix/base/reldate.py:460 +#: pretix/base/reldate.py:318 pretix/base/reldate.py:476 msgid "Not set" msgstr "" @@ -7213,13 +7639,13 @@ msgid "" "offline scanning – please refer to documentation or support for details)" msgstr "" -#: pretix/base/services/cancelevent.py:229 -#: pretix/base/services/cancelevent.py:287 +#: pretix/base/services/cancelevent.py:230 +#: pretix/base/services/cancelevent.py:308 msgid "Event canceled" msgstr "" -#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:194 -#: pretix/base/services/orders.py:151 +#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:235 +#: pretix/base/services/orders.py:155 msgid "" "We were not able to process your request completely as the server was too " "busy. Please try again." @@ -7238,7 +7664,7 @@ msgctxt "subevent" msgid "No date was specified." msgstr "" -#: pretix/base/services/cart.py:108 pretix/base/services/orders.py:188 +#: pretix/base/services/cart.py:108 pretix/base/services/orders.py:192 msgid "You selected a product which is not available for sale." msgstr "" @@ -7276,7 +7702,7 @@ msgid_plural "You cannot select more than %s items per order." msgstr[0] "" msgstr[1] "" -#: pretix/base/services/cart.py:131 pretix/base/services/orders.py:1542 +#: pretix/base/services/cart.py:131 pretix/base/services/orders.py:1598 #, python-format msgid "You cannot select more than %(max)s item of the product %(product)s." msgid_plural "" @@ -7284,7 +7710,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: pretix/base/services/cart.py:136 pretix/base/services/orders.py:1547 +#: pretix/base/services/cart.py:136 pretix/base/services/orders.py:1603 #, python-format msgid "You need to select at least %(min)s item of the product %(product)s." msgid_plural "" @@ -7303,8 +7729,8 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: pretix/base/services/cart.py:145 pretix/base/services/orders.py:154 -#: pretix/presale/templates/pretixpresale/event/index.html:171 +#: pretix/base/services/cart.py:145 pretix/base/services/orders.py:158 +#: pretix/presale/templates/pretixpresale/event/index.html:170 #: pretix/presale/views/waiting.py:145 pretix/presale/views/widget.py:781 msgid "The booking period for this event has not yet started." msgstr "" @@ -7325,7 +7751,7 @@ msgid "" "positions have been removed from your cart." msgstr "" -#: pretix/base/services/cart.py:152 pretix/base/services/orders.py:182 +#: pretix/base/services/cart.py:152 pretix/base/services/orders.py:186 msgid "" "The booking period for one of the events in your cart has ended. The " "affected positions have been removed from your cart." @@ -7343,7 +7769,7 @@ msgstr "" msgid "This voucher code is not known in our database." msgstr "" -#: pretix/base/services/cart.py:158 pretix/base/services/orders.py:157 +#: pretix/base/services/cart.py:158 pretix/base/services/orders.py:161 #, python-format msgid "" "The voucher code \"%(voucher)s\" can only be used if you select at least " @@ -7435,15 +7861,15 @@ msgctxt "subevent" msgid "The selected event date is not active." msgstr "" -#: pretix/base/services/cart.py:195 pretix/base/services/orders.py:189 +#: pretix/base/services/cart.py:195 pretix/base/services/orders.py:193 msgid "You can not select an add-on for the selected product." msgstr "" -#: pretix/base/services/cart.py:196 pretix/base/services/orders.py:190 +#: pretix/base/services/cart.py:196 pretix/base/services/orders.py:194 msgid "You can not select two variations of the same add-on product." msgstr "" -#: pretix/base/services/cart.py:198 pretix/base/services/orders.py:192 +#: pretix/base/services/cart.py:198 pretix/base/services/orders.py:196 #, python-format msgid "" "You can select at most %(max)s add-on from the category %(cat)s for the " @@ -7454,7 +7880,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: pretix/base/services/cart.py:203 pretix/base/services/orders.py:197 +#: pretix/base/services/cart.py:203 pretix/base/services/orders.py:201 #, python-format msgid "" "You need to select at least %(min)s add-on from the category %(cat)s for the " @@ -7465,7 +7891,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: pretix/base/services/cart.py:207 pretix/base/services/orders.py:201 +#: pretix/base/services/cart.py:207 pretix/base/services/orders.py:205 #, python-format msgid "" "You can select every add-on from the category %(cat)s for the product " @@ -7705,13 +8131,13 @@ msgstr "" msgid "Your exported data exceeded the size limit for scheduled exports." msgstr "" -#: pretix/base/services/invoices.py:103 +#: pretix/base/services/invoices.py:109 #, python-brace-format msgctxt "invoice" msgid "Please complete your payment before {expire_date}." msgstr "" -#: pretix/base/services/invoices.py:115 +#: pretix/base/services/invoices.py:121 #, python-brace-format msgctxt "invoice" msgid "" @@ -7722,49 +8148,51 @@ msgid "" "{country}" msgstr "" -#: pretix/base/services/invoices.py:220 pretix/base/services/invoices.py:257 +#: pretix/base/services/invoices.py:229 pretix/base/services/invoices.py:266 #, python-brace-format msgctxt "invoice" msgid "Event location: {location}" msgstr "" -#: pretix/base/services/invoices.py:236 +#: pretix/base/services/invoices.py:245 #, python-brace-format msgctxt "invoice" msgid "Attendee: {name}" msgstr "" -#: pretix/base/services/invoices.py:254 pretix/plugins/reports/exporters.py:298 +#: pretix/base/services/invoices.py:263 pretix/plugins/reports/exporters.py:309 +#, python-brace-format msgctxt "subevent" msgid "Date: {}" msgstr "" -#: pretix/base/services/invoices.py:469 +#: pretix/base/services/invoices.py:480 msgid "A payment provider specific text might appear here." msgstr "" -#: pretix/base/services/invoices.py:477 +#: pretix/base/services/invoices.py:488 msgid "214th Example Street" msgstr "" -#: pretix/base/services/invoices.py:478 +#: pretix/base/services/invoices.py:489 msgid "012345" msgstr "" -#: pretix/base/services/invoices.py:495 +#: pretix/base/services/invoices.py:506 +#, python-brace-format msgid "Sample product {}" msgstr "" -#: pretix/base/services/invoices.py:505 +#: pretix/base/services/invoices.py:516 msgid "Sample product A" msgstr "" -#: pretix/base/services/invoices.py:535 +#: pretix/base/services/invoices.py:576 #, python-brace-format msgid "New invoice: {number}" msgstr "" -#: pretix/base/services/invoices.py:537 +#: pretix/base/services/invoices.py:578 #, python-brace-format msgid "" "Hello,\n" @@ -7904,54 +8332,69 @@ msgid "" "\"{line}\": {message}" msgstr "" -#: pretix/base/services/modelimport.py:89 pretix/base/services/orders.py:1551 +#: pretix/base/services/modelimport.py:89 +#: pretix/base/services/modelimport.py:137 pretix/base/services/orders.py:1607 #, python-format msgid "Orders cannot have more than %(max)s positions." msgstr "" -#: pretix/base/services/modelimport.py:124 -#: pretix/base/services/modelimport.py:236 +#: pretix/base/services/modelimport.py:113 +#, python-format +msgid "" +"The grouping \"%(value)s\" occurs on non-consecutive lines (seen again on " +"line %(row)s)." +msgstr "" + +#: pretix/base/services/modelimport.py:151 +#, python-brace-format +msgid "" +"Inconsistent data in row {row}: Column {col} contains value \"{val_line}\", " +"but for this order, the value has already been set to \"{val_order}\"." +msgstr "" + +#: pretix/base/services/modelimport.py:165 +#: pretix/base/services/modelimport.py:277 #, python-brace-format msgid "Invalid data in row {row}: {message}" msgstr "" -#: pretix/base/services/modelimport.py:217 +#: pretix/base/services/modelimport.py:258 msgid "A voucher cannot be created without a code." msgstr "" -#: pretix/base/services/orders.py:130 +#: pretix/base/services/orders.py:134 msgid "" "Some of the products you selected were no longer available. Please see below " "for details." msgstr "" -#: pretix/base/services/orders.py:134 +#: pretix/base/services/orders.py:138 msgid "" "Some of the products you selected were no longer available in the quantity " "you selected. Please see below for details." msgstr "" -#: pretix/base/services/orders.py:138 +#: pretix/base/services/orders.py:142 msgid "" "The price of some of the items in your cart has changed in the meantime. " "Please see below for details." msgstr "" -#: pretix/base/services/orders.py:141 +#: pretix/base/services/orders.py:145 msgid "An internal error occurred, please try again." msgstr "" -#: pretix/base/services/orders.py:142 +#: pretix/base/services/orders.py:146 msgid "" "This order was changed by someone else simultaneously. Please check if your " "changes are still accurate and try again." msgstr "" -#: pretix/base/services/orders.py:144 +#: pretix/base/services/orders.py:148 msgid "Your cart is empty." msgstr "" -#: pretix/base/services/orders.py:146 +#: pretix/base/services/orders.py:150 #, python-format msgid "" "You cannot select more than %(max)s item of the product %(product)s. We " @@ -7962,193 +8405,193 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: pretix/base/services/orders.py:155 +#: pretix/base/services/orders.py:159 msgid "The booking period has ended." msgstr "" -#: pretix/base/services/orders.py:161 +#: pretix/base/services/orders.py:165 msgid "" "The voucher code used for one of the items in your cart is not known in our " "database." msgstr "" -#: pretix/base/services/orders.py:163 +#: pretix/base/services/orders.py:167 msgid "" "The voucher code used for one of the items in your cart has already been " "used the maximum number of times allowed. We removed this item from your " "cart." msgstr "" -#: pretix/base/services/orders.py:167 +#: pretix/base/services/orders.py:171 msgid "" "The voucher code used for one of the items in your cart has already been too " "often. We adjusted the price of the item in your cart." msgstr "" -#: pretix/base/services/orders.py:171 +#: pretix/base/services/orders.py:175 msgid "" "The voucher code used for one of the items in your cart is expired. We " "removed this item from your cart." msgstr "" -#: pretix/base/services/orders.py:174 +#: pretix/base/services/orders.py:178 msgid "" "The voucher code used for one of the items in your cart is not valid for " "this item. We removed this item from your cart." msgstr "" -#: pretix/base/services/orders.py:176 +#: pretix/base/services/orders.py:180 msgid "You need a valid voucher code to order one of the products." msgstr "" -#: pretix/base/services/orders.py:178 +#: pretix/base/services/orders.py:182 msgid "" "The booking period for one of the events in your cart has not yet started. " "The affected positions have been removed from your cart." msgstr "" -#: pretix/base/services/orders.py:185 +#: pretix/base/services/orders.py:189 msgid "" "One of the seats in your order was invalid, we removed the position from " "your cart." msgstr "" -#: pretix/base/services/orders.py:186 +#: pretix/base/services/orders.py:190 msgid "" "One of the seats in your order has been taken in the meantime, we removed " "the position from your cart." msgstr "" -#: pretix/base/services/orders.py:202 +#: pretix/base/services/orders.py:206 #, python-format msgid "" "You cannot remove the position %(addon)s since it has already been checked " "in." msgstr "" -#: pretix/base/services/orders.py:203 +#: pretix/base/services/orders.py:207 msgid "Paid products not supported without a valid currency." msgstr "" -#: pretix/base/services/orders.py:219 +#: pretix/base/services/orders.py:223 msgid "The order was not canceled." msgstr "" -#: pretix/base/services/orders.py:273 pretix/control/forms/orders.py:126 +#: pretix/base/services/orders.py:277 pretix/control/forms/orders.py:126 msgid "The new expiry date needs to be in the future." msgstr "" -#: pretix/base/services/orders.py:367 pretix/base/services/orders.py:453 +#: pretix/base/services/orders.py:371 pretix/base/services/orders.py:463 msgid "This order is not pending approval." msgstr "" -#: pretix/base/services/orders.py:511 pretix/presale/views/order.py:930 +#: pretix/base/services/orders.py:525 pretix/presale/views/order.py:930 #: pretix/presale/views/order.py:984 msgid "You cannot cancel this order." msgstr "" -#: pretix/base/services/orders.py:523 +#: pretix/base/services/orders.py:537 #, python-brace-format msgid "" "This order can not be canceled since the gift card {card} purchased in this " "order has already been redeemed." msgstr "" -#: pretix/base/services/orders.py:563 pretix/control/forms/orders.py:207 +#: pretix/base/services/orders.py:600 pretix/control/forms/orders.py:219 msgid "" "The cancellation fee cannot be higher than the total amount of this order." msgstr "" -#: pretix/base/services/orders.py:958 +#: pretix/base/services/orders.py:1000 msgid "The selected payment methods do not cover the total balance." msgstr "" -#: pretix/base/services/orders.py:1026 +#: pretix/base/services/orders.py:1068 msgid "" "While trying to place your order, we noticed that the order total has " "changed. Either one of the prices changed just now, or a gift card you used " "has been used in the meantime. Please check the prices below and try again." msgstr "" -#: pretix/base/services/orders.py:1521 +#: pretix/base/services/orders.py:1577 msgid "You need to select a variation of the product." msgstr "" -#: pretix/base/services/orders.py:1522 +#: pretix/base/services/orders.py:1578 #, python-brace-format msgid "" "The quota {name} does not have enough capacity left to perform the operation." msgstr "" -#: pretix/base/services/orders.py:1523 +#: pretix/base/services/orders.py:1579 msgid "There is no quota defined that allows this operation." msgstr "" -#: pretix/base/services/orders.py:1524 +#: pretix/base/services/orders.py:1580 msgid "The selected product is not active or has no price set." msgstr "" -#: pretix/base/services/orders.py:1525 +#: pretix/base/services/orders.py:1581 msgid "" "This operation would leave the order empty. Please cancel the order itself " "instead." msgstr "" -#: pretix/base/services/orders.py:1527 +#: pretix/base/services/orders.py:1583 msgid "" "This operation would make the order free and therefore immediately paid, " "however no quota is available." msgstr "" -#: pretix/base/services/orders.py:1530 +#: pretix/base/services/orders.py:1586 msgid "" "This is an add-on product, please select the base position it should be " "added to." msgstr "" -#: pretix/base/services/orders.py:1531 +#: pretix/base/services/orders.py:1587 msgid "" "The selected base position does not allow you to add this product as an add-" "on." msgstr "" -#: pretix/base/services/orders.py:1532 +#: pretix/base/services/orders.py:1588 msgid "You need to choose a subevent for the new position." msgstr "" -#: pretix/base/services/orders.py:1535 +#: pretix/base/services/orders.py:1591 #, python-brace-format msgid "" "You selected seat \"{seat}\" for a date that does not match the selected " "ticket date. Please choose a seat again." msgstr "" -#: pretix/base/services/orders.py:1537 +#: pretix/base/services/orders.py:1593 msgid "The selected product requires you to select a seat." msgstr "" -#: pretix/base/services/orders.py:1538 +#: pretix/base/services/orders.py:1594 msgid "The selected product does not allow to select a seat." msgstr "" -#: pretix/base/services/orders.py:1539 +#: pretix/base/services/orders.py:1595 msgid "The selected country is blocked by your tax rule." msgstr "" -#: pretix/base/services/orders.py:1540 +#: pretix/base/services/orders.py:1596 msgid "" "You cannot change the price of a position that has been used to issue a gift " "card." msgstr "" -#: pretix/base/services/orders.py:2365 pretix/base/services/orders.py:2382 +#: pretix/base/services/orders.py:2421 pretix/base/services/orders.py:2438 #, python-brace-format msgid "" "A position can not be canceled since the gift card {card} purchased in this " "order has already been redeemed." msgstr "" -#: pretix/base/services/orders.py:3058 +#: pretix/base/services/orders.py:3133 msgid "" "There was an error while trying to send the money back to you. Please " "contact the event organizer for further information." @@ -8181,7 +8624,7 @@ msgid "Please transfer money to this bank account: 9999-9999-9999-9999" msgstr "" #: pretix/base/services/placeholders.py:765 -#: pretix/control/views/organizer.py:336 +#: pretix/control/views/organizer.py:348 msgid "This value will be replaced based on dynamic parameters." msgstr "" @@ -8225,7 +8668,7 @@ msgstr "" msgid "Uncategorized" msgstr "" -#: pretix/base/services/tax.py:40 pretix/base/services/tax.py:209 +#: pretix/base/services/tax.py:44 pretix/base/services/tax.py:213 msgid "" "Your VAT ID could not be checked, as the VAT checking service of your " "country is currently not available. We will therefore need to charge VAT on " @@ -8233,16 +8676,16 @@ msgid "" "process." msgstr "" -#: pretix/base/services/tax.py:45 pretix/base/services/tax.py:189 -#: pretix/base/services/tax.py:216 +#: pretix/base/services/tax.py:49 pretix/base/services/tax.py:193 +#: pretix/base/services/tax.py:220 msgid "This VAT ID is not valid. Please re-check your input." msgstr "" -#: pretix/base/services/tax.py:46 pretix/base/services/tax.py:174 +#: pretix/base/services/tax.py:50 pretix/base/services/tax.py:178 msgid "Your VAT ID does not match the selected country." msgstr "" -#: pretix/base/services/tax.py:193 pretix/base/services/tax.py:201 +#: pretix/base/services/tax.py:197 pretix/base/services/tax.py:205 msgid "" "Your VAT ID could not be checked, as the VAT checking service of your " "country returned an incorrect result. We will therefore need to charge VAT " @@ -8284,7 +8727,7 @@ msgstr "" msgid "Plugin: %s" msgstr "" -#: pretix/base/services/vouchers.py:56 pretix/control/logdisplay.py:518 +#: pretix/base/services/vouchers.py:56 pretix/control/logdisplay.py:579 #, python-brace-format msgid "The voucher has been sent to {recipient}." msgstr "" @@ -8494,7 +8937,7 @@ msgid "Show exchange rates" msgstr "" #: pretix/base/settings.py:524 pretix/base/settings.py:532 -#: pretix/control/forms/item.py:625 +#: pretix/control/forms/item.py:626 msgid "Never" msgstr "" @@ -8657,8 +9100,8 @@ msgstr "" msgid "Only respected by some invoice renderers." msgstr "" -#: pretix/base/settings.py:744 pretix/base/settings.py:2907 -#: pretix/control/templates/pretixcontrol/pdf/index.html:376 +#: pretix/base/settings.py:744 pretix/base/settings.py:2959 +#: pretix/control/templates/pretixcontrol/pdf/index.html:436 msgid "Font" msgstr "" @@ -8828,135 +9271,157 @@ msgstr "" msgid "Show the presale start date before presale has started." msgstr "" -#: pretix/base/settings.py:1041 pretix/base/settings.py:1053 +#: pretix/base/settings.py:1037 pretix/base/settings.py:1045 +#: pretix/base/settings.py:1059 pretix/base/settings.py:1068 +msgid "Use default tax rate" +msgstr "" + +#: pretix/base/settings.py:1038 pretix/base/settings.py:1046 +#: pretix/base/settings.py:1057 pretix/base/settings.py:1066 +msgid "Charge no taxes" +msgstr "" + +#: pretix/base/settings.py:1042 +msgid "Tax handling on payment fees" +msgstr "" + +#: pretix/base/settings.py:1058 pretix/base/settings.py:1067 +msgid "Use same taxes as order positions (split according to net prices)" +msgstr "" + +#: pretix/base/settings.py:1063 +msgid "Tax handling on cancellation fees" +msgstr "" + +#: pretix/base/settings.py:1079 pretix/base/settings.py:1091 msgid "Do not generate invoices" msgstr "" -#: pretix/base/settings.py:1042 pretix/base/settings.py:1058 +#: pretix/base/settings.py:1080 pretix/base/settings.py:1096 msgid "Only manually in admin panel" msgstr "" -#: pretix/base/settings.py:1043 pretix/base/settings.py:1056 +#: pretix/base/settings.py:1081 pretix/base/settings.py:1094 msgid "Automatically on user request" msgstr "" -#: pretix/base/settings.py:1044 pretix/base/settings.py:1057 +#: pretix/base/settings.py:1082 pretix/base/settings.py:1095 msgid "Automatically on user request for paid orders" msgstr "" -#: pretix/base/settings.py:1045 +#: pretix/base/settings.py:1083 msgid "Automatically for all created orders" msgstr "" -#: pretix/base/settings.py:1046 +#: pretix/base/settings.py:1084 msgid "Automatically on payment or when required by payment method" msgstr "" -#: pretix/base/settings.py:1050 +#: pretix/base/settings.py:1088 msgid "Generate invoices" msgstr "" -#: pretix/base/settings.py:1054 +#: pretix/base/settings.py:1092 msgid "Automatically after payment or when required by payment method" msgstr "" -#: pretix/base/settings.py:1055 +#: pretix/base/settings.py:1093 msgid "Automatically before payment for all created orders" msgstr "" -#: pretix/base/settings.py:1060 +#: pretix/base/settings.py:1098 msgid "Invoices will never be automatically generated for free orders." msgstr "" -#: pretix/base/settings.py:1069 +#: pretix/base/settings.py:1107 msgid "Automatically cancel and reissue invoice on address changes" msgstr "" -#: pretix/base/settings.py:1070 +#: pretix/base/settings.py:1108 msgid "" "If customers change their invoice address on an existing order, the invoice " "will automatically be canceled and a new invoice will be issued. This " "setting does not affect changes made through the backend." msgstr "" -#: pretix/base/settings.py:1081 +#: pretix/base/settings.py:1119 msgid "Allow to update existing invoices" msgstr "" -#: pretix/base/settings.py:1082 +#: pretix/base/settings.py:1120 msgid "" "By default, invoices can never again be changed once they are issued. In " "most countries, we recommend to leave this option turned off and always " "issue a new invoice if a change needs to be made." msgstr "" -#: pretix/base/settings.py:1097 +#: pretix/base/settings.py:1135 msgid "Address line" msgstr "" -#: pretix/base/settings.py:1101 +#: pretix/base/settings.py:1139 msgid "Albert Einstein Road 52" msgstr "" -#: pretix/base/settings.py:1153 +#: pretix/base/settings.py:1191 msgid "Domestic tax ID" msgstr "" -#: pretix/base/settings.py:1154 +#: pretix/base/settings.py:1192 msgid "e.g. tax number in Germany, ABN in Australia, …" msgstr "" -#: pretix/base/settings.py:1163 +#: pretix/base/settings.py:1201 msgid "EU VAT ID" msgstr "" -#: pretix/base/settings.py:1176 +#: pretix/base/settings.py:1214 msgid "e.g. With this document, we sent you the invoice for your ticket order." msgstr "" -#: pretix/base/settings.py:1179 +#: pretix/base/settings.py:1217 msgid "Introductory text" msgstr "" -#: pretix/base/settings.py:1180 +#: pretix/base/settings.py:1218 msgid "Will be printed on every invoice above the invoice rows." msgstr "" -#: pretix/base/settings.py:1193 +#: pretix/base/settings.py:1231 msgid "" "e.g. Thank you for your purchase! You can find more information on the event " "at ..." msgstr "" -#: pretix/base/settings.py:1196 +#: pretix/base/settings.py:1234 msgid "Additional text" msgstr "" -#: pretix/base/settings.py:1197 +#: pretix/base/settings.py:1235 msgid "Will be printed on every invoice below the invoice total." msgstr "" -#: pretix/base/settings.py:1210 +#: pretix/base/settings.py:1248 msgid "" "e.g. your bank details, legal details like your VAT ID, registration " "numbers, etc." msgstr "" -#: pretix/base/settings.py:1213 +#: pretix/base/settings.py:1251 msgid "Footer" msgstr "" -#: pretix/base/settings.py:1214 +#: pretix/base/settings.py:1252 msgid "" "Will be printed centered and in a smaller font at the end of every invoice " "page." msgstr "" -#: pretix/base/settings.py:1227 +#: pretix/base/settings.py:1265 msgid "Attach invoices to emails" msgstr "" -#: pretix/base/settings.py:1228 +#: pretix/base/settings.py:1266 msgid "" "If invoices are automatically generated for all orders, they will be " "attached to the order confirmation mail. If they are automatically generated " @@ -8964,39 +9429,39 @@ msgid "" "are not automatically generated, they will not be attached to emails." msgstr "" -#: pretix/base/settings.py:1240 +#: pretix/base/settings.py:1278 msgid "Email address to receive a copy of each invoice" msgstr "" -#: pretix/base/settings.py:1241 +#: pretix/base/settings.py:1279 msgid "" "Each newly created invoice will be sent to this email address shortly after " "creation. You can use this for an automated import of invoices to your " "accounting system. The invoice will be the only attachment of the email." msgstr "" -#: pretix/base/settings.py:1256 +#: pretix/base/settings.py:1294 msgid "Show items outside presale period" msgstr "" -#: pretix/base/settings.py:1257 +#: pretix/base/settings.py:1295 msgid "" "Show item details before presale has started and after presale has ended" msgstr "" -#: pretix/base/settings.py:1277 +#: pretix/base/settings.py:1315 msgid "Available languages" msgstr "" -#: pretix/base/settings.py:1293 pretix/control/forms/event.py:140 +#: pretix/base/settings.py:1331 pretix/control/forms/event.py:139 msgid "Default language" msgstr "" -#: pretix/base/settings.py:1303 +#: pretix/base/settings.py:1341 msgid "Region" msgstr "" -#: pretix/base/settings.py:1304 +#: pretix/base/settings.py:1342 msgid "" "Will be used to determine date and time formatting as well as default " "country for customer addresses and phone numbers. For formatting, this takes " @@ -9004,11 +9469,11 @@ msgid "" "languages used in different regions globally (like English)." msgstr "" -#: pretix/base/settings.py:1316 +#: pretix/base/settings.py:1354 msgid "This shop represents an event" msgstr "" -#: pretix/base/settings.py:1318 +#: pretix/base/settings.py:1356 msgid "" "Uncheck this box if you are only selling something that has no specific " "date, such as gift cards or a ticket that can be used any time. The system " @@ -9017,45 +9482,45 @@ msgid "" "may still show up in other places." msgstr "" -#: pretix/base/settings.py:1331 +#: pretix/base/settings.py:1369 msgid "Show event end date" msgstr "" -#: pretix/base/settings.py:1332 +#: pretix/base/settings.py:1370 msgid "If disabled, only event's start date will be displayed to the public." msgstr "" -#: pretix/base/settings.py:1341 +#: pretix/base/settings.py:1379 msgid "Show dates with time" msgstr "" -#: pretix/base/settings.py:1342 +#: pretix/base/settings.py:1380 msgid "" "If disabled, the event's start and end date will be displayed without the " "time of day." msgstr "" -#: pretix/base/settings.py:1351 +#: pretix/base/settings.py:1389 msgid "Hide all products that are sold out" msgstr "" -#: pretix/base/settings.py:1361 pretix/control/forms/event.py:1682 +#: pretix/base/settings.py:1399 pretix/control/forms/event.py:1691 msgid "Publicly show how many tickets of a certain type are still available." msgstr "" -#: pretix/base/settings.py:1370 +#: pretix/base/settings.py:1408 msgid "Ask search engines not to index the ticket shop" msgstr "" -#: pretix/base/settings.py:1379 +#: pretix/base/settings.py:1417 msgid "Show variations of a product expanded by default" msgstr "" -#: pretix/base/settings.py:1388 +#: pretix/base/settings.py:1426 msgid "Enable waiting list" msgstr "" -#: pretix/base/settings.py:1389 pretix/control/forms/event.py:1687 +#: pretix/base/settings.py:1427 pretix/control/forms/event.py:1696 msgid "" "Once a ticket is sold out, people can add themselves to a waiting list. As " "soon as a ticket becomes available again, it will be reserved for the first " @@ -9063,11 +9528,11 @@ msgid "" "notification with a voucher that can be used to buy a ticket." msgstr "" -#: pretix/base/settings.py:1400 +#: pretix/base/settings.py:1438 msgid "Automatic waiting list assignments" msgstr "" -#: pretix/base/settings.py:1401 +#: pretix/base/settings.py:1439 msgid "" "If ticket capacity becomes free, automatically create a voucher and send it " "to the first person on the waiting list for that product. If this is not " @@ -9076,22 +9541,22 @@ msgid "" "enabled, tickets will still be sent out." msgstr "" -#: pretix/base/settings.py:1417 +#: pretix/base/settings.py:1455 msgid "Waiting list response time" msgstr "" -#: pretix/base/settings.py:1420 +#: pretix/base/settings.py:1458 msgid "" "If a ticket voucher is sent to a person on the waiting list, it has to be " "redeemed within this number of hours until it expires and can be re-assigned " "to the next person on the list." msgstr "" -#: pretix/base/settings.py:1431 +#: pretix/base/settings.py:1469 msgid "Disable waiting list" msgstr "" -#: pretix/base/settings.py:1432 +#: pretix/base/settings.py:1470 msgid "" "The waiting list will be fully disabled after this date. This means that " "nobody can add themselves to the waiting list any more, but also that " @@ -9100,53 +9565,53 @@ msgid "" "remain active." msgstr "" -#: pretix/base/settings.py:1444 +#: pretix/base/settings.py:1482 msgid "Ask for a name" msgstr "" -#: pretix/base/settings.py:1445 +#: pretix/base/settings.py:1483 msgid "Ask for a name when signing up to the waiting list." msgstr "" -#: pretix/base/settings.py:1454 +#: pretix/base/settings.py:1492 msgid "Require name" msgstr "" -#: pretix/base/settings.py:1455 +#: pretix/base/settings.py:1493 msgid "Require a name when signing up to the waiting list.." msgstr "" -#: pretix/base/settings.py:1465 +#: pretix/base/settings.py:1503 msgid "Ask for a phone number" msgstr "" -#: pretix/base/settings.py:1466 +#: pretix/base/settings.py:1504 msgid "Ask for a phone number when signing up to the waiting list." msgstr "" -#: pretix/base/settings.py:1475 +#: pretix/base/settings.py:1513 msgid "Require phone number" msgstr "" -#: pretix/base/settings.py:1476 +#: pretix/base/settings.py:1514 msgid "Require a phone number when signing up to the waiting list.." msgstr "" -#: pretix/base/settings.py:1486 +#: pretix/base/settings.py:1524 msgid "Phone number explanation" msgstr "" -#: pretix/base/settings.py:1489 +#: pretix/base/settings.py:1527 msgid "" "If you ask for a phone number, explain why you do so and what you will use " "the phone number for." msgstr "" -#: pretix/base/settings.py:1501 +#: pretix/base/settings.py:1539 msgid "Maximum number of entries per email address for the same product" msgstr "" -#: pretix/base/settings.py:1505 +#: pretix/base/settings.py:1543 msgid "" "With an increased limit, a customer may request more than one ticket for a " "specific product using the same, unique email address. However, regardless " @@ -9155,11 +9620,11 @@ msgid "" "ticket at a time." msgstr "" -#: pretix/base/settings.py:1517 +#: pretix/base/settings.py:1555 msgid "Show number of check-ins to customer" msgstr "" -#: pretix/base/settings.py:1518 +#: pretix/base/settings.py:1556 msgid "" "With this option enabled, your customers will be able to see how many times " "they entered the event. This is usually not necessary, but might be useful " @@ -9169,62 +9634,62 @@ msgid "" "check-in lists." msgstr "" -#: pretix/base/settings.py:1531 +#: pretix/base/settings.py:1569 msgid "Allow users to download tickets" msgstr "" -#: pretix/base/settings.py:1532 +#: pretix/base/settings.py:1570 msgid "If this is off, nobody can download a ticket." msgstr "" -#: pretix/base/settings.py:1541 +#: pretix/base/settings.py:1579 msgid "Download date" msgstr "" -#: pretix/base/settings.py:1542 +#: pretix/base/settings.py:1580 msgid "" "Ticket download will be offered after this date. If you use the event series " "feature and an order contains tickets for multiple event dates, download of " "all tickets will be available if at least one of the event dates allows it." msgstr "" -#: pretix/base/settings.py:1553 +#: pretix/base/settings.py:1591 msgid "Generate tickets for add-on products and bundled products" msgstr "" -#: pretix/base/settings.py:1554 +#: pretix/base/settings.py:1592 msgid "" "By default, tickets are only issued for products selected individually, not " "for add-on products or bundled products. With this option, a separate ticket " "is issued for every add-on product or bundled product as well." msgstr "" -#: pretix/base/settings.py:1567 +#: pretix/base/settings.py:1605 msgid "Generate tickets for all products" msgstr "" -#: pretix/base/settings.py:1568 +#: pretix/base/settings.py:1606 msgid "" "If turned off, tickets are only issued for products that are marked as an " "\"admission ticket\"in the product settings. You can also turn off ticket " "issuing in every product separately." msgstr "" -#: pretix/base/settings.py:1580 +#: pretix/base/settings.py:1618 msgid "Generate tickets for pending orders" msgstr "" -#: pretix/base/settings.py:1581 +#: pretix/base/settings.py:1619 msgid "" "If turned off, ticket downloads are only possible after an order has been " "marked as paid." msgstr "" -#: pretix/base/settings.py:1592 +#: pretix/base/settings.py:1630 msgid "Do not issue ticket before email address is validated" msgstr "" -#: pretix/base/settings.py:1593 +#: pretix/base/settings.py:1631 msgid "" "If turned on, tickets will not be offered for download directly after " "purchase. They will be attached to the payment confirmation email (if the " @@ -9233,11 +9698,11 @@ msgid "" "orders performed through other sales channels." msgstr "" -#: pretix/base/settings.py:1609 +#: pretix/base/settings.py:1647 msgid "Low availability threshold" msgstr "" -#: pretix/base/settings.py:1610 +#: pretix/base/settings.py:1648 msgid "" "If the availability of tickets falls below this percentage, the event (or a " "date, if it is an event series) will be highlighted to have low availability " @@ -9245,95 +9710,95 @@ msgid "" "availability will not be shown publicly." msgstr "" -#: pretix/base/settings.py:1624 +#: pretix/base/settings.py:1662 msgid "Show availability in event overviews" msgstr "" -#: pretix/base/settings.py:1625 +#: pretix/base/settings.py:1663 msgid "" "If checked, the list of events will show if events are sold out. This might " "make for longer page loading times if you have lots of events and the shown " "status might be out of date for up to two minutes." msgstr "" -#: pretix/base/settings.py:1638 pretix/base/settings.py:1646 +#: pretix/base/settings.py:1676 pretix/base/settings.py:1684 #: pretix/presale/templates/pretixpresale/fragment_calendar_nav.html:8 msgid "List" msgstr "" -#: pretix/base/settings.py:1639 pretix/base/settings.py:1647 +#: pretix/base/settings.py:1677 pretix/base/settings.py:1685 msgid "Week calendar" msgstr "" -#: pretix/base/settings.py:1640 pretix/base/settings.py:1648 +#: pretix/base/settings.py:1678 pretix/base/settings.py:1686 msgid "Month calendar" msgstr "" -#: pretix/base/settings.py:1644 +#: pretix/base/settings.py:1682 msgid "Default overview style" msgstr "" -#: pretix/base/settings.py:1650 +#: pretix/base/settings.py:1688 msgid "" "If your event series has more than 50 dates in the future, only the month or " "week calendar can be used." msgstr "" -#: pretix/base/settings.py:1659 +#: pretix/base/settings.py:1697 msgid "Show filter options for calendar or list view" msgstr "" -#: pretix/base/settings.py:1660 +#: pretix/base/settings.py:1698 msgid "" "You can set up possible filters as meta properties in your organizer " "settings." msgstr "" -#: pretix/base/settings.py:1669 +#: pretix/base/settings.py:1707 msgid "Hide all unavailable dates from calendar or list views" msgstr "" -#: pretix/base/settings.py:1670 pretix/base/settings.py:1681 +#: pretix/base/settings.py:1708 pretix/base/settings.py:1719 msgid "" "This option currently only affects the calendar of this event series, not " "the organizer-wide calendar." msgstr "" -#: pretix/base/settings.py:1680 +#: pretix/base/settings.py:1718 msgid "Hide all past dates from calendar" msgstr "" -#: pretix/base/settings.py:1692 pretix/base/settings.py:1701 +#: pretix/base/settings.py:1730 pretix/base/settings.py:1739 msgid "No modifications after order was submitted" msgstr "" -#: pretix/base/settings.py:1693 pretix/base/settings.py:1702 +#: pretix/base/settings.py:1731 pretix/base/settings.py:1740 msgid "Only the person who ordered can make changes" msgstr "" -#: pretix/base/settings.py:1694 pretix/base/settings.py:1703 +#: pretix/base/settings.py:1732 pretix/base/settings.py:1741 msgid "Both the attendee and the person who ordered can make changes" msgstr "" -#: pretix/base/settings.py:1698 +#: pretix/base/settings.py:1736 msgid "Allow customers to modify their information" msgstr "" -#: pretix/base/settings.py:1713 +#: pretix/base/settings.py:1751 msgid "Allow customers to modify their information after they checked in." msgstr "" -#: pretix/base/settings.py:1714 +#: pretix/base/settings.py:1752 msgid "" "By default, no more modifications are possible for an order as soon as one " "of the tickets in the order has been checked in." msgstr "" -#: pretix/base/settings.py:1724 +#: pretix/base/settings.py:1762 msgid "Last date of modifications" msgstr "" -#: pretix/base/settings.py:1725 +#: pretix/base/settings.py:1763 msgid "" "The last date users can modify details of their orders, such as attendee " "names or answers to questions. If you use the event series feature and an " @@ -9341,53 +9806,53 @@ msgid "" "used." msgstr "" -#: pretix/base/settings.py:1736 +#: pretix/base/settings.py:1774 msgid "Customers can change the variation of the products they purchased" msgstr "" -#: pretix/base/settings.py:1745 +#: pretix/base/settings.py:1783 msgid "Customers can change their selected add-on products" msgstr "" -#: pretix/base/settings.py:1755 pretix/base/settings.py:1766 +#: pretix/base/settings.py:1793 pretix/base/settings.py:1804 msgid "" "Only allow changes if the resulting price is higher or equal than the " "previous price." msgstr "" -#: pretix/base/settings.py:1756 pretix/base/settings.py:1767 +#: pretix/base/settings.py:1794 pretix/base/settings.py:1805 msgid "" "Only allow changes if the resulting price is higher than the previous price." msgstr "" -#: pretix/base/settings.py:1757 pretix/base/settings.py:1768 +#: pretix/base/settings.py:1795 pretix/base/settings.py:1806 msgid "" "Only allow changes if the resulting price is equal to the previous price." msgstr "" -#: pretix/base/settings.py:1758 pretix/base/settings.py:1769 +#: pretix/base/settings.py:1796 pretix/base/settings.py:1807 msgid "" "Allow changes regardless of price, as long as no refund is required (i.e. " "the resulting price is not lower than what has already been paid)." msgstr "" -#: pretix/base/settings.py:1760 pretix/base/settings.py:1771 +#: pretix/base/settings.py:1798 pretix/base/settings.py:1809 msgid "Allow changes regardless of price, even if this results in a refund." msgstr "" -#: pretix/base/settings.py:1764 +#: pretix/base/settings.py:1802 msgid "Requirement for changed prices" msgstr "" -#: pretix/base/settings.py:1782 +#: pretix/base/settings.py:1820 msgid "Do not allow changes after" msgstr "" -#: pretix/base/settings.py:1791 +#: pretix/base/settings.py:1829 msgid "Allow change even though the ticket has already been checked in" msgstr "" -#: pretix/base/settings.py:1792 +#: pretix/base/settings.py:1830 msgid "" "By default, order changes are disabled after any ticket in the order has " "been checked in. If you check this box, this requirement is lifted. It is " @@ -9396,11 +9861,11 @@ msgid "" "limitation on price changes above." msgstr "" -#: pretix/base/settings.py:1804 +#: pretix/base/settings.py:1842 msgid "Allow individual attendees to change their ticket" msgstr "" -#: pretix/base/settings.py:1805 +#: pretix/base/settings.py:1843 msgid "" "By default, only the person who ordered the tickets can make any changes. If " "you check this box, individual attendees can also make changes. However, " @@ -9409,77 +9874,77 @@ msgid "" "customer." msgstr "" -#: pretix/base/settings.py:1817 +#: pretix/base/settings.py:1855 msgid "Customers can cancel their unpaid orders" msgstr "" -#: pretix/base/settings.py:1829 +#: pretix/base/settings.py:1867 msgid "Charge a fixed cancellation fee" msgstr "" -#: pretix/base/settings.py:1830 pretix/base/settings.py:1841 -#: pretix/base/settings.py:1855 +#: pretix/base/settings.py:1868 pretix/base/settings.py:1879 +#: pretix/base/settings.py:1893 msgid "" "Only affects orders pending payments, a cancellation fee for free orders is " "never charged. Note that it will be your responsibility to claim the " "cancellation fee from the user." msgstr "" -#: pretix/base/settings.py:1840 +#: pretix/base/settings.py:1878 msgid "Charge payment, shipping and service fees" msgstr "" -#: pretix/base/settings.py:1854 +#: pretix/base/settings.py:1892 msgid "Charge a percentual cancellation fee" msgstr "" -#: pretix/base/settings.py:1865 pretix/base/settings.py:2004 +#: pretix/base/settings.py:1903 pretix/base/settings.py:2042 msgid "Do not allow cancellations after" msgstr "" -#: pretix/base/settings.py:1874 +#: pretix/base/settings.py:1912 msgid "Customers can cancel their paid orders" msgstr "" -#: pretix/base/settings.py:1875 +#: pretix/base/settings.py:1913 msgid "" "Paid money will be automatically paid back if the payment method allows it. " "Otherwise, a manual refund will be created for you to process manually." msgstr "" -#: pretix/base/settings.py:1888 pretix/control/forms/orders.py:899 +#: pretix/base/settings.py:1926 pretix/control/forms/orders.py:909 msgid "Keep a fixed cancellation fee" msgstr "" -#: pretix/base/settings.py:1897 +#: pretix/base/settings.py:1935 msgid "Keep payment, shipping and service fees" msgstr "" -#: pretix/base/settings.py:1909 pretix/control/forms/orders.py:910 +#: pretix/base/settings.py:1947 pretix/control/forms/orders.py:920 msgid "Keep a percentual cancellation fee" msgstr "" -#: pretix/base/settings.py:1918 +#: pretix/base/settings.py:1956 msgid "Allow customers to voluntarily choose a lower refund" msgstr "" -#: pretix/base/settings.py:1919 +#: pretix/base/settings.py:1957 msgid "" "With this option enabled, your customers can choose to get a smaller refund " "to support you." msgstr "" -#: pretix/base/settings.py:1924 +#: pretix/base/settings.py:1962 msgid "" "However, if you want us to help keep the lights on here, please consider " "using the slider below to request a smaller refund. Thank you!" msgstr "" -#: pretix/base/settings.py:1931 +#: pretix/base/settings.py:1969 msgid "Voluntary lower refund explanation" msgstr "" -#: pretix/base/settings.py:1934 +#: pretix/base/settings.py:1972 msgid "" "This text will be shown in between the explanation of how the refunds work " "and the slider which your customers can use to choose the amount they would " @@ -9487,107 +9952,107 @@ msgid "" "help your organization." msgstr "" -#: pretix/base/settings.py:1949 +#: pretix/base/settings.py:1987 msgid "Step size for reduction amount" msgstr "" -#: pretix/base/settings.py:1950 +#: pretix/base/settings.py:1988 msgid "" "By default, customers can choose an arbitrary amount for you to keep. If you " "set this to e.g. 10, they will only be able to choose values in increments " "of 10." msgstr "" -#: pretix/base/settings.py:1960 +#: pretix/base/settings.py:1998 msgid "" "Customers can only request a cancellation that needs to be approved by the " "event organizer before the order is canceled and a refund is issued." msgstr "" -#: pretix/base/settings.py:1970 +#: pretix/base/settings.py:2008 msgid "" "Do not show the cancellation fee to users when they request cancellation." msgstr "" -#: pretix/base/settings.py:1979 pretix/base/settings.py:1989 +#: pretix/base/settings.py:2017 pretix/base/settings.py:2027 msgid "All refunds are issued to the original payment method" msgstr "" -#: pretix/base/settings.py:1980 pretix/base/settings.py:1990 +#: pretix/base/settings.py:2018 pretix/base/settings.py:2028 msgid "" "Customers can choose between a gift card and a refund to their payment method" msgstr "" -#: pretix/base/settings.py:1981 pretix/base/settings.py:1991 +#: pretix/base/settings.py:2019 pretix/base/settings.py:2029 msgid "All refunds are issued as gift cards" msgstr "" -#: pretix/base/settings.py:1982 pretix/base/settings.py:1992 +#: pretix/base/settings.py:2020 pretix/base/settings.py:2030 msgid "Do not handle refunds automatically at all" msgstr "" -#: pretix/base/settings.py:1987 +#: pretix/base/settings.py:2025 #: pretix/control/templates/pretixcontrol/order/index.html:149 msgid "Refund method" msgstr "" -#: pretix/base/settings.py:2013 pretix/base/settings.py:2026 +#: pretix/base/settings.py:2051 pretix/base/settings.py:2064 msgid "Terms of cancellation" msgstr "" -#: pretix/base/settings.py:2016 +#: pretix/base/settings.py:2054 msgid "" "This text will be shown when cancellation is allowed for a paid order. Leave " "empty if you want pretix to automatically generate the terms of cancellation " "based on your settings." msgstr "" -#: pretix/base/settings.py:2029 +#: pretix/base/settings.py:2067 msgid "" "This text will be shown when cancellation is allowed for an unpaid or free " "order. Leave empty if you want pretix to automatically generate the terms of " "cancellation based on your settings." msgstr "" -#: pretix/base/settings.py:2039 pretix/control/forms/event.py:1710 +#: pretix/base/settings.py:2077 pretix/control/forms/event.py:1719 msgid "Contact address" msgstr "" -#: pretix/base/settings.py:2040 pretix/control/forms/event.py:1712 +#: pretix/base/settings.py:2078 pretix/control/forms/event.py:1721 msgid "We'll show this publicly to allow attendees to contact you." msgstr "" -#: pretix/base/settings.py:2048 pretix/control/forms/event.py:1704 +#: pretix/base/settings.py:2086 pretix/control/forms/event.py:1713 msgid "Imprint URL" msgstr "" -#: pretix/base/settings.py:2049 pretix/control/forms/event.py:1705 +#: pretix/base/settings.py:2087 pretix/control/forms/event.py:1714 msgid "" "This should point e.g. to a part of your website that has your contact " "details and legal information." msgstr "" -#: pretix/base/settings.py:2059 +#: pretix/base/settings.py:2097 msgid "Privacy Policy URL" msgstr "" -#: pretix/base/settings.py:2060 +#: pretix/base/settings.py:2098 msgid "" "This should point e.g. to a part of your website that explains how you use " "data gathered in your ticket shop." msgstr "" -#: pretix/base/settings.py:2071 +#: pretix/base/settings.py:2109 msgid "Accessibility information URL" msgstr "" -#: pretix/base/settings.py:2072 +#: pretix/base/settings.py:2110 msgid "" "This should point e.g. to a part of your website that explains how your " "ticket shop complies with accessibility regulation." msgstr "" -#: pretix/base/settings.py:2079 +#: pretix/base/settings.py:2117 #: pretix/presale/templates/pretixpresale/event/base.html:228 #: pretix/presale/templates/pretixpresale/event/base.html:233 #: pretix/presale/templates/pretixpresale/organizers/accessibility.html:6 @@ -9596,52 +10061,52 @@ msgstr "" msgid "Accessibility information" msgstr "" -#: pretix/base/settings.py:2083 +#: pretix/base/settings.py:2121 msgid "Accessibility information title" msgstr "" -#: pretix/base/settings.py:2093 +#: pretix/base/settings.py:2131 msgid "Accessibility information text" msgstr "" -#: pretix/base/settings.py:2114 +#: pretix/base/settings.py:2152 msgid "Attach ticket files" msgstr "" -#: pretix/base/settings.py:2116 +#: pretix/base/settings.py:2154 #, python-brace-format msgid "" "Tickets will never be attached if they're larger than {size} to avoid email " "delivery problems." msgstr "" -#: pretix/base/settings.py:2127 pretix/plugins/sendmail/forms.py:201 +#: pretix/base/settings.py:2165 pretix/plugins/sendmail/forms.py:201 #: pretix/plugins/sendmail/models.py:270 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:66 msgid "Attach calendar files" msgstr "" -#: pretix/base/settings.py:2128 +#: pretix/base/settings.py:2166 msgid "" "If enabled, we will attach an .ics calendar file to order confirmation " "emails." msgstr "" -#: pretix/base/settings.py:2137 +#: pretix/base/settings.py:2175 msgid "Attach calendar files only after order has been paid" msgstr "" -#: pretix/base/settings.py:2138 +#: pretix/base/settings.py:2176 msgid "" "Use this if you e.g. put a private access link into the calendar file to " "make sure people only receive it after their payment was confirmed." msgstr "" -#: pretix/base/settings.py:2147 +#: pretix/base/settings.py:2185 msgid "Event description" msgstr "" -#: pretix/base/settings.py:2150 +#: pretix/base/settings.py:2188 msgid "" "You can use this to share information with your attendees, such as travel " "information or the link to a digital event. If you keep it empty, we will " @@ -9651,52 +10116,52 @@ msgid "" "people." msgstr "" -#: pretix/base/settings.py:2163 +#: pretix/base/settings.py:2201 msgid "Subject prefix" msgstr "" -#: pretix/base/settings.py:2164 +#: pretix/base/settings.py:2202 msgid "" "This will be prepended to the subject of all outgoing emails, formatted as " "[prefix]. Choose, for example, a short form of your event name." msgstr "" -#: pretix/base/settings.py:2178 pretix/control/forms/mailsetup.py:37 +#: pretix/base/settings.py:2216 pretix/control/forms/mailsetup.py:37 #: pretix/control/forms/mailsetup.py:119 #: pretix/control/templates/pretixcontrol/event/mail.html:39 #: pretix/control/templates/pretixcontrol/organizers/mail.html:40 msgid "Sender address" msgstr "" -#: pretix/base/settings.py:2179 pretix/control/forms/mailsetup.py:38 +#: pretix/base/settings.py:2217 pretix/control/forms/mailsetup.py:38 #: pretix/control/forms/mailsetup.py:120 msgid "Sender address for outgoing emails" msgstr "" -#: pretix/base/settings.py:2188 +#: pretix/base/settings.py:2226 msgid "Sender name" msgstr "" -#: pretix/base/settings.py:2189 +#: pretix/base/settings.py:2227 msgid "" "Sender name used in conjunction with the sender address for outgoing emails. " "Defaults to your event name." msgstr "" -#: pretix/base/settings.py:2207 pretix/base/settings.py:2264 -#: pretix/base/settings.py:2281 pretix/base/settings.py:2299 +#: pretix/base/settings.py:2245 pretix/base/settings.py:2302 +#: pretix/base/settings.py:2319 pretix/base/settings.py:2337 #, python-brace-format msgid "Your order: {code}" msgstr "" -#: pretix/base/settings.py:2211 pretix/base/settings.py:2244 -#: pretix/base/settings.py:2349 pretix/base/settings.py:2582 -#: pretix/base/settings.py:2619 +#: pretix/base/settings.py:2249 pretix/base/settings.py:2282 +#: pretix/base/settings.py:2387 pretix/base/settings.py:2620 +#: pretix/base/settings.py:2657 #, python-brace-format msgid "Your event registration: {code}" msgstr "" -#: pretix/base/settings.py:2215 +#: pretix/base/settings.py:2253 #, python-brace-format msgid "" "Hello,\n" @@ -9711,12 +10176,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2228 +#: pretix/base/settings.py:2266 #, python-brace-format msgid "Your orders for {event}" msgstr "" -#: pretix/base/settings.py:2232 +#: pretix/base/settings.py:2270 #, python-brace-format msgid "" "Hello,\n" @@ -9730,7 +10195,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2248 +#: pretix/base/settings.py:2286 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -9744,7 +10209,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2268 +#: pretix/base/settings.py:2306 #, python-brace-format msgid "" "Hello,\n" @@ -9759,7 +10224,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2285 +#: pretix/base/settings.py:2323 #, python-brace-format msgid "" "Hello,\n" @@ -9775,7 +10240,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2303 +#: pretix/base/settings.py:2341 #, python-brace-format msgid "" "Hello,\n" @@ -9793,11 +10258,11 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2321 +#: pretix/base/settings.py:2359 msgid "Attachment for new orders" msgstr "" -#: pretix/base/settings.py:2326 +#: pretix/base/settings.py:2364 #, python-brace-format msgid "" "This file will be attached to the first email that we send for every new " @@ -9809,7 +10274,7 @@ msgid "" "vital email going to spam, you can only upload PDF files of up to {size} MB." msgstr "" -#: pretix/base/settings.py:2353 +#: pretix/base/settings.py:2391 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -9823,12 +10288,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2365 +#: pretix/base/settings.py:2403 #, python-brace-format msgid "Your order has been changed: {code}" msgstr "" -#: pretix/base/settings.py:2369 +#: pretix/base/settings.py:2407 #, python-brace-format msgid "" "Hello,\n" @@ -9842,12 +10307,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2381 +#: pretix/base/settings.py:2419 #, python-brace-format msgid "Payment received for your order: {code}" msgstr "" -#: pretix/base/settings.py:2385 +#: pretix/base/settings.py:2423 #, python-brace-format msgid "" "Hello,\n" @@ -9863,12 +10328,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2403 +#: pretix/base/settings.py:2441 #, python-brace-format msgid "Event registration confirmed: {code}" msgstr "" -#: pretix/base/settings.py:2407 +#: pretix/base/settings.py:2445 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -9882,23 +10347,23 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2424 pretix/control/forms/event.py:1136 -#: pretix/control/forms/event.py:1236 pretix/plugins/sendmail/models.py:275 +#: pretix/base/settings.py:2462 pretix/control/forms/event.py:1129 +#: pretix/control/forms/event.py:1243 pretix/plugins/sendmail/models.py:275 msgid "Number of days" msgstr "" -#: pretix/base/settings.py:2426 pretix/control/forms/event.py:1139 +#: pretix/base/settings.py:2464 pretix/control/forms/event.py:1132 msgid "" "This email will be sent out this many days before the order expires. If the " "value is 0, the mail will never be sent." msgstr "" -#: pretix/base/settings.py:2434 +#: pretix/base/settings.py:2472 #, python-brace-format msgid "Your order is about to expire: {code}" msgstr "" -#: pretix/base/settings.py:2438 +#: pretix/base/settings.py:2476 #, python-brace-format msgid "" "Hello,\n" @@ -9914,12 +10379,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2452 +#: pretix/base/settings.py:2490 #, python-brace-format msgid "Your order is pending payment: {code}" msgstr "" -#: pretix/base/settings.py:2456 +#: pretix/base/settings.py:2494 #, python-brace-format msgid "" "Hello,\n" @@ -9934,12 +10399,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2469 +#: pretix/base/settings.py:2507 #, python-brace-format msgid "Incomplete payment received: {code}" msgstr "" -#: pretix/base/settings.py:2473 +#: pretix/base/settings.py:2511 #, python-brace-format msgid "" "Hello,\n" @@ -9957,12 +10422,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2489 +#: pretix/base/settings.py:2527 #, python-brace-format msgid "Payment failed for your order: {code}" msgstr "" -#: pretix/base/settings.py:2493 +#: pretix/base/settings.py:2531 #, python-brace-format msgid "" "Hello,\n" @@ -9980,12 +10445,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2507 +#: pretix/base/settings.py:2545 #, python-brace-format msgid "You have been selected from the waitinglist for {event}" msgstr "" -#: pretix/base/settings.py:2511 +#: pretix/base/settings.py:2549 #, python-brace-format msgid "" "Hello,\n" @@ -10016,12 +10481,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2540 +#: pretix/base/settings.py:2578 #, python-brace-format msgid "Order canceled: {code}" msgstr "" -#: pretix/base/settings.py:2544 +#: pretix/base/settings.py:2582 #, python-brace-format msgid "" "Hello,\n" @@ -10037,12 +10502,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2558 +#: pretix/base/settings.py:2596 #, python-brace-format msgid "Order approved and awaiting payment: {code}" msgstr "" -#: pretix/base/settings.py:2562 +#: pretix/base/settings.py:2600 #, python-brace-format msgid "" "Hello,\n" @@ -10060,7 +10525,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2586 pretix/base/settings.py:2623 +#: pretix/base/settings.py:2624 pretix/base/settings.py:2661 #, python-brace-format msgid "" "Hello,\n" @@ -10074,12 +10539,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2598 +#: pretix/base/settings.py:2636 #, python-brace-format msgid "Order approved and confirmed: {code}" msgstr "" -#: pretix/base/settings.py:2602 +#: pretix/base/settings.py:2640 #, python-brace-format msgid "" "Hello,\n" @@ -10094,12 +10559,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2635 +#: pretix/base/settings.py:2673 #, python-brace-format msgid "Order denied: {code}" msgstr "" -#: pretix/base/settings.py:2639 +#: pretix/base/settings.py:2677 #, python-brace-format msgid "" "Hello,\n" @@ -10116,7 +10581,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2654 +#: pretix/base/settings.py:2692 #, python-brace-format msgid "" "Hello,\n" @@ -10128,12 +10593,30 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2672 pretix/base/settings.py:2688 +#: pretix/base/settings.py:2702 +#, python-brace-format +msgid "Invoice {invoice_number}" +msgstr "" + +#: pretix/base/settings.py:2706 +#, python-brace-format +msgid "" +"Hello,\n" +"\n" +"please find attached a new invoice for order {code} for {event}. This order " +"has been placed by {order_email}.\n" +"\n" +"Best regards, \n" +"\n" +"Your {event} team" +msgstr "" + +#: pretix/base/settings.py:2724 pretix/base/settings.py:2740 #, python-brace-format msgid "Your ticket is ready for download: {code}" msgstr "" -#: pretix/base/settings.py:2676 +#: pretix/base/settings.py:2728 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -10147,7 +10630,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2692 +#: pretix/base/settings.py:2744 #, python-brace-format msgid "" "Hello,\n" @@ -10161,12 +10644,12 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/base/settings.py:2704 +#: pretix/base/settings.py:2756 #, python-brace-format msgid "Activate your account at {organizer}" msgstr "" -#: pretix/base/settings.py:2708 +#: pretix/base/settings.py:2760 #, python-brace-format msgid "" "Hello {name},\n" @@ -10186,12 +10669,12 @@ msgid "" "Your {organizer} team" msgstr "" -#: pretix/base/settings.py:2726 +#: pretix/base/settings.py:2778 #, python-brace-format msgid "Confirm email address for your account at {organizer}" msgstr "" -#: pretix/base/settings.py:2730 +#: pretix/base/settings.py:2782 #, python-brace-format msgid "" "Hello {name},\n" @@ -10211,12 +10694,12 @@ msgid "" "Your {organizer} team" msgstr "" -#: pretix/base/settings.py:2748 +#: pretix/base/settings.py:2800 #, python-brace-format msgid "Set a new password for your account at {organizer}" msgstr "" -#: pretix/base/settings.py:2752 +#: pretix/base/settings.py:2804 #, python-brace-format msgid "" "Hello {name},\n" @@ -10236,57 +10719,57 @@ msgid "" "Your {organizer} team" msgstr "" -#: pretix/base/settings.py:2804 pretix/base/settings.py:2811 -#: pretix/base/settings.py:2825 pretix/base/settings.py:2833 -#: pretix/base/settings.py:2847 pretix/base/settings.py:2855 -#: pretix/base/settings.py:2869 pretix/base/settings.py:2876 +#: pretix/base/settings.py:2856 pretix/base/settings.py:2863 +#: pretix/base/settings.py:2877 pretix/base/settings.py:2885 +#: pretix/base/settings.py:2899 pretix/base/settings.py:2907 +#: pretix/base/settings.py:2921 pretix/base/settings.py:2928 msgid "Please enter the hexadecimal code of a color, e.g. #990000." msgstr "" -#: pretix/base/settings.py:2808 +#: pretix/base/settings.py:2860 msgid "Primary color" msgstr "" -#: pretix/base/settings.py:2829 +#: pretix/base/settings.py:2881 msgid "Accent color for success" msgstr "" -#: pretix/base/settings.py:2830 +#: pretix/base/settings.py:2882 msgid "We strongly suggest to use a shade of green." msgstr "" -#: pretix/base/settings.py:2851 +#: pretix/base/settings.py:2903 msgid "Accent color for errors" msgstr "" -#: pretix/base/settings.py:2852 +#: pretix/base/settings.py:2904 msgid "We strongly suggest to use a shade of red." msgstr "" -#: pretix/base/settings.py:2873 +#: pretix/base/settings.py:2925 msgid "Page background color" msgstr "" -#: pretix/base/settings.py:2888 +#: pretix/base/settings.py:2940 msgid "Use round edges" msgstr "" -#: pretix/base/settings.py:2897 +#: pretix/base/settings.py:2949 msgid "" "Use native spinners in the widget instead of custom ones for numeric inputs " "such as quantity." msgstr "" -#: pretix/base/settings.py:2908 +#: pretix/base/settings.py:2960 msgid "Only respected by modern browsers." msgstr "" -#: pretix/base/settings.py:2919 pretix/base/settings.py:2963 +#: pretix/base/settings.py:2971 pretix/base/settings.py:3015 #: pretix/control/forms/organizer.py:523 msgid "Header image" msgstr "" -#: pretix/base/settings.py:2922 +#: pretix/base/settings.py:2974 msgid "" "If you provide a logo image, we will by default not show your event name and " "date in the page header. If you use a white background, we show your logo " @@ -10295,26 +10778,26 @@ msgid "" "using small details on the picture as it will be resized on smaller screens." msgstr "" -#: pretix/base/settings.py:2943 pretix/base/settings.py:2986 +#: pretix/base/settings.py:2995 pretix/base/settings.py:3038 msgid "Use header image in its full size" msgstr "" -#: pretix/base/settings.py:2944 pretix/base/settings.py:2987 +#: pretix/base/settings.py:2996 pretix/base/settings.py:3039 msgid "We recommend to upload a picture at least 1170 pixels wide." msgstr "" -#: pretix/base/settings.py:2953 +#: pretix/base/settings.py:3005 msgid "Show event title even if a header image is present" msgstr "" -#: pretix/base/settings.py:2954 +#: pretix/base/settings.py:3006 msgid "" "The title will only be shown on the event front page. If no header image is " "uploaded for the event, but the header image from the organizer profile is " "used, this option will be ignored and the event title will always be shown." msgstr "" -#: pretix/base/settings.py:2966 pretix/control/forms/organizer.py:527 +#: pretix/base/settings.py:3018 pretix/control/forms/organizer.py:527 msgid "" "If you provide a logo image, we will by default not show your organization " "name in the page header. If you use a white background, we show your logo " @@ -10323,25 +10806,25 @@ msgid "" "using small details on the picture as it will be resized on smaller screens." msgstr "" -#: pretix/base/settings.py:2996 +#: pretix/base/settings.py:3048 msgid "Use header image also for events without an individually uploaded logo" msgstr "" -#: pretix/base/settings.py:3004 +#: pretix/base/settings.py:3056 msgid "Favicon" msgstr "" -#: pretix/base/settings.py:3007 +#: pretix/base/settings.py:3059 msgid "" "If you provide a favicon, we will show it instead of the default pretix " "icon. We recommend a size of at least 200x200px to accommodate most devices." msgstr "" -#: pretix/base/settings.py:3023 +#: pretix/base/settings.py:3075 msgid "Social media image" msgstr "" -#: pretix/base/settings.py:3026 +#: pretix/base/settings.py:3078 msgid "" "This picture will be used as a preview if you post links to your ticket shop " "on social media. Facebook advises to use a picture size of 1200 x 630 " @@ -10350,93 +10833,93 @@ msgid "" "square is shown. If you do not fill this, we will use the logo given above." msgstr "" -#: pretix/base/settings.py:3044 +#: pretix/base/settings.py:3096 msgid "Logo image" msgstr "" -#: pretix/base/settings.py:3048 +#: pretix/base/settings.py:3100 msgid "We will show your logo with a maximal height and width of 2.5 cm." msgstr "" -#: pretix/base/settings.py:3074 pretix/base/settings.py:3180 +#: pretix/base/settings.py:3126 pretix/base/settings.py:3232 msgid "Info text" msgstr "" -#: pretix/base/settings.py:3077 pretix/base/settings.py:3182 +#: pretix/base/settings.py:3129 pretix/base/settings.py:3234 msgid "" "Not displayed anywhere by default, but if you want to, you can use this e.g. " "in ticket templates." msgstr "" -#: pretix/base/settings.py:3086 +#: pretix/base/settings.py:3138 msgid "Banner text (top)" msgstr "" -#: pretix/base/settings.py:3089 +#: pretix/base/settings.py:3141 msgid "" "This text will be shown above every page of your shop. Please only use this " "for very important messages." msgstr "" -#: pretix/base/settings.py:3099 +#: pretix/base/settings.py:3151 msgid "Banner text (bottom)" msgstr "" -#: pretix/base/settings.py:3102 +#: pretix/base/settings.py:3154 msgid "" "This text will be shown below every page of your shop. Please only use this " "for very important messages." msgstr "" -#: pretix/base/settings.py:3112 +#: pretix/base/settings.py:3164 msgid "Voucher explanation" msgstr "" -#: pretix/base/settings.py:3115 +#: pretix/base/settings.py:3167 msgid "" "This text will be shown next to the input for a voucher code. You can use it " "e.g. to explain how to obtain a voucher code." msgstr "" -#: pretix/base/settings.py:3125 +#: pretix/base/settings.py:3177 msgid "Attendee data explanation" msgstr "" -#: pretix/base/settings.py:3128 +#: pretix/base/settings.py:3180 msgid "" "This text will be shown above the questions asked for every personalized " "product. You can use it e.g. to explain why you need information from them." msgstr "" -#: pretix/base/settings.py:3138 +#: pretix/base/settings.py:3190 msgid "Additional success message" msgstr "" -#: pretix/base/settings.py:3139 +#: pretix/base/settings.py:3191 msgid "" "This message will be shown after an order has been created successfully. It " "will be shown in additional to the default text." msgstr "" -#: pretix/base/settings.py:3151 +#: pretix/base/settings.py:3203 msgid "Help text of the phone number field" msgstr "" -#: pretix/base/settings.py:3158 +#: pretix/base/settings.py:3210 msgid "" "Make sure to enter a valid email address. We will send you an order " "confirmation including a link that you need to access your order later." msgstr "" -#: pretix/base/settings.py:3165 +#: pretix/base/settings.py:3217 msgid "Help text of the email field" msgstr "" -#: pretix/base/settings.py:3191 +#: pretix/base/settings.py:3243 msgid "Allow creating a new team during event creation" msgstr "" -#: pretix/base/settings.py:3192 +#: pretix/base/settings.py:3244 msgid "" "Users that do not have access to all events under this organizer, must " "select one of their teams to have access to the created event. This setting " @@ -10444,67 +10927,68 @@ msgid "" "not have \"Can change teams and permissions\" permission." msgstr "" -#: pretix/base/settings.py:3264 pretix/base/settings.py:3274 +#: pretix/base/settings.py:3316 pretix/base/settings.py:3326 msgid "Event start time (descending)" msgstr "" -#: pretix/base/settings.py:3266 pretix/base/settings.py:3276 +#: pretix/base/settings.py:3318 pretix/base/settings.py:3328 msgid "Name (descending)" msgstr "" -#: pretix/base/settings.py:3271 +#: pretix/base/settings.py:3323 msgctxt "subevent" msgid "Date ordering" msgstr "" -#: pretix/base/settings.py:3287 +#: pretix/base/settings.py:3339 msgid "Link back to organizer overview on all event pages" msgstr "" -#: pretix/base/settings.py:3296 +#: pretix/base/settings.py:3348 msgid "Homepage text" msgstr "" -#: pretix/base/settings.py:3298 +#: pretix/base/settings.py:3350 msgid "This will be displayed on the organizer homepage." msgstr "" -#: pretix/base/settings.py:3313 +#: pretix/base/settings.py:3365 msgid "Length of gift card codes" msgstr "" -#: pretix/base/settings.py:3314 +#: pretix/base/settings.py:3366 +#, python-brace-format msgid "" "The system generates by default {}-character long gift card codes. However, " "if a different length is required, it can be set here." msgstr "" -#: pretix/base/settings.py:3330 +#: pretix/base/settings.py:3382 msgid "Validity of gift card codes in years" msgstr "" -#: pretix/base/settings.py:3331 +#: pretix/base/settings.py:3383 msgid "" "If you set a number here, gift cards will by default expire at the end of " "the year after this many years. If you keep it empty, gift cards do not have " "an explicit expiry date." msgstr "" -#: pretix/base/settings.py:3342 +#: pretix/base/settings.py:3394 msgid "Enable cookie consent management features" msgstr "" -#: pretix/base/settings.py:3348 +#: pretix/base/settings.py:3400 msgid "" "By clicking \"Accept all cookies\", you agree to the storing of cookies and " "use of similar technologies on your device." msgstr "" -#: pretix/base/settings.py:3355 +#: pretix/base/settings.py:3407 msgid "Dialog text" msgstr "" -#: pretix/base/settings.py:3362 +#: pretix/base/settings.py:3414 msgid "" "We use cookies and similar technologies to gather data that allows us to " "improve this website and our offerings. If you do not agree, we will only " @@ -10512,209 +10996,192 @@ msgid "" "offers." msgstr "" -#: pretix/base/settings.py:3370 +#: pretix/base/settings.py:3422 msgid "Secondary dialog text" msgstr "" -#: pretix/base/settings.py:3376 +#: pretix/base/settings.py:3428 msgid "Privacy settings" msgstr "" -#: pretix/base/settings.py:3381 +#: pretix/base/settings.py:3433 msgid "Dialog title" msgstr "" -#: pretix/base/settings.py:3387 +#: pretix/base/settings.py:3439 msgid "Accept all cookies" msgstr "" -#: pretix/base/settings.py:3392 +#: pretix/base/settings.py:3444 msgid "\"Accept\" button description" msgstr "" -#: pretix/base/settings.py:3398 +#: pretix/base/settings.py:3450 msgid "Required cookies only" msgstr "" -#: pretix/base/settings.py:3403 +#: pretix/base/settings.py:3455 msgid "\"Reject\" button description" msgstr "" -#: pretix/base/settings.py:3413 +#: pretix/base/settings.py:3465 msgid "Customers can choose their own seats" msgstr "" -#: pretix/base/settings.py:3414 +#: pretix/base/settings.py:3466 msgid "" "If disabled, you will need to manually assign seats in the backend. Note " "that this can mean people will not know their seat after their purchase and " "it might not be written on their ticket." msgstr "" -#: pretix/base/settings.py:3440 +#: pretix/base/settings.py:3492 msgid "Show button to copy user input from other products" msgstr "" -#: pretix/base/settings.py:3450 +#: pretix/base/settings.py:3502 msgid "Most common English titles" msgstr "" -#: pretix/base/settings.py:3460 +#: pretix/base/settings.py:3512 msgid "Most common German titles" msgstr "" -#: pretix/base/settings.py:3473 +#: pretix/base/settings.py:3525 msgctxt "person_name_salutation" msgid "Ms" msgstr "" -#: pretix/base/settings.py:3474 +#: pretix/base/settings.py:3526 msgctxt "person_name_salutation" msgid "Mr" msgstr "" -#: pretix/base/settings.py:3475 +#: pretix/base/settings.py:3527 msgctxt "person_name_salutation" msgid "Mx" msgstr "" -#: pretix/base/settings.py:3507 pretix/base/settings.py:3520 -#: pretix/base/settings.py:3536 pretix/base/settings.py:3586 -#: pretix/base/settings.py:3599 pretix/base/settings.py:3613 -#: pretix/base/settings.py:3666 pretix/base/settings.py:3687 -#: pretix/base/settings.py:3709 -msgid "Given name" -msgstr "" - -#: pretix/base/settings.py:3508 pretix/base/settings.py:3521 -#: pretix/base/settings.py:3537 pretix/base/settings.py:3553 -#: pretix/base/settings.py:3570 pretix/base/settings.py:3585 -#: pretix/base/settings.py:3600 pretix/base/settings.py:3614 -#: pretix/base/settings.py:3667 pretix/base/settings.py:3688 -#: pretix/base/settings.py:3710 -msgid "Family name" -msgstr "" - -#: pretix/base/settings.py:3512 pretix/base/settings.py:3528 -#: pretix/base/settings.py:3544 pretix/base/settings.py:3559 -#: pretix/base/settings.py:3577 pretix/base/settings.py:3592 -#: pretix/base/settings.py:3622 pretix/base/settings.py:3646 -#: pretix/base/settings.py:3678 pretix/base/settings.py:3700 -#: pretix/base/settings.py:3731 +#: pretix/base/settings.py:3564 pretix/base/settings.py:3580 +#: pretix/base/settings.py:3596 pretix/base/settings.py:3611 +#: pretix/base/settings.py:3629 pretix/base/settings.py:3644 +#: pretix/base/settings.py:3674 pretix/base/settings.py:3698 +#: pretix/base/settings.py:3730 pretix/base/settings.py:3752 +#: pretix/base/settings.py:3783 msgctxt "person_name_sample" msgid "John" msgstr "" -#: pretix/base/settings.py:3513 pretix/base/settings.py:3529 -#: pretix/base/settings.py:3545 pretix/base/settings.py:3561 -#: pretix/base/settings.py:3579 pretix/base/settings.py:3593 -#: pretix/base/settings.py:3623 pretix/base/settings.py:3679 -#: pretix/base/settings.py:3701 pretix/base/settings.py:3732 +#: pretix/base/settings.py:3565 pretix/base/settings.py:3581 +#: pretix/base/settings.py:3597 pretix/base/settings.py:3613 +#: pretix/base/settings.py:3631 pretix/base/settings.py:3645 +#: pretix/base/settings.py:3675 pretix/base/settings.py:3731 +#: pretix/base/settings.py:3753 pretix/base/settings.py:3784 msgctxt "person_name_sample" msgid "Doe" msgstr "" -#: pretix/base/settings.py:3519 pretix/base/settings.py:3535 -#: pretix/base/settings.py:3567 pretix/base/settings.py:3686 -#: pretix/base/settings.py:3708 +#: pretix/base/settings.py:3571 pretix/base/settings.py:3587 +#: pretix/base/settings.py:3619 pretix/base/settings.py:3738 +#: pretix/base/settings.py:3760 msgctxt "person_name" msgid "Title" msgstr "" -#: pretix/base/settings.py:3527 pretix/base/settings.py:3543 -#: pretix/base/settings.py:3576 pretix/base/settings.py:3699 -#: pretix/base/settings.py:3730 +#: pretix/base/settings.py:3579 pretix/base/settings.py:3595 +#: pretix/base/settings.py:3628 pretix/base/settings.py:3751 +#: pretix/base/settings.py:3782 msgctxt "person_name_sample" msgid "Dr" msgstr "" -#: pretix/base/settings.py:3551 pretix/base/settings.py:3568 +#: pretix/base/settings.py:3603 pretix/base/settings.py:3620 msgid "First name" msgstr "" -#: pretix/base/settings.py:3552 pretix/base/settings.py:3569 +#: pretix/base/settings.py:3604 pretix/base/settings.py:3621 msgid "Middle name" msgstr "" -#: pretix/base/settings.py:3633 pretix/base/settings.py:3645 -#: pretix/control/forms/organizer.py:655 +#: pretix/base/settings.py:3685 pretix/base/settings.py:3697 +#: pretix/control/forms/organizer.py:658 msgctxt "person_name_sample" msgid "John Doe" msgstr "" -#: pretix/base/settings.py:3639 +#: pretix/base/settings.py:3691 msgid "Calling name" msgstr "" -#: pretix/base/settings.py:3653 +#: pretix/base/settings.py:3705 msgid "Latin transcription" msgstr "" -#: pretix/base/settings.py:3665 pretix/base/settings.py:3685 -#: pretix/base/settings.py:3707 +#: pretix/base/settings.py:3717 pretix/base/settings.py:3737 +#: pretix/base/settings.py:3759 msgctxt "person_name" msgid "Salutation" msgstr "" -#: pretix/base/settings.py:3677 pretix/base/settings.py:3698 -#: pretix/base/settings.py:3729 +#: pretix/base/settings.py:3729 pretix/base/settings.py:3750 +#: pretix/base/settings.py:3781 msgctxt "person_name_sample" msgid "Mr" msgstr "" -#: pretix/base/settings.py:3711 +#: pretix/base/settings.py:3763 msgctxt "person_name" msgid "Degree (after name)" msgstr "" -#: pretix/base/settings.py:3733 +#: pretix/base/settings.py:3785 msgctxt "person_name_sample" msgid "MA" msgstr "" -#: pretix/base/settings.py:3759 pretix/base/settings.py:3761 +#: pretix/base/settings.py:3811 pretix/base/settings.py:3813 msgctxt "address" msgid "Province" msgstr "" -#: pretix/base/settings.py:3760 +#: pretix/base/settings.py:3812 msgctxt "address" msgid "Prefecture" msgstr "" -#: pretix/base/settings.py:3849 pretix/control/forms/event.py:229 +#: pretix/base/settings.py:3901 pretix/control/forms/event.py:228 msgid "" "Your default locale must also be enabled for your event (see box above)." msgstr "" -#: pretix/base/settings.py:3853 +#: pretix/base/settings.py:3905 msgid "" "You cannot require specifying attendee names if you do not ask for them." msgstr "" -#: pretix/base/settings.py:3857 +#: pretix/base/settings.py:3909 msgid "You have to ask for attendee emails if you want to make them required." msgstr "" -#: pretix/base/settings.py:3861 +#: pretix/base/settings.py:3913 msgid "" "You have to ask for invoice addresses if you want to make them required." msgstr "" -#: pretix/base/settings.py:3865 +#: pretix/base/settings.py:3917 msgid "You have to require invoice addresses to require for company names." msgstr "" -#: pretix/base/settings.py:3872 +#: pretix/base/settings.py:3924 msgid "The last payment date cannot be before the end of presale." msgstr "" -#: pretix/base/settings.py:3880 +#: pretix/base/settings.py:3932 #, python-brace-format msgid "The value \"{identifier}\" is not a valid sales channel." msgstr "" -#: pretix/base/settings.py:3895 +#: pretix/base/settings.py:3947 msgid "This needs to be disabled if other NFC-based types are active." msgstr "" @@ -10771,31 +11238,31 @@ msgid "" "changes to them." msgstr "" -#: pretix/base/shredder.py:535 +#: pretix/base/shredder.py:538 msgid "Question answers" msgstr "" -#: pretix/base/shredder.py:537 +#: pretix/base/shredder.py:540 msgid "" "This will remove all answers to questions, as well as logged changes to them." msgstr "" -#: pretix/base/shredder.py:579 +#: pretix/base/shredder.py:582 msgid "" "This will remove all invoice PDFs, as well as any of their text content that " "might contain personal data from the database. Invoice numbers and totals " "will be conserved." msgstr "" -#: pretix/base/shredder.py:608 +#: pretix/base/shredder.py:612 msgid "Cached ticket files" msgstr "" -#: pretix/base/shredder.py:610 +#: pretix/base/shredder.py:614 msgid "This will remove all cached ticket files. No download will be offered." msgstr "" -#: pretix/base/shredder.py:632 +#: pretix/base/shredder.py:636 msgid "" "This will remove payment-related information. Depending on the payment " "method, all data will be removed or personal data only. No download will be " @@ -10874,7 +11341,7 @@ msgid "You do not have access to this page." msgstr "" #: pretix/base/templates/403.html:20 pretix/base/templates/404.html:19 -#: pretix/control/templates/pretixcontrol/base.html:197 +#: pretix/control/templates/pretixcontrol/base.html:195 #: pretix/control/templates/pretixcontrol/user/staff_session_start.html:4 #: pretix/control/templates/pretixcontrol/user/staff_session_start.html:6 #: pretix/presale/templates/pretixpresale/event/offline.html:21 @@ -10985,7 +11452,7 @@ msgid "Event:" msgstr "" #: pretix/base/templates/pretixbase/email/order_details.html:23 -#: pretix/base/templates/pretixbase/email/order_details.html:74 +#: pretix/base/templates/pretixbase/email/order_details.html:80 msgid "Order code:" msgstr "" @@ -10994,7 +11461,7 @@ msgid "created by" msgstr "" #: pretix/base/templates/pretixbase/email/order_details.html:34 -#: pretix/base/templates/pretixbase/email/order_details.html:126 +#: pretix/base/templates/pretixbase/email/order_details.html:132 msgid "Contact:" msgstr "" @@ -11004,7 +11471,7 @@ msgid "" "event:" msgstr "" -#: pretix/base/templates/pretixbase/email/order_details.html:83 +#: pretix/base/templates/pretixbase/email/order_details.html:89 msgid "Details:" msgstr "" @@ -11501,11 +11968,15 @@ msgid "Support for check-in questions" msgstr "" #: pretix/control/forms/checkin.py:197 pretix/control/forms/checkin.py:213 -#: pretix/control/forms/filter.py:2395 pretix/control/forms/filter.py:2437 -#: pretix/control/forms/filter.py:2602 +#: pretix/control/forms/filter.py:2391 pretix/control/forms/filter.py:2433 +#: pretix/control/forms/filter.py:2598 msgid "All gates" msgstr "" +#: pretix/control/forms/checkin.py:222 +msgid "I am sure that the check-in state of the entire event should be reset." +msgstr "" + #: pretix/control/forms/event.py:91 msgid "Use languages" msgstr "" @@ -11518,469 +11989,466 @@ msgstr "" msgid "This is an event series" msgstr "" -#: pretix/control/forms/event.py:132 +#: pretix/control/forms/event.py:131 msgid "" "You already used this slug for a different event. Please choose a new one." msgstr "" -#: pretix/control/forms/event.py:136 pretix/control/forms/event.py:520 +#: pretix/control/forms/event.py:135 pretix/control/forms/event.py:519 msgid "Event timezone" msgstr "" -#: pretix/control/forms/event.py:143 +#: pretix/control/forms/event.py:142 msgid "I don't want to specify taxes now" msgstr "" -#: pretix/control/forms/event.py:144 +#: pretix/control/forms/event.py:143 msgid "You can always configure tax rates later." msgstr "" -#: pretix/control/forms/event.py:148 +#: pretix/control/forms/event.py:147 msgid "Sales tax rate" msgstr "" -#: pretix/control/forms/event.py:149 +#: pretix/control/forms/event.py:148 msgid "" "Do you need to pay sales tax on your tickets? In this case, please enter the " "applicable tax rate here in percent. If you have a more complicated tax " "situation, you can add more tax rates and detailed configuration later." msgstr "" -#: pretix/control/forms/event.py:158 +#: pretix/control/forms/event.py:157 msgid "Grant access to team" msgstr "" -#: pretix/control/forms/event.py:159 +#: pretix/control/forms/event.py:158 msgid "" "You are allowed to create events under this organizer, however you do not " "have permission to edit all events under this organizer. Please select one " "of your existing teams that will be granted access to this event." msgstr "" -#: pretix/control/forms/event.py:164 +#: pretix/control/forms/event.py:163 msgid "Create a new team for this event with me as the only member" msgstr "" -#: pretix/control/forms/event.py:208 pretix/control/forms/event.py:379 +#: pretix/control/forms/event.py:207 pretix/control/forms/event.py:378 msgid "" "Sample Conference Center\n" "Heidelberg, Germany" msgstr "" -#: pretix/control/forms/event.py:233 +#: pretix/control/forms/event.py:232 msgid "Your default locale must be specified." msgstr "" -#: pretix/control/forms/event.py:237 +#: pretix/control/forms/event.py:236 #, python-brace-format msgid "" "You have not specified a tax rate. If you do not want us to compute sales " "taxes, please check \"{field}\" above." msgstr "" -#: pretix/control/forms/event.py:312 +#: pretix/control/forms/event.py:311 msgid "Copy configuration from" msgstr "" -#: pretix/control/forms/event.py:318 pretix/control/forms/event.py:321 -#: pretix/control/forms/item.py:414 +#: pretix/control/forms/event.py:317 pretix/control/forms/event.py:320 +#: pretix/control/forms/item.py:413 msgid "Do not copy" msgstr "" -#: pretix/control/forms/event.py:337 pretix/control/forms/item.py:1300 -#: pretix/control/forms/subevents.py:414 +#: pretix/control/forms/event.py:336 pretix/control/forms/item.py:1301 +#: pretix/control/forms/subevents.py:410 #, python-brace-format msgid "Default ({value})" msgstr "" -#: pretix/control/forms/event.py:385 pretix/control/forms/event.py:398 +#: pretix/control/forms/event.py:384 pretix/control/forms/event.py:397 msgid "Domain" msgstr "" -#: pretix/control/forms/event.py:389 +#: pretix/control/forms/event.py:388 msgid "You can configure this in your organizer settings." msgstr "" -#: pretix/control/forms/event.py:399 +#: pretix/control/forms/event.py:398 msgid "You can add more domains in your organizer account." msgstr "" -#: pretix/control/forms/event.py:400 +#: pretix/control/forms/event.py:399 msgid "Same as organizer account" msgstr "" -#: pretix/control/forms/event.py:505 +#: pretix/control/forms/event.py:504 #, python-brace-format msgid "" "A validation error has occurred on a setting that is not part of this form: " "{error}" msgstr "" -#: pretix/control/forms/event.py:523 pretix/control/forms/organizer.py:461 +#: pretix/control/forms/event.py:522 pretix/control/forms/organizer.py:461 msgid "Name format" msgstr "" -#: pretix/control/forms/event.py:524 pretix/control/forms/organizer.py:462 +#: pretix/control/forms/event.py:523 pretix/control/forms/organizer.py:462 msgid "" "This defines how pretix will ask for human names. Changing this after you " "already received orders might lead to unexpected behavior when sorting or " "changing names." msgstr "" -#: pretix/control/forms/event.py:529 pretix/control/forms/organizer.py:467 +#: pretix/control/forms/event.py:528 pretix/control/forms/organizer.py:467 msgid "Allowed titles" msgstr "" -#: pretix/control/forms/event.py:530 pretix/control/forms/organizer.py:468 +#: pretix/control/forms/event.py:529 pretix/control/forms/organizer.py:468 msgid "" "If the naming scheme you defined above allows users to input a title, you " "can use this to restrict the set of selectable titles." msgstr "" -#: pretix/control/forms/event.py:649 pretix/control/forms/organizer.py:542 +#: pretix/control/forms/event.py:648 pretix/control/forms/organizer.py:542 #, python-brace-format msgid "Ask for {fields}, display like {example}" msgstr "" -#: pretix/control/forms/event.py:655 pretix/control/forms/organizer.py:548 +#: pretix/control/forms/event.py:654 pretix/control/forms/organizer.py:548 msgid "Free text input" msgstr "" -#: pretix/control/forms/event.py:691 +#: pretix/control/forms/event.py:690 msgid "Do not ask" msgstr "" -#: pretix/control/forms/event.py:692 +#: pretix/control/forms/event.py:691 msgid "Ask, but do not require input" msgstr "" -#: pretix/control/forms/event.py:693 +#: pretix/control/forms/event.py:692 #: pretix/control/templates/pretixcontrol/event/settings.html:76 msgid "Ask and require input" msgstr "" #: pretix/control/forms/event.py:770 +#, python-brace-format msgid "" "You have configured gift cards to be valid {} years plus the year the gift " "card is issued in." msgstr "" -#: pretix/control/forms/event.py:789 -msgid "Tax rule for payment fees" -msgstr "" - -#: pretix/control/forms/event.py:791 -msgid "" -"The tax rule that applies for additional fees you configured for single " -"payment methods. This will set the tax rate and reverse charge rules, other " -"settings of the tax rule are ignored." -msgstr "" - -#: pretix/control/forms/event.py:897 +#: pretix/control/forms/event.py:887 msgid "Generate invoices for Sales channels" msgstr "" -#: pretix/control/forms/event.py:900 +#: pretix/control/forms/event.py:890 msgid "" "If you have enabled invoice generation in the previous setting, you can " "limit it here to specific sales channels." msgstr "" -#: pretix/control/forms/event.py:904 +#: pretix/control/forms/event.py:894 msgid "Invoice style" msgstr "" -#: pretix/control/forms/event.py:910 +#: pretix/control/forms/event.py:900 msgid "Invoice language" msgstr "" -#: pretix/control/forms/event.py:911 pretix/control/forms/event.py:926 +#: pretix/control/forms/event.py:901 pretix/control/forms/event.py:916 msgid "The user's language" msgstr "" -#: pretix/control/forms/event.py:934 +#: pretix/control/forms/event.py:924 #, python-brace-format msgid "" "An invoice will be issued before payment if the customer selects one of the " "following payment methods: {list}" msgstr "" -#: pretix/control/forms/event.py:938 +#: pretix/control/forms/event.py:928 msgid "" "None of the currently configured payment methods will cause an invoice to be " "issued before payment." msgstr "" -#: pretix/control/forms/event.py:947 +#: pretix/control/forms/event.py:937 msgid "Recommended" msgstr "" -#: pretix/control/forms/event.py:959 +#: pretix/control/forms/event.py:949 msgid "The online shop must be selected to receive these emails." msgstr "" -#: pretix/control/forms/event.py:975 +#: pretix/control/forms/event.py:965 msgid "Sales channels for checkout emails" msgstr "" -#: pretix/control/forms/event.py:976 +#: pretix/control/forms/event.py:966 msgid "" "The order placed and paid emails will only be send to orders from these " "sales channels. The online shop must be enabled." msgstr "" -#: pretix/control/forms/event.py:987 +#: pretix/control/forms/event.py:977 msgid "" "This email will only be send to orders from these sales channels. The online " "shop must be enabled." msgstr "" -#: pretix/control/forms/event.py:995 pretix/control/forms/organizer.py:583 +#: pretix/control/forms/event.py:985 pretix/control/forms/organizer.py:583 msgid "Bcc address" msgstr "" -#: pretix/control/forms/event.py:996 pretix/control/forms/organizer.py:584 -msgid "All emails will be sent to this address as a Bcc copy" +#: pretix/control/forms/event.py:987 pretix/control/forms/organizer.py:585 +msgid "All emails will be sent to this address as a Bcc copy." msgstr "" -#: pretix/control/forms/event.py:1002 pretix/control/forms/organizer.py:590 +#: pretix/control/forms/event.py:995 pretix/control/forms/organizer.py:593 msgid "Signature" msgstr "" -#: pretix/control/forms/event.py:1005 +#: pretix/control/forms/event.py:998 #, python-brace-format msgid "This will be attached to every email. Available placeholders: {event}" msgstr "" -#: pretix/control/forms/event.py:1010 pretix/control/forms/organizer.py:598 +#: pretix/control/forms/event.py:1003 pretix/control/forms/organizer.py:601 msgid "e.g. your contact details" msgstr "" -#: pretix/control/forms/event.py:1015 +#: pretix/control/forms/event.py:1008 msgid "HTML mail renderer" msgstr "" -#: pretix/control/forms/event.py:1020 pretix/control/forms/event.py:1047 -#: pretix/control/forms/event.py:1074 pretix/control/forms/event.py:1210 +#: pretix/control/forms/event.py:1013 pretix/control/forms/event.py:1040 +#: pretix/control/forms/event.py:1067 pretix/control/forms/event.py:1217 msgid "Subject sent to order contact address" msgstr "" -#: pretix/control/forms/event.py:1025 pretix/control/forms/event.py:1052 -#: pretix/control/forms/event.py:1079 pretix/control/forms/event.py:1215 +#: pretix/control/forms/event.py:1018 pretix/control/forms/event.py:1045 +#: pretix/control/forms/event.py:1072 pretix/control/forms/event.py:1222 msgid "Text sent to order contact address" msgstr "" -#: pretix/control/forms/event.py:1030 pretix/control/forms/event.py:1057 -#: pretix/control/forms/event.py:1084 pretix/control/forms/event.py:1220 -#: pretix/control/forms/event.py:1265 pretix/control/forms/event.py:1295 +#: pretix/control/forms/event.py:1023 pretix/control/forms/event.py:1050 +#: pretix/control/forms/event.py:1077 pretix/control/forms/event.py:1227 +#: pretix/control/forms/event.py:1272 pretix/control/forms/event.py:1302 msgid "Send an email to attendees" msgstr "" -#: pretix/control/forms/event.py:1031 pretix/control/forms/event.py:1058 -#: pretix/control/forms/event.py:1085 pretix/control/forms/event.py:1221 -#: pretix/control/forms/event.py:1266 pretix/control/forms/event.py:1296 +#: pretix/control/forms/event.py:1024 pretix/control/forms/event.py:1051 +#: pretix/control/forms/event.py:1078 pretix/control/forms/event.py:1228 +#: pretix/control/forms/event.py:1273 pretix/control/forms/event.py:1303 msgid "" "If the order contains attendees with email addresses different from the " "person who orders the tickets, the following email will be sent out to the " "attendees." msgstr "" -#: pretix/control/forms/event.py:1036 pretix/control/forms/event.py:1063 -#: pretix/control/forms/event.py:1090 pretix/control/forms/event.py:1226 -#: pretix/control/forms/event.py:1271 pretix/control/forms/event.py:1301 +#: pretix/control/forms/event.py:1029 pretix/control/forms/event.py:1056 +#: pretix/control/forms/event.py:1083 pretix/control/forms/event.py:1233 +#: pretix/control/forms/event.py:1278 pretix/control/forms/event.py:1308 msgid "Subject sent to attendees" msgstr "" -#: pretix/control/forms/event.py:1041 pretix/control/forms/event.py:1068 -#: pretix/control/forms/event.py:1095 pretix/control/forms/event.py:1231 -#: pretix/control/forms/event.py:1276 pretix/control/forms/event.py:1306 +#: pretix/control/forms/event.py:1034 pretix/control/forms/event.py:1061 +#: pretix/control/forms/event.py:1088 pretix/control/forms/event.py:1238 +#: pretix/control/forms/event.py:1283 pretix/control/forms/event.py:1313 msgid "Text sent to attendees" msgstr "" -#: pretix/control/forms/event.py:1106 pretix/control/forms/event.py:1180 -#: pretix/control/forms/event.py:1190 pretix/control/forms/event.py:1200 -#: pretix/control/forms/event.py:1205 pretix/control/forms/organizer.py:609 -#: pretix/control/forms/organizer.py:619 pretix/control/forms/organizer.py:629 +#: pretix/control/forms/event.py:1099 pretix/control/forms/event.py:1173 +#: pretix/control/forms/event.py:1183 pretix/control/forms/event.py:1193 +#: pretix/control/forms/event.py:1198 pretix/control/forms/event.py:1210 +#: pretix/control/forms/organizer.py:612 pretix/control/forms/organizer.py:622 +#: pretix/control/forms/organizer.py:632 #: pretix/control/templates/pretixcontrol/event/mail.html:88 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:111 msgid "Text" msgstr "" -#: pretix/control/forms/event.py:1111 +#: pretix/control/forms/event.py:1104 msgid "Subject (sent by admin)" msgstr "" -#: pretix/control/forms/event.py:1116 +#: pretix/control/forms/event.py:1109 msgid "Subject (sent by admin to attendee)" msgstr "" -#: pretix/control/forms/event.py:1121 +#: pretix/control/forms/event.py:1114 msgid "Text (sent by admin)" msgstr "" -#: pretix/control/forms/event.py:1126 +#: pretix/control/forms/event.py:1119 msgid "Subject (requested by user)" msgstr "" -#: pretix/control/forms/event.py:1131 +#: pretix/control/forms/event.py:1124 msgid "Text (requested by user)" msgstr "" -#: pretix/control/forms/event.py:1143 +#: pretix/control/forms/event.py:1136 msgid "Text (if order will expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1148 +#: pretix/control/forms/event.py:1141 msgid "Subject (if order will expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1153 +#: pretix/control/forms/event.py:1146 msgid "Text (if order will not expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1158 +#: pretix/control/forms/event.py:1151 msgid "Subject (if order will not expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1163 +#: pretix/control/forms/event.py:1156 msgid "Subject (if an incomplete payment was received)" msgstr "" -#: pretix/control/forms/event.py:1168 +#: pretix/control/forms/event.py:1161 msgid "Text (if an incomplete payment was received)" msgstr "" -#: pretix/control/forms/event.py:1171 +#: pretix/control/forms/event.py:1164 msgid "" "This email only applies to payment methods that can receive incomplete " "payments, such as bank transfer." msgstr "" -#: pretix/control/forms/event.py:1239 +#: pretix/control/forms/event.py:1206 pretix/control/forms/event.py:1213 +msgid "" +"This will only be used if the invoice is sent to a different email address " +"or at a different time than the order confirmation." +msgstr "" + +#: pretix/control/forms/event.py:1246 msgid "" "This email will be sent out this many days before the order event starts. If " "the field is empty, the mail will never be sent." msgstr "" -#: pretix/control/forms/event.py:1243 +#: pretix/control/forms/event.py:1250 msgid "Subject for received order" msgstr "" -#: pretix/control/forms/event.py:1248 +#: pretix/control/forms/event.py:1255 msgid "Text for received order" msgstr "" -#: pretix/control/forms/event.py:1253 +#: pretix/control/forms/event.py:1260 msgid "Subject for approved order" msgstr "" -#: pretix/control/forms/event.py:1258 +#: pretix/control/forms/event.py:1265 msgid "Text for approved order" msgstr "" -#: pretix/control/forms/event.py:1261 pretix/control/forms/event.py:1279 +#: pretix/control/forms/event.py:1268 pretix/control/forms/event.py:1286 msgid "" "This will only be sent out for non-free orders. Free orders will receive the " "free order template from below instead." msgstr "" -#: pretix/control/forms/event.py:1283 +#: pretix/control/forms/event.py:1290 msgid "Subject for approved free order" msgstr "" -#: pretix/control/forms/event.py:1288 +#: pretix/control/forms/event.py:1295 msgid "Text for approved free order" msgstr "" -#: pretix/control/forms/event.py:1291 pretix/control/forms/event.py:1309 +#: pretix/control/forms/event.py:1298 pretix/control/forms/event.py:1316 msgid "" "This will only be sent out for free orders. Non-free orders will receive the " "non-free order template from above instead." msgstr "" -#: pretix/control/forms/event.py:1313 +#: pretix/control/forms/event.py:1320 msgid "Subject for denied order" msgstr "" -#: pretix/control/forms/event.py:1318 +#: pretix/control/forms/event.py:1325 msgid "Text for denied order" msgstr "" -#: pretix/control/forms/event.py:1411 +#: pretix/control/forms/event.py:1420 msgid "Ticket code generator" msgstr "" -#: pretix/control/forms/event.py:1412 +#: pretix/control/forms/event.py:1421 msgid "For advanced users, usually does not need to be changed." msgstr "" -#: pretix/control/forms/event.py:1469 +#: pretix/control/forms/event.py:1478 msgid "Any country" msgstr "" -#: pretix/control/forms/event.py:1470 +#: pretix/control/forms/event.py:1479 msgid "European Union" msgstr "" -#: pretix/control/forms/event.py:1496 +#: pretix/control/forms/event.py:1505 msgid "Any customer" msgstr "" -#: pretix/control/forms/event.py:1497 +#: pretix/control/forms/event.py:1506 msgid "Individual" msgstr "" -#: pretix/control/forms/event.py:1498 +#: pretix/control/forms/event.py:1507 msgid "Business" msgstr "" -#: pretix/control/forms/event.py:1499 +#: pretix/control/forms/event.py:1508 msgid "Business with valid VAT ID" msgstr "" -#: pretix/control/forms/event.py:1505 +#: pretix/control/forms/event.py:1514 msgid "Charge VAT" msgstr "" -#: pretix/control/forms/event.py:1507 +#: pretix/control/forms/event.py:1516 msgid "No VAT" msgstr "" -#: pretix/control/forms/event.py:1508 +#: pretix/control/forms/event.py:1517 msgid "Sale not allowed" msgstr "" -#: pretix/control/forms/event.py:1509 +#: pretix/control/forms/event.py:1518 msgid "Order requires approval" msgstr "" -#: pretix/control/forms/event.py:1514 +#: pretix/control/forms/event.py:1523 msgid "Default tax code" msgstr "" -#: pretix/control/forms/event.py:1518 +#: pretix/control/forms/event.py:1527 msgid "Deviating tax rate" msgstr "" -#: pretix/control/forms/event.py:1523 pretix/control/forms/event.py:1527 +#: pretix/control/forms/event.py:1532 pretix/control/forms/event.py:1536 msgid "Text on invoice" msgstr "" -#: pretix/control/forms/event.py:1547 +#: pretix/control/forms/event.py:1556 msgid "" "A combination of this calculation mode with a non-zero tax rate does not " "make sense." msgstr "" -#: pretix/control/forms/event.py:1552 pretix/control/forms/event.py:1556 +#: pretix/control/forms/event.py:1561 pretix/control/forms/event.py:1565 msgid "This combination of calculation mode and tax code does not make sense." msgstr "" -#: pretix/control/forms/event.py:1621 +#: pretix/control/forms/event.py:1630 msgid "Pre-selected voucher" msgstr "" -#: pretix/control/forms/event.py:1623 +#: pretix/control/forms/event.py:1632 msgid "" "If set, the widget will show products as if this voucher has been entered " "and when a product is bought via the widget, this voucher will be used. This " @@ -11988,48 +12456,48 @@ msgid "" "secret products." msgstr "" -#: pretix/control/forms/event.py:1628 +#: pretix/control/forms/event.py:1637 msgid "Compatibility mode" msgstr "" -#: pretix/control/forms/event.py:1630 +#: pretix/control/forms/event.py:1639 msgid "" "Our regular widget doesn't work in all website builders. If you run into " "trouble, try using this compatibility mode." msgstr "" -#: pretix/control/forms/event.py:1651 +#: pretix/control/forms/event.py:1660 msgid "The given voucher code does not exist." msgstr "" -#: pretix/control/forms/event.py:1658 pretix/control/forms/organizer.py:112 +#: pretix/control/forms/event.py:1667 pretix/control/forms/organizer.py:112 #: pretix/control/views/shredder.py:179 msgid "The slug you entered was not correct." msgstr "" -#: pretix/control/forms/event.py:1693 +#: pretix/control/forms/event.py:1702 msgid "Ticket downloads" msgstr "" -#: pretix/control/forms/event.py:1694 +#: pretix/control/forms/event.py:1703 msgid "Your customers will be able to download their tickets in PDF format." msgstr "" -#: pretix/control/forms/event.py:1698 +#: pretix/control/forms/event.py:1707 msgid "Require all attendees to fill in their names" msgstr "" -#: pretix/control/forms/event.py:1699 +#: pretix/control/forms/event.py:1708 msgid "" "By default, we will ask for names but not require them. You can turn this " "off completely in the settings." msgstr "" -#: pretix/control/forms/event.py:1725 +#: pretix/control/forms/event.py:1734 msgid "Payment via Stripe" msgstr "" -#: pretix/control/forms/event.py:1726 +#: pretix/control/forms/event.py:1735 msgid "" "Stripe is an online payments processor supporting credit cards and lots of " "other payment options. To accept payments via Stripe, you will need to set " @@ -12037,27 +12505,27 @@ msgid "" "simple interface." msgstr "" -#: pretix/control/forms/event.py:1732 +#: pretix/control/forms/event.py:1741 msgid "Payment by bank transfer" msgstr "" -#: pretix/control/forms/event.py:1733 +#: pretix/control/forms/event.py:1742 msgid "" "Your customers will be instructed to wire the money to your account. You can " "then import your bank statements to process the payments within pretix, or " "mark them as paid manually." msgstr "" -#: pretix/control/forms/event.py:1772 +#: pretix/control/forms/event.py:1781 #: pretix/control/templates/pretixcontrol/event/quick_setup.html:45 msgid "Price (optional)" msgstr "" -#: pretix/control/forms/event.py:1777 +#: pretix/control/forms/event.py:1786 msgid "Free" msgstr "" -#: pretix/control/forms/event.py:1782 +#: pretix/control/forms/event.py:1791 msgid "Quantity available" msgstr "" @@ -12090,10 +12558,11 @@ msgid "Paid or confirmed" msgstr "" #: pretix/control/forms/filter.py:217 +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:47 #: pretix/control/templates/pretixcontrol/items/question.html:28 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:19 #: pretix/control/templates/pretixcontrol/orders/overview.html:87 -#: pretix/plugins/reports/exporters.py:386 +#: pretix/plugins/reports/exporters.py:397 msgid "Pending" msgstr "" @@ -12167,7 +12636,7 @@ msgstr "" #: pretix/control/forms/filter.py:238 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:8 #: pretix/control/templates/pretixcontrol/orders/overview.html:79 -#: pretix/plugins/reports/exporters.py:380 +#: pretix/plugins/reports/exporters.py:391 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7 msgid "Approval pending" msgstr "" @@ -12180,28 +12649,28 @@ msgstr "" msgid "Follow-up due" msgstr "" -#: pretix/control/forms/filter.py:462 pretix/control/forms/filter.py:1898 -#: pretix/control/forms/filter.py:2153 pretix/control/forms/filter.py:2457 -#: pretix/control/forms/filter.py:2476 pretix/control/forms/vouchers.py:152 +#: pretix/control/forms/filter.py:462 pretix/control/forms/filter.py:1894 +#: pretix/control/forms/filter.py:2149 pretix/control/forms/filter.py:2453 +#: pretix/control/forms/filter.py:2472 pretix/control/forms/vouchers.py:151 #: pretix/control/templates/pretixcontrol/items/question.html:38 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:119 #: pretix/plugins/sendmail/models.py:251 msgid "All products" msgstr "" -#: pretix/control/forms/filter.py:466 pretix/control/forms/filter.py:2157 -#: pretix/control/forms/filter.py:2461 pretix/control/forms/vouchers.py:140 +#: pretix/control/forms/filter.py:466 pretix/control/forms/filter.py:2153 +#: pretix/control/forms/filter.py:2457 pretix/control/forms/vouchers.py:139 #: pretix/control/views/typeahead.py:657 pretix/control/views/typeahead.py:774 #, python-brace-format msgid "{product} – Any variation" msgstr "" -#: pretix/control/forms/filter.py:530 pretix/control/forms/orders.py:852 +#: pretix/control/forms/filter.py:530 pretix/control/forms/orders.py:862 msgctxt "subevent" msgid "All dates starting at or after" msgstr "" -#: pretix/control/forms/filter.py:536 pretix/control/forms/orders.py:859 +#: pretix/control/forms/filter.py:536 pretix/control/forms/orders.py:869 msgctxt "subevent" msgid "All dates starting before" msgstr "" @@ -12240,11 +12709,11 @@ msgstr "" #: pretix/control/forms/filter.py:891 pretix/control/forms/filter.py:896 #: pretix/control/forms/filter.py:1009 pretix/control/forms/filter.py:1014 -#: pretix/control/forms/filter.py:1685 pretix/control/forms/filter.py:1690 +#: pretix/control/forms/filter.py:1683 pretix/control/forms/filter.py:1688 msgid "All organizers" msgstr "" -#: pretix/control/forms/filter.py:1001 pretix/control/forms/filter.py:1669 +#: pretix/control/forms/filter.py:1001 pretix/control/forms/filter.py:1667 msgid "All events" msgstr "" @@ -12268,22 +12737,22 @@ msgstr "" msgid "Paid until" msgstr "" -#: pretix/control/forms/filter.py:1202 pretix/control/forms/filter.py:1671 +#: pretix/control/forms/filter.py:1202 pretix/control/forms/filter.py:1669 msgid "Shop live and presale running" msgstr "" -#: pretix/control/forms/filter.py:1203 pretix/control/forms/filter.py:2011 +#: pretix/control/forms/filter.py:1203 pretix/control/forms/filter.py:2007 msgid "Inactive" msgstr "" -#: pretix/control/forms/filter.py:1204 pretix/control/forms/filter.py:1673 +#: pretix/control/forms/filter.py:1204 pretix/control/forms/filter.py:1671 #: pretix/control/templates/pretixcontrol/events/index.html:153 #: pretix/control/templates/pretixcontrol/organizers/detail.html:117 #: pretix/control/templates/pretixcontrol/subevents/index.html:170 msgid "Presale not started" msgstr "" -#: pretix/control/forms/filter.py:1205 pretix/control/forms/filter.py:1674 +#: pretix/control/forms/filter.py:1205 pretix/control/forms/filter.py:1672 #: pretix/control/templates/pretixcontrol/events/index.html:151 #: pretix/control/templates/pretixcontrol/organizers/detail.html:115 #: pretix/control/templates/pretixcontrol/subevents/index.html:168 @@ -12291,15 +12760,15 @@ msgid "Presale over" msgstr "" #: pretix/control/forms/filter.py:1210 pretix/control/forms/filter.py:1213 -#: pretix/control/forms/filter.py:1702 pretix/control/forms/filter.py:1705 -#: pretix/control/forms/filter.py:2335 +#: pretix/control/forms/filter.py:1698 pretix/control/forms/filter.py:1701 +#: pretix/control/forms/filter.py:2331 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html:84 msgid "Date from" msgstr "" #: pretix/control/forms/filter.py:1217 pretix/control/forms/filter.py:1220 -#: pretix/control/forms/filter.py:1709 pretix/control/forms/filter.py:1712 -#: pretix/control/forms/filter.py:2340 +#: pretix/control/forms/filter.py:1705 pretix/control/forms/filter.py:1708 +#: pretix/control/forms/filter.py:2336 msgid "Date until" msgstr "" @@ -12316,16 +12785,16 @@ msgstr "" msgid "Weekday" msgstr "" -#: pretix/control/forms/filter.py:1437 pretix/control/forms/filter.py:1439 -#: pretix/control/forms/filter.py:1488 pretix/control/forms/filter.py:1490 -#: pretix/control/forms/filter.py:1560 pretix/control/forms/filter.py:1562 -#: pretix/control/forms/filter.py:1614 pretix/control/forms/filter.py:1616 -#: pretix/control/forms/filter.py:2025 pretix/control/forms/filter.py:2027 -#: pretix/control/forms/filter.py:2593 pretix/control/forms/filter.py:2595 +#: pretix/control/forms/filter.py:1435 pretix/control/forms/filter.py:1437 +#: pretix/control/forms/filter.py:1486 pretix/control/forms/filter.py:1488 +#: pretix/control/forms/filter.py:1558 pretix/control/forms/filter.py:1560 +#: pretix/control/forms/filter.py:1612 pretix/control/forms/filter.py:1614 +#: pretix/control/forms/filter.py:2021 pretix/control/forms/filter.py:2023 +#: pretix/control/forms/filter.py:2589 pretix/control/forms/filter.py:2591 msgid "Search query" msgstr "" -#: pretix/control/forms/filter.py:1499 pretix/control/forms/filter.py:1571 +#: pretix/control/forms/filter.py:1497 pretix/control/forms/filter.py:1569 #: pretix/control/templates/pretixcontrol/organizers/customer.html:46 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:47 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:54 @@ -12335,12 +12804,12 @@ msgstr "" msgid "active" msgstr "" -#: pretix/control/forms/filter.py:1501 +#: pretix/control/forms/filter.py:1499 #: pretix/control/templates/pretixcontrol/organizers/customer.html:44 msgid "not yet activated" msgstr "" -#: pretix/control/forms/filter.py:1505 +#: pretix/control/forms/filter.py:1503 #: pretix/control/templates/pretixcontrol/organizers/customer.html:110 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:6 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:12 @@ -12348,233 +12817,237 @@ msgstr "" msgid "Memberships" msgstr "" -#: pretix/control/forms/filter.py:1509 +#: pretix/control/forms/filter.py:1507 msgid "Has no memberships" msgstr "" -#: pretix/control/forms/filter.py:1510 +#: pretix/control/forms/filter.py:1508 msgid "Has any membership" msgstr "" -#: pretix/control/forms/filter.py:1511 +#: pretix/control/forms/filter.py:1509 msgid "Has valid membership" msgstr "" -#: pretix/control/forms/filter.py:1670 +#: pretix/control/forms/filter.py:1668 msgid "Shop live" msgstr "" -#: pretix/control/forms/filter.py:1672 +#: pretix/control/forms/filter.py:1670 msgid "Shop not live" msgstr "" -#: pretix/control/forms/filter.py:1675 +#: pretix/control/forms/filter.py:1673 msgid "Single event running or in the future" msgstr "" -#: pretix/control/forms/filter.py:1676 +#: pretix/control/forms/filter.py:1674 msgid "Single event in the past" msgstr "" -#: pretix/control/forms/filter.py:1877 pretix/control/forms/filter.py:1879 +#: pretix/control/forms/filter.py:1873 pretix/control/forms/filter.py:1875 msgid "Search attendee…" msgstr "" -#: pretix/control/forms/filter.py:1884 -#: pretix/plugins/checkinlists/exporters.py:105 +#: pretix/control/forms/filter.py:1880 +#: pretix/plugins/checkinlists/exporters.py:106 msgid "Check-in status" msgstr "" -#: pretix/control/forms/filter.py:1886 -#: pretix/plugins/checkinlists/exporters.py:107 +#: pretix/control/forms/filter.py:1882 +#: pretix/plugins/checkinlists/exporters.py:108 msgid "All attendees" msgstr "" -#: pretix/control/forms/filter.py:1887 +#: pretix/control/forms/filter.py:1883 #: pretix/control/templates/pretixcontrol/checkin/index.html:183 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:96 -#: pretix/plugins/checkinlists/exporters.py:108 -#: pretix/plugins/checkinlists/exporters.py:499 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:103 +#: pretix/plugins/checkinlists/exporters.py:109 +#: pretix/plugins/checkinlists/exporters.py:500 msgid "Checked in" msgstr "" -#: pretix/control/forms/filter.py:1888 -#: pretix/plugins/checkinlists/exporters.py:109 +#: pretix/control/forms/filter.py:1884 +#: pretix/plugins/checkinlists/exporters.py:110 msgctxt "checkin state" msgid "Present" msgstr "" -#: pretix/control/forms/filter.py:1889 -#: pretix/plugins/checkinlists/exporters.py:110 +#: pretix/control/forms/filter.py:1885 +#: pretix/plugins/checkinlists/exporters.py:111 msgctxt "checkin state" msgid "Checked in but left" msgstr "" -#: pretix/control/forms/filter.py:1890 +#: pretix/control/forms/filter.py:1886 #: pretix/control/templates/pretixcontrol/checkin/index.html:178 -#: pretix/plugins/checkinlists/exporters.py:111 +#: pretix/plugins/checkinlists/exporters.py:112 msgid "Not checked in" msgstr "" -#: pretix/control/forms/filter.py:1909 +#: pretix/control/forms/filter.py:1905 msgctxt "subevent" msgid "Date start from" msgstr "" -#: pretix/control/forms/filter.py:1915 +#: pretix/control/forms/filter.py:1911 msgctxt "subevent" msgid "Date start until" msgstr "" -#: pretix/control/forms/filter.py:2016 pretix/control/forms/filter.py:2019 +#: pretix/control/forms/filter.py:2012 pretix/control/forms/filter.py:2015 #: pretix/control/templates/pretixcontrol/users/index.html:52 msgid "Administrator" msgstr "" -#: pretix/control/forms/filter.py:2020 +#: pretix/control/forms/filter.py:2016 msgid "No administrator" msgstr "" -#: pretix/control/forms/filter.py:2090 +#: pretix/control/forms/filter.py:2086 msgid "Valid" msgstr "" -#: pretix/control/forms/filter.py:2091 +#: pretix/control/forms/filter.py:2087 msgid "Unredeemed" msgstr "" -#: pretix/control/forms/filter.py:2092 +#: pretix/control/forms/filter.py:2088 msgid "Redeemed at least once" msgstr "" -#: pretix/control/forms/filter.py:2093 +#: pretix/control/forms/filter.py:2089 msgid "Fully redeemed" msgstr "" -#: pretix/control/forms/filter.py:2095 +#: pretix/control/forms/filter.py:2091 msgid "Redeemed and checked in with ticket" msgstr "" -#: pretix/control/forms/filter.py:2100 +#: pretix/control/forms/filter.py:2096 msgid "Quota handling" msgstr "" -#: pretix/control/forms/filter.py:2104 +#: pretix/control/forms/filter.py:2100 msgid "Allow to ignore quota" msgstr "" -#: pretix/control/forms/filter.py:2109 pretix/control/forms/filter.py:2111 +#: pretix/control/forms/filter.py:2105 pretix/control/forms/filter.py:2107 msgid "Filter by tag" msgstr "" -#: pretix/control/forms/filter.py:2116 pretix/control/forms/filter.py:2118 +#: pretix/control/forms/filter.py:2112 pretix/control/forms/filter.py:2114 msgid "Search voucher" msgstr "" -#: pretix/control/forms/filter.py:2163 pretix/control/forms/vouchers.py:131 +#: pretix/control/forms/filter.py:2159 pretix/control/forms/vouchers.py:130 #: pretix/control/views/typeahead.py:782 pretix/control/views/typeahead.py:786 #: pretix/control/views/vouchers.py:132 #, python-brace-format msgid "Any product in quota \"{quota}\"" msgstr "" -#: pretix/control/forms/filter.py:2285 +#: pretix/control/forms/filter.py:2281 msgid "Refund status" msgstr "" -#: pretix/control/forms/filter.py:2287 +#: pretix/control/forms/filter.py:2283 msgid "All open refunds" msgstr "" -#: pretix/control/forms/filter.py:2288 +#: pretix/control/forms/filter.py:2284 msgid "All refunds" msgstr "" -#: pretix/control/forms/filter.py:2326 pretix/plugins/reports/exporters.py:688 +#: pretix/control/forms/filter.py:2322 pretix/plugins/reports/exporters.py:699 msgid "Date filter" msgstr "" -#: pretix/control/forms/filter.py:2328 pretix/plugins/reports/exporters.py:690 +#: pretix/control/forms/filter.py:2324 pretix/plugins/reports/exporters.py:701 msgid "Filter by…" msgstr "" -#: pretix/control/forms/filter.py:2330 pretix/plugins/reports/exporters.py:692 +#: pretix/control/forms/filter.py:2326 pretix/plugins/reports/exporters.py:703 msgid "Date of last successful payment" msgstr "" -#: pretix/control/forms/filter.py:2370 +#: pretix/control/forms/filter.py:2366 msgid "All check-ins" msgstr "" -#: pretix/control/forms/filter.py:2371 +#: pretix/control/forms/filter.py:2367 msgid "Successful check-ins" msgstr "" -#: pretix/control/forms/filter.py:2372 +#: pretix/control/forms/filter.py:2368 msgid "Unsuccessful check-ins" msgstr "" -#: pretix/control/forms/filter.py:2377 +#: pretix/control/forms/filter.py:2373 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:64 -#: pretix/plugins/checkinlists/exporters.py:755 +#: pretix/plugins/checkinlists/exporters.py:756 msgid "Scan type" msgstr "" -#: pretix/control/forms/filter.py:2379 +#: pretix/control/forms/filter.py:2375 msgid "All directions" msgstr "" -#: pretix/control/forms/filter.py:2388 pretix/control/forms/filter.py:2428 +#: pretix/control/forms/filter.py:2384 pretix/control/forms/filter.py:2424 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:67 -#: pretix/plugins/checkinlists/exporters.py:761 +#: pretix/plugins/checkinlists/exporters.py:762 msgid "Device" msgstr "" -#: pretix/control/forms/filter.py:2389 pretix/control/forms/filter.py:2424 -#: pretix/control/forms/filter.py:2615 +#: pretix/control/forms/filter.py:2385 pretix/control/forms/filter.py:2420 +#: pretix/control/forms/filter.py:2611 msgid "All devices" msgstr "" -#: pretix/control/forms/filter.py:2403 +#: pretix/control/forms/filter.py:2399 msgctxt "filter" msgid "Start date" msgstr "" -#: pretix/control/forms/filter.py:2409 +#: pretix/control/forms/filter.py:2405 msgctxt "filter" msgid "End date" msgstr "" -#: pretix/control/forms/filter.py:2451 pretix/control/forms/filter.py:2455 +#: pretix/control/forms/filter.py:2447 +#: pretix/plugins/checkinlists/exporters.py:880 +msgid "All check-in lists" +msgstr "" + +#: pretix/control/forms/filter.py:2451 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:64 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:10 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:25 -#: pretix/plugins/autocheckin/forms.py:179 -#: pretix/plugins/autocheckin/forms.py:183 +#: pretix/plugins/autocheckin/forms.py:182 #: pretix/plugins/autocheckin/models.py:46 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:29 -#: pretix/plugins/checkinlists/exporters.py:80 -#: pretix/plugins/checkinlists/exporters.py:153 -#: pretix/plugins/checkinlists/exporters.py:474 -#: pretix/plugins/checkinlists/exporters.py:754 -#: pretix/plugins/checkinlists/exporters.py:842 +#: pretix/plugins/checkinlists/exporters.py:81 +#: pretix/plugins/checkinlists/exporters.py:154 +#: pretix/plugins/checkinlists/exporters.py:475 +#: pretix/plugins/checkinlists/exporters.py:755 +#: pretix/plugins/checkinlists/exporters.py:843 msgid "Check-in list" msgstr "" -#: pretix/control/forms/filter.py:2606 +#: pretix/control/forms/filter.py:2602 #: pretix/control/templates/pretixcontrol/organizers/devices.html:82 msgid "Software" msgstr "" -#: pretix/control/forms/filter.py:2613 +#: pretix/control/forms/filter.py:2609 msgid "Device status" msgstr "" -#: pretix/control/forms/filter.py:2616 +#: pretix/control/forms/filter.py:2612 msgid "Active devices" msgstr "" -#: pretix/control/forms/filter.py:2617 +#: pretix/control/forms/filter.py:2613 msgid "Revoked devices" msgstr "" @@ -12775,46 +13248,51 @@ msgid "" "plugins. This will be publicly available. Make sure to keep it up to date!" msgstr "" -#: pretix/control/forms/item.py:100 +#: pretix/control/forms/item.py:98 msgid "" "Products in this category are regular products displayed on the front page." msgstr "" -#: pretix/control/forms/item.py:103 +#: pretix/control/forms/item.py:101 msgid "Add-on product category" msgstr "" -#: pretix/control/forms/item.py:104 +#: pretix/control/forms/item.py:102 msgid "" "Products in this category are add-on products and can only be bought as add-" "ons." msgstr "" -#: pretix/control/forms/item.py:108 +#: pretix/control/forms/item.py:106 msgid "" "Products in this category are regular products, but are only shown in the " "cross-selling step, according to the configuration below." msgstr "" -#: pretix/control/forms/item.py:113 +#: pretix/control/forms/item.py:111 msgid "" "Products in this category are regular products displayed on the front page, " "but are additionally shown in the cross-selling step, according to the " "configuration below." msgstr "" -#: pretix/control/forms/item.py:142 pretix/control/forms/item.py:218 +#: pretix/control/forms/item.py:140 pretix/control/forms/item.py:216 msgid "This field is required" msgstr "" -#: pretix/control/forms/item.py:220 +#: pretix/control/forms/item.py:218 msgid "Dependencies between questions are not supported during check-in." msgstr "" -#: pretix/control/forms/item.py:315 +#: pretix/control/forms/item.py:313 msgid "No products" msgstr "" +#: pretix/control/forms/item.py:353 +#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:11 +msgid "Unlimited" +msgstr "" + #: pretix/control/forms/item.py:381 msgid "The product should exist in multiple variations" msgstr "" @@ -12825,116 +13303,116 @@ msgid "" "select the variations in the next step." msgstr "" -#: pretix/control/forms/item.py:402 pretix/control/forms/item.py:727 +#: pretix/control/forms/item.py:402 pretix/control/forms/item.py:728 msgid "No category" msgstr "" -#: pretix/control/forms/item.py:409 -msgid "No taxation" -msgstr "" - -#: pretix/control/forms/item.py:411 +#: pretix/control/forms/item.py:410 msgid "Copy product information" msgstr "" -#: pretix/control/forms/item.py:422 -msgid "Do not add to a quota now" +#: pretix/control/forms/item.py:419 +msgid "No taxation" msgstr "" #: pretix/control/forms/item.py:423 -msgid "Add product to an existing quota" +msgid "Do not add to a quota now" msgstr "" #: pretix/control/forms/item.py:424 +msgid "Add product to an existing quota" +msgstr "" + +#: pretix/control/forms/item.py:425 msgid "Create a new quota for this product" msgstr "" -#: pretix/control/forms/item.py:430 +#: pretix/control/forms/item.py:431 msgid "Quota options" msgstr "" -#: pretix/control/forms/item.py:438 +#: pretix/control/forms/item.py:439 msgid "Add to existing quota" msgstr "" -#: pretix/control/forms/item.py:447 +#: pretix/control/forms/item.py:448 msgid "New quota name" msgstr "" -#: pretix/control/forms/item.py:453 +#: pretix/control/forms/item.py:454 msgid "Size" msgstr "" -#: pretix/control/forms/item.py:454 +#: pretix/control/forms/item.py:455 msgid "Number of tickets" msgstr "" -#: pretix/control/forms/item.py:586 +#: pretix/control/forms/item.py:587 msgid "Quota name is required." msgstr "" -#: pretix/control/forms/item.py:591 +#: pretix/control/forms/item.py:592 msgid "Please select a quota." msgstr "" -#: pretix/control/forms/item.py:613 pretix/plugins/badges/forms.py:85 +#: pretix/control/forms/item.py:614 pretix/plugins/badges/forms.py:85 #: pretix/plugins/ticketoutputpdf/forms.py:55 msgid "(Event default)" msgstr "" -#: pretix/control/forms/item.py:623 +#: pretix/control/forms/item.py:624 msgid "Choose automatically depending on event settings" msgstr "" -#: pretix/control/forms/item.py:624 +#: pretix/control/forms/item.py:625 msgid "Yes, if ticket generation is enabled in general" msgstr "" -#: pretix/control/forms/item.py:642 +#: pretix/control/forms/item.py:643 msgid "" "e.g. This reduced price is available for full-time students, jobless and " "people over 65. This ticket includes access to all parts of the event, " "except the VIP area." msgstr "" -#: pretix/control/forms/item.py:686 +#: pretix/control/forms/item.py:687 msgid "" "This option is deprecated. For new products, use the newer option below that " "refers to another product instead of a quota." msgstr "" -#: pretix/control/forms/item.py:697 pretix/control/forms/item.py:713 +#: pretix/control/forms/item.py:698 pretix/control/forms/item.py:714 msgid "Shown independently of other products" msgstr "" -#: pretix/control/forms/item.py:738 +#: pretix/control/forms/item.py:739 msgid "Date chosen by customer" msgstr "" -#: pretix/control/forms/item.py:747 +#: pretix/control/forms/item.py:748 msgid "No membership granted" msgstr "" -#: pretix/control/forms/item.py:766 +#: pretix/control/forms/item.py:767 msgid "" "Gift card products should use a tax rule with a rate of 0 percent since " "sales tax will be applied when the gift card is redeemed." msgstr "" -#: pretix/control/forms/item.py:772 +#: pretix/control/forms/item.py:773 msgid "" "Do not set a specific validity for gift card products as it will not " "restrict the validity of the gift card. A validity of gift cards can be set " "in your organizer settings." msgstr "" -#: pretix/control/forms/item.py:791 pretix/control/forms/item.py:1058 +#: pretix/control/forms/item.py:792 pretix/control/forms/item.py:1059 msgid "" "If a valid membership is required, at least one valid membership type needs " "to be selected." msgstr "" -#: pretix/control/forms/item.py:802 +#: pretix/control/forms/item.py:803 msgid "" "Your product grants a non-transferable membership and should therefore be a " "personalized admission ticket. Otherwise customers might not be able to use " @@ -12942,17 +13420,17 @@ msgid "" "the membership type to be transferable." msgstr "" -#: pretix/control/forms/item.py:811 +#: pretix/control/forms/item.py:812 msgid "The start of validity must be before the end of validity." msgstr "" -#: pretix/control/forms/item.py:818 +#: pretix/control/forms/item.py:819 msgid "" "You have selected dynamic validity but have not entered a time period. This " "would render the tickets unusable." msgstr "" -#: pretix/control/forms/item.py:923 +#: pretix/control/forms/item.py:924 #, python-format msgid "" "The variation \"%s\" cannot be deleted because it has already been ordered " @@ -12960,40 +13438,40 @@ msgid "" "\"inactive\" instead." msgstr "" -#: pretix/control/forms/item.py:1000 +#: pretix/control/forms/item.py:1001 msgid "Use value from product" msgstr "" -#: pretix/control/forms/item.py:1085 +#: pretix/control/forms/item.py:1086 msgid "Add-ons" msgstr "" -#: pretix/control/forms/item.py:1109 +#: pretix/control/forms/item.py:1110 msgid "You added the same add-on category twice" msgstr "" -#: pretix/control/forms/item.py:1154 +#: pretix/control/forms/item.py:1155 msgid "" "Be aware that setting a minimal number makes it impossible to buy this " "product if all available add-ons are sold out." msgstr "" -#: pretix/control/forms/item.py:1161 +#: pretix/control/forms/item.py:1162 msgid "Bundled products" msgstr "" -#: pretix/control/forms/item.py:1211 +#: pretix/control/forms/item.py:1212 msgid "You added the same bundled product twice." msgstr "" -#: pretix/control/forms/item.py:1217 +#: pretix/control/forms/item.py:1218 #: pretix/control/templates/pretixcontrol/item/include_bundles.html:23 #: pretix/control/templates/pretixcontrol/item/include_bundles.html:50 msgid "Bundled product" msgstr "" -#: pretix/control/forms/item.py:1242 pretix/control/forms/orders.py:367 -#: pretix/control/forms/orders.py:557 +#: pretix/control/forms/item.py:1243 pretix/control/forms/orders.py:379 +#: pretix/control/forms/orders.py:568 msgid "inactive" msgstr "" @@ -13049,35 +13527,68 @@ msgstr "" msgid "We were unable to resolve this hostname." msgstr "" -#: pretix/control/forms/modelimport.py:49 +#: pretix/control/forms/mapping.py:40 +msgid "Overwrite" +msgstr "" + +#: pretix/control/forms/mapping.py:41 +msgid "Fill if new" +msgstr "" + +#: pretix/control/forms/mapping.py:42 +msgid "Fill if empty" +msgstr "" + +#: pretix/control/forms/mapping.py:43 +msgid "Add to list" +msgstr "" + +#: pretix/control/forms/mapping.py:50 +msgid "pretix field" +msgstr "" + +#: pretix/control/forms/modelimport.py:50 #, python-brace-format msgid "CSV column: \"{name}\"" msgstr "" -#: pretix/control/forms/modelimport.py:74 +#: pretix/control/forms/modelimport.py:76 msgid "Import mode" msgstr "" -#: pretix/control/forms/modelimport.py:76 +#: pretix/control/forms/modelimport.py:78 msgid "Create a separate order for each line" msgstr "" -#: pretix/control/forms/modelimport.py:77 +#: pretix/control/forms/modelimport.py:79 msgid "Create one order with one position per line" msgstr "" -#: pretix/control/forms/modelimport.py:83 +#: pretix/control/forms/modelimport.py:80 +msgid "" +"Group multiple lines together into the same order based on a grouping column" +msgstr "" + +#: pretix/control/forms/modelimport.py:87 msgid "Create orders as fully paid" msgstr "" -#: pretix/control/forms/modelimport.py:84 +#: pretix/control/forms/modelimport.py:88 msgid "Create orders as pending and still require payment" msgstr "" -#: pretix/control/forms/modelimport.py:88 +#: pretix/control/forms/modelimport.py:93 msgid "Create orders as test mode orders" msgstr "" +#: pretix/control/forms/modelimport.py:112 +msgid "A grouping cannot be specified for this import mode." +msgstr "" + +#: pretix/control/forms/modelimport.py:114 +msgid "A grouping needs to be specified for this import mode." +msgstr "" + #: pretix/control/forms/orders.py:85 msgid "Confirm order regardless of payment" msgstr "" @@ -13115,8 +13626,8 @@ msgid "" "payments." msgstr "" -#: pretix/control/forms/orders.py:167 pretix/control/forms/orders.py:214 -#: pretix/control/forms/orders.py:228 +#: pretix/control/forms/orders.py:167 pretix/control/forms/orders.py:226 +#: pretix/control/forms/orders.py:240 msgid "Notify customer by email" msgstr "" @@ -13129,102 +13640,117 @@ msgid "" "If you keep a fee, all positions within this order will be canceled and the " "order will be reduced to a cancellation fee. Payment and shipping fees will " "be canceled as well, so include them in your cancellation fee if you want to " -"keep them. Please always enter a gross value, tax will be calculated " -"automatically." +"keep them." msgstr "" -#: pretix/control/forms/orders.py:181 +#: pretix/control/forms/orders.py:180 msgid "Generate cancellation for invoice" msgstr "" -#: pretix/control/forms/orders.py:186 pretix/control/forms/orders.py:218 +#: pretix/control/forms/orders.py:185 pretix/control/forms/orders.py:230 msgid "Comment (will be sent to the user)" msgstr "" -#: pretix/control/forms/orders.py:187 pretix/control/forms/orders.py:219 +#: pretix/control/forms/orders.py:186 pretix/control/forms/orders.py:231 msgid "" "Will be included in the notification email when the respective placeholder " "is present in the configured email text." msgstr "" -#: pretix/control/forms/orders.py:229 +#: pretix/control/forms/orders.py:204 +msgid "" +"Please enter a gross amount. As per your event settings, the taxes will be " +"split the same way as the order positions." +msgstr "" + +#: pretix/control/forms/orders.py:209 +msgid "" +"Please enter a gross amount. As per your event settings, the default tax " +"rate will be charged." +msgstr "" + +#: pretix/control/forms/orders.py:213 +msgid "As per your event settings, no tax will be charged." +msgstr "" + +#: pretix/control/forms/orders.py:241 msgid "A mail will only be sent if the order is fully paid after this." msgstr "" -#: pretix/control/forms/orders.py:236 +#: pretix/control/forms/orders.py:248 msgid "Payment amount" msgstr "" -#: pretix/control/forms/orders.py:240 +#: pretix/control/forms/orders.py:252 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:24 -#: pretix/plugins/reports/exporters.py:499 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:681 -#: pretix/plugins/reports/exporters.py:886 +#: pretix/plugins/reports/exporters.py:510 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:692 +#: pretix/plugins/reports/exporters.py:897 msgid "Payment date" msgstr "" -#: pretix/control/forms/orders.py:264 +#: pretix/control/forms/orders.py:276 msgid "Please select some events." msgstr "" -#: pretix/control/forms/orders.py:285 +#: pretix/control/forms/orders.py:297 msgid "Re-calculate taxes" msgstr "" -#: pretix/control/forms/orders.py:288 +#: pretix/control/forms/orders.py:300 msgid "Do not re-calculate taxes" msgstr "" -#: pretix/control/forms/orders.py:289 +#: pretix/control/forms/orders.py:301 msgid "" "Re-calculate taxes based on address and product settings, keep gross amount " "the same." msgstr "" -#: pretix/control/forms/orders.py:290 +#: pretix/control/forms/orders.py:302 msgid "" "Re-calculate taxes based on address and product settings, keep net amount " "the same." msgstr "" -#: pretix/control/forms/orders.py:295 +#: pretix/control/forms/orders.py:307 msgid "Issue a new invoice if required" msgstr "" -#: pretix/control/forms/orders.py:299 +#: pretix/control/forms/orders.py:311 msgid "" "If an invoice exists for this order and this operation would change its " "contents, the old invoice will be canceled and a new invoice will be issued." msgstr "" -#: pretix/control/forms/orders.py:304 +#: pretix/control/forms/orders.py:316 msgid "Notify user" msgstr "" -#: pretix/control/forms/orders.py:308 +#: pretix/control/forms/orders.py:320 msgid "" "Send an email to the customer notifying that their order has been changed." msgstr "" -#: pretix/control/forms/orders.py:312 +#: pretix/control/forms/orders.py:324 msgid "Allow to overbook quotas when performing this operation" msgstr "" -#: pretix/control/forms/orders.py:328 +#: pretix/control/forms/orders.py:340 msgid "Add-on to" msgstr "" -#: pretix/control/forms/orders.py:333 +#: pretix/control/forms/orders.py:345 #: pretix/control/templates/pretixcontrol/checkin/index.html:104 #: pretix/control/templates/pretixcontrol/order/change.html:127 #: pretix/control/views/vouchers.py:120 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:23 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:99 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:101 msgid "Seat" msgstr "" -#: pretix/control/forms/orders.py:336 +#: pretix/control/forms/orders.py:348 #: pretix/control/templates/pretixcontrol/order/change.html:182 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:5 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:9 @@ -13234,150 +13760,151 @@ msgstr "" msgid "Membership" msgstr "" -#: pretix/control/forms/orders.py:344 +#: pretix/control/forms/orders.py:356 msgid "Including taxes, if any. Keep empty for the product's default price" msgstr "" -#: pretix/control/forms/orders.py:459 pretix/control/forms/orders.py:463 -#: pretix/control/forms/orders.py:491 pretix/control/forms/orders.py:533 -#: pretix/control/forms/orders.py:552 pretix/control/forms/orders.py:570 -#: pretix/control/forms/orders.py:598 +#: pretix/control/forms/orders.py:470 pretix/control/forms/orders.py:474 +#: pretix/control/forms/orders.py:502 pretix/control/forms/orders.py:544 +#: pretix/control/forms/orders.py:563 pretix/control/forms/orders.py:581 +#: pretix/control/forms/orders.py:609 msgid "(Unchanged)" msgstr "" -#: pretix/control/forms/orders.py:469 pretix/control/forms/orders.py:593 +#: pretix/control/forms/orders.py:480 pretix/control/forms/orders.py:604 msgid "New price (gross)" msgstr "" -#: pretix/control/forms/orders.py:473 +#: pretix/control/forms/orders.py:484 msgid "Ticket is blocked" msgstr "" -#: pretix/control/forms/orders.py:478 +#: pretix/control/forms/orders.py:489 msgid "Validity start" msgstr "" -#: pretix/control/forms/orders.py:483 +#: pretix/control/forms/orders.py:494 msgid "Validity end" msgstr "" -#: pretix/control/forms/orders.py:495 +#: pretix/control/forms/orders.py:506 msgid "Generate a new secret" msgstr "" -#: pretix/control/forms/orders.py:496 +#: pretix/control/forms/orders.py:507 msgid "" "This affects both the ticket secret (often used as a QR code) as well as the " "link used to individually access the ticket." msgstr "" -#: pretix/control/forms/orders.py:501 +#: pretix/control/forms/orders.py:512 msgid "Cancel this position" msgstr "" -#: pretix/control/forms/orders.py:505 +#: pretix/control/forms/orders.py:516 msgid "Split into new order" msgstr "" -#: pretix/control/forms/orders.py:571 +#: pretix/control/forms/orders.py:582 msgid "(No membership)" msgstr "" -#: pretix/control/forms/orders.py:602 +#: pretix/control/forms/orders.py:613 msgid "Remove this fee" msgstr "" -#: pretix/control/forms/orders.py:620 +#: pretix/control/forms/orders.py:631 msgid "" "Note that payment fees have a special semantic and might automatically be " "changed if the payment method of the order is changed." msgstr "" -#: pretix/control/forms/orders.py:628 +#: pretix/control/forms/orders.py:639 #: pretix/control/templates/pretixcontrol/order/change.html:214 #: pretix/control/templates/pretixcontrol/order/change.html:438 msgid "including all taxes" msgstr "" -#: pretix/control/forms/orders.py:666 +#: pretix/control/forms/orders.py:677 msgid "Invalidate secrets" msgstr "" -#: pretix/control/forms/orders.py:667 +#: pretix/control/forms/orders.py:678 msgid "" "Regenerates the order and ticket secrets. You will need to re-send the link " "to the order page to the user and the user will need to download his tickets " "again. The old versions will be invalid." msgstr "" -#: pretix/control/forms/orders.py:724 pretix/plugins/sendmail/forms.py:196 +#: pretix/control/forms/orders.py:734 pretix/plugins/sendmail/forms.py:196 msgid "Attach tickets" msgstr "" -#: pretix/control/forms/orders.py:725 pretix/plugins/sendmail/forms.py:197 +#: pretix/control/forms/orders.py:735 pretix/plugins/sendmail/forms.py:197 msgid "" "Will be ignored if tickets exceed a given size limit to ensure email " "deliverability." msgstr "" -#: pretix/control/forms/orders.py:732 +#: pretix/control/forms/orders.py:742 msgid "Attach invoices" msgstr "" -#: pretix/control/forms/orders.py:753 +#: pretix/control/forms/orders.py:763 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:20 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:30 msgid "Recipient" msgstr "" -#: pretix/control/forms/orders.py:768 +#: pretix/control/forms/orders.py:778 #, python-brace-format msgid "Attach {file}" msgstr "" -#: pretix/control/forms/orders.py:796 +#: pretix/control/forms/orders.py:806 msgid "" "Cancel the order. All tickets will no longer work. This can not be reverted." msgstr "" -#: pretix/control/forms/orders.py:797 +#: pretix/control/forms/orders.py:807 msgid "" "Mark the order as pending and allow the user to pay the open amount with " "another payment method." msgstr "" -#: pretix/control/forms/orders.py:799 +#: pretix/control/forms/orders.py:809 msgid "Do nothing and keep the order as it is." msgstr "" -#: pretix/control/forms/orders.py:826 +#: pretix/control/forms/orders.py:836 +#, python-brace-format msgid "The refund amount needs to be positive and less than {}." msgstr "" -#: pretix/control/forms/orders.py:832 +#: pretix/control/forms/orders.py:842 msgid "You need to specify an amount for a partial refund." msgstr "" -#: pretix/control/forms/orders.py:844 +#: pretix/control/forms/orders.py:854 msgid "Cancel all dates" msgstr "" -#: pretix/control/forms/orders.py:863 +#: pretix/control/forms/orders.py:873 msgid "Automatically refund money if possible" msgstr "" -#: pretix/control/forms/orders.py:866 +#: pretix/control/forms/orders.py:876 msgid "" "Only available for payment method that support automatic refunds. Tickets " "that have been blocked (manually or by a plugin) are not auto-canceled and " "you will need to deal with them manually." msgstr "" -#: pretix/control/forms/orders.py:870 +#: pretix/control/forms/orders.py:880 msgid "Create refund in the manual refund to-do list" msgstr "" -#: pretix/control/forms/orders.py:873 +#: pretix/control/forms/orders.py:883 msgid "" "Manual refunds will be created which will be listed in the manual refund to-" "do list. When combined with the automatic refund functionally, only payments " @@ -13386,29 +13913,29 @@ msgid "" "orders by offsetting with different orders or issuing gift cards." msgstr "" -#: pretix/control/forms/orders.py:879 +#: pretix/control/forms/orders.py:889 msgid "" "Refund order value to a gift card instead instead of the original payment " "method" msgstr "" -#: pretix/control/forms/orders.py:885 +#: pretix/control/forms/orders.py:895 msgid "Gift card validity" msgstr "" -#: pretix/control/forms/orders.py:904 +#: pretix/control/forms/orders.py:914 msgid "Keep a fixed cancellation fee per ticket" msgstr "" -#: pretix/control/forms/orders.py:905 +#: pretix/control/forms/orders.py:915 msgid "Free tickets and add-on products are not counted" msgstr "" -#: pretix/control/forms/orders.py:915 +#: pretix/control/forms/orders.py:925 msgid "Keep fees" msgstr "" -#: pretix/control/forms/orders.py:918 +#: pretix/control/forms/orders.py:928 msgid "" "The selected types of fees will not be refunded but instead added to the " "cancellation fee. Fees are never refunded in when an order in an event " @@ -13416,20 +13943,20 @@ msgid "" "dates." msgstr "" -#: pretix/control/forms/orders.py:924 +#: pretix/control/forms/orders.py:934 msgid "Send information via email" msgstr "" -#: pretix/control/forms/orders.py:930 +#: pretix/control/forms/orders.py:940 msgid "Send information to waiting list" msgstr "" -#: pretix/control/forms/orders.py:945 pretix/control/forms/orders.py:971 +#: pretix/control/forms/orders.py:955 pretix/control/forms/orders.py:981 #, python-brace-format msgid "Canceled: {event}" msgstr "" -#: pretix/control/forms/orders.py:956 +#: pretix/control/forms/orders.py:966 #, python-brace-format msgid "" "Hello,\n" @@ -13447,7 +13974,7 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/control/forms/orders.py:983 +#: pretix/control/forms/orders.py:993 #, python-brace-format msgid "" "Hello,\n" @@ -13461,24 +13988,24 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/control/forms/orders.py:1015 pretix/plugins/sendmail/forms.py:115 +#: pretix/control/forms/orders.py:1025 pretix/plugins/sendmail/forms.py:115 #: pretix/plugins/sendmail/forms.py:208 msgctxt "subevent" msgid "Please either select a specific date or a date range, not both." msgstr "" -#: pretix/control/forms/orders.py:1017 +#: pretix/control/forms/orders.py:1027 msgctxt "subevent" msgid "Please either select all dates or a date range, not both." msgstr "" -#: pretix/control/forms/orders.py:1019 pretix/plugins/sendmail/forms.py:117 +#: pretix/control/forms/orders.py:1029 pretix/plugins/sendmail/forms.py:117 #: pretix/plugins/sendmail/forms.py:210 msgctxt "subevent" msgid "If you set a date range, please set both a start and an end." msgstr "" -#: pretix/control/forms/orders.py:1021 +#: pretix/control/forms/orders.py:1031 msgid "Please confirm that you want to cancel ALL dates in this event series." msgstr "" @@ -13533,76 +14060,76 @@ msgid "" "limited use cases and might change at any point." msgstr "" -#: pretix/control/forms/organizer.py:593 +#: pretix/control/forms/organizer.py:596 msgid "This will be attached to every email." msgstr "" -#: pretix/control/forms/organizer.py:685 +#: pretix/control/forms/organizer.py:688 msgctxt "webhooks" msgid "Event types" msgstr "" -#: pretix/control/forms/organizer.py:717 +#: pretix/control/forms/organizer.py:722 msgid "Gift card value" msgstr "" -#: pretix/control/forms/organizer.py:790 +#: pretix/control/forms/organizer.py:794 msgid "An medium with this type and identifier is already registered." msgstr "" -#: pretix/control/forms/organizer.py:891 +#: pretix/control/forms/organizer.py:892 msgid "An account with this customer ID is already registered." msgstr "" -#: pretix/control/forms/organizer.py:908 +#: pretix/control/forms/organizer.py:909 #: pretix/control/templates/pretixcontrol/organizers/customer.html:61 #: pretix/presale/forms/customer.py:169 pretix/presale/forms/customer.py:493 msgid "Phone" msgstr "" -#: pretix/control/forms/organizer.py:1015 +#: pretix/control/forms/organizer.py:1016 msgctxt "sso_oidc" msgid "Base URL" msgstr "" -#: pretix/control/forms/organizer.py:1019 +#: pretix/control/forms/organizer.py:1020 msgctxt "sso_oidc" msgid "Client ID" msgstr "" -#: pretix/control/forms/organizer.py:1023 +#: pretix/control/forms/organizer.py:1024 msgctxt "sso_oidc" msgid "Client secret" msgstr "" -#: pretix/control/forms/organizer.py:1027 +#: pretix/control/forms/organizer.py:1028 msgctxt "sso_oidc" msgid "Scope" msgstr "" -#: pretix/control/forms/organizer.py:1028 +#: pretix/control/forms/organizer.py:1029 msgctxt "sso_oidc" msgid "Multiple scopes separated with spaces." msgstr "" -#: pretix/control/forms/organizer.py:1032 +#: pretix/control/forms/organizer.py:1033 msgctxt "sso_oidc" msgid "User ID field" msgstr "" -#: pretix/control/forms/organizer.py:1033 +#: pretix/control/forms/organizer.py:1034 msgctxt "sso_oidc" msgid "" "We will assume that the contents of the user ID fields are unique and can " "never change for a user." msgstr "" -#: pretix/control/forms/organizer.py:1039 +#: pretix/control/forms/organizer.py:1040 msgctxt "sso_oidc" msgid "Email field" msgstr "" -#: pretix/control/forms/organizer.py:1040 +#: pretix/control/forms/organizer.py:1041 msgctxt "sso_oidc" msgid "" "We will assume that all email addresses received from the SSO provider are " @@ -13610,17 +14137,17 @@ msgid "" "security issues might arise." msgstr "" -#: pretix/control/forms/organizer.py:1047 +#: pretix/control/forms/organizer.py:1048 msgctxt "sso_oidc" msgid "Phone field" msgstr "" -#: pretix/control/forms/organizer.py:1051 +#: pretix/control/forms/organizer.py:1052 msgctxt "sso_oidc" msgid "Query parameters" msgstr "" -#: pretix/control/forms/organizer.py:1052 +#: pretix/control/forms/organizer.py:1053 #, python-brace-format msgctxt "sso_oidc" msgid "" @@ -13628,19 +14155,19 @@ msgid "" "endpoint. Enter as: {example}" msgstr "" -#: pretix/control/forms/organizer.py:1113 +#: pretix/control/forms/organizer.py:1114 msgid "Invalidate old client secret and generate a new one" msgstr "" -#: pretix/control/forms/organizer.py:1146 +#: pretix/control/forms/organizer.py:1147 msgid "Organizer short name" msgstr "" -#: pretix/control/forms/organizer.py:1150 +#: pretix/control/forms/organizer.py:1151 msgid "Allow access to reusable media" msgstr "" -#: pretix/control/forms/organizer.py:1151 +#: pretix/control/forms/organizer.py:1152 msgid "" "This is required if you want the other organizer to participate in a shared " "system with e.g. NFC payment chips. You should only use this option for " @@ -13649,18 +14176,22 @@ msgid "" "to interact with the media type." msgstr "" -#: pretix/control/forms/organizer.py:1167 +#: pretix/control/forms/organizer.py:1168 msgid "The selected organizer does not exist or cannot be invited." msgstr "" -#: pretix/control/forms/organizer.py:1169 +#: pretix/control/forms/organizer.py:1170 msgid "The selected organizer has already been invited." msgstr "" -#: pretix/control/forms/organizer.py:1204 +#: pretix/control/forms/organizer.py:1205 msgid "A sales channel with the same identifier already exists." msgstr "" +#: pretix/control/forms/organizer.py:1217 +msgid "Events with active plugin" +msgstr "" + #: pretix/control/forms/renderers.py:56 #: pretix/control/templates/pretixcontrol/items/question_edit.html:139 msgctxt "form" @@ -13737,19 +14268,19 @@ msgstr "" msgid "Keep the current values" msgstr "" -#: pretix/control/forms/subevents.py:135 pretix/control/forms/subevents.py:143 +#: pretix/control/forms/subevents.py:135 pretix/control/forms/subevents.py:141 msgid "Selection contains various values" msgstr "" -#: pretix/control/forms/subevents.py:292 pretix/control/forms/subevents.py:321 +#: pretix/control/forms/subevents.py:288 pretix/control/forms/subevents.py:317 msgid "The end of availability should be after the start of availability." msgstr "" -#: pretix/control/forms/subevents.py:354 +#: pretix/control/forms/subevents.py:350 msgid "Available_until" msgstr "" -#: pretix/control/forms/subevents.py:473 +#: pretix/control/forms/subevents.py:469 msgid "Exclude these dates instead of adding them." msgstr "" @@ -13757,40 +14288,40 @@ msgstr "" msgid "Your changes could not be saved. See below for details." msgstr "" -#: pretix/control/forms/vouchers.py:160 +#: pretix/control/forms/vouchers.py:159 msgid "Specific seat ID" msgstr "" -#: pretix/control/forms/vouchers.py:201 pretix/presale/forms/waitinglist.py:103 +#: pretix/control/forms/vouchers.py:200 pretix/presale/forms/waitinglist.py:103 msgid "Invalid product selected." msgstr "" -#: pretix/control/forms/vouchers.py:223 +#: pretix/control/forms/vouchers.py:225 msgid "" "The voucher only matches hidden products but you have not selected that it " "should show them." msgstr "" -#: pretix/control/forms/vouchers.py:262 +#: pretix/control/forms/vouchers.py:271 msgid "Codes" msgstr "" -#: pretix/control/forms/vouchers.py:264 +#: pretix/control/forms/vouchers.py:273 msgid "" "Add one voucher code per line. We suggest that you copy this list and save " "it into a file." msgstr "" -#: pretix/control/forms/vouchers.py:269 +#: pretix/control/forms/vouchers.py:278 msgid "Send vouchers via email" msgstr "" -#: pretix/control/forms/vouchers.py:276 +#: pretix/control/forms/vouchers.py:285 #, python-brace-format msgid "Your voucher for {event}" msgstr "" -#: pretix/control/forms/vouchers.py:282 +#: pretix/control/forms/vouchers.py:291 #, python-brace-format msgid "" "Hello,\n" @@ -13807,1345 +14338,1435 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/control/forms/vouchers.py:288 +#: pretix/control/forms/vouchers.py:297 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:28 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:42 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:25 msgid "Recipients" msgstr "" -#: pretix/control/forms/vouchers.py:292 +#: pretix/control/forms/vouchers.py:301 msgid "or" msgstr "" -#: pretix/control/forms/vouchers.py:296 +#: pretix/control/forms/vouchers.py:305 msgid "" "You can either supply a list of email addresses with one email address per " -"line, or the contents of a CSV file with a title column and one or more of " -"the columns \"email\", \"number\", \"name\", or \"tag\"." +"line, or the contents of a CSV file with a title row and one or more of the " +"columns \"email\", \"number\", \"name\", or \"tag\"." msgstr "" -#: pretix/control/forms/vouchers.py:330 +#: pretix/control/forms/vouchers.py:339 msgid "Maximum usages per voucher" msgstr "" -#: pretix/control/forms/vouchers.py:333 +#: pretix/control/forms/vouchers.py:342 msgid "Number of times times EACH of these vouchers can be redeemed." msgstr "" -#: pretix/control/forms/vouchers.py:347 +#: pretix/control/forms/vouchers.py:356 msgid "Specific seat IDs" msgstr "" -#: pretix/control/forms/vouchers.py:364 +#: pretix/control/forms/vouchers.py:373 msgid "CSV input needs to contain a header row in the first line." msgstr "" -#: pretix/control/forms/vouchers.py:369 +#: pretix/control/forms/vouchers.py:378 #, python-brace-format msgid "CSV parsing failed: {error}." msgstr "" -#: pretix/control/forms/vouchers.py:371 +#: pretix/control/forms/vouchers.py:380 msgid "" "CSV input was not recognized to have multiple columns, maybe you have some " "invalid quoted field in your input." msgstr "" -#: pretix/control/forms/vouchers.py:373 +#: pretix/control/forms/vouchers.py:382 #, python-brace-format msgid "CSV input needs to contain a field with the header \"{header}\"." msgstr "" -#: pretix/control/forms/vouchers.py:376 +#: pretix/control/forms/vouchers.py:385 #, python-brace-format msgid "CSV input contains an unknown field with the header \"{header}\"." msgstr "" -#: pretix/control/forms/vouchers.py:381 pretix/control/forms/vouchers.py:396 +#: pretix/control/forms/vouchers.py:390 pretix/control/forms/vouchers.py:405 #, python-brace-format msgid "{value} is not a valid email address." msgstr "" -#: pretix/control/forms/vouchers.py:390 +#: pretix/control/forms/vouchers.py:399 #, python-brace-format msgid "Invalid value in row {number}." msgstr "" -#: pretix/control/forms/vouchers.py:409 +#: pretix/control/forms/vouchers.py:418 msgid "A voucher with one of these codes already exists." msgstr "" -#: pretix/control/forms/vouchers.py:416 +#: pretix/control/forms/vouchers.py:425 #, python-brace-format msgid "" "The voucher code {code} is too short. Make sure all voucher codes are at " "least {min_length} characters long." msgstr "" -#: pretix/control/forms/vouchers.py:423 +#: pretix/control/forms/vouchers.py:432 #, python-brace-format msgid "The voucher code {code} appears in your list twice." msgstr "" -#: pretix/control/forms/vouchers.py:427 +#: pretix/control/forms/vouchers.py:436 msgid "" "If vouchers should be sent by email, subject, message and recipients need to " "be specified." msgstr "" -#: pretix/control/forms/vouchers.py:434 +#: pretix/control/forms/vouchers.py:443 #, python-brace-format msgid "" "You generated {codes} vouchers, but entered recipients for {recp} vouchers." msgstr "" -#: pretix/control/forms/vouchers.py:439 +#: pretix/control/forms/vouchers.py:448 msgid "You need to specify as many seats as voucher codes." msgstr "" -#: pretix/control/logdisplay.py:71 pretix/control/logdisplay.py:81 +#: pretix/control/logdisplay.py:73 pretix/control/logdisplay.py:83 msgid "The order has been changed:" msgstr "" -#: pretix/control/logdisplay.py:98 +#: pretix/control/logdisplay.py:100 #, python-brace-format msgid "" "Position #{posid}: {old_item} ({old_price}) changed to {new_item} " "({new_price})." msgstr "" -#: pretix/control/logdisplay.py:109 +#: pretix/control/logdisplay.py:111 #, python-brace-format msgid "Position #{posid}: Used membership changed." msgstr "" -#: pretix/control/logdisplay.py:115 +#: pretix/control/logdisplay.py:117 #, python-brace-format msgid "Position #{posid}: Seat \"{old_seat}\" changed to \"{new_seat}\"." msgstr "" -#: pretix/control/logdisplay.py:125 +#: pretix/control/logdisplay.py:127 #, python-brace-format msgid "" "Position #{posid}: Event date \"{old_event}\" ({old_price}) changed to " "\"{new_event}\" ({new_price})." msgstr "" -#: pretix/control/logdisplay.py:139 +#: pretix/control/logdisplay.py:141 #, python-brace-format msgid "Price of position #{posid} changed from {old_price} to {new_price}." msgstr "" -#: pretix/control/logdisplay.py:152 +#: pretix/control/logdisplay.py:154 #, python-brace-format msgid "Tax rule of position #{posid} changed from {old_rule} to {new_rule}." msgstr "" -#: pretix/control/logdisplay.py:158 +#: pretix/control/logdisplay.py:160 #, python-brace-format msgid "Tax rule of fee #{fee} changed from {old_rule} to {new_rule}." msgstr "" -#: pretix/control/logdisplay.py:168 +#: pretix/control/logdisplay.py:170 msgid "A fee has been added" msgstr "" -#: pretix/control/logdisplay.py:176 +#: pretix/control/logdisplay.py:178 #, python-brace-format msgid "A fee was changed from {old_price} to {new_price}." msgstr "" -#: pretix/control/logdisplay.py:187 +#: pretix/control/logdisplay.py:189 #, python-brace-format msgid "A fee of {old_price} was removed." msgstr "" -#: pretix/control/logdisplay.py:200 +#: pretix/control/logdisplay.py:202 #, python-brace-format msgid "Position #{posid} ({old_item}, {old_price}) canceled." msgstr "" -#: pretix/control/logdisplay.py:217 +#: pretix/control/logdisplay.py:219 #, python-brace-format msgid "" "Position #{posid} created: {item} ({price}) as an add-on to position " "#{addon_to}." msgstr "" -#: pretix/control/logdisplay.py:223 +#: pretix/control/logdisplay.py:225 #, python-brace-format msgid "Position #{posid} created: {item} ({price})." msgstr "" -#: pretix/control/logdisplay.py:233 +#: pretix/control/logdisplay.py:235 #, python-brace-format msgid "A new secret has been generated for position #{posid}." msgstr "" -#: pretix/control/logdisplay.py:241 +#: pretix/control/logdisplay.py:243 #, python-brace-format msgid "" "The validity start date for position #{posid} has been changed to {value}." msgstr "" -#: pretix/control/logdisplay.py:253 +#: pretix/control/logdisplay.py:255 #, python-brace-format msgid "" "The validity end date for position #{posid} has been changed to {value}." msgstr "" -#: pretix/control/logdisplay.py:262 +#: pretix/control/logdisplay.py:264 #, python-brace-format msgid "A block has been added for position #{posid}." msgstr "" -#: pretix/control/logdisplay.py:268 +#: pretix/control/logdisplay.py:270 #, python-brace-format msgid "A block has been removed for position #{posid}." msgstr "" -#: pretix/control/logdisplay.py:285 +#: pretix/control/logdisplay.py:287 #, python-brace-format msgid "" "Position #{posid} ({old_item}, {old_price}) split into new order: {order}" msgstr "" -#: pretix/control/logdisplay.py:304 +#: pretix/control/logdisplay.py:306 #, python-brace-format msgid "This order has been created by splitting the order {order}" msgstr "" -#: pretix/control/logdisplay.py:311 +#: pretix/control/logdisplay.py:313 #, python-brace-format msgid "" "Unknown scan of code \"{barcode}…\" at {datetime} for list \"{list}\", type " "\"{type}\"." msgstr "" -#: pretix/control/logdisplay.py:312 +#: pretix/control/logdisplay.py:314 #, python-brace-format msgid "" "Unknown scan of code \"{barcode}…\" for list \"{list}\", type \"{type}\"." msgstr "" -#: pretix/control/logdisplay.py:315 +#: pretix/control/logdisplay.py:317 #, python-brace-format msgid "" "Scan of revoked code \"{barcode}…\" at {datetime} for list \"{list}\", type " "\"{type}\", was uploaded." msgstr "" -#: pretix/control/logdisplay.py:316 +#: pretix/control/logdisplay.py:318 #, python-brace-format msgid "" "Scan of revoked code \"{barcode}\" for list \"{list}\", type \"{type}\", was " "uploaded." msgstr "" -#: pretix/control/logdisplay.py:319 +#: pretix/control/logdisplay.py:321 #, python-brace-format msgid "" "Denied scan of position #{posid} at {datetime} for list \"{list}\", type " "\"{type}\", error code \"{errorcode}\"." msgstr "" -#: pretix/control/logdisplay.py:320 +#: pretix/control/logdisplay.py:322 #, python-brace-format msgid "" "Denied scan of position #{posid} for list \"{list}\", type \"{type}\", error " "code \"{errorcode}\"." msgstr "" -#: pretix/control/logdisplay.py:322 pretix/control/logdisplay.py:323 +#: pretix/control/logdisplay.py:325 +#, python-brace-format +msgid "" +"Annulled scan of position #{posid} at {datetime} for list \"{list}\", type " +"\"{type}\"." +msgstr "" + +#: pretix/control/logdisplay.py:326 +#, python-brace-format +msgid "" +"Annulled scan of position #{posid} for list \"{list}\", type \"{type}\"." +msgstr "" + +#: pretix/control/logdisplay.py:329 +#, python-brace-format +msgid "" +"Ignored annulment of position #{posid} at {datetime} for list \"{list}\", " +"type \"{type}\"." +msgstr "" + +#: pretix/control/logdisplay.py:330 +#, python-brace-format +msgid "" +"Ignored annulment of position #{posid} for list \"{list}\", type \"{type}\"." +msgstr "" + +#: pretix/control/logdisplay.py:332 pretix/control/logdisplay.py:333 #, python-brace-format msgid "The check-in of position #{posid} on list \"{list}\" has been reverted." msgstr "" -#: pretix/control/logdisplay.py:343 pretix/control/logdisplay.py:345 -#: pretix/control/logdisplay.py:887 pretix/control/logdisplay.py:889 +#: pretix/control/logdisplay.py:353 pretix/control/logdisplay.py:355 +#: pretix/control/logdisplay.py:968 pretix/control/logdisplay.py:970 msgid "(unknown)" msgstr "" -#: pretix/control/logdisplay.py:365 +#: pretix/control/logdisplay.py:375 #, python-brace-format msgid "" "Position #{posid} has been checked out at {datetime} for list \"{list}\"." msgstr "" -#: pretix/control/logdisplay.py:366 +#: pretix/control/logdisplay.py:376 #, python-brace-format msgid "Position #{posid} has been checked out for list \"{list}\"." msgstr "" -#: pretix/control/logdisplay.py:370 +#: pretix/control/logdisplay.py:380 #, python-brace-format msgid "" "Position #{posid} has been checked in at {datetime} for list \"{list}\"." msgstr "" -#: pretix/control/logdisplay.py:371 +#: pretix/control/logdisplay.py:381 #, python-brace-format msgid "Position #{posid} has been checked in for list \"{list}\"." msgstr "" -#: pretix/control/logdisplay.py:375 +#: pretix/control/logdisplay.py:385 #, python-brace-format msgid "" "A scan for position #{posid} at {datetime} for list \"{list}\" has been " "uploaded even though it has been scanned already." msgstr "" -#: pretix/control/logdisplay.py:381 +#: pretix/control/logdisplay.py:391 #, python-brace-format msgid "" "Position #{posid} has been scanned and rejected because it has already been " "scanned before on list \"{list}\"." msgstr "" -#: pretix/control/logdisplay.py:392 -msgid "The user confirmed the following message: \"{}\"" -msgstr "" - -#: pretix/control/logdisplay.py:404 +#: pretix/control/logdisplay.py:402 #, python-brace-format -msgid "The order has been canceled (comment: \"{comment}\")." -msgstr "" - -#: pretix/control/logdisplay.py:406 pretix/control/views/orders.py:1574 -#: pretix/presale/views/order.py:1049 -msgid "The order has been canceled." +msgid "The user confirmed the following message: \"{}\"" msgstr "" #: pretix/control/logdisplay.py:414 #, python-brace-format +msgid "The order has been canceled (comment: \"{comment}\")." +msgstr "" + +#: pretix/control/logdisplay.py:416 pretix/control/views/orders.py:1561 +#: pretix/presale/views/order.py:1049 +msgid "The order has been canceled." +msgstr "" + +#: pretix/control/logdisplay.py:424 +#, python-brace-format msgid "Position #{posid} has been printed at {datetime} with type \"{type}\"." msgstr "" -#: pretix/control/logdisplay.py:428 pretix/control/logdisplay.py:737 -msgid "The settings of a payment provider have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:431 pretix/control/logdisplay.py:736 -msgid "The settings of a ticket output provider have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:437 -msgid "Blocked manually" -msgstr "" - -#: pretix/control/logdisplay.py:439 -msgid "Blocked because of an API integration" -msgstr "" - -#: pretix/control/logdisplay.py:443 -#, python-brace-format -msgid "The test mode order {code} has been deleted." -msgstr "" - -#: pretix/control/logdisplay.py:444 -msgid "The order details have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:445 -msgid "The order has been marked as unpaid." -msgstr "" - #: pretix/control/logdisplay.py:446 -msgid "The order's secret has been changed." -msgstr "" - -#: pretix/control/logdisplay.py:447 -msgid "The order's expiry date has been changed." -msgstr "" - -#: pretix/control/logdisplay.py:448 -msgid "The order has been set to be usable before it is paid." -msgstr "" - -#: pretix/control/logdisplay.py:449 -msgid "The order has been set to require payment before use." -msgstr "" - -#: pretix/control/logdisplay.py:450 pretix/control/views/orders.py:1579 -msgid "The order has been marked as expired." -msgstr "" - -#: pretix/control/logdisplay.py:451 pretix/control/views/orders.py:1477 -msgid "The order has been marked as paid." -msgstr "" - -#: pretix/control/logdisplay.py:452 -msgid "The cancellation request has been deleted." -msgstr "" - -#: pretix/control/logdisplay.py:453 -msgid "The order has been refunded." -msgstr "" - -#: pretix/control/logdisplay.py:454 pretix/control/views/orders.py:1862 -msgid "The order has been reactivated." -msgstr "" - -#: pretix/control/logdisplay.py:455 -msgid "The order has been created." -msgstr "" - -#: pretix/control/logdisplay.py:457 -msgid "The order requires approval before it can continue to be processed." -msgstr "" - -#: pretix/control/logdisplay.py:458 pretix/control/views/orders.py:801 -msgid "The order has been approved." -msgstr "" - -#: pretix/control/logdisplay.py:459 #, python-brace-format -msgid "The order has been denied (comment: \"{comment}\")." -msgstr "" - -#: pretix/control/logdisplay.py:460 -#, python-brace-format -msgid "" -"The email address has been changed from \"{old_email}\" to \"{new_email}\"." -msgstr "" - -#: pretix/control/logdisplay.py:463 -msgid "" -"The email address has been confirmed to be working (the user clicked on a " -"link in the email for the first time)." +msgid "Data successfully transferred to {provider_display_name}." msgstr "" #: pretix/control/logdisplay.py:465 #, python-brace-format msgid "" -"The phone number has been changed from \"{old_phone}\" to \"{new_phone}\"." +"Transferring data to {provider_display_name} failed due to invalid " +"configuration:" +msgstr "" + +#: pretix/control/logdisplay.py:466 +#, python-brace-format +msgid "" +"Maximum number of retries exceeded while transferring data to " +"{provider_display_name}:" msgstr "" #: pretix/control/logdisplay.py:467 +#, python-brace-format +msgid "Error while transferring data to {provider_display_name}:" +msgstr "" + +#: pretix/control/logdisplay.py:468 pretix/control/logdisplay.py:469 +#, python-brace-format +msgid "Internal error while transferring data to {provider_display_name}." +msgstr "" + +#: pretix/control/logdisplay.py:483 pretix/control/logdisplay.py:818 +msgid "The settings of a payment provider have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:486 pretix/control/logdisplay.py:817 +msgid "The settings of a ticket output provider have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:492 +msgid "Blocked manually" +msgstr "" + +#: pretix/control/logdisplay.py:494 +msgid "Blocked because of an API integration" +msgstr "" + +#: pretix/control/logdisplay.py:498 +#, python-brace-format +msgid "The test mode order {code} has been deleted." +msgstr "" + +#: pretix/control/logdisplay.py:499 +msgid "The order details have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:500 +msgid "The order has been marked as unpaid." +msgstr "" + +#: pretix/control/logdisplay.py:501 +msgid "The order's secret has been changed." +msgstr "" + +#: pretix/control/logdisplay.py:502 +msgid "The order's expiry date has been changed." +msgstr "" + +#: pretix/control/logdisplay.py:503 +msgid "The order has been set to be usable before it is paid." +msgstr "" + +#: pretix/control/logdisplay.py:504 +msgid "The order has been set to require payment before use." +msgstr "" + +#: pretix/control/logdisplay.py:505 pretix/control/views/orders.py:1566 +msgid "The order has been marked as expired." +msgstr "" + +#: pretix/control/logdisplay.py:506 pretix/control/views/orders.py:1465 +msgid "The order has been marked as paid." +msgstr "" + +#: pretix/control/logdisplay.py:507 +msgid "The cancellation request has been deleted." +msgstr "" + +#: pretix/control/logdisplay.py:508 +msgid "The order has been refunded." +msgstr "" + +#: pretix/control/logdisplay.py:509 pretix/control/views/orders.py:1882 +msgid "The order has been reactivated." +msgstr "" + +#: pretix/control/logdisplay.py:510 +msgid "The order has been created." +msgstr "" + +#: pretix/control/logdisplay.py:512 +msgid "The order requires approval before it can continue to be processed." +msgstr "" + +#: pretix/control/logdisplay.py:513 pretix/control/views/orders.py:786 +msgid "The order has been approved." +msgstr "" + +#: pretix/control/logdisplay.py:514 +#, python-brace-format +msgid "The order has been denied (comment: \"{comment}\")." +msgstr "" + +#: pretix/control/logdisplay.py:515 +#, python-brace-format +msgid "" +"The email address has been changed from \"{old_email}\" to \"{new_email}\"." +msgstr "" + +#: pretix/control/logdisplay.py:518 +msgid "" +"The email address has been confirmed to be working (the user clicked on a " +"link in the email for the first time)." +msgstr "" + +#: pretix/control/logdisplay.py:520 +#, python-brace-format +msgid "" +"The phone number has been changed from \"{old_phone}\" to \"{new_phone}\"." +msgstr "" + +#: pretix/control/logdisplay.py:522 msgid "The customer account has been changed." msgstr "" -#: pretix/control/logdisplay.py:468 +#: pretix/control/logdisplay.py:523 msgid "The order locale has been changed." msgstr "" -#: pretix/control/logdisplay.py:469 pretix/control/views/orders.py:1618 +#: pretix/control/logdisplay.py:524 pretix/control/views/orders.py:1605 #: pretix/presale/views/order.py:741 pretix/presale/views/order.py:814 msgid "The invoice has been generated." msgstr "" -#: pretix/control/logdisplay.py:470 pretix/control/views/orders.py:1689 +#: pretix/control/logdisplay.py:525 pretix/control/views/orders.py:1678 msgid "The invoice has been regenerated." msgstr "" -#: pretix/control/logdisplay.py:471 pretix/control/views/orders.py:1720 +#: pretix/control/logdisplay.py:526 pretix/control/views/orders.py:1740 #: pretix/presale/views/order.py:827 msgid "The invoice has been reissued." msgstr "" -#: pretix/control/logdisplay.py:472 +#: pretix/control/logdisplay.py:527 +#, python-brace-format +msgid "The invoice {full_invoice_no} has been sent." +msgstr "" + +#: pretix/control/logdisplay.py:528 +#, python-brace-format +msgid "The transmission of invoice {full_invoice_no} has failed." +msgstr "" + +#: pretix/control/logdisplay.py:529 +#, python-brace-format +msgid "" +"Invoice {full_invoice_no} has not been transmitted because the transmission " +"provider does not support test mode invoices." +msgstr "" + +#: pretix/control/logdisplay.py:531 +#, python-brace-format +msgid "The invoice {full_invoice_no} has been scheduled for retransmission." +msgstr "" + +#: pretix/control/logdisplay.py:532 msgid "The order's internal comment has been updated." msgstr "" -#: pretix/control/logdisplay.py:473 +#: pretix/control/logdisplay.py:533 msgid "The order's follow-up date has been updated." msgstr "" -#: pretix/control/logdisplay.py:474 +#: pretix/control/logdisplay.py:534 msgid "The order's flag to require attention at check-in has been toggled." msgstr "" -#: pretix/control/logdisplay.py:476 +#: pretix/control/logdisplay.py:536 msgid "The order's check-in text has been changed." msgstr "" -#: pretix/control/logdisplay.py:477 +#: pretix/control/logdisplay.py:537 msgid "" "The order's flag to be considered valid even if unpaid has been toggled." msgstr "" -#: pretix/control/logdisplay.py:479 +#: pretix/control/logdisplay.py:539 #, python-brace-format msgid "A new payment {local_id} has been started instead of the previous one." msgstr "" -#: pretix/control/logdisplay.py:480 +#: pretix/control/logdisplay.py:540 msgid "An unidentified type email has been sent." msgstr "" -#: pretix/control/logdisplay.py:481 pretix/control/logdisplay.py:666 +#: pretix/control/logdisplay.py:541 pretix/control/logdisplay.py:727 msgid "Sending of an email has failed." msgstr "" -#: pretix/control/logdisplay.py:482 +#: pretix/control/logdisplay.py:542 msgid "" "The email has been sent without attached tickets since they would have been " "too large to be likely to arrive." msgstr "" -#: pretix/control/logdisplay.py:484 +#: pretix/control/logdisplay.py:544 +msgid "An invoice email has been sent." +msgstr "" + +#: pretix/control/logdisplay.py:545 msgid "A custom email has been sent." msgstr "" -#: pretix/control/logdisplay.py:485 +#: pretix/control/logdisplay.py:546 msgid "A custom email has been sent to an attendee." msgstr "" -#: pretix/control/logdisplay.py:486 +#: pretix/control/logdisplay.py:547 msgid "" "An email has been sent with a reminder that the ticket is available for " "download." msgstr "" -#: pretix/control/logdisplay.py:488 +#: pretix/control/logdisplay.py:549 msgid "" "An email has been sent with a warning that the order is about to expire." msgstr "" -#: pretix/control/logdisplay.py:491 +#: pretix/control/logdisplay.py:552 msgid "" "An email has been sent to notify the user that the order has been canceled." msgstr "" -#: pretix/control/logdisplay.py:492 +#: pretix/control/logdisplay.py:553 msgid "" "An email has been sent to notify the user that the event has been canceled." msgstr "" -#: pretix/control/logdisplay.py:495 +#: pretix/control/logdisplay.py:556 msgid "" "An email has been sent to notify the user that the order has been changed." msgstr "" -#: pretix/control/logdisplay.py:497 +#: pretix/control/logdisplay.py:558 msgid "" "An email has been sent to notify the user that the order has been received." msgstr "" -#: pretix/control/logdisplay.py:499 +#: pretix/control/logdisplay.py:560 msgid "" "An email has been sent to notify the user that payment has been received." msgstr "" -#: pretix/control/logdisplay.py:501 +#: pretix/control/logdisplay.py:562 msgid "" "An email has been sent to notify the user that the order has been denied." msgstr "" -#: pretix/control/logdisplay.py:502 +#: pretix/control/logdisplay.py:563 msgid "" "An email has been sent to notify the user that the order has been approved." msgstr "" -#: pretix/control/logdisplay.py:505 +#: pretix/control/logdisplay.py:566 msgid "" "An email has been sent to notify the user that the order has been received " "and requires payment." msgstr "" -#: pretix/control/logdisplay.py:506 +#: pretix/control/logdisplay.py:567 msgid "" "An email has been sent to notify the user that the order has been received " "and requires approval." msgstr "" -#: pretix/control/logdisplay.py:509 +#: pretix/control/logdisplay.py:570 msgid "" "An email with a link to the order detail page has been resent to the user." msgstr "" -#: pretix/control/logdisplay.py:510 +#: pretix/control/logdisplay.py:571 msgid "An email has been sent to notify the user that the payment failed." msgstr "" -#: pretix/control/logdisplay.py:517 +#: pretix/control/logdisplay.py:578 msgid "The voucher has been created." msgstr "" -#: pretix/control/logdisplay.py:519 -msgid "The voucher has been created and sent to a person on the waiting list." -msgstr "" - -#: pretix/control/logdisplay.py:521 +#: pretix/control/logdisplay.py:581 msgid "" "The voucher has been set to expire because the recipient removed themselves " "from the waiting list." msgstr "" -#: pretix/control/logdisplay.py:522 +#: pretix/control/logdisplay.py:582 msgid "The voucher has been changed." msgstr "" -#: pretix/control/logdisplay.py:523 +#: pretix/control/logdisplay.py:583 msgid "The voucher has been deleted." msgstr "" -#: pretix/control/logdisplay.py:532 +#: pretix/control/logdisplay.py:584 +#, python-brace-format +msgid "The voucher has been sent to {email} through the waiting list." +msgstr "" + +#: pretix/control/logdisplay.py:593 #, python-brace-format msgid "The voucher has been redeemed in order {order_code}." msgstr "" -#: pretix/control/logdisplay.py:547 +#: pretix/control/logdisplay.py:608 msgid "The category has been added." msgstr "" -#: pretix/control/logdisplay.py:548 +#: pretix/control/logdisplay.py:609 msgid "The category has been deleted." msgstr "" -#: pretix/control/logdisplay.py:549 +#: pretix/control/logdisplay.py:610 msgid "The category has been changed." msgstr "" -#: pretix/control/logdisplay.py:550 +#: pretix/control/logdisplay.py:611 msgid "The category has been reordered." msgstr "" -#: pretix/control/logdisplay.py:557 +#: pretix/control/logdisplay.py:618 msgid "The tax rule has been added." msgstr "" -#: pretix/control/logdisplay.py:558 +#: pretix/control/logdisplay.py:619 msgid "The tax rule has been deleted." msgstr "" -#: pretix/control/logdisplay.py:559 +#: pretix/control/logdisplay.py:620 msgid "The tax rule has been changed." msgstr "" -#: pretix/control/logdisplay.py:571 +#: pretix/control/logdisplay.py:632 #, python-brace-format msgid "{user} has been added to the team." msgstr "" -#: pretix/control/logdisplay.py:572 +#: pretix/control/logdisplay.py:633 #, python-brace-format msgid "{user} has been removed from the team." msgstr "" -#: pretix/control/logdisplay.py:573 +#: pretix/control/logdisplay.py:634 #, python-brace-format msgid "{user} has been invited to the team." msgstr "" -#: pretix/control/logdisplay.py:574 +#: pretix/control/logdisplay.py:635 #, python-brace-format msgid "Invite for {user} has been resent." msgstr "" -#: pretix/control/logdisplay.py:585 +#: pretix/control/logdisplay.py:646 #, python-brace-format msgid "{user} has joined the team using the invite sent to {email}." msgstr "" -#: pretix/control/logdisplay.py:595 +#: pretix/control/logdisplay.py:656 msgid "Your account settings have been changed." msgstr "" -#: pretix/control/logdisplay.py:598 pretix/control/views/user.py:253 +#: pretix/control/logdisplay.py:659 pretix/control/views/user.py:253 #, python-brace-format msgid "Your email address has been changed to {email}." msgstr "" -#: pretix/control/logdisplay.py:600 pretix/control/views/user.py:250 +#: pretix/control/logdisplay.py:661 pretix/control/views/user.py:250 msgid "Your password has been changed." msgstr "" -#: pretix/control/logdisplay.py:602 +#: pretix/control/logdisplay.py:663 msgid "Your account has been enabled." msgstr "" -#: pretix/control/logdisplay.py:604 +#: pretix/control/logdisplay.py:665 msgid "Your account has been disabled." msgstr "" -#: pretix/control/logdisplay.py:614 +#: pretix/control/logdisplay.py:675 +#, python-brace-format msgid "You impersonated {}." msgstr "" -#: pretix/control/logdisplay.py:615 +#: pretix/control/logdisplay.py:676 +#, python-brace-format msgid "You stopped impersonating {}." msgstr "" -#: pretix/control/logdisplay.py:622 +#: pretix/control/logdisplay.py:683 msgid "This object has been created by cloning." msgstr "" -#: pretix/control/logdisplay.py:623 +#: pretix/control/logdisplay.py:684 msgid "The organizer has been changed." msgstr "" -#: pretix/control/logdisplay.py:624 +#: pretix/control/logdisplay.py:685 msgid "The organizer settings have been changed." msgstr "" -#: pretix/control/logdisplay.py:625 pretix/control/logdisplay.py:744 +#: pretix/control/logdisplay.py:686 pretix/control/logdisplay.py:825 msgid "The footer links have been changed." msgstr "" -#: pretix/control/logdisplay.py:626 pretix/control/logdisplay.py:672 +#: pretix/control/logdisplay.py:687 pretix/control/logdisplay.py:733 msgid "A scheduled export has been added." msgstr "" -#: pretix/control/logdisplay.py:627 pretix/control/logdisplay.py:673 +#: pretix/control/logdisplay.py:688 pretix/control/logdisplay.py:734 msgid "A scheduled export has been changed." msgstr "" -#: pretix/control/logdisplay.py:628 pretix/control/logdisplay.py:674 +#: pretix/control/logdisplay.py:689 pretix/control/logdisplay.py:735 msgid "A scheduled export has been deleted." msgstr "" -#: pretix/control/logdisplay.py:629 pretix/control/logdisplay.py:675 +#: pretix/control/logdisplay.py:690 pretix/control/logdisplay.py:736 msgid "A scheduled export has been executed." msgstr "" -#: pretix/control/logdisplay.py:630 pretix/control/logdisplay.py:676 +#: pretix/control/logdisplay.py:691 pretix/control/logdisplay.py:737 #, python-brace-format msgid "A scheduled export has failed: {reason}." msgstr "" -#: pretix/control/logdisplay.py:631 +#: pretix/control/logdisplay.py:692 msgid "Gift card acceptance for another organizer has been added." msgstr "" -#: pretix/control/logdisplay.py:632 +#: pretix/control/logdisplay.py:693 msgid "Gift card acceptance for another organizer has been removed." msgstr "" -#: pretix/control/logdisplay.py:633 +#: pretix/control/logdisplay.py:694 msgid "A new gift card acceptor has been invited." msgstr "" -#: pretix/control/logdisplay.py:634 +#: pretix/control/logdisplay.py:695 msgid "A gift card acceptor has been removed." msgstr "" -#: pretix/control/logdisplay.py:635 +#: pretix/control/logdisplay.py:696 msgid "A gift card issuer has been removed or declined." msgstr "" -#: pretix/control/logdisplay.py:636 +#: pretix/control/logdisplay.py:697 msgid "A new gift card issuer has been accepted." msgstr "" -#: pretix/control/logdisplay.py:637 +#: pretix/control/logdisplay.py:698 msgid "The webhook has been created." msgstr "" -#: pretix/control/logdisplay.py:638 +#: pretix/control/logdisplay.py:699 msgid "The webhook has been changed." msgstr "" -#: pretix/control/logdisplay.py:639 +#: pretix/control/logdisplay.py:700 msgid "The webhook call retry jobs have been manually expedited." msgstr "" -#: pretix/control/logdisplay.py:640 +#: pretix/control/logdisplay.py:701 msgid "The webhook call retry jobs have been dropped." msgstr "" -#: pretix/control/logdisplay.py:641 +#: pretix/control/logdisplay.py:702 msgid "The SSO provider has been created." msgstr "" -#: pretix/control/logdisplay.py:642 +#: pretix/control/logdisplay.py:703 msgid "The SSO provider has been changed." msgstr "" -#: pretix/control/logdisplay.py:643 +#: pretix/control/logdisplay.py:704 msgid "The SSO provider has been deleted." msgstr "" -#: pretix/control/logdisplay.py:644 +#: pretix/control/logdisplay.py:705 msgid "The SSO client has been created." msgstr "" -#: pretix/control/logdisplay.py:645 +#: pretix/control/logdisplay.py:706 msgid "The SSO client has been changed." msgstr "" -#: pretix/control/logdisplay.py:646 +#: pretix/control/logdisplay.py:707 msgid "The SSO client has been deleted." msgstr "" -#: pretix/control/logdisplay.py:647 pretix/control/views/organizer.py:2346 +#: pretix/control/logdisplay.py:708 pretix/control/views/organizer.py:2615 msgid "The membership type has been created." msgstr "" -#: pretix/control/logdisplay.py:648 +#: pretix/control/logdisplay.py:709 msgid "The membership type has been changed." msgstr "" -#: pretix/control/logdisplay.py:649 +#: pretix/control/logdisplay.py:710 msgid "The membership type has been deleted." msgstr "" -#: pretix/control/logdisplay.py:650 pretix/control/views/organizer.py:3184 +#: pretix/control/logdisplay.py:711 pretix/control/views/organizer.py:3453 msgid "The sales channel has been created." msgstr "" -#: pretix/control/logdisplay.py:651 +#: pretix/control/logdisplay.py:712 msgid "The sales channel has been changed." msgstr "" -#: pretix/control/logdisplay.py:652 +#: pretix/control/logdisplay.py:713 msgid "The sales channel has been deleted." msgstr "" -#: pretix/control/logdisplay.py:653 +#: pretix/control/logdisplay.py:714 msgid "The account has been created." msgstr "" -#: pretix/control/logdisplay.py:654 +#: pretix/control/logdisplay.py:715 msgid "The account has been changed." msgstr "" -#: pretix/control/logdisplay.py:655 +#: pretix/control/logdisplay.py:716 msgid "A membership for this account has been added." msgstr "" -#: pretix/control/logdisplay.py:656 +#: pretix/control/logdisplay.py:717 msgid "A membership of this account has been changed." msgstr "" -#: pretix/control/logdisplay.py:657 +#: pretix/control/logdisplay.py:718 msgid "A membership of this account has been deleted." msgstr "" -#: pretix/control/logdisplay.py:658 +#: pretix/control/logdisplay.py:719 msgid "The account has been disabled and anonymized." msgstr "" -#: pretix/control/logdisplay.py:659 +#: pretix/control/logdisplay.py:720 msgid "A new password has been requested." msgstr "" -#: pretix/control/logdisplay.py:660 +#: pretix/control/logdisplay.py:721 msgid "A new password has been set." msgstr "" -#: pretix/control/logdisplay.py:661 +#: pretix/control/logdisplay.py:722 msgid "The reusable medium has been created." msgstr "" -#: pretix/control/logdisplay.py:662 +#: pretix/control/logdisplay.py:723 msgid "The reusable medium has been created automatically." msgstr "" -#: pretix/control/logdisplay.py:663 +#: pretix/control/logdisplay.py:724 msgid "The reusable medium has been changed." msgstr "" -#: pretix/control/logdisplay.py:664 +#: pretix/control/logdisplay.py:725 msgid "The medium has been connected to a new ticket." msgstr "" -#: pretix/control/logdisplay.py:665 +#: pretix/control/logdisplay.py:726 msgid "The medium has been connected to a new gift card." msgstr "" -#: pretix/control/logdisplay.py:667 +#: pretix/control/logdisplay.py:728 msgid "The event's internal comment has been updated." msgstr "" -#: pretix/control/logdisplay.py:668 +#: pretix/control/logdisplay.py:729 msgid "The event has been canceled." msgstr "" -#: pretix/control/logdisplay.py:669 +#: pretix/control/logdisplay.py:730 msgid "An event has been deleted." msgstr "" -#: pretix/control/logdisplay.py:670 +#: pretix/control/logdisplay.py:731 msgid "A removal process for personal data has been started." msgstr "" -#: pretix/control/logdisplay.py:671 +#: pretix/control/logdisplay.py:732 msgid "A removal process for personal data has been completed." msgstr "" -#: pretix/control/logdisplay.py:677 +#: pretix/control/logdisplay.py:738 msgid "The user has been created." msgstr "" -#: pretix/control/logdisplay.py:678 +#: pretix/control/logdisplay.py:739 #, python-brace-format msgid "" "A first login using {agent_type} on {os_type} from {country} has been " "detected." msgstr "" -#: pretix/control/logdisplay.py:680 pretix/control/views/user.py:490 +#: pretix/control/logdisplay.py:741 pretix/control/views/user.py:490 #: pretix/control/views/user.py:550 pretix/control/views/user.py:609 msgid "Two-factor authentication has been enabled." msgstr "" -#: pretix/control/logdisplay.py:681 pretix/control/views/user.py:393 +#: pretix/control/logdisplay.py:742 pretix/control/views/user.py:393 #: pretix/control/views/user.py:625 msgid "Two-factor authentication has been disabled." msgstr "" -#: pretix/control/logdisplay.py:682 pretix/control/views/user.py:642 +#: pretix/control/logdisplay.py:743 pretix/control/views/user.py:642 msgid "Your two-factor emergency codes have been regenerated." msgstr "" -#: pretix/control/logdisplay.py:683 +#: pretix/control/logdisplay.py:744 msgid "A two-factor emergency code has been generated." msgstr "" -#: pretix/control/logdisplay.py:684 +#: pretix/control/logdisplay.py:745 #, python-brace-format msgid "" "A new two-factor authentication device \"{name}\" has been added to your " "account." msgstr "" -#: pretix/control/logdisplay.py:686 +#: pretix/control/logdisplay.py:747 #, python-brace-format msgid "" "The two-factor authentication device \"{name}\" has been removed from your " "account." msgstr "" -#: pretix/control/logdisplay.py:688 +#: pretix/control/logdisplay.py:749 msgid "Notifications have been enabled." msgstr "" -#: pretix/control/logdisplay.py:689 +#: pretix/control/logdisplay.py:750 msgid "Notifications have been disabled." msgstr "" -#: pretix/control/logdisplay.py:690 +#: pretix/control/logdisplay.py:751 msgid "Your notification settings have been changed." msgstr "" -#: pretix/control/logdisplay.py:691 +#: pretix/control/logdisplay.py:752 msgid "This user has been anonymized." msgstr "" -#: pretix/control/logdisplay.py:694 +#: pretix/control/logdisplay.py:755 msgid "Password reset mail sent." msgstr "" -#: pretix/control/logdisplay.py:695 +#: pretix/control/logdisplay.py:756 msgid "The password has been reset." msgstr "" -#: pretix/control/logdisplay.py:696 +#: pretix/control/logdisplay.py:757 msgid "" "A repeated password reset has been denied, as the last request was less than " "24 hours ago." msgstr "" -#: pretix/control/logdisplay.py:698 +#: pretix/control/logdisplay.py:759 #, python-brace-format msgid "The organizer \"{name}\" has been deleted." msgstr "" -#: pretix/control/logdisplay.py:699 pretix/control/logdisplay.py:905 +#: pretix/control/logdisplay.py:760 pretix/control/logdisplay.py:986 msgid "A voucher has been sent to a person on the waiting list." msgstr "" -#: pretix/control/logdisplay.py:700 +#: pretix/control/logdisplay.py:761 msgid "An entry has been transferred to another waiting list." msgstr "" -#: pretix/control/logdisplay.py:701 +#: pretix/control/logdisplay.py:762 msgid "The team has been created." msgstr "" -#: pretix/control/logdisplay.py:702 +#: pretix/control/logdisplay.py:763 msgid "The team settings have been changed." msgstr "" -#: pretix/control/logdisplay.py:703 +#: pretix/control/logdisplay.py:764 msgid "The team has been deleted." msgstr "" -#: pretix/control/logdisplay.py:704 pretix/control/views/organizer.py:2012 +#: pretix/control/logdisplay.py:765 pretix/control/views/organizer.py:2281 msgid "The gate has been created." msgstr "" -#: pretix/control/logdisplay.py:705 +#: pretix/control/logdisplay.py:766 msgid "The gate has been changed." msgstr "" -#: pretix/control/logdisplay.py:706 +#: pretix/control/logdisplay.py:767 msgid "The gate has been deleted." msgstr "" -#: pretix/control/logdisplay.py:707 +#: pretix/control/logdisplay.py:768 msgctxt "subevent" msgid "The event date has been deleted." msgstr "" -#: pretix/control/logdisplay.py:708 +#: pretix/control/logdisplay.py:769 msgctxt "subevent" msgid "The event date has been canceled." msgstr "" -#: pretix/control/logdisplay.py:709 +#: pretix/control/logdisplay.py:770 msgctxt "subevent" msgid "The event date has been changed." msgstr "" -#: pretix/control/logdisplay.py:710 +#: pretix/control/logdisplay.py:771 msgctxt "subevent" msgid "The event date has been created." msgstr "" -#: pretix/control/logdisplay.py:711 +#: pretix/control/logdisplay.py:772 msgctxt "subevent" msgid "A quota has been added to the event date." msgstr "" -#: pretix/control/logdisplay.py:712 +#: pretix/control/logdisplay.py:773 msgctxt "subevent" msgid "A quota has been changed on the event date." msgstr "" -#: pretix/control/logdisplay.py:713 +#: pretix/control/logdisplay.py:774 msgctxt "subevent" msgid "A quota has been removed from the event date." msgstr "" -#: pretix/control/logdisplay.py:714 +#: pretix/control/logdisplay.py:775 msgid "The device has been created." msgstr "" -#: pretix/control/logdisplay.py:715 +#: pretix/control/logdisplay.py:776 msgid "The device has been changed." msgstr "" -#: pretix/control/logdisplay.py:716 +#: pretix/control/logdisplay.py:777 msgid "Access of the device has been revoked." msgstr "" -#: pretix/control/logdisplay.py:717 +#: pretix/control/logdisplay.py:778 msgid "The device has been initialized." msgstr "" -#: pretix/control/logdisplay.py:718 +#: pretix/control/logdisplay.py:779 msgid "The access token of the device has been regenerated." msgstr "" -#: pretix/control/logdisplay.py:719 +#: pretix/control/logdisplay.py:780 msgid "The device has notified the server of an hardware or software update." msgstr "" -#: pretix/control/logdisplay.py:720 +#: pretix/control/logdisplay.py:781 msgid "The gift card has been created." msgstr "" -#: pretix/control/logdisplay.py:721 pretix/control/views/organizer.py:1656 +#: pretix/control/logdisplay.py:782 pretix/control/views/organizer.py:1925 msgid "The gift card has been changed." msgstr "" -#: pretix/control/logdisplay.py:722 +#: pretix/control/logdisplay.py:783 msgid "A manual transaction has been performed." msgstr "" -#: pretix/control/logdisplay.py:723 +#: pretix/control/logdisplay.py:784 #, python-brace-format msgid "The token \"{name}\" has been created." msgstr "" -#: pretix/control/logdisplay.py:724 +#: pretix/control/logdisplay.py:785 #, python-brace-format msgid "The token \"{name}\" has been revoked." msgstr "" -#: pretix/control/logdisplay.py:731 -msgid "A meta property has been added to this event." +#: pretix/control/logdisplay.py:786 +msgid "The check-in and print log state has been reset." msgstr "" -#: pretix/control/logdisplay.py:732 -msgid "A meta property has been removed from this event." -msgstr "" - -#: pretix/control/logdisplay.py:733 -msgid "A meta property has been changed on this event." -msgstr "" - -#: pretix/control/logdisplay.py:734 -msgid "The event settings have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:735 -msgid "The ticket download settings have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:738 -msgid "The shop has been taken live." -msgstr "" - -#: pretix/control/logdisplay.py:739 -msgid "The shop has been taken offline." -msgstr "" - -#: pretix/control/logdisplay.py:740 -msgid "The shop has been taken into test mode." -msgstr "" - -#: pretix/control/logdisplay.py:741 -msgid "The test mode has been disabled." -msgstr "" - -#: pretix/control/logdisplay.py:742 -msgid "The event has been created." -msgstr "" - -#: pretix/control/logdisplay.py:743 -msgid "The event details have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:745 -msgid "An answer option has been added to the question." -msgstr "" - -#: pretix/control/logdisplay.py:746 -msgid "An answer option has been removed from the question." -msgstr "" - -#: pretix/control/logdisplay.py:747 -msgid "An answer option has been changed." -msgstr "" - -#: pretix/control/logdisplay.py:748 -msgid "A user has been added to the event team." -msgstr "" - -#: pretix/control/logdisplay.py:749 -msgid "A user has been invited to the event team." -msgstr "" - -#: pretix/control/logdisplay.py:750 -msgid "A user's permissions have been changed." -msgstr "" - -#: pretix/control/logdisplay.py:751 -msgid "A user has been removed from the event team." -msgstr "" - -#: pretix/control/logdisplay.py:758 -msgid "The check-in list has been added." -msgstr "" - -#: pretix/control/logdisplay.py:759 pretix/control/logdisplay.py:760 -msgid "The check-in list has been deleted." -msgstr "" - -#: pretix/control/logdisplay.py:761 -msgid "The check-in list has been changed." -msgstr "" - -#: pretix/control/logdisplay.py:764 -#, python-brace-format -msgid "Check-in list {val}" -msgstr "" - -#: pretix/control/logdisplay.py:771 +#: pretix/control/logdisplay.py:793 pretix/control/logdisplay.py:852 msgid "The plugin has been enabled." msgstr "" -#: pretix/control/logdisplay.py:772 pretix/control/views/event.py:464 +#: pretix/control/logdisplay.py:794 pretix/control/logdisplay.py:853 +#: pretix/control/views/event.py:490 pretix/control/views/organizer.py:753 msgid "The plugin has been disabled." msgstr "" -#: pretix/control/logdisplay.py:775 +#: pretix/control/logdisplay.py:797 pretix/control/logdisplay.py:856 #, python-brace-format msgid "Plugin {val}" msgstr "" -#: pretix/control/logdisplay.py:791 +#: pretix/control/logdisplay.py:812 +msgid "A meta property has been added to this event." +msgstr "" + +#: pretix/control/logdisplay.py:813 +msgid "A meta property has been removed from this event." +msgstr "" + +#: pretix/control/logdisplay.py:814 +msgid "A meta property has been changed on this event." +msgstr "" + +#: pretix/control/logdisplay.py:815 +msgid "The event settings have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:816 +msgid "The ticket download settings have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:819 +msgid "The shop has been taken live." +msgstr "" + +#: pretix/control/logdisplay.py:820 +msgid "The shop has been taken offline." +msgstr "" + +#: pretix/control/logdisplay.py:821 +msgid "The shop has been taken into test mode." +msgstr "" + +#: pretix/control/logdisplay.py:822 +msgid "The test mode has been disabled." +msgstr "" + +#: pretix/control/logdisplay.py:823 +msgid "The event has been created." +msgstr "" + +#: pretix/control/logdisplay.py:824 +msgid "The event details have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:826 +msgid "An answer option has been added to the question." +msgstr "" + +#: pretix/control/logdisplay.py:827 +msgid "An answer option has been removed from the question." +msgstr "" + +#: pretix/control/logdisplay.py:828 +msgid "An answer option has been changed." +msgstr "" + +#: pretix/control/logdisplay.py:829 +msgid "A user has been added to the event team." +msgstr "" + +#: pretix/control/logdisplay.py:830 +msgid "A user has been invited to the event team." +msgstr "" + +#: pretix/control/logdisplay.py:831 +msgid "A user's permissions have been changed." +msgstr "" + +#: pretix/control/logdisplay.py:832 +msgid "A user has been removed from the event team." +msgstr "" + +#: pretix/control/logdisplay.py:839 +msgid "The check-in list has been added." +msgstr "" + +#: pretix/control/logdisplay.py:840 pretix/control/logdisplay.py:841 +msgid "The check-in list has been deleted." +msgstr "" + +#: pretix/control/logdisplay.py:842 +msgid "The check-in list has been changed." +msgstr "" + +#: pretix/control/logdisplay.py:845 +#, python-brace-format +msgid "Check-in list {val}" +msgstr "" + +#: pretix/control/logdisplay.py:872 msgid "The product has been created." msgstr "" -#: pretix/control/logdisplay.py:792 +#: pretix/control/logdisplay.py:873 msgid "The product has been changed." msgstr "" -#: pretix/control/logdisplay.py:793 +#: pretix/control/logdisplay.py:874 msgid "The product has been reordered." msgstr "" -#: pretix/control/logdisplay.py:794 +#: pretix/control/logdisplay.py:875 msgid "The product has been deleted." msgstr "" -#: pretix/control/logdisplay.py:795 +#: pretix/control/logdisplay.py:876 msgid "An add-on has been added to this product." msgstr "" -#: pretix/control/logdisplay.py:796 +#: pretix/control/logdisplay.py:877 msgid "An add-on has been removed from this product." msgstr "" -#: pretix/control/logdisplay.py:797 +#: pretix/control/logdisplay.py:878 msgid "An add-on has been changed on this product." msgstr "" -#: pretix/control/logdisplay.py:798 +#: pretix/control/logdisplay.py:879 msgid "A bundled item has been added to this product." msgstr "" -#: pretix/control/logdisplay.py:799 +#: pretix/control/logdisplay.py:880 msgid "A bundled item has been removed from this product." msgstr "" -#: pretix/control/logdisplay.py:800 +#: pretix/control/logdisplay.py:881 msgid "A bundled item has been changed on this product." msgstr "" -#: pretix/control/logdisplay.py:807 +#: pretix/control/logdisplay.py:888 #, python-brace-format msgid "The variation \"{value}\" has been created." msgstr "" -#: pretix/control/logdisplay.py:808 +#: pretix/control/logdisplay.py:889 #, python-brace-format msgid "The variation \"{value}\" has been deleted." msgstr "" -#: pretix/control/logdisplay.py:809 +#: pretix/control/logdisplay.py:890 #, python-brace-format msgid "The variation \"{value}\" has been changed." msgstr "" -#: pretix/control/logdisplay.py:826 +#: pretix/control/logdisplay.py:907 #, python-brace-format msgid "Payment {local_id} has been confirmed." msgstr "" -#: pretix/control/logdisplay.py:827 +#: pretix/control/logdisplay.py:908 #, python-brace-format msgid "Payment {local_id} has been canceled." msgstr "" -#: pretix/control/logdisplay.py:828 +#: pretix/control/logdisplay.py:909 #, python-brace-format msgid "Canceling payment {local_id} has failed." msgstr "" -#: pretix/control/logdisplay.py:829 +#: pretix/control/logdisplay.py:910 #, python-brace-format msgid "Payment {local_id} has been started." msgstr "" -#: pretix/control/logdisplay.py:830 +#: pretix/control/logdisplay.py:911 #, python-brace-format msgid "Payment {local_id} has failed." msgstr "" -#: pretix/control/logdisplay.py:831 +#: pretix/control/logdisplay.py:912 #, python-brace-format msgid "The order could not be marked as paid: {message}" msgstr "" -#: pretix/control/logdisplay.py:832 +#: pretix/control/logdisplay.py:913 msgid "The order has been overpaid." msgstr "" -#: pretix/control/logdisplay.py:833 +#: pretix/control/logdisplay.py:914 #, python-brace-format msgid "Refund {local_id} has been created." msgstr "" -#: pretix/control/logdisplay.py:834 +#: pretix/control/logdisplay.py:915 #, python-brace-format msgid "Refund {local_id} has been created by an external entity." msgstr "" -#: pretix/control/logdisplay.py:835 +#: pretix/control/logdisplay.py:916 msgid "The customer requested you to issue a refund." msgstr "" -#: pretix/control/logdisplay.py:836 +#: pretix/control/logdisplay.py:917 #, python-brace-format msgid "Refund {local_id} has been completed." msgstr "" -#: pretix/control/logdisplay.py:837 +#: pretix/control/logdisplay.py:918 #, python-brace-format msgid "Refund {local_id} has been canceled." msgstr "" -#: pretix/control/logdisplay.py:838 +#: pretix/control/logdisplay.py:919 #, python-brace-format msgid "Refund {local_id} has failed." msgstr "" -#: pretix/control/logdisplay.py:845 +#: pretix/control/logdisplay.py:926 msgid "The quota has been added." msgstr "" -#: pretix/control/logdisplay.py:846 +#: pretix/control/logdisplay.py:927 msgid "The quota has been deleted." msgstr "" -#: pretix/control/logdisplay.py:847 +#: pretix/control/logdisplay.py:928 msgid "The quota has been changed." msgstr "" -#: pretix/control/logdisplay.py:848 +#: pretix/control/logdisplay.py:929 msgid "The quota has closed." msgstr "" -#: pretix/control/logdisplay.py:849 pretix/control/views/item.py:1081 +#: pretix/control/logdisplay.py:930 pretix/control/views/item.py:1081 msgid "The quota has been re-opened." msgstr "" -#: pretix/control/logdisplay.py:856 +#: pretix/control/logdisplay.py:937 msgid "The question has been added." msgstr "" -#: pretix/control/logdisplay.py:857 +#: pretix/control/logdisplay.py:938 msgid "The question has been deleted." msgstr "" -#: pretix/control/logdisplay.py:858 +#: pretix/control/logdisplay.py:939 msgid "The question has been changed." msgstr "" -#: pretix/control/logdisplay.py:859 +#: pretix/control/logdisplay.py:940 msgid "The question has been reordered." msgstr "" -#: pretix/control/logdisplay.py:866 +#: pretix/control/logdisplay.py:947 msgid "The discount has been added." msgstr "" -#: pretix/control/logdisplay.py:867 +#: pretix/control/logdisplay.py:948 msgid "The discount has been deleted." msgstr "" -#: pretix/control/logdisplay.py:868 +#: pretix/control/logdisplay.py:949 msgid "The discount has been changed." msgstr "" -#: pretix/control/logdisplay.py:892 +#: pretix/control/logdisplay.py:973 #, python-brace-format msgid "" "Position #{posid} has been checked in manually at {datetime} on list \"{list}" "\"." msgstr "" -#: pretix/control/logdisplay.py:897 +#: pretix/control/logdisplay.py:978 #, python-brace-format msgid "" "Position #{posid} has been checked in again at {datetime} on list \"{list}\"." msgstr "" -#: pretix/control/logdisplay.py:906 +#: pretix/control/logdisplay.py:987 msgid "An entry has been removed from the waiting list." msgstr "" -#: pretix/control/logdisplay.py:907 +#: pretix/control/logdisplay.py:988 msgid "An entry has been changed on the waiting list." msgstr "" -#: pretix/control/logdisplay.py:908 +#: pretix/control/logdisplay.py:989 msgid "An entry has been added to the waiting list." msgstr "" @@ -15168,7 +15789,7 @@ msgid "Dashboard" msgstr "" #: pretix/control/navigation.py:49 pretix/control/navigation.py:382 -#: pretix/control/navigation.py:487 +#: pretix/control/navigation.py:492 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:38 #: pretix/control/templates/pretixcontrol/event/mail.html:14 #: pretix/control/templates/pretixcontrol/event/tax_edit.html:25 @@ -15184,19 +15805,20 @@ msgstr "" #: pretix/control/navigation.py:57 #: pretix/control/templates/pretixcontrol/event/quick_setup.html:151 -#: pretix/control/templates/pretixcontrol/order/index.html:838 +#: pretix/control/templates/pretixcontrol/order/index.html:890 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:37 #: pretix/plugins/banktransfer/apps.py:42 #: pretix/plugins/manualpayment/apps.py:39 pretix/plugins/paypal2/apps.py:45 #: pretix/plugins/stripe/apps.py:44 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:43 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:42 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:11 #: pretix/presale/templates/pretixpresale/event/order.html:86 msgid "Payment" msgstr "" -#: pretix/control/navigation.py:73 pretix/control/views/event.py:1520 -#: pretix/control/views/event.py:1522 pretix/control/views/event.py:1554 -#: pretix/control/views/event.py:1559 pretix/control/views/subevents.py:293 +#: pretix/control/navigation.py:73 pretix/control/views/event.py:1610 +#: pretix/control/views/event.py:1612 pretix/control/views/event.py:1644 +#: pretix/control/views/event.py:1649 pretix/control/views/subevents.py:293 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:60 #: pretix/plugins/ticketoutputpdf/apps.py:55 #: pretix/plugins/ticketoutputpdf/exporters.py:68 @@ -15227,9 +15849,11 @@ msgid "Widget" msgstr "" #: pretix/control/navigation.py:126 pretix/control/navigation.py:435 -#: pretix/control/navigation.py:480 +#: pretix/control/navigation.py:485 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:138 #: pretix/control/templates/pretixcontrol/event/payment.html:47 -#: pretix/control/templates/pretixcontrol/event/plugins.html:106 +#: pretix/control/templates/pretixcontrol/event/plugins.html:117 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:135 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:12 #: pretix/plugins/returnurl/apps.py:40 #: pretix/plugins/ticketoutputpdf/apps.py:55 @@ -15249,11 +15873,11 @@ msgid "Overview" msgstr "" #: pretix/control/navigation.py:221 -#: pretix/control/templates/pretixcontrol/order/index.html:825 +#: pretix/control/templates/pretixcontrol/order/index.html:877 #: pretix/control/templates/pretixcontrol/orders/refunds.html:7 #: pretix/control/templates/pretixcontrol/orders/refunds.html:9 -#: pretix/plugins/reports/accountingreport.py:497 -#: pretix/plugins/reports/accountingreport.py:684 +#: pretix/plugins/reports/accountingreport.py:498 +#: pretix/plugins/reports/accountingreport.py:685 #: pretix/presale/templates/pretixpresale/event/order.html:137 msgid "Refunds" msgstr "" @@ -15284,14 +15908,15 @@ msgstr "" #: pretix/control/navigation.py:356 #: pretix/control/templates/pretixcontrol/event/plugins.html:20 #: pretix/control/templates/pretixcontrol/orders/search.html:20 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:20 msgid "Search" msgstr "" #: pretix/control/navigation.py:368 -#: pretix/control/templates/pretixcontrol/order/index.html:731 -#: pretix/plugins/reports/accountingreport.py:496 -#: pretix/plugins/reports/accountingreport.py:677 -#: pretix/plugins/reports/accountingreport.py:871 +#: pretix/control/templates/pretixcontrol/order/index.html:783 +#: pretix/plugins/reports/accountingreport.py:497 +#: pretix/plugins/reports/accountingreport.py:678 +#: pretix/plugins/reports/accountingreport.py:872 msgid "Payments" msgstr "" @@ -15348,39 +15973,43 @@ msgstr "" msgid "System report" msgstr "" -#: pretix/control/navigation.py:494 +#: pretix/control/navigation.py:455 pretix/control/navigation.py:675 +msgid "Data sync problems" +msgstr "" + +#: pretix/control/navigation.py:506 #: pretix/control/templates/pretixcontrol/organizers/properties.html:5 msgid "Event metadata" msgstr "" -#: pretix/control/navigation.py:515 +#: pretix/control/navigation.py:527 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:6 msgid "Webhooks" msgstr "" -#: pretix/control/navigation.py:548 +#: pretix/control/navigation.py:560 msgid "Acceptance" msgstr "" -#: pretix/control/navigation.py:569 +#: pretix/control/navigation.py:581 #: pretix/control/templates/pretixcontrol/organizers/customers.html:6 #: pretix/control/templates/pretixcontrol/organizers/customers.html:9 msgid "Customers" msgstr "" -#: pretix/control/navigation.py:588 +#: pretix/control/navigation.py:600 #: pretix/control/templates/pretixcontrol/organizers/ssoclients.html:4 #: pretix/control/templates/pretixcontrol/organizers/ssoclients.html:6 msgid "SSO clients" msgstr "" -#: pretix/control/navigation.py:597 +#: pretix/control/navigation.py:609 #: pretix/control/templates/pretixcontrol/organizers/ssoproviders.html:4 #: pretix/control/templates/pretixcontrol/organizers/ssoproviders.html:6 msgid "SSO providers" msgstr "" -#: pretix/control/navigation.py:626 pretix/control/navigation.py:633 +#: pretix/control/navigation.py:638 pretix/control/navigation.py:645 msgid "Devices" msgstr "" @@ -15389,14 +16018,14 @@ msgstr "" msgid "You do not have permission to view this content." msgstr "" -#: pretix/control/templates/pretixcontrol/auth/base.html:44 -#: pretix/control/templates/pretixcontrol/base.html:360 +#: pretix/control/templates/pretixcontrol/auth/base.html:42 +#: pretix/control/templates/pretixcontrol/base.html:358 #, python-format msgid "You are currently working on behalf of %(user)s." msgstr "" -#: pretix/control/templates/pretixcontrol/auth/base.html:49 -#: pretix/control/templates/pretixcontrol/base.html:365 +#: pretix/control/templates/pretixcontrol/auth/base.html:47 +#: pretix/control/templates/pretixcontrol/base.html:363 msgid "Stop impersonating" msgstr "" @@ -15481,10 +16110,10 @@ msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:11 #: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html:45 #: pretix/presale/templates/pretixpresale/event/checkout_addons.html:90 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:125 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:126 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:80 -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:130 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:192 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:131 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:194 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:53 #: pretix/presale/templates/pretixpresale/event/order_change.html:27 #: pretix/presale/templates/pretixpresale/event/order_pay.html:28 @@ -15536,9 +16165,9 @@ msgstr "" #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:124 #: pretix/control/templates/pretixcontrol/email_setup_simple.html:82 #: pretix/control/templates/pretixcontrol/email_setup_smtp.html:38 -#: pretix/control/templates/pretixcontrol/event/cancel.html:90 -#: pretix/control/templates/pretixcontrol/event/invoicing.html:68 -#: pretix/control/templates/pretixcontrol/event/mail.html:132 +#: pretix/control/templates/pretixcontrol/event/cancel.html:91 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:162 +#: pretix/control/templates/pretixcontrol/event/mail.html:135 #: pretix/control/templates/pretixcontrol/event/payment.html:88 #: pretix/control/templates/pretixcontrol/event/payment_provider.html:36 #: pretix/control/templates/pretixcontrol/event/quick_setup.html:201 @@ -15556,7 +16185,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/oauth/app_update.html:12 #: pretix/control/templates/pretixcontrol/order/change_contact.html:28 #: pretix/control/templates/pretixcontrol/order/change_locale.html:33 -#: pretix/control/templates/pretixcontrol/order/change_questions.html:86 +#: pretix/control/templates/pretixcontrol/order/change_questions.html:87 #: pretix/control/templates/pretixcontrol/order/extend.html:28 #: pretix/control/templates/pretixcontrol/orders/export_form.html:45 #: pretix/control/templates/pretixcontrol/organizers/channel_add.html:22 @@ -15574,13 +16203,14 @@ msgstr "" #: pretix/control/templates/pretixcontrol/organizers/giftcard_edit.html:21 #: pretix/control/templates/pretixcontrol/organizers/mail.html:73 #: pretix/control/templates/pretixcontrol/organizers/membershiptype_edit.html:15 +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:41 #: pretix/control/templates/pretixcontrol/organizers/property_edit.html:103 #: pretix/control/templates/pretixcontrol/organizers/reusable_medium_edit.html:28 #: pretix/control/templates/pretixcontrol/organizers/ssoclient_edit.html:15 #: pretix/control/templates/pretixcontrol/organizers/ssoprovider_edit.html:28 #: pretix/control/templates/pretixcontrol/organizers/team_edit.html:47 #: pretix/control/templates/pretixcontrol/organizers/webhook_edit.html:21 -#: pretix/control/templates/pretixcontrol/pdf/index.html:544 +#: pretix/control/templates/pretixcontrol/pdf/index.html:46 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:630 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:368 #: pretix/control/templates/pretixcontrol/subevents/detail.html:287 @@ -15608,76 +16238,76 @@ msgstr "" msgid "Create a new account" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:103 +#: pretix/control/templates/pretixcontrol/base.html:101 msgid "Toggle navigation" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:118 -#: pretix/control/templates/pretixcontrol/base.html:141 -#: pretix/control/templates/pretixcontrol/base.html:145 -#: pretix/control/templates/pretixcontrol/base.html:146 +#: pretix/control/templates/pretixcontrol/base.html:116 +#: pretix/control/templates/pretixcontrol/base.html:139 +#: pretix/control/templates/pretixcontrol/base.html:143 +#: pretix/control/templates/pretixcontrol/base.html:144 msgid "Go to shop" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:124 -#: pretix/control/templates/pretixcontrol/base.html:152 -#: pretix/control/templates/pretixcontrol/base.html:153 +#: pretix/control/templates/pretixcontrol/base.html:122 +#: pretix/control/templates/pretixcontrol/base.html:150 +#: pretix/control/templates/pretixcontrol/base.html:151 msgid "Public profile" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:204 +#: pretix/control/templates/pretixcontrol/base.html:202 msgid "End admin session" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:216 +#: pretix/control/templates/pretixcontrol/base.html:214 msgid "Account Settings" msgstr "" +#: pretix/control/templates/pretixcontrol/base.html:219 #: pretix/control/templates/pretixcontrol/base.html:221 -#: pretix/control/templates/pretixcontrol/base.html:223 #: pretix/presale/templates/pretixpresale/fragment_login_status.html:14 msgid "Log out" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:249 +#: pretix/control/templates/pretixcontrol/base.html:247 msgid "Organizer account" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:272 +#: pretix/control/templates/pretixcontrol/base.html:270 msgid "Search for events" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:329 -#: pretix/presale/templates/pretixpresale/base.html:54 +#: pretix/control/templates/pretixcontrol/base.html:327 +#: pretix/presale/templates/pretixpresale/base.html:51 msgid "" "We've detected that you are using Microsoft Internet Explorer." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:332 -#: pretix/presale/templates/pretixpresale/base.html:57 +#: pretix/control/templates/pretixcontrol/base.html:330 +#: pretix/presale/templates/pretixpresale/base.html:54 msgid "" "Internet Explorer is an old browser that does not support lots of recent web-" "based technologies and is no longer supported by this website." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:336 -#: pretix/presale/templates/pretixpresale/base.html:61 +#: pretix/control/templates/pretixcontrol/base.html:334 +#: pretix/presale/templates/pretixpresale/base.html:58 msgid "" "We kindly ask you to move to one of our supported browsers, such as " "Microsoft Edge, Mozilla Firefox, Google Chrome, or Safari." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:345 +#: pretix/control/templates/pretixcontrol/base.html:343 msgid "" "Please leave a short comment on what you did in the following admin sessions:" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:376 +#: pretix/control/templates/pretixcontrol/base.html:374 msgid "Read more" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:393 +#: pretix/control/templates/pretixcontrol/base.html:391 msgid "" "Your event contains test mode orders even though " "test mode has been disabled. You should delete those orders " @@ -15685,11 +16315,11 @@ msgid "" "people from actually buying tickets." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:400 +#: pretix/control/templates/pretixcontrol/base.html:398 msgid "Show all test mode orders" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:408 +#: pretix/control/templates/pretixcontrol/base.html:406 msgid "" "Starting with version 1.2.0, pretix automatically checks for updates in the " "background. During this check, anonymous data is transmitted to servers " @@ -15698,41 +16328,41 @@ msgid "" "if a new update arrives. This message will disappear once you clicked it." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:421 +#: pretix/control/templates/pretixcontrol/base.html:419 msgid "" "Click here to do a license compliance check to make sure your usage of " "pretix is in line with pretix' license." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:430 +#: pretix/control/templates/pretixcontrol/base.html:428 msgid "" "The cronjob component of pretix was not executed in the last hours. Please " "check that you have completed all installation steps and your cronjob is " "executed correctly." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:439 +#: pretix/control/templates/pretixcontrol/base.html:437 msgid "" "pretix is running in debug mode. For security reasons, please never run " "debug mode on a production instance." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:445 +#: pretix/control/templates/pretixcontrol/base.html:443 msgid "" "For security reasons, please change your password before you continue. " "Afterwards you will be redirected to your original destination." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:457 +#: pretix/control/templates/pretixcontrol/base.html:455 #, python-format msgid "Times displayed in %(tz)s" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:463 +#: pretix/control/templates/pretixcontrol/base.html:461 msgid "running in development mode" msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:472 +#: pretix/control/templates/pretixcontrol/base.html:470 #: pretix/presale/templates/pretixpresale/fragment_modals.html:38 #: pretix/presale/templates/pretixpresale/postmessage.html:27 #: pretix/presale/templates/pretixpresale/waiting.html:42 @@ -15849,8 +16479,8 @@ msgid "Transaction ID" msgstr "" #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:98 -#: pretix/plugins/banktransfer/payment.py:463 -#: pretix/plugins/banktransfer/payment.py:472 +#: pretix/plugins/banktransfer/payment.py:297 +#: pretix/plugins/banktransfer/payment.py:306 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:32 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:33 msgid "Reference" @@ -15894,8 +16524,10 @@ msgstr[1] "" #: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:24 #: pretix/control/templates/pretixcontrol/checkin/list_delete.html:18 +#: pretix/control/templates/pretixcontrol/checkin/reset.html:43 +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:20 #: pretix/control/templates/pretixcontrol/email_setup_simple.html:76 -#: pretix/control/templates/pretixcontrol/event/tax_delete.html:17 +#: pretix/control/templates/pretixcontrol/event/tax_delete.html:16 #: pretix/control/templates/pretixcontrol/item/delete.html:11 #: pretix/control/templates/pretixcontrol/item/delete.html:38 #: pretix/control/templates/pretixcontrol/items/category_delete.html:14 @@ -15909,7 +16541,7 @@ msgstr[1] "" #: pretix/control/templates/pretixcontrol/order/change.html:543 #: pretix/control/templates/pretixcontrol/order/change_contact.html:25 #: pretix/control/templates/pretixcontrol/order/change_locale.html:30 -#: pretix/control/templates/pretixcontrol/order/change_questions.html:83 +#: pretix/control/templates/pretixcontrol/order/change_questions.html:84 #: pretix/control/templates/pretixcontrol/order/extend.html:25 #: pretix/control/templates/pretixcontrol/order/pay.html:34 #: pretix/control/templates/pretixcontrol/order/pay_complete.html:34 @@ -15933,7 +16565,7 @@ msgstr[1] "" #: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html:16 #: pretix/control/templates/pretixcontrol/organizers/team_delete.html:10 #: pretix/control/templates/pretixcontrol/organizers/team_delete.html:21 -#: pretix/control/templates/pretixcontrol/pdf/index.html:77 +#: pretix/control/templates/pretixcontrol/pdf/index.html:153 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:378 #: pretix/control/templates/pretixcontrol/subevents/delete.html:12 #: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html:41 @@ -15955,7 +16587,7 @@ msgstr[1] "" #: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html:38 #: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html:12 #: pretix/presale/templates/pretixpresale/event/order_change.html:22 -#: pretix/presale/templates/pretixpresale/event/order_modify.html:79 +#: pretix/presale/templates/pretixpresale/event/order_modify.html:80 #: pretix/presale/templates/pretixpresale/event/order_pay.html:23 #: pretix/presale/templates/pretixpresale/event/order_pay_change.html:60 #: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html:40 @@ -15967,7 +16599,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:27 #: pretix/control/templates/pretixcontrol/checkin/list_delete.html:24 #: pretix/control/templates/pretixcontrol/event/delete.html:30 -#: pretix/control/templates/pretixcontrol/event/tax_delete.html:21 +#: pretix/control/templates/pretixcontrol/event/tax_delete.html:20 #: pretix/control/templates/pretixcontrol/item/delete.html:41 #: pretix/control/templates/pretixcontrol/items/categories.html:60 #: pretix/control/templates/pretixcontrol/items/category_delete.html:17 @@ -15989,7 +16621,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html:20 #: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html:20 #: pretix/control/templates/pretixcontrol/organizers/team_delete.html:24 -#: pretix/control/templates/pretixcontrol/pdf/index.html:167 +#: pretix/control/templates/pretixcontrol/pdf/index.html:111 #: pretix/control/templates/pretixcontrol/subevents/delete.html:15 #: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html:44 #: pretix/control/templates/pretixcontrol/user/2fa_delete.html:21 @@ -15998,7 +16630,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html:16 #: pretix/control/templates/pretixcontrol/waitinglist/delete.html:15 #: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html:36 -#: pretix/control/views/orders.py:382 +#: pretix/control/views/orders.py:387 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html:15 #: pretix/plugins/badges/templates/pretixplugins/badges/delete.html:16 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html:15 @@ -16074,18 +16706,18 @@ msgstr "" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:65 #: pretix/control/templates/pretixcontrol/checkin/simulator.html:49 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:14 -#: pretix/plugins/checkinlists/exporters.py:766 +#: pretix/plugins/checkinlists/exporters.py:767 msgid "Result" msgstr "" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:78 -#: pretix/control/templates/pretixcontrol/order/index.html:392 +#: pretix/control/templates/pretixcontrol/order/index.html:432 #, python-format msgid "Automatically marked not present: %(date)s" msgstr "" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:82 -#: pretix/control/templates/pretixcontrol/order/index.html:397 +#: pretix/control/templates/pretixcontrol/order/index.html:437 #, python-format msgid "Additional entry scan: %(date)s" msgstr "" @@ -16096,7 +16728,7 @@ msgid "Offline scan. Upload time: %(date)s" msgstr "" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:88 -#: pretix/control/templates/pretixcontrol/order/index.html:399 +#: pretix/control/templates/pretixcontrol/order/index.html:439 #, python-format msgid "Automatically checked in: %(date)s" msgstr "" @@ -16117,6 +16749,8 @@ msgstr "" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:152 #: pretix/control/templates/pretixcontrol/event/index.html:24 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:27 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:33 msgid "Copy to clipboard" msgstr "" @@ -16136,7 +16770,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/checkin/index.html:22 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:21 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:160 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:167 #: pretix/control/templates/pretixcontrol/checkin/simulator.html:8 #: pretix/control/templates/pretixcontrol/checkin/simulator.html:20 msgid "Check-in simulator" @@ -16157,6 +16791,7 @@ msgid "No attendee record was found." msgstr "" #: pretix/control/templates/pretixcontrol/checkin/index.html:91 +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:19 #: pretix/control/templates/pretixcontrol/orders/index.html:127 #: pretix/control/templates/pretixcontrol/organizers/devices.html:68 #: pretix/control/templates/pretixcontrol/subevents/index.html:89 @@ -16343,7 +16978,13 @@ msgstr "" msgid "Connected devices" msgstr "" -#: pretix/control/templates/pretixcontrol/checkin/lists.html:156 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:90 +#: pretix/control/templates/pretixcontrol/checkin/reset.html:4 +#: pretix/control/templates/pretixcontrol/checkin/reset.html:6 +msgid "Reset check-in" +msgstr "" + +#: pretix/control/templates/pretixcontrol/checkin/lists.html:163 #: pretix/control/templates/pretixcontrol/items/categories.html:57 #: pretix/control/templates/pretixcontrol/items/discounts.html:149 #: pretix/control/templates/pretixcontrol/items/index.html:165 @@ -16354,6 +16995,45 @@ msgstr "" msgid "Clone" msgstr "" +#: pretix/control/templates/pretixcontrol/checkin/reset.html:10 +msgid "" +"With this feature, you can reset the entire check-in state of the event. " +"This will delete all check-in records as well as all records of printed " +"tickets or badges. We recommend to use this feature after testing your " +"hardware setup but only before your event started, and you admitted any real " +"attendees or printed any real badges or tickets." +msgstr "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:18 +#, python-format +msgid "This will permanently delete 1 check-in." +msgid_plural "" +"This will permanently delete %(count)s check-ins." +msgstr[0] "" +msgstr[1] "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:23 +#, python-format +msgid "Additionally, 1 print log will be deleted." +msgid_plural "" +"Additionally, %(count)s print logs will be deleted." +msgstr[0] "" +msgstr[1] "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:30 +msgid "This cannot be reverted!" +msgstr "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:34 +msgid "" +"The deleted entries will still show up in the \"Order history\" section, but " +"for all other purposes the system will behave as if they never existed." +msgstr "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:46 +msgid "Proceed with reset" +msgstr "" + #: pretix/control/templates/pretixcontrol/checkin/simulator.html:22 msgid "" "This tool allows you to validate your check-in configuration. You can enter " @@ -16425,6 +17105,95 @@ msgstr "" msgid "Other features" msgstr "" +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:8 +msgid "Data transfer to external systems" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:18 +#: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:22 +msgid "Retry now" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:22 +msgid "Sync now" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:31 +#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:16 +#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:19 +msgid "Error" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:34 +#, python-format +msgid "Error. Retry %(num)s of %(max)s." +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:38 +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:43 +#, python-format +msgid "Waiting until %(datetime)s" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:49 +#, python-format +msgid "triggered at %(datetime)s" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:62 +msgid "identified by" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:68 +msgid "No data transmitted." +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:5 +msgid "Sync problems" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:7 +msgid "" +"On this page, we provide a list of orders where data synchronization to an " +"external system has failed. You can start another attempt to sync them " +"manually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:24 +msgid "Sync provider" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:26 +msgid "Failure mode" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:51 +#, python-format +msgid "Temporary error, will retry after %(datetime)s" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:63 +msgid "No problems." +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:74 +msgid "Retry selected" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:75 +msgid "Cancel selected" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html:31 +#: pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html:62 +msgid "Edit value mapping" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html:76 +#: pretix/control/templates/pretixcontrol/event/settings.html:487 +msgid "Add property" +msgstr "" + #: pretix/control/templates/pretixcontrol/email/email_setup.txt:1 #, python-format msgid "" @@ -16625,7 +17394,7 @@ msgstr "" msgid "Unpaid or free orders" msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:39 +#: pretix/control/templates/pretixcontrol/event/cancel.html:40 msgid "" "If a user requests cancels a paid order and the money can not be refunded " "automatically, e.g. due to the selected payment method, you will need to " @@ -16633,67 +17402,67 @@ msgid "" "this event." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:45 +#: pretix/control/templates/pretixcontrol/event/cancel.html:46 #: pretix/control/templates/pretixcontrol/user/settings.html:29 msgid "Change notification settings" msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:51 +#: pretix/control/templates/pretixcontrol/event/cancel.html:52 msgid "Order changes" msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:54 +#: pretix/control/templates/pretixcontrol/event/cancel.html:55 msgid "" "Allowing customers to change their own orders is a complex process due to " "the many different options pretix provides. Therefore, this feature " "currently has the following limitations:" msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:60 +#: pretix/control/templates/pretixcontrol/event/cancel.html:61 msgid "" "It is possible to switch to a different variation of the same product, but " "not to an entirely different product (except for add-on products)." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:61 +#: pretix/control/templates/pretixcontrol/event/cancel.html:62 msgid "" "Changing the seat or the event date in an event series will become available " "in the future, but is not possible now." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:62 +#: pretix/control/templates/pretixcontrol/event/cancel.html:63 msgid "" "If a change leads to a price change, there will not be a change to fees such " "as payment, service, or shipping fees, even though an additional payment " "might be required." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:63 +#: pretix/control/templates/pretixcontrol/event/cancel.html:64 msgid "" "If an add-on product is newly added, the system currently does not validate " "if there are required questions or fields that need to be filled out." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:64 +#: pretix/control/templates/pretixcontrol/event/cancel.html:65 msgid "" "Customers currently cannot switch to a product variation or add an add-on " "product that requires them to use a voucher or membership." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:65 +#: pretix/control/templates/pretixcontrol/event/cancel.html:66 msgid "" "Additional constraints and validation steps added by plugins are not " "enforced." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:76 +#: pretix/control/templates/pretixcontrol/event/cancel.html:77 msgid "" "If the change leads to a price reduction and automatic refunds are enabled " "for self-service cancellations, the system will try to refund the money " "automatically." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:80 +#: pretix/control/templates/pretixcontrol/event/cancel.html:81 msgid "" "Refunds can be issued as a gift card if the respective option is set, but " "there is no customer choice between gift card and direct refund." @@ -16928,42 +17697,104 @@ msgstr "" msgid "Show affected orders" msgstr "" -#: pretix/control/templates/pretixcontrol/event/index.html:142 -#: pretix/control/templates/pretixcontrol/order/index.html:1004 +#: pretix/control/templates/pretixcontrol/event/index.html:84 +msgid "" +"Orders in this event could not be synced to an external system as configured." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/index.html:88 +msgid "Show sync problems" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/index.html:151 +#: pretix/control/templates/pretixcontrol/order/index.html:1062 msgid "Update comment" msgstr "" -#: pretix/control/templates/pretixcontrol/event/index.html:152 +#: pretix/control/templates/pretixcontrol/event/index.html:161 #: pretix/control/templates/pretixcontrol/event/logs.html:4 #: pretix/control/templates/pretixcontrol/event/logs.html:6 msgid "Event logs" msgstr "" -#: pretix/control/templates/pretixcontrol/event/index.html:162 +#: pretix/control/templates/pretixcontrol/event/index.html:171 msgid "Show more logs" msgstr "" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:5 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:6 msgid "Invoice settings" msgstr "" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:11 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:12 msgid "Invoice generation" msgstr "" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:26 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:27 msgid "Address form" msgstr "" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:39 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:40 msgid "Issuer details" msgstr "" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:49 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:50 msgid "Invoice customization" msgstr "" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:65 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:64 +msgid "Invoice transmission" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:66 +msgid "" +"pretix can transmit invoices using different transmission methods. Different " +"transmission methods might be required depending on country and industry. By " +"default, sending invoices as PDF files via email is always available. Other " +"types of transmission can be added by plugins." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:73 +msgid "" +"Whether a transmission method listed here is actually selectable for " +"customers may depend on the country of the customer or whether the customer " +"is entering a business address." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:82 +msgid "Transmission method" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:98 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:125 +#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:109 +#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:111 +msgid "Available" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:100 +msgid "" +"When this type is available for an invoice address, no other type can be " +"selected." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:101 +msgid "(exclusive)" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:108 +msgid "Unavailable" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:130 +msgid "Not configured" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:152 +msgid "Enable additional invoice transmission plugins" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:159 msgid "Save and show preview" msgstr "" @@ -17089,9 +17920,9 @@ msgstr "" #: pretix/control/templates/pretixcontrol/event/logs.html:86 #: pretix/control/templates/pretixcontrol/event/logs_embed.html:47 #: pretix/control/templates/pretixcontrol/includes/logs.html:42 -#: pretix/control/templates/pretixcontrol/order/index.html:793 -#: pretix/control/templates/pretixcontrol/order/index.html:805 -#: pretix/control/templates/pretixcontrol/order/index.html:910 +#: pretix/control/templates/pretixcontrol/order/index.html:845 +#: pretix/control/templates/pretixcontrol/order/index.html:857 +#: pretix/control/templates/pretixcontrol/order/index.html:962 #: pretix/control/templates/pretixcontrol/organizers/device_logs.html:42 #: pretix/control/templates/pretixcontrol/organizers/logs.html:72 #: pretix/control/templates/pretixcontrol/search/payments.html:147 @@ -17135,7 +17966,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/event/mail.html:79 #: pretix/control/templates/pretixcontrol/event/mail_settings_fragment.html:29 #: pretix/control/templates/pretixcontrol/event/tickets.html:35 -#: pretix/control/templates/pretixcontrol/pdf/index.html:540 +#: pretix/control/templates/pretixcontrol/pdf/index.html:41 #: pretix/control/templates/pretixcontrol/vouchers/bulk.html:97 #: pretix/control/templates/pretixcontrol/vouchers/bulk.html:120 msgid "Preview" @@ -17160,7 +17991,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/event/mail.html:99 #: pretix/control/templates/pretixcontrol/order/index.html:249 -#: pretix/control/templates/pretixcontrol/order/index.html:532 +#: pretix/control/templates/pretixcontrol/order/index.html:584 msgid "Resend link" msgstr "" @@ -17180,15 +18011,15 @@ msgstr "" msgid "Order custom mail" msgstr "" -#: pretix/control/templates/pretixcontrol/event/mail.html:120 +#: pretix/control/templates/pretixcontrol/event/mail.html:123 msgid "Reminder to download tickets" msgstr "" -#: pretix/control/templates/pretixcontrol/event/mail.html:123 +#: pretix/control/templates/pretixcontrol/event/mail.html:126 msgid "Order approval process" msgstr "" -#: pretix/control/templates/pretixcontrol/event/mail.html:126 +#: pretix/control/templates/pretixcontrol/event/mail.html:129 msgid "Attachments" msgstr "" @@ -17253,6 +18084,7 @@ msgid "" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:6 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:6 msgid "Available plugins" msgstr "" @@ -17264,34 +18096,36 @@ msgid "" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:15 -#: pretix/control/views/checkin.py:423 pretix/control/views/discounts.py:113 -#: pretix/control/views/event.py:239 pretix/control/views/event.py:548 -#: pretix/control/views/event.py:587 pretix/control/views/event.py:734 -#: pretix/control/views/event.py:963 pretix/control/views/event.py:1334 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:15 +#: pretix/control/views/checkin.py:424 pretix/control/views/discounts.py:113 +#: pretix/control/views/event.py:246 pretix/control/views/event.py:576 +#: pretix/control/views/event.py:615 pretix/control/views/event.py:778 +#: pretix/control/views/event.py:1007 pretix/control/views/event.py:1380 +#: pretix/control/views/event.py:1420 #: pretix/control/views/global_settings.py:65 #: pretix/control/views/global_settings.py:88 pretix/control/views/item.py:264 #: pretix/control/views/item.py:795 pretix/control/views/item.py:1121 #: pretix/control/views/item.py:1299 pretix/control/views/item.py:1449 #: pretix/control/views/mailsetup.py:151 pretix/control/views/mailsetup.py:163 #: pretix/control/views/mailsetup.py:190 pretix/control/views/mailsetup.py:258 -#: pretix/control/views/organizer.py:260 pretix/control/views/organizer.py:288 -#: pretix/control/views/organizer.py:504 pretix/control/views/organizer.py:676 -#: pretix/control/views/organizer.py:1071 -#: pretix/control/views/organizer.py:1169 -#: pretix/control/views/organizer.py:1333 -#: pretix/control/views/organizer.py:2052 -#: pretix/control/views/organizer.py:2189 -#: pretix/control/views/organizer.py:2386 -#: pretix/control/views/organizer.py:2502 -#: pretix/control/views/organizer.py:2631 -#: pretix/control/views/organizer.py:2825 -#: pretix/control/views/organizer.py:2854 -#: pretix/control/views/organizer.py:2894 -#: pretix/control/views/organizer.py:2971 -#: pretix/control/views/organizer.py:3068 -#: pretix/control/views/organizer.py:3097 -#: pretix/control/views/organizer.py:3235 pretix/control/views/subevents.py:525 -#: pretix/control/views/subevents.py:1590 pretix/control/views/user.py:236 +#: pretix/control/views/organizer.py:272 pretix/control/views/organizer.py:300 +#: pretix/control/views/organizer.py:516 pretix/control/views/organizer.py:850 +#: pretix/control/views/organizer.py:945 pretix/control/views/organizer.py:1340 +#: pretix/control/views/organizer.py:1438 +#: pretix/control/views/organizer.py:1602 +#: pretix/control/views/organizer.py:2321 +#: pretix/control/views/organizer.py:2458 +#: pretix/control/views/organizer.py:2655 +#: pretix/control/views/organizer.py:2771 +#: pretix/control/views/organizer.py:2900 +#: pretix/control/views/organizer.py:3094 +#: pretix/control/views/organizer.py:3123 +#: pretix/control/views/organizer.py:3163 +#: pretix/control/views/organizer.py:3240 +#: pretix/control/views/organizer.py:3337 +#: pretix/control/views/organizer.py:3366 +#: pretix/control/views/organizer.py:3504 pretix/control/views/subevents.py:525 +#: pretix/control/views/subevents.py:1597 pretix/control/views/user.py:236 #: pretix/control/views/users.py:114 pretix/control/views/vouchers.py:305 #: pretix/plugins/autocheckin/views.py:164 pretix/plugins/badges/views.py:157 #: pretix/plugins/sendmail/views.py:645 pretix/plugins/stripe/views.py:679 @@ -17301,36 +18135,60 @@ msgid "Your changes have been saved." msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:34 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:34 msgid "Search results" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:56 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:56 msgid "Top recommendation" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:60 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:60 msgid "Experimental feature" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:83 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:106 msgid "Incompatible" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:87 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:110 msgid "Not available" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:93 -#: pretix/control/templates/pretixcontrol/event/plugins.html:105 +msgid "This plugin can only be disabled for the entire organizer account." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:98 +msgid "" +"After disabling this plugin, some functionality may remain active in the " +"organizer account." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:104 +#: pretix/control/templates/pretixcontrol/event/plugins.html:116 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:122 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:134 msgid "Open plugin settings" msgstr "" -#: pretix/control/templates/pretixcontrol/event/plugins.html:94 +#: pretix/control/templates/pretixcontrol/event/plugins.html:105 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:123 msgid "Go to" msgstr "" -#: pretix/control/templates/pretixcontrol/event/plugins.html:116 +#: pretix/control/templates/pretixcontrol/event/plugins.html:130 +#: pretix/control/templates/pretixcontrol/event/plugins.html:147 +msgid "Open in organizer settings" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:134 #: pretix/control/templates/pretixcontrol/oauth/app_delete.html:15 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:145 #: pretix/control/templates/pretixcontrol/user/2fa_disable.html:20 #: pretix/control/templates/pretixcontrol/user/2fa_main.html:79 #: pretix/control/templates/pretixcontrol/user/2fa_main.html:83 @@ -17339,7 +18197,20 @@ msgstr "" msgid "Disable" msgstr "" -#: pretix/control/templates/pretixcontrol/event/plugins.html:121 +#: pretix/control/templates/pretixcontrol/event/plugins.html:141 +#: pretix/control/views/organizer.py:807 +msgid "This plugin can only be enabled for the entire organizer account." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:154 +msgid "" +"Enabling this plugin will enable some of its functionality for the entire " +"organizer account." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:159 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:157 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:177 #: pretix/control/templates/pretixcontrol/user/2fa_enable.html:21 #: pretix/control/templates/pretixcontrol/user/2fa_main.html:99 #: pretix/control/templates/pretixcontrol/user/notifications.html:23 @@ -17399,11 +18270,6 @@ msgid "" "in the navigation. Don't worry, you can change everything you input here." msgstr "" -#: pretix/control/templates/pretixcontrol/event/quick_setup.html:132 -#: pretix/control/views/event.py:381 -msgid "Features" -msgstr "" - #: pretix/control/templates/pretixcontrol/event/quick_setup.html:134 msgid "" "We recommend that you take some time to go through the \"Settings\" part of " @@ -17524,7 +18390,7 @@ msgid "Shop design" msgstr "" #: pretix/control/templates/pretixcontrol/event/settings.html:232 -#: pretix/control/templates/pretixcontrol/events/create_basics.html:56 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:59 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:411 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:96 #: pretix/control/templates/pretixcontrol/subevents/detail.html:54 @@ -17556,12 +18422,6 @@ msgctxt "subevents" msgid "Calendar and list views" msgstr "" -#: pretix/control/templates/pretixcontrol/event/settings.html:280 -#: pretix/control/templates/pretixcontrol/order/index.html:176 -#: pretix/presale/templates/pretixpresale/event/order.html:22 -msgid "Order details" -msgstr "" - #: pretix/control/templates/pretixcontrol/event/settings.html:284 msgid "Other settings" msgstr "" @@ -17634,10 +18494,6 @@ msgstr "" msgid "Property" msgstr "" -#: pretix/control/templates/pretixcontrol/event/settings.html:487 -msgid "Add property" -msgstr "" - #: pretix/control/templates/pretixcontrol/event/settings.html:505 #: pretix/control/templates/pretixcontrol/events/index.html:165 #: pretix/control/templates/pretixcontrol/organizers/detail.html:130 @@ -17667,8 +18523,8 @@ msgstr "" #: pretix/control/templates/pretixcontrol/event/tax_delete.html:12 msgid "" -"You cannot delete a tax rule that is in use for a product or has been in use " -"for any existing orders." +"You cannot delete a tax rule that is in use for a product, has been in use " +"for any existing orders, or is the default tax rule of the event." msgstr "" #: pretix/control/templates/pretixcontrol/event/tax_edit.html:7 @@ -17734,16 +18590,22 @@ msgstr "" msgid "Create a new tax rule" msgstr "" -#: pretix/control/templates/pretixcontrol/event/tax_index.html:27 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:28 msgid "Rate" msgstr "" -#: pretix/control/templates/pretixcontrol/event/tax_index.html:41 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:51 +#: pretix/plugins/badges/templates/pretixplugins/badges/index.html:63 +#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:60 +msgid "Make default" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/tax_index.html:58 #, python-format msgid "incl. %(rate)s %%" msgstr "" -#: pretix/control/templates/pretixcontrol/event/tax_index.html:43 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:60 #, python-format msgid "excl. %(rate)s %%" msgstr "" @@ -17862,7 +18724,7 @@ msgstr "" msgid "Set to random" msgstr "" -#: pretix/control/templates/pretixcontrol/events/create_basics.html:18 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:21 msgid "" "This is the address users can buy your tickets at. Should be short, only " "contain lowercase letters, numbers, dots, and dashes, and must be unique " @@ -17871,18 +18733,18 @@ msgid "" "choose to use a random value." msgstr "" -#: pretix/control/templates/pretixcontrol/events/create_basics.html:26 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:29 msgid "" "We will also use this in some places like order codes, invoice numbers or " "bank transfer references as an abbreviation to reference this event." msgstr "" -#: pretix/control/templates/pretixcontrol/events/create_basics.html:32 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:35 msgid "" "We strongly recommend against using short forms of more then 16 characters." msgstr "" -#: pretix/control/templates/pretixcontrol/events/create_basics.html:50 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:53 msgid "Display settings" msgstr "" @@ -17961,7 +18823,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/events/index.html:121 #: pretix/control/templates/pretixcontrol/organizers/detail.html:97 -#: pretix/control/views/dashboards.py:519 pretix/control/views/typeahead.py:89 +#: pretix/control/views/dashboards.py:523 pretix/control/views/typeahead.py:89 msgctxt "subevent" msgid "No dates" msgstr "" @@ -17973,14 +18835,14 @@ msgstr "" #: pretix/control/templates/pretixcontrol/events/index.html:149 #: pretix/control/templates/pretixcontrol/organizers/detail.html:113 -#: pretix/control/views/dashboards.py:532 +#: pretix/control/views/dashboards.py:536 msgid "Shop disabled" msgstr "" #: pretix/control/templates/pretixcontrol/events/index.html:155 #: pretix/control/templates/pretixcontrol/organizers/detail.html:119 #: pretix/control/templates/pretixcontrol/subevents/index.html:172 -#: pretix/control/views/dashboards.py:538 +#: pretix/control/views/dashboards.py:542 msgid "On sale" msgstr "" @@ -18730,10 +19592,6 @@ msgstr "" msgid "%(num)s available" msgstr "" -#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:11 -msgid "Unlimited" -msgstr "" - #: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:14 msgid "Fully reserved" msgstr "" @@ -18804,8 +19662,8 @@ msgid "Can only be bought using a voucher" msgstr "" #: pretix/control/templates/pretixcontrol/items/index.html:149 -#: pretix/control/templates/pretixcontrol/order/index.html:616 -#: pretix/control/templates/pretixcontrol/order/index.html:656 +#: pretix/control/templates/pretixcontrol/order/index.html:668 +#: pretix/control/templates/pretixcontrol/order/index.html:708 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:360 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:415 #, python-format @@ -18813,8 +19671,8 @@ msgid "plus %(rate)s%% %(taxname)s" msgstr "" #: pretix/control/templates/pretixcontrol/items/index.html:153 -#: pretix/control/templates/pretixcontrol/order/index.html:626 -#: pretix/control/templates/pretixcontrol/order/index.html:666 +#: pretix/control/templates/pretixcontrol/order/index.html:678 +#: pretix/control/templates/pretixcontrol/order/index.html:718 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:370 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:425 #, python-format @@ -18837,9 +19695,9 @@ msgstr "" #: pretix/control/templates/pretixcontrol/items/question.html:26 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:31 #: pretix/control/templates/pretixcontrol/orders/overview.html:88 -#: pretix/plugins/checkinlists/exporters.py:502 -#: pretix/plugins/checkinlists/exporters.py:696 -#: pretix/plugins/reports/exporters.py:386 +#: pretix/plugins/checkinlists/exporters.py:503 +#: pretix/plugins/checkinlists/exporters.py:697 +#: pretix/plugins/reports/exporters.py:397 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:23 msgid "Paid" msgstr "" @@ -18868,9 +19726,9 @@ msgstr "" #: pretix/control/templates/pretixcontrol/items/question.html:112 #: pretix/control/templates/pretixcontrol/order/transactions.html:67 -#: pretix/plugins/reports/accountingreport.py:408 -#: pretix/plugins/reports/accountingreport.py:441 -#: pretix/plugins/reports/accountingreport.py:565 +#: pretix/plugins/reports/accountingreport.py:409 +#: pretix/plugins/reports/accountingreport.py:442 +#: pretix/plugins/reports/accountingreport.py:566 msgid "Sum" msgstr "" @@ -19207,7 +20065,7 @@ msgstr "" #: pretix/control/templates/pretixcontrol/order/cancel.html:10 #: pretix/control/templates/pretixcontrol/order/index.html:68 #: pretix/control/templates/pretixcontrol/order/index.html:166 -#: pretix/presale/templates/pretixpresale/event/order.html:479 +#: pretix/presale/templates/pretixpresale/event/order.html:483 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:7 msgid "Cancel order" msgstr "" @@ -19365,14 +20223,14 @@ msgid "Validity time" msgstr "" #: pretix/control/templates/pretixcontrol/order/change.html:247 -#: pretix/control/templates/pretixcontrol/order/index.html:455 +#: pretix/control/templates/pretixcontrol/order/index.html:495 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:107 #, python-format msgid "Valid from %(datetime)s" msgstr "" #: pretix/control/templates/pretixcontrol/order/change.html:255 -#: pretix/control/templates/pretixcontrol/order/index.html:459 +#: pretix/control/templates/pretixcontrol/order/index.html:499 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:111 #, python-format msgid "Valid until %(datetime)s" @@ -19419,7 +20277,7 @@ msgid "Add fee" msgstr "" #: pretix/control/templates/pretixcontrol/order/change.html:520 -#: pretix/control/templates/pretixcontrol/order/change_questions.html:65 +#: pretix/control/templates/pretixcontrol/order/change_questions.html:66 msgid "Other operations" msgstr "" @@ -19449,8 +20307,8 @@ msgid "Change order information" msgstr "" #: pretix/control/templates/pretixcontrol/order/change_questions.html:25 -#: pretix/control/templates/pretixcontrol/order/index.html:940 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:75 +#: pretix/control/templates/pretixcontrol/order/index.html:992 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:74 #: pretix/presale/templates/pretixpresale/event/checkout_questions.html:35 #: pretix/presale/templates/pretixpresale/event/order_modify.html:29 msgid "Invoice information" @@ -19500,13 +20358,13 @@ msgstr "" #: pretix/control/templates/pretixcontrol/order/index.html:46 #: pretix/control/templates/pretixcontrol/orders/index.html:297 -#: pretix/control/views/orders.py:310 +#: pretix/control/views/orders.py:311 msgid "Approve" msgstr "" #: pretix/control/templates/pretixcontrol/order/index.html:51 #: pretix/control/templates/pretixcontrol/orders/index.html:304 -#: pretix/control/views/orders.py:324 +#: pretix/control/views/orders.py:325 msgid "Deny" msgstr "" @@ -19545,7 +20403,7 @@ msgid "" msgstr "" #: pretix/control/templates/pretixcontrol/order/index.html:116 -#: pretix/control/views/orders.py:372 +#: pretix/control/views/orders.py:373 msgid "Refund for overpayment" msgstr "" @@ -19608,236 +20466,264 @@ msgid "" "sent them." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:276 +#: pretix/control/templates/pretixcontrol/order/index.html:278 msgid "" "We don't know if this invoice was emailed to the customer since it was " "created before our system tracked this information" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:281 +#: pretix/control/templates/pretixcontrol/order/index.html:283 msgid "Invoice was emailed to customer" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:286 +#: pretix/control/templates/pretixcontrol/order/index.html:288 msgid "Invoice was not yet emailed to customer" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:296 +#: pretix/control/templates/pretixcontrol/order/index.html:294 +msgid "Invoice is scheduled to be transmitted" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:299 +msgid "Invoice is not yet transmitted" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:302 +msgid "Invoice is currently in transmission" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:307 +msgid "Invoice not transmitted in test mode" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:312 +msgid "Invoice transmission failed" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:317 +msgid "Invoice has been transmitted" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:329 +msgid "Transmit" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:331 +msgid "Retransmit" +msgstr "" + +#: pretix/control/templates/pretixcontrol/order/index.html:342 msgid "Rebuild the invoice with updated data but the same invoice number." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:297 +#: pretix/control/templates/pretixcontrol/order/index.html:343 #: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html:20 msgid "Regenerate" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:308 +#: pretix/control/templates/pretixcontrol/order/index.html:354 msgid "" "Generate a cancellation document for this invoice and create a new invoice " "with a new invoice number." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:311 +#: pretix/control/templates/pretixcontrol/order/index.html:357 msgid "Generate cancellation" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:313 +#: pretix/control/templates/pretixcontrol/order/index.html:359 msgid "Cancel and reissue" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:326 -msgid "Email invoices" -msgstr "" - -#: pretix/control/templates/pretixcontrol/order/index.html:335 -#: pretix/control/templates/pretixcontrol/order/index.html:347 +#: pretix/control/templates/pretixcontrol/order/index.html:375 +#: pretix/control/templates/pretixcontrol/order/index.html:387 msgid "Generate invoice" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:361 +#: pretix/control/templates/pretixcontrol/order/index.html:401 msgid "Change answers" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:365 +#: pretix/control/templates/pretixcontrol/order/index.html:405 msgid "Change products" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:370 +#: pretix/control/templates/pretixcontrol/order/index.html:410 #: pretix/presale/templates/pretixpresale/event/order.html:197 msgid "Ordered items" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:389 +#: pretix/control/templates/pretixcontrol/order/index.html:429 #, python-format msgid "Denied scan: %(date)s" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:394 +#: pretix/control/templates/pretixcontrol/order/index.html:434 #, python-format msgid "Exit scan: %(date)s" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:401 +#: pretix/control/templates/pretixcontrol/order/index.html:441 #, python-format msgid "Entry scan: %(date)s" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:420 +#: pretix/control/templates/pretixcontrol/order/index.html:460 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:55 msgid "Voucher code used:" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:422 +#: pretix/control/templates/pretixcontrol/order/index.html:462 #, python-format msgid "Used %(amount)s discount from budget" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:439 +#: pretix/control/templates/pretixcontrol/order/index.html:479 msgid "" "The price of this product was reduced because of an automatic discount or " "this product was part of the discount calculation for a different product in " "this order." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:451 +#: pretix/control/templates/pretixcontrol/order/index.html:491 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:103 #, python-format msgid "Valid %(datetime_range)s" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:497 +#: pretix/control/templates/pretixcontrol/order/index.html:537 msgid "Ticket page" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:516 -#: pretix/control/templates/pretixcontrol/order/index.html:537 -#: pretix/control/templates/pretixcontrol/order/index.html:546 -#: pretix/control/templates/pretixcontrol/order/index.html:560 +#: pretix/control/templates/pretixcontrol/order/index.html:568 +#: pretix/control/templates/pretixcontrol/order/index.html:589 #: pretix/control/templates/pretixcontrol/order/index.html:598 -#: pretix/control/templates/pretixcontrol/order/index.html:605 +#: pretix/control/templates/pretixcontrol/order/index.html:612 +#: pretix/control/templates/pretixcontrol/order/index.html:650 +#: pretix/control/templates/pretixcontrol/order/index.html:657 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:228 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:234 msgid "not answered" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:570 +#: pretix/control/templates/pretixcontrol/order/index.html:622 msgid "This question will be asked during check-in." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:582 +#: pretix/control/templates/pretixcontrol/order/index.html:634 msgid "" "This file has been uploaded by a user and could contain viruses or other " "malicious content." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:583 +#: pretix/control/templates/pretixcontrol/order/index.html:635 msgid "UNSAFE" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:687 +#: pretix/control/templates/pretixcontrol/order/index.html:739 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:453 msgid "Taxes" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:696 +#: pretix/control/templates/pretixcontrol/order/index.html:748 #: pretix/control/templates/pretixcontrol/orders/overview.html:89 #: pretix/control/templates/pretixcontrol/orders/overview.html:177 -#: pretix/plugins/reports/accountingreport.py:498 -#: pretix/plugins/reports/exporters.py:386 -#: pretix/plugins/reports/exporters.py:435 -#: pretix/plugins/reports/exporters.py:627 -#: pretix/plugins/reports/exporters.py:957 +#: pretix/plugins/reports/accountingreport.py:499 +#: pretix/plugins/reports/exporters.py:397 +#: pretix/plugins/reports/exporters.py:446 +#: pretix/plugins/reports/exporters.py:638 +#: pretix/plugins/reports/exporters.py:968 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:465 msgid "Total" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:706 +#: pretix/control/templates/pretixcontrol/order/index.html:758 #: pretix/presale/templates/pretixpresale/event/order.html:210 msgid "Successful payments" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:715 +#: pretix/control/templates/pretixcontrol/order/index.html:767 #: pretix/presale/templates/pretixpresale/event/order.html:219 msgid "Pending total" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:741 +#: pretix/control/templates/pretixcontrol/order/index.html:793 #: pretix/control/templates/pretixcontrol/search/payments.html:88 msgid "Confirmation date" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:754 +#: pretix/control/templates/pretixcontrol/order/index.html:806 #: pretix/control/templates/pretixcontrol/search/payments.html:125 msgid "" "This payment was created with an older version of pretix, therefore accurate " "data might not be available." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:755 +#: pretix/control/templates/pretixcontrol/order/index.html:807 #: pretix/control/templates/pretixcontrol/search/payments.html:126 msgid "MIGRATED" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:767 +#: pretix/control/templates/pretixcontrol/order/index.html:819 #: pretix/control/templates/pretixcontrol/order/pay_cancel.html:4 #: pretix/control/templates/pretixcontrol/order/pay_cancel.html:8 msgid "Cancel payment" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:772 +#: pretix/control/templates/pretixcontrol/order/index.html:824 msgid "Confirm as paid" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:815 +#: pretix/control/templates/pretixcontrol/order/index.html:867 msgid "Create a refund" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:836 +#: pretix/control/templates/pretixcontrol/order/index.html:888 #: pretix/control/templates/pretixcontrol/orders/refunds.html:60 msgid "Source" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:869 +#: pretix/control/templates/pretixcontrol/order/index.html:921 msgid "Cancel transfer" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:874 +#: pretix/control/templates/pretixcontrol/order/index.html:926 #: pretix/control/templates/pretixcontrol/orders/refunds.html:112 msgid "Confirm as done" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:881 +#: pretix/control/templates/pretixcontrol/order/index.html:933 #: pretix/control/templates/pretixcontrol/orders/refunds.html:118 msgid "Ignore" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:887 +#: pretix/control/templates/pretixcontrol/order/index.html:939 #: pretix/control/templates/pretixcontrol/order/refund_process.html:58 #: pretix/control/templates/pretixcontrol/orders/refunds.html:123 msgid "Process refund" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:935 +#: pretix/control/templates/pretixcontrol/order/index.html:987 #: pretix/presale/templates/pretixpresale/event/base.html:141 #: pretix/presale/templates/pretixpresale/event/timemachine.html:30 msgid "Change" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:951 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:91 +#: pretix/control/templates/pretixcontrol/order/index.html:1003 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:90 #: pretix/presale/templates/pretixpresale/event/order.html:318 msgid "ZIP code and city" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:964 +#: pretix/control/templates/pretixcontrol/order/index.html:1016 msgid "Valid EU VAT ID" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:970 +#: pretix/control/templates/pretixcontrol/order/index.html:1022 msgid "Check" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:1018 +#: pretix/control/templates/pretixcontrol/order/index.html:1076 msgid "Order history" msgstr "" @@ -20589,12 +21475,12 @@ msgid "Select action" msgstr "" #: pretix/control/templates/pretixcontrol/orders/index.html:311 -#: pretix/control/views/orders.py:356 +#: pretix/control/views/orders.py:357 msgid "Refund overpaid amount" msgstr "" #: pretix/control/templates/pretixcontrol/orders/index.html:319 -#: pretix/control/views/orders.py:341 +#: pretix/control/views/orders.py:342 msgid "Mark as expired if overdue" msgstr "" @@ -20620,7 +21506,7 @@ msgid "Revenue (net)" msgstr "" #: pretix/control/templates/pretixcontrol/orders/overview.html:49 -#: pretix/plugins/reports/exporters.py:465 +#: pretix/plugins/reports/exporters.py:476 msgid "" "Filtering this report by date is not recommended as it might lead to " "misleading information since this report only sees the current state of any " @@ -20637,7 +21523,7 @@ msgid "" msgstr "" #: pretix/control/templates/pretixcontrol/orders/overview.html:80 -#: pretix/plugins/reports/exporters.py:382 +#: pretix/plugins/reports/exporters.py:393 msgid "Purchased" msgstr "" @@ -20900,11 +21786,11 @@ msgstr "" msgid "System URL:" msgstr "" -#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:25 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:30 msgid "Token:" msgstr "" -#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:31 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:40 msgid "Device overview" msgstr "" @@ -21351,6 +22237,67 @@ msgid "" "This can be used to enable products like year passes, tickets of ten, etc." msgstr "" +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:6 +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:12 +#, python-format +msgid "Events with plugin %(name)s" +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:18 +#, python-format +msgid "" +"The plugin \"%(name)s\" can be enabled or disabled for every event " +"individually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:24 +#, python-format +msgid "" +"The plugin \"%(name)s\" is enabled for your organizer account, but also " +"needs to be enabled for the specific events you want to use it with." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:31 +msgid "" +"Using this form, you can quickly enable or disable it for many events. Note " +"that it might still be necessary to configure the plugin for each event " +"individually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:8 +msgid "" +"On this page, you can choose plugins you want to enable for your organizer " +"account. Plugins might bring additional software functionality, connect your " +"events to third-party services, or apply other forms of customizations." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:80 +msgid "Active (all events)" +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:85 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:94 +#, python-format +msgid "Active (%(count)s event)" +msgid_plural "Active (%(count)s events)" +msgstr[0] "" +msgstr[1] "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:116 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:173 +msgid "" +"Parts of this plugin can be enabled or disabled for events individually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:149 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:167 +msgid "Manage events" +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:162 +msgid "This plugin can be enabled or disabled for events individually." +msgstr "" + #: pretix/control/templates/pretixcontrol/organizers/properties.html:7 msgid "" "You can here define a set of metadata properties (i.e. variables) that you " @@ -21615,10 +22562,6 @@ msgid_plural "%(count)s webhooks are scheduled to be retried." msgstr[0] "" msgstr[1] "" -#: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:22 -msgid "Retry now" -msgstr "" - #: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:25 msgid "Stop retrying" msgstr "" @@ -21709,60 +22652,95 @@ msgstr "" msgid "Page %(page)s" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:5 -#: pretix/control/templates/pretixcontrol/pdf/index.html:15 +#: pretix/control/templates/pretixcontrol/pdf/index.html:6 +#: pretix/control/templates/pretixcontrol/pdf/index.html:16 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:5 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:15 msgid "PDF Editor" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:31 +#: pretix/control/templates/pretixcontrol/pdf/index.html:36 #: pretix/plugins/banktransfer/refund_export.py:46 msgid "Code" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:35 -msgid "Paste" +#: pretix/control/templates/pretixcontrol/pdf/index.html:52 +msgid "Text box" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:39 +#: pretix/control/templates/pretixcontrol/pdf/index.html:59 +msgid "QR Code" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:64 +msgid "QR code for Check-In" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:71 +msgid "QR code for Lead Scanning" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:78 +msgid "Other QR code" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:87 +msgid "Image" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:92 +msgid "" +"You can use this to add user-uploaded pictures from questions or pictures " +"generated by plugins. If you want to embed a logo or other images, use a " +"custom background instead." +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:93 +msgid "Dynamic image" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:100 +msgid "pretix Logo" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:107 +msgid "Duplicate" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:117 msgid "Undo" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:43 +#: pretix/control/templates/pretixcontrol/pdf/index.html:121 msgid "Redo" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:48 -msgid "Editor" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:66 +#: pretix/control/templates/pretixcontrol/pdf/index.html:142 msgid "" "This feature is only intended for advanced users. We recommend to only use " "it to copy and share ticket designs, not to modify the design source code." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:80 +#: pretix/control/templates/pretixcontrol/pdf/index.html:156 msgid "Apply" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:88 +#: pretix/control/templates/pretixcontrol/pdf/index.html:164 msgid "Uploading new PDF background…" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:96 +#: pretix/control/templates/pretixcontrol/pdf/index.html:172 msgid "Welcome to the PDF ticket editor!" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:98 +#: pretix/control/templates/pretixcontrol/pdf/index.html:174 msgid "" "This editor allows you to create a design for the PDF tickets of your event. " "You can upload a background PDF and then use this tool to place texts and a " "QR code on the ticket." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:109 +#: pretix/control/templates/pretixcontrol/pdf/index.html:185 msgid "" "Please note that the editor can only provide a rough preview. Some details, " "for example in text rendering, might look slightly different in the final " @@ -21770,7 +22748,7 @@ msgid "" "preview." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:123 +#: pretix/control/templates/pretixcontrol/pdf/index.html:199 msgid "" "The editor is tested with recent versions of Google Chrome, Mozilla Firefox " "and Opera. Other browsers, especially Internet Explorer or Microsoft Edge, " @@ -21778,217 +22756,169 @@ msgid "" "fonts." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:131 +#: pretix/control/templates/pretixcontrol/pdf/index.html:207 msgid "" "The editor requires JavaScript to work. Please enable JavaScript in your " "browser to continue." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:141 -#: pretix/control/templates/pretixcontrol/pdf/index.html:173 +#: pretix/control/templates/pretixcontrol/pdf/index.html:217 +#: pretix/control/templates/pretixcontrol/pdf/index.html:233 msgid "Loading…" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:144 +#: pretix/control/templates/pretixcontrol/pdf/index.html:220 msgid "Start editing" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:159 -msgid "Cut" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:163 -#: pretix/control/templates/pretixcontrol/vouchers/detail.html:54 -msgid "Copy" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:180 +#: pretix/control/templates/pretixcontrol/pdf/index.html:240 msgid "Layout name" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:187 +#: pretix/control/templates/pretixcontrol/pdf/index.html:247 msgid "Preferred language" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:200 -#: pretix/control/templates/pretixcontrol/pdf/index.html:210 +#: pretix/control/templates/pretixcontrol/pdf/index.html:260 +#: pretix/control/templates/pretixcontrol/pdf/index.html:270 msgid "Upload PDF as background" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:202 +#: pretix/control/templates/pretixcontrol/pdf/index.html:262 msgid "" "You can upload a PDF to use as a custom background. The paper size will " "match the PDF." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:217 +#: pretix/control/templates/pretixcontrol/pdf/index.html:277 msgid "Download current background" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:224 +#: pretix/control/templates/pretixcontrol/pdf/index.html:284 msgid "Or choose custom paper size" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:226 +#: pretix/control/templates/pretixcontrol/pdf/index.html:286 msgid "" "To manually change the paper size, you need to create a new, empty " "background." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:234 -#: pretix/control/templates/pretixcontrol/pdf/index.html:321 -#: pretix/control/templates/pretixcontrol/pdf/index.html:363 +#: pretix/control/templates/pretixcontrol/pdf/index.html:294 +#: pretix/control/templates/pretixcontrol/pdf/index.html:381 +#: pretix/control/templates/pretixcontrol/pdf/index.html:423 msgid "Width (mm)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:238 -#: pretix/control/templates/pretixcontrol/pdf/index.html:326 +#: pretix/control/templates/pretixcontrol/pdf/index.html:298 +#: pretix/control/templates/pretixcontrol/pdf/index.html:386 msgid "Height (mm)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:247 +#: pretix/control/templates/pretixcontrol/pdf/index.html:307 msgid "Create empty background" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:254 +#: pretix/control/templates/pretixcontrol/pdf/index.html:314 msgid "Style" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:256 +#: pretix/control/templates/pretixcontrol/pdf/index.html:316 msgid "Dark" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:257 +#: pretix/control/templates/pretixcontrol/pdf/index.html:317 msgid "Light" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:263 +#: pretix/control/templates/pretixcontrol/pdf/index.html:323 msgid "Image content" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:274 +#: pretix/control/templates/pretixcontrol/pdf/index.html:334 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:20 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:34 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:29 msgid "Content" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:283 +#: pretix/control/templates/pretixcontrol/pdf/index.html:343 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:50 msgid "Event attribute:" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:288 +#: pretix/control/templates/pretixcontrol/pdf/index.html:348 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:59 msgid "Item attribute:" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:291 +#: pretix/control/templates/pretixcontrol/pdf/index.html:351 msgid "Other… (multilingual)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:292 +#: pretix/control/templates/pretixcontrol/pdf/index.html:352 msgid "Other…" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:302 +#: pretix/control/templates/pretixcontrol/pdf/index.html:362 msgid "Show available placeholders" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:309 +#: pretix/control/templates/pretixcontrol/pdf/index.html:369 msgid "x (mm)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:314 +#: pretix/control/templates/pretixcontrol/pdf/index.html:374 msgid "y (mm)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:333 +#: pretix/control/templates/pretixcontrol/pdf/index.html:393 msgid "Size (mm)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:340 +#: pretix/control/templates/pretixcontrol/pdf/index.html:400 msgid "QR color" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:355 +#: pretix/control/templates/pretixcontrol/pdf/index.html:415 msgid "Render without whitespace" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:357 +#: pretix/control/templates/pretixcontrol/pdf/index.html:417 msgid "" "Required for consistent size across platforms. Supported on Android starting " "with pretixPRINT 2.3.3 and on Desktop with pretixSCAN 1.9.3." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:368 +#: pretix/control/templates/pretixcontrol/pdf/index.html:428 msgid "Rotation (°)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:387 +#: pretix/control/templates/pretixcontrol/pdf/index.html:447 msgid "Font size (pt)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:392 +#: pretix/control/templates/pretixcontrol/pdf/index.html:452 msgid "Line height" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:399 +#: pretix/control/templates/pretixcontrol/pdf/index.html:459 msgid "Text color" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:422 +#: pretix/control/templates/pretixcontrol/pdf/index.html:482 msgid "Flow multiple lines downward from specified position" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:476 +#: pretix/control/templates/pretixcontrol/pdf/index.html:536 msgid "Automatically reduce font size to fit content" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:482 +#: pretix/control/templates/pretixcontrol/pdf/index.html:542 msgid "Allow long words to be split (preview is not accurate)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:493 -msgid "Add a new object" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:498 -msgid "Text box" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:502 -msgid "Text (deprecated)" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:506 -msgid "QR code for Check-In" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:512 -msgid "QR code for Lead Scanning" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:518 -msgid "Other QR code" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:524 -msgid "pretix Logo" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:527 -msgid "" -"You can use this to add user-uploaded pictures from questions or pictures " -"generated by plugins. If you want to embed a logo or other images, use a " -"custom background instead." -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:529 -msgid "Dynamic image" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:550 +#: pretix/control/templates/pretixcontrol/pdf/index.html:553 #, python-format msgid "" "This layout uses new features. If you print from your device, make sure you " @@ -22342,7 +23272,7 @@ msgid "Create many new dates" msgstr "" #: pretix/control/templates/pretixcontrol/subevents/index.html:96 -#: pretix/plugins/reports/accountingreport.py:120 +#: pretix/plugins/reports/accountingreport.py:121 msgid "Begin" msgstr "" @@ -22945,6 +23875,10 @@ msgstr "" msgid "Voucher link" msgstr "" +#: pretix/control/templates/pretixcontrol/vouchers/detail.html:54 +msgid "Copy" +msgstr "" + #: pretix/control/templates/pretixcontrol/vouchers/detail.html:116 msgid "Voucher history" msgstr "" @@ -23239,16 +24173,19 @@ msgid "" msgstr "" #: pretix/control/views/auth.py:252 +#, python-brace-format msgid "" "You cannot accept the invitation for \"{}\" as you already are part of this " "team." msgstr "" #: pretix/control/views/auth.py:266 +#, python-brace-format msgid "You are now part of the team \"{}\"." msgstr "" #: pretix/control/views/auth.py:296 +#, python-brace-format msgid "Welcome to pretix! You are now part of the team \"{}\"." msgstr "" @@ -23288,36 +24225,36 @@ msgstr "" msgid "Invalid code, please try again." msgstr "" -#: pretix/control/views/checkin.py:280 +#: pretix/control/views/checkin.py:281 msgid "The selected check-ins have been reverted." msgstr "" -#: pretix/control/views/checkin.py:282 +#: pretix/control/views/checkin.py:283 msgid "The selected tickets have been marked as checked out." msgstr "" -#: pretix/control/views/checkin.py:284 +#: pretix/control/views/checkin.py:285 msgid "The selected tickets have been marked as checked in." msgstr "" -#: pretix/control/views/checkin.py:373 +#: pretix/control/views/checkin.py:374 msgid "The new check-in list has been created." msgstr "" -#: pretix/control/views/checkin.py:380 pretix/control/views/checkin.py:440 +#: pretix/control/views/checkin.py:381 pretix/control/views/checkin.py:441 #: pretix/control/views/discounts.py:134 pretix/control/views/discounts.py:182 -#: pretix/control/views/event.py:268 pretix/control/views/event.py:551 -#: pretix/control/views/event.py:590 pretix/control/views/event.py:737 -#: pretix/control/views/event.py:929 pretix/control/views/event.py:1287 -#: pretix/control/views/event.py:1353 pretix/control/views/event.py:1461 +#: pretix/control/views/event.py:275 pretix/control/views/event.py:579 +#: pretix/control/views/event.py:618 pretix/control/views/event.py:781 +#: pretix/control/views/event.py:973 pretix/control/views/event.py:1333 +#: pretix/control/views/event.py:1399 pretix/control/views/event.py:1551 #: pretix/control/views/item.py:280 pretix/control/views/item.py:327 #: pretix/control/views/item.py:805 pretix/control/views/item.py:831 #: pretix/control/views/item.py:951 pretix/control/views/item.py:1155 #: pretix/control/views/item.py:1321 pretix/control/views/item.py:1506 -#: pretix/control/views/organizer.py:263 pretix/control/views/organizer.py:291 -#: pretix/control/views/organizer.py:1188 pretix/control/views/subevents.py:504 -#: pretix/control/views/subevents.py:630 pretix/control/views/subevents.py:1039 -#: pretix/control/views/subevents.py:1498 pretix/control/views/user.py:358 +#: pretix/control/views/organizer.py:275 pretix/control/views/organizer.py:303 +#: pretix/control/views/organizer.py:1457 pretix/control/views/subevents.py:504 +#: pretix/control/views/subevents.py:630 pretix/control/views/subevents.py:1046 +#: pretix/control/views/subevents.py:1505 pretix/control/views/user.py:358 #: pretix/control/views/vouchers.py:277 pretix/control/views/vouchers.py:351 #: pretix/control/views/vouchers.py:534 pretix/control/views/waitinglist.py:420 #: pretix/plugins/autocheckin/views.py:112 @@ -23328,11 +24265,11 @@ msgstr "" msgid "We could not save your changes. See below for details." msgstr "" -#: pretix/control/views/checkin.py:419 pretix/control/views/checkin.py:456 +#: pretix/control/views/checkin.py:420 pretix/control/views/checkin.py:457 msgid "The requested list does not exist." msgstr "" -#: pretix/control/views/checkin.py:465 +#: pretix/control/views/checkin.py:466 msgid "The selected list has been deleted." msgstr "" @@ -23413,7 +24350,7 @@ msgstr "" msgid "Set up event" msgstr "" -#: pretix/control/views/dashboards.py:534 +#: pretix/control/views/dashboards.py:538 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:110 #: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:116 #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:47 @@ -23422,7 +24359,7 @@ msgstr "" msgid "Sale over" msgstr "" -#: pretix/control/views/dashboards.py:536 +#: pretix/control/views/dashboards.py:540 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:119 #: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:123 #: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:86 @@ -23430,13 +24367,37 @@ msgstr "" msgid "Soon" msgstr "" -#: pretix/control/views/dashboards.py:561 +#: pretix/control/views/dashboards.py:565 #, python-brace-format msgid "{num} order" msgid_plural "{num} orders" msgstr[0] "" msgstr[1] "" +#: pretix/control/views/datasync.py:82 +msgid "The sync job has been enqueued and will run in the next minutes." +msgstr "" + +#: pretix/control/views/datasync.py:89 pretix/control/views/datasync.py:99 +msgid "The sync job is already in progress." +msgstr "" + +#: pretix/control/views/datasync.py:92 +msgid "The sync job has been canceled." +msgstr "" + +#: pretix/control/views/datasync.py:105 +msgid "The sync job has been set to run as soon as possible." +msgstr "" + +#: pretix/control/views/datasync.py:136 +msgid "The selected jobs have been set to run as soon as possible." +msgstr "" + +#: pretix/control/views/datasync.py:139 +msgid "The selected jobs have been canceled." +msgstr "" + #: pretix/control/views/discounts.py:67 pretix/control/views/discounts.py:109 #: pretix/control/views/discounts.py:214 msgid "The requested discount does not exist." @@ -23460,8 +24421,8 @@ msgstr "" #: pretix/control/views/discounts.py:260 pretix/control/views/item.py:190 #: pretix/control/views/item.py:402 pretix/control/views/item.py:536 -#: pretix/control/views/organizer.py:2272 -#: pretix/control/views/organizer.py:3330 +#: pretix/control/views/organizer.py:2541 +#: pretix/control/views/organizer.py:3599 msgid "Some of the provided object ids are invalid." msgstr "" @@ -23469,140 +24430,133 @@ msgstr "" msgid "Not all discounts have been selected." msgstr "" -#: pretix/control/views/event.py:383 -msgid "Integrations" +#: pretix/control/views/event.py:454 +msgid "" +"You do not have sufficient permission to enable plugins that need to be " +"enabled for the entire organizer account." msgstr "" -#: pretix/control/views/event.py:384 -msgid "Customizations" -msgstr "" - -#: pretix/control/views/event.py:385 -msgid "Output and export formats" -msgstr "" - -#: pretix/control/views/event.py:386 -msgid "API features" -msgstr "" - -#: pretix/control/views/event.py:447 +#: pretix/control/views/event.py:473 pretix/control/views/organizer.py:713 +#, python-brace-format msgid "The plugin {} is now active, you can configure it here:" msgstr "" -#: pretix/control/views/event.py:456 +#: pretix/control/views/event.py:482 pretix/control/views/organizer.py:722 +#, python-brace-format msgid "The plugin {} is now active." msgstr "" -#: pretix/control/views/event.py:519 +#: pretix/control/views/event.py:547 msgid "" "This payment provider does not exist or the respective plugin is disabled." msgstr "" -#: pretix/control/views/event.py:776 pretix/control/views/organizer.py:344 +#: pretix/control/views/event.py:820 pretix/control/views/organizer.py:356 #: pretix/control/views/vouchers.py:561 msgid "invalid item" msgstr "" -#: pretix/control/views/event.py:851 +#: pretix/control/views/event.py:895 #, python-format msgid "Your order: %(code)s" msgstr "" -#: pretix/control/views/event.py:860 +#: pretix/control/views/event.py:904 msgid "Unknown email renderer." msgstr "" -#: pretix/control/views/event.py:876 pretix/control/views/orders.py:693 +#: pretix/control/views/event.py:920 pretix/control/views/orders.py:678 #: pretix/presale/views/order.py:1088 pretix/presale/views/order.py:1095 msgid "You requested an invalid ticket output type." msgstr "" -#: pretix/control/views/event.py:1024 +#: pretix/control/views/event.py:1068 msgid "Your shop is live now!" msgstr "" -#: pretix/control/views/event.py:1032 +#: pretix/control/views/event.py:1076 msgid "We've taken your shop down. You can re-enable it whenever you want!" msgstr "" -#: pretix/control/views/event.py:1040 +#: pretix/control/views/event.py:1084 msgid "Your shop is now in test mode!" msgstr "" -#: pretix/control/views/event.py:1057 +#: pretix/control/views/event.py:1101 msgid "" "An order could not be deleted as some constraints (e.g. data created by plug-" "ins) do not allow it." msgstr "" -#: pretix/control/views/event.py:1063 +#: pretix/control/views/event.py:1107 msgid "We've disabled test mode for you. Let's sell some real tickets!" msgstr "" -#: pretix/control/views/event.py:1085 +#: pretix/control/views/event.py:1129 msgid "This event can not be deleted." msgstr "" -#: pretix/control/views/event.py:1108 +#: pretix/control/views/event.py:1152 msgid "The event has been deleted." msgstr "" -#: pretix/control/views/event.py:1111 +#: pretix/control/views/event.py:1155 msgid "" "The event could not be deleted as some constraints (e.g. data created by " "plug-ins) do not allow it." msgstr "" -#: pretix/control/views/event.py:1127 +#: pretix/control/views/event.py:1171 #, python-brace-format msgid "" "Specifically, the following plugins still contain data depends on this " "event: {plugin_names}" msgstr "" -#: pretix/control/views/event.py:1207 pretix/control/views/orders.py:782 +#: pretix/control/views/event.py:1251 pretix/control/views/orders.py:767 msgid "The comment has been updated." msgstr "" -#: pretix/control/views/event.py:1209 pretix/control/views/orders.py:784 +#: pretix/control/views/event.py:1253 pretix/control/views/orders.py:769 msgid "Could not update the comment." msgstr "" -#: pretix/control/views/event.py:1247 pretix/control/views/main.py:330 +#: pretix/control/views/event.py:1291 pretix/control/views/main.py:337 msgid "VAT" msgstr "" -#: pretix/control/views/event.py:1281 +#: pretix/control/views/event.py:1327 msgid "The new tax rule has been created." msgstr "" -#: pretix/control/views/event.py:1304 pretix/control/views/event.py:1369 +#: pretix/control/views/event.py:1350 pretix/control/views/event.py:1413 +#: pretix/control/views/event.py:1459 msgid "The requested tax rule does not exist." msgstr "" -#: pretix/control/views/event.py:1378 +#: pretix/control/views/event.py:1468 msgid "The selected tax rule has been deleted." msgstr "" -#: pretix/control/views/event.py:1380 +#: pretix/control/views/event.py:1470 msgid "The selected tax rule can not be deleted." msgstr "" -#: pretix/control/views/event.py:1431 +#: pretix/control/views/event.py:1521 msgid "Your event is not empty, you need to set it up manually." msgstr "" -#: pretix/control/views/event.py:1566 +#: pretix/control/views/event.py:1656 msgid "" "Your changes have been saved. You can now go on with looking at the details " "or take your event live to start selling!" msgstr "" -#: pretix/control/views/event.py:1585 +#: pretix/control/views/event.py:1675 msgid "Regular ticket" msgstr "" -#: pretix/control/views/event.py:1590 +#: pretix/control/views/event.py:1680 msgid "Reduced ticket" msgstr "" @@ -23708,8 +24662,8 @@ msgid "The order of categories has been updated." msgstr "" #: pretix/control/views/item.py:405 pretix/control/views/item.py:539 -#: pretix/control/views/organizer.py:2275 -#: pretix/control/views/organizer.py:3333 +#: pretix/control/views/organizer.py:2544 +#: pretix/control/views/organizer.py:3602 msgid "Not all objects have been selected." msgstr "" @@ -23849,11 +24803,11 @@ msgid "" "period." msgstr "" -#: pretix/control/views/main.py:217 +#: pretix/control/views/main.py:218 msgid "You do not have permission to clone this event." msgstr "" -#: pretix/control/views/main.py:283 +#: pretix/control/views/main.py:284 #, python-brace-format msgid "Team {event}" msgstr "" @@ -23899,111 +24853,87 @@ msgstr "" msgid "Access for the selected application has been revoked." msgstr "" -#: pretix/control/views/orders.py:192 +#: pretix/control/views/orders.py:193 msgid "We could not process your input. See below for details." msgstr "" -#: pretix/control/views/orders.py:265 +#: pretix/control/views/orders.py:266 #, python-brace-format msgid "" "Successfully executed the action \"{label}\" on {success} of {total} orders." msgstr "" -#: pretix/control/views/orders.py:557 -msgid "Your invoice" -msgid_plural "Your invoices" -msgstr[0] "" -msgstr[1] "" - -#: pretix/control/views/orders.py:559 -#, python-brace-format -msgid "" -"Hello,\n" -"\n" -"please find your invoice attached to this email.\n" -"\n" -"Your {event} team" -msgid_plural "" -"Hello,\n" -"\n" -"please find your invoices attached to this email.\n" -"\n" -"Your {event} team" -msgstr[0] "" -msgstr[1] "" - -#: pretix/control/views/orders.py:695 pretix/plugins/banktransfer/views.py:901 -#: pretix/presale/views/order.py:158 pretix/presale/views/order.py:240 -#: pretix/presale/views/order.py:334 pretix/presale/views/order.py:361 -#: pretix/presale/views/order.py:429 pretix/presale/views/order.py:496 -#: pretix/presale/views/order.py:542 pretix/presale/views/order.py:728 -#: pretix/presale/views/order.py:841 pretix/presale/views/order.py:913 -#: pretix/presale/views/order.py:928 pretix/presale/views/order.py:977 -#: pretix/presale/views/order.py:982 pretix/presale/views/order.py:1097 -#: pretix/presale/views/order.py:1270 pretix/presale/views/order.py:1662 -#: pretix/presale/views/order.py:1693 +#: pretix/control/views/orders.py:680 pretix/presale/views/order.py:158 +#: pretix/presale/views/order.py:240 pretix/presale/views/order.py:334 +#: pretix/presale/views/order.py:361 pretix/presale/views/order.py:429 +#: pretix/presale/views/order.py:496 pretix/presale/views/order.py:542 +#: pretix/presale/views/order.py:728 pretix/presale/views/order.py:841 +#: pretix/presale/views/order.py:913 pretix/presale/views/order.py:928 +#: pretix/presale/views/order.py:977 pretix/presale/views/order.py:982 +#: pretix/presale/views/order.py:1097 pretix/presale/views/order.py:1270 +#: pretix/presale/views/order.py:1662 pretix/presale/views/order.py:1693 msgid "Unknown order code or not authorized to access this order." msgstr "" -#: pretix/control/views/orders.py:697 pretix/presale/views/order.py:1102 +#: pretix/control/views/orders.py:682 pretix/presale/views/order.py:1102 msgid "Ticket download is not enabled for this product." msgstr "" -#: pretix/control/views/orders.py:818 +#: pretix/control/views/orders.py:803 msgid "The order has been deleted." msgstr "" -#: pretix/control/views/orders.py:825 +#: pretix/control/views/orders.py:810 msgid "" "The order could not be deleted as some constraints (e.g. data created by " "plug-ins) do not allow it." msgstr "" -#: pretix/control/views/orders.py:833 +#: pretix/control/views/orders.py:818 msgid "Only orders created in test mode can be deleted." msgstr "" -#: pretix/control/views/orders.py:854 +#: pretix/control/views/orders.py:839 msgid "The order has been denied and is therefore now canceled." msgstr "" -#: pretix/control/views/orders.py:894 +#: pretix/control/views/orders.py:879 msgid "This payment has been canceled." msgstr "" -#: pretix/control/views/orders.py:896 +#: pretix/control/views/orders.py:881 msgid "This payment can not be canceled at the moment." msgstr "" -#: pretix/control/views/orders.py:922 +#: pretix/control/views/orders.py:907 msgid "The refund has been canceled." msgstr "" -#: pretix/control/views/orders.py:924 +#: pretix/control/views/orders.py:909 msgid "This refund can not be canceled at the moment." msgstr "" -#: pretix/control/views/orders.py:958 +#: pretix/control/views/orders.py:943 msgid "The refund has been processed." msgstr "" -#: pretix/control/views/orders.py:960 pretix/control/views/orders.py:986 +#: pretix/control/views/orders.py:945 pretix/control/views/orders.py:971 msgid "This refund can not be processed at the moment." msgstr "" -#: pretix/control/views/orders.py:984 +#: pretix/control/views/orders.py:969 msgid "The refund has been marked as done." msgstr "" -#: pretix/control/views/orders.py:1010 +#: pretix/control/views/orders.py:995 msgid "The request has been removed. If you want, you can now inform the user." msgstr "" -#: pretix/control/views/orders.py:1017 +#: pretix/control/views/orders.py:1002 msgid "Your cancellation request" msgstr "" -#: pretix/control/views/orders.py:1018 +#: pretix/control/views/orders.py:1003 #, python-brace-format msgid "" "Hello,\n" @@ -24014,69 +24944,72 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/control/views/orders.py:1074 +#: pretix/control/views/orders.py:1059 msgid "" "The payment has been marked as complete, but we were unable to send a " "confirmation mail." msgstr "" -#: pretix/control/views/orders.py:1077 +#: pretix/control/views/orders.py:1062 msgid "The payment has been marked as complete." msgstr "" -#: pretix/control/views/orders.py:1079 +#: pretix/control/views/orders.py:1064 msgid "This payment can not be confirmed at the moment." msgstr "" -#: pretix/control/views/orders.py:1170 +#: pretix/control/views/orders.py:1155 msgid "" "The refund was prevented due to a refund already being processed at the same " "time. Please have a look at the order details and check if your refund is " "still necessary." msgstr "" -#: pretix/control/views/orders.py:1270 +#: pretix/control/views/orders.py:1255 msgid "You entered an order in an event with a different currency." msgstr "" -#: pretix/control/views/orders.py:1321 +#: pretix/control/views/orders.py:1306 msgid "" "You can not refund more than the amount of a payment that is not yet " "refunded." msgstr "" -#: pretix/control/views/orders.py:1326 +#: pretix/control/views/orders.py:1311 msgid "" "You selected a partial refund for a payment method that only supports full " "refunds." msgstr "" -#: pretix/control/views/orders.py:1356 +#: pretix/control/views/orders.py:1341 +#, python-brace-format msgid "" "One of the refunds failed to be processed. You should retry to refund in a " "different way. The error message was: {}" msgstr "" -#: pretix/control/views/orders.py:1362 +#: pretix/control/views/orders.py:1347 +#, python-brace-format msgid "A refund of {} has been processed." msgstr "" -#: pretix/control/views/orders.py:1366 +#: pretix/control/views/orders.py:1351 +#, python-brace-format msgid "" "A refund of {} has been saved, but not yet fully executed. You can mark it " "as complete below." msgstr "" -#: pretix/control/views/orders.py:1395 +#: pretix/control/views/orders.py:1380 msgid "" "A new gift card was created. You can now send the user their gift card code." msgstr "" -#: pretix/control/views/orders.py:1403 +#: pretix/control/views/orders.py:1388 msgid "Your gift card code" msgstr "" -#: pretix/control/views/orders.py:1405 +#: pretix/control/views/orders.py:1390 #, python-brace-format msgid "" "Hello,\n" @@ -24089,184 +25022,201 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/control/views/orders.py:1416 +#: pretix/control/views/orders.py:1401 msgid "The refunds you selected do not match the selected total refund amount." msgstr "" -#: pretix/control/views/orders.py:1544 +#: pretix/control/views/orders.py:1531 msgid "" "The order has been marked as paid, but we were unable to send a confirmation " "mail." msgstr "" -#: pretix/control/views/orders.py:1547 +#: pretix/control/views/orders.py:1534 msgid "The payment has been created successfully." msgstr "" -#: pretix/control/views/orders.py:1561 +#: pretix/control/views/orders.py:1548 msgid "" "The order has been canceled. You can now select how you want to transfer the " "money back to the user." msgstr "" -#: pretix/control/views/orders.py:1632 pretix/control/views/orders.py:1636 +#: pretix/control/views/orders.py:1619 pretix/control/views/orders.py:1623 msgid "No VAT ID specified." msgstr "" -#: pretix/control/views/orders.py:1640 +#: pretix/control/views/orders.py:1627 msgid "No country specified." msgstr "" -#: pretix/control/views/orders.py:1644 +#: pretix/control/views/orders.py:1631 msgid "VAT ID could not be checked since this country is not supported." msgstr "" -#: pretix/control/views/orders.py:1655 +#: pretix/control/views/orders.py:1642 msgid "" "The VAT ID could not be checked, as the VAT checking service of the country " "is currently not available." msgstr "" -#: pretix/control/views/orders.py:1658 +#: pretix/control/views/orders.py:1645 msgid "This VAT ID is valid." msgstr "" -#: pretix/control/views/orders.py:1672 pretix/control/views/orders.py:1705 +#: pretix/control/views/orders.py:1659 pretix/control/views/orders.py:1693 +#: pretix/control/views/orders.py:1725 msgid "Unknown invoice." msgstr "" -#: pretix/control/views/orders.py:1675 +#: pretix/control/views/orders.py:1662 msgid "Invoices may not be changed after they are created." msgstr "" -#: pretix/control/views/orders.py:1677 pretix/control/views/orders.py:1708 +#: pretix/control/views/orders.py:1664 +msgid "Invoices may not be changed after they are transmitted." +msgstr "" + +#: pretix/control/views/orders.py:1666 pretix/control/views/orders.py:1728 msgid "The invoice has already been canceled." msgstr "" -#: pretix/control/views/orders.py:1679 +#: pretix/control/views/orders.py:1668 msgid "The invoice file has already been exported." msgstr "" -#: pretix/control/views/orders.py:1681 +#: pretix/control/views/orders.py:1670 msgid "The invoice file is too old to be regenerated." msgstr "" -#: pretix/control/views/orders.py:1683 pretix/control/views/orders.py:1710 +#: pretix/control/views/orders.py:1672 pretix/control/views/orders.py:1730 msgid "The invoice has been cleaned of personal data." msgstr "" -#: pretix/control/views/orders.py:1741 +#: pretix/control/views/orders.py:1697 +msgid "" +"The invoice is currently being transmitted. You can start a new attempt " +"after the current one has been completed." +msgstr "" + +#: pretix/control/views/orders.py:1704 +msgid "The invoice has been scheduled for retransmission." +msgstr "" + +#: pretix/control/views/orders.py:1761 msgid "The email has been queued to be sent." msgstr "" -#: pretix/control/views/orders.py:1765 pretix/presale/views/order.py:1279 +#: pretix/control/views/orders.py:1785 pretix/presale/views/order.py:1279 msgid "This invoice has not been found" msgstr "" -#: pretix/control/views/orders.py:1772 pretix/presale/views/order.py:1286 +#: pretix/control/views/orders.py:1792 pretix/presale/views/order.py:1286 msgid "The invoice file is no longer stored on the server." msgstr "" -#: pretix/control/views/orders.py:1777 pretix/presale/views/order.py:1291 +#: pretix/control/views/orders.py:1797 pretix/presale/views/order.py:1291 msgid "" "The invoice file has not yet been generated, we will generate it for you " "now. Please try again in a few seconds." msgstr "" -#: pretix/control/views/orders.py:1805 +#: pretix/control/views/orders.py:1825 msgid "The payment term has been changed." msgstr "" -#: pretix/control/views/orders.py:1810 pretix/control/views/orders.py:1867 +#: pretix/control/views/orders.py:1830 pretix/control/views/orders.py:1887 msgid "" "We were not able to process the request completely as the server was too " "busy." msgstr "" -#: pretix/control/views/orders.py:1818 +#: pretix/control/views/orders.py:1838 msgid "This action is only allowed for pending orders." msgstr "" -#: pretix/control/views/orders.py:1873 +#: pretix/control/views/orders.py:1893 msgid "This action is only allowed for canceled orders." msgstr "" -#: pretix/control/views/orders.py:2130 pretix/presale/views/order.py:1565 +#: pretix/control/views/orders.py:2150 pretix/presale/views/order.py:1565 msgid "An error occurred. Please see the details below." msgstr "" -#: pretix/control/views/orders.py:2138 +#: pretix/control/views/orders.py:2158 msgid "The order has been changed and the user has been notified." msgstr "" -#: pretix/control/views/orders.py:2140 pretix/control/views/orders.py:2276 -#: pretix/control/views/orders.py:2313 pretix/presale/views/order.py:1600 +#: pretix/control/views/orders.py:2160 pretix/control/views/orders.py:2296 +#: pretix/control/views/orders.py:2333 pretix/presale/views/order.py:1600 msgid "The order has been changed." msgstr "" -#: pretix/control/views/orders.py:2167 pretix/presale/checkoutflow.py:945 +#: pretix/control/views/orders.py:2187 pretix/presale/checkoutflow.py:945 #: pretix/presale/views/order.py:783 pretix/presale/views/order.py:888 msgid "" "We had difficulties processing your input. Please review the errors below." msgstr "" -#: pretix/control/views/orders.py:2278 +#: pretix/control/views/orders.py:2298 msgid "Nothing about the order had to be changed." msgstr "" -#: pretix/control/views/orders.py:2359 pretix/plugins/sendmail/views.py:176 +#: pretix/control/views/orders.py:2379 pretix/plugins/sendmail/views.py:176 msgid "We could not send the email. See below for details." msgstr "" -#: pretix/control/views/orders.py:2375 pretix/control/views/orders.py:2445 +#: pretix/control/views/orders.py:2395 pretix/control/views/orders.py:2465 #: pretix/plugins/sendmail/views.py:204 pretix/plugins/sendmail/views.py:671 #, python-brace-format msgid "Subject: {subject}" msgstr "" -#: pretix/control/views/orders.py:2394 pretix/control/views/orders.py:2465 +#: pretix/control/views/orders.py:2414 pretix/control/views/orders.py:2485 +#, python-brace-format msgid "Your message has been queued and will be sent to {}." msgstr "" -#: pretix/control/views/orders.py:2398 pretix/control/views/orders.py:2468 +#: pretix/control/views/orders.py:2418 pretix/control/views/orders.py:2488 +#, python-brace-format msgid "Failed to send mail to the following user: {}" msgstr "" -#: pretix/control/views/orders.py:2521 pretix/presale/views/order.py:1062 +#: pretix/control/views/orders.py:2541 pretix/presale/views/order.py:1062 msgid "" "This link is no longer valid. Please go back, refresh the page, and try " "again." msgstr "" -#: pretix/control/views/orders.py:2597 +#: pretix/control/views/orders.py:2617 msgid "There is no order with the given order code." msgstr "" -#: pretix/control/views/orders.py:2703 pretix/control/views/organizer.py:1805 +#: pretix/control/views/orders.py:2723 pretix/control/views/organizer.py:2074 msgid "The selected exporter was not found." msgstr "" -#: pretix/control/views/orders.py:2713 pretix/control/views/organizer.py:1815 +#: pretix/control/views/orders.py:2733 pretix/control/views/organizer.py:2084 msgid "There was a problem processing your input. See below for error details." msgstr "" -#: pretix/control/views/orders.py:2748 pretix/control/views/organizer.py:1858 +#: pretix/control/views/orders.py:2768 pretix/control/views/organizer.py:2127 #, python-brace-format msgid "" "Your export schedule has been saved. The next export will start around " "{datetime}." msgstr "" -#: pretix/control/views/orders.py:2753 pretix/control/views/organizer.py:1863 +#: pretix/control/views/orders.py:2773 pretix/control/views/organizer.py:2132 msgid "Your export schedule has been saved, but no next export is planned." msgstr "" -#: pretix/control/views/orders.py:2792 pretix/control/views/organizer.py:1903 +#: pretix/control/views/orders.py:2812 pretix/control/views/organizer.py:2172 #, python-brace-format msgid "Export: {title}" msgstr "" -#: pretix/control/views/orders.py:2793 pretix/control/views/organizer.py:1905 +#: pretix/control/views/orders.py:2813 pretix/control/views/organizer.py:2174 #, python-brace-format msgid "" "Hello,\n" @@ -24274,288 +25224,303 @@ msgid "" "attached to this email, you can find a new scheduled report for {name}." msgstr "" -#: pretix/control/views/orders.py:2861 pretix/control/views/organizer.py:1973 +#: pretix/control/views/orders.py:2881 pretix/control/views/organizer.py:2242 msgid "" "Your export is queued to start soon. The results will be send via email. " "Depending on system load and type and size of export, this may take a few " "minutes." msgstr "" -#: pretix/control/views/orders.py:2940 +#: pretix/control/views/orders.py:2960 msgid "All orders have been canceled." msgstr "" -#: pretix/control/views/orders.py:2942 +#: pretix/control/views/orders.py:2962 #, python-brace-format msgid "" "The orders have been canceled. An error occurred with {count} orders, please " "check all uncanceled orders." msgstr "" -#: pretix/control/views/orders.py:2963 +#: pretix/control/views/orders.py:2983 msgid "Your input was not valid." msgstr "" -#: pretix/control/views/organizer.py:162 +#: pretix/control/views/organizer.py:174 msgid "Token name" msgstr "" -#: pretix/control/views/organizer.py:390 +#: pretix/control/views/organizer.py:402 msgid "This organizer can not be deleted." msgstr "" -#: pretix/control/views/organizer.py:413 +#: pretix/control/views/organizer.py:425 msgid "The organizer has been deleted." msgstr "" -#: pretix/control/views/organizer.py:417 +#: pretix/control/views/organizer.py:429 msgid "" "The organizer could not be deleted as some constraints (e.g. data created by " "plug-ins) do not allow it." msgstr "" -#: pretix/control/views/organizer.py:427 +#: pretix/control/views/organizer.py:439 #, python-brace-format msgid "" "The following database models still contain data that cannot be deleted " "automatically: {affected_models}" msgstr "" -#: pretix/control/views/organizer.py:567 +#: pretix/control/views/organizer.py:579 msgid "The new organizer has been created." msgstr "" -#: pretix/control/views/organizer.py:570 +#: pretix/control/views/organizer.py:582 msgid "Administrators" msgstr "" -#: pretix/control/views/organizer.py:633 +#: pretix/control/views/organizer.py:803 +msgid "Unknown plugin." +msgstr "" + +#: pretix/control/views/organizer.py:809 +msgid "This plugin is currently not active on the organizer account." +msgstr "" + +#: pretix/control/views/organizer.py:813 +msgid "This plugin is currently not allowed for this organizer account." +msgstr "" + +#: pretix/control/views/organizer.py:902 msgid "The team has been created. You can now add members to the team." msgstr "" -#: pretix/control/views/organizer.py:644 pretix/control/views/organizer.py:680 -#: pretix/control/views/organizer.py:916 pretix/control/views/organizer.py:1004 -#: pretix/control/views/organizer.py:1075 -#: pretix/control/views/organizer.py:1294 -#: pretix/control/views/organizer.py:1337 -#: pretix/control/views/organizer.py:2021 -#: pretix/control/views/organizer.py:2056 -#: pretix/control/views/organizer.py:2162 -#: pretix/control/views/organizer.py:2193 -#: pretix/control/views/organizer.py:2355 -#: pretix/control/views/organizer.py:2390 -#: pretix/control/views/organizer.py:2464 -#: pretix/control/views/organizer.py:2506 -#: pretix/control/views/organizer.py:2586 -#: pretix/control/views/organizer.py:2636 -#: pretix/control/views/organizer.py:3195 -#: pretix/control/views/organizer.py:3239 +#: pretix/control/views/organizer.py:913 pretix/control/views/organizer.py:949 +#: pretix/control/views/organizer.py:1185 +#: pretix/control/views/organizer.py:1273 +#: pretix/control/views/organizer.py:1344 +#: pretix/control/views/organizer.py:1563 +#: pretix/control/views/organizer.py:1606 +#: pretix/control/views/organizer.py:2290 +#: pretix/control/views/organizer.py:2325 +#: pretix/control/views/organizer.py:2431 +#: pretix/control/views/organizer.py:2462 +#: pretix/control/views/organizer.py:2624 +#: pretix/control/views/organizer.py:2659 +#: pretix/control/views/organizer.py:2733 +#: pretix/control/views/organizer.py:2775 +#: pretix/control/views/organizer.py:2855 +#: pretix/control/views/organizer.py:2905 +#: pretix/control/views/organizer.py:3464 +#: pretix/control/views/organizer.py:3508 msgid "Your changes could not be saved." msgstr "" -#: pretix/control/views/organizer.py:713 +#: pretix/control/views/organizer.py:982 msgid "The selected team cannot be deleted." msgstr "" -#: pretix/control/views/organizer.py:725 +#: pretix/control/views/organizer.py:994 msgid "" "The team could not be deleted because the team or one of its API tokens is " "part of historical audit logs." msgstr "" -#: pretix/control/views/organizer.py:733 +#: pretix/control/views/organizer.py:1002 msgid "" "The team could not be deleted as some constraints (e.g. data created by plug-" "ins) do not allow it." msgstr "" -#: pretix/control/views/organizer.py:739 +#: pretix/control/views/organizer.py:1008 msgid "The selected team has been deleted." msgstr "" -#: pretix/control/views/organizer.py:803 +#: pretix/control/views/organizer.py:1072 msgid "" "You cannot remove the last member from this team as no one would be left " "with the permission to change teams." msgstr "" -#: pretix/control/views/organizer.py:814 +#: pretix/control/views/organizer.py:1083 msgid "The member has been removed from the team." msgstr "" -#: pretix/control/views/organizer.py:821 pretix/control/views/organizer.py:837 +#: pretix/control/views/organizer.py:1090 +#: pretix/control/views/organizer.py:1106 msgid "Invalid invite selected." msgstr "" -#: pretix/control/views/organizer.py:830 +#: pretix/control/views/organizer.py:1099 msgid "The invite has been revoked." msgstr "" -#: pretix/control/views/organizer.py:846 +#: pretix/control/views/organizer.py:1115 msgid "The invite has been resent." msgstr "" -#: pretix/control/views/organizer.py:853 +#: pretix/control/views/organizer.py:1122 msgid "Invalid token selected." msgstr "" -#: pretix/control/views/organizer.py:863 +#: pretix/control/views/organizer.py:1132 msgid "The token has been revoked." msgstr "" -#: pretix/control/views/organizer.py:875 +#: pretix/control/views/organizer.py:1144 msgid "Users need to have a pretix account before they can be invited." msgstr "" -#: pretix/control/views/organizer.py:885 +#: pretix/control/views/organizer.py:1154 msgid "The new member has been invited to the team." msgstr "" -#: pretix/control/views/organizer.py:900 +#: pretix/control/views/organizer.py:1169 msgid "The new member has been added to the team." msgstr "" -#: pretix/control/views/organizer.py:911 +#: pretix/control/views/organizer.py:1180 +#, python-brace-format msgid "" "A new API token has been created with the following secret: {}\n" "Please copy this secret to a safe place. You will not be able to view it " "again here." msgstr "" -#: pretix/control/views/organizer.py:1208 +#: pretix/control/views/organizer.py:1477 msgid "This device has been set up successfully." msgstr "" -#: pretix/control/views/organizer.py:1236 +#: pretix/control/views/organizer.py:1505 msgid "This device currently does not have access." msgstr "" -#: pretix/control/views/organizer.py:1248 +#: pretix/control/views/organizer.py:1517 msgid "Access for this device has been revoked." msgstr "" -#: pretix/control/views/organizer.py:1369 +#: pretix/control/views/organizer.py:1638 msgid "" "All requests will now be scheduled for an immediate attempt. Please allow " "for a few minutes before they are processed." msgstr "" -#: pretix/control/views/organizer.py:1376 +#: pretix/control/views/organizer.py:1645 msgid "All unprocessed webhooks have been stopped from retrying." msgstr "" -#: pretix/control/views/organizer.py:1408 +#: pretix/control/views/organizer.py:1677 msgid "The selected organizer has been invited." msgstr "" -#: pretix/control/views/organizer.py:1445 -#: pretix/control/views/organizer.py:1456 +#: pretix/control/views/organizer.py:1714 +#: pretix/control/views/organizer.py:1725 msgid "The selected connection has been removed." msgstr "" -#: pretix/control/views/organizer.py:1467 +#: pretix/control/views/organizer.py:1736 msgid "The selected connection has been accepted." msgstr "" -#: pretix/control/views/organizer.py:1525 -#: pretix/control/views/organizer.py:1562 +#: pretix/control/views/organizer.py:1794 +#: pretix/control/views/organizer.py:1831 msgid "Gift cards are not allowed to have negative values." msgstr "" -#: pretix/control/views/organizer.py:1552 +#: pretix/control/views/organizer.py:1821 msgid "The transaction could not be reversed." msgstr "" -#: pretix/control/views/organizer.py:1554 +#: pretix/control/views/organizer.py:1823 msgid "The transaction has been reversed." msgstr "" -#: pretix/control/views/organizer.py:1559 +#: pretix/control/views/organizer.py:1828 msgid "Your input was invalid, please try again." msgstr "" -#: pretix/control/views/organizer.py:1577 +#: pretix/control/views/organizer.py:1846 msgid "The manual transaction has been saved." msgstr "" -#: pretix/control/views/organizer.py:1619 +#: pretix/control/views/organizer.py:1888 msgid "The gift card has been created and can now be used." msgstr "" -#: pretix/control/views/organizer.py:1713 +#: pretix/control/views/organizer.py:1982 msgid "All events (that I have access to)" msgstr "" -#: pretix/control/views/organizer.py:2080 +#: pretix/control/views/organizer.py:2349 msgid "The selected gate has been deleted." msgstr "" -#: pretix/control/views/organizer.py:2123 +#: pretix/control/views/organizer.py:2392 msgid "You cannot set a default value that is not a valid value." msgstr "" -#: pretix/control/views/organizer.py:2150 +#: pretix/control/views/organizer.py:2419 msgid "The property has been created." msgstr "" -#: pretix/control/views/organizer.py:2217 +#: pretix/control/views/organizer.py:2486 msgid "The selected property has been deleted." msgstr "" -#: pretix/control/views/organizer.py:2241 +#: pretix/control/views/organizer.py:2510 msgid "The order of properties has been updated." msgstr "" -#: pretix/control/views/organizer.py:2420 -#: pretix/control/views/organizer.py:2536 -#: pretix/control/views/organizer.py:2666 -#: pretix/control/views/organizer.py:2932 +#: pretix/control/views/organizer.py:2689 +#: pretix/control/views/organizer.py:2805 +#: pretix/control/views/organizer.py:2935 +#: pretix/control/views/organizer.py:3201 msgid "The selected object has been deleted." msgstr "" -#: pretix/control/views/organizer.py:2455 +#: pretix/control/views/organizer.py:2724 msgid "The provider has been created." msgstr "" -#: pretix/control/views/organizer.py:2575 +#: pretix/control/views/organizer.py:2844 #, python-brace-format msgid "" "The SSO client has been created. Please note down the following client " "secret, it will never be shown again: {secret}" msgstr "" -#: pretix/control/views/organizer.py:2625 +#: pretix/control/views/organizer.py:2894 #, python-brace-format msgid "" "Your changes have been saved. Please note down the following client secret, " "it will never be shown again: {secret}" msgstr "" -#: pretix/control/views/organizer.py:2734 +#: pretix/control/views/organizer.py:3003 msgid "" "We've sent the customer an email with further instructions on resetting your " "password." msgstr "" -#: pretix/control/views/organizer.py:2997 +#: pretix/control/views/organizer.py:3266 msgid "The customer account has been anonymized." msgstr "" -#: pretix/control/views/organizer.py:3267 +#: pretix/control/views/organizer.py:3536 msgid "This channel can not be deleted." msgstr "" -#: pretix/control/views/organizer.py:3272 +#: pretix/control/views/organizer.py:3541 msgid "The selected sales channel has been deleted." msgstr "" -#: pretix/control/views/organizer.py:3274 +#: pretix/control/views/organizer.py:3543 msgid "" "The channel could not be deleted as some constraints (e.g. data created by " "plug-ins) did not allow it." msgstr "" -#: pretix/control/views/organizer.py:3299 +#: pretix/control/views/organizer.py:3568 msgid "The order of sales channels has been updated." msgstr "" @@ -24615,11 +25580,12 @@ msgctxt "subevent" msgid "The selected dates have been deleted or disabled." msgstr "" -#: pretix/control/views/subevents.py:894 +#: pretix/control/views/subevents.py:901 msgid "Please do not create more than 100.000 dates at once." msgstr "" -#: pretix/control/views/subevents.py:1030 +#: pretix/control/views/subevents.py:1037 +#, python-brace-format msgctxt "subevent" msgid "{} new dates have been created." msgstr "" @@ -24629,10 +25595,12 @@ msgid "Series:" msgstr "" #: pretix/control/views/typeahead.py:115 +#, python-brace-format msgid "Order {}" msgstr "" #: pretix/control/views/typeahead.py:128 +#, python-brace-format msgid "Voucher {}" msgstr "" @@ -24832,6 +25800,22 @@ msgstr "" msgid "The waitinglist entry has been transferred." msgstr "" +#: pretix/helpers/countries.py:128 +msgid "Belarus" +msgstr "" + +#: pretix/helpers/countries.py:129 +msgid "French Guiana" +msgstr "" + +#: pretix/helpers/countries.py:130 +msgid "North Macedonia" +msgstr "" + +#: pretix/helpers/countries.py:131 +msgid "Macao" +msgstr "" + #: pretix/helpers/daterange.py:56 pretix/helpers/daterange.py:118 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:77 #: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:46 @@ -24929,7 +25913,7 @@ msgstr "" msgid "All variations" msgstr "" -#: pretix/plugins/autocheckin/forms.py:248 +#: pretix/plugins/autocheckin/forms.py:247 msgid "" "When restricting by payment method, the rule should run after the payment " "was received." @@ -25133,9 +26117,9 @@ msgid "Only include tickets for dates on or before this date." msgstr "" #: pretix/plugins/badges/exporters.py:493 -#: pretix/plugins/checkinlists/exporters.py:117 -#: pretix/plugins/reports/exporters.py:495 -#: pretix/plugins/reports/exporters.py:677 +#: pretix/plugins/checkinlists/exporters.py:118 +#: pretix/plugins/reports/exporters.py:506 +#: pretix/plugins/reports/exporters.py:688 #: pretix/plugins/ticketoutputpdf/exporters.py:92 msgid "Sort by" msgstr "" @@ -25252,11 +26236,6 @@ msgstr "" msgid "Create a new badge layout" msgstr "" -#: pretix/plugins/badges/templates/pretixplugins/badges/index.html:63 -#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:60 -msgid "Make default" -msgstr "" - #: pretix/plugins/badges/views.py:89 msgid "The new badge layout has been created." msgstr "" @@ -25271,6 +26250,7 @@ msgid "The selected badge layout been deleted." msgstr "" #: pretix/plugins/badges/views.py:217 +#, python-brace-format msgid "Badge layout: {}" msgstr "" @@ -25279,9 +26259,9 @@ msgstr "" #: pretix/plugins/banktransfer/apps.py:42 #: pretix/plugins/banktransfer/apps.py:45 #: pretix/plugins/banktransfer/apps.py:46 -#: pretix/plugins/banktransfer/payment.py:67 -#: pretix/plugins/banktransfer/signals.py:50 -#: pretix/plugins/banktransfer/signals.py:87 +#: pretix/plugins/banktransfer/payment.py:60 +#: pretix/plugins/banktransfer/signals.py:48 +#: pretix/plugins/banktransfer/signals.py:85 msgid "Bank transfer" msgstr "" @@ -25292,8 +26272,8 @@ msgid "" msgstr "" #: pretix/plugins/banktransfer/apps.py:45 -#: pretix/plugins/banktransfer/signals.py:58 -#: pretix/plugins/banktransfer/signals.py:94 +#: pretix/plugins/banktransfer/signals.py:56 +#: pretix/plugins/banktransfer/signals.py:92 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_base.html:4 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_base.html:7 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_base_organizer.html:4 @@ -25302,8 +26282,8 @@ msgid "Import bank data" msgstr "" #: pretix/plugins/banktransfer/apps.py:46 -#: pretix/plugins/banktransfer/signals.py:66 -#: pretix/plugins/banktransfer/signals.py:102 +#: pretix/plugins/banktransfer/signals.py:64 +#: pretix/plugins/banktransfer/signals.py:100 msgid "Export refunds" msgstr "" @@ -25312,7 +26292,7 @@ msgid "" "Install the python package 'chardet' for better CSV import capabilities." msgstr "" -#: pretix/plugins/banktransfer/payment.py:75 +#: pretix/plugins/banktransfer/payment.py:68 msgid "" "I have understood that people will pay the ticket price directly to my bank " "account and pretix cannot automatically know what payments arrived. " @@ -25321,100 +26301,101 @@ msgid "" "information." msgstr "" -#: pretix/plugins/banktransfer/payment.py:82 +#: pretix/plugins/banktransfer/payment.py:75 msgid "Bank account type" msgstr "" -#: pretix/plugins/banktransfer/payment.py:85 +#: pretix/plugins/banktransfer/payment.py:78 msgid "SEPA bank account" msgstr "" -#: pretix/plugins/banktransfer/payment.py:86 +#: pretix/plugins/banktransfer/payment.py:79 msgid "Other bank account" msgstr "" -#: pretix/plugins/banktransfer/payment.py:91 +#: pretix/plugins/banktransfer/payment.py:84 msgid "Name of account holder" msgstr "" -#: pretix/plugins/banktransfer/payment.py:93 +#: pretix/plugins/banktransfer/payment.py:86 msgid "" "Please note: special characters other than letters, numbers, and some " "punctuation can cause problems with some banks." msgstr "" -#: pretix/plugins/banktransfer/payment.py:103 -#: pretix/plugins/banktransfer/payment.py:466 -#: pretix/plugins/banktransfer/payment.py:657 +#: pretix/plugins/banktransfer/payment.py:96 +#: pretix/plugins/banktransfer/payment.py:300 +#: pretix/plugins/banktransfer/payment.py:490 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:15 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:15 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:14 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:50 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html:6 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:24 msgid "IBAN" msgstr "" -#: pretix/plugins/banktransfer/payment.py:113 -#: pretix/plugins/banktransfer/payment.py:467 +#: pretix/plugins/banktransfer/payment.py:106 +#: pretix/plugins/banktransfer/payment.py:301 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:16 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:16 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:15 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:66 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:25 msgid "BIC" msgstr "" -#: pretix/plugins/banktransfer/payment.py:123 +#: pretix/plugins/banktransfer/payment.py:116 msgid "Name of bank" msgstr "" -#: pretix/plugins/banktransfer/payment.py:133 +#: pretix/plugins/banktransfer/payment.py:126 msgid "Bank account details" msgstr "" -#: pretix/plugins/banktransfer/payment.py:136 +#: pretix/plugins/banktransfer/payment.py:129 msgid "" "Include everything else that your customers might need to send you a bank " "transfer payment. If you have lots of international customers, they might " "need your full address and your bank's full address." msgstr "" -#: pretix/plugins/banktransfer/payment.py:142 +#: pretix/plugins/banktransfer/payment.py:135 msgid "" "For SEPA accounts, you can leave this empty. Otherwise, please add " "everything that your customers need to transfer the money, e.g. account " "numbers, routing numbers, addresses, etc." msgstr "" -#: pretix/plugins/banktransfer/payment.py:161 +#: pretix/plugins/banktransfer/payment.py:154 msgid "Do not include hyphens in the payment reference." msgstr "" -#: pretix/plugins/banktransfer/payment.py:162 +#: pretix/plugins/banktransfer/payment.py:155 msgid "This is required in some countries." msgstr "" -#: pretix/plugins/banktransfer/payment.py:166 +#: pretix/plugins/banktransfer/payment.py:159 msgid "Include invoice number in the payment reference." msgstr "" -#: pretix/plugins/banktransfer/payment.py:170 +#: pretix/plugins/banktransfer/payment.py:163 msgid "Prefix for the payment reference" msgstr "" -#: pretix/plugins/banktransfer/payment.py:174 +#: pretix/plugins/banktransfer/payment.py:167 msgid "Additional text to show on pending orders" msgstr "" -#: pretix/plugins/banktransfer/payment.py:175 +#: pretix/plugins/banktransfer/payment.py:168 msgid "" "This text will be shown on the order confirmation page for pending orders in " "addition to the standard text." msgstr "" -#: pretix/plugins/banktransfer/payment.py:184 +#: pretix/plugins/banktransfer/payment.py:177 msgid "IBAN blocklist for refunds" msgstr "" -#: pretix/plugins/banktransfer/payment.py:187 +#: pretix/plugins/banktransfer/payment.py:180 msgid "" "Put one IBAN or IBAN prefix per line. The system will not attempt to send " "refunds to any of these IBANs. Useful e.g. if you receive a lot of " @@ -25425,82 +26406,45 @@ msgid "" "starting with 12345." msgstr "" -#: pretix/plugins/banktransfer/payment.py:218 -msgid "" -"Allow users to enter an additional email address that the invoice will be " -"sent to." -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:220 -msgid "" -"This requires that the invoice creation settings allow the invoice to be " -"created right after the payment method was chosen. Only the invoice will be " -"sent to this email address, subsequent invoice corrections will not be sent " -"automatically. Only the invoice will be sent, no additional information." -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:229 -msgid "Invoice email subject" -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:241 -msgid "Invoice email text" -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:256 +#: pretix/plugins/banktransfer/payment.py:207 msgid "Restrict to business customers" msgstr "" -#: pretix/plugins/banktransfer/payment.py:257 +#: pretix/plugins/banktransfer/payment.py:208 msgid "" "Only allow choosing this payment provider for customers who enter an invoice " "address and select \"Business or institutional customer\"." msgstr "" -#: pretix/plugins/banktransfer/payment.py:288 +#: pretix/plugins/banktransfer/payment.py:238 msgid "Please fill out your bank account details." msgstr "" -#: pretix/plugins/banktransfer/payment.py:292 +#: pretix/plugins/banktransfer/payment.py:242 msgid "Please enter your bank account details." msgstr "" -#: pretix/plugins/banktransfer/payment.py:332 -msgid "" -"Please additionally send my invoice directly to our accounting department" -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:336 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:161 -msgid "Invoice recipient email" -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:338 -msgid "" -"The invoice recipient will receive an email which includes the invoice and " -"your email address so they know who placed this order." -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:457 +#: pretix/plugins/banktransfer/payment.py:291 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:15 msgid "Please transfer the full amount to the following bank account:" msgstr "" -#: pretix/plugins/banktransfer/payment.py:465 -#: pretix/plugins/banktransfer/payment.py:654 +#: pretix/plugins/banktransfer/payment.py:299 +#: pretix/plugins/banktransfer/payment.py:487 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:14 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:14 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:13 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html:5 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:23 -#: pretix/plugins/banktransfer/views.py:835 +#: pretix/plugins/banktransfer/views.py:829 #: pretix/plugins/stripe/payment.py:1458 #: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_confirm.html:32 #: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_confirm.html:35 msgid "Account holder" msgstr "" -#: pretix/plugins/banktransfer/payment.py:468 +#: pretix/plugins/banktransfer/payment.py:302 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:17 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:17 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:16 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:26 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:23 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:31 @@ -25510,24 +26454,25 @@ msgstr "" msgid "Bank" msgstr "" -#: pretix/plugins/banktransfer/payment.py:548 +#: pretix/plugins/banktransfer/payment.py:381 msgid "Invalid IBAN/BIC" msgstr "" -#: pretix/plugins/banktransfer/payment.py:624 +#: pretix/plugins/banktransfer/payment.py:457 #, python-brace-format msgid "Bank account {iban}" msgstr "" -#: pretix/plugins/banktransfer/payment.py:640 +#: pretix/plugins/banktransfer/payment.py:473 msgid "Can only create a bank transfer refund from an existing payment." msgstr "" -#: pretix/plugins/banktransfer/payment.py:660 +#: pretix/plugins/banktransfer/payment.py:493 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html:7 msgid "BIC (optional)" msgstr "" -#: pretix/plugins/banktransfer/payment.py:699 +#: pretix/plugins/banktransfer/payment.py:532 msgid "Your input was invalid, please see below for details." msgstr "" @@ -25544,28 +26489,10 @@ msgstr "" msgid "Refund" msgstr "" -#: pretix/plugins/banktransfer/signals.py:126 +#: pretix/plugins/banktransfer/signals.py:125 msgid "The invoice was sent to the designated email address." msgstr "" -#: pretix/plugins/banktransfer/signals.py:132 -#, python-brace-format -msgid "Invoice {invoice_number}" -msgstr "" - -#: pretix/plugins/banktransfer/signals.py:137 -#, python-brace-format -msgid "" -"Hello,\n" -"\n" -"you receive this message because an order for {event} was placed by " -"{order_email} and we have been asked to forward the invoice to you.\n" -"\n" -"Best regards, \n" -"\n" -"Your {event} team" -msgstr "" - #: pretix/plugins/banktransfer/tasks.py:171 msgid "Automatic split to multiple orders not possible." msgstr "" @@ -25575,50 +26502,45 @@ msgid "The order has already been canceled." msgstr "" #: pretix/plugins/banktransfer/tasks.py:193 -#: pretix/plugins/banktransfer/views.py:106 -#: pretix/plugins/banktransfer/views.py:193 +#: pretix/plugins/banktransfer/views.py:100 +#: pretix/plugins/banktransfer/views.py:187 msgid "Currencies do not match." msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:6 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:6 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:5 msgid "" "After completing your purchase, we will ask you to transfer the money to the " "following bank account, using a personal reference code:" msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:11 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:11 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:10 msgid "" "Please do not yet start a payment. We'll assign you a personal reference " "code after you completed the order." msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:26 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:26 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:25 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:39 msgid "Reference code (important):" msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:31 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:31 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:30 msgid "" "We will assign you a personal reference code to use after you completed the " "order." msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:36 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:36 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:35 msgid "" "After completing your purchase, we will ask you to transfer the money to our " "bank account, using a personal reference code." msgstr "" -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:43 -#, python-format -msgid "We will send a copy of your invoice directly to %(recipient)s." -msgstr "" - #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:6 msgid "Send invoice to" msgstr "" @@ -25678,7 +26600,7 @@ msgid "" msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html:29 -#: pretix/plugins/banktransfer/views.py:561 +#: pretix/plugins/banktransfer/views.py:555 msgid "" "An import is currently being processed, please try again in a few minutes." msgstr "" @@ -25792,25 +26714,6 @@ msgstr "" msgid "Scan the QR code with your banking app" msgstr "" -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:141 -#, python-format -msgid "At your request, we sent the invoice directly to %(recipient)s." -msgstr "" - -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:146 -msgid "Send again or somewhere else" -msgstr "" - -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:155 -msgid "" -"To send the invoice directly to your accounting department, please enter " -"their email address:" -msgstr "" - -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:168 -msgid "Send invoice via email" -msgstr "" - #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:5 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:7 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/sepa_export.html:7 @@ -25956,114 +26859,90 @@ msgstr "" msgid "Discard" msgstr "" -#: pretix/plugins/banktransfer/views.py:146 +#: pretix/plugins/banktransfer/views.py:140 msgid "" "Negative amount but refund can't be logged, please create manual refund " "first." msgstr "" -#: pretix/plugins/banktransfer/views.py:172 +#: pretix/plugins/banktransfer/views.py:166 msgid "Problem sending email." msgstr "" -#: pretix/plugins/banktransfer/views.py:198 +#: pretix/plugins/banktransfer/views.py:192 msgid "Unknown order code" msgstr "" -#: pretix/plugins/banktransfer/views.py:355 +#: pretix/plugins/banktransfer/views.py:349 msgid "Search text" msgstr "" -#: pretix/plugins/banktransfer/views.py:356 +#: pretix/plugins/banktransfer/views.py:350 msgid "min" msgstr "" -#: pretix/plugins/banktransfer/views.py:357 +#: pretix/plugins/banktransfer/views.py:351 msgid "max" msgstr "" -#: pretix/plugins/banktransfer/views.py:366 +#: pretix/plugins/banktransfer/views.py:360 msgid "Filter form is not valid." msgstr "" -#: pretix/plugins/banktransfer/views.py:409 +#: pretix/plugins/banktransfer/views.py:403 msgid "All unresolved transactions have been discarded." msgstr "" -#: pretix/plugins/banktransfer/views.py:429 +#: pretix/plugins/banktransfer/views.py:423 msgid "You must choose a file to import." msgstr "" -#: pretix/plugins/banktransfer/views.py:433 +#: pretix/plugins/banktransfer/views.py:427 msgid "" "We were unable to detect the file type of this import. Please contact " "support for help." msgstr "" -#: pretix/plugins/banktransfer/views.py:446 -#: pretix/plugins/banktransfer/views.py:495 +#: pretix/plugins/banktransfer/views.py:440 +#: pretix/plugins/banktransfer/views.py:489 msgid "We were unable to process your input." msgstr "" -#: pretix/plugins/banktransfer/views.py:460 +#: pretix/plugins/banktransfer/views.py:454 msgid "" "I'm sorry, but we were unable to import this CSV file. Please contact " "support for help." msgstr "" -#: pretix/plugins/banktransfer/views.py:465 +#: pretix/plugins/banktransfer/views.py:459 msgid "" "I'm sorry, but we detected this file as empty. Please contact support for " "help." msgstr "" -#: pretix/plugins/banktransfer/views.py:485 +#: pretix/plugins/banktransfer/views.py:479 msgid "Invalid input data." msgstr "" -#: pretix/plugins/banktransfer/views.py:489 +#: pretix/plugins/banktransfer/views.py:483 msgid "You need to select the column containing the payment reference." msgstr "" -#: pretix/plugins/banktransfer/views.py:570 +#: pretix/plugins/banktransfer/views.py:564 msgid "No currency has been selected." msgstr "" -#: pretix/plugins/banktransfer/views.py:718 +#: pretix/plugins/banktransfer/views.py:712 #, python-brace-format msgid "" "We could not find bank account information for the refund {refund_id}. It " "was marked as failed." msgstr "" -#: pretix/plugins/banktransfer/views.py:751 +#: pretix/plugins/banktransfer/views.py:745 msgid "No valid orders have been found." msgstr "" -#: pretix/plugins/banktransfer/views.py:905 pretix/presale/checkoutflow.py:1016 -#: pretix/presale/checkoutflow.py:1022 -msgid "Please enter a valid email address." -msgstr "" - -#: pretix/plugins/banktransfer/views.py:912 -msgid "" -"No pending bank transfer payment found. Maybe the order has been paid " -"already?" -msgstr "" - -#: pretix/plugins/banktransfer/views.py:915 -msgid "Sending invoices via email is disabled by the event organizer." -msgstr "" - -#: pretix/plugins/banktransfer/views.py:920 -msgid "No invoice found, please request an invoice first." -msgstr "" - -#: pretix/plugins/banktransfer/views.py:932 -#, python-brace-format -msgid "Sending the latest invoice via email to {email}." -msgstr "" - #: pretix/plugins/checkinlists/apps.py:47 msgid "Check-in list exporter" msgstr "" @@ -26072,134 +26951,130 @@ msgstr "" msgid "This plugin allows you to generate check-in lists for your conference." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:91 +#: pretix/plugins/checkinlists/exporters.py:92 #: pretix/plugins/ticketoutputpdf/exporters.py:88 msgid "Only include tickets for dates within this range." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:95 +#: pretix/plugins/checkinlists/exporters.py:96 msgid "Include QR-code secret" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:100 +#: pretix/plugins/checkinlists/exporters.py:101 msgid "Only tickets requiring special attention" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:133 +#: pretix/plugins/checkinlists/exporters.py:134 msgid "Include questions" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:303 +#: pretix/plugins/checkinlists/exporters.py:304 msgid "Check-in list (PDF)" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:304 -#: pretix/plugins/checkinlists/exporters.py:475 -#: pretix/plugins/checkinlists/exporters.py:672 -#: pretix/plugins/checkinlists/exporters.py:742 +#: pretix/plugins/checkinlists/exporters.py:305 +#: pretix/plugins/checkinlists/exporters.py:476 +#: pretix/plugins/checkinlists/exporters.py:673 +#: pretix/plugins/checkinlists/exporters.py:743 msgctxt "export_category" msgid "Check-in" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:305 +#: pretix/plugins/checkinlists/exporters.py:306 msgid "" "Download a PDF version of a check-in list that can be used to check people " "in at the event without digital methods." msgstr "" #. Translators: maximum 5 characters -#: pretix/plugins/checkinlists/exporters.py:373 +#: pretix/plugins/checkinlists/exporters.py:374 msgctxt "tablehead" msgid "paid" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:476 +#: pretix/plugins/checkinlists/exporters.py:477 msgid "" "Download a spreadsheet with all attendees that are included in a check-in " "list." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:499 +#: pretix/plugins/checkinlists/exporters.py:500 msgid "Checked out" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:499 -#: pretix/plugins/checkinlists/exporters.py:764 +#: pretix/plugins/checkinlists/exporters.py:500 +#: pretix/plugins/checkinlists/exporters.py:765 msgid "Automatically checked in" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:505 -#: pretix/plugins/checkinlists/exporters.py:693 -#: pretix/plugins/checkinlists/exporters.py:758 -#: pretix/plugins/paypal/payment.py:123 pretix/plugins/paypal2/payment.py:120 +#: pretix/plugins/checkinlists/exporters.py:506 +#: pretix/plugins/checkinlists/exporters.py:694 +#: pretix/plugins/checkinlists/exporters.py:759 +#: pretix/plugins/paypal/payment.py:124 pretix/plugins/paypal2/payment.py:121 msgid "Secret" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:671 +#: pretix/plugins/checkinlists/exporters.py:672 msgid "Valid check-in codes" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:673 +#: pretix/plugins/checkinlists/exporters.py:674 msgid "" "Download a spreadsheet with all valid check-in barcodes e.g. for import into " "a different system. Does not included blocked codes or personal data." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:741 +#: pretix/plugins/checkinlists/exporters.py:742 msgid "Check-in log (all scans)" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:743 +#: pretix/plugins/checkinlists/exporters.py:744 msgid "" "Download a spreadsheet with one line for every scan that happened at your " "check-in stations." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:762 +#: pretix/plugins/checkinlists/exporters.py:763 msgid "Offline" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:763 +#: pretix/plugins/checkinlists/exporters.py:764 msgid "Offline override" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:767 +#: pretix/plugins/checkinlists/exporters.py:768 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:83 msgid "Error message" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:768 +#: pretix/plugins/checkinlists/exporters.py:769 msgid "Upload date" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:769 +#: pretix/plugins/checkinlists/exporters.py:770 msgid "Upload time" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:826 +#: pretix/plugins/checkinlists/exporters.py:827 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:519 #: pretix/presale/templates/pretixpresale/fragment_modals.html:52 #: pretix/presale/templates/pretixpresale/fragment_modals.html:148 msgid "OK" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:858 +#: pretix/plugins/checkinlists/exporters.py:859 msgid "Successful scans only" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:879 -msgid "All check-in lists" -msgstr "" - #: pretix/plugins/manualpayment/apps.py:37 msgid "A fully customizable payment method for manual processing." msgstr "" #: pretix/plugins/paypal/apps.py:44 pretix/plugins/paypal/apps.py:47 -#: pretix/plugins/paypal/payment.py:75 pretix/plugins/paypal2/apps.py:45 -#: pretix/plugins/paypal2/payment.py:82 pretix/plugins/paypal2/payment.py:138 -#: pretix/plugins/paypal2/payment.py:1096 -#: pretix/plugins/paypal2/payment.py:1097 pretix/plugins/stripe/payment.py:1816 +#: pretix/plugins/paypal/payment.py:76 pretix/plugins/paypal2/apps.py:45 +#: pretix/plugins/paypal2/payment.py:83 pretix/plugins/paypal2/payment.py:139 +#: pretix/plugins/paypal2/payment.py:1097 +#: pretix/plugins/paypal2/payment.py:1098 pretix/plugins/stripe/payment.py:1816 msgid "PayPal" msgstr "" @@ -26209,106 +27084,107 @@ msgid "" "payment methods world-wide." msgstr "" -#: pretix/plugins/paypal/payment.py:91 pretix/plugins/paypal2/payment.py:376 +#: pretix/plugins/paypal/payment.py:92 pretix/plugins/paypal2/payment.py:377 msgid "" "The PayPal sandbox is being used, you can test without actually sending " "money but you will need a PayPal sandbox user to log in." msgstr "" -#: pretix/plugins/paypal/payment.py:103 +#: pretix/plugins/paypal/payment.py:104 msgid "PayPal account" msgstr "" -#: pretix/plugins/paypal/payment.py:116 pretix/plugins/paypal2/payment.py:113 +#: pretix/plugins/paypal/payment.py:117 pretix/plugins/paypal2/payment.py:114 #, python-brace-format msgid "{text}" msgstr "" -#: pretix/plugins/paypal/payment.py:117 pretix/plugins/paypal2/payment.py:114 +#: pretix/plugins/paypal/payment.py:118 pretix/plugins/paypal2/payment.py:115 msgid "Click here for a tutorial on how to obtain the required keys" msgstr "" -#: pretix/plugins/paypal/payment.py:129 pretix/plugins/paypal2/payment.py:126 +#: pretix/plugins/paypal/payment.py:130 pretix/plugins/paypal2/payment.py:127 #: pretix/plugins/stripe/payment.py:258 msgid "Endpoint" msgstr "" -#: pretix/plugins/paypal/payment.py:141 pretix/plugins/paypal2/payment.py:200 +#: pretix/plugins/paypal/payment.py:142 pretix/plugins/paypal2/payment.py:201 msgid "Reference prefix" msgstr "" -#: pretix/plugins/paypal/payment.py:142 pretix/plugins/paypal2/payment.py:201 +#: pretix/plugins/paypal/payment.py:143 pretix/plugins/paypal2/payment.py:202 msgid "" "Any value entered here will be added in front of the regular booking " "reference containing the order number." msgstr "" -#: pretix/plugins/paypal/payment.py:148 pretix/plugins/paypal2/payment.py:207 +#: pretix/plugins/paypal/payment.py:149 pretix/plugins/paypal2/payment.py:208 msgid "Reference postfix" msgstr "" -#: pretix/plugins/paypal/payment.py:149 pretix/plugins/paypal2/payment.py:208 +#: pretix/plugins/paypal/payment.py:150 pretix/plugins/paypal2/payment.py:209 msgid "" "Any value entered here will be added behind the regular booking reference " "containing the order number." msgstr "" -#: pretix/plugins/paypal/payment.py:187 pretix/plugins/paypal2/payment.py:261 +#: pretix/plugins/paypal/payment.py:188 pretix/plugins/paypal2/payment.py:262 msgid "Disconnect from PayPal" msgstr "" -#: pretix/plugins/paypal/payment.py:241 pretix/plugins/paypal/payment.py:307 -#: pretix/plugins/paypal/payment.py:345 pretix/plugins/paypal/payment.py:360 -#: pretix/plugins/paypal/payment.py:428 pretix/plugins/paypal/payment.py:431 -#: pretix/plugins/paypal/payment.py:589 pretix/plugins/paypal/payment.py:666 -#: pretix/plugins/paypal2/payment.py:470 pretix/plugins/paypal2/payment.py:480 -#: pretix/plugins/paypal2/payment.py:602 pretix/plugins/paypal2/payment.py:606 -#: pretix/plugins/paypal2/payment.py:675 pretix/plugins/paypal2/payment.py:739 -#: pretix/plugins/paypal2/payment.py:1020 -#: pretix/plugins/paypal2/payment.py:1030 -#: pretix/plugins/paypal2/payment.py:1126 +#: pretix/plugins/paypal/payment.py:242 pretix/plugins/paypal/payment.py:308 +#: pretix/plugins/paypal/payment.py:346 pretix/plugins/paypal/payment.py:361 +#: pretix/plugins/paypal/payment.py:429 pretix/plugins/paypal/payment.py:432 +#: pretix/plugins/paypal/payment.py:590 pretix/plugins/paypal/payment.py:667 +#: pretix/plugins/paypal2/payment.py:471 pretix/plugins/paypal2/payment.py:481 +#: pretix/plugins/paypal2/payment.py:603 pretix/plugins/paypal2/payment.py:607 +#: pretix/plugins/paypal2/payment.py:676 pretix/plugins/paypal2/payment.py:740 +#: pretix/plugins/paypal2/payment.py:1021 +#: pretix/plugins/paypal2/payment.py:1031 +#: pretix/plugins/paypal2/payment.py:1127 msgid "We had trouble communicating with PayPal" msgstr "" -#: pretix/plugins/paypal/payment.py:374 pretix/plugins/paypal/payment.py:383 -#: pretix/plugins/paypal/payment.py:457 pretix/plugins/paypal2/payment.py:651 -#: pretix/plugins/paypal2/payment.py:692 pretix/plugins/paypal2/payment.py:754 -#: pretix/plugins/paypal2/payment.py:785 pretix/plugins/paypal2/payment.py:810 +#: pretix/plugins/paypal/payment.py:375 pretix/plugins/paypal/payment.py:384 +#: pretix/plugins/paypal/payment.py:458 pretix/plugins/paypal2/payment.py:652 +#: pretix/plugins/paypal2/payment.py:693 pretix/plugins/paypal2/payment.py:755 +#: pretix/plugins/paypal2/payment.py:786 pretix/plugins/paypal2/payment.py:811 msgid "" "We were unable to process your payment. See below for details on how to " "proceed." msgstr "" -#: pretix/plugins/paypal/payment.py:438 pretix/plugins/paypal/payment.py:447 -#: pretix/plugins/paypal2/payment.py:797 +#: pretix/plugins/paypal/payment.py:439 pretix/plugins/paypal/payment.py:448 +#: pretix/plugins/paypal2/payment.py:798 msgid "" "PayPal has not yet approved the payment. We will inform you as soon as the " "payment completed." msgstr "" -#: pretix/plugins/paypal/payment.py:472 pretix/plugins/paypal2/payment.py:825 +#: pretix/plugins/paypal/payment.py:473 pretix/plugins/paypal2/payment.py:826 #: pretix/plugins/stripe/payment.py:985 msgid "There was an error sending the confirmation mail." msgstr "" -#: pretix/plugins/paypal/payment.py:565 pretix/plugins/paypal/payment.py:572 -#: pretix/plugins/paypal2/payment.py:978 pretix/plugins/paypal2/payment.py:999 +#: pretix/plugins/paypal/payment.py:566 pretix/plugins/paypal/payment.py:573 +#: pretix/plugins/paypal2/payment.py:979 pretix/plugins/paypal2/payment.py:1000 +#, python-brace-format msgid "Refunding the amount via PayPal failed: {}" msgstr "" -#: pretix/plugins/paypal/payment.py:707 pretix/plugins/paypal/payment.py:715 -#: pretix/plugins/paypal2/payment.py:1076 -#: pretix/plugins/paypal2/payment.py:1084 -msgid "The payment for this invoice has already been received." -msgstr "" - #: pretix/plugins/paypal/payment.py:708 pretix/plugins/paypal/payment.py:716 #: pretix/plugins/paypal2/payment.py:1077 #: pretix/plugins/paypal2/payment.py:1085 +msgid "The payment for this invoice has already been received." +msgstr "" + +#: pretix/plugins/paypal/payment.py:709 pretix/plugins/paypal/payment.py:717 +#: pretix/plugins/paypal2/payment.py:1078 +#: pretix/plugins/paypal2/payment.py:1086 msgid "PayPal payment ID" msgstr "" -#: pretix/plugins/paypal/payment.py:710 pretix/plugins/paypal2/payment.py:1079 +#: pretix/plugins/paypal/payment.py:711 pretix/plugins/paypal2/payment.py:1080 msgid "PayPal sale ID" msgstr "" @@ -26397,22 +27273,22 @@ msgid "" "methods world-wide." msgstr "" -#: pretix/plugins/paypal2/payment.py:99 +#: pretix/plugins/paypal2/payment.py:100 msgid "PayPal Merchant ID" msgstr "" -#: pretix/plugins/paypal2/payment.py:141 +#: pretix/plugins/paypal2/payment.py:142 msgid "" "Even if a customer chooses an Alternative Payment Method, they will always " "have the option to revert back to paying with their PayPal account. For this " "reason, this payment method is always active." msgstr "" -#: pretix/plugins/paypal2/payment.py:149 +#: pretix/plugins/paypal2/payment.py:150 msgid "Alternative Payment Methods" msgstr "" -#: pretix/plugins/paypal2/payment.py:151 +#: pretix/plugins/paypal2/payment.py:152 msgid "" "In addition to payments through a PayPal account, you can also offer your " "customers the option to pay with credit cards and other, local payment " @@ -26422,11 +27298,11 @@ msgid "" "PayPal Plus." msgstr "" -#: pretix/plugins/paypal2/payment.py:166 +#: pretix/plugins/paypal2/payment.py:167 msgid "Disable SEPA Direct Debit" msgstr "" -#: pretix/plugins/paypal2/payment.py:168 +#: pretix/plugins/paypal2/payment.py:169 msgid "" "While most payment methods cannot be recalled by a customer without " "outlining their exact grief with the merchants, SEPA Direct Debit can be " @@ -26435,53 +27311,53 @@ msgid "" "Debit payments in order to reduce the risk of costly chargebacks." msgstr "" -#: pretix/plugins/paypal2/payment.py:182 +#: pretix/plugins/paypal2/payment.py:183 msgid "Enable Buy Now Pay Later" msgstr "" -#: pretix/plugins/paypal2/payment.py:184 +#: pretix/plugins/paypal2/payment.py:185 msgid "" "Offer your customers the possibility to buy now (up to a certain limit) and " "pay in multiple installments or within 30 days. You, as the merchant, are " "getting your money right away." msgstr "" -#: pretix/plugins/paypal2/payment.py:216 +#: pretix/plugins/paypal2/payment.py:217 msgid "-- Automatic --" msgstr "" -#: pretix/plugins/paypal2/payment.py:222 +#: pretix/plugins/paypal2/payment.py:223 msgid "Buyer country" msgstr "" -#: pretix/plugins/paypal2/payment.py:246 +#: pretix/plugins/paypal2/payment.py:247 msgid "" "To accept payments via PayPal, you will need an account at PayPal. By " "clicking on the following button, you can either create a new PayPal account " "or connect pretix to an existing one." msgstr "" -#: pretix/plugins/paypal2/payment.py:251 +#: pretix/plugins/paypal2/payment.py:252 #, python-brace-format msgid "Connect with {icon} PayPal" msgstr "" -#: pretix/plugins/paypal2/payment.py:265 +#: pretix/plugins/paypal2/payment.py:266 msgid "" "Please configure a PayPal Webhook to the following endpoint in order to " "automatically cancel orders when payments are refunded externally." msgstr "" -#: pretix/plugins/paypal2/payment.py:276 +#: pretix/plugins/paypal2/payment.py:277 msgid "PayPal does not process payments in your event's currency." msgstr "" -#: pretix/plugins/paypal2/payment.py:277 +#: pretix/plugins/paypal2/payment.py:278 msgid "" "Please check this PayPal page for a complete list of supported currencies." msgstr "" -#: pretix/plugins/paypal2/payment.py:282 +#: pretix/plugins/paypal2/payment.py:283 msgid "" "Your event's currency is supported by PayPal as a payment and balance " "currency for in-country accounts only. This means, that the receiving as " @@ -26490,13 +27366,13 @@ msgid "" "to send any payments." msgstr "" -#: pretix/plugins/paypal2/payment.py:334 pretix/plugins/paypal2/views.py:250 +#: pretix/plugins/paypal2/payment.py:335 pretix/plugins/paypal2/views.py:250 msgid "An error occurred during connecting with PayPal, please try again." msgstr "" -#: pretix/plugins/paypal2/payment.py:466 pretix/plugins/paypal2/payment.py:598 -#: pretix/plugins/paypal2/payment.py:672 pretix/plugins/paypal2/payment.py:735 -#: pretix/plugins/paypal2/payment.py:780 pretix/plugins/paypal2/payment.py:1015 +#: pretix/plugins/paypal2/payment.py:467 pretix/plugins/paypal2/payment.py:599 +#: pretix/plugins/paypal2/payment.py:673 pretix/plugins/paypal2/payment.py:736 +#: pretix/plugins/paypal2/payment.py:781 pretix/plugins/paypal2/payment.py:1016 #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html:5 msgid "" "Your payment has failed due to a known issue within PayPal. Please try " @@ -26504,26 +27380,26 @@ msgid "" "attempt. You can also try other payment methods, if available." msgstr "" -#: pretix/plugins/paypal2/payment.py:476 pretix/plugins/paypal2/payment.py:1026 +#: pretix/plugins/paypal2/payment.py:477 pretix/plugins/paypal2/payment.py:1027 msgid "" "Something went wrong when requesting the payment status. Please try again." msgstr "" -#: pretix/plugins/paypal2/payment.py:485 pretix/plugins/paypal2/payment.py:1035 +#: pretix/plugins/paypal2/payment.py:486 pretix/plugins/paypal2/payment.py:1036 msgid "You may need to enable JavaScript for PayPal payments." msgstr "" -#: pretix/plugins/paypal2/payment.py:969 +#: pretix/plugins/paypal2/payment.py:970 msgid "" "Refunding the amount via PayPal failed: The original payment does not " "contain the required information to issue an automated refund." msgstr "" -#: pretix/plugins/paypal2/payment.py:1103 +#: pretix/plugins/paypal2/payment.py:1104 msgid "PayPal APM" msgstr "" -#: pretix/plugins/paypal2/payment.py:1104 +#: pretix/plugins/paypal2/payment.py:1105 msgid "PayPal Alternative Payment Methods" msgstr "" @@ -26568,6 +27444,7 @@ msgid "Capture pending." msgstr "" #: pretix/plugins/paypal2/signals.py:75 +#, python-brace-format msgid "PayPal reported an event: {}" msgstr "" @@ -26636,11 +27513,6 @@ msgid "" "different payment method, if you prefer." msgstr "" -#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:16 -#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:19 -msgid "Error" -msgstr "" - #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:24 msgid "Capture status" msgstr "" @@ -26671,7 +27543,7 @@ msgid "Please turn on JavaScript." msgstr "" #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html:29 -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:56 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:57 msgid "Please select how you want to pay." msgstr "" @@ -26721,38 +27593,38 @@ msgid "" "event." msgstr "" -#: pretix/plugins/reports/accountingreport.py:58 +#: pretix/plugins/reports/accountingreport.py:59 msgid "Accounting report" msgstr "" -#: pretix/plugins/reports/accountingreport.py:60 +#: pretix/plugins/reports/accountingreport.py:61 msgid "" "Download a PDF report of all sales and payments within a given time frame." msgstr "" -#: pretix/plugins/reports/accountingreport.py:62 -#: pretix/plugins/reports/exporters.py:246 +#: pretix/plugins/reports/accountingreport.py:63 +#: pretix/plugins/reports/exporters.py:257 msgctxt "export_category" msgid "Analysis" msgstr "" -#: pretix/plugins/reports/accountingreport.py:82 +#: pretix/plugins/reports/accountingreport.py:83 msgid "Ignore test mode orders" msgstr "" -#: pretix/plugins/reports/accountingreport.py:90 +#: pretix/plugins/reports/accountingreport.py:91 msgid "Split event series by date" msgstr "" -#: pretix/plugins/reports/accountingreport.py:128 +#: pretix/plugins/reports/accountingreport.py:129 msgid "End" msgstr "" -#: pretix/plugins/reports/accountingreport.py:139 +#: pretix/plugins/reports/accountingreport.py:140 msgid "Report includes test orders which may be deleted later!" msgstr "" -#: pretix/plugins/reports/accountingreport.py:144 +#: pretix/plugins/reports/accountingreport.py:145 msgid "" "The report time frame includes data generated with an old software version " "that did not yet store all data required to create this report. The report " @@ -26760,27 +27632,27 @@ msgid "" "the time frame." msgstr "" -#: pretix/plugins/reports/accountingreport.py:644 -#: pretix/plugins/reports/accountingreport.py:694 +#: pretix/plugins/reports/accountingreport.py:645 +#: pretix/plugins/reports/accountingreport.py:695 #, python-brace-format msgid "Pending payments at {datetime}" msgstr "" -#: pretix/plugins/reports/accountingreport.py:751 -#: pretix/plugins/reports/accountingreport.py:789 +#: pretix/plugins/reports/accountingreport.py:752 +#: pretix/plugins/reports/accountingreport.py:790 #, python-brace-format msgid "Total gift card value at {datetime}" msgstr "" -#: pretix/plugins/reports/accountingreport.py:770 +#: pretix/plugins/reports/accountingreport.py:771 msgid "Gift card transactions (credit)" msgstr "" -#: pretix/plugins/reports/accountingreport.py:780 +#: pretix/plugins/reports/accountingreport.py:781 msgid "Gift card transactions (debit)" msgstr "" -#: pretix/plugins/reports/accountingreport.py:882 +#: pretix/plugins/reports/accountingreport.py:883 msgid "Open items" msgstr "" @@ -26792,102 +27664,102 @@ msgstr "" msgid "Generate printable reports about your sales." msgstr "" -#: pretix/plugins/reports/exporters.py:97 +#: pretix/plugins/reports/exporters.py:99 #, python-format msgid "Page %d of %d" msgstr "" -#: pretix/plugins/reports/exporters.py:200 +#: pretix/plugins/reports/exporters.py:211 #, python-format msgid "Page %d" msgstr "" -#: pretix/plugins/reports/exporters.py:202 +#: pretix/plugins/reports/exporters.py:213 #, python-format msgid "Created: %s" msgstr "" -#: pretix/plugins/reports/exporters.py:245 +#: pretix/plugins/reports/exporters.py:256 msgid "Order overview (PDF)" msgstr "" -#: pretix/plugins/reports/exporters.py:247 +#: pretix/plugins/reports/exporters.py:258 msgid "Download a PDF version of the key sales numbers per ticket type." msgstr "" -#: pretix/plugins/reports/exporters.py:275 +#: pretix/plugins/reports/exporters.py:286 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:58 msgid "Orders by product" msgstr "" -#: pretix/plugins/reports/exporters.py:275 +#: pretix/plugins/reports/exporters.py:286 msgid "(excl. taxes)" msgstr "" -#: pretix/plugins/reports/exporters.py:275 +#: pretix/plugins/reports/exporters.py:286 msgid "(incl. taxes)" msgstr "" -#: pretix/plugins/reports/exporters.py:285 -#: pretix/plugins/reports/exporters.py:304 +#: pretix/plugins/reports/exporters.py:296 +#: pretix/plugins/reports/exporters.py:315 #, python-brace-format msgid "{axis} between {start} and {end}" msgstr "" -#: pretix/plugins/reports/exporters.py:390 -#: pretix/plugins/reports/exporters.py:391 -#: pretix/plugins/reports/exporters.py:392 -#: pretix/plugins/reports/exporters.py:393 -#: pretix/plugins/reports/exporters.py:394 -#: pretix/plugins/reports/exporters.py:395 +#: pretix/plugins/reports/exporters.py:401 +#: pretix/plugins/reports/exporters.py:402 +#: pretix/plugins/reports/exporters.py:403 +#: pretix/plugins/reports/exporters.py:404 +#: pretix/plugins/reports/exporters.py:405 +#: pretix/plugins/reports/exporters.py:406 msgid "#" msgstr "" -#: pretix/plugins/reports/exporters.py:477 +#: pretix/plugins/reports/exporters.py:488 msgid "Tax split list (PDF)" msgstr "" -#: pretix/plugins/reports/exporters.py:479 +#: pretix/plugins/reports/exporters.py:490 msgid "Download a PDF list with the tax amounts included in each order." msgstr "" -#: pretix/plugins/reports/exporters.py:556 +#: pretix/plugins/reports/exporters.py:567 #, python-brace-format msgid "Orders by tax rate ({currency})" msgstr "" -#: pretix/plugins/reports/exporters.py:565 -#: pretix/plugins/reports/exporters.py:794 -#: pretix/plugins/reports/exporters.py:846 -#: pretix/plugins/reports/exporters.py:887 +#: pretix/plugins/reports/exporters.py:576 +#: pretix/plugins/reports/exporters.py:805 +#: pretix/plugins/reports/exporters.py:857 +#: pretix/plugins/reports/exporters.py:898 msgid "Gross" msgstr "" -#: pretix/plugins/reports/exporters.py:565 -#: pretix/plugins/reports/exporters.py:795 -#: pretix/plugins/reports/exporters.py:847 -#: pretix/plugins/reports/exporters.py:887 +#: pretix/plugins/reports/exporters.py:576 +#: pretix/plugins/reports/exporters.py:806 +#: pretix/plugins/reports/exporters.py:858 +#: pretix/plugins/reports/exporters.py:898 msgid "Tax" msgstr "" -#: pretix/plugins/reports/exporters.py:650 +#: pretix/plugins/reports/exporters.py:661 msgid "Tax split list" msgstr "" -#: pretix/plugins/reports/exporters.py:652 +#: pretix/plugins/reports/exporters.py:663 msgid "Download a spreadsheet with the tax amounts included in each order." msgstr "" -#: pretix/plugins/reports/exporters.py:658 +#: pretix/plugins/reports/exporters.py:669 msgid "Taxes by country" msgstr "" -#: pretix/plugins/reports/exporters.py:659 +#: pretix/plugins/reports/exporters.py:670 msgid "Business customers" msgstr "" -#: pretix/plugins/reports/exporters.py:791 -#: pretix/plugins/reports/exporters.py:836 +#: pretix/plugins/reports/exporters.py:802 +#: pretix/plugins/reports/exporters.py:847 msgid "Country code" msgstr "" @@ -26944,7 +27816,7 @@ msgid "Waiting for" msgstr "" #: pretix/plugins/sendmail/forms.py:97 pretix/plugins/sendmail/forms.py:171 -#: pretix/plugins/sendmail/forms.py:349 +#: pretix/plugins/sendmail/forms.py:348 msgctxt "sendmail_form" msgid "Restrict to a specific event date" msgstr "" @@ -27006,17 +27878,17 @@ msgstr "" msgid "Attachment of tickets is disabled in this event's email settings." msgstr "" -#: pretix/plugins/sendmail/forms.py:234 pretix/plugins/sendmail/forms.py:388 +#: pretix/plugins/sendmail/forms.py:234 pretix/plugins/sendmail/forms.py:386 #: pretix/plugins/sendmail/views.py:267 msgid "payment pending but already confirmed" msgstr "" -#: pretix/plugins/sendmail/forms.py:235 pretix/plugins/sendmail/forms.py:390 +#: pretix/plugins/sendmail/forms.py:235 pretix/plugins/sendmail/forms.py:388 #: pretix/plugins/sendmail/views.py:268 msgid "payment pending (except unapproved or already confirmed)" msgstr "" -#: pretix/plugins/sendmail/forms.py:239 pretix/plugins/sendmail/forms.py:394 +#: pretix/plugins/sendmail/forms.py:239 pretix/plugins/sendmail/forms.py:392 #: pretix/plugins/sendmail/views.py:266 msgid "pending with payment overdue" msgstr "" @@ -27031,44 +27903,44 @@ msgctxt "sendmail_form" msgid "Restrict to recipients with check-in on list" msgstr "" -#: pretix/plugins/sendmail/forms.py:373 +#: pretix/plugins/sendmail/forms.py:371 msgid "Type of schedule time" msgstr "" -#: pretix/plugins/sendmail/forms.py:376 +#: pretix/plugins/sendmail/forms.py:374 msgid "Absolute" msgstr "" -#: pretix/plugins/sendmail/forms.py:377 +#: pretix/plugins/sendmail/forms.py:375 msgid "Relative, before event start" msgstr "" -#: pretix/plugins/sendmail/forms.py:378 +#: pretix/plugins/sendmail/forms.py:376 msgid "Relative, before event end" msgstr "" -#: pretix/plugins/sendmail/forms.py:379 +#: pretix/plugins/sendmail/forms.py:377 msgid "Relative, after event start" msgstr "" -#: pretix/plugins/sendmail/forms.py:380 +#: pretix/plugins/sendmail/forms.py:378 msgid "Relative, after event end" msgstr "" -#: pretix/plugins/sendmail/forms.py:397 +#: pretix/plugins/sendmail/forms.py:395 msgctxt "sendmail_from" msgid "Restrict to orders with status" msgstr "" -#: pretix/plugins/sendmail/forms.py:412 +#: pretix/plugins/sendmail/forms.py:410 msgid "Please specify the send date" msgstr "" -#: pretix/plugins/sendmail/forms.py:417 +#: pretix/plugins/sendmail/forms.py:415 msgid "Please specify the offset days and time" msgstr "" -#: pretix/plugins/sendmail/forms.py:428 +#: pretix/plugins/sendmail/forms.py:426 msgid "Please specify a product" msgstr "" @@ -27076,10 +27948,6 @@ msgstr "" msgid "scheduled" msgstr "" -#: pretix/plugins/sendmail/models.py:52 -msgid "failed" -msgstr "" - #: pretix/plugins/sendmail/models.py:53 msgid "completed" msgstr "" @@ -27326,10 +28194,6 @@ msgstr "" msgid "Next execution:" msgstr "" -#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:56 -msgid "unknown" -msgstr "" - #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:60 msgid "Last execution:" msgstr "" @@ -27483,11 +28347,6 @@ msgstr "" msgid "Minimum Price" msgstr "" -#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:109 -#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:111 -msgid "Available" -msgstr "" - #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:116 msgid "On Sale" msgstr "" @@ -28060,22 +28919,27 @@ msgid "Payment authorization failed." msgstr "" #: pretix/plugins/stripe/signals.py:104 +#, python-brace-format msgid "Charge failed. Reason: {}" msgstr "" #: pretix/plugins/stripe/signals.py:106 +#, python-brace-format msgid "Dispute created. Reason: {}" msgstr "" #: pretix/plugins/stripe/signals.py:108 +#, python-brace-format msgid "Dispute updated. Reason: {}" msgstr "" #: pretix/plugins/stripe/signals.py:110 +#, python-brace-format msgid "Dispute closed. Status: {}" msgstr "" #: pretix/plugins/stripe/signals.py:113 +#, python-brace-format msgid "Stripe reported an event: {}" msgstr "" @@ -28294,6 +29158,7 @@ msgid "An error occurred during connecting with Stripe, please try again." msgstr "" #: pretix/plugins/stripe/views.py:157 pretix/plugins/stripe/views.py:159 +#, python-brace-format msgid "Stripe returned an error: {}" msgstr "" @@ -28469,6 +29334,7 @@ msgid "The selected ticket layout been deleted." msgstr "" #: pretix/plugins/ticketoutputpdf/views.py:250 +#, python-brace-format msgid "Ticket PDF layout: {}" msgstr "" @@ -28526,68 +29392,73 @@ msgctxt "checkoutflow" msgid "Your information" msgstr "" -#: pretix/presale/checkoutflow.py:990 +#: pretix/presale/checkoutflow.py:994 msgid "" "Unfortunately, based on the invoice address you entered, we're not able to " "sell you the selected products for tax-related legal reasons." msgstr "" -#: pretix/presale/checkoutflow.py:996 +#: pretix/presale/checkoutflow.py:1000 msgid "" "Due to the invoice address you entered, we need to apply a different tax " "rate to your purchase and the price of the products in your cart has changed " "accordingly." msgstr "" -#: pretix/presale/checkoutflow.py:1029 +#: pretix/presale/checkoutflow.py:1024 pretix/presale/checkoutflow.py:1030 +msgid "Please enter a valid email address." +msgstr "" + +#: pretix/presale/checkoutflow.py:1037 msgid "Please enter your invoicing address." msgstr "" -#: pretix/presale/checkoutflow.py:1033 +#: pretix/presale/checkoutflow.py:1041 msgid "Please enter your name." msgstr "" -#: pretix/presale/checkoutflow.py:1068 pretix/presale/checkoutflow.py:1073 -#: pretix/presale/checkoutflow.py:1078 pretix/presale/checkoutflow.py:1083 -#: pretix/presale/checkoutflow.py:1088 +#: pretix/presale/checkoutflow.py:1076 pretix/presale/checkoutflow.py:1081 +#: pretix/presale/checkoutflow.py:1086 pretix/presale/checkoutflow.py:1091 +#: pretix/presale/checkoutflow.py:1096 msgid "Please fill in answers to all required questions." msgstr "" -#: pretix/presale/checkoutflow.py:1249 +#: pretix/presale/checkoutflow.py:1259 msgctxt "checkoutflow" msgid "Payment" msgstr "" -#: pretix/presale/checkoutflow.py:1362 +#: pretix/presale/checkoutflow.py:1372 +#, python-brace-format msgid "" "Your payment method has been applied, but {} still need to be paid. Please " "select a payment method for the remainder." msgstr "" -#: pretix/presale/checkoutflow.py:1387 pretix/presale/views/order.py:676 +#: pretix/presale/checkoutflow.py:1397 pretix/presale/views/order.py:676 msgid "Please select a payment method." msgstr "" -#: pretix/presale/checkoutflow.py:1414 pretix/presale/checkoutflow.py:1428 -#: pretix/presale/checkoutflow.py:1439 +#: pretix/presale/checkoutflow.py:1424 pretix/presale/checkoutflow.py:1438 +#: pretix/presale/checkoutflow.py:1449 msgid "Please select a payment method to proceed." msgstr "" -#: pretix/presale/checkoutflow.py:1444 pretix/presale/views/order.py:435 +#: pretix/presale/checkoutflow.py:1454 pretix/presale/views/order.py:435 #: pretix/presale/views/order.py:502 msgid "The payment information you entered was incomplete." msgstr "" -#: pretix/presale/checkoutflow.py:1489 +#: pretix/presale/checkoutflow.py:1499 msgctxt "checkoutflow" msgid "Review order" msgstr "" -#: pretix/presale/checkoutflow.py:1583 +#: pretix/presale/checkoutflow.py:1593 msgid "You need to check all checkboxes on the bottom of the page." msgstr "" -#: pretix/presale/checkoutflow.py:1638 +#: pretix/presale/checkoutflow.py:1648 msgid "" "There was an error sending the confirmation mail. Please try again later." msgstr "" @@ -28712,8 +29583,8 @@ msgstr "" #: pretix/presale/forms/order.py:113 pretix/presale/forms/order.py:121 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:171 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:311 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:186 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:339 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:188 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:341 #: pretix/presale/templates/pretixpresale/event/voucher.html:198 #: pretix/presale/templates/pretixpresale/event/voucher.html:353 msgid "plus taxes" @@ -28763,16 +29634,16 @@ msgstr "" msgid "Organizer: {organizer}" msgstr "" -#: pretix/presale/templates/pretixpresale/base.html:47 +#: pretix/presale/templates/pretixpresale/base.html:44 msgctxt "skip-to-main-nav" msgid "Skip link" msgstr "" -#: pretix/presale/templates/pretixpresale/base.html:48 +#: pretix/presale/templates/pretixpresale/base.html:45 msgid "Skip to main content" msgstr "" -#: pretix/presale/templates/pretixpresale/base.html:76 +#: pretix/presale/templates/pretixpresale/base.html:75 msgid "Footer Navigation" msgstr "" @@ -28865,7 +29736,7 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/base.html:222 #: pretix/presale/templates/pretixpresale/organizers/base.html:100 -msgid "Contact event organizer" +msgid "Contact" msgstr "" #: pretix/presale/templates/pretixpresale/event/base.html:225 @@ -28914,11 +29785,11 @@ msgid "Our recommendations" msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_addons.html:85 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:202 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:120 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:205 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:121 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:75 -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:125 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:187 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:126 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:189 #: pretix/presale/templates/pretixpresale/organizers/customer_address_delete.html:28 #: pretix/presale/templates/pretixpresale/organizers/customer_profile_delete.html:28 msgid "Go back" @@ -28931,20 +29802,19 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:12 #: pretix/presale/templates/pretixpresale/event/checkout_base.html:56 -#: pretix/presale/templates/pretixpresale/event/checkout_base.html:57 msgid "Checkout" msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:15 #: pretix/presale/templates/pretixpresale/event/checkout_base.html:21 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:18 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:17 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:9 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:11 msgid "Your cart" msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:28 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:28 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:27 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:18 msgid "Cart expired" msgstr "" @@ -28954,91 +29824,90 @@ msgid "Show full cart" msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:52 -#: pretix/presale/templates/pretixpresale/event/index.html:87 +#: pretix/presale/templates/pretixpresale/event/index.html:86 msgid "Add tickets for a different date" msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:8 #: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:10 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:11 msgid "Review order" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:13 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:12 msgid "Please review the details below and confirm your order." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:20 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:19 msgid "Add or remove tickets" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:37 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:36 msgid "Please hang tight, we're finalizing your order!" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:45 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:44 msgid "Modify payment" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:46 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:77 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:126 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:45 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:76 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:129 msgid "Modify" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:76 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:75 msgid "Modify invoice information" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:124 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:127 #: pretix/presale/templates/pretixpresale/event/checkout_questions.html:19 #: pretix/presale/templates/pretixpresale/event/order_modify.html:33 msgid "Contact information" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:125 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:128 msgid "Modify contact information" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:168 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:171 msgid "Confirmations" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:186 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:189 msgid "" "After you submitted your order using the button below, it will require " "approval by the event organizer before it can be confirmed and forms a valid " "contract." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:188 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:191 msgid "" "We will send you an email as soon as the event organizer approved or " "rejected your order." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:192 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:195 msgid "" "If your order was approved, we will send you a link that you can use to pay." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:208 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:211 msgid "Place binding order" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:210 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:213 msgid "Submit registration" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:18 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:19 msgid "Log in with a customer account" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:25 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:26 msgid "You are currently logged in with the following credentials." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:43 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:44 #, python-format msgid "" "If you created a customer account at %(org)s before, you can log in now and " @@ -29046,11 +29915,11 @@ msgid "" "orders in one place and access them at any time." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:76 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:77 msgid "Create a new customer account" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:83 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:84 #, python-format msgid "" "We will send you an email with a link to activate your account and set a " @@ -29058,11 +29927,11 @@ msgid "" "still go ahead with this purchase before you received the email." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:100 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:101 msgid "Continue as a guest" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:106 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:107 msgid "" "You are not required to create an account. If you proceed as a guest, you " "will be able to access the details and status of your order any time through " @@ -29076,7 +29945,7 @@ msgid "" msgstr "" #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:34 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:110 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:112 msgid "Selected add-ons" msgstr "" @@ -29087,48 +29956,48 @@ msgid "" "product." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:12 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:13 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:30 msgid "You already selected the following payment methods:" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:29 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:30 msgid "Remove payment" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:39 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:40 msgid "Remaining balance" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:40 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:41 msgid "Please select a payment method below." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:53 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:54 msgid "Please select how you want to pay the remaining balance:" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:91 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:92 msgid "This sales channel does not provide support for test mode." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:93 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:94 msgid "If you continue, you might pay an actual order with non-existing money!" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:101 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:102 msgid "This payment provider does not provide support for test mode." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:103 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:104 msgid "If you continue, actual money might be transferred." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:114 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:115 msgid "There are no payment providers enabled." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:116 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:117 msgid "" "Please go to the payment settings and activate one or more payment providers." msgstr "" @@ -29137,21 +30006,21 @@ msgstr "" msgid "Before we continue, we need you to answer some questions." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:47 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:49 msgid "Auto-fill with address" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:54 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:157 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:56 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:159 msgid "Fill form" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:91 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:168 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:93 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:170 msgid "Copy answers from above" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:148 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:150 msgid "Auto-fill with profile" msgstr "" @@ -29210,7 +30079,7 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:64 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:258 #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:55 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:277 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:279 #: pretix/presale/templates/pretixpresale/event/voucher.html:293 #, python-format msgid "minimum amount to order: %(num)s" @@ -29221,9 +30090,9 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:185 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:300 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:325 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:76 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:174 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:327 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:77 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:176 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:329 #: pretix/presale/templates/pretixpresale/event/voucher.html:117 #: pretix/presale/templates/pretixpresale/event/voucher.html:186 #: pretix/presale/templates/pretixpresale/event/voucher.html:341 @@ -29244,19 +30113,19 @@ msgid "from %(from_price)s to %(to_price)s" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:98 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:103 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:105 msgid "Hide variants" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:102 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:107 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:109 msgid "Show variants" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:129 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:271 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:133 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:288 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:135 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:290 #: pretix/presale/templates/pretixpresale/event/voucher.html:147 #: pretix/presale/templates/pretixpresale/event/voucher.html:304 msgid "Original price:" @@ -29264,8 +30133,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:136 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:278 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:143 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:298 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:145 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:300 #: pretix/presale/templates/pretixpresale/event/voucher.html:157 #: pretix/presale/templates/pretixpresale/event/voucher.html:314 msgid "New price:" @@ -29275,10 +30144,10 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:150 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:289 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:291 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:160 #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:162 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:314 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:164 #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:316 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:318 #: pretix/presale/templates/pretixpresale/event/voucher.html:173 #: pretix/presale/templates/pretixpresale/event/voucher.html:175 #: pretix/presale/templates/pretixpresale/event/voucher.html:328 @@ -29289,9 +30158,9 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:153 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:294 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:149 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:165 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:319 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:151 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:167 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:321 #: pretix/presale/templates/pretixpresale/event/voucher.html:163 #: pretix/presale/templates/pretixpresale/event/voucher.html:178 #: pretix/presale/templates/pretixpresale/event/voucher.html:333 @@ -29301,8 +30170,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:173 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:313 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:188 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:341 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:190 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:343 #: pretix/presale/templates/pretixpresale/event/voucher.html:200 #: pretix/presale/templates/pretixpresale/event/voucher.html:355 msgid "incl. taxes" @@ -29310,8 +30179,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:176 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:316 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:192 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:345 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:194 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:347 #: pretix/presale/templates/pretixpresale/event/voucher.html:204 #: pretix/presale/templates/pretixpresale/event/voucher.html:359 #, python-format @@ -29320,8 +30189,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:180 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:320 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:198 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:351 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:200 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:353 #: pretix/presale/templates/pretixpresale/event/voucher.html:210 #: pretix/presale/templates/pretixpresale/event/voucher.html:365 #, python-format @@ -29330,8 +30199,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:203 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:349 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:219 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:371 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:221 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:373 #: pretix/presale/templates/pretixpresale/event/voucher.html:230 #: pretix/presale/templates/pretixpresale/event/voucher.html:385 msgctxt "checkbox" @@ -29340,8 +30209,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:208 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:354 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:224 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:376 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:226 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:378 #: pretix/presale/templates/pretixpresale/event/voucher.html:235 #: pretix/presale/templates/pretixpresale/event/voucher.html:390 msgid "Decrease quantity" @@ -29349,8 +30218,8 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:218 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:364 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:235 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:388 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:237 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:390 #: pretix/presale/templates/pretixpresale/event/voucher.html:242 #: pretix/presale/templates/pretixpresale/event/voucher.html:398 msgid "Increase quantity" @@ -29374,17 +30243,17 @@ msgid "Not available any more." msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:23 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:87 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:89 msgid "SOLD OUT" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:25 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:85 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:87 msgid "FULLY BOOKED" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:37 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:95 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:97 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:99 #: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:104 #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:30 @@ -29493,7 +30362,7 @@ msgid "We're trying to reserve another one for you!" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:304 -#: pretix/presale/templates/pretixpresale/event/index.html:187 +#: pretix/presale/templates/pretixpresale/event/index.html:186 #: pretix/presale/templates/pretixpresale/event/seatingplan.html:24 #: pretix/presale/templates/pretixpresale/event/voucher.html:62 #, python-format @@ -29571,7 +30440,7 @@ msgid "Empty cart" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:68 -#: pretix/presale/templates/pretixpresale/event/index.html:249 +#: pretix/presale/templates/pretixpresale/event/index.html:248 #: pretix/presale/templates/pretixpresale/event/voucher_form.html:16 msgid "Redeem a voucher" msgstr "" @@ -29668,9 +30537,9 @@ msgid "" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_change_confirm.html:152 -#: pretix/presale/templates/pretixpresale/event/order.html:391 -#: pretix/presale/templates/pretixpresale/event/order.html:427 -#: pretix/presale/templates/pretixpresale/event/order.html:448 +#: pretix/presale/templates/pretixpresale/event/order.html:395 +#: pretix/presale/templates/pretixpresale/event/order.html:431 +#: pretix/presale/templates/pretixpresale/event/order.html:452 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:113 msgid "" "The refund will be issued in form of a gift card that you can use for " @@ -29824,30 +30693,30 @@ msgid "Uncategorized items" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:40 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:259 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:261 #: pretix/presale/templates/pretixpresale/event/voucher.html:94 #: pretix/presale/templates/pretixpresale/event/voucher.html:275 #, python-format msgid "Show full-size image of %(item)s" msgstr "" -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:191 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:344 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:193 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:346 #: pretix/presale/templates/pretixpresale/event/voucher.html:203 #: pretix/presale/templates/pretixpresale/event/voucher.html:358 #, python-format msgid "%(value)s incl. taxes" msgstr "" -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:197 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:350 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:199 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:352 #: pretix/presale/templates/pretixpresale/event/voucher.html:209 #: pretix/presale/templates/pretixpresale/event/voucher.html:364 #, python-format msgid "%(value)s without taxes" msgstr "" -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:304 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:306 #: pretix/presale/templates/pretixpresale/event/voucher.html:320 #, python-format msgid "Set price in %(currency)s for %(item)s" @@ -29944,51 +30813,43 @@ msgid "" " " msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:50 -msgid "Your cart, general information, add products to your cart" -msgstr "" - -#: pretix/presale/templates/pretixpresale/event/index.html:50 -msgid "General information, add products to your cart" -msgstr "" - -#: pretix/presale/templates/pretixpresale/event/index.html:70 +#: pretix/presale/templates/pretixpresale/event/index.html:69 msgid "Please select a date to redeem your voucher." msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:89 +#: pretix/presale/templates/pretixpresale/event/index.html:88 msgid "View other date" msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:92 +#: pretix/presale/templates/pretixpresale/event/index.html:91 msgid "Choose date to book a ticket" msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:156 +#: pretix/presale/templates/pretixpresale/event/index.html:155 #: pretix/presale/views/waiting.py:141 pretix/presale/views/widget.py:774 msgid "The booking period for this event is over." msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:164 +#: pretix/presale/templates/pretixpresale/event/index.html:163 #: pretix/presale/views/widget.py:776 #, python-format msgid "The booking period for this event will start on %(date)s at %(time)s." msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:186 +#: pretix/presale/templates/pretixpresale/event/index.html:185 #: pretix/presale/templates/pretixpresale/event/seatingplan.html:23 #: pretix/presale/templates/pretixpresale/event/voucher.html:61 msgid "We're now trying to reserve this for you!" msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:205 +#: pretix/presale/templates/pretixpresale/event/index.html:204 msgid "" "Some of the categories in the seating plan above are currently sold out. If " "you want, you can add yourself to the waiting list. We will then notify if " "seats are available again." msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:214 +#: pretix/presale/templates/pretixpresale/event/index.html:213 msgid "Join waiting list" msgstr "" @@ -30003,11 +30864,11 @@ msgstr "" msgid "Add to cart" msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:256 +#: pretix/presale/templates/pretixpresale/event/index.html:255 msgid "If you have already ordered a ticket" msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:260 +#: pretix/presale/templates/pretixpresale/event/index.html:259 msgid "" "If you want to see or change the status and details of your order, click on " "the link in one of the emails we sent you during the order process. If you " @@ -30015,7 +30876,7 @@ msgid "" "your order to be sent to you again." msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:269 +#: pretix/presale/templates/pretixpresale/event/index.html:268 msgid "Resend order link" msgstr "" @@ -30037,52 +30898,52 @@ msgid "Please try again later." msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:13 -#: pretix/presale/templates/pretixpresale/event/order.html:30 +#: pretix/presale/templates/pretixpresale/event/order.html:29 msgid "Thank you!" msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:15 -#: pretix/presale/templates/pretixpresale/event/order.html:33 +#: pretix/presale/templates/pretixpresale/event/order.html:32 msgid "Your order has been placed successfully. See below for details." msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:17 -#: pretix/presale/templates/pretixpresale/event/order.html:49 +#: pretix/presale/templates/pretixpresale/event/order.html:48 msgid "Your order has been processed successfully! See below for details." msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:19 -#: pretix/presale/templates/pretixpresale/event/order.html:51 +#: pretix/presale/templates/pretixpresale/event/order.html:50 msgid "We successfully received your payment. See below for details." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:36 +#: pretix/presale/templates/pretixpresale/event/order.html:35 msgid "" "Please note that we still await approval by the event organizer before your " "order is confirmed." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:40 +#: pretix/presale/templates/pretixpresale/event/order.html:39 msgid "" "Please note that we still await approval by the event organizer before you " "can pay and complete this order." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:44 +#: pretix/presale/templates/pretixpresale/event/order.html:43 msgid "Please note that we still await your payment to complete the process." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:56 +#: pretix/presale/templates/pretixpresale/event/order.html:55 msgid "" "Please bookmark or save the link to this exact page if you want to access " -"your order later. We also sent you an email containing the link to the " -"address you specified." +"your order later. We also sent you an email to the address you specified " +"containing the link to this page." msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:59 msgid "" "Please save the following link if you want to access your order later. We " -"also sent you an email containing the link to the address you specified." +"also sent you an email to the address you specified containing the link." msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:74 @@ -30161,7 +31022,7 @@ msgstr "" #: pretix/presale/templates/pretixpresale/event/order.html:268 #: pretix/presale/templates/pretixpresale/event/order.html:275 -#: pretix/presale/templates/pretixpresale/event/order_modify.html:85 +#: pretix/presale/templates/pretixpresale/event/order_modify.html:86 msgid "Request invoice" msgstr "" @@ -30177,37 +31038,37 @@ msgstr "" msgid "Internal Reference" msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:350 +#: pretix/presale/templates/pretixpresale/event/order.html:354 msgctxt "action" msgid "Change or cancel your order" msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:352 +#: pretix/presale/templates/pretixpresale/event/order.html:356 msgctxt "action" msgid "Change your order" msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:354 +#: pretix/presale/templates/pretixpresale/event/order.html:358 msgctxt "action" msgid "Cancel your order" msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:362 +#: pretix/presale/templates/pretixpresale/event/order.html:366 msgid "" "If you want to make changes to the products you bought, you can click on the " "button to change your order." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:370 +#: pretix/presale/templates/pretixpresale/event/order.html:374 msgid "Change order" msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:382 +#: pretix/presale/templates/pretixpresale/event/order.html:386 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:27 msgid "You can request to cancel this order." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:385 +#: pretix/presale/templates/pretixpresale/event/order.html:389 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:30 msgid "" "If your request is approved, the organizer will determine if you will " @@ -30215,38 +31076,38 @@ msgid "" "their cancellation policy." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:393 -#: pretix/presale/templates/pretixpresale/event/order.html:429 -#: pretix/presale/templates/pretixpresale/event/order.html:450 +#: pretix/presale/templates/pretixpresale/event/order.html:397 +#: pretix/presale/templates/pretixpresale/event/order.html:433 +#: pretix/presale/templates/pretixpresale/event/order.html:454 msgid "" "The refund can be issued to your original payment method or as a gift card." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:395 -#: pretix/presale/templates/pretixpresale/event/order.html:431 -#: pretix/presale/templates/pretixpresale/event/order.html:452 +#: pretix/presale/templates/pretixpresale/event/order.html:399 +#: pretix/presale/templates/pretixpresale/event/order.html:435 +#: pretix/presale/templates/pretixpresale/event/order.html:456 msgid "The refund will be issued to your original payment method." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:397 -#: pretix/presale/templates/pretixpresale/event/order.html:410 -#: pretix/presale/templates/pretixpresale/event/order.html:433 -#: pretix/presale/templates/pretixpresale/event/order.html:454 -#: pretix/presale/templates/pretixpresale/event/order.html:466 -#: pretix/presale/templates/pretixpresale/event/order.html:471 +#: pretix/presale/templates/pretixpresale/event/order.html:401 +#: pretix/presale/templates/pretixpresale/event/order.html:414 +#: pretix/presale/templates/pretixpresale/event/order.html:437 +#: pretix/presale/templates/pretixpresale/event/order.html:458 +#: pretix/presale/templates/pretixpresale/event/order.html:470 +#: pretix/presale/templates/pretixpresale/event/order.html:475 msgid "This will invalidate all tickets in this order." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:402 +#: pretix/presale/templates/pretixpresale/event/order.html:406 msgid "" "You can request to cancel this order, but you will not receive a refund." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:406 +#: pretix/presale/templates/pretixpresale/event/order.html:410 msgid "You can cancel this order, but you will not receive a refund." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:415 +#: pretix/presale/templates/pretixpresale/event/order.html:419 #, python-format msgid "" "You can request to cancel this order. If your request is approved, a " @@ -30254,7 +31115,7 @@ msgid "" "receive a refund of the remainder." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:421 +#: pretix/presale/templates/pretixpresale/event/order.html:425 #, python-format msgid "" "You can cancel this order. In this case, a cancellation fee of " @@ -30262,17 +31123,17 @@ msgid "" "remainder." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:438 +#: pretix/presale/templates/pretixpresale/event/order.html:442 msgid "" "You can request to cancel this order. If your request is approved, you get a " "full refund." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:443 +#: pretix/presale/templates/pretixpresale/event/order.html:447 msgid "You can cancel this order and receive a full refund." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:462 +#: pretix/presale/templates/pretixpresale/event/order.html:466 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:54 #, python-format msgid "" @@ -30280,7 +31141,7 @@ msgid "" "required to pay a cancellation fee of %(fee)s." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:468 +#: pretix/presale/templates/pretixpresale/event/order.html:472 msgid "You can cancel this order using the following button." msgstr "" @@ -30374,7 +31235,7 @@ msgid "" "invoice. Please contact us if you need a new invoice." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order_modify.html:87 +#: pretix/presale/templates/pretixpresale/event/order_modify.html:88 #: pretix/presale/templates/pretixpresale/event/position_modify.html:49 msgid "Save changes" msgstr "" @@ -31340,18 +32201,18 @@ msgstr "" msgid "from %(start_date)s" msgstr "" -#: pretix/settings.py:789 +#: pretix/settings.py:792 msgid "User profile only" msgstr "" -#: pretix/settings.py:790 +#: pretix/settings.py:793 msgid "Read access" msgstr "" -#: pretix/settings.py:791 +#: pretix/settings.py:794 msgid "Write access" msgstr "" -#: pretix/settings.py:802 +#: pretix/settings.py:805 msgid "Kosovo" msgstr "" diff --git a/src/pretix/locale/ang/LC_MESSAGES/djangojs.po b/src/pretix/locale/ang/LC_MESSAGES/djangojs.po index 0c06afbb3..b57462d01 100644 --- a/src/pretix/locale/ang/LC_MESSAGES/djangojs.po +++ b/src/pretix/locale/ang/LC_MESSAGES/djangojs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-06-26 09:11+0000\n" +"POT-Creation-Date: 2025-08-19 16:02+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -344,8 +344,8 @@ msgstr "" msgid "close" msgstr "" -#: pretix/static/pretixbase/js/addressform.js:59 -#: pretix/static/pretixpresale/js/ui/main.js:513 +#: pretix/static/pretixbase/js/addressform.js:105 +#: pretix/static/pretixpresale/js/ui/main.js:509 msgid "required" msgstr "" @@ -557,48 +557,48 @@ msgstr "" msgid "The PDF background file could not be loaded for the following reason:" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:903 +#: pretix/static/pretixcontrol/js/ui/editor.js:904 msgid "Group of objects" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:908 +#: pretix/static/pretixcontrol/js/ui/editor.js:909 msgid "Text object (deprecated)" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:910 +#: pretix/static/pretixcontrol/js/ui/editor.js:911 msgid "Text box" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:912 +#: pretix/static/pretixcontrol/js/ui/editor.js:913 msgid "Barcode area" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:914 +#: pretix/static/pretixcontrol/js/ui/editor.js:915 msgid "Image area" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:916 +#: pretix/static/pretixcontrol/js/ui/editor.js:917 msgid "Powered by pretix" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:918 +#: pretix/static/pretixcontrol/js/ui/editor.js:919 msgid "Object" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:922 +#: pretix/static/pretixcontrol/js/ui/editor.js:923 msgid "Ticket design" msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:1258 +#: pretix/static/pretixcontrol/js/ui/editor.js:1292 msgid "Saving failed." msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:1327 -#: pretix/static/pretixcontrol/js/ui/editor.js:1378 +#: pretix/static/pretixcontrol/js/ui/editor.js:1361 +#: pretix/static/pretixcontrol/js/ui/editor.js:1412 msgid "Error while uploading your PDF file, please try again." msgstr "" -#: pretix/static/pretixcontrol/js/ui/editor.js:1361 +#: pretix/static/pretixcontrol/js/ui/editor.js:1395 msgid "Do you really want to leave the editor without saving your changes?" msgstr "" @@ -630,40 +630,40 @@ msgid "" "will be impacted." msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:416 -#: pretix/static/pretixcontrol/js/ui/main.js:436 +#: pretix/static/pretixcontrol/js/ui/main.js:417 +#: pretix/static/pretixcontrol/js/ui/main.js:437 msgid "Search query" msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:434 +#: pretix/static/pretixcontrol/js/ui/main.js:435 msgid "All" msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:435 +#: pretix/static/pretixcontrol/js/ui/main.js:436 msgid "None" msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:439 +#: pretix/static/pretixcontrol/js/ui/main.js:440 msgid "Selected only" msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:811 +#: pretix/static/pretixcontrol/js/ui/main.js:812 msgid "Enter page number between 1 and %(max)s." msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:814 +#: pretix/static/pretixcontrol/js/ui/main.js:815 msgid "Invalid page number." msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:972 +#: pretix/static/pretixcontrol/js/ui/main.js:973 msgid "Use a different name internally" msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:1012 +#: pretix/static/pretixcontrol/js/ui/main.js:1013 msgid "Click to close" msgstr "" -#: pretix/static/pretixcontrol/js/ui/main.js:1093 +#: pretix/static/pretixcontrol/js/ui/main.js:1094 msgid "You have unsaved changes!" msgstr "" @@ -740,7 +740,7 @@ msgstr "" msgid "Please enter the amount the organizer can keep." msgstr "" -#: pretix/static/pretixpresale/js/ui/main.js:558 +#: pretix/static/pretixpresale/js/ui/main.js:554 msgid "Your local time:" msgstr "" diff --git a/src/pretix/locale/ar/LC_MESSAGES/django.po b/src/pretix/locale/ar/LC_MESSAGES/django.po index 4a6a28d97..055bb6896 100644 --- a/src/pretix/locale/ar/LC_MESSAGES/django.po +++ b/src/pretix/locale/ar/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-06-26 09:09+0000\n" +"POT-Creation-Date: 2025-08-19 16:35+0000\n" "PO-Revision-Date: 2025-04-08 18:00+0000\n" "Last-Translator: Menaouer Chaabi " "<98581961+DerJimno@users.noreply.github.com>\n" @@ -146,10 +146,14 @@ msgid "Spanish" msgstr "الأسبانية" #: pretix/_base_settings.py:118 +msgid "Spanish (Latin America)" +msgstr "" + +#: pretix/_base_settings.py:119 msgid "Turkish" msgstr "التركية" -#: pretix/_base_settings.py:119 +#: pretix/_base_settings.py:120 msgid "Ukrainian" msgstr "الأوكرانية" @@ -190,7 +194,7 @@ msgid "Allowed Post Logout URIs list, space separated" msgstr "قائمة العناوين المسموح بها بعد تسجيل الخروج، مفصولة بمسافة" #: pretix/api/models.py:51 pretix/base/models/customers.py:406 -#: pretix/plugins/paypal/payment.py:113 pretix/plugins/paypal2/payment.py:110 +#: pretix/plugins/paypal/payment.py:114 pretix/plugins/paypal2/payment.py:111 msgid "Client ID" msgstr "هوية العميل" @@ -208,45 +212,45 @@ msgid "Target URL" msgstr "الرابط المستهدف" #: pretix/api/models.py:118 pretix/base/models/devices.py:122 -#: pretix/base/models/organizer.py:286 +#: pretix/base/models/organizer.py:352 msgid "All events (including newly created ones)" msgstr "كل الفعاليات (بما في ذلك تلك التي تم إنشاؤها حديثا)" #: pretix/api/models.py:119 pretix/base/models/devices.py:123 -#: pretix/base/models/organizer.py:287 +#: pretix/base/models/organizer.py:353 msgid "Limit to events" msgstr "حد على الفعاليات" -#: pretix/api/models.py:120 pretix/base/exporters/orderlist.py:284 -#: pretix/base/exporters/orderlist.py:1077 -#: pretix/base/modelimport_orders.py:602 +#: pretix/api/models.py:120 pretix/base/exporters/orderlist.py:285 +#: pretix/base/exporters/orderlist.py:1095 #: pretix/base/modelimport_vouchers.py:326 pretix/base/models/orders.py:272 -#: pretix/base/models/vouchers.py:292 pretix/control/forms/filter.py:557 -#: pretix/control/templates/pretixcontrol/order/index.html:898 +#: pretix/base/models/vouchers.py:295 pretix/control/forms/filter.py:557 +#: pretix/control/templates/pretixcontrol/order/index.html:950 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:38 #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:21 #: pretix/control/views/vouchers.py:121 #: pretix/plugins/banktransfer/refund_export.py:46 -#: pretix/plugins/checkinlists/exporters.py:523 +#: pretix/plugins/checkinlists/exporters.py:524 msgid "Comment" msgstr "تعليق" -#: pretix/api/serializers/cart.py:168 pretix/api/serializers/order.py:1414 +#: pretix/api/serializers/cart.py:168 pretix/api/serializers/order.py:1466 +#, python-brace-format msgid "The product \"{}\" is not assigned to a quota." msgstr "لم يتم تعيين حصة للمنتج \"{}\"." -#: pretix/api/serializers/checkin.py:65 pretix/base/models/event.py:1691 +#: pretix/api/serializers/checkin.py:65 pretix/base/models/event.py:1698 #: pretix/base/models/items.py:1917 pretix/base/models/items.py:2203 msgid "One or more items do not belong to this event." msgstr "هناك عنصر أو أكثر لا ينتمي إلى هذه الفعالية." #: pretix/api/serializers/checkin.py:69 pretix/api/serializers/checkin.py:72 #: pretix/base/models/items.py:2214 pretix/base/models/items.py:2217 -#: pretix/base/models/waitinglist.py:307 pretix/base/models/waitinglist.py:310 +#: pretix/base/models/waitinglist.py:310 pretix/base/models/waitinglist.py:313 msgid "The subevent does not belong to this event." msgstr "الفعالية الفرعية لا تنتمي إلى هذه الفعالية." -#: pretix/api/serializers/event.py:231 +#: pretix/api/serializers/event.py:219 msgid "" "Events cannot be created as 'live'. Quotas and payment must be added to the " "event before sales can go live." @@ -254,22 +258,22 @@ msgstr "" "لا يمكن إنشاء الفعاليات على نحو\"مباشر\". يجب إضافة الحصص والدفع إلى " "الفعالية قبل بدء المبيعات." -#: pretix/api/serializers/event.py:246 pretix/api/serializers/event.py:555 +#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554 #, python-brace-format msgid "Meta data property '{name}' does not exist." msgstr "خاصية البيانات الوصفية ل '{name}' غير موجودة." -#: pretix/api/serializers/event.py:249 pretix/api/serializers/event.py:558 +#: pretix/api/serializers/event.py:237 pretix/api/serializers/event.py:557 #, python-brace-format msgid "Meta data property '{name}' does not allow value '{value}'." msgstr "خاصية البيانات الوصفية '{name}' لا تسمح بقيمة '{value}'." -#: pretix/api/serializers/event.py:293 +#: pretix/api/serializers/event.py:283 pretix/api/serializers/organizer.py:85 #, python-brace-format msgid "Unknown plugin: '{name}'." msgstr "إضافة غير معروفة: '{name}'." -#: pretix/api/serializers/event.py:296 +#: pretix/api/serializers/event.py:286 pretix/api/serializers/organizer.py:88 #, python-brace-format msgid "Restricted plugin: '{name}'." msgstr "إضافة مقيدة: '{name}'." @@ -280,11 +284,11 @@ msgstr "إضافة مقيدة: '{name}'." msgid "Item meta data property '{name}' does not exist." msgstr "خاصية البيانات الوصفية للعنصر '{name}' غير موجودة." -#: pretix/api/serializers/item.py:207 pretix/control/forms/item.py:1273 +#: pretix/api/serializers/item.py:207 pretix/control/forms/item.py:1274 msgid "The bundled item must not be the same item as the bundling one." msgstr "يجب ألا يكون العنصر المجمّع هو نفس عنصر التجميع." -#: pretix/api/serializers/item.py:210 pretix/control/forms/item.py:1275 +#: pretix/api/serializers/item.py:210 pretix/control/forms/item.py:1276 msgid "The bundled item must not have bundles on its own." msgstr "يجب ألا يحتوي العنصر المجمع على حزم بمفرده." @@ -308,7 +312,7 @@ msgstr "" "يجب ألا ترتبط منتجات بطاقات الهدايا بمعدلات ضريبية غير صفرية حيث سيتم تطبيق " "ضريبة المبيعات عند استرداد بطاقة الهدايا." -#: pretix/api/serializers/item.py:322 pretix/control/forms/item.py:780 +#: pretix/api/serializers/item.py:322 pretix/control/forms/item.py:781 msgid "Gift card products should not be admission products at the same time." msgstr "لا يمكن أن تكون منتجات بطاقات الهدايا هي نفس منتجات القبول." @@ -320,19 +324,19 @@ msgstr "" "خيارات التحديث عبر PATCH/PUT غير مدعومة. الرجاء استخدام نقطة نهاية المتداخلة " "المخصصة." -#: pretix/api/serializers/item.py:538 pretix/control/forms/item.py:178 +#: pretix/api/serializers/item.py:538 pretix/control/forms/item.py:176 msgid "Question cannot depend on a question asked during check-in." msgstr "لا يمكن أن يعتمد السؤال على سؤال تم طرحه أثناء التسجيل." -#: pretix/api/serializers/item.py:543 pretix/control/forms/item.py:183 +#: pretix/api/serializers/item.py:543 pretix/control/forms/item.py:181 msgid "Circular dependency between questions detected." msgstr "الأسئلة تدور في حلقة لا متناهية." -#: pretix/api/serializers/item.py:548 pretix/control/forms/item.py:192 +#: pretix/api/serializers/item.py:548 pretix/control/forms/item.py:190 msgid "This type of question cannot be asked during check-in." msgstr "لا يمكن طرح هذا النوع من الأسئلة أثناء تسجيل الدخول." -#: pretix/api/serializers/item.py:551 pretix/control/forms/item.py:200 +#: pretix/api/serializers/item.py:551 pretix/control/forms/item.py:198 msgid "This type of question cannot be shown during check-in." msgstr "لا يمكن عرض هذا النوع من الأسئلة أثناء تسجيل الدخول." @@ -342,50 +346,52 @@ msgid "" "account." msgstr "توجد وسيلة بنفس المعرف والنوع في حساب المنظم الخاص بك." -#: pretix/api/serializers/order.py:79 +#: pretix/api/serializers/order.py:81 #, python-brace-format msgid "\"{input}\" is not a valid choice." msgstr "\"{input}\" ادخال غير صالحة، يرجى المحاولة مرة أخرى." -#: pretix/api/serializers/order.py:1375 pretix/api/views/cart.py:224 -#: pretix/base/services/orders.py:1533 +#: pretix/api/serializers/order.py:1427 pretix/api/views/cart.py:224 +#: pretix/base/services/orders.py:1589 #, python-brace-format msgid "The selected seat \"{seat}\" is not available." msgstr "المقعد المحدد \"{seat}\" غير متوفر." -#: pretix/api/serializers/order.py:1401 pretix/api/serializers/order.py:1408 +#: pretix/api/serializers/order.py:1453 pretix/api/serializers/order.py:1460 +#, python-brace-format msgid "The product \"{}\" is not available on this date." msgstr "المنتج \"{}\" غير متوفر في هذا التاريخ." -#: pretix/api/serializers/order.py:1423 pretix/api/views/cart.py:200 +#: pretix/api/serializers/order.py:1475 pretix/api/views/cart.py:200 +#, python-brace-format msgid "" "There is not enough quota available on quota \"{}\" to perform the operation." msgstr "لا توجد حصة كافية متاحة في الحصة \"{}\" لإجراء العملية." -#: pretix/api/serializers/organizer.py:105 -#: pretix/control/forms/organizer.py:892 pretix/presale/forms/customer.py:458 +#: pretix/api/serializers/organizer.py:145 +#: pretix/control/forms/organizer.py:893 pretix/presale/forms/customer.py:458 msgid "An account with this email address is already registered." msgstr "هناك حساب مرتبط بهذا البريد الإلكتروني مسبقا." -#: pretix/api/serializers/organizer.py:238 -#: pretix/control/forms/organizer.py:741 +#: pretix/api/serializers/organizer.py:278 +#: pretix/control/forms/organizer.py:746 msgid "" "A gift card with the same secret already exists in your or an affiliated " "organizer account." msgstr "توجد مسبقا بطاقة هدايا بنفس السر في حسابك أو حساب منظم تابع." -#: pretix/api/serializers/organizer.py:329 -#: pretix/control/views/organizer.py:773 +#: pretix/api/serializers/organizer.py:369 +#: pretix/control/views/organizer.py:1042 msgid "pretix account invitation" msgstr "دعوة حساب pretix" -#: pretix/api/serializers/organizer.py:351 -#: pretix/control/views/organizer.py:872 +#: pretix/api/serializers/organizer.py:391 +#: pretix/control/views/organizer.py:1141 msgid "This user already has been invited for this team." msgstr "تمت دعوة هذا المستخدم سابقا لهذا الفريق." -#: pretix/api/serializers/organizer.py:367 -#: pretix/control/views/organizer.py:889 +#: pretix/api/serializers/organizer.py:407 +#: pretix/control/views/organizer.py:1158 msgid "This user already has permissions for this team." msgstr "هذا المستخدم لديه تصاريح سابقة لهذا الفريق." @@ -394,239 +400,269 @@ msgid "" "The specified voucher has already been used the maximum number of times." msgstr "تم استخدام رمز كود الخصم هذا سابقا لأقصى عدد مسموح به من المرات." -#: pretix/api/views/checkin.py:611 pretix/api/views/checkin.py:618 +#: pretix/api/views/checkin.py:616 pretix/api/views/checkin.py:623 msgid "Medium connected to other event" msgstr "الوسيط متصل بحدث آخر" -#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:692 +#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:753 #, python-brace-format msgid "" "The application \"{application_name}\" has been authorized to access your " "account." msgstr "تم تفويض التطبيق \"{application_name}\" للوصول إلى حسابك." -#: pretix/api/views/order.py:607 pretix/control/views/orders.py:1610 +#: pretix/api/views/order.py:608 pretix/control/views/orders.py:1597 #: pretix/presale/views/order.py:733 pretix/presale/views/order.py:806 msgid "You cannot generate an invoice for this order." msgstr "لا يمكن انشاء فاتورة لهذا الطلب." -#: pretix/api/views/order.py:612 pretix/control/views/orders.py:1612 +#: pretix/api/views/order.py:613 pretix/control/views/orders.py:1599 #: pretix/presale/views/order.py:735 pretix/presale/views/order.py:808 msgid "An invoice for this order already exists." msgstr "توجد فاتورة مصدرة لهذا الطلب مسبقاً." -#: pretix/api/views/order.py:638 pretix/control/views/orders.py:1738 +#: pretix/api/views/order.py:639 pretix/control/views/orders.py:1758 #: pretix/control/views/users.py:145 msgid "There was an error sending the mail. Please try again later." msgstr "حدث خطأ اثناء ارسال البريد الاكتروني. الرجاء المحاولة مرة أخرى لاحقاً." -#: pretix/api/views/order.py:718 pretix/base/services/cart.py:216 -#: pretix/base/services/orders.py:187 pretix/presale/views/order.py:790 +#: pretix/api/views/order.py:719 pretix/base/services/cart.py:216 +#: pretix/base/services/orders.py:191 pretix/presale/views/order.py:790 msgid "One of the selected products is not available in the selected country." msgstr "أحد المنتجات المختارة غير متوفر في البلد المحدد." -#: pretix/api/webhooks.py:237 pretix/base/notifications.py:233 +#: pretix/api/webhooks.py:262 pretix/base/notifications.py:233 msgid "New order placed" msgstr "تم وضع طلب جديد" -#: pretix/api/webhooks.py:241 pretix/base/notifications.py:239 +#: pretix/api/webhooks.py:266 pretix/base/notifications.py:239 msgid "New order requires approval" msgstr "الطلب الجديد بحاجة إلى موافقة" -#: pretix/api/webhooks.py:245 pretix/base/notifications.py:245 +#: pretix/api/webhooks.py:270 pretix/base/notifications.py:245 msgid "Order marked as paid" msgstr "تم تمييز الطلب على أنه مدفوع" -#: pretix/api/webhooks.py:249 pretix/base/models/checkin.py:354 +#: pretix/api/webhooks.py:274 pretix/base/models/checkin.py:355 #: pretix/base/notifications.py:251 #: pretix/control/templates/pretixcontrol/event/mail.html:114 -#: pretix/control/views/orders.py:1571 +#: pretix/control/views/orders.py:1558 msgid "Order canceled" msgstr "تم إلغاء الطلب" -#: pretix/api/webhooks.py:253 pretix/base/notifications.py:257 +#: pretix/api/webhooks.py:278 pretix/base/notifications.py:257 msgid "Order reactivated" msgstr "تمت إعادة تنشيط الطلب" -#: pretix/api/webhooks.py:257 pretix/base/notifications.py:263 +#: pretix/api/webhooks.py:282 pretix/base/notifications.py:263 msgid "Order expired" msgstr "الطلب منتهي الصلاحية" -#: pretix/api/webhooks.py:261 +#: pretix/api/webhooks.py:286 msgid "Order expiry date changed" msgstr "تم تغيير تاريخ نهاية الطلب" -#: pretix/api/webhooks.py:265 pretix/base/notifications.py:269 +#: pretix/api/webhooks.py:290 pretix/base/notifications.py:269 msgid "Order information changed" msgstr "تم تغيير معلومات الطلب" -#: pretix/api/webhooks.py:269 pretix/base/notifications.py:275 +#: pretix/api/webhooks.py:294 pretix/base/notifications.py:275 msgid "Order contact address changed" msgstr "تم تغيير عنوان اتصال الطلب" -#: pretix/api/webhooks.py:273 pretix/base/notifications.py:281 +#: pretix/api/webhooks.py:298 pretix/base/notifications.py:281 #: pretix/control/templates/pretixcontrol/event/mail.html:102 msgid "Order changed" msgstr "تم تغيير الطلب." -#: pretix/api/webhooks.py:277 +#: pretix/api/webhooks.py:302 #, fuzzy #| msgid "Enable payment method" msgid "Refund of payment created" msgstr "تمكين طريقة الدفع" -#: pretix/api/webhooks.py:281 pretix/base/notifications.py:293 +#: pretix/api/webhooks.py:306 pretix/base/notifications.py:293 msgid "External refund of payment" msgstr "استرداد الدفع الخارجي" -#: pretix/api/webhooks.py:285 +#: pretix/api/webhooks.py:310 #, fuzzy #| msgid "Text (requested by user)" msgid "Refund of payment requested by customer" msgstr "النص (عن طريق المستخدم المطلوب)" -#: pretix/api/webhooks.py:289 +#: pretix/api/webhooks.py:314 #, fuzzy #| msgid "Payment completed." msgid "Refund of payment completed" msgstr "تم السداد." -#: pretix/api/webhooks.py:293 +#: pretix/api/webhooks.py:318 #, fuzzy #| msgid "Refund {local_id} has been canceled." msgid "Refund of payment canceled" msgstr "تم إلغاء استرداد {local_id}." -#: pretix/api/webhooks.py:297 +#: pretix/api/webhooks.py:322 #, fuzzy #| msgid "Refund order" msgid "Refund of payment failed" msgstr "أجل استرداد" -#: pretix/api/webhooks.py:301 +#: pretix/api/webhooks.py:326 #, fuzzy #| msgid "Payment confirmation date" msgid "Payment confirmed" msgstr "تاريخ الدفع تأكيدا" -#: pretix/api/webhooks.py:305 +#: pretix/api/webhooks.py:330 msgid "Order approved" msgstr "تمت الموافقة على الطلب" -#: pretix/api/webhooks.py:309 +#: pretix/api/webhooks.py:334 msgid "Order denied" msgstr "تم رفض الطلب" -#: pretix/api/webhooks.py:313 +#: pretix/api/webhooks.py:338 #, fuzzy #| msgid "Order denied" msgid "Order deleted" msgstr "تم رفض الطلب" -#: pretix/api/webhooks.py:317 +#: pretix/api/webhooks.py:342 msgid "Ticket checked in" msgstr "تم تسجيل التذكرة" -#: pretix/api/webhooks.py:321 +#: pretix/api/webhooks.py:346 msgid "Ticket check-in reverted" msgstr "تم التراجع عن اصدار التذكرة" -#: pretix/api/webhooks.py:325 +#: pretix/api/webhooks.py:350 msgid "Event created" msgstr "تم إنشاء الفعالية" -#: pretix/api/webhooks.py:329 +#: pretix/api/webhooks.py:354 msgid "Event details changed" msgstr "تم تغيير تفاصيل الفعالية" -#: pretix/api/webhooks.py:333 +#: pretix/api/webhooks.py:358 #, fuzzy #| msgid "Event date" msgid "Event deleted" msgstr "تاريخ الفعالية" -#: pretix/api/webhooks.py:337 +#: pretix/api/webhooks.py:362 msgctxt "subevent" msgid "Event series date added" msgstr "تمت إضافة تاريخ سلسلة الفعاليات" -#: pretix/api/webhooks.py:341 +#: pretix/api/webhooks.py:366 msgctxt "subevent" msgid "Event series date changed" msgstr "تم تغيير تاريخ سلسلة الفعاليات" -#: pretix/api/webhooks.py:345 +#: pretix/api/webhooks.py:370 msgctxt "subevent" msgid "Event series date deleted" msgstr "تم حذف تاريخ سلسلة الفعاليات" -#: pretix/api/webhooks.py:349 +#: pretix/api/webhooks.py:374 +#, fuzzy +#| msgid "Product name" +msgid "Product changed" +msgstr "اسم المنتج" + +#: pretix/api/webhooks.py:375 msgid "" -"Product changed (including product added or deleted and including changes to " -"nested objects like variations or bundles)" +"This includes product added or deleted and changes to nested objects like " +"variations or bundles." msgstr "" -#: pretix/api/webhooks.py:354 +#: pretix/api/webhooks.py:380 #, fuzzy #| msgid "Shop not live" msgid "Shop taken live" msgstr "تسوق لا يعيش" -#: pretix/api/webhooks.py:358 +#: pretix/api/webhooks.py:384 #, fuzzy #| msgid "The shop has been taken offline." msgid "Shop taken offline" msgstr "وقد اتخذت المحل حاليا." -#: pretix/api/webhooks.py:362 +#: pretix/api/webhooks.py:388 #, fuzzy #| msgid "The order has been reactivated." msgid "Test-Mode of shop has been activated" msgstr "تم إعادة تنشيط الطلب." -#: pretix/api/webhooks.py:366 +#: pretix/api/webhooks.py:392 #, fuzzy #| msgid "The order has been reactivated." msgid "Test-Mode of shop has been deactivated" msgstr "تم إعادة تنشيط الطلب." -#: pretix/api/webhooks.py:370 +#: pretix/api/webhooks.py:396 #, fuzzy #| msgid "Waiting list entry" msgid "Waiting list entry added" msgstr "دخول قائمة الانتظار" -#: pretix/api/webhooks.py:374 +#: pretix/api/webhooks.py:400 #, fuzzy #| msgid "Waiting list entry" msgid "Waiting list entry changed" msgstr "دخول قائمة الانتظار" -#: pretix/api/webhooks.py:378 +#: pretix/api/webhooks.py:404 #, fuzzy #| msgid "Waiting list entry" msgid "Waiting list entry deleted" msgstr "دخول قائمة الانتظار" -#: pretix/api/webhooks.py:382 +#: pretix/api/webhooks.py:408 #, fuzzy #| msgid "Waiting list entries" msgid "Waiting list entry received voucher" msgstr "مدخلات قائمة الانتظار" -#: pretix/api/webhooks.py:386 +#: pretix/api/webhooks.py:412 +#, fuzzy +#| msgid "Voucher code" +msgid "Voucher added" +msgstr "رمز كود الخصم" + +#: pretix/api/webhooks.py:416 +#, fuzzy +#| msgid "Voucher assigned" +msgid "Voucher changed" +msgstr "تم تعيين كود الخصم" + +#: pretix/api/webhooks.py:417 +msgid "" +"Only includes explicit changes to the voucher, not e.g. an increase of the " +"number of redemptions." +msgstr "" + +#: pretix/api/webhooks.py:421 +#, fuzzy +#| msgid "Voucher redeemed" +msgid "Voucher deleted" +msgstr "تم استخدام كود الخصم" + +#: pretix/api/webhooks.py:425 #, fuzzy #| msgid "Customer actions" msgid "Customer account created" msgstr "إجراءات العملاء" -#: pretix/api/webhooks.py:390 +#: pretix/api/webhooks.py:429 #, fuzzy #| msgid "Customer actions" msgid "Customer account changed" msgstr "إجراءات العملاء" -#: pretix/api/webhooks.py:394 +#: pretix/api/webhooks.py:433 #, fuzzy #| msgid "This user has been anonymized." msgid "Customer account anonymized" @@ -634,13 +670,13 @@ msgstr "تم طمس هويتها لهذا المستخدم." #: pretix/base/addressvalidation.py:100 pretix/base/addressvalidation.py:103 #: pretix/base/addressvalidation.py:108 pretix/base/forms/questions.py:1046 -#: pretix/base/forms/questions.py:1077 pretix/base/forms/questions.py:1270 -#: pretix/base/payment.py:96 pretix/control/forms/event.py:798 -#: pretix/control/forms/event.py:804 pretix/control/forms/event.py:848 -#: pretix/control/forms/event.py:1445 pretix/control/forms/mailsetup.py:87 -#: pretix/control/forms/mailsetup.py:129 pretix/control/forms/subevents.py:185 -#: pretix/plugins/banktransfer/payment.py:673 -#: pretix/plugins/banktransfer/payment.py:679 +#: pretix/base/forms/questions.py:1077 pretix/base/forms/questions.py:1328 +#: pretix/base/payment.py:96 pretix/control/forms/event.py:792 +#: pretix/control/forms/event.py:798 pretix/control/forms/event.py:838 +#: pretix/control/forms/event.py:1454 pretix/control/forms/mailsetup.py:87 +#: pretix/control/forms/mailsetup.py:129 pretix/control/forms/subevents.py:181 +#: pretix/plugins/banktransfer/payment.py:506 +#: pretix/plugins/banktransfer/payment.py:512 #: pretix/presale/forms/customer.py:152 msgid "This field is required." msgstr "هذه الخانة مطلوبة." @@ -659,26 +695,26 @@ msgid "{system} User" msgstr "{system} اسم المستخدم" #: pretix/base/auth.py:155 pretix/base/exporters/customers.py:67 -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:444 -#: pretix/base/exporters/orderlist.py:577 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:453 +#: pretix/base/exporters/orderlist.py:586 #: pretix/base/exporters/waitinglist.py:109 pretix/base/forms/auth.py:257 -#: pretix/base/models/auth.py:244 pretix/base/models/customers.py:94 -#: pretix/base/models/notifications.py:46 pretix/base/models/orders.py:246 -#: pretix/base/pdf.py:325 pretix/control/navigation.py:81 -#: pretix/control/navigation.py:501 +#: pretix/base/invoicing/email.py:43 pretix/base/models/auth.py:244 +#: pretix/base/models/customers.py:94 pretix/base/models/notifications.py:46 +#: pretix/base/models/orders.py:246 pretix/base/pdf.py:334 +#: pretix/control/navigation.py:81 pretix/control/navigation.py:513 #: pretix/control/templates/pretixcontrol/checkin/index.html:107 #: pretix/control/templates/pretixcontrol/event/settings.html:71 #: pretix/control/templates/pretixcontrol/orders/fragment_export_schedule_form.html:108 #: pretix/control/templates/pretixcontrol/organizers/customer.html:49 #: pretix/control/templates/pretixcontrol/organizers/customers.html:59 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:161 -#: pretix/plugins/checkinlists/exporters.py:507 -#: pretix/presale/checkoutflow.py:1532 pretix/presale/forms/checkout.py:57 +#: pretix/plugins/checkinlists/exporters.py:508 +#: pretix/presale/checkoutflow.py:1542 pretix/presale/forms/checkout.py:57 #: pretix/presale/forms/customer.py:57 pretix/presale/forms/customer.py:142 #: pretix/presale/forms/customer.py:298 pretix/presale/forms/customer.py:344 #: pretix/presale/forms/customer.py:388 pretix/presale/forms/user.py:40 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:30 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:31 #: pretix/presale/templates/pretixpresale/event/order.html:300 msgid "Email" msgstr "البريد الإلكتروني" @@ -780,24 +816,422 @@ msgid "" "{fields}." msgstr "" -#: pretix/base/customersso/oidc.py:219 pretix/base/customersso/oidc.py:226 -#: pretix/base/customersso/oidc.py:245 pretix/base/customersso/oidc.py:262 -#: pretix/base/customersso/oidc.py:269 pretix/presale/views/customer.py:743 +#: pretix/base/customersso/oidc.py:223 pretix/base/customersso/oidc.py:231 +#: pretix/base/customersso/oidc.py:254 pretix/base/customersso/oidc.py:271 +#: pretix/base/customersso/oidc.py:278 pretix/presale/views/customer.py:743 #: pretix/presale/views/customer.py:753 pretix/presale/views/customer.py:792 #: pretix/presale/views/customer.py:866 #, python-brace-format msgid "Login was not successful. Error message: \"{error}\"." msgstr "" -#: pretix/base/customersso/oidc.py:252 +#: pretix/base/customersso/oidc.py:261 msgid "" "The email address on this account is not yet verified. Please first confirm " "the email address in your customer account." msgstr "" +#: pretix/base/datasync/datasync.py:255 +#, python-brace-format +msgid "" +"Field \"{field_name}\" is not valid for {available_inputs}. Please check " +"your {provider_name} settings." +msgstr "" + +#: pretix/base/datasync/datasync.py:267 +#, python-brace-format +msgid "" +"Please update value mapping for field \"{field_name}\" - option \"{val}\" " +"not assigned" +msgstr "" + +#: pretix/base/datasync/sourcefields.py:128 +#, fuzzy +#| msgid "Order positions" +msgid "Order position details" +msgstr "حالات الطلب" + +#: pretix/base/datasync/sourcefields.py:129 +#, fuzzy +#| msgid "Attendee email" +msgid "Attendee details" +msgstr "البريد الإلكتروني للحاضر" + +#: pretix/base/datasync/sourcefields.py:130 pretix/base/exporters/answers.py:66 +#: pretix/base/models/items.py:1767 pretix/control/navigation.py:172 +#: pretix/control/templates/pretixcontrol/items/questions.html:3 +#: pretix/control/templates/pretixcontrol/items/questions.html:5 +msgid "Questions" +msgstr "أسئلة" + +#: pretix/base/datasync/sourcefields.py:131 +#, fuzzy +#| msgid "Product name" +msgid "Product details" +msgstr "اسم المنتج" + +#: pretix/base/datasync/sourcefields.py:132 +#: pretix/control/templates/pretixcontrol/event/settings.html:280 +#: pretix/control/templates/pretixcontrol/order/index.html:176 +#: pretix/presale/templates/pretixpresale/event/order.html:22 +msgid "Order details" +msgstr "تفاصيل الطلب" + +#: pretix/base/datasync/sourcefields.py:133 +#: pretix/base/datasync/sourcefields.py:299 +#: pretix/base/datasync/sourcefields.py:614 +#: pretix/base/datasync/sourcefields.py:638 +#: pretix/base/modelimport_orders.py:199 pretix/base/modelimport_orders.py:216 +#: pretix/base/modelimport_orders.py:232 pretix/base/modelimport_orders.py:244 +#: pretix/base/modelimport_orders.py:256 pretix/base/modelimport_orders.py:274 +#: pretix/base/modelimport_orders.py:295 pretix/base/modelimport_orders.py:321 +#: pretix/base/modelimport_orders.py:333 pretix/control/forms/filter.py:621 +#: pretix/control/forms/filter.py:625 pretix/control/forms/filter.py:629 +#: pretix/control/forms/filter.py:633 pretix/control/forms/filter.py:638 +#: pretix/control/forms/filter.py:643 +msgid "Invoice address" +msgstr "عنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:134 +#, fuzzy +#| msgid "Meta information" +msgid "Event information" +msgstr "المعلومات الوصفية" + +#: pretix/base/datasync/sourcefields.py:135 +#, fuzzy +#| msgid "Send recovery information" +msgctxt "subevent" +msgid "Event or date information" +msgstr "إرسال معلومات الاسترداد" + +#: pretix/base/datasync/sourcefields.py:175 +#: pretix/base/exporters/orderlist.py:604 +#: pretix/base/exporters/orderlist.py:609 pretix/base/forms/questions.py:679 +#: pretix/base/modelimport_orders.py:347 pretix/base/models/customers.py:300 +#: pretix/base/models/orders.py:1504 pretix/base/pdf.py:181 +#: pretix/control/forms/filter.py:648 pretix/control/forms/organizer.py:987 +#: pretix/control/templates/pretixcontrol/order/index.html:566 +#: pretix/control/templates/pretixcontrol/organizers/customer.html:120 +#: pretix/control/views/item.py:442 pretix/plugins/badges/exporters.py:495 +#: pretix/plugins/checkinlists/exporters.py:121 +#: pretix/plugins/checkinlists/exporters.py:494 +#: pretix/plugins/ticketoutputpdf/exporters.py:94 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:162 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:165 +#: pretix/presale/templates/pretixpresale/event/fragment_change_form.html:38 +#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:50 +#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:36 +msgid "Attendee name" +msgstr "اسم الحاضر" + +#: pretix/base/datasync/sourcefields.py:187 +#: pretix/base/datasync/sourcefields.py:604 +#: pretix/base/datasync/sourcefields.py:628 +#, fuzzy +#| msgid "Attendee name" +msgid "Attendee" +msgstr "اسم الحاضر" + +#: pretix/base/datasync/sourcefields.py:207 +#: pretix/base/exporters/orderlist.py:611 pretix/base/forms/questions.py:685 +#: pretix/base/models/customers.py:307 pretix/base/models/orders.py:1512 +#: pretix/base/pdf.py:223 +#: pretix/control/templates/pretixcontrol/order/index.html:571 +#: pretix/control/views/item.py:454 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:172 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:175 +msgid "Attendee email" +msgstr "البريد الإلكتروني للحاضر" + +#: pretix/base/datasync/sourcefields.py:219 +#, fuzzy +#| msgid "Attendee email" +msgid "Attendee or order email" +msgstr "البريد الإلكتروني للحاضر" + +#: pretix/base/datasync/sourcefields.py:232 pretix/base/pdf.py:186 +#: pretix/control/templates/pretixcontrol/order/index.html:595 +#: pretix/plugins/badges/exporters.py:496 +#: pretix/plugins/ticketoutputpdf/exporters.py:95 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:182 +#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:185 +msgid "Attendee company" +msgstr "شركة حاضرة" + +#: pretix/base/datasync/sourcefields.py:241 +#, fuzzy +#| msgid "Attendee address" +msgid "Attendee address street" +msgstr "عنوان الحاضر" + +#: pretix/base/datasync/sourcefields.py:250 +#, fuzzy +#| msgid "Attendee ZIP code" +msgid "Attendee address ZIP code" +msgstr "الرمز البريدي للحضور" + +#: pretix/base/datasync/sourcefields.py:259 +#, fuzzy +#| msgid "Attendee address" +msgid "Attendee address city" +msgstr "عنوان الحاضر" + +#: pretix/base/datasync/sourcefields.py:268 +#, fuzzy +#| msgid "Attendee address" +msgid "Attendee address country" +msgstr "عنوان الحاضر" + +#: pretix/base/datasync/sourcefields.py:279 pretix/base/pdf.py:344 +msgid "Invoice address company" +msgstr "شركة عنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:288 +#: pretix/base/exporters/orderlist.py:464 +#: pretix/base/exporters/orderlist.py:469 +#: pretix/base/exporters/orderlist.py:653 +#: pretix/base/exporters/orderlist.py:657 pretix/base/pdf.py:339 +msgid "Invoice address name" +msgstr "اسم عنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:317 +#: pretix/base/exporters/orderlist.py:659 pretix/base/pdf.py:349 +msgid "Invoice address street" +msgstr "شارع عنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:326 +#: pretix/base/exporters/orderlist.py:659 pretix/base/pdf.py:354 +msgid "Invoice address ZIP code" +msgstr "الرمز البريدي لعنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:335 +#: pretix/base/exporters/orderlist.py:659 pretix/base/pdf.py:359 +msgid "Invoice address city" +msgstr "مدينة عنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:344 +#: pretix/base/exporters/orderlist.py:660 pretix/base/pdf.py:369 +msgid "Invoice address country" +msgstr "بلد عنوان الفاتورة" + +#: pretix/base/datasync/sourcefields.py:353 +#, fuzzy +#| msgid "Order details" +msgid "Order email" +msgstr "تفاصيل الطلب" + +#: pretix/base/datasync/sourcefields.py:362 +#, fuzzy +#| msgid "Organizer name" +msgid "Order email domain" +msgstr "اسم المنظم" + +#: pretix/base/datasync/sourcefields.py:371 +#: pretix/base/exporters/invoices.py:201 pretix/base/exporters/invoices.py:328 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:451 +#: pretix/base/exporters/orderlist.py:583 +#: pretix/base/exporters/orderlist.py:897 pretix/base/models/orders.py:210 +#: pretix/base/notifications.py:199 pretix/base/pdf.py:103 +#: pretix/control/templates/pretixcontrol/checkin/index.html:95 +#: pretix/control/templates/pretixcontrol/order/index.html:181 +#: pretix/control/templates/pretixcontrol/order/refund_choose.html:116 +#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:22 +#: pretix/control/templates/pretixcontrol/orders/index.html:47 +#: pretix/control/templates/pretixcontrol/orders/index.html:131 +#: pretix/control/templates/pretixcontrol/organizers/customer.html:204 +#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:41 +#: pretix/control/templates/pretixcontrol/search/orders.html:48 +#: pretix/plugins/badges/exporters.py:497 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:29 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:41 +#: pretix/plugins/checkinlists/exporters.py:122 +#: pretix/plugins/checkinlists/exporters.py:493 +#: pretix/plugins/checkinlists/exporters.py:757 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:895 +#: pretix/plugins/ticketoutputpdf/exporters.py:96 +msgid "Order code" +msgstr "رمز الطلب" + +#: pretix/base/datasync/sourcefields.py:380 +#, fuzzy +#| msgid "Order date" +msgid "Event and order code" +msgstr "تاريخ الطلب" + +#: pretix/base/datasync/sourcefields.py:389 +#: pretix/base/exporters/orderlist.py:262 pretix/base/notifications.py:201 +#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:25 +#: pretix/control/templates/pretixcontrol/search/orders.html:60 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:897 +msgid "Order total" +msgstr "إجمالي الطلب" + +#: pretix/base/datasync/sourcefields.py:398 +#, fuzzy +#| msgid "Product name and variation" +msgid "Product and variation name" +msgstr "اسم المنتج ونوعه" + +#: pretix/base/datasync/sourcefields.py:410 pretix/base/exporters/items.py:57 +#: pretix/base/exporters/orderlist.py:597 +#: pretix/base/exporters/orderlist.py:908 +#: pretix/base/exporters/waitinglist.py:112 +#, fuzzy +#| msgid "Product" +msgid "Product ID" +msgstr "منتج" + +#: pretix/base/datasync/sourcefields.py:419 +#, fuzzy +#| msgid "All products" +msgid "Product is admission product" +msgstr "منتجات غير مسجلة" + +#: pretix/base/datasync/sourcefields.py:428 +#, fuzzy +#| msgid "Event name" +msgid "Event short form" +msgstr "اسم الحدث" + +#: pretix/base/datasync/sourcefields.py:437 pretix/base/exporters/events.py:57 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:450 +#: pretix/base/exporters/orderlist.py:582 +#: pretix/base/exporters/waitinglist.py:116 pretix/base/models/event.py:571 +#: pretix/base/pdf.py:233 pretix/control/forms/filter.py:1248 +#: pretix/control/forms/filter.py:1693 +#: pretix/control/templates/pretixcontrol/events/index.html:68 +#: pretix/control/templates/pretixcontrol/organizers/detail.html:64 +msgid "Event name" +msgstr "اسم الفعالية" + +#: pretix/base/datasync/sourcefields.py:446 +#: pretix/base/exporters/invoices.py:326 +msgid "Event start date" +msgstr "تاريخ بدء الفعالية" + +#: pretix/base/datasync/sourcefields.py:455 +#: pretix/base/exporters/invoices.py:350 pretix/base/pdf.py:287 +msgid "Event end date" +msgstr "تاريخ إنتهاء الفعالية" + +#: pretix/base/datasync/sourcefields.py:464 +#: pretix/base/exporters/waitinglist.py:123 +#: pretix/base/modelimport_vouchers.py:39 pretix/base/models/vouchers.py:193 +#: pretix/control/templates/pretixcontrol/vouchers/index.html:18 +#: pretix/control/templates/pretixcontrol/vouchers/index.html:114 +#: pretix/control/views/vouchers.py:119 pretix/control/views/waitinglist.py:314 +#: pretix/plugins/checkinlists/exporters.py:520 +#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:74 +#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:76 +#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:12 +#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:20 +msgid "Voucher code" +msgstr "رمز كود الخصم" + +#: pretix/base/datasync/sourcefields.py:473 pretix/base/pdf.py:116 +#, fuzzy +#| msgid "Order position number" +msgid "Order code and position number" +msgstr "رقم حالة الطلب" + +#: pretix/base/datasync/sourcefields.py:482 +#, fuzzy +#| msgid "Client secret" +msgid "Ticket price" +msgstr "كلمة سر الزبون" + +#: pretix/base/datasync/sourcefields.py:491 pretix/base/notifications.py:204 +#: pretix/control/forms/filter.py:211 pretix/control/forms/modelimport.py:85 +msgid "Order status" +msgstr "حالة الطلب" + +#: pretix/base/datasync/sourcefields.py:500 +#, fuzzy +#| msgid "Devices" +msgid "Ticket status" +msgstr "الأجهزة" + +#: pretix/base/datasync/sourcefields.py:509 +#, fuzzy +#| msgid "Purchased" +msgid "Order date and time" +msgstr "اشترى" + +#: pretix/base/datasync/sourcefields.py:518 +#, fuzzy +#| msgid "Printing date and time" +msgid "Payment date and time" +msgstr "تاريخ ووقت الطباعة" + +#: pretix/base/datasync/sourcefields.py:527 +#: pretix/base/exporters/orderlist.py:271 +#: pretix/base/exporters/orderlist.py:666 pretix/base/modelimport_orders.py:508 +#: pretix/control/templates/pretixcontrol/order/index.html:193 +#: pretix/control/templates/pretixcontrol/pdf/index.html:249 +msgid "Order locale" +msgstr "مكان الطلب" + +#: pretix/base/datasync/sourcefields.py:536 +#, fuzzy +#| msgid "Order position" +msgid "Order position ID" +msgstr "حالة الطلب" + +#: pretix/base/datasync/sourcefields.py:545 +#: pretix/base/exporters/orderlist.py:291 +#, fuzzy +#| msgid "Order time" +msgid "Order link" +msgstr "توقيت الطلب" + +#: pretix/base/datasync/sourcefields.py:560 +#, fuzzy +#| msgid "Ticket layout" +msgid "Ticket link" +msgstr "نسق تذكرة" + +#: pretix/base/datasync/sourcefields.py:578 +#, fuzzy, python-brace-format +#| msgid "Check-in list" +msgid "Check-in datetime on list {}" +msgstr "تحقق في قائمة" + +#: pretix/base/datasync/sourcefields.py:590 +#, fuzzy, python-brace-format +#| msgid "Question: %(name)s" +msgid "Question: {name}" +msgstr "سؤال: %(name)s" + +#: pretix/base/datasync/sourcefields.py:604 +#: pretix/base/datasync/sourcefields.py:614 pretix/base/settings.py:3559 +#: pretix/base/settings.py:3572 pretix/base/settings.py:3588 +#: pretix/base/settings.py:3638 pretix/base/settings.py:3651 +#: pretix/base/settings.py:3665 pretix/base/settings.py:3718 +#: pretix/base/settings.py:3739 pretix/base/settings.py:3761 +msgid "Given name" +msgstr "الاسم الاول" + +#: pretix/base/datasync/sourcefields.py:628 +#: pretix/base/datasync/sourcefields.py:638 pretix/base/settings.py:3560 +#: pretix/base/settings.py:3573 pretix/base/settings.py:3589 +#: pretix/base/settings.py:3605 pretix/base/settings.py:3622 +#: pretix/base/settings.py:3637 pretix/base/settings.py:3652 +#: pretix/base/settings.py:3666 pretix/base/settings.py:3719 +#: pretix/base/settings.py:3740 pretix/base/settings.py:3762 +msgid "Family name" +msgstr "اسم العائلة" + #: pretix/base/email.py:203 pretix/base/exporters/items.py:157 -#: pretix/base/exporters/items.py:205 pretix/control/views/main.py:322 -#: pretix/plugins/badges/apps.py:50 pretix/plugins/badges/models.py:48 +#: pretix/base/exporters/items.py:205 pretix/base/models/tax.py:381 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:27 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:44 +#: pretix/control/views/main.py:323 pretix/plugins/badges/apps.py:50 +#: pretix/plugins/badges/models.py:48 #: pretix/plugins/badges/templates/pretixplugins/badges/index.html:35 #: pretix/plugins/badges/templates/pretixplugins/badges/index.html:55 #: pretix/plugins/ticketoutputpdf/models.py:328 @@ -841,12 +1275,12 @@ msgid "Question answer file uploads" msgstr "إجابات السؤال" #: pretix/base/exporters/answers.py:55 pretix/base/exporters/json.py:52 -#: pretix/base/exporters/mail.py:53 pretix/base/exporters/orderlist.py:87 -#: pretix/base/exporters/orderlist.py:823 -#: pretix/base/exporters/orderlist.py:1002 -#: pretix/base/exporters/orderlist.py:1241 -#: pretix/plugins/reports/exporters.py:478 -#: pretix/plugins/reports/exporters.py:651 +#: pretix/base/exporters/mail.py:53 pretix/base/exporters/orderlist.py:88 +#: pretix/base/exporters/orderlist.py:841 +#: pretix/base/exporters/orderlist.py:1020 +#: pretix/base/exporters/orderlist.py:1259 +#: pretix/plugins/reports/exporters.py:489 +#: pretix/plugins/reports/exporters.py:662 #, fuzzy #| msgid "Order data" msgctxt "export_category" @@ -859,26 +1293,17 @@ msgid "" "customers while creating an order." msgstr "" -#: pretix/base/exporters/answers.py:66 pretix/base/models/items.py:1767 -#: pretix/control/navigation.py:172 -#: pretix/control/templates/pretixcontrol/items/questions.html:3 -#: pretix/control/templates/pretixcontrol/items/questions.html:5 -msgid "Questions" -msgstr "أسئلة" - -#: pretix/base/exporters/answers.py:76 pretix/base/exporters/orderlist.py:583 -#: pretix/base/exporters/orderlist.py:898 -#: pretix/base/exporters/orderlist.py:1138 pretix/base/models/checkin.py:58 +#: pretix/base/exporters/answers.py:76 pretix/base/exporters/orderlist.py:592 +#: pretix/base/exporters/orderlist.py:916 +#: pretix/base/exporters/orderlist.py:1156 pretix/base/models/checkin.py:58 #: pretix/base/models/items.py:2067 pretix/base/models/orders.py:1485 -#: pretix/base/models/orders.py:2999 pretix/base/models/vouchers.py:187 -#: pretix/base/models/waitinglist.py:61 pretix/control/forms/event.py:1610 -#: pretix/control/forms/filter.py:425 pretix/control/forms/filter.py:1901 -#: pretix/control/forms/filter.py:2123 pretix/control/forms/filter.py:2238 -#: pretix/control/forms/filter.py:2320 pretix/control/forms/filter.py:2537 -#: pretix/control/forms/item.py:333 pretix/control/forms/orders.py:348 -#: pretix/control/forms/orders.py:400 pretix/control/forms/orders.py:839 -#: pretix/control/forms/vouchers.py:118 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:99 +#: pretix/base/models/orders.py:3010 pretix/base/models/vouchers.py:190 +#: pretix/base/models/waitinglist.py:61 pretix/control/forms/event.py:1619 +#: pretix/control/forms/filter.py:425 pretix/control/forms/filter.py:1897 +#: pretix/control/forms/filter.py:2119 pretix/control/forms/filter.py:2234 +#: pretix/control/forms/filter.py:2316 pretix/control/forms/filter.py:2533 +#: pretix/control/forms/orders.py:360 pretix/control/forms/orders.py:849 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:106 #: pretix/control/templates/pretixcontrol/items/quotas.html:51 #: pretix/control/templates/pretixcontrol/order/change.html:108 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:43 @@ -888,37 +1313,36 @@ msgstr "أسئلة" #: pretix/control/templates/pretixcontrol/vouchers/index.html:140 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:167 #: pretix/control/views/waitinglist.py:318 -#: pretix/plugins/checkinlists/exporters.py:511 -#: pretix/plugins/checkinlists/exporters.py:700 -#: pretix/plugins/sendmail/forms.py:137 pretix/plugins/sendmail/forms.py:282 -#: pretix/plugins/sendmail/forms.py:363 +#: pretix/plugins/checkinlists/exporters.py:512 +#: pretix/plugins/checkinlists/exporters.py:701 +#: pretix/plugins/sendmail/forms.py:137 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:32 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:48 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:125 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:127 #: pretix/presale/templates/pretixpresale/event/fragment_change_form.html:20 msgctxt "subevent" msgid "Date" msgstr "تاريخ" #: pretix/base/exporters/answers.py:79 pretix/base/exporters/answers.py:88 -#: pretix/control/forms/checkin.py:83 pretix/control/forms/event.py:1611 +#: pretix/control/forms/checkin.py:83 pretix/control/forms/event.py:1620 #: pretix/control/forms/filter.py:428 pretix/control/forms/filter.py:455 -#: pretix/control/forms/filter.py:1904 pretix/control/forms/filter.py:1937 -#: pretix/control/forms/filter.py:2126 pretix/control/forms/filter.py:2146 -#: pretix/control/forms/filter.py:2241 pretix/control/forms/filter.py:2257 -#: pretix/control/forms/filter.py:2323 pretix/control/forms/filter.py:2358 -#: pretix/control/forms/filter.py:2540 pretix/control/forms/filter.py:2555 -#: pretix/control/forms/orders.py:841 pretix/control/forms/orders.py:1003 +#: pretix/control/forms/filter.py:1900 pretix/control/forms/filter.py:1933 +#: pretix/control/forms/filter.py:2122 pretix/control/forms/filter.py:2142 +#: pretix/control/forms/filter.py:2237 pretix/control/forms/filter.py:2253 +#: pretix/control/forms/filter.py:2319 pretix/control/forms/filter.py:2354 +#: pretix/control/forms/filter.py:2536 pretix/control/forms/filter.py:2551 +#: pretix/control/forms/orders.py:851 pretix/control/forms/orders.py:1013 #: pretix/control/templates/pretixcontrol/event/fragment_subevent_choice_simple.html:5 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:67 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:129 #: pretix/plugins/sendmail/forms.py:99 pretix/plugins/sendmail/forms.py:173 -#: pretix/plugins/sendmail/forms.py:351 +#: pretix/plugins/sendmail/forms.py:350 msgctxt "subevent" msgid "All dates" msgstr "كل التواريخ" -#: pretix/base/exporters/customers.py:49 pretix/control/navigation.py:606 +#: pretix/base/exporters/customers.py:49 pretix/control/navigation.py:618 #: pretix/control/templates/pretixcontrol/organizers/edit.html:132 msgid "Customer accounts" msgstr "حسابات العملاء" @@ -937,7 +1361,7 @@ msgstr "" #: pretix/base/exporters/customers.py:64 pretix/base/models/customers.py:82 #: pretix/control/templates/pretixcontrol/organizers/customer.html:29 #: pretix/control/templates/pretixcontrol/organizers/customers.html:54 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:36 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:37 #: pretix/presale/templates/pretixpresale/organizers/customer_base.html:37 #, fuzzy #| msgctxt "invoice" @@ -961,50 +1385,50 @@ msgstr "مقدم خدمة السداد" msgid "External identifier" msgstr "معرف داخلي" -#: pretix/base/exporters/customers.py:68 pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:445 -#: pretix/base/exporters/orderlist.py:578 +#: pretix/base/exporters/customers.py:68 pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:454 +#: pretix/base/exporters/orderlist.py:587 #: pretix/base/exporters/waitinglist.py:110 -#: pretix/base/modelimport_orders.py:72 pretix/base/models/customers.py:95 +#: pretix/base/modelimport_orders.py:87 pretix/base/models/customers.py:95 #: pretix/base/models/customers.py:396 pretix/base/models/items.py:1659 #: pretix/base/models/orders.py:250 pretix/base/models/waitinglist.py:80 -#: pretix/base/pdf.py:320 +#: pretix/base/pdf.py:329 #: pretix/control/templates/pretixcontrol/order/index.html:257 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:163 #: pretix/control/views/waitinglist.py:314 -#: pretix/plugins/checkinlists/exporters.py:508 -#: pretix/presale/checkoutflow.py:1538 pretix/presale/forms/checkout.py:84 +#: pretix/plugins/checkinlists/exporters.py:509 +#: pretix/presale/checkoutflow.py:1548 pretix/presale/forms/checkout.py:84 #: pretix/presale/forms/waitinglist.py:80 #: pretix/presale/templates/pretixpresale/event/order.html:304 msgid "Phone number" msgstr "رقم الجوال" #: pretix/base/exporters/customers.py:69 pretix/base/models/auth.py:246 -#: pretix/base/models/customers.py:97 pretix/base/models/orders.py:3270 -#: pretix/base/settings.py:3640 pretix/base/settings.py:3652 +#: pretix/base/models/customers.py:97 pretix/base/models/orders.py:3281 +#: pretix/base/settings.py:3692 pretix/base/settings.py:3704 #: pretix/control/templates/pretixcontrol/users/index.html:47 msgid "Full name" msgstr "الاسم الكامل" #: pretix/base/exporters/customers.py:74 pretix/base/exporters/invoices.py:206 #: pretix/base/exporters/invoices.py:214 pretix/base/exporters/invoices.py:332 -#: pretix/base/exporters/invoices.py:340 pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/waitinglist.py:108 pretix/base/forms/questions.py:1227 +#: pretix/base/exporters/invoices.py:340 pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/waitinglist.py:108 pretix/base/forms/questions.py:1247 #: pretix/base/models/devices.py:65 pretix/base/models/devices.py:127 -#: pretix/base/models/event.py:1493 pretix/base/models/event.py:1735 +#: pretix/base/models/event.py:1500 pretix/base/models/event.py:1742 #: pretix/base/models/items.py:2071 pretix/base/models/items.py:2244 -#: pretix/base/models/memberships.py:41 pretix/base/models/organizer.py:75 -#: pretix/base/models/organizer.py:535 pretix/base/models/seating.py:85 -#: pretix/base/models/waitinglist.py:69 pretix/base/settings.py:3265 -#: pretix/base/settings.py:3275 pretix/base/settings.py:3629 -#: pretix/control/forms/filter.py:625 pretix/control/forms/item.py:445 -#: pretix/control/forms/organizer.py:917 +#: pretix/base/models/memberships.py:41 pretix/base/models/organizer.py:77 +#: pretix/base/models/organizer.py:601 pretix/base/models/seating.py:85 +#: pretix/base/models/waitinglist.py:69 pretix/base/settings.py:3317 +#: pretix/base/settings.py:3327 pretix/base/settings.py:3681 +#: pretix/control/forms/filter.py:625 pretix/control/forms/item.py:446 +#: pretix/control/forms/organizer.py:918 #: pretix/control/templates/pretixcontrol/checkin/index.html:109 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:92 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:99 #: pretix/control/templates/pretixcontrol/event/tax_index.html:26 #: pretix/control/templates/pretixcontrol/oauth/app_list.html:12 #: pretix/control/templates/pretixcontrol/oauth/authorized.html:17 -#: pretix/control/templates/pretixcontrol/order/index.html:947 +#: pretix/control/templates/pretixcontrol/order/index.html:999 #: pretix/control/templates/pretixcontrol/organizers/customer.html:58 #: pretix/control/templates/pretixcontrol/organizers/customers.html:62 #: pretix/control/templates/pretixcontrol/organizers/devices.html:77 @@ -1016,16 +1440,16 @@ msgstr "الاسم الكامل" #: pretix/control/templates/pretixcontrol/waitinglist/index.html:159 #: pretix/control/views/waitinglist.py:314 pretix/plugins/badges/models.py:53 #: pretix/plugins/badges/templates/pretixplugins/badges/index.html:34 -#: pretix/plugins/checkinlists/exporters.py:375 -#: pretix/plugins/checkinlists/exporters.py:760 -#: pretix/plugins/reports/exporters.py:885 +#: pretix/plugins/checkinlists/exporters.py:376 +#: pretix/plugins/checkinlists/exporters.py:761 +#: pretix/plugins/reports/exporters.py:896 #: pretix/plugins/ticketoutputpdf/models.py:333 #: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:32 #: pretix/presale/forms/customer.py:179 pretix/presale/forms/customer.py:483 #: pretix/presale/forms/waitinglist.py:68 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:87 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:139 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:34 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:86 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:142 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:35 #: pretix/presale/templates/pretixpresale/event/order.html:312 msgid "Name" msgstr "اسم" @@ -1051,7 +1475,7 @@ msgstr "تاريخ التسجيل" #: pretix/base/exporters/customers.py:81 pretix/base/exporters/invoices.py:205 #: pretix/base/exporters/waitinglist.py:120 pretix/base/models/auth.py:258 #: pretix/base/models/customers.py:106 pretix/base/models/exports.py:54 -#: pretix/control/forms/event.py:1616 pretix/control/forms/exports.py:49 +#: pretix/control/forms/event.py:1625 pretix/control/forms/exports.py:49 #: pretix/control/forms/exports.py:88 pretix/control/views/waitinglist.py:315 msgid "Language" msgstr "اللغة" @@ -1081,49 +1505,51 @@ msgstr "" #: pretix/base/exporters/items.py:213 pretix/base/exporters/items.py:214 #: pretix/base/exporters/items.py:215 pretix/base/exporters/items.py:218 #: pretix/base/exporters/items.py:221 pretix/base/exporters/items.py:222 -#: pretix/base/exporters/items.py:223 pretix/base/exporters/orderlist.py:393 -#: pretix/base/exporters/orderlist.py:398 -#: pretix/base/exporters/orderlist.py:742 -#: pretix/base/exporters/orderlist.py:765 -#: pretix/base/exporters/orderlist.py:797 -#: pretix/base/exporters/orderlist.py:1381 -#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:187 -#: pretix/base/modelimport.py:194 pretix/base/models/orders.py:1401 -#: pretix/control/forms/filter.py:172 pretix/control/forms/filter.py:520 -#: pretix/control/forms/filter.py:707 pretix/control/forms/item.py:614 -#: pretix/control/forms/subevents.py:119 pretix/control/views/item.py:733 -#: pretix/control/views/vouchers.py:139 pretix/control/views/vouchers.py:140 -#: pretix/plugins/checkinlists/exporters.py:600 -#: pretix/plugins/checkinlists/exporters.py:603 -#: pretix/plugins/checkinlists/exporters.py:630 -#: pretix/plugins/checkinlists/exporters.py:646 -#: pretix/plugins/checkinlists/exporters.py:715 -#: pretix/plugins/checkinlists/exporters.py:822 +#: pretix/base/exporters/items.py:223 pretix/base/exporters/orderlist.py:395 +#: pretix/base/exporters/orderlist.py:400 +#: pretix/base/exporters/orderlist.py:752 +#: pretix/base/exporters/orderlist.py:775 +#: pretix/base/exporters/orderlist.py:807 +#: pretix/base/exporters/orderlist.py:1399 +#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:194 +#: pretix/base/modelimport.py:201 pretix/base/models/orders.py:1401 +#: pretix/base/models/orders.py:3427 pretix/control/forms/filter.py:172 +#: pretix/control/forms/filter.py:520 pretix/control/forms/filter.py:707 +#: pretix/control/forms/item.py:615 pretix/control/forms/subevents.py:119 +#: pretix/control/views/item.py:733 pretix/control/views/vouchers.py:139 +#: pretix/control/views/vouchers.py:140 +#: pretix/plugins/checkinlists/exporters.py:601 +#: pretix/plugins/checkinlists/exporters.py:604 +#: pretix/plugins/checkinlists/exporters.py:631 +#: pretix/plugins/checkinlists/exporters.py:647 +#: pretix/plugins/checkinlists/exporters.py:716 #: pretix/plugins/checkinlists/exporters.py:823 #: pretix/plugins/checkinlists/exporters.py:824 +#: pretix/plugins/checkinlists/exporters.py:825 msgid "Yes" msgstr "نعم" #: pretix/base/exporters/customers.py:100 #: pretix/base/exporters/customers.py:101 pretix/base/exporters/events.py:83 -#: pretix/base/exporters/invoices.py:305 pretix/base/exporters/orderlist.py:393 -#: pretix/base/exporters/orderlist.py:398 -#: pretix/base/exporters/orderlist.py:765 -#: pretix/base/exporters/orderlist.py:797 -#: pretix/base/exporters/orderlist.py:1381 -#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:186 -#: pretix/base/modelimport.py:196 pretix/base/models/orders.py:1403 -#: pretix/control/forms/filter.py:172 pretix/control/forms/filter.py:521 -#: pretix/control/forms/filter.py:708 pretix/control/forms/item.py:615 -#: pretix/control/forms/subevents.py:120 pretix/control/views/item.py:733 -#: pretix/control/views/vouchers.py:139 pretix/control/views/vouchers.py:140 -#: pretix/plugins/checkinlists/exporters.py:600 -#: pretix/plugins/checkinlists/exporters.py:603 -#: pretix/plugins/checkinlists/exporters.py:630 -#: pretix/plugins/checkinlists/exporters.py:715 -#: pretix/plugins/checkinlists/exporters.py:822 +#: pretix/base/exporters/invoices.py:305 pretix/base/exporters/orderlist.py:395 +#: pretix/base/exporters/orderlist.py:400 +#: pretix/base/exporters/orderlist.py:775 +#: pretix/base/exporters/orderlist.py:807 +#: pretix/base/exporters/orderlist.py:1399 +#: pretix/base/exporters/reusablemedia.py:63 pretix/base/modelimport.py:193 +#: pretix/base/modelimport.py:203 pretix/base/models/orders.py:1403 +#: pretix/base/models/orders.py:3429 pretix/control/forms/filter.py:172 +#: pretix/control/forms/filter.py:521 pretix/control/forms/filter.py:708 +#: pretix/control/forms/item.py:616 pretix/control/forms/subevents.py:120 +#: pretix/control/views/item.py:733 pretix/control/views/vouchers.py:139 +#: pretix/control/views/vouchers.py:140 +#: pretix/plugins/checkinlists/exporters.py:601 +#: pretix/plugins/checkinlists/exporters.py:604 +#: pretix/plugins/checkinlists/exporters.py:631 +#: pretix/plugins/checkinlists/exporters.py:716 #: pretix/plugins/checkinlists/exporters.py:823 #: pretix/plugins/checkinlists/exporters.py:824 +#: pretix/plugins/checkinlists/exporters.py:825 msgid "No" msgstr "لا" @@ -1146,14 +1572,14 @@ msgid "Event ticket {event}-{code}" msgstr "تذكرة الفعالية {event}-{code}" #: pretix/base/exporters/dekodi.py:234 pretix/base/exporters/invoices.py:74 -#: pretix/base/exporters/orderlist.py:128 -#: pretix/base/exporters/orderlist.py:837 -#: pretix/base/exporters/orderlist.py:1191 -#: pretix/plugins/checkinlists/exporters.py:88 -#: pretix/plugins/checkinlists/exporters.py:864 -#: pretix/plugins/reports/accountingreport.py:74 -#: pretix/plugins/reports/exporters.py:461 -#: pretix/plugins/reports/exporters.py:698 +#: pretix/base/exporters/orderlist.py:129 +#: pretix/base/exporters/orderlist.py:855 +#: pretix/base/exporters/orderlist.py:1209 +#: pretix/plugins/checkinlists/exporters.py:89 +#: pretix/plugins/checkinlists/exporters.py:865 +#: pretix/plugins/reports/accountingreport.py:75 +#: pretix/plugins/reports/exporters.py:472 +#: pretix/plugins/reports/exporters.py:709 #: pretix/plugins/ticketoutputpdf/exporters.py:85 #, fuzzy #| msgid "Date and time" @@ -1191,29 +1617,17 @@ msgid "" "account." msgstr "" -#: pretix/base/exporters/events.py:57 pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:441 -#: pretix/base/exporters/orderlist.py:573 -#: pretix/base/exporters/waitinglist.py:116 pretix/base/models/event.py:572 -#: pretix/base/pdf.py:224 pretix/control/forms/filter.py:1248 -#: pretix/control/forms/filter.py:1250 pretix/control/forms/filter.py:1695 -#: pretix/control/forms/filter.py:1697 -#: pretix/control/templates/pretixcontrol/events/index.html:68 -#: pretix/control/templates/pretixcontrol/organizers/detail.html:64 -msgid "Event name" -msgstr "اسم الفعالية" - -#: pretix/base/exporters/events.py:58 pretix/base/models/event.py:588 -#: pretix/base/models/organizer.py:91 +#: pretix/base/exporters/events.py:58 pretix/base/models/event.py:587 +#: pretix/base/models/organizer.py:93 #: pretix/control/templates/pretixcontrol/organizers/index.html:47 msgid "Short form" msgstr "نموذج قصير" -#: pretix/base/exporters/events.py:59 pretix/base/models/event.py:590 +#: pretix/base/exporters/events.py:59 pretix/base/models/event.py:589 msgid "Shop is live" msgstr "المتجر نشط" -#: pretix/base/exporters/events.py:60 pretix/base/models/event.py:592 +#: pretix/base/exporters/events.py:60 pretix/base/models/event.py:591 msgid "Event currency" msgstr "عملة الفعالية" @@ -1222,61 +1636,65 @@ msgstr "عملة الفعالية" msgid "Timezone" msgstr "المنطقة الزمنية" -#: pretix/base/exporters/events.py:62 pretix/base/models/event.py:595 -#: pretix/base/models/event.py:1495 pretix/base/settings.py:3263 -#: pretix/base/settings.py:3273 pretix/control/forms/subevents.py:487 +#: pretix/base/exporters/events.py:62 pretix/base/models/event.py:594 +#: pretix/base/models/event.py:1502 pretix/base/settings.py:3315 +#: pretix/base/settings.py:3325 pretix/control/forms/subevents.py:483 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:268 msgid "Event start time" msgstr "وقت بداية الفعالية" -#: pretix/base/exporters/events.py:63 pretix/base/models/event.py:597 -#: pretix/base/models/event.py:1497 pretix/base/pdf.py:286 -#: pretix/control/forms/subevents.py:492 +#: pretix/base/exporters/events.py:63 pretix/base/models/event.py:596 +#: pretix/base/models/event.py:1504 pretix/base/pdf.py:295 +#: pretix/control/forms/subevents.py:488 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:270 msgid "Event end time" msgstr "وقت نهاية الفعالية" -#: pretix/base/exporters/events.py:64 pretix/base/models/event.py:599 -#: pretix/base/models/event.py:1499 pretix/control/forms/subevents.py:497 +#: pretix/base/exporters/events.py:64 pretix/base/models/event.py:598 +#: pretix/base/models/event.py:1506 pretix/control/forms/subevents.py:493 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:274 msgid "Admission time" msgstr "وقت قبول التسجيل" -#: pretix/base/exporters/events.py:65 pretix/base/models/event.py:611 -#: pretix/base/models/event.py:1508 pretix/control/forms/subevents.py:93 +#: pretix/base/exporters/events.py:65 pretix/base/models/event.py:610 +#: pretix/base/models/event.py:1515 pretix/control/forms/subevents.py:93 msgid "Start of presale" msgstr "بداية عرض ما قبل البيع" -#: pretix/base/exporters/events.py:66 pretix/base/models/event.py:605 -#: pretix/base/models/event.py:1502 pretix/control/forms/subevents.py:99 +#: pretix/base/exporters/events.py:66 pretix/base/models/event.py:604 +#: pretix/base/models/event.py:1509 pretix/control/forms/subevents.py:99 msgid "End of presale" msgstr "نهاية عرض ما قبل البيع" #: pretix/base/exporters/events.py:67 pretix/base/exporters/invoices.py:351 -#: pretix/base/models/event.py:617 pretix/base/models/event.py:1514 +#: pretix/base/models/event.py:616 pretix/base/models/event.py:1521 msgid "Location" msgstr "الموقع" -#: pretix/base/exporters/events.py:68 pretix/base/models/event.py:625 -#: pretix/base/models/event.py:1517 +#: pretix/base/exporters/events.py:68 pretix/base/models/event.py:624 +#: pretix/base/models/event.py:1524 +#: pretix/control/templates/pretixcontrol/event/fragment_geodata.html:18 +#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:54 msgid "Latitude" msgstr "خط العرض" -#: pretix/base/exporters/events.py:69 pretix/base/models/event.py:633 -#: pretix/base/models/event.py:1525 +#: pretix/base/exporters/events.py:69 pretix/base/models/event.py:632 +#: pretix/base/models/event.py:1532 +#: pretix/control/templates/pretixcontrol/event/fragment_geodata.html:28 +#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:64 msgid "Longitude" msgstr "خط الطول" -#: pretix/base/exporters/events.py:70 pretix/base/models/event.py:645 -#: pretix/base/models/event.py:1540 -#: pretix/control/templates/pretixcontrol/event/index.html:128 -#: pretix/control/templates/pretixcontrol/order/index.html:991 +#: pretix/base/exporters/events.py:70 pretix/base/models/event.py:644 +#: pretix/base/models/event.py:1547 +#: pretix/control/templates/pretixcontrol/event/index.html:137 +#: pretix/control/templates/pretixcontrol/order/index.html:1049 msgid "Internal comment" msgstr "ملاحظة داخلية" #: pretix/base/exporters/invoices.py:82 pretix/base/models/orders.py:1753 -#: pretix/base/models/orders.py:2162 pretix/control/forms/filter.py:204 -#: pretix/control/forms/filter.py:1024 pretix/control/forms/filter.py:2278 +#: pretix/base/models/orders.py:2173 pretix/control/forms/filter.py:204 +#: pretix/control/forms/filter.py:1024 pretix/control/forms/filter.py:2274 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:9 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:14 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:44 @@ -1291,7 +1709,7 @@ msgstr "مقدم خدمة السداد" #: pretix/base/exporters/invoices.py:84 pretix/base/exporters/invoices.py:86 #: pretix/control/forms/filter.py:206 pretix/control/forms/filter.py:1026 -#: pretix/control/forms/filter.py:2280 +#: pretix/control/forms/filter.py:2276 msgid "All payment providers" msgstr "جميع مزودي خدمات السداد" @@ -1324,9 +1742,9 @@ msgid "" "one with a line for every position of every invoice." msgstr "" -#: pretix/base/exporters/invoices.py:191 pretix/base/shredder.py:576 +#: pretix/base/exporters/invoices.py:191 pretix/base/shredder.py:579 #: pretix/control/templates/pretixcontrol/order/index.html:268 -#: pretix/control/templates/pretixcontrol/order/index.html:341 +#: pretix/control/templates/pretixcontrol/order/index.html:381 #: pretix/control/templates/pretixcontrol/organizers/edit.html:312 #: pretix/presale/templates/pretixpresale/event/order.html:236 #: pretix/presale/templates/pretixpresale/event/order.html:257 @@ -1342,55 +1760,28 @@ msgid "Invoice number" msgstr "رقم الفاتورة" #: pretix/base/exporters/invoices.py:200 pretix/base/exporters/invoices.py:327 -#: pretix/base/exporters/orderlist.py:1214 -#: pretix/base/exporters/orderlist.py:1259 +#: pretix/base/exporters/orderlist.py:1232 +#: pretix/base/exporters/orderlist.py:1277 #: pretix/base/exporters/waitinglist.py:107 pretix/base/forms/widgets.py:213 #: pretix/base/models/items.py:1655 pretix/base/models/orders.py:259 -#: pretix/base/models/orders.py:2974 pretix/base/models/orders.py:3094 +#: pretix/base/models/orders.py:2985 pretix/base/models/orders.py:3105 +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:25 #: pretix/control/templates/pretixcontrol/order/transactions.html:19 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:72 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:17 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:11 -#: pretix/plugins/checkinlists/exporters.py:752 +#: pretix/plugins/checkinlists/exporters.py:753 #: pretix/presale/templates/pretixpresale/event/fragment_giftcard_history.html:6 #: pretix/presale/templates/pretixpresale/organizers/calendar_day.html:58 msgid "Date" msgstr "التاريخ" -#: pretix/base/exporters/invoices.py:201 pretix/base/exporters/invoices.py:328 -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:442 -#: pretix/base/exporters/orderlist.py:574 -#: pretix/base/exporters/orderlist.py:879 pretix/base/models/orders.py:210 -#: pretix/base/notifications.py:199 pretix/base/pdf.py:103 -#: pretix/control/templates/pretixcontrol/checkin/index.html:95 -#: pretix/control/templates/pretixcontrol/order/index.html:181 -#: pretix/control/templates/pretixcontrol/order/refund_choose.html:116 -#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:22 -#: pretix/control/templates/pretixcontrol/orders/index.html:47 -#: pretix/control/templates/pretixcontrol/orders/index.html:131 -#: pretix/control/templates/pretixcontrol/organizers/customer.html:204 -#: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:41 -#: pretix/control/templates/pretixcontrol/search/orders.html:48 -#: pretix/plugins/badges/exporters.py:497 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:29 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:41 -#: pretix/plugins/checkinlists/exporters.py:121 -#: pretix/plugins/checkinlists/exporters.py:492 -#: pretix/plugins/checkinlists/exporters.py:756 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:884 -#: pretix/plugins/ticketoutputpdf/exporters.py:96 -msgid "Order code" -msgstr "رمز الطلب" - #: pretix/base/exporters/invoices.py:202 pretix/base/exporters/invoices.py:329 #: pretix/base/forms/auth.py:160 pretix/base/modelimport_orders.py:59 #: pretix/base/models/customers.py:395 pretix/base/models/waitinglist.py:76 #: pretix/control/forms/filter.py:553 #: pretix/control/templates/pretixcontrol/users/index.html:42 #: pretix/control/views/waitinglist.py:314 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:163 msgid "Email address" msgstr "عنوان البريد الإلكتروني" @@ -1413,68 +1804,68 @@ msgid "Invoice sender:" msgstr "مرسل الفاتورة:" #: pretix/base/exporters/invoices.py:207 pretix/base/exporters/invoices.py:333 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:604 pretix/base/forms/questions.py:704 -#: pretix/base/modelimport_orders.py:206 pretix/base/modelimport_orders.py:352 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:613 pretix/base/forms/questions.py:704 +#: pretix/base/modelimport_orders.py:232 pretix/base/modelimport_orders.py:386 #: pretix/base/models/customers.py:311 pretix/base/models/orders.py:1539 -#: pretix/base/models/orders.py:3272 pretix/control/forms/filter.py:629 +#: pretix/base/models/orders.py:3283 pretix/control/forms/filter.py:629 #: pretix/control/forms/filter.py:660 -#: pretix/control/templates/pretixcontrol/order/index.html:949 -#: pretix/plugins/checkinlists/exporters.py:534 -#: pretix/plugins/reports/exporters.py:840 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:89 +#: pretix/control/templates/pretixcontrol/order/index.html:1001 +#: pretix/plugins/checkinlists/exporters.py:535 +#: pretix/plugins/reports/exporters.py:851 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:88 #: pretix/presale/templates/pretixpresale/event/order.html:316 msgid "Address" msgstr "العنوان" #: pretix/base/exporters/invoices.py:208 pretix/base/exporters/invoices.py:216 #: pretix/base/exporters/invoices.py:334 pretix/base/exporters/invoices.py:342 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:605 pretix/base/forms/questions.py:715 -#: pretix/base/modelimport_orders.py:217 pretix/base/modelimport_orders.py:363 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:614 pretix/base/forms/questions.py:715 +#: pretix/base/modelimport_orders.py:244 pretix/base/modelimport_orders.py:397 #: pretix/base/models/customers.py:312 pretix/base/models/orders.py:1540 -#: pretix/base/models/orders.py:3273 pretix/base/settings.py:1124 +#: pretix/base/models/orders.py:3284 pretix/base/settings.py:1162 #: pretix/control/forms/filter.py:633 pretix/control/forms/filter.py:664 #: pretix/control/views/item.py:488 -#: pretix/plugins/checkinlists/exporters.py:535 -#: pretix/plugins/reports/exporters.py:841 +#: pretix/plugins/checkinlists/exporters.py:536 +#: pretix/plugins/reports/exporters.py:852 msgid "ZIP code" msgstr "الرمز البريدي" #: pretix/base/exporters/invoices.py:209 pretix/base/exporters/invoices.py:217 #: pretix/base/exporters/invoices.py:335 pretix/base/exporters/invoices.py:343 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:606 pretix/base/forms/questions.py:723 -#: pretix/base/modelimport_orders.py:228 pretix/base/modelimport_orders.py:374 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:615 pretix/base/forms/questions.py:723 +#: pretix/base/modelimport_orders.py:256 pretix/base/modelimport_orders.py:408 #: pretix/base/models/customers.py:313 pretix/base/models/orders.py:1541 -#: pretix/base/models/orders.py:3274 pretix/base/settings.py:1136 +#: pretix/base/models/orders.py:3285 pretix/base/settings.py:1174 #: pretix/control/forms/filter.py:638 pretix/control/forms/filter.py:669 #: pretix/control/views/item.py:498 -#: pretix/plugins/checkinlists/exporters.py:536 -#: pretix/plugins/reports/exporters.py:842 +#: pretix/plugins/checkinlists/exporters.py:537 +#: pretix/plugins/reports/exporters.py:853 msgid "City" msgstr "المدينة" #: pretix/base/exporters/invoices.py:210 pretix/base/exporters/invoices.py:218 #: pretix/base/exporters/invoices.py:336 pretix/base/exporters/invoices.py:344 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:607 pretix/base/forms/questions.py:735 -#: pretix/base/modelimport_orders.py:244 pretix/base/modelimport_orders.py:390 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:616 pretix/base/forms/questions.py:735 +#: pretix/base/modelimport_orders.py:274 pretix/base/modelimport_orders.py:425 #: pretix/base/models/customers.py:314 pretix/base/models/orders.py:1542 -#: pretix/base/models/orders.py:3275 pretix/base/models/orders.py:3276 -#: pretix/base/settings.py:1145 pretix/control/forms/filter.py:643 +#: pretix/base/models/orders.py:3286 pretix/base/models/orders.py:3287 +#: pretix/base/settings.py:1183 pretix/control/forms/filter.py:643 #: pretix/control/forms/filter.py:674 -#: pretix/control/templates/pretixcontrol/order/index.html:953 +#: pretix/control/templates/pretixcontrol/order/index.html:1005 #: pretix/control/views/item.py:508 -#: pretix/plugins/checkinlists/exporters.py:537 -#: pretix/plugins/reports/exporters.py:792 -#: pretix/plugins/reports/exporters.py:837 -#: pretix/plugins/reports/exporters.py:886 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:93 +#: pretix/plugins/checkinlists/exporters.py:538 +#: pretix/plugins/reports/exporters.py:803 +#: pretix/plugins/reports/exporters.py:848 +#: pretix/plugins/reports/exporters.py:897 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:92 #: pretix/presale/templates/pretixpresale/event/order.html:320 msgid "Country" msgstr "الدولة" @@ -1485,14 +1876,14 @@ msgstr "الرقم الضريبي" #: pretix/base/exporters/invoices.py:212 pretix/base/exporters/invoices.py:220 #: pretix/base/exporters/invoices.py:338 pretix/base/exporters/invoices.py:346 -#: pretix/base/exporters/orderlist.py:270 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:653 pretix/base/modelimport_orders.py:288 -#: pretix/base/models/orders.py:3279 -#: pretix/control/templates/pretixcontrol/order/index.html:960 -#: pretix/plugins/reports/exporters.py:844 -#: pretix/plugins/reports/exporters.py:886 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:100 +#: pretix/base/exporters/orderlist.py:271 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:662 pretix/base/modelimport_orders.py:321 +#: pretix/base/models/orders.py:3290 +#: pretix/control/templates/pretixcontrol/order/index.html:1012 +#: pretix/plugins/reports/exporters.py:855 +#: pretix/plugins/reports/exporters.py:897 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:99 #: pretix/presale/templates/pretixpresale/event/order.html:327 msgid "VAT ID" msgstr "رقم تعريف ضريبة القيمة المضافة" @@ -1511,18 +1902,18 @@ msgid "Invoice recipient:" msgstr "مستلم الفاتورة:" #: pretix/base/exporters/invoices.py:213 pretix/base/exporters/invoices.py:339 -#: pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:454 -#: pretix/base/exporters/orderlist.py:603 -#: pretix/base/exporters/orderlist.py:643 pretix/base/forms/questions.py:696 -#: pretix/base/modelimport_orders.py:176 pretix/base/modelimport_orders.py:341 +#: pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:463 +#: pretix/base/exporters/orderlist.py:612 +#: pretix/base/exporters/orderlist.py:652 pretix/base/forms/questions.py:696 +#: pretix/base/modelimport_orders.py:199 pretix/base/modelimport_orders.py:375 #: pretix/control/forms/filter.py:621 pretix/control/forms/filter.py:656 -#: pretix/control/templates/pretixcontrol/order/index.html:945 +#: pretix/control/templates/pretixcontrol/order/index.html:997 #: pretix/control/views/item.py:466 -#: pretix/plugins/checkinlists/exporters.py:518 -#: pretix/plugins/reports/exporters.py:839 -#: pretix/plugins/reports/exporters.py:885 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:84 +#: pretix/plugins/checkinlists/exporters.py:519 +#: pretix/plugins/reports/exporters.py:850 +#: pretix/plugins/reports/exporters.py:896 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:83 #: pretix/presale/templates/pretixpresale/event/order.html:308 msgid "Company" msgstr "الشركة" @@ -1532,36 +1923,36 @@ msgid "Street address" msgstr "عنوان الشارع" #: pretix/base/exporters/invoices.py:219 pretix/base/exporters/invoices.py:345 -#: pretix/base/exporters/orderlist.py:269 -#: pretix/base/exporters/orderlist.py:462 -#: pretix/base/exporters/orderlist.py:608 pretix/base/forms/questions.py:760 -#: pretix/base/forms/questions.py:1177 pretix/base/modelimport_orders.py:263 +#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:471 +#: pretix/base/exporters/orderlist.py:617 pretix/base/forms/questions.py:760 +#: pretix/base/forms/questions.py:1197 pretix/base/modelimport_orders.py:295 #: pretix/base/models/customers.py:315 pretix/base/models/orders.py:1543 -#: pretix/base/models/orders.py:3278 pretix/base/views/js_helpers.py:44 -#: pretix/control/templates/pretixcontrol/order/index.html:956 -#: pretix/plugins/checkinlists/exporters.py:538 -#: pretix/plugins/reports/exporters.py:843 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:96 +#: pretix/base/models/orders.py:3289 pretix/base/views/js_helpers.py:48 +#: pretix/control/templates/pretixcontrol/order/index.html:1008 +#: pretix/plugins/checkinlists/exporters.py:539 +#: pretix/plugins/reports/exporters.py:854 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:95 #: pretix/presale/templates/pretixpresale/event/order.html:323 msgctxt "address" msgid "State" msgstr "المنطقة" #: pretix/base/exporters/invoices.py:221 pretix/base/exporters/invoices.py:347 -#: pretix/base/models/orders.py:3288 pretix/base/models/orders.py:3323 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:104 +#: pretix/base/models/orders.py:3299 pretix/base/models/orders.py:3355 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:103 msgid "Beneficiary" msgstr "المستفيد" #: pretix/base/exporters/invoices.py:222 pretix/base/exporters/invoices.py:348 -#: pretix/base/modelimport_orders.py:299 pretix/base/models/orders.py:3283 -#: pretix/control/templates/pretixcontrol/order/index.html:980 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:112 +#: pretix/base/modelimport_orders.py:333 pretix/base/models/orders.py:3294 +#: pretix/control/templates/pretixcontrol/order/index.html:1033 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:111 msgid "Internal reference" msgstr "المرجع الداخلي" #: pretix/base/exporters/invoices.py:223 pretix/base/models/tax.py:162 -#: pretix/control/forms/event.py:1506 +#: pretix/control/forms/event.py:1515 msgid "Reverse charge" msgstr "التكلفة العكسية" @@ -1586,11 +1977,10 @@ msgid "Payment matching IDs" msgstr "معرفات مطابقة الدفع" #: pretix/base/exporters/invoices.py:229 pretix/base/exporters/invoices.py:349 -#: pretix/base/exporters/orderlist.py:289 -#: pretix/base/exporters/orderlist.py:466 -#: pretix/base/exporters/orderlist.py:661 +#: pretix/base/exporters/orderlist.py:290 +#: pretix/base/exporters/orderlist.py:475 +#: pretix/base/exporters/orderlist.py:670 pretix/base/plugins.py:137 #: pretix/control/templates/pretixcontrol/event/payment.html:11 -#: pretix/control/views/event.py:382 msgid "Payment providers" msgstr "مزودي خدمات الدفع" @@ -1599,6 +1989,7 @@ msgid "Cancellation" msgstr "إلغاء" #: pretix/base/exporters/invoices.py:285 pretix/base/exporters/invoices.py:388 +#: pretix/control/templates/pretixcontrol/event/mail.html:120 #: pretix/control/templates/pretixcontrol/order/index.html:272 #: pretix/control/templates/pretixcontrol/order/mail_history.html:70 #: pretix/presale/templates/pretixpresale/event/order.html:244 @@ -1609,13 +2000,13 @@ msgstr "فاتورة" msgid "Line number" msgstr "رقم السطر" -#: pretix/base/exporters/invoices.py:320 pretix/base/exporters/orderlist.py:449 +#: pretix/base/exporters/invoices.py:320 pretix/base/exporters/orderlist.py:458 #: pretix/base/models/items.py:492 pretix/base/models/items.py:1155 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:32 msgid "Description" msgstr "الوصف" -#: pretix/base/exporters/invoices.py:321 pretix/control/forms/orders.py:343 +#: pretix/base/exporters/invoices.py:321 pretix/control/forms/orders.py:355 msgid "Gross price" msgstr "السعر الإجمالي" @@ -1623,22 +2014,22 @@ msgstr "السعر الإجمالي" msgid "Net price" msgstr "السعر الصافي" -#: pretix/base/exporters/invoices.py:323 pretix/base/exporters/orderlist.py:453 -#: pretix/base/exporters/orderlist.py:594 -#: pretix/base/exporters/orderlist.py:904 pretix/base/models/orders.py:2326 -#: pretix/base/models/orders.py:2498 pretix/base/models/orders.py:3020 +#: pretix/base/exporters/invoices.py:323 pretix/base/exporters/orderlist.py:462 +#: pretix/base/exporters/orderlist.py:603 +#: pretix/base/exporters/orderlist.py:922 pretix/base/models/orders.py:2337 +#: pretix/base/models/orders.py:2509 pretix/base/models/orders.py:3031 msgid "Tax value" msgstr "قيمة الضريبة" -#: pretix/base/exporters/invoices.py:324 pretix/base/exporters/orderlist.py:451 -#: pretix/base/exporters/orderlist.py:592 -#: pretix/base/exporters/orderlist.py:901 pretix/base/models/orders.py:2313 -#: pretix/base/models/orders.py:2485 pretix/base/models/orders.py:3007 -#: pretix/base/models/orders.py:3107 pretix/base/models/tax.py:348 +#: pretix/base/exporters/invoices.py:324 pretix/base/exporters/orderlist.py:460 +#: pretix/base/exporters/orderlist.py:601 +#: pretix/base/exporters/orderlist.py:919 pretix/base/models/orders.py:2324 +#: pretix/base/models/orders.py:2496 pretix/base/models/orders.py:3018 +#: pretix/base/models/orders.py:3118 pretix/base/models/tax.py:348 #: pretix/control/templates/pretixcontrol/order/transactions.html:21 -#: pretix/plugins/reports/accountingreport.py:315 -#: pretix/plugins/reports/exporters.py:793 -#: pretix/plugins/reports/exporters.py:838 +#: pretix/plugins/reports/accountingreport.py:316 +#: pretix/plugins/reports/exporters.py:804 +#: pretix/plugins/reports/exporters.py:849 msgid "Tax rate" msgstr "معدل الضريبة" @@ -1646,21 +2037,13 @@ msgstr "معدل الضريبة" msgid "Tax name" msgstr "الاسم الضريبي" -#: pretix/base/exporters/invoices.py:326 -msgid "Event start date" -msgstr "تاريخ بدء الفعالية" - -#: pretix/base/exporters/invoices.py:350 pretix/base/pdf.py:278 -msgid "Event end date" -msgstr "تاريخ إنتهاء الفعالية" - #: pretix/base/exporters/items.py:49 #, fuzzy #| msgid "Product name" msgid "Product data" msgstr "اسم المنتج" -#: pretix/base/exporters/items.py:50 pretix/base/exporters/orderlist.py:1128 +#: pretix/base/exporters/items.py:50 pretix/base/exporters/orderlist.py:1146 #, fuzzy #| msgid "Product name" msgctxt "export_category" @@ -1671,16 +2054,8 @@ msgstr "اسم المنتج" msgid "Download a spreadsheet with details about all products and variations." msgstr "" -#: pretix/base/exporters/items.py:57 pretix/base/exporters/orderlist.py:588 -#: pretix/base/exporters/orderlist.py:890 -#: pretix/base/exporters/waitinglist.py:112 -#, fuzzy -#| msgid "Product" -msgid "Product ID" -msgstr "منتج" - -#: pretix/base/exporters/items.py:58 pretix/base/exporters/orderlist.py:590 -#: pretix/base/exporters/orderlist.py:892 +#: pretix/base/exporters/items.py:58 pretix/base/exporters/orderlist.py:599 +#: pretix/base/exporters/orderlist.py:910 #: pretix/base/exporters/waitinglist.py:114 #, fuzzy #| msgid "Variation" @@ -1705,29 +2080,31 @@ msgstr "الاسم الداخلي" msgid "Item name" msgstr "اسم العنصر" -#: pretix/base/exporters/items.py:68 pretix/base/exporters/orderlist.py:589 -#: pretix/base/exporters/orderlist.py:893 +#: pretix/base/exporters/items.py:68 pretix/base/exporters/orderlist.py:598 +#: pretix/base/exporters/orderlist.py:911 #: pretix/base/exporters/waitinglist.py:113 pretix/base/models/items.py:1148 -#: pretix/base/models/orders.py:1495 pretix/base/models/orders.py:2992 -#: pretix/plugins/checkinlists/exporters.py:695 +#: pretix/base/models/orders.py:1495 pretix/base/models/orders.py:3003 +#: pretix/plugins/checkinlists/exporters.py:696 msgid "Variation" msgstr "النوع" #: pretix/base/exporters/items.py:71 pretix/base/exporters/reusablemedia.py:48 #: pretix/base/models/customers.py:57 pretix/base/models/customers.py:403 -#: pretix/base/models/discount.py:60 pretix/base/models/event.py:1484 +#: pretix/base/models/discount.py:60 pretix/base/models/event.py:1491 #: pretix/base/models/items.py:489 pretix/base/models/items.py:1152 #: pretix/base/models/media.py:77 pretix/base/settings.py:204 #: pretix/base/settings.py:239 pretix/base/settings.py:270 -#: pretix/control/forms/filter.py:1201 pretix/control/forms/filter.py:2010 +#: pretix/control/forms/filter.py:1201 pretix/control/forms/filter.py:2006 #: pretix/control/templates/pretixcontrol/event/plugins.html:25 #: pretix/control/templates/pretixcontrol/event/plugins.html:75 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:25 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:75 #: pretix/control/templates/pretixcontrol/users/index.html:51 msgid "Active" msgstr "نشط" #: pretix/base/exporters/items.py:72 pretix/base/models/discount.py:77 -#: pretix/control/forms/event.py:986 pretix/control/navigation.py:508 +#: pretix/control/forms/event.py:976 pretix/control/navigation.py:520 #: pretix/control/templates/pretixcontrol/organizers/channels.html:6 #: pretix/plugins/autocheckin/models.py:64 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:30 @@ -1765,9 +2142,9 @@ msgstr "إنشاء التذاكر" msgid "Generate tickets" msgstr "إنشاء التذاكر" -#: pretix/base/exporters/items.py:79 pretix/base/exporters/orderlist.py:1135 +#: pretix/base/exporters/items.py:79 pretix/base/exporters/orderlist.py:1153 #: pretix/base/exporters/waitinglist.py:41 pretix/base/shredder.py:367 -#: pretix/control/forms/event.py:1686 pretix/control/navigation.py:237 +#: pretix/control/forms/event.py:1695 pretix/control/navigation.py:237 #: pretix/control/templates/pretixcontrol/event/settings.html:363 #: pretix/control/templates/pretixcontrol/orders/cancel.html:62 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:6 @@ -1775,9 +2152,9 @@ msgstr "إنشاء التذاكر" #: pretix/plugins/sendmail/views.py:448 #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:31 #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:44 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:91 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:98 -#: pretix/presale/templates/pretixpresale/event/index.html:201 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:93 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:100 +#: pretix/presale/templates/pretixpresale/event/index.html:200 #: pretix/presale/templates/pretixpresale/event/waitinglist.html:3 #: pretix/presale/templates/pretixpresale/event/waitinglist_remove.html:3 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:97 @@ -1791,8 +2168,8 @@ msgstr "قائمة الانتظار" #: pretix/base/exporters/items.py:80 pretix/base/models/discount.py:82 #: pretix/base/models/items.py:224 pretix/base/models/items.py:280 #: pretix/base/models/items.py:562 pretix/base/models/items.py:1205 -#: pretix/base/payment.py:392 pretix/control/forms/subevents.py:327 -#: pretix/control/forms/subevents.py:349 +#: pretix/base/payment.py:392 pretix/control/forms/subevents.py:323 +#: pretix/control/forms/subevents.py:345 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:506 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:172 #: pretix/control/templates/pretixcontrol/subevents/detail.html:149 @@ -1802,7 +2179,7 @@ msgstr "متاح من" #: pretix/base/exporters/items.py:81 pretix/base/models/discount.py:87 #: pretix/base/models/items.py:229 pretix/base/models/items.py:285 #: pretix/base/models/items.py:572 pretix/base/models/items.py:1215 -#: pretix/base/payment.py:398 pretix/control/forms/subevents.py:332 +#: pretix/base/payment.py:398 pretix/control/forms/subevents.py:328 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:511 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:177 #: pretix/control/templates/pretixcontrol/subevents/detail.html:154 @@ -1839,17 +2216,17 @@ msgstr "الحد الأدنى للمبلغ حسب كل طلب" msgid "Maximum amount per order" msgstr "الحد الأقصى حسب كل طلب" -#: pretix/base/exporters/items.py:89 pretix/base/exporters/orderlist.py:282 -#: pretix/base/modelimport_orders.py:610 pretix/base/models/items.py:656 +#: pretix/base/exporters/items.py:89 pretix/base/exporters/orderlist.py:283 +#: pretix/base/modelimport_orders.py:652 pretix/base/models/items.py:656 #: pretix/base/models/items.py:1242 pretix/base/models/orders.py:282 -#: pretix/plugins/checkinlists/exporters.py:522 +#: pretix/plugins/checkinlists/exporters.py:523 msgid "Requires special attention" msgstr "يتطلب اهتماما خاصا" -#: pretix/base/exporters/items.py:90 pretix/base/exporters/orderlist.py:283 -#: pretix/base/modelimport_orders.py:618 pretix/base/models/items.py:663 +#: pretix/base/exporters/items.py:90 pretix/base/exporters/orderlist.py:284 +#: pretix/base/modelimport_orders.py:661 pretix/base/models/items.py:663 #: pretix/base/models/items.py:1249 pretix/base/models/orders.py:289 -#: pretix/plugins/checkinlists/exporters.py:524 +#: pretix/plugins/checkinlists/exporters.py:525 #, fuzzy #| msgid "Check-in list" msgid "Check-in text" @@ -1878,7 +2255,7 @@ msgstr "يتتطلب عضوية سارية المفعول" msgid "Hide without a valid membership" msgstr "يتتطلب عضوية سارية المفعول" -#: pretix/base/exporters/json.py:51 pretix/base/exporters/orderlist.py:86 +#: pretix/base/exporters/json.py:51 pretix/base/exporters/orderlist.py:87 msgid "Order data" msgstr "بيانات الطلب" @@ -1898,68 +2275,68 @@ msgid "" "or from ticket holders." msgstr "" -#: pretix/base/exporters/mail.py:76 pretix/plugins/reports/exporters.py:487 -#: pretix/plugins/reports/exporters.py:669 +#: pretix/base/exporters/mail.py:76 pretix/plugins/reports/exporters.py:498 +#: pretix/plugins/reports/exporters.py:680 msgid "Filter by status" msgstr "تصنيف حسب الحالة" -#: pretix/base/exporters/orderlist.py:88 +#: pretix/base/exporters/orderlist.py:89 msgid "" "Download a spreadsheet of all orders. The spreadsheet will include three " "sheets, one with a line for every order, one with a line for every order " "position, and one with a line for every additional fee charged in an order." msgstr "" -#: pretix/base/exporters/orderlist.py:100 pretix/base/models/orders.py:332 +#: pretix/base/exporters/orderlist.py:101 pretix/base/models/orders.py:332 #: pretix/control/navigation.py:255 pretix/control/navigation.py:362 #: pretix/control/templates/pretixcontrol/orders/index.html:8 #: pretix/control/templates/pretixcontrol/orders/index.html:10 #: pretix/control/templates/pretixcontrol/organizers/customer.html:198 -#: pretix/plugins/reports/accountingreport.py:670 -#: pretix/plugins/reports/accountingreport.py:862 -#: pretix/plugins/reports/exporters.py:657 pretix/plugins/statistics/apps.py:39 +#: pretix/plugins/reports/accountingreport.py:671 +#: pretix/plugins/reports/accountingreport.py:863 +#: pretix/plugins/reports/exporters.py:668 pretix/plugins/statistics/apps.py:39 #: pretix/presale/templates/pretixpresale/organizers/customer_orders.html:13 #: pretix/presale/views/customer.py:360 msgid "Orders" msgstr "طلبات" -#: pretix/base/exporters/orderlist.py:101 pretix/base/models/orders.py:2547 +#: pretix/base/exporters/orderlist.py:102 pretix/base/models/orders.py:2558 #: pretix/base/notifications.py:205 msgid "Order positions" msgstr "حالات الطلب" -#: pretix/base/exporters/orderlist.py:102 +#: pretix/base/exporters/orderlist.py:103 msgid "Order fees" msgstr "رسوم الطلب" -#: pretix/base/exporters/orderlist.py:110 +#: pretix/base/exporters/orderlist.py:111 msgid "Only paid orders" msgstr "الطلبات المدفوعة فقط" -#: pretix/base/exporters/orderlist.py:116 +#: pretix/base/exporters/orderlist.py:117 msgid "Include payment amounts" msgstr "تضمين مبالغ الدفع" -#: pretix/base/exporters/orderlist.py:122 +#: pretix/base/exporters/orderlist.py:123 msgid "Show multiple choice answers grouped in one column" msgstr "أظهر إجابات متعددة الخيار، مجمعة في عمود واحد" -#: pretix/base/exporters/orderlist.py:131 -#: pretix/plugins/reports/exporters.py:701 +#: pretix/base/exporters/orderlist.py:132 +#: pretix/plugins/reports/exporters.py:712 #, fuzzy #| msgid "Only include orders created on or after this date." msgid "Only include orders created within this date range." msgstr "قم بتضمين الطلبات التي تم إنشاؤها في هذا التاريخ أو بعده فقط." -#: pretix/base/exporters/orderlist.py:135 pretix/base/notifications.py:194 -#: pretix/base/pdf.py:234 pretix/plugins/badges/exporters.py:499 -#: pretix/plugins/reports/exporters.py:305 -#: pretix/plugins/reports/exporters.py:454 +#: pretix/base/exporters/orderlist.py:136 pretix/base/notifications.py:194 +#: pretix/base/pdf.py:243 pretix/plugins/badges/exporters.py:499 +#: pretix/plugins/reports/exporters.py:316 +#: pretix/plugins/reports/exporters.py:465 #: pretix/plugins/ticketoutputpdf/exporters.py:97 msgid "Event date" msgstr "تاريخ الفعالية" -#: pretix/base/exporters/orderlist.py:138 +#: pretix/base/exporters/orderlist.py:139 #, fuzzy #| msgid "" #| "Only include orders including at least one ticket for a date on or after " @@ -1971,42 +2348,35 @@ msgstr "" "قم بتضمين الطلبات التي تشمل تذكرة واحدة على الأقل في هذا التاريخ أو بعده. " "سيشمل أيضا تواريخ أخرى في حالة الطلبات المختلطة!" -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:440 -#: pretix/base/exporters/orderlist.py:572 -#: pretix/base/exporters/orderlist.py:876 -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1259 -#: pretix/base/exporters/waitinglist.py:115 pretix/control/forms/event.py:1662 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:449 +#: pretix/base/exporters/orderlist.py:581 +#: pretix/base/exporters/orderlist.py:894 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1277 +#: pretix/base/exporters/waitinglist.py:115 pretix/control/forms/event.py:1671 #: pretix/control/forms/organizer.py:116 msgid "Event slug" msgstr "رابط الفعالية" -#: pretix/base/exporters/orderlist.py:261 pretix/base/notifications.py:201 -#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:25 -#: pretix/control/templates/pretixcontrol/search/orders.html:60 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:886 -msgid "Order total" -msgstr "إجمالي الطلب" - -#: pretix/base/exporters/orderlist.py:261 -#: pretix/base/exporters/orderlist.py:443 -#: pretix/base/exporters/orderlist.py:576 -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1312 +#: pretix/base/exporters/orderlist.py:262 +#: pretix/base/exporters/orderlist.py:452 +#: pretix/base/exporters/orderlist.py:585 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1330 #: pretix/base/exporters/waitinglist.py:122 #: pretix/base/exporters/waitinglist.py:172 pretix/base/models/orders.py:216 #: pretix/control/forms/filter.py:1019 pretix/control/forms/filter.py:1198 -#: pretix/control/forms/filter.py:1426 pretix/control/forms/filter.py:1495 -#: pretix/control/forms/filter.py:1567 pretix/control/forms/filter.py:1667 -#: pretix/control/forms/filter.py:2007 pretix/control/forms/filter.py:2087 -#: pretix/control/forms/filter.py:2368 +#: pretix/control/forms/filter.py:1424 pretix/control/forms/filter.py:1493 +#: pretix/control/forms/filter.py:1565 pretix/control/forms/filter.py:1665 +#: pretix/control/forms/filter.py:2003 pretix/control/forms/filter.py:2083 +#: pretix/control/forms/filter.py:2364 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:52 #: pretix/control/templates/pretixcontrol/checkin/index.html:112 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:83 #: pretix/control/templates/pretixcontrol/events/index.html:90 -#: pretix/control/templates/pretixcontrol/order/index.html:743 -#: pretix/control/templates/pretixcontrol/order/index.html:839 +#: pretix/control/templates/pretixcontrol/order/index.html:795 +#: pretix/control/templates/pretixcontrol/order/index.html:891 #: pretix/control/templates/pretixcontrol/orders/bulk_action.html:26 #: pretix/control/templates/pretixcontrol/orders/index.html:151 #: pretix/control/templates/pretixcontrol/orders/refunds.html:65 @@ -2023,18 +2393,18 @@ msgstr "إجمالي الطلب" #: pretix/control/templates/pretixcontrol/waitinglist/index.html:170 #: pretix/control/views/waitinglist.py:314 #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:9 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:886 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:897 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:34 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:79 msgid "Status" msgstr "حالة" -#: pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:446 -#: pretix/base/exporters/orderlist.py:579 -#: pretix/base/exporters/orderlist.py:880 pretix/base/notifications.py:203 -#: pretix/control/forms/filter.py:2329 +#: pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:455 +#: pretix/base/exporters/orderlist.py:588 +#: pretix/base/exporters/orderlist.py:898 pretix/base/notifications.py:203 +#: pretix/control/forms/filter.py:2325 #: pretix/control/templates/pretixcontrol/order/index.html:183 #: pretix/control/templates/pretixcontrol/orders/bulk_action.html:24 #: pretix/control/templates/pretixcontrol/orders/index.html:140 @@ -2042,71 +2412,64 @@ msgstr "حالة" #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:45 #: pretix/control/templates/pretixcontrol/search/orders.html:57 #: pretix/plugins/badges/exporters.py:498 -#: pretix/plugins/checkinlists/exporters.py:122 -#: pretix/plugins/checkinlists/exporters.py:520 -#: pretix/plugins/reports/exporters.py:498 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:680 +#: pretix/plugins/checkinlists/exporters.py:123 +#: pretix/plugins/checkinlists/exporters.py:521 +#: pretix/plugins/reports/exporters.py:509 +#: pretix/plugins/reports/exporters.py:572 #: pretix/plugins/reports/exporters.py:691 -#: pretix/plugins/reports/exporters.py:884 +#: pretix/plugins/reports/exporters.py:702 +#: pretix/plugins/reports/exporters.py:895 msgid "Order date" msgstr "تاريخ الطلب" -#: pretix/base/exporters/orderlist.py:262 -#: pretix/base/exporters/orderlist.py:447 -#: pretix/base/exporters/orderlist.py:580 -#: pretix/base/exporters/orderlist.py:881 -#: pretix/plugins/checkinlists/exporters.py:521 +#: pretix/base/exporters/orderlist.py:263 +#: pretix/base/exporters/orderlist.py:456 +#: pretix/base/exporters/orderlist.py:589 +#: pretix/base/exporters/orderlist.py:899 +#: pretix/plugins/checkinlists/exporters.py:522 msgid "Order time" msgstr "توقيت الطلب" -#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:271 msgid "Custom address field" msgstr "حقل العنوان المخصص" -#: pretix/base/exporters/orderlist.py:270 +#: pretix/base/exporters/orderlist.py:271 msgid "Date of last payment" msgstr "تاريخ آخر دفع" -#: pretix/base/exporters/orderlist.py:270 pretix/base/services/stats.py:237 +#: pretix/base/exporters/orderlist.py:271 pretix/base/services/stats.py:237 msgid "Fees" msgstr "الرسوم" -#: pretix/base/exporters/orderlist.py:270 -#: pretix/base/exporters/orderlist.py:657 pretix/base/modelimport_orders.py:472 -#: pretix/control/templates/pretixcontrol/order/index.html:193 -#: pretix/control/templates/pretixcontrol/pdf/index.html:189 -msgid "Order locale" -msgstr "مكان الطلب" - -#: pretix/base/exporters/orderlist.py:275 +#: pretix/base/exporters/orderlist.py:276 #, python-brace-format msgid "Gross at {rate} % tax" msgstr "الإجمالي في {rate} % ضريبة" -#: pretix/base/exporters/orderlist.py:276 +#: pretix/base/exporters/orderlist.py:277 #, python-brace-format msgid "Net at {rate} % tax" msgstr "صافي {rate} % ضريبة" -#: pretix/base/exporters/orderlist.py:277 +#: pretix/base/exporters/orderlist.py:278 #, python-brace-format msgid "Tax value at {rate} % tax" msgstr "قيمة الضريبة {rate} % ضريبة" -#: pretix/base/exporters/orderlist.py:280 +#: pretix/base/exporters/orderlist.py:281 msgid "Invoice numbers" msgstr "أرقام الفواتير" -#: pretix/base/exporters/orderlist.py:281 -#: pretix/base/exporters/orderlist.py:656 pretix/base/modelimport_orders.py:540 +#: pretix/base/exporters/orderlist.py:282 +#: pretix/base/exporters/orderlist.py:665 pretix/base/modelimport_orders.py:578 #: pretix/control/forms/filter.py:585 #: pretix/control/templates/pretixcontrol/order/index.html:190 msgid "Sales channel" msgstr "قناة المبيعات" -#: pretix/base/exporters/orderlist.py:285 -#: pretix/base/exporters/orderlist.py:621 pretix/base/models/orders.py:277 +#: pretix/base/exporters/orderlist.py:286 +#: pretix/base/exporters/orderlist.py:630 pretix/base/models/orders.py:277 #: pretix/control/forms/filter.py:240 #, fuzzy #| msgctxt "subevent" @@ -2114,120 +2477,113 @@ msgstr "قناة المبيعات" msgid "Follow-up date" msgstr "كل التواريخ" -#: pretix/base/exporters/orderlist.py:286 +#: pretix/base/exporters/orderlist.py:287 #: pretix/control/templates/pretixcontrol/orders/index.html:150 #: pretix/control/templates/pretixcontrol/organizers/customer.html:208 msgid "Positions" msgstr "الحالات" -#: pretix/base/exporters/orderlist.py:287 -#: pretix/base/exporters/orderlist.py:658 pretix/base/models/orders.py:321 +#: pretix/base/exporters/orderlist.py:288 +#: pretix/base/exporters/orderlist.py:667 pretix/base/models/orders.py:321 #: pretix/control/forms/filter.py:567 msgid "Email address verified" msgstr "تم التحقق من عنوان البريد الإلكتروني" -#: pretix/base/exporters/orderlist.py:288 -#: pretix/base/exporters/orderlist.py:465 -#: pretix/base/exporters/orderlist.py:659 +#: pretix/base/exporters/orderlist.py:289 +#: pretix/base/exporters/orderlist.py:474 +#: pretix/base/exporters/orderlist.py:668 #, fuzzy #| msgctxt "invoice" #| msgid "Customer VAT ID" msgid "External customer ID" msgstr "معرف ضريبة القيمة المضافة للعميل" -#: pretix/base/exporters/orderlist.py:293 +#: pretix/base/exporters/orderlist.py:295 #, python-brace-format msgid "Paid by {method}" msgstr "تم السداد بواسطة {method}" -#: pretix/base/exporters/orderlist.py:448 -#: pretix/base/exporters/orderlist.py:894 +#: pretix/base/exporters/orderlist.py:457 +#: pretix/base/exporters/orderlist.py:912 msgid "Fee type" msgstr "نوع الرسوم" -#: pretix/base/exporters/orderlist.py:450 -#: pretix/base/exporters/orderlist.py:591 -#: pretix/base/exporters/orderlist.py:900 pretix/base/modelimport_orders.py:431 -#: pretix/base/models/orders.py:1500 pretix/base/models/orders.py:3003 -#: pretix/base/pdf.py:158 pretix/control/forms/orders.py:627 +#: pretix/base/exporters/orderlist.py:459 +#: pretix/base/exporters/orderlist.py:600 +#: pretix/base/exporters/orderlist.py:918 pretix/base/modelimport_orders.py:467 +#: pretix/base/models/orders.py:1500 pretix/base/models/orders.py:3014 +#: pretix/base/pdf.py:158 pretix/control/forms/orders.py:638 #: pretix/control/templates/pretixcontrol/item/index.html:146 #: pretix/control/templates/pretixcontrol/order/change.html:194 #: pretix/control/templates/pretixcontrol/order/change.html:418 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:496 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:162 #: pretix/control/templates/pretixcontrol/subevents/detail.html:139 -#: pretix/plugins/checkinlists/exporters.py:376 -#: pretix/plugins/checkinlists/exporters.py:499 -#: pretix/plugins/reports/accountingreport.py:314 +#: pretix/plugins/checkinlists/exporters.py:377 +#: pretix/plugins/checkinlists/exporters.py:500 +#: pretix/plugins/reports/accountingreport.py:315 msgid "Price" msgstr "السعر" -#: pretix/base/exporters/orderlist.py:452 -#: pretix/base/exporters/orderlist.py:593 -#: pretix/base/exporters/orderlist.py:903 +#: pretix/base/exporters/orderlist.py:461 +#: pretix/base/exporters/orderlist.py:602 +#: pretix/base/exporters/orderlist.py:921 #: pretix/control/templates/pretixcontrol/event/tax_edit.html:9 #: pretix/control/templates/pretixcontrol/event/tax_edit.html:16 #: pretix/control/templates/pretixcontrol/order/change.html:165 msgid "Tax rule" msgstr "قاعدة الضريبة" -#: pretix/base/exporters/orderlist.py:455 -#: pretix/base/exporters/orderlist.py:460 -#: pretix/base/exporters/orderlist.py:644 -#: pretix/base/exporters/orderlist.py:648 pretix/base/pdf.py:330 -msgid "Invoice address name" -msgstr "اسم عنوان الفاتورة" - -#: pretix/base/exporters/orderlist.py:480 -#: pretix/base/exporters/orderlist.py:683 pretix/base/models/orders.py:205 +#: pretix/base/exporters/orderlist.py:489 +#: pretix/base/exporters/orderlist.py:693 pretix/base/models/orders.py:205 msgid "canceled" msgstr "ملغى" -#: pretix/base/exporters/orderlist.py:575 -#: pretix/base/exporters/orderlist.py:887 -#: pretix/plugins/checkinlists/exporters.py:757 +#: pretix/base/exporters/orderlist.py:584 +#: pretix/base/exporters/orderlist.py:905 +#: pretix/plugins/checkinlists/exporters.py:758 msgid "Position ID" msgstr "معرف الحالة" -#: pretix/base/exporters/orderlist.py:584 -#: pretix/base/exporters/orderlist.py:1139 +#: pretix/base/exporters/orderlist.py:593 +#: pretix/base/exporters/orderlist.py:1157 #: pretix/base/exporters/waitinglist.py:118 pretix/base/forms/questions.py:650 #: pretix/base/forms/questions.py:659 pretix/base/models/memberships.py:145 #: pretix/control/forms/rrule.py:49 #: pretix/control/templates/pretixcontrol/events/index.html:78 -#: pretix/control/templates/pretixcontrol/order/index.html:740 -#: pretix/control/templates/pretixcontrol/order/index.html:834 +#: pretix/control/templates/pretixcontrol/order/index.html:792 +#: pretix/control/templates/pretixcontrol/order/index.html:886 #: pretix/control/templates/pretixcontrol/orders/refunds.html:55 #: pretix/control/templates/pretixcontrol/organizers/detail.html:66 #: pretix/control/templates/pretixcontrol/search/payments.html:83 #: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:19 #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:18 -#: pretix/plugins/checkinlists/exporters.py:512 -#: pretix/plugins/checkinlists/exporters.py:701 +#: pretix/plugins/checkinlists/exporters.py:513 +#: pretix/plugins/checkinlists/exporters.py:702 msgid "Start date" msgstr "تاريخ البداية" -#: pretix/base/exporters/orderlist.py:585 -#: pretix/base/exporters/orderlist.py:1140 +#: pretix/base/exporters/orderlist.py:594 +#: pretix/base/exporters/orderlist.py:1158 #: pretix/base/exporters/waitinglist.py:119 #: pretix/base/models/memberships.py:148 #: pretix/control/templates/pretixcontrol/events/index.html:82 #: pretix/control/templates/pretixcontrol/organizers/detail.html:68 #: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:21 #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:20 -#: pretix/plugins/checkinlists/exporters.py:513 -#: pretix/plugins/checkinlists/exporters.py:702 +#: pretix/plugins/checkinlists/exporters.py:514 +#: pretix/plugins/checkinlists/exporters.py:703 msgid "End date" msgstr "تاريخ الإنتهاء" -#: pretix/base/exporters/orderlist.py:587 -#: pretix/base/exporters/orderlist.py:891 +#: pretix/base/exporters/orderlist.py:596 +#: pretix/base/exporters/orderlist.py:909 #: pretix/base/exporters/waitinglist.py:111 -#: pretix/base/modelimport_orders.py:109 +#: pretix/base/modelimport_orders.py:129 #: pretix/base/modelimport_vouchers.py:174 pretix/base/models/items.py:794 -#: pretix/base/models/vouchers.py:250 pretix/base/models/waitinglist.py:91 -#: pretix/control/forms/filter.py:2129 pretix/control/forms/filter.py:2384 -#: pretix/control/forms/orders.py:323 pretix/control/forms/vouchers.py:67 +#: pretix/base/models/vouchers.py:253 pretix/base/models/waitinglist.py:91 +#: pretix/control/forms/filter.py:2125 pretix/control/forms/filter.py:2380 +#: pretix/control/forms/orders.py:335 pretix/control/forms/vouchers.py:67 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:66 #: pretix/control/templates/pretixcontrol/item/base.html:3 #: pretix/control/templates/pretixcontrol/order/change.html:139 @@ -2237,12 +2593,12 @@ msgstr "تاريخ الإنتهاء" #: pretix/control/templates/pretixcontrol/vouchers/index.html:134 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:165 #: pretix/control/views/vouchers.py:119 pretix/control/views/waitinglist.py:314 -#: pretix/plugins/checkinlists/exporters.py:376 -#: pretix/plugins/checkinlists/exporters.py:499 -#: pretix/plugins/checkinlists/exporters.py:694 -#: pretix/plugins/checkinlists/exporters.py:759 -#: pretix/plugins/reports/accountingreport.py:270 -#: pretix/plugins/reports/exporters.py:375 +#: pretix/plugins/checkinlists/exporters.py:377 +#: pretix/plugins/checkinlists/exporters.py:500 +#: pretix/plugins/checkinlists/exporters.py:695 +#: pretix/plugins/checkinlists/exporters.py:760 +#: pretix/plugins/reports/accountingreport.py:271 +#: pretix/plugins/reports/exporters.py:386 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:100 #: pretix/presale/forms/order.py:36 pretix/presale/forms/waitinglist.py:54 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:12 @@ -2250,36 +2606,7 @@ msgstr "تاريخ الإنتهاء" msgid "Product" msgstr "منتج" -#: pretix/base/exporters/orderlist.py:595 -#: pretix/base/exporters/orderlist.py:600 pretix/base/forms/questions.py:679 -#: pretix/base/modelimport_orders.py:313 pretix/base/models/customers.py:300 -#: pretix/base/models/orders.py:1504 pretix/base/pdf.py:172 -#: pretix/control/forms/filter.py:648 pretix/control/forms/organizer.py:986 -#: pretix/control/templates/pretixcontrol/order/index.html:514 -#: pretix/control/templates/pretixcontrol/organizers/customer.html:120 -#: pretix/control/views/item.py:442 pretix/plugins/badges/exporters.py:495 -#: pretix/plugins/checkinlists/exporters.py:120 -#: pretix/plugins/checkinlists/exporters.py:493 -#: pretix/plugins/ticketoutputpdf/exporters.py:94 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:162 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:165 -#: pretix/presale/templates/pretixpresale/event/fragment_change_form.html:38 -#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:50 -#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:36 -msgid "Attendee name" -msgstr "اسم الحاضر" - -#: pretix/base/exporters/orderlist.py:602 pretix/base/forms/questions.py:685 -#: pretix/base/models/customers.py:307 pretix/base/models/orders.py:1512 -#: pretix/base/pdf.py:214 -#: pretix/control/templates/pretixcontrol/order/index.html:519 -#: pretix/control/views/item.py:454 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:172 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:175 -msgid "Attendee email" -msgstr "البريد الإلكتروني للحاضر" - -#: pretix/base/exporters/orderlist.py:609 pretix/base/models/vouchers.py:312 +#: pretix/base/exporters/orderlist.py:618 pretix/base/models/vouchers.py:315 #: pretix/control/templates/pretixcontrol/vouchers/bulk.html:5 #: pretix/control/templates/pretixcontrol/vouchers/detail.html:6 #: pretix/control/templates/pretixcontrol/vouchers/detail.html:8 @@ -2287,108 +2614,92 @@ msgstr "البريد الإلكتروني للحاضر" msgid "Voucher" msgstr "كود الخصم" -#: pretix/base/exporters/orderlist.py:610 +#: pretix/base/exporters/orderlist.py:619 msgid "Pseudonymization ID" msgstr "معرف الاسم المستعار" -#: pretix/base/exporters/orderlist.py:611 pretix/control/forms/filter.py:678 +#: pretix/base/exporters/orderlist.py:620 pretix/control/forms/filter.py:678 #: pretix/control/templates/pretixcontrol/order/change.html:280 #, fuzzy #| msgid "Client secret" msgid "Ticket secret" msgstr "كلمة سر التذكرة" -#: pretix/base/exporters/orderlist.py:612 pretix/base/modelimport_orders.py:570 +#: pretix/base/exporters/orderlist.py:621 pretix/base/modelimport_orders.py:610 #: pretix/base/modelimport_vouchers.py:272 -#: pretix/plugins/checkinlists/exporters.py:525 +#: pretix/plugins/checkinlists/exporters.py:526 msgid "Seat ID" msgstr "رقم المقعد" -#: pretix/base/exporters/orderlist.py:613 -#: pretix/plugins/checkinlists/exporters.py:526 +#: pretix/base/exporters/orderlist.py:622 +#: pretix/plugins/checkinlists/exporters.py:527 msgid "Seat name" msgstr "اسم المقعد" -#: pretix/base/exporters/orderlist.py:614 -#: pretix/plugins/checkinlists/exporters.py:527 +#: pretix/base/exporters/orderlist.py:623 +#: pretix/plugins/checkinlists/exporters.py:528 msgid "Seat zone" msgstr "منطقة المقعد" -#: pretix/base/exporters/orderlist.py:615 -#: pretix/plugins/checkinlists/exporters.py:528 +#: pretix/base/exporters/orderlist.py:624 +#: pretix/plugins/checkinlists/exporters.py:529 msgid "Seat row" msgstr "صف المقعد" -#: pretix/base/exporters/orderlist.py:616 -#: pretix/plugins/checkinlists/exporters.py:529 +#: pretix/base/exporters/orderlist.py:625 +#: pretix/plugins/checkinlists/exporters.py:530 msgid "Seat number" msgstr "رقم المقعد" -#: pretix/base/exporters/orderlist.py:617 +#: pretix/base/exporters/orderlist.py:626 #: pretix/control/templates/pretixcontrol/order/change.html:224 -#: pretix/plugins/checkinlists/exporters.py:428 -#: pretix/plugins/checkinlists/exporters.py:530 +#: pretix/plugins/checkinlists/exporters.py:429 +#: pretix/plugins/checkinlists/exporters.py:531 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:108 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:110 msgid "Blocked" msgstr "محجوب" -#: pretix/base/exporters/orderlist.py:618 pretix/base/modelimport_orders.py:500 -#: pretix/base/models/orders.py:2514 +#: pretix/base/exporters/orderlist.py:627 pretix/base/modelimport_orders.py:537 +#: pretix/base/models/orders.py:2525 #: pretix/control/templates/pretixcontrol/organizers/customer.html:117 -#: pretix/plugins/checkinlists/exporters.py:531 -#: pretix/plugins/checkinlists/exporters.py:704 +#: pretix/plugins/checkinlists/exporters.py:532 +#: pretix/plugins/checkinlists/exporters.py:705 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:46 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:54 msgid "Valid from" msgstr "من تاريخ" -#: pretix/base/exporters/orderlist.py:619 pretix/base/modelimport_orders.py:508 -#: pretix/base/modelimport_vouchers.py:111 pretix/base/models/orders.py:2519 -#: pretix/base/models/vouchers.py:221 +#: pretix/base/exporters/orderlist.py:628 pretix/base/modelimport_orders.py:545 +#: pretix/base/modelimport_vouchers.py:111 pretix/base/models/orders.py:2530 +#: pretix/base/models/vouchers.py:224 #: pretix/control/templates/pretixcontrol/organizers/customer.html:118 #: pretix/control/views/vouchers.py:119 -#: pretix/plugins/checkinlists/exporters.py:532 -#: pretix/plugins/checkinlists/exporters.py:705 +#: pretix/plugins/checkinlists/exporters.py:533 +#: pretix/plugins/checkinlists/exporters.py:706 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:48 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:60 msgid "Valid until" msgstr "حتى تاريخ" -#: pretix/base/exporters/orderlist.py:620 +#: pretix/base/exporters/orderlist.py:629 pretix/base/modelimport_orders.py:643 msgid "Order comment" msgstr "ملاحظات الطلب" -#: pretix/base/exporters/orderlist.py:622 +#: pretix/base/exporters/orderlist.py:631 #, fuzzy #| msgid "Add-On to position #%(posid)s" msgid "Add-on to position ID" msgstr "إضافة على #%(posid)s" -#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:340 -msgid "Invoice address street" -msgstr "شارع عنوان الفاتورة" - -#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:345 -msgid "Invoice address ZIP code" -msgstr "الرمز البريدي لعنوان الفاتورة" - -#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:350 -msgid "Invoice address city" -msgstr "مدينة عنوان الفاتورة" - -#: pretix/base/exporters/orderlist.py:651 pretix/base/pdf.py:360 -msgid "Invoice address country" -msgstr "بلد عنوان الفاتورة" - -#: pretix/base/exporters/orderlist.py:652 +#: pretix/base/exporters/orderlist.py:661 #, fuzzy #| msgid "Invoice address state" msgctxt "address" msgid "Invoice address state" msgstr "منطقة عنوان الفاتورة" -#: pretix/base/exporters/orderlist.py:660 pretix/control/navigation.py:305 +#: pretix/base/exporters/orderlist.py:669 pretix/control/navigation.py:305 #: pretix/control/templates/pretixcontrol/checkin/lists.html:6 #: pretix/control/templates/pretixcontrol/checkin/lists.html:8 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:519 @@ -2398,44 +2709,50 @@ msgstr "منطقة عنوان الفاتورة" msgid "Check-in lists" msgstr "تحقق في القوائم" -#: pretix/base/exporters/orderlist.py:822 +#: pretix/base/exporters/orderlist.py:671 +#, fuzzy +#| msgid "Resend order link" +msgid "Position order link" +msgstr "إعادة إرسال روابط الطلب" + +#: pretix/base/exporters/orderlist.py:840 #, fuzzy #| msgid "Transaction Code" msgid "Order transaction data" msgstr "رمز معاملة الخادم" -#: pretix/base/exporters/orderlist.py:824 +#: pretix/base/exporters/orderlist.py:842 msgid "" "Download a spreadsheet of all substantial changes to orders, i.e. all " "changes to products, prices or tax rates. The information is only accurate " "for changes made with pretix versions released after October 2021." msgstr "" -#: pretix/base/exporters/orderlist.py:840 +#: pretix/base/exporters/orderlist.py:858 #, fuzzy #| msgid "Only include orders created on or after this date." msgid "Only include transactions created within this date range." msgstr "قم بتضمين الطلبات التي تم إنشاؤها في هذا التاريخ أو بعده فقط." -#: pretix/base/exporters/orderlist.py:875 pretix/base/models/event.py:672 +#: pretix/base/exporters/orderlist.py:893 pretix/base/models/event.py:671 #: pretix/base/models/items.py:468 pretix/base/models/items.py:2060 -#: pretix/base/models/orders.py:233 pretix/base/models/orders.py:3086 -#: pretix/base/models/vouchers.py:181 pretix/base/models/waitinglist.py:55 +#: pretix/base/models/orders.py:233 pretix/base/models/orders.py:3097 +#: pretix/base/models/vouchers.py:184 pretix/base/models/waitinglist.py:55 #: pretix/base/notifications.py:187 pretix/control/forms/filter.py:994 #: pretix/control/templates/pretixcontrol/organizers/customer.html:205 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:42 #: pretix/control/templates/pretixcontrol/search/orders.html:51 #: pretix/multidomain/models.py:65 -#: pretix/plugins/reports/accountingreport.py:111 -#: pretix/plugins/reports/accountingreport.py:270 +#: pretix/plugins/reports/accountingreport.py:112 +#: pretix/plugins/reports/accountingreport.py:271 #: pretix/presale/templates/pretixpresale/event/waitinglist.html:11 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:95 msgid "Event" msgstr "فعالية" -#: pretix/base/exporters/orderlist.py:877 -#: pretix/base/exporters/orderlist.py:1216 -#: pretix/base/exporters/orderlist.py:1360 +#: pretix/base/exporters/orderlist.py:895 +#: pretix/base/exporters/orderlist.py:1234 +#: pretix/base/exporters/orderlist.py:1378 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:50 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:34 #: pretix/plugins/banktransfer/refund_export.py:46 @@ -2447,31 +2764,31 @@ msgstr "فعالية" msgid "Currency" msgstr "العملة" -#: pretix/base/exporters/orderlist.py:883 +#: pretix/base/exporters/orderlist.py:901 #, fuzzy #| msgid "Transaction Code" msgid "Transaction date" msgstr "كود المعاملة" -#: pretix/base/exporters/orderlist.py:884 +#: pretix/base/exporters/orderlist.py:902 #, fuzzy #| msgid "Transaction Code" msgid "Transaction time" msgstr "كود المعاملة" -#: pretix/base/exporters/orderlist.py:885 +#: pretix/base/exporters/orderlist.py:903 #, fuzzy #| msgid "Order data" msgid "Old data" msgstr "بيانات الطلب" -#: pretix/base/exporters/orderlist.py:888 pretix/base/models/items.py:1555 +#: pretix/base/exporters/orderlist.py:906 pretix/base/models/items.py:1555 #: pretix/control/templates/pretixcontrol/order/transactions.html:23 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:207 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:353 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:16 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:223 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:375 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:225 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:377 #: pretix/presale/templates/pretixpresale/event/voucher.html:234 #: pretix/presale/templates/pretixpresale/event/voucher.html:389 #, fuzzy @@ -2479,259 +2796,259 @@ msgstr "بيانات الطلب" msgid "Quantity" msgstr "كمية" -#: pretix/base/exporters/orderlist.py:895 +#: pretix/base/exporters/orderlist.py:913 #, fuzzy #| msgid "Internal reference" msgid "Internal fee type" msgstr "المرجع الداخلي" -#: pretix/base/exporters/orderlist.py:897 +#: pretix/base/exporters/orderlist.py:915 #, fuzzy #| msgid "Date" msgctxt "subevent" msgid "Date ID" msgstr "التاريخ" -#: pretix/base/exporters/orderlist.py:902 +#: pretix/base/exporters/orderlist.py:920 #, fuzzy #| msgid "Tax rule" msgid "Tax rule ID" msgstr "قاعدة الضريبة" -#: pretix/base/exporters/orderlist.py:905 -#: pretix/plugins/reports/accountingreport.py:319 +#: pretix/base/exporters/orderlist.py:923 +#: pretix/plugins/reports/accountingreport.py:320 #, fuzzy #| msgctxt "invoice" #| msgid "Gross value" msgid "Gross total" msgstr "القيمة الإجمالية" -#: pretix/base/exporters/orderlist.py:906 -#: pretix/plugins/reports/accountingreport.py:318 +#: pretix/base/exporters/orderlist.py:924 +#: pretix/plugins/reports/accountingreport.py:319 #, fuzzy #| msgid "Total" msgid "Tax total" msgstr "المجموع" -#: pretix/base/exporters/orderlist.py:916 +#: pretix/base/exporters/orderlist.py:934 msgid "" "This value is supplied for informational purposes, it is not part of the " "original transaction data and might have changed since the transaction." msgstr "" -#: pretix/base/exporters/orderlist.py:939 +#: pretix/base/exporters/orderlist.py:957 msgid "Converted from legacy version" msgstr "" -#: pretix/base/exporters/orderlist.py:1001 +#: pretix/base/exporters/orderlist.py:1019 #, fuzzy #| msgid "Order payments and refunds" msgid "Payments and refunds" msgstr "مدفوعات الطلب والمبالغ المستردة" -#: pretix/base/exporters/orderlist.py:1003 +#: pretix/base/exporters/orderlist.py:1021 msgid "Download a spreadsheet of all payments or refunds of every order." msgstr "" -#: pretix/base/exporters/orderlist.py:1012 +#: pretix/base/exporters/orderlist.py:1030 #, fuzzy #| msgid "Extend payment term" msgid "Date range (payment date)" msgstr "تمديد فترة السداد" -#: pretix/base/exporters/orderlist.py:1015 +#: pretix/base/exporters/orderlist.py:1033 msgid "" "Note that using this will exclude any non-confirmed payments or non-" "completed refunds." msgstr "" -#: pretix/base/exporters/orderlist.py:1019 +#: pretix/base/exporters/orderlist.py:1037 msgid "Date range (start of transaction)" msgstr "" -#: pretix/base/exporters/orderlist.py:1025 +#: pretix/base/exporters/orderlist.py:1043 msgid "Payment states" msgstr "‪حالات الدفع" -#: pretix/base/exporters/orderlist.py:1033 +#: pretix/base/exporters/orderlist.py:1051 msgid "Refund states" msgstr "حالات استعادة المبلغ" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1217 -#: pretix/base/exporters/orderlist.py:1259 pretix/base/models/orders.py:331 -#: pretix/base/models/orders.py:1740 pretix/base/models/orders.py:2143 -#: pretix/base/models/orders.py:2302 pretix/base/models/orders.py:2474 -#: pretix/base/models/orders.py:2965 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1235 +#: pretix/base/exporters/orderlist.py:1277 pretix/base/models/orders.py:331 +#: pretix/base/models/orders.py:1740 pretix/base/models/orders.py:2154 +#: pretix/base/models/orders.py:2313 pretix/base/models/orders.py:2485 +#: pretix/base/models/orders.py:2976 +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:23 #: pretix/control/templates/pretixcontrol/organizers/customer.html:119 #: pretix/control/templates/pretixcontrol/search/payments.html:78 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:15 -#: pretix/plugins/checkinlists/exporters.py:374 +#: pretix/plugins/checkinlists/exporters.py:375 #: pretix/presale/templates/pretixpresale/event/order.html:67 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:70 msgid "Order" msgstr "الطلب" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1259 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1277 #: pretix/control/templates/pretixcontrol/search/payments.html:75 #: pretix/plugins/paypal/templates/pretixplugins/paypal/control.html:5 #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html:5 msgid "Payment ID" msgstr "معرف الدفع" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/base/exporters/orderlist.py:1357 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/base/exporters/orderlist.py:1375 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:30 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:59 msgid "Creation date" msgstr "تاريخ الإنشاء" -#: pretix/base/exporters/orderlist.py:1076 -#: pretix/control/templates/pretixcontrol/order/index.html:835 +#: pretix/base/exporters/orderlist.py:1094 +#: pretix/control/templates/pretixcontrol/order/index.html:887 msgid "Completion date" msgstr "تاريخ الاكتمال" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 msgid "Status code" msgstr "رمز الحالة" -#: pretix/base/exporters/orderlist.py:1077 -#: pretix/base/exporters/orderlist.py:1215 -#: pretix/base/exporters/orderlist.py:1259 pretix/base/models/orders.py:1736 -#: pretix/base/models/orders.py:2139 pretix/control/forms/filter.py:1051 +#: pretix/base/exporters/orderlist.py:1095 +#: pretix/base/exporters/orderlist.py:1233 +#: pretix/base/exporters/orderlist.py:1277 pretix/base/models/orders.py:1736 +#: pretix/base/models/orders.py:2150 pretix/control/forms/filter.py:1051 #: pretix/control/forms/filter.py:1054 -#: pretix/control/templates/pretixcontrol/order/index.html:744 -#: pretix/control/templates/pretixcontrol/order/index.html:840 +#: pretix/control/templates/pretixcontrol/order/index.html:796 +#: pretix/control/templates/pretixcontrol/order/index.html:892 #: pretix/control/templates/pretixcontrol/orders/refunds.html:70 #: pretix/control/templates/pretixcontrol/search/payments.html:98 -#: pretix/plugins/banktransfer/payment.py:464 -#: pretix/plugins/banktransfer/payment.py:473 +#: pretix/plugins/banktransfer/payment.py:298 +#: pretix/plugins/banktransfer/payment.py:307 #: pretix/plugins/banktransfer/refund_export.py:46 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:25 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13 msgid "Amount" msgstr "المبلغ" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:102 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:115 -#: pretix/control/templates/pretixcontrol/order/index.html:742 -#: pretix/control/templates/pretixcontrol/order/index.html:837 +#: pretix/control/templates/pretixcontrol/order/index.html:794 +#: pretix/control/templates/pretixcontrol/order/index.html:889 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:85 -#: pretix/plugins/reports/accountingreport.py:495 +#: pretix/plugins/reports/accountingreport.py:496 #: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_confirm.html:29 msgid "Payment method" msgstr "طريقة السداد" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 #, fuzzy #| msgid "Payment matching IDs" msgid "Matching ID" msgstr "معرفات مطابقة الدفع" -#: pretix/base/exporters/orderlist.py:1077 +#: pretix/base/exporters/orderlist.py:1095 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:38 #, fuzzy #| msgid "Payment settings" msgid "Payment details" msgstr "إعدادات الدفع" -#: pretix/base/exporters/orderlist.py:1127 +#: pretix/base/exporters/orderlist.py:1145 msgid "Quota availabilities" msgstr "توافر الحصة" -#: pretix/base/exporters/orderlist.py:1129 +#: pretix/base/exporters/orderlist.py:1147 msgid "" "Download a spreadsheet of all quotas including their current availability." msgstr "" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 #: pretix/control/templates/pretixcontrol/items/quotas.html:45 msgid "Quota name" msgstr "اسم الحصة" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 #: pretix/control/templates/pretixcontrol/items/quota.html:56 msgid "Total quota" msgstr "الحصة الإجمالية" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 #: pretix/control/templates/pretixcontrol/event/cancel.html:20 #: pretix/control/views/item.py:970 msgid "Paid orders" msgstr "الطلبات المدفوعة" -#: pretix/base/exporters/orderlist.py:1134 pretix/control/views/item.py:975 +#: pretix/base/exporters/orderlist.py:1152 pretix/control/views/item.py:975 msgid "Pending orders" msgstr "الطلبات المعلقة" -#: pretix/base/exporters/orderlist.py:1134 +#: pretix/base/exporters/orderlist.py:1152 msgid "Blocking vouchers" msgstr "حظر كود الخصم" -#: pretix/base/exporters/orderlist.py:1135 pretix/control/views/item.py:994 +#: pretix/base/exporters/orderlist.py:1153 pretix/control/views/item.py:994 msgid "Current user's carts" msgstr "عربات المستخدم الحالية" -#: pretix/base/exporters/orderlist.py:1135 +#: pretix/base/exporters/orderlist.py:1153 msgid "Exited orders" msgstr "طلبات خارجة" -#: pretix/base/exporters/orderlist.py:1135 +#: pretix/base/exporters/orderlist.py:1153 msgid "Current availability" msgstr "المتوفر حاليا" -#: pretix/base/exporters/orderlist.py:1152 -#: pretix/base/exporters/orderlist.py:1159 +#: pretix/base/exporters/orderlist.py:1170 +#: pretix/base/exporters/orderlist.py:1177 #: pretix/control/templates/pretixcontrol/items/quota.html:58 #: pretix/control/views/item.py:1001 msgid "Infinite" msgstr "غير محدود" -#: pretix/base/exporters/orderlist.py:1181 +#: pretix/base/exporters/orderlist.py:1199 #, fuzzy #| msgid "Gift card redemptions" msgid "Gift card transactions" msgstr "استرداد بطاقة هدية" -#: pretix/base/exporters/orderlist.py:1183 -#: pretix/base/exporters/orderlist.py:1288 +#: pretix/base/exporters/orderlist.py:1201 +#: pretix/base/exporters/orderlist.py:1306 #, fuzzy #| msgid "Gift cards" msgctxt "export_category" msgid "Gift cards" msgstr "بطاقات الهدايا" -#: pretix/base/exporters/orderlist.py:1184 +#: pretix/base/exporters/orderlist.py:1202 msgid "Download a spreadsheet of all gift card transactions." msgstr "" -#: pretix/base/exporters/orderlist.py:1212 -#: pretix/base/exporters/orderlist.py:1259 -#: pretix/base/exporters/orderlist.py:1355 pretix/base/models/giftcards.py:89 +#: pretix/base/exporters/orderlist.py:1230 +#: pretix/base/exporters/orderlist.py:1277 +#: pretix/base/exporters/orderlist.py:1373 pretix/base/models/giftcards.py:89 #: pretix/base/payment.py:1454 #: pretix/control/templates/pretixcontrol/giftcards/payment.html:4 -#: pretix/control/templates/pretixcontrol/order/index.html:506 +#: pretix/control/templates/pretixcontrol/order/index.html:558 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:28 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:56 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:152 msgid "Gift card code" msgstr "رمز بطاقة الهدية" -#: pretix/base/exporters/orderlist.py:1213 -#: pretix/base/exporters/orderlist.py:1302 -#: pretix/base/exporters/orderlist.py:1305 +#: pretix/base/exporters/orderlist.py:1231 +#: pretix/base/exporters/orderlist.py:1320 +#: pretix/base/exporters/orderlist.py:1323 #: pretix/base/models/memberships.py:120 pretix/control/forms/filter.py:244 -#: pretix/control/forms/filter.py:1417 pretix/control/forms/filter.py:1420 +#: pretix/control/forms/filter.py:1415 pretix/control/forms/filter.py:1418 #: pretix/control/templates/pretixcontrol/event/live.html:75 msgid "Test mode" msgstr "وضع الاختبار" -#: pretix/base/exporters/orderlist.py:1218 pretix/base/models/organizer.py:96 -#: pretix/control/forms/event.py:110 pretix/control/forms/event.py:116 -#: pretix/control/forms/filter.py:888 pretix/control/forms/filter.py:1006 -#: pretix/control/forms/filter.py:1682 +#: pretix/base/exporters/orderlist.py:1236 pretix/base/models/organizer.py:102 +#: pretix/control/forms/event.py:110 pretix/control/forms/filter.py:888 +#: pretix/control/forms/filter.py:1006 pretix/control/forms/filter.py:1680 #: pretix/control/templates/pretixcontrol/email_setup.html:6 #: pretix/control/templates/pretixcontrol/email_setup_simple.html:6 #: pretix/control/templates/pretixcontrol/email_setup_smtp.html:6 @@ -2744,8 +3061,8 @@ msgstr "وضع الاختبار" msgid "Organizer" msgstr "منظم" -#: pretix/base/exporters/orderlist.py:1225 pretix/base/invoice.py:573 -#: pretix/control/templates/pretixcontrol/base.html:283 +#: pretix/base/exporters/orderlist.py:1243 pretix/base/invoicing/pdf.py:576 +#: pretix/control/templates/pretixcontrol/base.html:281 #: pretix/control/templates/pretixcontrol/checkin/index.html:145 #: pretix/control/templates/pretixcontrol/order/index.html:25 #: pretix/control/templates/pretixcontrol/orders/bulk_action.html:38 @@ -2772,106 +3089,107 @@ msgstr "منظم" msgid "TEST MODE" msgstr "وضع الاختبار" -#: pretix/base/exporters/orderlist.py:1240 +#: pretix/base/exporters/orderlist.py:1258 msgid "Gift card redemptions" msgstr "استرداد بطاقة هدية" -#: pretix/base/exporters/orderlist.py:1242 +#: pretix/base/exporters/orderlist.py:1260 msgid "" "Download a spreadsheet of all payments or refunds that involve gift cards." msgstr "" -#: pretix/base/exporters/orderlist.py:1259 +#: pretix/base/exporters/orderlist.py:1277 #: pretix/control/templates/pretixcontrol/giftcards/payment.html:16 msgid "Issuer" msgstr "جهة الاصدار" -#: pretix/base/exporters/orderlist.py:1286 pretix/control/navigation.py:538 -#: pretix/control/navigation.py:556 +#: pretix/base/exporters/orderlist.py:1304 pretix/control/navigation.py:550 +#: pretix/control/navigation.py:568 #: pretix/control/templates/pretixcontrol/organizers/edit.html:156 -#: pretix/plugins/reports/accountingreport.py:898 +#: pretix/plugins/reports/accountingreport.py:899 msgid "Gift cards" msgstr "بطاقات الهدايا" -#: pretix/base/exporters/orderlist.py:1289 +#: pretix/base/exporters/orderlist.py:1307 msgid "Download a spreadsheet of all gift cards including their current value." msgstr "" -#: pretix/base/exporters/orderlist.py:1296 +#: pretix/base/exporters/orderlist.py:1314 msgid "Show value at" msgstr "إظهار القيمة عند" -#: pretix/base/exporters/orderlist.py:1299 +#: pretix/base/exporters/orderlist.py:1317 msgid "Defaults to the time of report." msgstr "" -#: pretix/base/exporters/orderlist.py:1304 -#: pretix/base/exporters/orderlist.py:1314 pretix/control/forms/filter.py:519 -#: pretix/control/forms/filter.py:1200 pretix/control/forms/filter.py:1419 -#: pretix/control/forms/filter.py:1428 pretix/control/forms/filter.py:1498 -#: pretix/control/forms/filter.py:1508 pretix/control/forms/filter.py:1570 -#: pretix/control/forms/filter.py:2009 pretix/control/forms/filter.py:2018 -#: pretix/control/forms/filter.py:2089 pretix/control/forms/filter.py:2102 -#: pretix/control/forms/filter.py:2608 pretix/control/forms/filter.py:2627 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:134 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:140 +#: pretix/base/exporters/orderlist.py:1322 +#: pretix/base/exporters/orderlist.py:1332 pretix/control/forms/filter.py:519 +#: pretix/control/forms/filter.py:1200 pretix/control/forms/filter.py:1417 +#: pretix/control/forms/filter.py:1426 pretix/control/forms/filter.py:1496 +#: pretix/control/forms/filter.py:1506 pretix/control/forms/filter.py:1568 +#: pretix/control/forms/filter.py:2005 pretix/control/forms/filter.py:2014 +#: pretix/control/forms/filter.py:2085 pretix/control/forms/filter.py:2098 +#: pretix/control/forms/filter.py:2604 pretix/control/forms/filter.py:2623 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:141 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:147 #: pretix/control/templates/pretixcontrol/event/plugins.html:24 #: pretix/control/templates/pretixcontrol/items/discounts.html:113 #: pretix/control/templates/pretixcontrol/organizers/devices.html:147 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:24 #: pretix/control/templates/pretixcontrol/organizers/teams.html:61 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:52 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:43 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:62 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:76 -#: pretix/plugins/reports/accountingreport.py:104 +#: pretix/plugins/reports/accountingreport.py:105 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:67 msgid "All" msgstr "الكل" -#: pretix/base/exporters/orderlist.py:1306 pretix/control/forms/filter.py:1421 +#: pretix/base/exporters/orderlist.py:1324 pretix/control/forms/filter.py:1419 msgid "Live" msgstr "مباشر" -#: pretix/base/exporters/orderlist.py:1315 pretix/control/forms/filter.py:1429 -#: pretix/control/templates/pretixcontrol/pdf/index.html:265 +#: pretix/base/exporters/orderlist.py:1333 pretix/control/forms/filter.py:1427 +#: pretix/control/templates/pretixcontrol/pdf/index.html:325 msgid "Empty" msgstr "فارغ" -#: pretix/base/exporters/orderlist.py:1316 pretix/control/forms/filter.py:1430 +#: pretix/base/exporters/orderlist.py:1334 pretix/control/forms/filter.py:1428 msgid "Valid and with value" msgstr "صالحة وذات قيمة" -#: pretix/base/exporters/orderlist.py:1317 pretix/control/forms/filter.py:1431 +#: pretix/base/exporters/orderlist.py:1335 pretix/control/forms/filter.py:1429 msgid "Expired and with value" msgstr "منتهية الصلاحية وذات قيمة" -#: pretix/base/exporters/orderlist.py:1318 pretix/control/forms/filter.py:227 -#: pretix/control/forms/filter.py:1432 pretix/control/forms/filter.py:2094 +#: pretix/base/exporters/orderlist.py:1336 pretix/control/forms/filter.py:227 +#: pretix/control/forms/filter.py:1430 pretix/control/forms/filter.py:2090 #: pretix/control/templates/pretixcontrol/items/question.html:31 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:37 #: pretix/control/templates/pretixcontrol/orders/overview.html:78 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:84 -#: pretix/plugins/reports/exporters.py:378 +#: pretix/plugins/reports/exporters.py:389 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:26 msgid "Expired" msgstr "منتهية الصلاحية" -#: pretix/base/exporters/orderlist.py:1356 pretix/base/models/giftcards.py:98 +#: pretix/base/exporters/orderlist.py:1374 pretix/base/models/giftcards.py:98 msgid "Test mode card" msgstr "بطاقة وضع الاختبار" -#: pretix/base/exporters/orderlist.py:1358 -#: pretix/base/modelimport_orders.py:516 pretix/base/models/giftcards.py:102 +#: pretix/base/exporters/orderlist.py:1376 +#: pretix/base/modelimport_orders.py:553 pretix/base/models/giftcards.py:102 #: pretix/control/templates/pretixcontrol/order/index.html:203 #: pretix/control/templates/pretixcontrol/organizers/giftcards.html:62 msgid "Expiry date" msgstr "تاريخ الانتهاء" -#: pretix/base/exporters/orderlist.py:1359 pretix/control/forms/orders.py:892 +#: pretix/base/exporters/orderlist.py:1377 pretix/control/forms/orders.py:902 msgid "Special terms and conditions" msgstr "شروط وأحكام خاصة" -#: pretix/base/exporters/orderlist.py:1361 +#: pretix/base/exporters/orderlist.py:1379 #: pretix/control/templates/pretixcontrol/order/change.html:98 #: pretix/control/templates/pretixcontrol/order/change.html:410 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:32 @@ -2879,19 +3197,19 @@ msgstr "شروط وأحكام خاصة" msgid "Current value" msgstr "القيمة الحالية" -#: pretix/base/exporters/orderlist.py:1362 +#: pretix/base/exporters/orderlist.py:1380 msgid "Created in order" msgstr "تم الإنشاء بالترتيب" -#: pretix/base/exporters/orderlist.py:1363 +#: pretix/base/exporters/orderlist.py:1381 msgid "Last invoice number of order" msgstr "رقم الفاتورة الأخير للطلب" -#: pretix/base/exporters/orderlist.py:1364 +#: pretix/base/exporters/orderlist.py:1382 msgid "Last invoice date of order" msgstr "تاريخ آخر فاتورة للطلب" -#: pretix/base/exporters/reusablemedia.py:34 pretix/control/navigation.py:616 +#: pretix/base/exporters/reusablemedia.py:34 pretix/control/navigation.py:628 #: pretix/control/templates/pretixcontrol/organizers/edit.html:222 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:35 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:114 @@ -2927,7 +3245,7 @@ msgid "Identifier" msgstr "معرف داخلي" #: pretix/base/exporters/reusablemedia.py:49 pretix/base/models/media.py:81 -#: pretix/base/models/orders.py:265 pretix/base/models/orders.py:3098 +#: pretix/base/models/orders.py:265 pretix/base/models/orders.py:3109 #: pretix/control/forms/orders.py:78 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:138 msgid "Expiration date" @@ -2935,7 +3253,8 @@ msgstr "تاريخ إنتهاء الصلاحية" #: pretix/base/exporters/reusablemedia.py:50 pretix/base/models/media.py:90 #: pretix/control/templates/pretixcontrol/order/index.html:216 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:133 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:136 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:8 #, fuzzy #| msgid "Customer actions" msgid "Customer account" @@ -3000,7 +3319,7 @@ msgid "Voucher expired" msgstr "كود الخصم منتهية الصلاحية" #: pretix/base/exporters/waitinglist.py:117 -#: pretix/base/modelimport_orders.py:95 pretix/base/modelimport_vouchers.py:60 +#: pretix/base/modelimport_orders.py:111 pretix/base/modelimport_vouchers.py:60 #: pretix/control/templates/pretixcontrol/checkin/index.html:100 msgctxt "subevents" msgid "Date" @@ -3011,19 +3330,6 @@ msgstr "التاريخ" msgid "Priority" msgstr "الأولوية" -#: pretix/base/exporters/waitinglist.py:123 -#: pretix/base/modelimport_vouchers.py:39 pretix/base/models/vouchers.py:190 -#: pretix/control/templates/pretixcontrol/vouchers/index.html:18 -#: pretix/control/templates/pretixcontrol/vouchers/index.html:114 -#: pretix/control/views/vouchers.py:119 pretix/control/views/waitinglist.py:314 -#: pretix/plugins/checkinlists/exporters.py:519 -#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:74 -#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:76 -#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:12 -#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:20 -msgid "Voucher code" -msgstr "رمز كود الخصم" - #: pretix/base/forms/__init__.py:95 pretix/base/forms/__init__.py:106 #: pretix/base/forms/__init__.py:118 #, python-brace-format @@ -3135,30 +3441,64 @@ msgstr "" msgid "Street and Number" msgstr "الشارع والرقم" -#: pretix/base/forms/questions.py:1154 +#: pretix/base/forms/questions.py:1162 msgid "" "Optional, but depending on the country you reside in we might need to charge " "you additional taxes if you do not enter it." msgstr "" -#: pretix/base/forms/questions.py:1156 pretix/base/forms/questions.py:1162 +#: pretix/base/forms/questions.py:1164 pretix/base/forms/questions.py:1170 msgid "If you are registered in Switzerland, you can enter your UID instead." msgstr "" -#: pretix/base/forms/questions.py:1160 +#: pretix/base/forms/questions.py:1168 msgid "" "Optional, but it might be required for you to claim tax benefits on your " "invoice depending on your and the seller’s country of residence." msgstr "" -#: pretix/base/forms/questions.py:1266 +#: pretix/base/forms/questions.py:1177 +#, fuzzy +#| msgid "Cancellation requested" +msgid "No invoice requested" +msgstr "طلبات الإلغاء" + +#: pretix/base/forms/questions.py:1179 +msgid "Invoice transmission method" +msgstr "" + +#: pretix/base/forms/questions.py:1324 msgid "You need to provide a company name." msgstr "تحتاج إلى تقديم اسم شركة." -#: pretix/base/forms/questions.py:1268 +#: pretix/base/forms/questions.py:1326 msgid "You need to provide your name." msgstr "تحتاج إلى تقديم اسمك." +#: pretix/base/forms/questions.py:1352 +msgid "" +"If you enter an invoice address, you also need to select an invoice " +"transmission method." +msgstr "" + +#: pretix/base/forms/questions.py:1380 +#, fuzzy +#| msgid "The selected product is not active or has no price set." +msgid "" +"The selected transmission type is not available in your country or for your " +"type of address." +msgstr "المنتج المحدد غير نشط أو ليس له سعر محدد." + +#: pretix/base/forms/questions.py:1389 +msgid "" +"The selected type of invoice transmission requires a field that is currently " +"not available, please reach out to the organizer." +msgstr "" + +#: pretix/base/forms/questions.py:1393 +msgid "This field is required for the selected type of invoice transmission." +msgstr "" + #: pretix/base/forms/user.py:51 pretix/control/forms/users.py:43 msgid "" "There already is an account associated with this email address. Please " @@ -3239,7 +3579,7 @@ msgid "" "\"{{\" and \"}}\"." msgstr "" -#: pretix/base/forms/validators.py:72 pretix/control/views/event.py:807 +#: pretix/base/forms/validators.py:72 pretix/control/views/event.py:851 #, fuzzy, python-format #| msgid "Invalid placeholder(s): %(value)s" msgid "Invalid placeholder: {%(value)s}" @@ -3257,7 +3597,7 @@ msgid "Available placeholders: {list}" msgstr "النائبة المتاحة: {list}" #: pretix/base/forms/widgets.py:214 pretix/base/models/items.py:1656 -#: pretix/base/reldate.py:216 pretix/plugins/checkinlists/exporters.py:753 +#: pretix/plugins/checkinlists/exporters.py:754 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:40 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:54 msgid "Time" @@ -3271,68 +3611,121 @@ msgstr "عميل قطاع الأعمال أو عميل مؤسسة" msgid "Individual customer" msgstr "عميل فردي" -#: pretix/base/invoice.py:138 +#: pretix/base/invoicing/email.py:50 +msgid "Email invoice directly to accounting department" +msgstr "" + +#: pretix/base/invoicing/email.py:51 +#, fuzzy +#| msgid "Please enter the same email address twice." +msgid "" +"If not selected, the invoice will be sent to you using the email address " +"listed above." +msgstr "الرجاء إدخال نفس عنوان البريد الإلكتروني مرتين." + +#: pretix/base/invoicing/email.py:55 +#, fuzzy +#| msgid "Email address verified" +msgid "Email address for invoice" +msgstr "تم التحقق من عنوان البريد الإلكتروني" + +#: pretix/base/invoicing/email.py:91 +#, fuzzy +#| msgid "Preview email" +msgid "PDF via email" +msgstr "البريد الإلكتروني المعاينة" + +#: pretix/base/invoicing/national.py:37 +msgctxt "italian_invoice" +msgid "Italian Exchange System (SdI)" +msgstr "" + +#: pretix/base/invoicing/national.py:38 +msgctxt "italian_invoice" +msgid "Exchange System (SdI)" +msgstr "" + +#: pretix/base/invoicing/national.py:49 +#, fuzzy +#| msgid "Gift card code" +msgctxt "italian_invoice" +msgid "Fiscal code" +msgstr "رمز بطاقة الهدية" + +#: pretix/base/invoicing/national.py:53 +msgctxt "italian_invoice" +msgid "Address for certified electronic mail" +msgstr "" + +#: pretix/base/invoicing/national.py:57 +#, fuzzy +#| msgid "Recipient" +msgctxt "italian_invoice" +msgid "Recipient code" +msgstr "مستلم" + +#: pretix/base/invoicing/pdf.py:140 #, python-format msgctxt "invoice" msgid "Page %d of %d" msgstr "صفحة %d من %d" -#: pretix/base/invoice.py:375 +#: pretix/base/invoicing/pdf.py:378 msgctxt "invoice" msgid "Classic renderer (pretix 1.0)" msgstr "المقدم الكلاسيكي (pretix 1.0)" -#: pretix/base/invoice.py:419 +#: pretix/base/invoicing/pdf.py:422 msgctxt "invoice" msgid "Invoice from" msgstr "فاتورة من طرف" -#: pretix/base/invoice.py:425 +#: pretix/base/invoicing/pdf.py:428 msgctxt "invoice" msgid "Invoice to" msgstr "فاتورة إلى" -#: pretix/base/invoice.py:462 pretix/base/invoice.py:1016 +#: pretix/base/invoicing/pdf.py:465 pretix/base/invoicing/pdf.py:1033 msgctxt "invoice" msgid "Order code" msgstr "رمز الطلب" -#: pretix/base/invoice.py:471 pretix/base/invoice.py:1029 +#: pretix/base/invoicing/pdf.py:474 pretix/base/invoicing/pdf.py:1046 msgctxt "invoice" msgid "Cancellation number" msgstr "رقم الإلغاء" -#: pretix/base/invoice.py:477 pretix/base/invoice.py:1031 +#: pretix/base/invoicing/pdf.py:480 pretix/base/invoicing/pdf.py:1048 msgctxt "invoice" msgid "Original invoice" msgstr "فاتورة أصلية" -#: pretix/base/invoice.py:482 pretix/base/invoice.py:1036 +#: pretix/base/invoicing/pdf.py:485 pretix/base/invoicing/pdf.py:1053 msgctxt "invoice" msgid "Invoice number" msgstr "رقم الفاتورة" -#: pretix/base/invoice.py:490 pretix/base/invoice.py:1051 +#: pretix/base/invoicing/pdf.py:493 pretix/base/invoicing/pdf.py:1068 msgctxt "invoice" msgid "Cancellation date" msgstr "تاريخ الإلغاء" -#: pretix/base/invoice.py:496 +#: pretix/base/invoicing/pdf.py:499 msgctxt "invoice" msgid "Original invoice date" msgstr "تاريخ الفاتورة الأصلي" -#: pretix/base/invoice.py:503 pretix/base/invoice.py:1053 +#: pretix/base/invoicing/pdf.py:506 pretix/base/invoicing/pdf.py:1070 msgctxt "invoice" msgid "Invoice date" msgstr "تاريخ الفاتورة" -#: pretix/base/invoice.py:519 +#: pretix/base/invoicing/pdf.py:522 msgctxt "invoice" msgid "Event" msgstr "الفعالية" -#: pretix/base/invoice.py:545 +#: pretix/base/invoicing/pdf.py:548 #, python-brace-format msgctxt "invoice" msgid "" @@ -3342,39 +3735,39 @@ msgstr "" "من {from_date}\n" "حتى {to_date}" -#: pretix/base/invoice.py:578 pretix/base/services/mail.py:502 +#: pretix/base/invoicing/pdf.py:581 pretix/base/services/mail.py:502 #, python-brace-format msgctxt "invoice" msgid "Invoice {num}" msgstr "فاتورة {num}" -#: pretix/base/invoice.py:621 +#: pretix/base/invoicing/pdf.py:624 #, python-brace-format msgctxt "invoice" msgid "Customer reference: {reference}" msgstr "رقم مرجع العميل: {reference}" -#: pretix/base/invoice.py:629 +#: pretix/base/invoicing/pdf.py:632 msgctxt "invoice" msgid "Customer VAT ID" msgstr "معرف ضريبة القيمة المضافة للعميل" -#: pretix/base/invoice.py:636 +#: pretix/base/invoicing/pdf.py:639 msgctxt "invoice" msgid "Beneficiary" msgstr "المستفيد" -#: pretix/base/invoice.py:657 +#: pretix/base/invoicing/pdf.py:665 msgctxt "invoice" msgid "Tax Invoice" msgstr "فاتورة الضريبة" -#: pretix/base/invoice.py:658 +#: pretix/base/invoicing/pdf.py:666 msgctxt "invoice" msgid "Invoice" msgstr "فاتورة" -#: pretix/base/invoice.py:659 +#: pretix/base/invoicing/pdf.py:667 #: pretix/control/templates/pretixcontrol/order/index.html:272 #: pretix/control/templates/pretixcontrol/order/mail_history.html:70 #: pretix/presale/templates/pretixpresale/event/order.html:244 @@ -3382,99 +3775,99 @@ msgctxt "invoice" msgid "Cancellation" msgstr "إلغاء" -#: pretix/base/invoice.py:681 pretix/base/invoice.py:689 +#: pretix/base/invoicing/pdf.py:689 pretix/base/invoicing/pdf.py:697 msgctxt "invoice" msgid "Description" msgstr "وصف" -#: pretix/base/invoice.py:682 pretix/base/invoice.py:690 +#: pretix/base/invoicing/pdf.py:690 pretix/base/invoicing/pdf.py:698 msgctxt "invoice" msgid "Qty" msgstr "الكمية" -#: pretix/base/invoice.py:683 pretix/base/invoice.py:833 +#: pretix/base/invoicing/pdf.py:691 pretix/base/invoicing/pdf.py:850 msgctxt "invoice" msgid "Tax rate" msgstr "معدل الضريبة" -#: pretix/base/invoice.py:684 +#: pretix/base/invoicing/pdf.py:692 msgctxt "invoice" msgid "Net" msgstr "الصافي" -#: pretix/base/invoice.py:685 +#: pretix/base/invoicing/pdf.py:693 msgctxt "invoice" msgid "Gross" msgstr "الإجمالي" -#: pretix/base/invoice.py:691 +#: pretix/base/invoicing/pdf.py:699 msgctxt "invoice" msgid "Amount" msgstr "المبلغ" -#: pretix/base/invoice.py:707 +#: pretix/base/invoicing/pdf.py:715 #, python-brace-format msgctxt "invoice" msgid "Single price: {net_price} net / {gross_price} gross" msgstr "" -#: pretix/base/invoice.py:724 +#: pretix/base/invoicing/pdf.py:738 #, fuzzy, python-brace-format #| msgid "Original price" msgctxt "invoice" msgid "Single price: {price}" msgstr "السعر الأصلي" -#: pretix/base/invoice.py:742 pretix/base/invoice.py:748 +#: pretix/base/invoicing/pdf.py:759 pretix/base/invoicing/pdf.py:765 msgctxt "invoice" msgid "Invoice total" msgstr "إجمالي الفاتورة" -#: pretix/base/invoice.py:758 +#: pretix/base/invoicing/pdf.py:775 msgctxt "invoice" msgid "Received payments" msgstr "المدفوعات المستلمة" -#: pretix/base/invoice.py:763 +#: pretix/base/invoicing/pdf.py:780 msgctxt "invoice" msgid "Outstanding payments" msgstr "المدفوعات المتأخرة" -#: pretix/base/invoice.py:780 +#: pretix/base/invoicing/pdf.py:797 #, fuzzy #| msgid "Issued gift cards" msgctxt "invoice" msgid "Paid by gift card" msgstr "بطاقات هدية صدر" -#: pretix/base/invoice.py:785 +#: pretix/base/invoicing/pdf.py:802 #, fuzzy #| msgid "Pending amount" msgctxt "invoice" msgid "Remaining amount" msgstr "مبالغ متأخرة" -#: pretix/base/invoice.py:834 +#: pretix/base/invoicing/pdf.py:851 msgctxt "invoice" msgid "Net value" msgstr "صافي القيمة" -#: pretix/base/invoice.py:835 +#: pretix/base/invoicing/pdf.py:852 msgctxt "invoice" msgid "Gross value" msgstr "القيمة الإجمالية" -#: pretix/base/invoice.py:836 +#: pretix/base/invoicing/pdf.py:853 msgctxt "invoice" msgid "Tax" msgstr "الضريبة" -#: pretix/base/invoice.py:866 +#: pretix/base/invoicing/pdf.py:883 msgctxt "invoice" msgid "Included taxes" msgstr "الضرائب المدرجة" -#: pretix/base/invoice.py:894 +#: pretix/base/invoicing/pdf.py:911 #, fuzzy, python-brace-format #| msgctxt "invoice" #| msgid "" @@ -3488,7 +3881,7 @@ msgstr "" "باستخدام معدل التحويل 1: {rate} كما نشره البنك المركزي الأوروبي بتاريخ " "{date} ، وهذا يعادل:" -#: pretix/base/invoice.py:909 +#: pretix/base/invoicing/pdf.py:926 #, fuzzy, python-brace-format #| msgctxt "invoice" #| msgid "" @@ -3502,28 +3895,51 @@ msgstr "" "باستخدام معدل التحويل 1: {rate} كما نشره البنك المركزي الأوروبي بتاريخ " "{date} ، إجمالي الفاتورة يعادل {total}." -#: pretix/base/invoice.py:923 +#: pretix/base/invoicing/pdf.py:940 msgid "Default invoice renderer (European-style letter)" msgstr "" -#: pretix/base/invoice.py:1012 +#: pretix/base/invoicing/pdf.py:1029 #, fuzzy #| msgid "Please enter a valid state." msgctxt "invoice" msgid "(Please quote at all times.)" msgstr "الرجاء اختيار ولاية صحيحة." -#: pretix/base/invoice.py:1059 +#: pretix/base/invoicing/pdf.py:1076 msgid "Simplified invoice renderer" msgstr "" -#: pretix/base/invoice.py:1078 +#: pretix/base/invoicing/pdf.py:1095 #, fuzzy, python-brace-format #| msgid "Event date range" msgctxt "invoice" msgid "Event date: {date_range}" msgstr "نطاق تاريخ الفعالية" +#: pretix/base/invoicing/peppol.py:128 +msgid "" +"A PEPPOL participant ID always starts with a prefix, followed by a colon (:)." +msgstr "" + +#: pretix/base/invoicing/peppol.py:132 +#, python-format +msgid "" +"The PEPPOL participant ID prefix %(number)s is not known to our system. " +"Please reach out to us if you are sure this ID is correct." +msgstr "" + +#: pretix/base/invoicing/peppol.py:136 +#, python-format +msgid "" +"The PEPPOL participant ID does not match the validation rules for the prefix " +"%(number)s. Please reach out to us if you are sure this ID is correct." +msgstr "" + +#: pretix/base/invoicing/peppol.py:156 +msgid "PEPPOL participant ID" +msgstr "" + #: pretix/base/logentrytype_registry.py:43 msgid "" "The relevant plugin is currently not active. To activate it, click here to " @@ -3589,13 +4005,6 @@ msgstr "سؤال{val}" msgid "Tax rule {val}" msgstr "قاعدة الضريبة {val}" -#: pretix/base/logentrytypes.py:151 -#, fuzzy, python-brace-format -#| msgctxt "subevent" -#| msgid "Date {val}" -msgid "{val}" -msgstr "تاريخ {val}" - #: pretix/base/media.py:71 msgid "Barcode / QR-Code" msgstr "" @@ -3614,150 +4023,188 @@ msgstr "القائمة الافتراضية" msgid "Keep empty" msgstr "أبقه فارغا" -#: pretix/base/modelimport.py:139 +#: pretix/base/modelimport.py:146 #, python-brace-format msgid "Invalid setting for column \"{header}\"." msgstr "إعداد غير صالح للعمود \"{header}\"." -#: pretix/base/modelimport.py:199 +#: pretix/base/modelimport.py:206 #, python-brace-format msgid "Could not parse {value} as a yes/no value." msgstr "" -#: pretix/base/modelimport.py:222 +#: pretix/base/modelimport.py:229 #, python-brace-format msgid "Could not parse {value} as a date and time." msgstr "" -#: pretix/base/modelimport.py:232 pretix/control/views/orders.py:1184 -#: pretix/control/views/orders.py:1213 pretix/control/views/orders.py:1257 -#: pretix/control/views/orders.py:1292 pretix/control/views/orders.py:1315 +#: pretix/base/modelimport.py:239 pretix/control/views/orders.py:1169 +#: pretix/control/views/orders.py:1198 pretix/control/views/orders.py:1242 +#: pretix/control/views/orders.py:1277 pretix/control/views/orders.py:1300 msgid "You entered an invalid number." msgstr "لقد أدخلت رقما غير صالح." -#: pretix/base/modelimport.py:279 pretix/base/modelimport.py:291 +#: pretix/base/modelimport.py:286 pretix/base/modelimport.py:298 msgctxt "subevent" msgid "No matching date was found." msgstr "لم يتم العثور على تاريخ مطابق." -#: pretix/base/modelimport.py:281 pretix/base/modelimport.py:293 +#: pretix/base/modelimport.py:288 pretix/base/modelimport.py:300 msgctxt "subevent" msgid "Multiple matching dates were found." msgstr "تم العثور على تواريخ مطابقة متعددة." -#: pretix/base/modelimport_orders.py:85 +#: pretix/base/modelimport_orders.py:73 +msgid "Grouping" +msgstr "" + +#: pretix/base/modelimport_orders.py:75 +msgid "" +"Only applicable when \"Import mode\" is set to \"Group multiple lines " +"together...\". Lines with the same grouping value will be put in the same " +"order, but MUST be consecutive lines of the input file." +msgstr "" + +#: pretix/base/modelimport_orders.py:101 #, fuzzy #| msgid "You entered an invalid number." msgid "Enter a valid phone number." msgstr "لقد أدخلت رقما غير صالح." -#: pretix/base/modelimport_orders.py:100 pretix/presale/views/waiting.py:157 +#: pretix/base/modelimport_orders.py:114 +msgctxt "subevents" +msgid "" +"The date can be specified through its full name, full date and time, or " +"internal ID, provided only one date in the system matches the input." +msgstr "" + +#: pretix/base/modelimport_orders.py:120 pretix/presale/views/waiting.py:157 msgctxt "subevent" msgid "You need to select a date." msgstr "تحتاج إلى تحديد تاريخ." -#: pretix/base/modelimport_orders.py:128 +#: pretix/base/modelimport_orders.py:131 +msgid "" +"The product can be specified by its internal ID, full name or internal name." +msgstr "" + +#: pretix/base/modelimport_orders.py:149 #: pretix/base/modelimport_vouchers.py:194 msgid "No matching product was found." msgstr "لم يتم العثور على منتج مطابق." -#: pretix/base/modelimport_orders.py:130 +#: pretix/base/modelimport_orders.py:151 #: pretix/base/modelimport_vouchers.py:196 msgid "Multiple matching products were found." msgstr "تم العثور على منتجات مطابقة متعددة." -#: pretix/base/modelimport_orders.py:139 +#: pretix/base/modelimport_orders.py:160 #: pretix/base/modelimport_vouchers.py:205 pretix/base/models/items.py:1257 -#: pretix/base/models/vouchers.py:263 pretix/base/models/waitinglist.py:99 +#: pretix/base/models/vouchers.py:266 pretix/base/models/waitinglist.py:99 msgid "Product variation" msgstr "نوع المنتج" -#: pretix/base/modelimport_orders.py:159 +#: pretix/base/modelimport_orders.py:161 +msgid "The variation can be specified by its internal ID or full name." +msgstr "" + +#: pretix/base/modelimport_orders.py:181 #: pretix/base/modelimport_vouchers.py:225 #: pretix/base/modelimport_vouchers.py:259 msgid "No matching variation was found." msgstr "لم يتم العثور على نوع مطابق." -#: pretix/base/modelimport_orders.py:161 +#: pretix/base/modelimport_orders.py:183 #: pretix/base/modelimport_vouchers.py:227 #: pretix/base/modelimport_vouchers.py:261 msgid "Multiple matching variations were found." msgstr "تم العثور على أصناف مطابقة متعددة." -#: pretix/base/modelimport_orders.py:164 +#: pretix/base/modelimport_orders.py:186 msgid "You need to select a variation for this product." msgstr "تحتاج إلى تحديد صنف مختلف لهذا المنتج." -#: pretix/base/modelimport_orders.py:176 pretix/base/modelimport_orders.py:191 -#: pretix/base/modelimport_orders.py:206 pretix/base/modelimport_orders.py:217 -#: pretix/base/modelimport_orders.py:228 pretix/base/modelimport_orders.py:244 -#: pretix/base/modelimport_orders.py:263 pretix/base/modelimport_orders.py:288 -#: pretix/base/modelimport_orders.py:299 pretix/control/forms/filter.py:621 -#: pretix/control/forms/filter.py:625 pretix/control/forms/filter.py:629 -#: pretix/control/forms/filter.py:633 pretix/control/forms/filter.py:638 -#: pretix/control/forms/filter.py:643 -msgid "Invoice address" -msgstr "عنوان الفاتورة" +#: pretix/base/modelimport_orders.py:265 pretix/base/modelimport_orders.py:417 +#, fuzzy +#| msgid "The count needs to be equal to or greater than zero." +msgid "The country needs to be specified using a two-letter country code." +msgstr "يجب أن يكون العدد مساويا للصفر أو أكبر منه." -#: pretix/base/modelimport_orders.py:251 pretix/base/modelimport_orders.py:397 +#: pretix/base/modelimport_orders.py:281 pretix/base/modelimport_orders.py:432 msgid "Please enter a valid country code." msgstr "الرجاء إدخال رمز دولة صالح." -#: pretix/base/modelimport_orders.py:268 pretix/base/modelimport_orders.py:414 +#: pretix/base/modelimport_orders.py:290 pretix/base/modelimport_orders.py:441 +msgid "The state can be specified by its short form or full name." +msgstr "" + +#: pretix/base/modelimport_orders.py:300 pretix/base/modelimport_orders.py:450 msgid "States are not supported for this country." msgstr "خيار الولايات غير متاح لهذا البلد." -#: pretix/base/modelimport_orders.py:276 pretix/base/modelimport_orders.py:422 +#: pretix/base/modelimport_orders.py:308 pretix/base/modelimport_orders.py:458 msgid "Please enter a valid state." msgstr "الرجاء اختيار ولاية صحيحة." -#: pretix/base/modelimport_orders.py:325 pretix/control/forms/filter.py:652 +#: pretix/base/modelimport_orders.py:359 pretix/control/forms/filter.py:652 msgid "Attendee email address" msgstr "عنوان البريد الإلكتروني للحاضر" -#: pretix/base/modelimport_orders.py:341 pretix/base/modelimport_orders.py:352 -#: pretix/base/modelimport_orders.py:363 pretix/base/modelimport_orders.py:374 -#: pretix/base/modelimport_orders.py:390 pretix/base/modelimport_orders.py:409 +#: pretix/base/modelimport_orders.py:375 pretix/base/modelimport_orders.py:386 +#: pretix/base/modelimport_orders.py:397 pretix/base/modelimport_orders.py:408 +#: pretix/base/modelimport_orders.py:425 pretix/base/modelimport_orders.py:445 #: pretix/control/forms/filter.py:656 pretix/control/forms/filter.py:660 #: pretix/control/forms/filter.py:664 pretix/control/forms/filter.py:669 #: pretix/control/forms/filter.py:674 -#: pretix/control/templates/pretixcontrol/order/index.html:551 +#: pretix/control/templates/pretixcontrol/order/index.html:603 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:193 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:196 msgid "Attendee address" msgstr "عنوان الحاضر" -#: pretix/base/modelimport_orders.py:409 +#: pretix/base/modelimport_orders.py:445 msgid "State" msgstr "ولاية" -#: pretix/base/modelimport_orders.py:432 +#: pretix/base/modelimport_orders.py:468 msgid "Calculate from product" msgstr "احسب من المنتج" -#: pretix/base/modelimport_orders.py:450 +#: pretix/base/modelimport_orders.py:486 #: pretix/control/templates/pretixcontrol/checkin/index.html:111 -#: pretix/control/templates/pretixcontrol/order/index.html:491 +#: pretix/control/templates/pretixcontrol/order/index.html:531 msgid "Ticket code" msgstr "رمز التذكرة" -#: pretix/base/modelimport_orders.py:451 +#: pretix/base/modelimport_orders.py:487 msgid "Generate automatically" msgstr "إنشاء تلقائي" -#: pretix/base/modelimport_orders.py:460 +#: pretix/base/modelimport_orders.py:496 msgid "You cannot assign a position secret that already exists." msgstr "لا يمكنك تعيين وضع سري موجود مسبقا." -#: pretix/base/modelimport_orders.py:491 +#: pretix/base/modelimport_orders.py:528 msgid "Please enter a valid language code." msgstr "الرجاء إدخال رمز لغة صالح." -#: pretix/base/modelimport_orders.py:559 pretix/base/modelimport_orders.py:561 +#: pretix/base/modelimport_orders.py:581 +msgid "" +"The sales channel can be specified by it's internal identifier or its full " +"name." +msgstr "" + +#: pretix/base/modelimport_orders.py:599 pretix/base/modelimport_orders.py:601 msgid "Please enter a valid sales channel." msgstr "الرجاء إدخال قناة بيع صالحة." -#: pretix/base/modelimport_orders.py:585 +#: pretix/base/modelimport_orders.py:611 +#, fuzzy +#| msgid "The refund amount needs to be positive and less than {}." +msgid "The seat needs to be specified by its internal ID." +msgstr "احتياجات المبلغ المسترد لتكون إيجابية وأقل من {}." + +#: pretix/base/modelimport_orders.py:626 #: pretix/base/modelimport_vouchers.py:291 #, fuzzy #| msgctxt "subevent" @@ -3765,57 +4212,56 @@ msgstr "الرجاء إدخال قناة بيع صالحة." msgid "Multiple matching seats were found." msgstr "تم العثور على تواريخ مطابقة متعددة." -#: pretix/base/modelimport_orders.py:587 +#: pretix/base/modelimport_orders.py:628 #: pretix/base/modelimport_vouchers.py:293 msgid "No matching seat was found." msgstr "لم يتم العثور على مقعد مطابق." -#: pretix/base/modelimport_orders.py:590 +#: pretix/base/modelimport_orders.py:631 #: pretix/base/modelimport_vouchers.py:296 pretix/base/services/cart.py:213 -#: pretix/base/services/modelimport.py:134 -#: pretix/base/services/modelimport.py:246 +#: pretix/base/services/modelimport.py:175 +#: pretix/base/services/modelimport.py:287 msgid "" "The seat you selected has already been taken. Please select a different seat." msgstr "المقعد الذي اخترته قد تم شغله مسبقا. الرجاء اختيار مقعد مختلف." -#: pretix/base/modelimport_orders.py:593 pretix/base/services/cart.py:210 +#: pretix/base/modelimport_orders.py:634 pretix/base/services/cart.py:210 msgid "You need to select a specific seat." msgstr "يجب أن تختار مقعدا محددا." -#: pretix/base/modelimport_orders.py:647 pretix/base/models/items.py:1671 -#: pretix/base/models/items.py:1766 pretix/control/forms/item.py:149 +#: pretix/base/modelimport_orders.py:691 pretix/base/models/items.py:1671 +#: pretix/base/models/items.py:1766 pretix/control/forms/item.py:147 #: pretix/control/templates/pretixcontrol/items/question_edit.html:10 #: pretix/control/templates/pretixcontrol/items/question_edit.html:17 #: pretix/control/templates/pretixcontrol/items/questions.html:21 msgid "Question" msgstr "سؤال" -#: pretix/base/modelimport_orders.py:657 pretix/base/modelimport_orders.py:665 +#: pretix/base/modelimport_orders.py:701 pretix/base/modelimport_orders.py:709 #: pretix/base/models/items.py:1830 pretix/base/models/items.py:1848 msgid "Invalid option selected." msgstr "تم تحديد خيار غير صحيح." -#: pretix/base/modelimport_orders.py:659 pretix/base/modelimport_orders.py:667 +#: pretix/base/modelimport_orders.py:703 pretix/base/modelimport_orders.py:711 msgid "Ambiguous option selected." msgstr "تم تحديد خيار غامض." -#: pretix/base/modelimport_orders.py:698 pretix/base/models/orders.py:239 -#: pretix/control/forms/orders.py:696 pretix/control/forms/organizer.py:844 +#: pretix/base/modelimport_orders.py:742 pretix/base/models/orders.py:239 msgid "Customer" msgstr "عميل" -#: pretix/base/modelimport_orders.py:711 +#: pretix/base/modelimport_orders.py:756 #, fuzzy #| msgid "No matching seat was found." msgid "No matching customer was found." msgstr "لم يتم العثور على مقعد مطابق." -#: pretix/base/modelimport_vouchers.py:50 pretix/base/models/vouchers.py:488 +#: pretix/base/modelimport_vouchers.py:50 pretix/base/models/vouchers.py:491 msgid "A voucher with this code already exists." msgstr "يوجد كود الخصم مسبقا يحمل هذا الرمز." #: pretix/base/modelimport_vouchers.py:68 pretix/base/models/memberships.py:57 -#: pretix/base/models/vouchers.py:196 pretix/control/views/vouchers.py:120 +#: pretix/base/models/vouchers.py:199 pretix/control/views/vouchers.py:120 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:52 msgid "Maximum usages" msgstr "الاستخدامات القصوى" @@ -3826,26 +4272,26 @@ msgstr "الاستخدامات القصوى" msgid "The maximum number of usages must be set." msgstr "الحد الأقصى لعدد العناصر لكل طلب" -#: pretix/base/modelimport_vouchers.py:88 pretix/base/models/vouchers.py:205 +#: pretix/base/modelimport_vouchers.py:88 pretix/base/models/vouchers.py:208 #, fuzzy #| msgid "Maximum usages" msgid "Minimum usages" msgstr "الاستخدامات القصوى" -#: pretix/base/modelimport_vouchers.py:103 pretix/base/models/vouchers.py:213 +#: pretix/base/modelimport_vouchers.py:103 pretix/base/models/vouchers.py:216 msgid "Maximum discount budget" msgstr "الحد الأقصى للخصم" -#: pretix/base/modelimport_vouchers.py:119 pretix/base/models/vouchers.py:225 -#: pretix/control/forms/filter.py:2103 +#: pretix/base/modelimport_vouchers.py:119 pretix/base/models/vouchers.py:228 +#: pretix/control/forms/filter.py:2099 msgid "Reserve ticket from quota" msgstr "حجز تذكرة من الحصة" -#: pretix/base/modelimport_vouchers.py:127 pretix/base/models/vouchers.py:233 +#: pretix/base/modelimport_vouchers.py:127 pretix/base/models/vouchers.py:236 msgid "Allow to bypass quota" msgstr "السماح بتجاوز الحصة" -#: pretix/base/modelimport_vouchers.py:135 pretix/base/models/vouchers.py:239 +#: pretix/base/modelimport_vouchers.py:135 pretix/base/models/vouchers.py:242 msgid "Price mode" msgstr "وضع السعر" @@ -3854,7 +4300,7 @@ msgstr "وضع السعر" msgid "Could not parse {value} as a price mode, use one of {options}." msgstr "" -#: pretix/base/modelimport_vouchers.py:160 pretix/base/models/vouchers.py:245 +#: pretix/base/modelimport_vouchers.py:160 pretix/base/models/vouchers.py:248 msgid "Voucher value" msgstr "قيمة كود الخصم" @@ -3863,7 +4309,7 @@ msgid "It is pointless to set a value without a price mode." msgstr "" #: pretix/base/modelimport_vouchers.py:237 pretix/base/models/items.py:2121 -#: pretix/base/models/vouchers.py:272 +#: pretix/base/models/vouchers.py:275 #: pretix/control/templates/pretixcontrol/items/quota_edit.html:8 #: pretix/control/templates/pretixcontrol/items/quota_edit.html:15 msgid "Quota" @@ -3875,39 +4321,39 @@ msgstr "حصة" msgid "You cannot specify a quota if you specified a product." msgstr "تحتاج إلى تحديد أي حصة أو منتج." -#: pretix/base/modelimport_vouchers.py:282 pretix/base/models/vouchers.py:495 +#: pretix/base/modelimport_vouchers.py:282 pretix/base/models/vouchers.py:498 msgid "You need to choose a date if you select a seat." msgstr "يجب إختيار تاريخ إذا قمت باختيار مقعد." -#: pretix/base/modelimport_vouchers.py:299 pretix/base/models/vouchers.py:513 +#: pretix/base/modelimport_vouchers.py:299 pretix/base/models/vouchers.py:516 msgid "You need to choose a specific product if you select a seat." msgstr "يجب أن تختار منتجا محددا إذا اخترت مقعدا محددا." -#: pretix/base/modelimport_vouchers.py:302 pretix/base/models/vouchers.py:516 +#: pretix/base/modelimport_vouchers.py:302 pretix/base/models/vouchers.py:519 msgid "Seat-specific vouchers can only be used once." msgstr "يمكن استخدام أكود الخصم الخاصة بالمقاعد مرة واحدة فقط." -#: pretix/base/modelimport_vouchers.py:306 pretix/base/models/vouchers.py:519 +#: pretix/base/modelimport_vouchers.py:306 pretix/base/models/vouchers.py:522 #, python-brace-format msgid "You need to choose the product \"{prod}\" for this seat." msgstr "يجب أن تختار المنتج \"{prod}\" لهذا المقعد." -#: pretix/base/modelimport_vouchers.py:318 pretix/base/models/vouchers.py:285 +#: pretix/base/modelimport_vouchers.py:318 pretix/base/models/vouchers.py:288 #: pretix/control/templates/pretixcontrol/vouchers/index.html:129 #: pretix/control/templates/pretixcontrol/vouchers/tags.html:42 #: pretix/control/views/vouchers.py:120 msgid "Tag" msgstr "علامة" -#: pretix/base/modelimport_vouchers.py:334 pretix/base/models/vouchers.py:297 +#: pretix/base/modelimport_vouchers.py:334 pretix/base/models/vouchers.py:300 msgid "Shows hidden products that match this voucher" msgstr "تظهر المنتجات المخفية التي تطابق كود الخصم هذا" -#: pretix/base/modelimport_vouchers.py:343 pretix/base/models/vouchers.py:301 +#: pretix/base/modelimport_vouchers.py:343 pretix/base/models/vouchers.py:304 msgid "Offer all add-on products for free when redeeming this voucher" msgstr "" -#: pretix/base/modelimport_vouchers.py:351 pretix/base/models/vouchers.py:305 +#: pretix/base/modelimport_vouchers.py:351 pretix/base/models/vouchers.py:308 msgid "" "Include all bundled products without a designated price when redeeming this " "voucher" @@ -3951,7 +4397,7 @@ msgstr "إذا قمت بإيقاف التشغيل، فلن تتلقى أي إش #: pretix/control/templates/pretixcontrol/user/staff_session_list.html:15 #: pretix/control/templates/pretixcontrol/users/form.html:4 #: pretix/control/templates/pretixcontrol/users/form.html:6 -#: pretix/control/views/organizer.py:158 tests/base/test_mail.py:149 +#: pretix/control/views/organizer.py:170 tests/base/test_mail.py:149 msgid "User" msgstr "المستخدم" @@ -3975,7 +4421,7 @@ msgid "All products (including newly created ones)" msgstr "جميع المنتجات (بما في ذلك تلك التي تم إنشاؤها حديثا)" #: pretix/base/models/checkin.py:56 pretix/plugins/badges/exporters.py:436 -#: pretix/plugins/checkinlists/exporters.py:850 +#: pretix/plugins/checkinlists/exporters.py:851 msgid "Limit to products" msgstr "مقتصر على المنتجات" @@ -4026,7 +4472,7 @@ msgid "" "rejected.." msgstr "" -#: pretix/base/models/checkin.py:85 pretix/control/navigation.py:640 +#: pretix/base/models/checkin.py:85 pretix/control/navigation.py:652 #: pretix/control/templates/pretixcontrol/organizers/gates.html:5 msgid "Gates" msgstr "بوابات" @@ -4066,74 +4512,80 @@ msgstr "دخول" msgid "Exit" msgstr "خروج" -#: pretix/base/models/checkin.py:355 +#: pretix/base/models/checkin.py:356 #, fuzzy #| msgid "Unknown invoice." msgid "Unknown ticket" msgstr "فاتورة غير معروفة." -#: pretix/base/models/checkin.py:356 +#: pretix/base/models/checkin.py:357 #, fuzzy #| msgid "Ticket download" msgid "Ticket not paid" msgstr "حمل تذكرة" -#: pretix/base/models/checkin.py:357 +#: pretix/base/models/checkin.py:358 msgid "Forbidden by custom rule" msgstr "" -#: pretix/base/models/checkin.py:358 +#: pretix/base/models/checkin.py:359 #, fuzzy #| msgid "Ticket layout changed." msgid "Ticket code revoked/changed" msgstr "تم تغيير نسق التذكرة." -#: pretix/base/models/checkin.py:359 +#: pretix/base/models/checkin.py:360 #, fuzzy #| msgid "Action required" msgid "Information required" msgstr "الإجراء مطلوب" -#: pretix/base/models/checkin.py:360 +#: pretix/base/models/checkin.py:361 #, fuzzy #| msgid "Ticket layouts" msgid "Ticket already used" msgstr "أنماط التذاكر" -#: pretix/base/models/checkin.py:361 +#: pretix/base/models/checkin.py:362 #, fuzzy #| msgid "Ticket type not allowed" msgid "Ticket type not allowed here" msgstr "نوع التذكرة غير مسموح به" -#: pretix/base/models/checkin.py:362 +#: pretix/base/models/checkin.py:363 msgid "Ticket code is ambiguous on list" msgstr "" -#: pretix/base/models/checkin.py:363 +#: pretix/base/models/checkin.py:364 #, fuzzy #| msgid "Internal Server Error" msgid "Server error" msgstr "خطأ في الخادم الداخلي" -#: pretix/base/models/checkin.py:364 +#: pretix/base/models/checkin.py:365 #, fuzzy #| msgid "Ticket code" msgid "Ticket blocked" msgstr "رمز التذكرة" -#: pretix/base/models/checkin.py:365 +#: pretix/base/models/checkin.py:366 #, fuzzy #| msgid "Order approved" msgid "Order not approved" msgstr "تمت الموافقة على الطلب" -#: pretix/base/models/checkin.py:366 +#: pretix/base/models/checkin.py:367 #, fuzzy #| msgid "This voucher is not valid for this seat." msgid "Ticket not valid at this time" msgstr "كود الخصم هذا غير صالح لهذا المقعد." +#: pretix/base/models/checkin.py:368 +#, fuzzy +#| msgid "Check-in status" +msgid "Check-in annulled" +msgstr "تحقق ذات المركز" + #: pretix/base/models/customers.py:55 #, fuzzy #| msgid "Product name" @@ -4165,8 +4617,8 @@ msgid "" "underscores. It must start and end with a letter or number." msgstr "" -#: pretix/base/models/customers.py:195 pretix/control/forms/filter.py:1500 -#: pretix/control/forms/filter.py:1572 +#: pretix/base/models/customers.py:195 pretix/control/forms/filter.py:1498 +#: pretix/control/forms/filter.py:1570 #: pretix/control/templates/pretixcontrol/organizers/customer.html:42 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:56 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:135 @@ -4177,12 +4629,12 @@ msgid "disabled" msgstr "معاق" #: pretix/base/models/customers.py:310 pretix/base/models/orders.py:1538 -#: pretix/base/models/orders.py:3269 pretix/base/settings.py:1112 +#: pretix/base/models/orders.py:3280 pretix/base/settings.py:1150 msgid "Company name" msgstr "اسم الشركة" #: pretix/base/models/customers.py:314 pretix/base/models/orders.py:1542 -#: pretix/base/models/orders.py:3276 pretix/base/settings.py:83 +#: pretix/base/models/orders.py:3287 pretix/base/settings.py:83 #: pretix/plugins/stripe/payment.py:272 msgid "Select country" msgstr "اختر الدولة" @@ -4252,6 +4704,24 @@ msgstr "أنواع العضوية المسموح بها" msgid "Separate multiple values with spaces" msgstr "إنشاء قسائم متعددة" +#: pretix/base/models/datasync.py:53 +msgid "Temporary error, auto-retry limit exceeded" +msgstr "" + +#: pretix/base/models/datasync.py:54 +#, fuzzy +#| msgid "Stripe reported an error: %s" +msgid "Provider reported a permanent error" +msgstr "أبلغنا Stripe عن خطأ: %s" + +#: pretix/base/models/datasync.py:55 +msgid "Misconfiguration, please check provider settings" +msgstr "" + +#: pretix/base/models/datasync.py:56 pretix/base/models/datasync.py:57 +msgid "System error, needs manual intervention" +msgstr "" + #: pretix/base/models/devices.py:70 pretix/base/models/items.py:1675 msgid "Internal identifier" msgstr "معرف داخلي" @@ -4261,11 +4731,11 @@ msgid "This identifier is already used for a different question." msgstr "هذا المعرف مستخدم مسبقا لسؤال مختلف." #: pretix/base/models/devices.py:113 pretix/control/forms/checkin.py:196 -#: pretix/control/forms/checkin.py:217 pretix/control/forms/filter.py:2394 -#: pretix/control/forms/filter.py:2441 pretix/control/forms/filter.py:2601 +#: pretix/control/forms/checkin.py:217 pretix/control/forms/filter.py:2390 +#: pretix/control/forms/filter.py:2437 pretix/control/forms/filter.py:2597 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:67 #: pretix/control/templates/pretixcontrol/organizers/gates.html:16 -#: pretix/plugins/checkinlists/exporters.py:765 +#: pretix/plugins/checkinlists/exporters.py:766 msgid "Gate" msgstr "بوابة" @@ -4299,7 +4769,7 @@ msgstr "أضف تذاكر لتاريخ مختلف" #: pretix/base/models/discount.py:69 pretix/base/models/items.py:1161 #: pretix/base/models/items.py:1481 pretix/base/models/items.py:1708 -#: pretix/base/models/organizer.py:553 +#: pretix/base/models/organizer.py:619 msgid "Position" msgstr "حالة" @@ -4463,7 +4933,7 @@ msgstr "يجب أن تكون نهاية فترة عرض ما قبل البيع msgid "The end of the event has to be later than its start." msgstr "نهاية الفعالية يجب أن تكون في وقت لاحق بعد بدايتها." -#: pretix/base/models/event.py:577 +#: pretix/base/models/event.py:576 msgid "" "Should be short, only contain lowercase letters, numbers, dots, and dashes, " "and must be unique among your events. We recommend some kind of abbreviation " @@ -4477,15 +4947,15 @@ msgstr "" "استخدام ذلك في عناوين الروابط ورموز الطلب، وأرقام الفاتورة ومراجع التحويل " "المصرفي." -#: pretix/base/models/event.py:584 pretix/base/models/organizer.py:87 +#: pretix/base/models/event.py:583 pretix/base/models/organizer.py:89 msgid "The slug may only contain letters, numbers, dots and dashes." msgstr "يجب أن يحتوي الرابط فقط على أحرف وأرقام ونقاط وشرطات." -#: pretix/base/models/event.py:601 pretix/base/models/event.py:1488 +#: pretix/base/models/event.py:600 pretix/base/models/event.py:1495 msgid "Show in lists" msgstr "أظهرهذا في قوائم" -#: pretix/base/models/event.py:602 +#: pretix/base/models/event.py:601 msgid "" "If selected, this event will show up publicly on the list of events for your " "organizer account." @@ -4493,7 +4963,7 @@ msgstr "" "إذا تم تحديدها، فستظهر هذه الفعالية بشكل عام في قائمة الفعاليات لحساب المنظم " "الخاص بك." -#: pretix/base/models/event.py:606 pretix/base/models/event.py:1503 +#: pretix/base/models/event.py:605 pretix/base/models/event.py:1510 #: pretix/control/forms/subevents.py:100 msgid "" "Optional. No products will be sold after this date. If you do not set this " @@ -4502,75 +4972,76 @@ msgstr "" "اختياري. لن يتم بيع أي منتجات بعد هذا التاريخ. إذا لم تقم بتعيين هذه " "القيمة ، فسينتهي عرض ما قبل البيع بعد تاريخ انتهاء الفعالية الخاصة بك." -#: pretix/base/models/event.py:612 pretix/base/models/event.py:1509 +#: pretix/base/models/event.py:611 pretix/base/models/event.py:1516 #: pretix/control/forms/subevents.py:94 msgid "Optional. No products will be sold before this date." msgstr "اختياري. لن يتم بيع أي منتجات قبل هذا التاريخ." -#: pretix/base/models/event.py:621 +#: pretix/base/models/event.py:620 msgid "This event is remote or partially remote." msgstr "" -#: pretix/base/models/event.py:622 +#: pretix/base/models/event.py:621 msgid "" "This will be used to let users know if the event is in a different timezone " "and let’s us calculate users’ local times." msgstr "" -#: pretix/base/models/event.py:642 pretix/control/navigation.py:65 +#: pretix/base/models/event.py:641 pretix/base/models/organizer.py:97 +#: pretix/control/navigation.py:65 pretix/control/navigation.py:499 msgid "Plugins" msgstr "الإضافات" -#: pretix/base/models/event.py:649 pretix/base/pdf.py:229 -#: pretix/control/forms/event.py:274 pretix/control/forms/filter.py:1677 +#: pretix/base/models/event.py:648 pretix/base/pdf.py:238 +#: pretix/control/forms/event.py:273 pretix/control/forms/filter.py:1675 #: pretix/control/templates/pretixcontrol/event/index.html:13 #: pretix/control/templates/pretixcontrol/events/index.html:114 #: pretix/control/templates/pretixcontrol/organizers/detail.html:90 -#: pretix/control/views/dashboards.py:543 +#: pretix/control/views/dashboards.py:547 #: pretix/presale/templates/pretixpresale/event/index.html:33 #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:7 #: pretix/presale/views/widget.py:700 msgid "Event series" msgstr "فعالية بأوقات مختلفة" -#: pretix/base/models/event.py:653 pretix/base/models/event.py:1537 +#: pretix/base/models/event.py:652 pretix/base/models/event.py:1544 #, fuzzy #| msgid "Settings" msgid "Seating plan" msgstr "الإعدادات" -#: pretix/base/models/event.py:660 pretix/base/models/items.py:675 +#: pretix/base/models/event.py:659 pretix/base/models/items.py:675 #, fuzzy #| msgid "Sales channels" msgid "Sell on all sales channels" msgstr "قنوات البيع" -#: pretix/base/models/event.py:665 pretix/base/models/items.py:680 +#: pretix/base/models/event.py:664 pretix/base/models/items.py:680 #: pretix/base/models/items.py:1230 pretix/base/payment.py:474 msgid "Restrict to specific sales channels" msgstr "يقتصر على قنوات بيع محددة" -#: pretix/base/models/event.py:673 pretix/control/navigation.py:344 -#: pretix/control/navigation.py:470 +#: pretix/base/models/event.py:672 pretix/control/navigation.py:344 +#: pretix/control/navigation.py:475 #: pretix/control/templates/pretixcontrol/events/index.html:5 #: pretix/control/templates/pretixcontrol/events/index.html:7 #: pretix/control/templates/pretixcontrol/organizers/devices.html:88 #: pretix/control/templates/pretixcontrol/organizers/teams.html:39 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:37 -#: pretix/control/views/organizer.py:1725 -#: pretix/plugins/reports/accountingreport.py:104 -#: pretix/plugins/reports/accountingreport.py:107 +#: pretix/control/views/organizer.py:1994 +#: pretix/plugins/reports/accountingreport.py:105 +#: pretix/plugins/reports/accountingreport.py:108 msgid "Events" msgstr "فعاليات" -#: pretix/base/models/event.py:1316 +#: pretix/base/models/event.py:1315 msgid "" "You have configured at least one paid product but have not enabled any " "payment methods." msgstr "" "لقد قمت بإعداد منتج مدفوع واحد على الأقل، ولكن لم تقم بتفعيل أي وسيلة سداد." -#: pretix/base/models/event.py:1319 +#: pretix/base/models/event.py:1318 #, fuzzy #| msgid "" #| "You have configured at least one paid product but have not enabled any " @@ -4581,37 +5052,37 @@ msgid "" msgstr "" "لقد قمت بإعداد منتج مدفوع واحد على الأقل، ولكن لم تقم بتفعيل أي وسيلة سداد." -#: pretix/base/models/event.py:1322 +#: pretix/base/models/event.py:1321 msgid "You need to configure at least one quota to sell anything." msgstr "تحتاج إلى إعداد حصة واحدة على الأقل لبيع أي شيء." -#: pretix/base/models/event.py:1327 +#: pretix/base/models/event.py:1326 #, python-brace-format msgid "You need to fill the meta parameter \"{property}\"." msgstr "تحتاج إلى ملء المعلومة الوصفية \"{property}\"." -#: pretix/base/models/event.py:1434 +#: pretix/base/models/event.py:1441 msgid "" "Once created an event cannot change between an series and a single event." msgstr "بمجرد إنشاء فعالية لا يمكن التغيير بين سلسلة فعاليات وفعالية واحدة." -#: pretix/base/models/event.py:1440 +#: pretix/base/models/event.py:1447 msgid "The event slug cannot be changed." msgstr "لا يمكن تغيير رابط الفعالية." -#: pretix/base/models/event.py:1443 +#: pretix/base/models/event.py:1450 msgid "This slug has already been used for a different event." msgstr "لقد تم استخدام هذا الرابط مسبقا لفعالية مختلفة." -#: pretix/base/models/event.py:1449 +#: pretix/base/models/event.py:1456 msgid "The event cannot end before it starts." msgstr "لا يمكن أن تنتهي الفعالية قبل أن تبدأ." -#: pretix/base/models/event.py:1455 +#: pretix/base/models/event.py:1462 msgid "The event's presale cannot end before it starts." msgstr "لا يمكن أن ينتهي العرض المسبق للفعالية قبل أن يبدأ." -#: pretix/base/models/event.py:1485 +#: pretix/base/models/event.py:1492 msgid "" "Only with this checkbox enabled, this date is visible in the frontend to " "users." @@ -4619,7 +5090,7 @@ msgstr "" "يكون هذا التاريخ مرئيا في الواجهة الأمامية للمستخدمين فقط في حال تم تمكين " "مربع الاختيار هذا." -#: pretix/base/models/event.py:1489 +#: pretix/base/models/event.py:1496 msgid "" "If selected, this event will show up publicly on the list of dates for your " "event." @@ -4627,44 +5098,44 @@ msgstr "" "إذا تم الحديد، فستظهر هذه الفعالية بشكل عام في قائمة تواريخ الفعالية الخاصة " "بك." -#: pretix/base/models/event.py:1534 pretix/base/settings.py:3064 +#: pretix/base/models/event.py:1541 pretix/base/settings.py:3116 msgid "Frontpage text" msgstr "نص الصفحة الأولى" -#: pretix/base/models/event.py:1551 +#: pretix/base/models/event.py:1558 msgid "Date in event series" msgstr "التاريخ في سلسلة الفعالية" -#: pretix/base/models/event.py:1552 +#: pretix/base/models/event.py:1559 msgid "Dates in event series" msgstr "التواريخ في سلسلة الفعالية" -#: pretix/base/models/event.py:1697 +#: pretix/base/models/event.py:1704 msgid "One or more variations do not belong to this event." msgstr "عنصر أو أكثر لا ينتمي إلى هذه الفعالية." -#: pretix/base/models/event.py:1727 pretix/base/models/items.py:2236 +#: pretix/base/models/event.py:1734 pretix/base/models/items.py:2236 msgid "Can not contain spaces or special characters except underscores" msgstr "لا يمكن أن يحتوي على مسافات أو أحرف خاصة باستثناء الشرطات السفلية" -#: pretix/base/models/event.py:1732 pretix/base/models/items.py:2241 +#: pretix/base/models/event.py:1739 pretix/base/models/items.py:2241 msgid "The property name may only contain letters, numbers and underscores." msgstr "لا يسمح أن يحتوي اسم الملكية إلا على أحرف وأرقام وشرطات سفلية فقط." -#: pretix/base/models/event.py:1737 +#: pretix/base/models/event.py:1744 msgid "Default value" msgstr "القيمة الافتراضية" -#: pretix/base/models/event.py:1739 +#: pretix/base/models/event.py:1746 #: pretix/control/templates/pretixcontrol/organizers/properties.html:50 msgid "Can only be changed by organizer-level administrators" msgstr "لا يمكن تغييرها إلا من قبل المسؤولين برتبة منظم" -#: pretix/base/models/event.py:1741 +#: pretix/base/models/event.py:1748 msgid "Required for events" msgstr "مطلوب للفعاليات" -#: pretix/base/models/event.py:1742 +#: pretix/base/models/event.py:1749 msgid "" "If checked, an event can only be taken live if the property is set. In event " "series, its always optional to set a value for individual dates" @@ -4672,60 +5143,60 @@ msgstr "" "إذا تم تحديده ، فلا يمكن أن تكون الفعالية مباشرة إلا إذا تم تعيين الخاصية. " "في سلسلة الفعالية، يكون دائما تعيين قيمة للتواريخ الفردية أمرا اختياريا" -#: pretix/base/models/event.py:1748 pretix/base/models/items.py:2253 +#: pretix/base/models/event.py:1755 pretix/base/models/items.py:2253 msgid "Valid values" msgstr "قيم صالحة" -#: pretix/base/models/event.py:1751 +#: pretix/base/models/event.py:1758 #: pretix/control/templates/pretixcontrol/organizers/properties.html:45 #, fuzzy #| msgid "Show number of tickets left" msgid "Show filter option to customers" msgstr "إظهار عدد التذاكر المتبقية" -#: pretix/base/models/event.py:1752 +#: pretix/base/models/event.py:1759 msgid "" "This field will be shown to filter events in the public event list and " "calendar." msgstr "" -#: pretix/base/models/event.py:1755 pretix/control/forms/organizer.py:269 +#: pretix/base/models/event.py:1762 pretix/control/forms/organizer.py:269 #: pretix/control/forms/organizer.py:273 #, fuzzy #| msgid "Public profile" msgid "Public name" msgstr "حساب عام" -#: pretix/base/models/event.py:1759 +#: pretix/base/models/event.py:1766 #: pretix/control/templates/pretixcontrol/organizers/properties.html:40 msgid "Can be used for filtering" msgstr "" -#: pretix/base/models/event.py:1760 +#: pretix/base/models/event.py:1767 msgid "" "This field will be shown to filter events or reports in the backend, and it " "can also be used for hidden filter parameters in the frontend (e.g. using " "the widget)." msgstr "" -#: pretix/base/models/event.py:1770 +#: pretix/base/models/event.py:1777 msgid "A property can either be required or have a default value, not both." msgstr "يمكن أن تكون الخاصية إما مطلوبة أو لها قيمة افتراضية ، وليس كليهما." -#: pretix/base/models/event.py:1850 pretix/base/models/organizer.py:516 +#: pretix/base/models/event.py:1857 pretix/base/models/organizer.py:582 #, fuzzy #| msgid "Info text" msgid "Link text" msgstr "معلومات النص" -#: pretix/base/models/event.py:1853 pretix/base/models/organizer.py:519 +#: pretix/base/models/event.py:1860 pretix/base/models/organizer.py:585 #, fuzzy #| msgid "Imprint URL" msgid "Link URL" msgstr "رابط موقع مقدم الخدمة" #: pretix/base/models/exports.py:42 pretix/control/navigation.py:229 -#: pretix/control/navigation.py:650 +#: pretix/control/navigation.py:662 msgid "Export" msgstr "تصدير" @@ -4736,7 +5207,8 @@ msgid "Additional recipients" msgstr "إعدادات إضافية" #: pretix/base/models/exports.py:61 pretix/base/models/exports.py:66 -#: pretix/base/models/exports.py:71 +#: pretix/base/models/exports.py:71 pretix/control/forms/event.py:988 +#: pretix/control/forms/organizer.py:586 msgid "You can specify multiple recipients separated by commas." msgstr "" @@ -4752,20 +5224,20 @@ msgstr "إعدادات إضافية" msgid "Additional recipients (Bcc)" msgstr "إعدادات إضافية" -#: pretix/base/models/exports.py:74 pretix/control/forms/event.py:1101 -#: pretix/control/forms/event.py:1175 pretix/control/forms/event.py:1185 -#: pretix/control/forms/event.py:1195 pretix/control/forms/orders.py:720 -#: pretix/control/forms/orders.py:942 pretix/control/forms/orders.py:969 -#: pretix/control/forms/organizer.py:604 pretix/control/forms/organizer.py:614 -#: pretix/control/forms/organizer.py:624 pretix/control/forms/vouchers.py:273 -#: pretix/plugins/sendmail/forms.py:57 pretix/plugins/sendmail/forms.py:73 -#: pretix/plugins/sendmail/models.py:248 +#: pretix/base/models/exports.py:74 pretix/control/forms/event.py:1094 +#: pretix/control/forms/event.py:1168 pretix/control/forms/event.py:1178 +#: pretix/control/forms/event.py:1188 pretix/control/forms/event.py:1203 +#: pretix/control/forms/orders.py:730 pretix/control/forms/orders.py:952 +#: pretix/control/forms/orders.py:979 pretix/control/forms/organizer.py:607 +#: pretix/control/forms/organizer.py:617 pretix/control/forms/organizer.py:627 +#: pretix/control/forms/vouchers.py:282 pretix/plugins/sendmail/forms.py:57 +#: pretix/plugins/sendmail/forms.py:73 pretix/plugins/sendmail/models.py:248 msgid "Subject" msgstr "موضوع" -#: pretix/base/models/exports.py:78 pretix/control/forms/orders.py:759 -#: pretix/control/forms/orders.py:782 pretix/control/forms/orders.py:950 -#: pretix/control/forms/orders.py:977 pretix/control/forms/vouchers.py:279 +#: pretix/base/models/exports.py:78 pretix/control/forms/orders.py:769 +#: pretix/control/forms/orders.py:792 pretix/control/forms/orders.py:960 +#: pretix/control/forms/orders.py:987 pretix/control/forms/vouchers.py:288 #: pretix/plugins/sendmail/forms.py:58 pretix/plugins/sendmail/forms.py:78 #: pretix/plugins/sendmail/models.py:249 msgid "Message" @@ -4806,13 +5278,50 @@ msgstr "‪شروط وأحكام خاصة" msgid "Manual transaction" msgstr "المعاملات اليدوية" -#: pretix/base/models/invoices.py:185 +#: pretix/base/models/invoices.py:120 +#, fuzzy +#| msgid "Pending amount" +msgid "pending transmission" +msgstr "مبالغ متأخرة" + +#: pretix/base/models/invoices.py:121 +msgid "currently being transmitted" +msgstr "" + +#: pretix/base/models/invoices.py:122 +#, fuzzy +#| msgctxt "subevent" +#| msgid "No date selected." +msgid "transmitted" +msgstr "لم يتم تحديد تاريخ." + +#: pretix/base/models/invoices.py:123 pretix/plugins/sendmail/models.py:52 +#, fuzzy +#| msgctxt "payment_state" +#| msgid "failed" +msgid "failed" +msgstr "فشل" + +#: pretix/base/models/invoices.py:124 +#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:56 +#, fuzzy +#| msgid "(unknown)" +msgid "unknown" +msgstr "(غير معروف)" + +#: pretix/base/models/invoices.py:125 +#, fuzzy +#| msgid "in private test mode" +msgid "not transmitted due to test mode" +msgstr "في وضع الاختبار الخاص" + +#: pretix/base/models/invoices.py:217 #, python-format msgctxt "invoice" msgid "Tax ID: %s" msgstr "رقم تعريف الضريبة: %s" -#: pretix/base/models/invoices.py:191 pretix/base/services/invoices.py:139 +#: pretix/base/models/invoices.py:223 pretix/base/services/invoices.py:148 #, python-format msgctxt "invoice" msgid "VAT-ID: %s" @@ -4847,17 +5356,17 @@ msgstr "" "مصادر قوائم الإضافات." #: pretix/base/models/items.py:114 pretix/base/models/items.py:159 -#: pretix/control/forms/item.py:99 +#: pretix/control/forms/item.py:97 #, fuzzy #| msgid "No category" msgid "Normal category" msgstr "ليس هناك فئة" -#: pretix/base/models/items.py:115 pretix/control/forms/item.py:112 +#: pretix/base/models/items.py:115 pretix/control/forms/item.py:110 msgid "Normal + cross-selling category" msgstr "" -#: pretix/base/models/items.py:116 pretix/control/forms/item.py:107 +#: pretix/base/models/items.py:116 pretix/control/forms/item.py:105 #, fuzzy #| msgid "No category" msgid "Cross-selling category" @@ -4937,14 +5446,14 @@ msgstr "عميل" msgid "Dynamic validity" msgstr "صلاحية بطاقة هدية" -#: pretix/base/models/items.py:444 pretix/control/forms/item.py:667 +#: pretix/base/models/items.py:444 pretix/control/forms/item.py:668 #: pretix/control/templates/pretixcontrol/subevents/fragment_unavail_mode_indicator.html:3 #, fuzzy #| msgid "Waiting, product unavailable" msgid "Hide product if unavailable" msgstr "الانتظار، المنتج غير متوفر" -#: pretix/base/models/items.py:445 pretix/control/forms/item.py:668 +#: pretix/base/models/items.py:445 pretix/control/forms/item.py:669 #: pretix/control/templates/pretixcontrol/subevents/fragment_unavail_mode_indicator.html:5 #, fuzzy #| msgid "The ordered product \"{item}\" is no longer available." @@ -5046,8 +5555,8 @@ msgstr "عرض قائمة الانتظار لهذه التذكرة" msgid "This will only work if waiting lists are enabled for this event." msgstr "لن يعمل هذا إلا إذا تم تمكين قوائم الانتظار لهذه الفعالية." -#: pretix/base/models/items.py:548 pretix/base/settings.py:1360 -#: pretix/control/forms/event.py:1681 +#: pretix/base/models/items.py:548 pretix/base/settings.py:1398 +#: pretix/control/forms/event.py:1690 msgid "Show number of tickets left" msgstr "إظهار عدد التذاكر المتبقية" @@ -5055,7 +5564,7 @@ msgstr "إظهار عدد التذاكر المتبقية" msgid "Publicly show how many tickets are still available." msgstr "أظهر للجمهور عدد التذاكر التي لا تزال متاحة." -#: pretix/base/models/items.py:556 pretix/control/forms/item.py:632 +#: pretix/base/models/items.py:556 pretix/control/forms/item.py:633 msgid "Product picture" msgstr "صورة المنتج" @@ -5260,7 +5769,7 @@ msgid "" "change but keep their current validity." msgstr "" -#: pretix/base/models/items.py:738 pretix/control/forms/item.py:735 +#: pretix/base/models/items.py:738 pretix/control/forms/item.py:736 #, fuzzy #| msgid "Gift card validity" msgid "Start of validity" @@ -5340,10 +5849,10 @@ msgid "" msgstr "" #: pretix/base/models/items.py:795 pretix/base/models/items.py:1702 -#: pretix/control/forms/filter.py:421 pretix/control/forms/filter.py:1895 -#: pretix/control/forms/item.py:278 pretix/control/navigation.py:138 +#: pretix/control/forms/filter.py:421 pretix/control/forms/filter.py:1891 +#: pretix/control/forms/item.py:276 pretix/control/navigation.py:138 #: pretix/control/navigation.py:147 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:104 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:111 #: pretix/control/templates/pretixcontrol/items/base.html:3 #: pretix/control/templates/pretixcontrol/items/discounts.html:60 #: pretix/control/templates/pretixcontrol/items/index.html:5 @@ -5354,6 +5863,7 @@ msgstr "" #: pretix/plugins/autocheckin/models.py:72 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:31 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:32 +#: pretix/presale/templates/pretixpresale/event/index.html:221 msgid "Products" msgstr "منتجات" @@ -5436,7 +5946,7 @@ msgstr "" "عليك تأكيده قبل دفعه وإكماله. يمكنك استخدام هذا على سبيل المثال للتذاكر " "المخصومة المتوفرة فقط لمجموعات محددة." -#: pretix/base/models/items.py:1195 pretix/control/navigation.py:579 +#: pretix/base/models/items.py:1195 pretix/control/navigation.py:591 #: pretix/control/templates/pretixcontrol/organizers/membershiptypes.html:4 #: pretix/control/templates/pretixcontrol/organizers/membershiptypes.html:6 msgid "Membership types" @@ -5612,7 +6122,7 @@ msgid "Country code (ISO 3166-1 alpha-2)" msgstr "رمز البلد (ISO 3166-1 alpha-2)" #: pretix/base/models/items.py:1681 pretix/base/models/items.py:1957 -#: pretix/base/models/organizer.py:543 +#: pretix/base/models/organizer.py:609 #, fuzzy #| msgid "The property name may only contain letters, numbers and underscores." msgid "" @@ -5776,6 +6286,7 @@ msgid "Answer" msgstr "إجابة" #: pretix/base/models/items.py:1985 +#, python-brace-format msgid "The identifier \"{}\" is already used for a different option." msgstr "المعرف \"{}\" مستخدم سابقا لخيار مختلف." @@ -5787,22 +6298,22 @@ msgstr "خيار السؤال" msgid "Question options" msgstr "خيارات السؤال" -#: pretix/base/models/items.py:2074 pretix/control/forms/event.py:1715 +#: pretix/base/models/items.py:2074 pretix/control/forms/event.py:1724 #: pretix/control/templates/pretixcontrol/items/quotas.html:56 msgid "Total capacity" msgstr "السعة الإجمالية" -#: pretix/base/models/items.py:2076 pretix/control/forms/item.py:455 +#: pretix/base/models/items.py:2076 pretix/control/forms/item.py:456 msgid "Leave empty for an unlimited number of tickets." msgstr "اتركه فارغا لعدد غير محدود من التذاكر." #: pretix/base/models/items.py:2080 pretix/base/models/orders.py:1489 -#: pretix/base/models/orders.py:2986 +#: pretix/base/models/orders.py:2997 #: pretix/control/templates/pretixcontrol/checkin/index.html:97 msgid "Item" msgstr "بند" -#: pretix/base/models/items.py:2088 pretix/control/forms/item.py:914 +#: pretix/base/models/items.py:2088 pretix/control/forms/item.py:915 #: pretix/plugins/autocheckin/models.py:74 msgid "Variations" msgstr "متغيرات" @@ -5877,7 +6388,7 @@ msgstr "" "يحتوي عنصر واحد أو أكثر على أشكال مختلفة ولكن لا يوجد أي منها في قائمة " "المتغيرات." -#: pretix/base/models/items.py:2212 pretix/base/models/waitinglist.py:305 +#: pretix/base/models/items.py:2212 pretix/base/models/waitinglist.py:308 msgid "Subevent cannot be null for event series." msgstr "لا يمكن أن تكون الفعالية الفرعية في سلسلة الفعاليات غير معرفة." @@ -5944,7 +6455,7 @@ msgstr "عدد المرات التي يمكن فيها استخدام هذه ا #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:41 #: pretix/control/templates/pretixcontrol/orders/overview.html:77 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:78 -#: pretix/plugins/reports/exporters.py:376 +#: pretix/plugins/reports/exporters.py:387 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:28 #: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:34 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:44 @@ -5962,11 +6473,11 @@ msgid "pending" msgstr "معلق" #: pretix/base/models/orders.py:203 pretix/base/payment.py:568 -#: pretix/base/services/invoices.py:475 +#: pretix/base/services/invoices.py:486 msgid "paid" msgstr "مدفوع" -#: pretix/base/models/orders.py:204 pretix/control/forms/filter.py:1573 +#: pretix/base/models/orders.py:204 pretix/control/forms/filter.py:1571 #: pretix/control/templates/pretixcontrol/organizers/reusable_medium.html:37 msgid "expired" msgstr "منتهي الصلاحية" @@ -5981,7 +6492,7 @@ msgstr "المكان" msgid "Total amount" msgstr "المبلغ الإجمالي" -#: pretix/base/models/orders.py:273 pretix/base/models/vouchers.py:293 +#: pretix/base/models/orders.py:273 pretix/base/models/vouchers.py:296 msgid "" "The text entered in this field will not be visible to the user and is " "available for your convenience." @@ -6024,7 +6535,7 @@ msgid "API meta information" msgstr "المعلومات الوصفية" #: pretix/base/models/orders.py:414 pretix/plugins/sendmail/forms.py:236 -#: pretix/plugins/sendmail/forms.py:391 pretix/plugins/sendmail/views.py:269 +#: pretix/plugins/sendmail/forms.py:389 pretix/plugins/sendmail/views.py:269 msgid "approval pending" msgstr "في انتظار الموافقة" @@ -6119,62 +6630,62 @@ msgctxt "payment_state" msgid "refunded" msgstr "تم الاسترداد" -#: pretix/base/models/orders.py:1756 pretix/base/models/orders.py:2170 -#: pretix/base/shredder.py:629 +#: pretix/base/models/orders.py:1756 pretix/base/models/orders.py:2181 +#: pretix/base/shredder.py:633 msgid "Payment information" msgstr "معلومات الدفع" -#: pretix/base/models/orders.py:2111 +#: pretix/base/models/orders.py:2122 msgctxt "refund_state" msgid "started externally" msgstr "بدأ من الخارج" -#: pretix/base/models/orders.py:2112 +#: pretix/base/models/orders.py:2123 msgctxt "refund_state" msgid "created" msgstr "تم الإنشاء" -#: pretix/base/models/orders.py:2113 +#: pretix/base/models/orders.py:2124 msgctxt "refund_state" msgid "in transit" msgstr "قيد الإرسال" -#: pretix/base/models/orders.py:2114 +#: pretix/base/models/orders.py:2125 msgctxt "refund_state" msgid "done" msgstr "منجز" -#: pretix/base/models/orders.py:2115 +#: pretix/base/models/orders.py:2126 msgctxt "refund_state" msgid "failed" msgstr "فشل" -#: pretix/base/models/orders.py:2117 +#: pretix/base/models/orders.py:2128 msgctxt "refund_state" msgid "canceled" msgstr "ألغيت" -#: pretix/base/models/orders.py:2125 +#: pretix/base/models/orders.py:2136 msgctxt "refund_source" msgid "Organizer" msgstr "منظم" -#: pretix/base/models/orders.py:2126 +#: pretix/base/models/orders.py:2137 msgctxt "refund_source" msgid "Customer" msgstr "عميل" -#: pretix/base/models/orders.py:2127 +#: pretix/base/models/orders.py:2138 msgctxt "refund_source" msgid "External" msgstr "خارجي" -#: pretix/base/models/orders.py:2165 +#: pretix/base/models/orders.py:2176 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:198 msgid "Refund reason" msgstr "سبب استرداد الأموال" -#: pretix/base/models/orders.py:2166 +#: pretix/base/models/orders.py:2177 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:199 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:201 msgid "" @@ -6183,40 +6694,39 @@ msgstr "" "قد يتم عرضها للمستخدم النهائي أو استخدامها على سبيل المثال كجزء من مرجع " "السداد." -#: pretix/base/models/orders.py:2286 +#: pretix/base/models/orders.py:2297 msgid "Service fee" msgstr "رسوم الخدمة" -#: pretix/base/models/orders.py:2287 +#: pretix/base/models/orders.py:2298 msgid "Payment fee" msgstr "رسوم السداد" -#: pretix/base/models/orders.py:2288 +#: pretix/base/models/orders.py:2299 msgid "Shipping fee" msgstr "رسوم الشحن" -#: pretix/base/models/orders.py:2289 +#: pretix/base/models/orders.py:2300 #: pretix/control/templates/pretixcontrol/order/index.html:157 msgid "Cancellation fee" msgstr "رسوم الإلغاء" -#: pretix/base/models/orders.py:2290 +#: pretix/base/models/orders.py:2301 msgid "Insurance fee" msgstr "" -#: pretix/base/models/orders.py:2291 +#: pretix/base/models/orders.py:2302 #, fuzzy #| msgid "Other fees" msgid "Late fee" msgstr "رسوم أخرى" -#: pretix/base/models/orders.py:2292 +#: pretix/base/models/orders.py:2303 msgid "Other fees" msgstr "رسوم أخرى" -#: pretix/base/models/orders.py:2293 pretix/base/payment.py:1372 +#: pretix/base/models/orders.py:2304 pretix/base/payment.py:1372 #: pretix/base/payment.py:1419 pretix/base/settings.py:992 -#: pretix/control/forms/organizer.py:830 #: pretix/control/templates/pretixcontrol/items/index.html:107 #: pretix/control/templates/pretixcontrol/order/index.html:152 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:383 @@ -6225,7 +6735,7 @@ msgstr "رسوم أخرى" msgid "Gift card" msgstr "بطاقة هدايا" -#: pretix/base/models/orders.py:2298 +#: pretix/base/models/orders.py:2309 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:74 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:115 #: pretix/control/views/vouchers.py:120 @@ -6233,62 +6743,68 @@ msgstr "بطاقة هدايا" msgid "Value" msgstr "قيمة" -#: pretix/base/models/orders.py:2546 +#: pretix/base/models/orders.py:2557 msgid "Order position" msgstr "حالة الطلب" -#: pretix/base/models/orders.py:3091 +#: pretix/base/models/orders.py:3102 msgid "Cart ID (e.g. session key)" msgstr "معرف عربة التسوق (مثل مفتاح الجلسة)" -#: pretix/base/models/orders.py:3102 +#: pretix/base/models/orders.py:3113 #, fuzzy #| msgid "Expiration date" msgid "Limit for extending expiration date" msgstr "تاريخ إنتهاء الصلاحية" -#: pretix/base/models/orders.py:3131 +#: pretix/base/models/orders.py:3142 msgid "Cart position" msgstr "حالة سلة التسوق" -#: pretix/base/models/orders.py:3132 +#: pretix/base/models/orders.py:3143 msgid "Cart positions" msgstr "حالات سلة التسوق" -#: pretix/base/models/orders.py:3268 +#: pretix/base/models/orders.py:3279 msgid "Business customer" msgstr "عميل قطاع الأعمال" -#: pretix/base/models/orders.py:3284 +#: pretix/base/models/orders.py:3295 msgid "This reference will be printed on your invoice for your convenience." msgstr "ستتم طباعة هذا المرجع على فاتورتك وفقا لما يناسبك." -#: pretix/base/models/orders.py:3468 +#: pretix/base/models/orders.py:3422 +#, fuzzy +#| msgid "Transaction Code" +msgid "Transmission type" +msgstr "كود المعاملة" + +#: pretix/base/models/orders.py:3520 #: pretix/plugins/badges/templates/pretixplugins/badges/control_order_position_buttons.html:9 msgid "Badge" msgstr "شارة" -#: pretix/base/models/orders.py:3469 pretix/base/pdf.py:1113 -#: pretix/control/forms/organizer.py:781 pretix/control/forms/organizer.py:817 +#: pretix/base/models/orders.py:3521 pretix/base/pdf.py:1122 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:66 #: pretix/plugins/ticketoutputpdf/ticketoutput.py:113 msgid "Ticket" msgstr "تذكرة" -#: pretix/base/models/orders.py:3470 +#: pretix/base/models/orders.py:3522 #, fuzzy #| msgid "Verification failed" msgid "Certificate" msgstr "فشل التحقق" -#: pretix/base/models/orders.py:3471 pretix/control/views/event.py:393 -#: pretix/control/views/event.py:398 +#: pretix/base/models/orders.py:3523 pretix/control/views/event.py:393 +#: pretix/control/views/event.py:398 pretix/control/views/organizer.py:649 +#: pretix/control/views/organizer.py:654 #, fuzzy #| msgid "Other…" msgid "Other" msgstr "آخر…" -#: pretix/base/models/organizer.py:79 +#: pretix/base/models/organizer.py:81 msgid "" "Should be short, only contain lowercase letters, numbers, dots, and dashes. " "Every slug can only be used once. This is being used in URLs to refer to " @@ -6298,49 +6814,49 @@ msgstr "" "والشرطات. كل رابط يمكن استخدامه مرة واحدة فقط. ويستخدم هذا في عناوين الروابط " "للإشارة إلى حسابات المنظم والفعاليات الخاصة بك." -#: pretix/base/models/organizer.py:97 pretix/control/navigation.py:350 +#: pretix/base/models/organizer.py:103 pretix/control/navigation.py:350 #: pretix/control/templates/pretixcontrol/oauth/authorized.html:19 #: pretix/control/templates/pretixcontrol/organizers/index.html:6 #: pretix/control/templates/pretixcontrol/organizers/index.html:8 msgid "Organizers" msgstr "المنظمون" -#: pretix/base/models/organizer.py:284 +#: pretix/base/models/organizer.py:350 #: pretix/control/templates/pretixcontrol/organizers/teams.html:35 msgid "Team name" msgstr "اسم الفريق" -#: pretix/base/models/organizer.py:285 +#: pretix/base/models/organizer.py:351 #: pretix/control/templates/pretixcontrol/organizers/team_members.html:13 msgid "Team members" msgstr "أعضاء الفريق" -#: pretix/base/models/organizer.py:289 +#: pretix/base/models/organizer.py:355 #, fuzzy #| msgid "Do you really want to disable two-factor authentication?" msgid "Require all members of this team to use two-factor authentication" msgstr "هل تريد حقا أن اثنين عامل التوثيق تعطيلها؟" -#: pretix/base/models/organizer.py:290 +#: pretix/base/models/organizer.py:356 msgid "" "If you turn this on, all members of the team will be required to either set " "up two-factor authentication or leave the team. The setting may take a few " "minutes to become effective for all users." msgstr "" -#: pretix/base/models/organizer.py:297 +#: pretix/base/models/organizer.py:363 msgid "Can create events" msgstr "يسمح بإنشاء فعاليات" -#: pretix/base/models/organizer.py:301 +#: pretix/base/models/organizer.py:367 msgid "Can change teams and permissions" msgstr "يمكن تغيير الفرق والتصاريح" -#: pretix/base/models/organizer.py:305 +#: pretix/base/models/organizer.py:371 msgid "Can change organizer settings" msgstr "يسمح بتغيير إعدادات المنظم" -#: pretix/base/models/organizer.py:306 +#: pretix/base/models/organizer.py:372 msgid "" "Someone with this setting can get access to most data of all of your events, " "i.e. via privacy reports, so be careful who you add to this team!" @@ -6348,41 +6864,41 @@ msgstr "" "يمكن لأي شخص لديه هذا الإعداد الوصول إلى معظم البيانات لجميع الفعاليات‏ " "الخاصة بك ، أي عبر تقارير الخصوصية ، لذا كن حذرا عند الإضافة إلى الفريق!" -#: pretix/base/models/organizer.py:311 +#: pretix/base/models/organizer.py:377 msgid "Can manage customer accounts" msgstr "يسمح بإدارة حسابات العملاء" -#: pretix/base/models/organizer.py:315 +#: pretix/base/models/organizer.py:381 #, fuzzy #| msgid "Can manage customer accounts" msgid "Can manage reusable media" msgstr "يسمح بإدارة حسابات العملاء" -#: pretix/base/models/organizer.py:319 +#: pretix/base/models/organizer.py:385 msgid "Can manage gift cards" msgstr "يسمح بإدارة بطاقات الهدايا" -#: pretix/base/models/organizer.py:323 +#: pretix/base/models/organizer.py:389 msgid "Can change event settings" msgstr "يسمح بتغيير إعدادات الفعالية" -#: pretix/base/models/organizer.py:327 +#: pretix/base/models/organizer.py:393 msgid "Can change product settings" msgstr "يسمح بتغيير إعدادات المنتج" -#: pretix/base/models/organizer.py:331 +#: pretix/base/models/organizer.py:397 msgid "Can view orders" msgstr "يسمح بعرض الطلبات" -#: pretix/base/models/organizer.py:335 +#: pretix/base/models/organizer.py:401 msgid "Can change orders" msgstr "يسمح بتغيير الطلبات" -#: pretix/base/models/organizer.py:339 +#: pretix/base/models/organizer.py:405 msgid "Can perform check-ins" msgstr "يسمح بإجراء عمليات التسجيل" -#: pretix/base/models/organizer.py:340 +#: pretix/base/models/organizer.py:406 msgid "" "This includes searching for attendees, which can be used to obtain personal " "information about attendees. Users with \"can change orders\" can also " @@ -6392,53 +6908,54 @@ msgstr "" "الحضور. ويسمح للمستخدمين الذين لديهم خاصية \"يمكن تغيير الطلبات\" إجراء " "عمليات التسجيل." -#: pretix/base/models/organizer.py:345 +#: pretix/base/models/organizer.py:411 msgid "Can view vouchers" msgstr "يسمح باستعراض أكواد الخصم" -#: pretix/base/models/organizer.py:349 +#: pretix/base/models/organizer.py:415 msgid "Can change vouchers" msgstr "يسمح بتغيير أكواد الخصم" -#: pretix/base/models/organizer.py:353 +#: pretix/base/models/organizer.py:419 #, python-format msgid "%(name)s on %(object)s" msgstr "%(name)s على %(object)s" -#: pretix/base/models/organizer.py:385 -#: pretix/control/templates/pretixcontrol/events/create_basics.html:64 +#: pretix/base/models/organizer.py:451 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:67 msgid "Team" msgstr "فريق" -#: pretix/base/models/organizer.py:386 pretix/control/navigation.py:527 +#: pretix/base/models/organizer.py:452 pretix/control/navigation.py:539 #: pretix/control/templates/pretixcontrol/organizers/teams.html:6 msgid "Teams" msgstr "فرق" -#: pretix/base/models/organizer.py:406 +#: pretix/base/models/organizer.py:472 #, python-brace-format msgid "Invite to team '{team}' for '{email}'" msgstr "دعوة إلى فريق '{team}' ل '{email}'" -#: pretix/base/models/organizer.py:538 +#: pretix/base/models/organizer.py:604 #: pretix/control/templates/pretixcontrol/organizers/channels.html:23 #, fuzzy #| msgid "Internal identifier" msgid "Identifier" msgstr "معرف داخلي" -#: pretix/base/models/organizer.py:548 +#: pretix/base/models/organizer.py:614 #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:54 #: pretix/control/templates/pretixcontrol/items/questions.html:22 msgid "Type" msgstr "نوع" #: pretix/base/models/seating.py:45 pretix/base/models/tax.py:305 -#: pretix/base/pdf.py:1269 +#: pretix/base/pdf.py:1278 msgid "Your layout file is not a valid JSON file." msgstr "ملف التخطيط الخاص بك ليس ملف \"ترميز باستعمال جافا سكريبت\" صالح." #: pretix/base/models/seating.py:54 pretix/base/models/seating.py:78 +#, python-brace-format msgid "Your layout file is not a valid seating plan. Error message: {}" msgstr "ملف التخطيط الخاص بك ليس خطة جلوس صالحة. رسالة خطأ: {}" @@ -6609,7 +7126,7 @@ msgid "" msgstr "" #: pretix/base/models/tax.py:314 -#, fuzzy +#, fuzzy, python-brace-format #| msgid "Your layout file is not a valid seating plan. Error message: {}" msgid "Your set of rules is not valid. Error message: {}" msgstr "ملف التخطيط الخاص بك ليس خطة جلوس صالحة. رسالة خطأ: {}" @@ -6622,7 +7139,7 @@ msgstr "" msgid "Should be short, e.g. \"VAT\"" msgstr "يجب أن يكون قصيرا، على سبيل المثال VAT" -#: pretix/base/models/tax.py:330 pretix/control/forms/event.py:1513 +#: pretix/base/models/tax.py:330 pretix/control/forms/event.py:1522 #: pretix/control/templates/pretixcontrol/order/transactions.html:22 #, fuzzy #| msgid "Status code" @@ -6688,36 +7205,36 @@ msgstr "" "بلد إقامتك. هذا هو البلد الذي لن تنطبق فيه قاعدة الرسوم العكسية للاتحاد " "الأوروبي ، إذا تم الإعداد أعلاه." -#: pretix/base/models/tax.py:412 +#: pretix/base/models/tax.py:423 msgid "You need to set your home country to use the reverse charge feature." msgstr "تحتاج إلى تحديد بلدك لاستخدام ميزة التكلفة العكسية." -#: pretix/base/models/tax.py:416 pretix/control/forms/event.py:1560 +#: pretix/base/models/tax.py:427 pretix/control/forms/event.py:1569 msgid "" "A combination of this tax code with a non-zero tax rate does not make sense." msgstr "" -#: pretix/base/models/tax.py:421 pretix/control/forms/event.py:1564 +#: pretix/base/models/tax.py:432 pretix/control/forms/event.py:1573 msgid "" "A combination of this tax code with a zero tax rate does not make sense." msgstr "" -#: pretix/base/models/tax.py:426 +#: pretix/base/models/tax.py:437 #, python-brace-format msgid "incl. {rate}% {name}" msgstr "بما في ذلك {rate}% {name}" -#: pretix/base/models/tax.py:428 +#: pretix/base/models/tax.py:439 #, python-brace-format msgid "plus {rate}% {name}" msgstr "بالإضافة إلى {rate}% {name}" -#: pretix/base/models/tax.py:430 -#: pretix/control/templates/pretixcontrol/event/tax_index.html:46 +#: pretix/base/models/tax.py:441 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:63 msgid "reverse charge enabled" msgstr "تم تمكين التكلفة العكسية" -#: pretix/base/models/tax.py:568 +#: pretix/base/models/tax.py:579 msgctxt "invoice" msgid "" "Reverse Charge: According to Article 194, 196 of Council Directive 2006/112/" @@ -6726,7 +7243,7 @@ msgstr "" "التكلفة العكسية: وفقا للمادة 194 ، 196 من توجيه المجلس 2006/112/EEC ، تقع " "مسؤولية ضريبة القيمة المضافة على عاتق متلقي الخدمة." -#: pretix/base/models/tax.py:574 +#: pretix/base/models/tax.py:585 msgctxt "invoice" msgid "VAT liability rests with the service recipient." msgstr "تقع مسؤولية ضريبة القيمة المضافة على عاتق متلقي الخدمة." @@ -6747,15 +7264,15 @@ msgstr "اخصم من سعر المنتج" msgid "Reduce product price by (%)" msgstr "اخفض سعر المنتج بنسبة (%)" -#: pretix/base/models/vouchers.py:197 +#: pretix/base/models/vouchers.py:200 msgid "Number of times this voucher can be redeemed." msgstr "عدد المرات التي يمكن فيها استخدام كود الخصم هذا." -#: pretix/base/models/vouchers.py:201 pretix/control/views/vouchers.py:120 +#: pretix/base/models/vouchers.py:204 pretix/control/views/vouchers.py:120 msgid "Redeemed" msgstr "مستخدم" -#: pretix/base/models/vouchers.py:206 +#: pretix/base/models/vouchers.py:209 msgid "" "If set to more than one, the voucher must be redeemed for this many products " "when it is used for the first time. On later usages, it can also be used for " @@ -6764,7 +7281,7 @@ msgid "" "cancellations." msgstr "" -#: pretix/base/models/vouchers.py:214 +#: pretix/base/models/vouchers.py:217 msgid "" "This is the maximum monetary amount that will be discounted using this " "voucher across all usages. If this is sum reached, the voucher can no longer " @@ -6774,7 +7291,7 @@ msgstr "" "جميع الاستخدامات. إذا تم الوصول إلى هذا المبلغ ، فلن يعد من الممكن استخدام " "كود الخصم." -#: pretix/base/models/vouchers.py:227 +#: pretix/base/models/vouchers.py:230 msgid "" "If activated, this voucher will be substracted from the affected product's " "quotas, such that it is guaranteed that anyone with this voucher code does " @@ -6783,7 +7300,7 @@ msgstr "" "في حال التفعيل ، سيتم خصم كود الخصم هذا من حصص المنتجات المتأثرة ، بحيث يتم " "ضمان حصول أي شخص لديه رمز كود الخصم هذا على تذكرة." -#: pretix/base/models/vouchers.py:235 +#: pretix/base/models/vouchers.py:238 msgid "" "If activated, a holder of this voucher code can buy tickets, even if there " "are none left." @@ -6791,27 +7308,27 @@ msgstr "" "في حالة التفعيل ، يمكن لحامل رمز كود الخصم شراء التذاكر ، حتى إذا لم يتبق " "منها شيء." -#: pretix/base/models/vouchers.py:254 pretix/control/forms/vouchers.py:69 +#: pretix/base/models/vouchers.py:257 pretix/control/forms/vouchers.py:69 msgid "" "This product is added to the user's cart if the voucher is redeemed. Instead " "of a specific product, you can also select a quota. In this case, all " "products assigned to this quota can be selected." msgstr "" -#: pretix/base/models/vouchers.py:265 +#: pretix/base/models/vouchers.py:268 msgid "This variation of the product select above is being used." msgstr "يتم استخدام هذا النوع في المنتج المحدد أعلاه." -#: pretix/base/models/vouchers.py:274 +#: pretix/base/models/vouchers.py:277 msgid "" "If enabled, the voucher is valid for any product affected by this quota." msgstr "في حالة التفعيل، يكون كود الخصم صالحا لأي منتج متأثر بهذه الحصة." -#: pretix/base/models/vouchers.py:281 +#: pretix/base/models/vouchers.py:284 msgid "Specific seat" msgstr "مقعد محدد" -#: pretix/base/models/vouchers.py:288 +#: pretix/base/models/vouchers.py:291 msgid "" "You can use this field to group multiple vouchers together. If you enter the " "same value for multiple vouchers, you can get statistics on how many of them " @@ -6821,55 +7338,55 @@ msgstr "" "لأكواد خصم متعددة ، يمكنك الحصول على إحصائيات حول عدد ما تم استبداله منها " "وما إلى ذلك." -#: pretix/base/models/vouchers.py:313 pretix/control/navigation.py:267 +#: pretix/base/models/vouchers.py:316 pretix/control/navigation.py:267 #: pretix/control/templates/pretixcontrol/vouchers/index.html:6 #: pretix/control/templates/pretixcontrol/vouchers/index.html:8 msgid "Vouchers" msgstr "أكواد الخصم" -#: pretix/base/models/vouchers.py:339 +#: pretix/base/models/vouchers.py:342 msgid "You cannot select a quota that belongs to a different event." msgstr "لا يمكنك تحديد حصة تنتمي إلى فعالية مختلفة." -#: pretix/base/models/vouchers.py:341 +#: pretix/base/models/vouchers.py:344 msgid "You cannot select a quota and a specific product at the same time." msgstr "لا يمكنك اختيار حصة ومنتج محدد في نفس الوقت." -#: pretix/base/models/vouchers.py:344 +#: pretix/base/models/vouchers.py:347 msgid "" "You cannot select a product that is only available as an add-on product or " "as part of a bundle, since vouchers cannot be applied to add-on products or " "bundled products." msgstr "" -#: pretix/base/models/vouchers.py:348 +#: pretix/base/models/vouchers.py:351 #, fuzzy #| msgid "You cannot select a quota that belongs to a different event." msgid "You cannot select a product that belongs to a different event." msgstr "لا يمكنك تحديد حصة تنتمي إلى فعالية مختلفة." -#: pretix/base/models/vouchers.py:350 pretix/base/models/vouchers.py:360 +#: pretix/base/models/vouchers.py:353 pretix/base/models/vouchers.py:363 msgid "" "You cannot select a variation without having selected a product that " "provides variations." msgstr "لا يمكنك اختيار أحد الأشكال دون تحديد منتج يوفر متغيرات." -#: pretix/base/models/vouchers.py:353 +#: pretix/base/models/vouchers.py:356 msgid "This variation does not belong to this product." msgstr "هذا المتغير لا ينتمي إلى هذا المنتج." -#: pretix/base/models/vouchers.py:355 +#: pretix/base/models/vouchers.py:358 msgid "It is currently not possible to create vouchers for add-on products." msgstr "لا يمكن حاليا إنشاء أكواد الخصم للمنتجات الإضافية." -#: pretix/base/models/vouchers.py:357 pretix/base/models/vouchers.py:469 +#: pretix/base/models/vouchers.py:360 pretix/base/models/vouchers.py:472 msgid "" "You need to select a specific product or quota if this voucher should " "reserve tickets." msgstr "" "تحتاج إلى تحديد منتج أو حصة محددة إذا كان كود الخصم هذا مخصصا لحجز التذاكر." -#: pretix/base/models/vouchers.py:367 +#: pretix/base/models/vouchers.py:370 #, python-format msgid "" "This voucher has already been redeemed %(redeemed)s times. You cannot reduce " @@ -6878,7 +7395,7 @@ msgstr "" "تم استرداد كود الخصم هذا مسبقا %(redeemed)s مرة. لا يمكنك تقليل الحد الأقصى " "لعدد الاستخدامات تحت هذا الرقم." -#: pretix/base/models/vouchers.py:376 +#: pretix/base/models/vouchers.py:379 #, fuzzy #| msgid "" #| "The maximum number per order can not be lower than the minimum number per " @@ -6888,18 +7405,18 @@ msgid "" "usages." msgstr "لا يمكن أن يكون العدد الأقصى لكل طلب أقل من العدد الأدنى للطلب." -#: pretix/base/models/vouchers.py:382 pretix/base/models/vouchers.py:451 +#: pretix/base/models/vouchers.py:385 pretix/base/models/vouchers.py:454 msgid "" "If you want this voucher to block quota, you need to select a specific date." msgstr "" "إذا كنت تريد من كود الخصم هذا حجز حصة ، فأنت بحاجة إلى تحديد تاريخ محدد." -#: pretix/base/models/vouchers.py:384 +#: pretix/base/models/vouchers.py:387 msgid "You can not select a subevent if your event is not an event series." msgstr "" "لا يمكنك تحديد فعالية فرعية إذا لم تكن الفعالية الخاصة بك سلسلة فعاليات." -#: pretix/base/models/vouchers.py:482 +#: pretix/base/models/vouchers.py:485 msgid "" "You cannot create a voucher that blocks quota as the selected product or " "quota is currently sold out or completely reserved." @@ -6907,12 +7424,12 @@ msgstr "" "لا يمكنك إنشاء كود خصم يمنع الحصة لأن المنتج أو الحصة المحددة تم بيعها حاليا " "أو حجزها بالكامل." -#: pretix/base/models/vouchers.py:504 +#: pretix/base/models/vouchers.py:507 #, python-brace-format msgid "The specified seat ID \"{id}\" does not exist for this event." msgstr "رقم المقعد المحدد \"{id}\" غير متواجد في هذه الفعالية." -#: pretix/base/models/vouchers.py:508 +#: pretix/base/models/vouchers.py:511 #, python-brace-format msgid "" "The seat \"{id}\" is currently unavailable (blocked, already sold or a " @@ -6966,15 +7483,15 @@ msgstr "هذا الإدخال مجهول المصدر ولا يمكن استخد msgid "Automatically created from waiting list entry for {email}" msgstr "تم إنشاؤه تلقائيا عبر إدخال قائمة الانتظار ل{email}" -#: pretix/base/models/waitinglist.py:297 +#: pretix/base/models/waitinglist.py:300 msgid "The selected item does not belong to this event." msgstr "العنصر المحدد لا ينتمي إلى هذه الفعالية." -#: pretix/base/models/waitinglist.py:299 +#: pretix/base/models/waitinglist.py:302 msgid "Please select a specific variation of this product." msgstr "الرجاء تحديد متغير معين من هذا المنتج." -#: pretix/base/models/waitinglist.py:317 +#: pretix/base/models/waitinglist.py:320 msgid "" "You are already on this waiting list! We will notify you as soon as we have " "a ticket available for you." @@ -6989,8 +7506,8 @@ msgid "Dates" msgstr "تواريخ" #: pretix/base/notifications.py:200 -#: pretix/control/templates/pretixcontrol/order/index.html:678 -#: pretix/plugins/reports/accountingreport.py:317 +#: pretix/control/templates/pretixcontrol/order/index.html:730 +#: pretix/plugins/reports/accountingreport.py:318 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:442 msgid "Net total" msgstr "الإجمالي الصافي" @@ -6999,18 +7516,13 @@ msgstr "الإجمالي الصافي" msgid "Pending amount" msgstr "مبالغ متأخرة" -#: pretix/base/notifications.py:204 pretix/control/forms/filter.py:211 -#: pretix/control/forms/modelimport.py:81 -msgid "Order status" -msgstr "حالة الطلب" - #: pretix/base/notifications.py:222 msgid "Purchased products" msgstr "المنتجات التي تم شراءها" #: pretix/base/notifications.py:223 pretix/base/services/placeholders.py:384 #: pretix/base/services/placeholders.py:393 -#: pretix/base/templates/pretixbase/email/order_details.html:141 +#: pretix/base/templates/pretixbase/email/order_details.html:147 msgid "View order details" msgstr "معاينة تفاصيل الطلب" @@ -7326,7 +7838,7 @@ msgstr "شباك التذاكر" msgid "Manual payment" msgstr "الدفع اليدوي" -#: pretix/base/payment.py:1219 pretix/plugins/banktransfer/payment.py:202 +#: pretix/base/payment.py:1219 pretix/plugins/banktransfer/payment.py:195 msgid "" "In test mode, you can just manually mark this order as paid in the backend " "after it has been created." @@ -7335,7 +7847,7 @@ msgstr "" "التحكم بعد إنشائه." #: pretix/base/payment.py:1240 pretix/base/payment.py:1427 -#: pretix/plugins/banktransfer/payment.py:156 +#: pretix/plugins/banktransfer/payment.py:149 msgid "Payment method name" msgstr "اسم طريقة الدفع" @@ -7382,7 +7894,7 @@ msgstr "" "المستخدم إلى كيفية متابعة الدفع. يمكنك استخدام العناصر {order}, {amount}, " "{currency} و {amount_with_currency}." -#: pretix/base/payment.py:1267 pretix/plugins/banktransfer/payment.py:151 +#: pretix/base/payment.py:1267 pretix/plugins/banktransfer/payment.py:144 msgid "" "Create an invoice for orders using bank transfer immediately if the event is " "otherwise configured to create invoices after payment is completed." @@ -7394,7 +7906,7 @@ msgstr "" msgid "Offsetting" msgstr "تعويض" -#: pretix/base/payment.py:1332 pretix/control/views/orders.py:1266 +#: pretix/base/payment.py:1332 pretix/control/views/orders.py:1251 msgid "You entered an order that could not be found." msgstr "لقد أدخلت طلبا لا يمكن العثور عليه." @@ -7429,19 +7941,13 @@ msgstr "رمز التذكرة (محتوى الباركود)" msgid "Order position number" msgstr "رقم حالة الطلب" -#: pretix/base/pdf.py:116 -#, fuzzy -#| msgid "Order position number" -msgid "Order code and position number" -msgstr "رقم حالة الطلب" - -#: pretix/base/pdf.py:121 pretix/control/forms/event.py:1768 +#: pretix/base/pdf.py:121 pretix/control/forms/event.py:1777 #: pretix/control/templates/pretixcontrol/items/index.html:38 msgid "Product name" msgstr "اسم المنتج" #: pretix/base/pdf.py:122 pretix/base/services/tickets.py:101 -#: pretix/control/views/event.py:844 pretix/control/views/pdf.py:94 +#: pretix/control/views/event.py:888 pretix/control/views/pdf.py:94 msgid "Sample product" msgstr "نموذج منتج" @@ -7458,7 +7964,7 @@ msgid "Product description" msgstr "وصف المنتج" #: pretix/base/pdf.py:132 pretix/base/services/tickets.py:102 -#: pretix/control/views/event.py:845 pretix/control/views/pdf.py:95 +#: pretix/control/views/event.py:889 pretix/control/views/pdf.py:95 msgid "Sample product description" msgstr "نموذج وصف منتج" @@ -7482,44 +7988,43 @@ msgstr "نموذج وصف نوع المنتج" msgid "Ticket category" msgstr "فئة التذكرة" -#: pretix/base/pdf.py:159 pretix/base/pdf.py:164 +#: pretix/base/pdf.py:159 pretix/base/pdf.py:164 pretix/base/pdf.py:173 msgid "123.45 EUR" msgstr "123.45 يورو" #: pretix/base/pdf.py:163 -msgid "Price including add-ons" +#, fuzzy +#| msgid "Price including add-ons" +msgid "Price including bundled products" msgstr "السعر شاملا الإضافات" -#: pretix/base/pdf.py:173 pretix/base/pdf.py:331 -#: pretix/base/services/invoices.py:476 +#: pretix/base/pdf.py:172 +#, fuzzy +#| msgid "Price including add-ons" +msgid "Price including add-ons and bundled products" +msgstr "السعر شاملا الإضافات" + +#: pretix/base/pdf.py:182 pretix/base/pdf.py:340 +#: pretix/base/services/invoices.py:487 #: pretix/base/services/placeholders.py:571 #: pretix/base/services/placeholders.py:653 #: pretix/base/services/placeholders.py:669 -#: pretix/base/services/placeholders.py:678 pretix/control/views/event.py:846 +#: pretix/base/services/placeholders.py:678 pretix/control/views/event.py:890 msgid "John Doe" msgstr "جون دو" -#: pretix/base/pdf.py:177 -#: pretix/control/templates/pretixcontrol/order/index.html:543 -#: pretix/plugins/badges/exporters.py:496 -#: pretix/plugins/ticketoutputpdf/exporters.py:95 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:182 -#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:185 -msgid "Attendee company" -msgstr "شركة حاضرة" - -#: pretix/base/pdf.py:178 pretix/base/pdf.py:336 +#: pretix/base/pdf.py:187 pretix/base/pdf.py:345 #: pretix/base/services/tickets.py:119 pretix/control/views/pdf.py:110 #: pretix/control/views/pdf.py:116 pretix/control/views/pdf.py:123 #: pretix/control/views/pdf.py:128 msgid "Sample company" msgstr "نموذج شركة" -#: pretix/base/pdf.py:182 +#: pretix/base/pdf.py:191 msgid "Full attendee address" msgstr "عنوان الحاضرالكامل" -#: pretix/base/pdf.py:183 +#: pretix/base/pdf.py:192 msgid "" "John Doe\n" "Sample company\n" @@ -7533,162 +8038,158 @@ msgstr "" "12345 أي مدينة\n" "اتلانتس" -#: pretix/base/pdf.py:187 +#: pretix/base/pdf.py:196 msgid "Attendee street" msgstr "شارع الحاضر" -#: pretix/base/pdf.py:192 +#: pretix/base/pdf.py:201 msgid "Attendee ZIP code" msgstr "الرمز البريدي للحضور" -#: pretix/base/pdf.py:197 +#: pretix/base/pdf.py:206 msgid "Attendee city" msgstr "مدينة الحاضر" -#: pretix/base/pdf.py:202 +#: pretix/base/pdf.py:211 msgid "Attendee state" msgstr "منطقة الحاضر" -#: pretix/base/pdf.py:207 +#: pretix/base/pdf.py:216 msgid "Attendee country" msgstr "بلد الحضور" -#: pretix/base/pdf.py:219 +#: pretix/base/pdf.py:228 #, fuzzy #| msgid "Pseudonymization ID" msgid "Pseudonymization ID (lead scanning)" msgstr "معرف الاسم المستعار" -#: pretix/base/pdf.py:225 pretix/base/pdf.py:230 +#: pretix/base/pdf.py:234 pretix/base/pdf.py:239 msgid "Sample event name" msgstr "مثال اسم فعالية" -#: pretix/base/pdf.py:235 +#: pretix/base/pdf.py:244 msgid "May 31st, 2017" msgstr "31 مايو 2017" -#: pretix/base/pdf.py:239 +#: pretix/base/pdf.py:248 msgid "Event date range" msgstr "نطاق تاريخ الفعالية" -#: pretix/base/pdf.py:240 +#: pretix/base/pdf.py:249 msgid "May 31st – June 4th, 2017" msgstr "31 مايو - 4 يونيو، 2017" -#: pretix/base/pdf.py:244 +#: pretix/base/pdf.py:253 msgid "Event begin date and time" msgstr "تاريخ ووقت بداية الفعالية" -#: pretix/base/pdf.py:245 +#: pretix/base/pdf.py:254 msgid "2017-05-31 20:00" msgstr "20:00 2017-05-31" -#: pretix/base/pdf.py:252 +#: pretix/base/pdf.py:261 msgid "Event begin date" msgstr "تاريخ بداية الفعالية" -#: pretix/base/pdf.py:253 pretix/base/pdf.py:279 pretix/base/pdf.py:388 -#: pretix/base/pdf.py:412 pretix/base/pdf.py:436 pretix/base/pdf.py:460 -#: pretix/base/pdf.py:517 pretix/base/pdf.py:522 +#: pretix/base/pdf.py:262 pretix/base/pdf.py:288 pretix/base/pdf.py:397 +#: pretix/base/pdf.py:421 pretix/base/pdf.py:445 pretix/base/pdf.py:469 +#: pretix/base/pdf.py:526 pretix/base/pdf.py:531 msgid "2017-05-31" msgstr "2017-05-31" -#: pretix/base/pdf.py:260 +#: pretix/base/pdf.py:269 msgid "Event begin time" msgstr "وقت بداية الفعالية" -#: pretix/base/pdf.py:261 +#: pretix/base/pdf.py:270 msgid "20:00" msgstr "20:00" -#: pretix/base/pdf.py:265 +#: pretix/base/pdf.py:274 #, fuzzy #| msgid "Event begin date" msgid "Event begin weekday" msgstr "تاريخ بداية الفعالية" -#: pretix/base/pdf.py:266 pretix/base/pdf.py:295 +#: pretix/base/pdf.py:275 pretix/base/pdf.py:304 #: pretix/base/services/checkin.py:362 pretix/control/forms/filter.py:1240 msgid "Friday" msgstr "يوم الجمعة" -#: pretix/base/pdf.py:270 +#: pretix/base/pdf.py:279 msgid "Event end date and time" msgstr "تاريخ ووقت إنتهاء الفعالية" -#: pretix/base/pdf.py:271 +#: pretix/base/pdf.py:280 msgid "2017-05-31 22:00" msgstr "22:00 2017-05-31" -#: pretix/base/pdf.py:287 +#: pretix/base/pdf.py:296 msgid "22:00" msgstr "22:00" -#: pretix/base/pdf.py:294 +#: pretix/base/pdf.py:303 #, fuzzy #| msgid "Event end date" msgid "Event end weekday" msgstr "تاريخ إنتهاء الفعالية" -#: pretix/base/pdf.py:299 +#: pretix/base/pdf.py:308 msgid "Event admission date and time" msgstr "تاريخ ووقت قبول الفعالية" -#: pretix/base/pdf.py:300 pretix/base/pdf.py:396 pretix/base/pdf.py:420 -#: pretix/base/pdf.py:444 pretix/base/pdf.py:468 pretix/base/pdf.py:511 +#: pretix/base/pdf.py:309 pretix/base/pdf.py:405 pretix/base/pdf.py:429 +#: pretix/base/pdf.py:453 pretix/base/pdf.py:477 pretix/base/pdf.py:520 msgid "2017-05-31 19:00" msgstr "19:00 2017-05-31" -#: pretix/base/pdf.py:307 +#: pretix/base/pdf.py:316 msgid "Event admission time" msgstr "وقت تسجيل الفعالية" -#: pretix/base/pdf.py:308 pretix/base/pdf.py:404 pretix/base/pdf.py:428 -#: pretix/base/pdf.py:452 pretix/base/pdf.py:476 +#: pretix/base/pdf.py:317 pretix/base/pdf.py:413 pretix/base/pdf.py:437 +#: pretix/base/pdf.py:461 pretix/base/pdf.py:485 msgid "19:00" msgstr "19:00" -#: pretix/base/pdf.py:315 +#: pretix/base/pdf.py:324 msgid "Event location" msgstr "موقع الفعالية" -#: pretix/base/pdf.py:316 pretix/base/settings.py:1134 +#: pretix/base/pdf.py:325 pretix/base/settings.py:1172 msgid "Random City" msgstr "مدينة عشوائية" -#: pretix/base/pdf.py:335 -msgid "Invoice address company" -msgstr "شركة عنوان الفاتورة" - -#: pretix/base/pdf.py:341 +#: pretix/base/pdf.py:350 msgid "Sesame Street 42" msgstr "شارع سيسيم 42" -#: pretix/base/pdf.py:346 +#: pretix/base/pdf.py:355 msgid "12345" msgstr "12345" -#: pretix/base/pdf.py:351 pretix/base/services/invoices.py:479 +#: pretix/base/pdf.py:360 pretix/base/services/invoices.py:490 msgid "Sample city" msgstr "مدينة مثال" -#: pretix/base/pdf.py:355 +#: pretix/base/pdf.py:364 msgid "Invoice address state" msgstr "منطقة عنوان الفاتورة" -#: pretix/base/pdf.py:356 +#: pretix/base/pdf.py:365 msgid "Sample State" msgstr "منطقة مثال" -#: pretix/base/pdf.py:361 +#: pretix/base/pdf.py:370 msgid "Atlantis" msgstr "اتلانتس" -#: pretix/base/pdf.py:365 +#: pretix/base/pdf.py:374 msgid "List of Add-Ons" msgstr "قائمة الإضافات" -#: pretix/base/pdf.py:366 +#: pretix/base/pdf.py:375 #, fuzzy #| msgid "" #| "Add-on 1\n" @@ -7700,236 +8201,265 @@ msgstr "" "الإضافة 1\n" "الإضافة 2" -#: pretix/base/pdf.py:372 pretix/control/forms/filter.py:1380 -#: pretix/control/forms/filter.py:1382 +#: pretix/base/pdf.py:381 pretix/control/forms/filter.py:1378 +#: pretix/control/forms/filter.py:1380 #: pretix/control/templates/pretixcontrol/organizers/index.html:42 msgid "Organizer name" msgstr "اسم المنظم" -#: pretix/base/pdf.py:373 +#: pretix/base/pdf.py:382 msgid "Event organizer company" msgstr "شركة منظم الفعالية" -#: pretix/base/pdf.py:377 +#: pretix/base/pdf.py:386 msgid "Organizer info text" msgstr "نص معلومات المنظم" -#: pretix/base/pdf.py:378 +#: pretix/base/pdf.py:387 msgid "Event organizer info text" msgstr "نص معلومات منظم الفعالية" -#: pretix/base/pdf.py:382 pretix/base/pdf.py:383 +#: pretix/base/pdf.py:391 pretix/base/pdf.py:392 msgid "Event info text" msgstr "نص معلومات الفعالية" -#: pretix/base/pdf.py:387 +#: pretix/base/pdf.py:396 msgid "Printing date" msgstr "تاريخ الطباعة" -#: pretix/base/pdf.py:395 +#: pretix/base/pdf.py:404 msgid "Printing date and time" msgstr "تاريخ ووقت الطباعة" -#: pretix/base/pdf.py:403 +#: pretix/base/pdf.py:412 msgid "Printing time" msgstr "وقت الطباعة" -#: pretix/base/pdf.py:411 pretix/control/forms/item.py:737 +#: pretix/base/pdf.py:420 pretix/control/forms/item.py:738 #, fuzzy #| msgid "Purchased" msgid "Purchase date" msgstr "اشترى" -#: pretix/base/pdf.py:419 +#: pretix/base/pdf.py:428 #, fuzzy #| msgid "Purchased" msgid "Purchase date and time" msgstr "اشترى" -#: pretix/base/pdf.py:427 +#: pretix/base/pdf.py:436 #, fuzzy #| msgid "Purchased" msgid "Purchase time" msgstr "اشترى" -#: pretix/base/pdf.py:435 +#: pretix/base/pdf.py:444 #, fuzzy #| msgid "Valid until" msgid "Validity start date" msgstr "حتى تاريخ" -#: pretix/base/pdf.py:443 +#: pretix/base/pdf.py:452 #, fuzzy #| msgid "Printing date and time" msgid "Validity start date and time" msgstr "تاريخ ووقت الطباعة" -#: pretix/base/pdf.py:451 +#: pretix/base/pdf.py:460 #, fuzzy #| msgid "Valid until" msgid "Validity start time" msgstr "حتى تاريخ" -#: pretix/base/pdf.py:459 +#: pretix/base/pdf.py:468 #, fuzzy #| msgid "Valid until" msgid "Validity end date" msgstr "حتى تاريخ" -#: pretix/base/pdf.py:467 +#: pretix/base/pdf.py:476 #, fuzzy #| msgid "Event end date and time" msgid "Validity end date and time" msgstr "تاريخ ووقت إنتهاء الفعالية" -#: pretix/base/pdf.py:475 +#: pretix/base/pdf.py:484 #, fuzzy #| msgid "Valid until" msgid "Validity end time" msgstr "حتى تاريخ" -#: pretix/base/pdf.py:483 +#: pretix/base/pdf.py:492 msgid "Reusable Medium ID" msgstr "" -#: pretix/base/pdf.py:488 +#: pretix/base/pdf.py:497 msgid "Seat: Full name" msgstr "مقعد: الاسم الكامل" -#: pretix/base/pdf.py:489 +#: pretix/base/pdf.py:498 msgid "Ground floor, Row 3, Seat 4" msgstr "الطابق الأرضي، الصف 3، مقعد 4" -#: pretix/base/pdf.py:491 pretix/base/pdf.py:497 -#: pretix/control/forms/orders.py:332 +#: pretix/base/pdf.py:500 pretix/base/pdf.py:506 +#: pretix/control/forms/orders.py:344 msgid "General admission" msgstr "التسجيل العام" -#: pretix/base/pdf.py:494 +#: pretix/base/pdf.py:503 msgid "Seat: zone" msgstr "مقعد: المنطقة" -#: pretix/base/pdf.py:495 +#: pretix/base/pdf.py:504 msgid "Ground floor" msgstr "الطابق الأرضي" -#: pretix/base/pdf.py:500 +#: pretix/base/pdf.py:509 msgid "Seat: row" msgstr "مقعد: صف" -#: pretix/base/pdf.py:505 +#: pretix/base/pdf.py:514 msgid "Seat: seat number" msgstr "مقعد: عدد المقاعد" -#: pretix/base/pdf.py:510 +#: pretix/base/pdf.py:519 msgid "Date and time of first scan" msgstr "تاريخ ووقت أول مسح" -#: pretix/base/pdf.py:516 +#: pretix/base/pdf.py:525 #, fuzzy #| msgid "Gift card code" msgid "Gift card: Issuance date" msgstr "رمز بطاقة الهدية" -#: pretix/base/pdf.py:521 +#: pretix/base/pdf.py:530 #, fuzzy #| msgid "Expiration date" msgid "Gift card: Expiration date" msgstr "تاريخ إنتهاء الصلاحية" -#: pretix/base/pdf.py:562 pretix/base/pdf.py:600 pretix/base/pdf.py:606 +#: pretix/base/pdf.py:571 pretix/base/pdf.py:609 pretix/base/pdf.py:615 #: pretix/plugins/badges/exporters.py:504 #: pretix/plugins/ticketoutputpdf/exporters.py:102 #, python-brace-format msgid "Question: {question}" msgstr "سؤال: {question}" -#: pretix/base/pdf.py:601 pretix/base/pdf.py:607 +#: pretix/base/pdf.py:610 pretix/base/pdf.py:616 #, python-brace-format msgid "" msgstr "<جواب: {question}>" -#: pretix/base/pdf.py:648 +#: pretix/base/pdf.py:657 #, fuzzy #| msgid "Attendee names" msgid "Attendee name for salutation" msgstr "أسماء الحضور" -#: pretix/base/pdf.py:649 pretix/base/pdf.py:672 +#: pretix/base/pdf.py:658 pretix/base/pdf.py:681 #: pretix/base/services/placeholders.py:696 -#: pretix/control/forms/organizer.py:661 +#: pretix/control/forms/organizer.py:664 msgid "Mr Doe" msgstr "السيد دو" -#: pretix/base/pdf.py:655 pretix/base/pdf.py:662 +#: pretix/base/pdf.py:664 pretix/base/pdf.py:671 #: pretix/plugins/badges/exporters.py:501 -#: pretix/plugins/checkinlists/exporters.py:124 -#: pretix/plugins/checkinlists/exporters.py:497 +#: pretix/plugins/checkinlists/exporters.py:125 +#: pretix/plugins/checkinlists/exporters.py:498 #: pretix/plugins/ticketoutputpdf/exporters.py:99 #, python-brace-format msgid "Attendee name: {part}" msgstr "اسم الحاضر: {part}" -#: pretix/base/pdf.py:671 +#: pretix/base/pdf.py:680 #, fuzzy #| msgid "Invoice address explanation" msgid "Invoice address name for salutation" msgstr "شرح عنوان الفاتورة" -#: pretix/base/pdf.py:678 +#: pretix/base/pdf.py:687 #, python-brace-format msgid "Invoice address name: {part}" msgstr "اسم عنوان الفاتورة: {part}" -#: pretix/base/pdf.py:1278 -#, fuzzy +#: pretix/base/pdf.py:1287 +#, fuzzy, python-brace-format #| msgid "Your layout file is not a valid seating plan. Error message: {}" msgid "Your layout file is not a valid layout. Error message: {}" msgstr "ملف التخطيط الخاص بك ليس خطة جلوس صالحة. رسالة خطأ: {}" -#: pretix/base/reldate.py:35 +#: pretix/base/plugins.py:136 +#: pretix/control/templates/pretixcontrol/event/quick_setup.html:132 +msgid "Features" +msgstr "المميزات" + +#: pretix/base/plugins.py:138 +#, fuzzy +#| msgid "Invoice generation" +msgid "Integrations" +msgstr "جيل فاتورة" + +#: pretix/base/plugins.py:139 +#, fuzzy +#| msgid "Customer actions" +msgid "Customizations" +msgstr "إجراءات العملاء" + +#: pretix/base/plugins.py:140 +#, fuzzy +#| msgid "Export format" +msgid "Output and export formats" +msgstr "تنسيق التصدير" + +#: pretix/base/plugins.py:141 +#, fuzzy +#| msgid "Features" +msgid "API features" +msgstr "المميزات" + +#: pretix/base/reldate.py:38 msgid "Event start" msgstr "بداية الفعالية" -#: pretix/base/reldate.py:36 +#: pretix/base/reldate.py:39 msgid "Event end" msgstr "نهاية الفعالية" -#: pretix/base/reldate.py:37 +#: pretix/base/reldate.py:40 msgid "Event admission" msgstr "تسجيل الفعالية" -#: pretix/base/reldate.py:38 +#: pretix/base/reldate.py:41 msgid "Presale start" msgstr "بداية إعلان ما قبل البيع" -#: pretix/base/reldate.py:39 +#: pretix/base/reldate.py:42 msgid "Presale end" msgstr "نهاية إعلان ما قبل البيع" -#: pretix/base/reldate.py:183 +#: pretix/base/reldate.py:186 #, fuzzy #| msgid "days before" msgid "before" msgstr "أيام قبل" -#: pretix/base/reldate.py:184 +#: pretix/base/reldate.py:187 msgid "after" msgstr "" -#: pretix/base/reldate.py:292 pretix/base/reldate.py:456 +#: pretix/base/reldate.py:308 pretix/base/reldate.py:472 msgid "Fixed date:" msgstr "التاريخ المحدد:" -#: pretix/base/reldate.py:293 pretix/base/reldate.py:457 +#: pretix/base/reldate.py:309 pretix/base/reldate.py:473 msgid "Relative date:" msgstr "تاريخ نسبي:" -#: pretix/base/reldate.py:294 +#: pretix/base/reldate.py:310 msgid "Relative time:" msgstr "وقت نسبي:" -#: pretix/base/reldate.py:302 pretix/base/reldate.py:460 +#: pretix/base/reldate.py:318 pretix/base/reldate.py:476 msgid "Not set" msgstr "غير محدد" @@ -7951,13 +8481,13 @@ msgstr "" "ويغير دلالات المسح دون اتصال - يرجى الرجوع إلى التوثيق أو الدعم للحصول على " "التفاصيل)" -#: pretix/base/services/cancelevent.py:229 -#: pretix/base/services/cancelevent.py:287 +#: pretix/base/services/cancelevent.py:230 +#: pretix/base/services/cancelevent.py:308 msgid "Event canceled" msgstr "تم إلغاء الفعالية" -#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:194 -#: pretix/base/services/orders.py:151 +#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:235 +#: pretix/base/services/orders.py:155 msgid "" "We were not able to process your request completely as the server was too " "busy. Please try again." @@ -7977,7 +8507,7 @@ msgctxt "subevent" msgid "No date was specified." msgstr "لم يتم تحديد تاريخ." -#: pretix/base/services/cart.py:108 pretix/base/services/orders.py:188 +#: pretix/base/services/cart.py:108 pretix/base/services/orders.py:192 msgid "You selected a product which is not available for sale." msgstr "لقد اخترت منتجا غير متوفر للبيع." @@ -8033,7 +8563,7 @@ msgstr[3] "لا يمكنك تحديد أكثر من %s عناصر لكل طلب. msgstr[4] "لا يمكنك تحديد أكثر من %s عناصر لكل طلب." msgstr[5] "لا يمكنك تحديد أكثر من %s عناصر لكل طلب." -#: pretix/base/services/cart.py:131 pretix/base/services/orders.py:1542 +#: pretix/base/services/cart.py:131 pretix/base/services/orders.py:1598 #, fuzzy, python-format #| msgid "" #| "You cannot select more than %(max)s items of the product %(product)s." @@ -8047,7 +8577,7 @@ msgstr[3] "لا يمكنك تحديد أكثر من %(max)s عناصر من ال msgstr[4] "لا يمكنك تحديد أكثر من %(max)s عناصر من المنتج %(product)s." msgstr[5] "لا يمكنك تحديد أكثر من %(max)s عناصر من المنتج %(product)s." -#: pretix/base/services/cart.py:136 pretix/base/services/orders.py:1547 +#: pretix/base/services/cart.py:136 pretix/base/services/orders.py:1603 #, fuzzy, python-format #| msgid "" #| "You need to select at least %(min)s items of the product %(product)s." @@ -8091,8 +8621,8 @@ msgstr[5] "" "أزلنا %(product)s من عربة التسوق الخاصة بك كما لا يمكنك شراء أقل من %(min)s " "عناصر من المنتج." -#: pretix/base/services/cart.py:145 pretix/base/services/orders.py:154 -#: pretix/presale/templates/pretixpresale/event/index.html:171 +#: pretix/base/services/cart.py:145 pretix/base/services/orders.py:158 +#: pretix/presale/templates/pretixpresale/event/index.html:170 #: pretix/presale/views/waiting.py:145 pretix/presale/views/widget.py:781 #, fuzzy #| msgid "The presale period for this event has not yet started." @@ -8125,7 +8655,7 @@ msgstr "" "لم تبدأ فترة عرض ما قبل البيع لهذه الفعالية بعد. تمت إزالة العناصر المتأثرة " "من عربة التسوق الخاصة بك." -#: pretix/base/services/cart.py:152 pretix/base/services/orders.py:182 +#: pretix/base/services/cart.py:152 pretix/base/services/orders.py:186 #, fuzzy #| msgid "" #| "The presale period for one of the events in your cart has ended. The " @@ -8151,7 +8681,7 @@ msgstr "السعر الذي تم إدخاله مرتفع جدا." msgid "This voucher code is not known in our database." msgstr "رمز كود الخصم هذا غير معروف في قاعدة البيانات الخاصة بنا." -#: pretix/base/services/cart.py:158 pretix/base/services/orders.py:157 +#: pretix/base/services/cart.py:158 pretix/base/services/orders.py:161 #, python-format msgid "" "The voucher code \"%(voucher)s\" can only be used if you select at least " @@ -8259,15 +8789,15 @@ msgctxt "subevent" msgid "The selected event date is not active." msgstr "تاريخ الفعالية المحدد غير نشط." -#: pretix/base/services/cart.py:195 pretix/base/services/orders.py:189 +#: pretix/base/services/cart.py:195 pretix/base/services/orders.py:193 msgid "You can not select an add-on for the selected product." msgstr "لا يمكنك اختيار إضافة للمنتج المحدد." -#: pretix/base/services/cart.py:196 pretix/base/services/orders.py:190 +#: pretix/base/services/cart.py:196 pretix/base/services/orders.py:194 msgid "You can not select two variations of the same add-on product." msgstr "لا يمكنك تحديد نوعين مختلفين من نفس منتج قائمة الإضافة." -#: pretix/base/services/cart.py:198 pretix/base/services/orders.py:192 +#: pretix/base/services/cart.py:198 pretix/base/services/orders.py:196 #, fuzzy, python-format #| msgid "" #| "You can select at most %(max)s add-ons from the category %(cat)s for the " @@ -8291,7 +8821,7 @@ msgstr[4] "" msgstr[5] "" "يمكنك الاختيار على الأكثر %(max)s من الإضافات لفئة %(cat)s للمنتج %(base)s." -#: pretix/base/services/cart.py:203 pretix/base/services/orders.py:197 +#: pretix/base/services/cart.py:203 pretix/base/services/orders.py:201 #, fuzzy, python-format #| msgid "" #| "You need to select at least %(min)s add-ons from the category %(cat)s for " @@ -8315,7 +8845,7 @@ msgstr[4] "" msgstr[5] "" "تحتاج إلى اختيار على الأقل %(min)s من الإضافات لفئة %(cat)s للمنتج %(base)s." -#: pretix/base/services/cart.py:207 pretix/base/services/orders.py:201 +#: pretix/base/services/cart.py:207 pretix/base/services/orders.py:205 #, fuzzy, python-format #| msgid "" #| "You can select every add-ons from the category %(cat)s for the product " @@ -8597,13 +9127,13 @@ msgstr "تم رفض طلب الإذن" msgid "Your exported data exceeded the size limit for scheduled exports." msgstr "" -#: pretix/base/services/invoices.py:103 +#: pretix/base/services/invoices.py:109 #, python-brace-format msgctxt "invoice" msgid "Please complete your payment before {expire_date}." msgstr "يرجى إتمام عملية الدفع قبل {expire_date}." -#: pretix/base/services/invoices.py:115 +#: pretix/base/services/invoices.py:121 #, python-brace-format msgctxt "invoice" msgid "" @@ -8619,50 +9149,52 @@ msgstr "" "{i.zipcode} {i.city} {state}\n" "{country}" -#: pretix/base/services/invoices.py:220 pretix/base/services/invoices.py:257 +#: pretix/base/services/invoices.py:229 pretix/base/services/invoices.py:266 #, fuzzy, python-brace-format #| msgid "Event location" msgctxt "invoice" msgid "Event location: {location}" msgstr "موقع الفعالية" -#: pretix/base/services/invoices.py:236 +#: pretix/base/services/invoices.py:245 #, python-brace-format msgctxt "invoice" msgid "Attendee: {name}" msgstr "الحاضر: {name}" -#: pretix/base/services/invoices.py:254 pretix/plugins/reports/exporters.py:298 +#: pretix/base/services/invoices.py:263 pretix/plugins/reports/exporters.py:309 +#, python-brace-format msgctxt "subevent" msgid "Date: {}" msgstr "تاريخ: {}" -#: pretix/base/services/invoices.py:469 +#: pretix/base/services/invoices.py:480 msgid "A payment provider specific text might appear here." msgstr "قد يظهر نص محدد لمزود خدمة الدفع هنا." -#: pretix/base/services/invoices.py:477 +#: pretix/base/services/invoices.py:488 msgid "214th Example Street" msgstr "مثال شارع رقم 214" -#: pretix/base/services/invoices.py:478 +#: pretix/base/services/invoices.py:489 msgid "012345" msgstr "012345" -#: pretix/base/services/invoices.py:495 +#: pretix/base/services/invoices.py:506 +#, python-brace-format msgid "Sample product {}" msgstr "نموذج منتج {}" -#: pretix/base/services/invoices.py:505 +#: pretix/base/services/invoices.py:516 msgid "Sample product A" msgstr "نموذج منتج أ" -#: pretix/base/services/invoices.py:535 +#: pretix/base/services/invoices.py:576 #, python-brace-format msgid "New invoice: {number}" msgstr "فاتورة جديدة: {number}" -#: pretix/base/services/invoices.py:537 +#: pretix/base/services/invoices.py:578 #, fuzzy, python-brace-format #| msgid "" #| "Hello,\n" @@ -8851,31 +9383,46 @@ msgstr "" "خطأ أثناء استيراد القيمة \"{value}\" للعمود \"{column}\" في السطر \"{line}" "\": {message}" -#: pretix/base/services/modelimport.py:89 pretix/base/services/orders.py:1551 +#: pretix/base/services/modelimport.py:89 +#: pretix/base/services/modelimport.py:137 pretix/base/services/orders.py:1607 #, python-format msgid "Orders cannot have more than %(max)s positions." msgstr "" -#: pretix/base/services/modelimport.py:124 -#: pretix/base/services/modelimport.py:236 +#: pretix/base/services/modelimport.py:113 +#, python-format +msgid "" +"The grouping \"%(value)s\" occurs on non-consecutive lines (seen again on " +"line %(row)s)." +msgstr "" + +#: pretix/base/services/modelimport.py:151 +#, python-brace-format +msgid "" +"Inconsistent data in row {row}: Column {col} contains value \"{val_line}\", " +"but for this order, the value has already been set to \"{val_order}\"." +msgstr "" + +#: pretix/base/services/modelimport.py:165 +#: pretix/base/services/modelimport.py:277 #, python-brace-format msgid "Invalid data in row {row}: {message}" msgstr "بيانات غير صالحة في الصف {row}: {message}" -#: pretix/base/services/modelimport.py:217 +#: pretix/base/services/modelimport.py:258 #, fuzzy #| msgid "A voucher can not be deleted if it already has been redeemed." msgid "A voucher cannot be created without a code." msgstr "لا يمكن حذف قسيمة إذا كان بالفعل قد تم استبدالها." -#: pretix/base/services/orders.py:130 +#: pretix/base/services/orders.py:134 msgid "" "Some of the products you selected were no longer available. Please see below " "for details." msgstr "" "بعض المنتجات التي حددتها لم تعد متوفرة. انظر أدناه للحصول على التفاصيل." -#: pretix/base/services/orders.py:134 +#: pretix/base/services/orders.py:138 msgid "" "Some of the products you selected were no longer available in the quantity " "you selected. Please see below for details." @@ -8883,7 +9430,7 @@ msgstr "" "لم تعد بعض المنتجات التي اخترتها متوفرة بالكمية التي حددتها. انظر أدناه " "للحصول على التفاصيل." -#: pretix/base/services/orders.py:138 +#: pretix/base/services/orders.py:142 msgid "" "The price of some of the items in your cart has changed in the meantime. " "Please see below for details." @@ -8891,21 +9438,21 @@ msgstr "" "تم تغيير سعر بعض العناصر في سلة التسوق الخاصة. انظر أدناه للحصول على " "التفاصيل." -#: pretix/base/services/orders.py:141 +#: pretix/base/services/orders.py:145 msgid "An internal error occurred, please try again." msgstr "حدث خطأ داخلي ، يرجى المحاولة مرة أخرى." -#: pretix/base/services/orders.py:142 +#: pretix/base/services/orders.py:146 msgid "" "This order was changed by someone else simultaneously. Please check if your " "changes are still accurate and try again." msgstr "" -#: pretix/base/services/orders.py:144 +#: pretix/base/services/orders.py:148 msgid "Your cart is empty." msgstr "عربة التسوق الخاصة بك فارغة." -#: pretix/base/services/orders.py:146 +#: pretix/base/services/orders.py:150 #, fuzzy, python-format #| msgid "" #| "You cannot select more than %(max)s items of the product %(product)s. We " @@ -8935,13 +9482,13 @@ msgstr[5] "" "لا يمكنك تحديد أكثر من %(max)s وحدة من المنتج %(product)s. قمنا بإزالة " "العناصر الزائدة في سلة التسوق الخاصة بك." -#: pretix/base/services/orders.py:155 +#: pretix/base/services/orders.py:159 #, fuzzy #| msgid "The presale period has ended." msgid "The booking period has ended." msgstr "انتهت فترة عرض ما قبل البيع." -#: pretix/base/services/orders.py:161 +#: pretix/base/services/orders.py:165 msgid "" "The voucher code used for one of the items in your cart is not known in our " "database." @@ -8949,7 +9496,7 @@ msgstr "" "رمز كود الخصم المستخدم لأحد العناصر الموجودة في سلة التسوق الخاصة بك غير " "معروف في قاعدة البيانات الخاصة بنا." -#: pretix/base/services/orders.py:163 +#: pretix/base/services/orders.py:167 msgid "" "The voucher code used for one of the items in your cart has already been " "used the maximum number of times allowed. We removed this item from your " @@ -8959,7 +9506,7 @@ msgstr "" "بك سابقا وتجاوز عدد المرات المسموح به. أزلنا هذا العنصر من سلة التسوق الخاصة " "بك." -#: pretix/base/services/orders.py:167 +#: pretix/base/services/orders.py:171 msgid "" "The voucher code used for one of the items in your cart has already been too " "often. We adjusted the price of the item in your cart." @@ -8967,7 +9514,7 @@ msgstr "" "رمز كود الخصم المستخدم لأحد العناصر في سلة التسوق الخاصة بك تم استخدامه " "كثيرا في السابق. قمنا بتعديل سعر العنصر في سلة التسوق الخاصة بك." -#: pretix/base/services/orders.py:171 +#: pretix/base/services/orders.py:175 msgid "" "The voucher code used for one of the items in your cart is expired. We " "removed this item from your cart." @@ -8975,7 +9522,7 @@ msgstr "" "انتهت صلاحية رمز كود الخصم المستخدم لأحد العناصر الموجودة في سلة التسوق " "الخاصة بك. أزلنا هذا العنصر من سلة التسوق الخاصة بك." -#: pretix/base/services/orders.py:174 +#: pretix/base/services/orders.py:178 msgid "" "The voucher code used for one of the items in your cart is not valid for " "this item. We removed this item from your cart." @@ -8983,13 +9530,13 @@ msgstr "" "رمز كود الخصم المستخدم لأحد العناصر الموجودة في سلة التسوق الخاصة بك غير " "صالح لهذا العنصر. أزلنا هذا العنصر من سلة التسوق الخاصة بك." -#: pretix/base/services/orders.py:176 +#: pretix/base/services/orders.py:180 #, fuzzy #| msgid "You need a valid voucher code to order this product." msgid "You need a valid voucher code to order one of the products." msgstr "تحتاج إلى رمز كود خصم صالح لطلب هذا المنتج." -#: pretix/base/services/orders.py:178 +#: pretix/base/services/orders.py:182 #, fuzzy #| msgid "" #| "The presale period for one of the events in your cart has not yet " @@ -9001,7 +9548,7 @@ msgstr "" "لم تبدأ فترة عرض ما قبل البيع لإحدى الفعاليات في عربة التسوق الخاصة بك بعد. " "تمت إزالة العناصر المتأثرة من عربة التسوق الخاصة بك." -#: pretix/base/services/orders.py:185 +#: pretix/base/services/orders.py:189 msgid "" "One of the seats in your order was invalid, we removed the position from " "your cart." @@ -9009,7 +9556,7 @@ msgstr "" "كان أحد المقاعد في طلبك غير صالح ، قمنا بإزالة العنصر من عربة التسوق الخاصة " "بك." -#: pretix/base/services/orders.py:186 +#: pretix/base/services/orders.py:190 msgid "" "One of the seats in your order has been taken in the meantime, we removed " "the position from your cart." @@ -9017,7 +9564,7 @@ msgstr "" "تم أخذ أحد المقاعد في طلبك في هذه الأثناء، وقمنا بإزالة العنصر من عربة " "التسوق الخاصة بك." -#: pretix/base/services/orders.py:202 +#: pretix/base/services/orders.py:206 #, fuzzy, python-format #| msgid "" #| "You cannot delete the product %(item)s because it " @@ -9027,32 +9574,32 @@ msgid "" "in." msgstr "لا يمكنك حذف المنتج على %(item)s لأنه بالفعل قد أمرت." -#: pretix/base/services/orders.py:203 +#: pretix/base/services/orders.py:207 #, fuzzy #| msgid "This gift card does not support this currency." msgid "Paid products not supported without a valid currency." msgstr "بطاقة الهدايا هذه لا تدعم هذه العملة." -#: pretix/base/services/orders.py:219 +#: pretix/base/services/orders.py:223 #, fuzzy #| msgid "The order has been canceled." msgid "The order was not canceled." msgstr "تم إلغاء هذا الأمر." -#: pretix/base/services/orders.py:273 pretix/control/forms/orders.py:126 +#: pretix/base/services/orders.py:277 pretix/control/forms/orders.py:126 msgid "The new expiry date needs to be in the future." msgstr "يجب أن يكون تاريخ إنتهاء الصلاحية الجديد في المستقبل." -#: pretix/base/services/orders.py:367 pretix/base/services/orders.py:453 +#: pretix/base/services/orders.py:371 pretix/base/services/orders.py:463 msgid "This order is not pending approval." msgstr "هذا الطلب ليس في انتظار الموافقة." -#: pretix/base/services/orders.py:511 pretix/presale/views/order.py:930 +#: pretix/base/services/orders.py:525 pretix/presale/views/order.py:930 #: pretix/presale/views/order.py:984 msgid "You cannot cancel this order." msgstr "لا يمكنك إلغاء هذا الطلب." -#: pretix/base/services/orders.py:523 +#: pretix/base/services/orders.py:537 #, python-brace-format msgid "" "This order can not be canceled since the gift card {card} purchased in this " @@ -9061,7 +9608,7 @@ msgstr "" "لا يمكن إلغاء هذا الطلب لأنه تم بالفعل استرداد قيمة بطاقة الهدايا {card} " "المشتراة لهذا الطلب." -#: pretix/base/services/orders.py:563 pretix/control/forms/orders.py:207 +#: pretix/base/services/orders.py:600 pretix/control/forms/orders.py:219 #, fuzzy #| msgid "" #| "The cancellation fee cannot be higher than the payment credit of this " @@ -9070,13 +9617,13 @@ msgid "" "The cancellation fee cannot be higher than the total amount of this order." msgstr "لا يمكن أن تكون رسوم الإلغاء أعلى من رصيد الدفع لهذا الطلب." -#: pretix/base/services/orders.py:958 +#: pretix/base/services/orders.py:1000 #, fuzzy #| msgid "This payment method does not support automatic refunds." msgid "The selected payment methods do not cover the total balance." msgstr "طريقة الدفع هذه لا يدعم استرداد التلقائي." -#: pretix/base/services/orders.py:1026 +#: pretix/base/services/orders.py:1068 msgid "" "While trying to place your order, we noticed that the order total has " "changed. Either one of the prices changed just now, or a gift card you used " @@ -9086,31 +9633,31 @@ msgstr "" "الأسعار الآن ، أو أن بطاقة الهدايا التي استخدمتها جاري استعمالها في الوقت " "الحالي. يرجى التحقق من الأسعار أدناه والمحاولة مرة أخرى." -#: pretix/base/services/orders.py:1521 +#: pretix/base/services/orders.py:1577 msgid "You need to select a variation of the product." msgstr "تحتاج إلى تحديد نوع من المنتج." -#: pretix/base/services/orders.py:1522 +#: pretix/base/services/orders.py:1578 #, python-brace-format msgid "" "The quota {name} does not have enough capacity left to perform the operation." msgstr "الحصة {name} لم يتبق لديها سعة كافية لإجراء العملية." -#: pretix/base/services/orders.py:1523 +#: pretix/base/services/orders.py:1579 msgid "There is no quota defined that allows this operation." msgstr "لا توجد حصة محددة تسمح بهذه العملية." -#: pretix/base/services/orders.py:1524 +#: pretix/base/services/orders.py:1580 msgid "The selected product is not active or has no price set." msgstr "المنتج المحدد غير نشط أو ليس له سعر محدد." -#: pretix/base/services/orders.py:1525 +#: pretix/base/services/orders.py:1581 msgid "" "This operation would leave the order empty. Please cancel the order itself " "instead." msgstr "سيترك هذا الإجراء الطلب فارغا. يرجى إلغاء الطلب نفسه بدلا من ذلك." -#: pretix/base/services/orders.py:1527 +#: pretix/base/services/orders.py:1583 msgid "" "This operation would make the order free and therefore immediately paid, " "however no quota is available." @@ -9118,23 +9665,23 @@ msgstr "" "ستجعل هذه العملية الطلب مجانيا وبالتالي يتم دفعه على الفور ، إلا أنه لا " "تتوفر حصة." -#: pretix/base/services/orders.py:1530 +#: pretix/base/services/orders.py:1586 msgid "" "This is an add-on product, please select the base position it should be " "added to." msgstr "هذا منتج إضافي ، يرجى تحديد العنصر الأساسي الذي تجب الإضافة إليه." -#: pretix/base/services/orders.py:1531 +#: pretix/base/services/orders.py:1587 msgid "" "The selected base position does not allow you to add this product as an add-" "on." msgstr "لا يسمح لك العنصر المختار بإضافة هذا المنتج كقائمة مضافة." -#: pretix/base/services/orders.py:1532 +#: pretix/base/services/orders.py:1588 msgid "You need to choose a subevent for the new position." msgstr "تحتاج إلى اختيار فعالية فرعية للعنصر الجديد." -#: pretix/base/services/orders.py:1535 +#: pretix/base/services/orders.py:1591 #, python-brace-format msgid "" "You selected seat \"{seat}\" for a date that does not match the selected " @@ -9143,25 +9690,25 @@ msgstr "" "لقد حددت المقعد \"{seat}\" لتاريخ لا يتطابق مع تاريخ التذكرة المحدد. الرجاء " "اختيار مقعد مرة أخرى." -#: pretix/base/services/orders.py:1537 +#: pretix/base/services/orders.py:1593 msgid "The selected product requires you to select a seat." msgstr "المنتج المحدد يتطلب منك اختيار مقعد." -#: pretix/base/services/orders.py:1538 +#: pretix/base/services/orders.py:1594 msgid "The selected product does not allow to select a seat." msgstr "المنتج المحدد لا يسمح باختيار مقعد." -#: pretix/base/services/orders.py:1539 +#: pretix/base/services/orders.py:1595 msgid "The selected country is blocked by your tax rule." msgstr "تم حظر البلد المحدد من خلال القاعدة الضريبية الخاصة بك." -#: pretix/base/services/orders.py:1540 +#: pretix/base/services/orders.py:1596 msgid "" "You cannot change the price of a position that has been used to issue a gift " "card." msgstr "لا يمكنك تغيير سعر العنصر الذي تم استخدامه لإصدار بطاقة هدايا." -#: pretix/base/services/orders.py:2365 pretix/base/services/orders.py:2382 +#: pretix/base/services/orders.py:2421 pretix/base/services/orders.py:2438 #, python-brace-format msgid "" "A position can not be canceled since the gift card {card} purchased in this " @@ -9170,7 +9717,7 @@ msgstr "" "لا يمكن إلغاء العنصر نظرا لأنه تم بالفعل استرداد قيمة بطاقة الهدايا {card} " "المشتراة في هذا الطلب." -#: pretix/base/services/orders.py:3058 +#: pretix/base/services/orders.py:3133 msgid "" "There was an error while trying to send the money back to you. Please " "contact the event organizer for further information." @@ -9205,7 +9752,7 @@ msgid "Please transfer money to this bank account: 9999-9999-9999-9999" msgstr "يرجى تحويل المبلغ إلى هذا الحساب المصرفي: 9999-9999-9999-9999" #: pretix/base/services/placeholders.py:765 -#: pretix/control/views/organizer.py:336 +#: pretix/control/views/organizer.py:348 msgid "This value will be replaced based on dynamic parameters." msgstr "سيتم استبدال هذه القيمة استنادا إلى معايير ديناميكية." @@ -9256,7 +9803,7 @@ msgstr "تم السداد." msgid "Uncategorized" msgstr "غير مصنف" -#: pretix/base/services/tax.py:40 pretix/base/services/tax.py:209 +#: pretix/base/services/tax.py:44 pretix/base/services/tax.py:213 msgid "" "Your VAT ID could not be checked, as the VAT checking service of your " "country is currently not available. We will therefore need to charge VAT on " @@ -9268,17 +9815,17 @@ msgstr "" "القيمة المضافة على فاتورتك. يمكنك استرداد مبلغ الضريبة من خلال إجراءات " "استرداد ضريبة القيمة المضافة." -#: pretix/base/services/tax.py:45 pretix/base/services/tax.py:189 -#: pretix/base/services/tax.py:216 +#: pretix/base/services/tax.py:49 pretix/base/services/tax.py:193 +#: pretix/base/services/tax.py:220 msgid "This VAT ID is not valid. Please re-check your input." msgstr "" "معرف ضريبة القيمة المضافة هذا غير صالح. يرجى إعادة فحص المدخلات الخاصة بك." -#: pretix/base/services/tax.py:46 pretix/base/services/tax.py:174 +#: pretix/base/services/tax.py:50 pretix/base/services/tax.py:178 msgid "Your VAT ID does not match the selected country." msgstr "معرف ضريبة القيمة المضافة لا يطابق البلد المختار." -#: pretix/base/services/tax.py:193 pretix/base/services/tax.py:201 +#: pretix/base/services/tax.py:197 pretix/base/services/tax.py:205 msgid "" "Your VAT ID could not be checked, as the VAT checking service of your " "country returned an incorrect result. We will therefore need to charge VAT " @@ -9337,7 +9884,7 @@ msgstr "" msgid "Plugin: %s" msgstr "المكونات الإضافية: %s" -#: pretix/base/services/vouchers.py:56 pretix/control/logdisplay.py:518 +#: pretix/base/services/vouchers.py:56 pretix/control/logdisplay.py:579 #, python-brace-format msgid "The voucher has been sent to {recipient}." msgstr "تم إرسال كود الخصم إلى {recipient}." @@ -9594,7 +10141,7 @@ msgid "Show exchange rates" msgstr "إظهار تاريخ انتهاء الفعالية" #: pretix/base/settings.py:524 pretix/base/settings.py:532 -#: pretix/control/forms/item.py:625 +#: pretix/control/forms/item.py:626 msgid "Never" msgstr "أبدا" @@ -9793,8 +10340,8 @@ msgstr "" msgid "Only respected by some invoice renderers." msgstr "يستخدم للمتصفحات الحديثة فقط." -#: pretix/base/settings.py:744 pretix/base/settings.py:2907 -#: pretix/control/templates/pretixcontrol/pdf/index.html:376 +#: pretix/base/settings.py:744 pretix/base/settings.py:2959 +#: pretix/control/templates/pretixcontrol/pdf/index.html:436 msgid "Font" msgstr "الخط" @@ -9998,57 +10545,86 @@ msgstr "عرض تاريخ البداية" msgid "Show the presale start date before presale has started." msgstr "اعرض تاريخ بداية البيع المسبق قبل أن بدايته." -#: pretix/base/settings.py:1041 pretix/base/settings.py:1053 +#: pretix/base/settings.py:1037 pretix/base/settings.py:1045 +#: pretix/base/settings.py:1059 pretix/base/settings.py:1068 +#, fuzzy +#| msgid "Default price" +msgid "Use default tax rate" +msgstr "السعر الافتراضي" + +#: pretix/base/settings.py:1038 pretix/base/settings.py:1046 +#: pretix/base/settings.py:1057 pretix/base/settings.py:1066 +#, fuzzy +msgid "Charge no taxes" +msgstr "تم تحديث الرسوم." + +#: pretix/base/settings.py:1042 +#, fuzzy +#| msgid "Tax rule for payment fees" +msgid "Tax handling on payment fees" +msgstr "حكم الضرائب لدفع الرسوم" + +#: pretix/base/settings.py:1058 pretix/base/settings.py:1067 +msgid "Use same taxes as order positions (split according to net prices)" +msgstr "" + +#: pretix/base/settings.py:1063 +#, fuzzy +#| msgid "Keep a fixed cancellation fee" +msgid "Tax handling on cancellation fees" +msgstr "احتفظ برسوم إلغاء ثابتة" + +#: pretix/base/settings.py:1079 pretix/base/settings.py:1091 msgid "Do not generate invoices" msgstr "لا تصدر فواتير" -#: pretix/base/settings.py:1042 pretix/base/settings.py:1058 +#: pretix/base/settings.py:1080 pretix/base/settings.py:1096 msgid "Only manually in admin panel" msgstr "فقط يدويا في لوحة الإدارة" -#: pretix/base/settings.py:1043 pretix/base/settings.py:1056 +#: pretix/base/settings.py:1081 pretix/base/settings.py:1094 msgid "Automatically on user request" msgstr "تلقائيا بناء على طلب المستخدم" -#: pretix/base/settings.py:1044 pretix/base/settings.py:1057 +#: pretix/base/settings.py:1082 pretix/base/settings.py:1095 #, fuzzy #| msgid "Automatically on user request" msgid "Automatically on user request for paid orders" msgstr "تلقائيا بناء على طلب المستخدم" -#: pretix/base/settings.py:1045 +#: pretix/base/settings.py:1083 msgid "Automatically for all created orders" msgstr "تلقائيا لجميع الطلبات التي تم إنشاؤها" -#: pretix/base/settings.py:1046 +#: pretix/base/settings.py:1084 msgid "Automatically on payment or when required by payment method" msgstr "تلقائيا عند الدفع أو عند الطلب بواسطة طريقة السداد" -#: pretix/base/settings.py:1050 +#: pretix/base/settings.py:1088 msgid "Generate invoices" msgstr "إنشاء الفواتير" -#: pretix/base/settings.py:1054 +#: pretix/base/settings.py:1092 #, fuzzy #| msgid "Automatically on payment or when required by payment method" msgid "Automatically after payment or when required by payment method" msgstr "تلقائيا عند الدفع أو عند الطلب بواسطة طريقة السداد" -#: pretix/base/settings.py:1055 +#: pretix/base/settings.py:1093 #, fuzzy #| msgid "Automatically for all created orders" msgid "Automatically before payment for all created orders" msgstr "تلقائيا لجميع الطلبات التي تم إنشاؤها" -#: pretix/base/settings.py:1060 +#: pretix/base/settings.py:1098 msgid "Invoices will never be automatically generated for free orders." msgstr "لن يتم إنشاء الفواتير تلقائيا للطلبات المجانية." -#: pretix/base/settings.py:1069 +#: pretix/base/settings.py:1107 msgid "Automatically cancel and reissue invoice on address changes" msgstr "إلغاء الفاتورة تلقائيا عند تغيير العنوان وإعادة إصدارها" -#: pretix/base/settings.py:1070 +#: pretix/base/settings.py:1108 msgid "" "If customers change their invoice address on an existing order, the invoice " "will automatically be canceled and a new invoice will be issued. This " @@ -10058,50 +10634,50 @@ msgstr "" "الفاتورة تلقائيا وسيتم إصدار فاتورة جديدة. لن يؤثر هذا الإعداد على التعديلات " "في لوحة التحكم." -#: pretix/base/settings.py:1081 +#: pretix/base/settings.py:1119 msgid "Allow to update existing invoices" msgstr "" -#: pretix/base/settings.py:1082 +#: pretix/base/settings.py:1120 msgid "" "By default, invoices can never again be changed once they are issued. In " "most countries, we recommend to leave this option turned off and always " "issue a new invoice if a change needs to be made." msgstr "" -#: pretix/base/settings.py:1097 +#: pretix/base/settings.py:1135 msgid "Address line" msgstr "العنوان" -#: pretix/base/settings.py:1101 +#: pretix/base/settings.py:1139 msgid "Albert Einstein Road 52" msgstr "شارع ألبرت أينشتاين 52" -#: pretix/base/settings.py:1153 +#: pretix/base/settings.py:1191 msgid "Domestic tax ID" msgstr "معرف الضريبة المحلية" -#: pretix/base/settings.py:1154 +#: pretix/base/settings.py:1192 msgid "e.g. tax number in Germany, ABN in Australia, …" msgstr "على سبيل المثال الرقم الضريبي في ألمانيا ، رقم العمل الأسترالي،…" -#: pretix/base/settings.py:1163 +#: pretix/base/settings.py:1201 msgid "EU VAT ID" msgstr "رقم ضريبة القيمة المضافة في الاتحاد الأوروبي" -#: pretix/base/settings.py:1176 +#: pretix/base/settings.py:1214 msgid "e.g. With this document, we sent you the invoice for your ticket order." msgstr "على سبيل المثال باستخدام هذا المستند ، أرسلنا إليك فاتورة طلب تذكرتك." -#: pretix/base/settings.py:1179 +#: pretix/base/settings.py:1217 msgid "Introductory text" msgstr "نص تمهيدي" -#: pretix/base/settings.py:1180 +#: pretix/base/settings.py:1218 msgid "Will be printed on every invoice above the invoice rows." msgstr "ستتم طباعتها على كل فاتورة فوق صفوف الفاتورة." -#: pretix/base/settings.py:1193 +#: pretix/base/settings.py:1231 msgid "" "e.g. Thank you for your purchase! You can find more information on the event " "at ..." @@ -10109,15 +10685,15 @@ msgstr "" "مثلا شكرا لك على الشراء! يمكنك العثور على مزيد من المعلومات حول هذه الفعالية " "في ..." -#: pretix/base/settings.py:1196 +#: pretix/base/settings.py:1234 msgid "Additional text" msgstr "نص إضافي" -#: pretix/base/settings.py:1197 +#: pretix/base/settings.py:1235 msgid "Will be printed on every invoice below the invoice total." msgstr "ستتم الطباعة على كل فاتورة تحت إجمالي الفاتورة." -#: pretix/base/settings.py:1210 +#: pretix/base/settings.py:1248 msgid "" "e.g. your bank details, legal details like your VAT ID, registration " "numbers, etc." @@ -10125,21 +10701,21 @@ msgstr "" "مثلا تفاصيل حسابك المصرفي، التفاصيل القانونية مثل معرف ضريبة القيمة المضافة، " "أرقام التسجيل، الخ." -#: pretix/base/settings.py:1213 +#: pretix/base/settings.py:1251 msgid "Footer" msgstr "تذييل" -#: pretix/base/settings.py:1214 +#: pretix/base/settings.py:1252 msgid "" "Will be printed centered and in a smaller font at the end of every invoice " "page." msgstr "ستتم طباعتها في المنتصف وبخط أصغر في نهاية كل صفحة فاتورة." -#: pretix/base/settings.py:1227 +#: pretix/base/settings.py:1265 msgid "Attach invoices to emails" msgstr "إرفق الفواتير في رسائل البريد الإلكتروني" -#: pretix/base/settings.py:1228 +#: pretix/base/settings.py:1266 msgid "" "If invoices are automatically generated for all orders, they will be " "attached to the order confirmation mail. If they are automatically generated " @@ -10150,11 +10726,11 @@ msgstr "" "الطلب. إذا تم إنشاؤها تلقائيا عند الدفع ، فسيتم إرفاقها ببريد تأكيد الدفع. " "إذا لم يتم إنشاؤها تلقائيا ، فلن يتم إرفاقها برسائل البريد الإلكتروني." -#: pretix/base/settings.py:1240 +#: pretix/base/settings.py:1278 msgid "Email address to receive a copy of each invoice" msgstr "عنوان البريد الإلكتروني لتلقي نسخة من كل فاتورة" -#: pretix/base/settings.py:1241 +#: pretix/base/settings.py:1279 msgid "" "Each newly created invoice will be sent to this email address shortly after " "creation. You can use this for an automated import of invoices to your " @@ -10164,28 +10740,28 @@ msgstr "" "وقت قصير من إنشائها. يمكنك استخدام هذا للاستيراد الآلي للفواتير إلى نظام " "المحاسبة الخاص بك. ستكون الفاتورة هي المرفق الوحيد بالبريد الإلكتروني." -#: pretix/base/settings.py:1256 +#: pretix/base/settings.py:1294 msgid "Show items outside presale period" msgstr "إظهار العناصر خارج فترة عرض ما قبل البيع" -#: pretix/base/settings.py:1257 +#: pretix/base/settings.py:1295 msgid "" "Show item details before presale has started and after presale has ended" msgstr "إظهار تفاصيل العنصر قبل بداية البيع المسبق وبعد انتهائه" -#: pretix/base/settings.py:1277 +#: pretix/base/settings.py:1315 msgid "Available languages" msgstr "اللغات المتاحة" -#: pretix/base/settings.py:1293 pretix/control/forms/event.py:140 +#: pretix/base/settings.py:1331 pretix/control/forms/event.py:139 msgid "Default language" msgstr "اللغة الافتراضية" -#: pretix/base/settings.py:1303 +#: pretix/base/settings.py:1341 msgid "Region" msgstr "منطقة" -#: pretix/base/settings.py:1304 +#: pretix/base/settings.py:1342 msgid "" "Will be used to determine date and time formatting as well as default " "country for customer addresses and phone numbers. For formatting, this takes " @@ -10197,13 +10773,13 @@ msgstr "" "من اللغة وبالتالي فهو مناسب في الغالب للغات المستخدمة في مناطق مختلفة على " "مستوى العالم (مثل اللغة الإنجليزية)." -#: pretix/base/settings.py:1316 +#: pretix/base/settings.py:1354 #, fuzzy #| msgid "This is not an event series." msgid "This shop represents an event" msgstr "هذه ليست سلسلة فعالية." -#: pretix/base/settings.py:1318 +#: pretix/base/settings.py:1356 msgid "" "Uncheck this box if you are only selling something that has no specific " "date, such as gift cards or a ticket that can be used any time. The system " @@ -10212,19 +10788,19 @@ msgid "" "may still show up in other places." msgstr "" -#: pretix/base/settings.py:1331 +#: pretix/base/settings.py:1369 msgid "Show event end date" msgstr "إظهار تاريخ انتهاء الفعالية" -#: pretix/base/settings.py:1332 +#: pretix/base/settings.py:1370 msgid "If disabled, only event's start date will be displayed to the public." msgstr "إذا تم تعطيل هذا الخيار، فسيظهر للجمهور تاريخ بداية الفعالية فقط." -#: pretix/base/settings.py:1341 +#: pretix/base/settings.py:1379 msgid "Show dates with time" msgstr "عرض التواريخ مع الوقت" -#: pretix/base/settings.py:1342 +#: pretix/base/settings.py:1380 msgid "" "If disabled, the event's start and end date will be displayed without the " "time of day." @@ -10232,27 +10808,27 @@ msgstr "" "إذا تم تعطيل هذا الخيار ، فسيتم عرض تاريخ بداية الفعالية وانتهائها بدون " "توقيت اليوم." -#: pretix/base/settings.py:1351 +#: pretix/base/settings.py:1389 msgid "Hide all products that are sold out" msgstr "إخفاء جميع المنتجات التي تم بيعها" -#: pretix/base/settings.py:1361 pretix/control/forms/event.py:1682 +#: pretix/base/settings.py:1399 pretix/control/forms/event.py:1691 msgid "Publicly show how many tickets of a certain type are still available." msgstr "اعرض علنا عدد التذاكر من نوع معين والتي لا تزال متاحة." -#: pretix/base/settings.py:1370 +#: pretix/base/settings.py:1408 msgid "Ask search engines not to index the ticket shop" msgstr "اطلب من محركات البحث عدم فهرسة متجر التذاكر" -#: pretix/base/settings.py:1379 +#: pretix/base/settings.py:1417 msgid "Show variations of a product expanded by default" msgstr "إظهار الأشكال المختلفة للمنتج موسعة بشكل افتراضي" -#: pretix/base/settings.py:1388 +#: pretix/base/settings.py:1426 msgid "Enable waiting list" msgstr "تمكين قائمة الانتظار" -#: pretix/base/settings.py:1389 pretix/control/forms/event.py:1687 +#: pretix/base/settings.py:1427 pretix/control/forms/event.py:1696 #, fuzzy msgid "" "Once a ticket is sold out, people can add themselves to a waiting list. As " @@ -10264,11 +10840,11 @@ msgstr "" "تصبح التذكرة متاحة مرة أخرى ، سيتم حجزها لأول شخص في قائمة الانتظار وسيتلقى " "هذا الشخص إشعارا بالبريد الإلكتروني مع قسيمة يمكن استخدامها لشراء تذكرة." -#: pretix/base/settings.py:1400 +#: pretix/base/settings.py:1438 msgid "Automatic waiting list assignments" msgstr "مهام قائمة الانتظار التلقائية" -#: pretix/base/settings.py:1401 +#: pretix/base/settings.py:1439 #, fuzzy msgid "" "If ticket capacity becomes free, automatically create a voucher and send it " @@ -10282,11 +10858,11 @@ msgstr "" "البريد الإلكتروني تلقائيا ولكن يمكنك إرسالها يدويا عبر لوحة التحكم. إذا قمت " "بتعطيل قائمة الانتظار مع إبقاء هذا الخيار مفعلا ، فسيستمر إرسال التذاكر." -#: pretix/base/settings.py:1417 +#: pretix/base/settings.py:1455 msgid "Waiting list response time" msgstr "وقت استجابة قائمة الانتظار" -#: pretix/base/settings.py:1420 +#: pretix/base/settings.py:1458 #, fuzzy msgid "" "If a ticket voucher is sent to a person on the waiting list, it has to be " @@ -10297,13 +10873,13 @@ msgstr "" "خلال هذا العدد من الساعات حتى تنتهي صلاحيتها ويمكن إعادة تخصيصها إلى الشخص " "التالي في القائمة." -#: pretix/base/settings.py:1431 +#: pretix/base/settings.py:1469 #, fuzzy #| msgid "Enable waiting list" msgid "Disable waiting list" msgstr "تمكين قائمة الانتظار" -#: pretix/base/settings.py:1432 +#: pretix/base/settings.py:1470 msgid "" "The waiting list will be fully disabled after this date. This means that " "nobody can add themselves to the waiting list any more, but also that " @@ -10312,56 +10888,56 @@ msgid "" "remain active." msgstr "" -#: pretix/base/settings.py:1444 +#: pretix/base/settings.py:1482 msgid "Ask for a name" msgstr "اطلب الاسم" -#: pretix/base/settings.py:1445 +#: pretix/base/settings.py:1483 msgid "Ask for a name when signing up to the waiting list." msgstr "اطلب اسما عند التسجيل في قائمة الانتظار." -#: pretix/base/settings.py:1454 +#: pretix/base/settings.py:1492 msgid "Require name" msgstr "اطلب اسم" -#: pretix/base/settings.py:1455 +#: pretix/base/settings.py:1493 msgid "Require a name when signing up to the waiting list.." msgstr "طلب اسم عند التسجيل في قائمة الانتظار .." -#: pretix/base/settings.py:1465 +#: pretix/base/settings.py:1503 msgid "Ask for a phone number" msgstr "اطلب رقم هاتف" -#: pretix/base/settings.py:1466 +#: pretix/base/settings.py:1504 msgid "Ask for a phone number when signing up to the waiting list." msgstr "اطلب رقم هاتف عند التسجيل في قائمة الانتظار." -#: pretix/base/settings.py:1475 +#: pretix/base/settings.py:1513 msgid "Require phone number" msgstr "يلزم رقم الهاتف" -#: pretix/base/settings.py:1476 +#: pretix/base/settings.py:1514 msgid "Require a phone number when signing up to the waiting list.." msgstr "طلب رقم هاتف عند التسجيل في قائمة الانتظار .." -#: pretix/base/settings.py:1486 +#: pretix/base/settings.py:1524 msgid "Phone number explanation" msgstr "تفسير رقم الهاتف" -#: pretix/base/settings.py:1489 +#: pretix/base/settings.py:1527 msgid "" "If you ask for a phone number, explain why you do so and what you will use " "the phone number for." msgstr "" "إذا طلبت رقم هاتف ، اشرح سبب قيامك بذلك وما الذي ستستخدم رقم الهاتف لأجله." -#: pretix/base/settings.py:1501 +#: pretix/base/settings.py:1539 #, fuzzy #| msgid "Maximum number of items per order" msgid "Maximum number of entries per email address for the same product" msgstr "الحد الأقصى لعدد العناصر لكل طلب" -#: pretix/base/settings.py:1505 +#: pretix/base/settings.py:1543 msgid "" "With an increased limit, a customer may request more than one ticket for a " "specific product using the same, unique email address. However, regardless " @@ -10370,13 +10946,13 @@ msgid "" "ticket at a time." msgstr "" -#: pretix/base/settings.py:1517 +#: pretix/base/settings.py:1555 #, fuzzy #| msgid "Show number of tickets left" msgid "Show number of check-ins to customer" msgstr "إظهار عدد التذاكر المتبقية" -#: pretix/base/settings.py:1518 +#: pretix/base/settings.py:1556 msgid "" "With this option enabled, your customers will be able to see how many times " "they entered the event. This is usually not necessary, but might be useful " @@ -10386,19 +10962,19 @@ msgid "" "check-in lists." msgstr "" -#: pretix/base/settings.py:1531 +#: pretix/base/settings.py:1569 msgid "Allow users to download tickets" msgstr "السماح للمستخدمين بتحميل التذاكر" -#: pretix/base/settings.py:1532 +#: pretix/base/settings.py:1570 msgid "If this is off, nobody can download a ticket." msgstr "إذا تم تعطيل هذا الخيار، فلا يمكن لأي شخص تنزيل تذكرة." -#: pretix/base/settings.py:1541 +#: pretix/base/settings.py:1579 msgid "Download date" msgstr "تاريخ التنزيل" -#: pretix/base/settings.py:1542 +#: pretix/base/settings.py:1580 msgid "" "Ticket download will be offered after this date. If you use the event series " "feature and an order contains tickets for multiple event dates, download of " @@ -10408,13 +10984,13 @@ msgstr "" "الفعاليات وكان الطلب يحتوي على تذاكر لتواريخ فعاليات متعددة ، فسيكون تنزيل " "جميع التذاكر متاحا إذا سمح بذلك أحد تواريخ الفعالية على الأقل." -#: pretix/base/settings.py:1553 +#: pretix/base/settings.py:1591 #, fuzzy #| msgid "Generate tickets for add-on products" msgid "Generate tickets for add-on products and bundled products" msgstr "إنشاء تذاكر للمنتجات الإضافية" -#: pretix/base/settings.py:1554 +#: pretix/base/settings.py:1592 #, fuzzy #| msgid "" #| "By default, tickets are only issued for products selected individually, " @@ -10429,11 +11005,11 @@ msgstr "" "للمنتجات الإضافية. باستخدام هذا الخيار ، يتم إصدار تذكرة منفصلة لكل منتج " "إضافي أيضا." -#: pretix/base/settings.py:1567 +#: pretix/base/settings.py:1605 msgid "Generate tickets for all products" msgstr "إنشاء تذاكر لجميع المنتجات" -#: pretix/base/settings.py:1568 +#: pretix/base/settings.py:1606 msgid "" "If turned off, tickets are only issued for products that are marked as an " "\"admission ticket\"in the product settings. You can also turn off ticket " @@ -10443,11 +11019,11 @@ msgstr "" "\"بطاقة دخول\" عليها في إعدادات المنتج. يمكنك أيضا إيقاف تشغيل إصدار التذاكر " "لكل منتج على حدة." -#: pretix/base/settings.py:1580 +#: pretix/base/settings.py:1618 msgid "Generate tickets for pending orders" msgstr "إصدار تذاكر للطلبات المعلقة" -#: pretix/base/settings.py:1581 +#: pretix/base/settings.py:1619 msgid "" "If turned off, ticket downloads are only possible after an order has been " "marked as paid." @@ -10455,11 +11031,11 @@ msgstr "" "إذا تم إيقاف تشغيل هذا الخيار، فلن يكون تنزيل التذاكر ممكنا إلا بعد وضع " "علامة على الطلب على أنه مدفوع." -#: pretix/base/settings.py:1592 +#: pretix/base/settings.py:1630 msgid "Do not issue ticket before email address is validated" msgstr "لا تصدر تذكرة قبل التحقق من صحة عنوان البريد الإلكتروني" -#: pretix/base/settings.py:1593 +#: pretix/base/settings.py:1631 msgid "" "If turned on, tickets will not be offered for download directly after " "purchase. They will be attached to the payment confirmation email (if the " @@ -10472,13 +11048,13 @@ msgstr "" "جدا)، وسيتمكن العميل من تنزيلها من الصفحة بمجرد النقر على الرابط في البريد " "الإلكتروني. لا يؤثر على الطلبات المنفذة من خلال قنوات البيع الأخرى." -#: pretix/base/settings.py:1609 +#: pretix/base/settings.py:1647 #, fuzzy #| msgid "Quota availabilities" msgid "Low availability threshold" msgstr "توافر الحصة" -#: pretix/base/settings.py:1610 +#: pretix/base/settings.py:1648 msgid "" "If the availability of tickets falls below this percentage, the event (or a " "date, if it is an event series) will be highlighted to have low availability " @@ -10486,11 +11062,11 @@ msgid "" "availability will not be shown publicly." msgstr "" -#: pretix/base/settings.py:1624 +#: pretix/base/settings.py:1662 msgid "Show availability in event overviews" msgstr "إظهار التوفر في \"نبذة عن الفعالية\"" -#: pretix/base/settings.py:1625 +#: pretix/base/settings.py:1663 msgid "" "If checked, the list of events will show if events are sold out. This might " "make for longer page loading times if you have lots of events and the shown " @@ -10500,24 +11076,24 @@ msgstr "" "يؤدي هذا إلى إطالة وقت تحميل الصفحات إذا كان لديك الكثير من الفعاليات وقد " "تكون الحالة المعروضة قديمة لمدة تصل إلى دقيقتين." -#: pretix/base/settings.py:1638 pretix/base/settings.py:1646 +#: pretix/base/settings.py:1676 pretix/base/settings.py:1684 #: pretix/presale/templates/pretixpresale/fragment_calendar_nav.html:8 msgid "List" msgstr "قائمة" -#: pretix/base/settings.py:1639 pretix/base/settings.py:1647 +#: pretix/base/settings.py:1677 pretix/base/settings.py:1685 msgid "Week calendar" msgstr "تقويم الأسبوع" -#: pretix/base/settings.py:1640 pretix/base/settings.py:1648 +#: pretix/base/settings.py:1678 pretix/base/settings.py:1686 msgid "Month calendar" msgstr "تقويم الشهر" -#: pretix/base/settings.py:1644 +#: pretix/base/settings.py:1682 msgid "Default overview style" msgstr "نمط النظرة العامة الافتراضي" -#: pretix/base/settings.py:1650 +#: pretix/base/settings.py:1688 msgid "" "If your event series has more than 50 dates in the future, only the month or " "week calendar can be used." @@ -10525,13 +11101,13 @@ msgstr "" "إذا كانت سلسلة الفعاليات الخاصة بك تحتوي على أكثر من 50 تاريخا في المستقبل ، " "فيمكن استخدام تقويم الشهر أو الأسبوع فقط." -#: pretix/base/settings.py:1659 +#: pretix/base/settings.py:1697 #, fuzzy #| msgid "Hide all unavailable dates from calendar or list views" msgid "Show filter options for calendar or list view" msgstr "إخفاء جميع التواريخ غير المتاحة من التقويم أو طرق عرض القائمة" -#: pretix/base/settings.py:1660 +#: pretix/base/settings.py:1698 #, fuzzy #| msgid "The selected product is not active or has no price set." msgid "" @@ -10539,57 +11115,57 @@ msgid "" "settings." msgstr "المنتج المحدد غير نشط أو ليس له سعر محدد." -#: pretix/base/settings.py:1669 +#: pretix/base/settings.py:1707 msgid "Hide all unavailable dates from calendar or list views" msgstr "إخفاء جميع التواريخ غير المتاحة من التقويم أو طرق عرض القائمة" -#: pretix/base/settings.py:1670 pretix/base/settings.py:1681 +#: pretix/base/settings.py:1708 pretix/base/settings.py:1719 msgid "" "This option currently only affects the calendar of this event series, not " "the organizer-wide calendar." msgstr "" -#: pretix/base/settings.py:1680 +#: pretix/base/settings.py:1718 #, fuzzy #| msgid "Hide all unavailable dates from calendar or list views" msgid "Hide all past dates from calendar" msgstr "إخفاء جميع التواريخ غير المتاحة من التقويم أو طرق عرض القائمة" -#: pretix/base/settings.py:1692 pretix/base/settings.py:1701 +#: pretix/base/settings.py:1730 pretix/base/settings.py:1739 msgid "No modifications after order was submitted" msgstr "" -#: pretix/base/settings.py:1693 pretix/base/settings.py:1702 +#: pretix/base/settings.py:1731 pretix/base/settings.py:1740 #, fuzzy #| msgid "Only pending or paid orders can be changed." msgid "Only the person who ordered can make changes" msgstr "يمكن فقط تغيير الطلبات المعلقة أو المدفوعة." -#: pretix/base/settings.py:1694 pretix/base/settings.py:1703 +#: pretix/base/settings.py:1732 pretix/base/settings.py:1741 msgid "Both the attendee and the person who ordered can make changes" msgstr "" -#: pretix/base/settings.py:1698 +#: pretix/base/settings.py:1736 #, fuzzy #| msgid "Allow customers to modify their information after they checked in." msgid "Allow customers to modify their information" msgstr "اسمح للعملاء بتعديل معلوماتهم بعد تمام التسجيل." -#: pretix/base/settings.py:1713 +#: pretix/base/settings.py:1751 msgid "Allow customers to modify their information after they checked in." msgstr "اسمح للعملاء بتعديل معلوماتهم بعد تمام التسجيل." -#: pretix/base/settings.py:1714 +#: pretix/base/settings.py:1752 msgid "" "By default, no more modifications are possible for an order as soon as one " "of the tickets in the order has been checked in." msgstr "" -#: pretix/base/settings.py:1724 +#: pretix/base/settings.py:1762 msgid "Last date of modifications" msgstr "آخر موعد لإجراء التعديلات" -#: pretix/base/settings.py:1725 +#: pretix/base/settings.py:1763 msgid "" "The last date users can modify details of their orders, such as attendee " "names or answers to questions. If you use the event series feature and an " @@ -10600,58 +11176,58 @@ msgstr "" "الحضور أو إجابات الأسئلة. إذا كنت تستخدم ميزة سلسلة الفعاليات وكان الطلب " "يحتوي على تذاكر لتواريخ فعاليات متعددة ، فسيتم استخدام أقرب تاريخ." -#: pretix/base/settings.py:1736 +#: pretix/base/settings.py:1774 msgid "Customers can change the variation of the products they purchased" msgstr "يمكن للعملاء تغيير تنوع المنتجات التي قاموا بشرائها" -#: pretix/base/settings.py:1745 +#: pretix/base/settings.py:1783 #, fuzzy #| msgid "Customers can cancel their paid orders" msgid "Customers can change their selected add-on products" msgstr "يمكن للعملاء إلغاء طلباتهم المدفوعة" -#: pretix/base/settings.py:1755 pretix/base/settings.py:1766 +#: pretix/base/settings.py:1793 pretix/base/settings.py:1804 msgid "" "Only allow changes if the resulting price is higher or equal than the " "previous price." msgstr "السماح بالتغييرات فقط إذا كان السعر الناتج أعلى أو يساوي السعر السابق." -#: pretix/base/settings.py:1756 pretix/base/settings.py:1767 +#: pretix/base/settings.py:1794 pretix/base/settings.py:1805 msgid "" "Only allow changes if the resulting price is higher than the previous price." msgstr "السماح بالتغييرات فقط إذا كان السعر الناتج أعلى من السعر السابق." -#: pretix/base/settings.py:1757 pretix/base/settings.py:1768 +#: pretix/base/settings.py:1795 pretix/base/settings.py:1806 msgid "" "Only allow changes if the resulting price is equal to the previous price." msgstr "السماح بالتغييرات فقط إذا كان السعر الناتج أعلى من السعر السابق." -#: pretix/base/settings.py:1758 pretix/base/settings.py:1769 +#: pretix/base/settings.py:1796 pretix/base/settings.py:1807 msgid "" "Allow changes regardless of price, as long as no refund is required (i.e. " "the resulting price is not lower than what has already been paid)." msgstr "" -#: pretix/base/settings.py:1760 pretix/base/settings.py:1771 +#: pretix/base/settings.py:1798 pretix/base/settings.py:1809 msgid "Allow changes regardless of price, even if this results in a refund." msgstr "" "السماح بالتغييرات بغض النظر عن السعر ، حتى لو أدى ذلك إلى استرداد الأموال." -#: pretix/base/settings.py:1764 +#: pretix/base/settings.py:1802 msgid "Requirement for changed prices" msgstr "شرط تغيير الأسعار" -#: pretix/base/settings.py:1782 +#: pretix/base/settings.py:1820 msgid "Do not allow changes after" msgstr "لا تسمح بالتغييرات بعد" -#: pretix/base/settings.py:1791 +#: pretix/base/settings.py:1829 #, fuzzy #| msgid "The payment for this invoice has already been received." msgid "Allow change even though the ticket has already been checked in" msgstr "تم إستلام قيمة هذه الفاتورة مسبقا." -#: pretix/base/settings.py:1792 +#: pretix/base/settings.py:1830 msgid "" "By default, order changes are disabled after any ticket in the order has " "been checked in. If you check this box, this requirement is lifted. It is " @@ -10660,11 +11236,11 @@ msgid "" "limitation on price changes above." msgstr "" -#: pretix/base/settings.py:1804 +#: pretix/base/settings.py:1842 msgid "Allow individual attendees to change their ticket" msgstr "" -#: pretix/base/settings.py:1805 +#: pretix/base/settings.py:1843 msgid "" "By default, only the person who ordered the tickets can make any changes. If " "you check this box, individual attendees can also make changes. However, " @@ -10673,45 +11249,45 @@ msgid "" "customer." msgstr "" -#: pretix/base/settings.py:1817 +#: pretix/base/settings.py:1855 msgid "Customers can cancel their unpaid orders" msgstr "يمكن للعملاء إلغاء طلباتهم غير المدفوعة" -#: pretix/base/settings.py:1829 +#: pretix/base/settings.py:1867 #, fuzzy #| msgid "Keep a fixed cancellation fee" msgid "Charge a fixed cancellation fee" msgstr "احتفظ برسوم إلغاء ثابتة" -#: pretix/base/settings.py:1830 pretix/base/settings.py:1841 -#: pretix/base/settings.py:1855 +#: pretix/base/settings.py:1868 pretix/base/settings.py:1879 +#: pretix/base/settings.py:1893 msgid "" "Only affects orders pending payments, a cancellation fee for free orders is " "never charged. Note that it will be your responsibility to claim the " "cancellation fee from the user." msgstr "" -#: pretix/base/settings.py:1840 +#: pretix/base/settings.py:1878 #, fuzzy #| msgid "Keep payment, shipping and service fees" msgid "Charge payment, shipping and service fees" msgstr "احتفظ برسوم السداد والشحن والخدمة" -#: pretix/base/settings.py:1854 +#: pretix/base/settings.py:1892 #, fuzzy #| msgid "Keep a percentual cancellation fee" msgid "Charge a percentual cancellation fee" msgstr "احتفظ بنسبة رسوم الإلغاء" -#: pretix/base/settings.py:1865 pretix/base/settings.py:2004 +#: pretix/base/settings.py:1903 pretix/base/settings.py:2042 msgid "Do not allow cancellations after" msgstr "لا تسمح بالإلغاء بعد" -#: pretix/base/settings.py:1874 +#: pretix/base/settings.py:1912 msgid "Customers can cancel their paid orders" msgstr "يمكن للعملاء إلغاء طلباتهم المدفوعة" -#: pretix/base/settings.py:1875 +#: pretix/base/settings.py:1913 msgid "" "Paid money will be automatically paid back if the payment method allows it. " "Otherwise, a manual refund will be created for you to process manually." @@ -10719,29 +11295,29 @@ msgstr "" "سيتم رد الأموال المدفوعة تلقائيا إذا كانت طريقة الدفع تسمح بذلك. وبخلاف " "ذلك ، سيتم إنشاء استرداد يدوي لتتم معالجته يدويا." -#: pretix/base/settings.py:1888 pretix/control/forms/orders.py:899 +#: pretix/base/settings.py:1926 pretix/control/forms/orders.py:909 msgid "Keep a fixed cancellation fee" msgstr "احتفظ برسوم إلغاء ثابتة" -#: pretix/base/settings.py:1897 +#: pretix/base/settings.py:1935 msgid "Keep payment, shipping and service fees" msgstr "احتفظ برسوم السداد والشحن والخدمة" -#: pretix/base/settings.py:1909 pretix/control/forms/orders.py:910 +#: pretix/base/settings.py:1947 pretix/control/forms/orders.py:920 msgid "Keep a percentual cancellation fee" msgstr "احتفظ بنسبة رسوم الإلغاء" -#: pretix/base/settings.py:1918 +#: pretix/base/settings.py:1956 msgid "Allow customers to voluntarily choose a lower refund" msgstr "السماح للعملاء طواعية باختيار استرداد أقل" -#: pretix/base/settings.py:1919 +#: pretix/base/settings.py:1957 msgid "" "With this option enabled, your customers can choose to get a smaller refund " "to support you." msgstr "مع تمكين هذا الخيار ، يمكن لعملائك اختيار استرداد مبلغ أصغر لدعمك." -#: pretix/base/settings.py:1924 +#: pretix/base/settings.py:1962 msgid "" "However, if you want us to help keep the lights on here, please consider " "using the slider below to request a smaller refund. Thank you!" @@ -10749,12 +11325,12 @@ msgstr "" "إذا كنت تريد منا المساعدة في استمرار النشاط، فيرجى استخدام شريط التمرير " "أدناه لطلب استرداد مبلغ أقل. شكرا لك!" -#: pretix/base/settings.py:1931 +#: pretix/base/settings.py:1969 #, fuzzy msgid "Voluntary lower refund explanation" msgstr "تبرير تخفيض المبلغ الطوعي" -#: pretix/base/settings.py:1934 +#: pretix/base/settings.py:1972 msgid "" "This text will be shown in between the explanation of how the refunds work " "and the slider which your customers can use to choose the amount they would " @@ -10765,11 +11341,11 @@ msgstr "" "الذي يمكن لعملائك استخدامه لاختيار المبلغ الذي يرغبون في استلامه. يمكنك " "استخدامه على سبيل المثال لشرح اختيار استرداد أقل مما سيساعد مؤسستك." -#: pretix/base/settings.py:1949 +#: pretix/base/settings.py:1987 msgid "Step size for reduction amount" msgstr "حجم مبلغ التخفيض" -#: pretix/base/settings.py:1950 +#: pretix/base/settings.py:1988 msgid "" "By default, customers can choose an arbitrary amount for you to keep. If you " "set this to e.g. 10, they will only be able to choose values in increments " @@ -10779,7 +11355,7 @@ msgstr "" "ذلك على سبيل المثال 10 ، سيكونون قادرين فقط على اختيار القيم بزيادات قدرها " "10." -#: pretix/base/settings.py:1960 +#: pretix/base/settings.py:1998 msgid "" "Customers can only request a cancellation that needs to be approved by the " "event organizer before the order is canceled and a refund is issued." @@ -10787,68 +11363,68 @@ msgstr "" "يمكن للعملاء فقط طلب الإلغاء الذي يحتاج إلى موافقة منظم الفالية قبل إلغاء " "الطلب وإصدار أمر الاسترداد." -#: pretix/base/settings.py:1970 +#: pretix/base/settings.py:2008 msgid "" "Do not show the cancellation fee to users when they request cancellation." msgstr "" -#: pretix/base/settings.py:1979 pretix/base/settings.py:1989 +#: pretix/base/settings.py:2017 pretix/base/settings.py:2027 msgid "All refunds are issued to the original payment method" msgstr "يتم إصدار جميع المبالغ المستردة بطريقة الدفع الأصلية" -#: pretix/base/settings.py:1980 pretix/base/settings.py:1990 +#: pretix/base/settings.py:2018 pretix/base/settings.py:2028 msgid "" "Customers can choose between a gift card and a refund to their payment method" msgstr "" "يمكن للعملاء الاختيار بين بطاقة هدايا واسترداد الأموال بطريقة الدفع الخاصة " "بهم" -#: pretix/base/settings.py:1981 pretix/base/settings.py:1991 +#: pretix/base/settings.py:2019 pretix/base/settings.py:2029 msgid "All refunds are issued as gift cards" msgstr "يتم إصدار جميع المبالغ المستردة كبطاقات هدايا" -#: pretix/base/settings.py:1982 pretix/base/settings.py:1992 +#: pretix/base/settings.py:2020 pretix/base/settings.py:2030 msgid "Do not handle refunds automatically at all" msgstr "" -#: pretix/base/settings.py:1987 +#: pretix/base/settings.py:2025 #: pretix/control/templates/pretixcontrol/order/index.html:149 msgid "Refund method" msgstr "طريقة الاسترداد" -#: pretix/base/settings.py:2013 pretix/base/settings.py:2026 +#: pretix/base/settings.py:2051 pretix/base/settings.py:2064 #, fuzzy #| msgid "Generate cancellation" msgid "Terms of cancellation" msgstr "توليد إلغاء" -#: pretix/base/settings.py:2016 +#: pretix/base/settings.py:2054 msgid "" "This text will be shown when cancellation is allowed for a paid order. Leave " "empty if you want pretix to automatically generate the terms of cancellation " "based on your settings." msgstr "" -#: pretix/base/settings.py:2029 +#: pretix/base/settings.py:2067 msgid "" "This text will be shown when cancellation is allowed for an unpaid or free " "order. Leave empty if you want pretix to automatically generate the terms of " "cancellation based on your settings." msgstr "" -#: pretix/base/settings.py:2039 pretix/control/forms/event.py:1710 +#: pretix/base/settings.py:2077 pretix/control/forms/event.py:1719 msgid "Contact address" msgstr "عنوان الإتصال" -#: pretix/base/settings.py:2040 pretix/control/forms/event.py:1712 +#: pretix/base/settings.py:2078 pretix/control/forms/event.py:1721 msgid "We'll show this publicly to allow attendees to contact you." msgstr "سيظهر هذا علنا للسماح للحاضرين بالاتصال بك." -#: pretix/base/settings.py:2048 pretix/control/forms/event.py:1704 +#: pretix/base/settings.py:2086 pretix/control/forms/event.py:1713 msgid "Imprint URL" msgstr "رابط موقع مقدم الخدمة" -#: pretix/base/settings.py:2049 pretix/control/forms/event.py:1705 +#: pretix/base/settings.py:2087 pretix/control/forms/event.py:1714 msgid "" "This should point e.g. to a part of your website that has your contact " "details and legal information." @@ -10856,11 +11432,11 @@ msgstr "" "ينبغي أن يشير هذا إلى على سبيل المثال جزء من موقع الويب الخاص بك الذي يحتوي " "على تفاصيل الاتصال الخاصة بك والمعلومات القانونية." -#: pretix/base/settings.py:2059 +#: pretix/base/settings.py:2097 msgid "Privacy Policy URL" msgstr "" -#: pretix/base/settings.py:2060 +#: pretix/base/settings.py:2098 #, fuzzy #| msgid "" #| "This should point e.g. to a part of your website that has your contact " @@ -10872,13 +11448,13 @@ msgstr "" "ينبغي أن يشير هذا إلى على سبيل المثال جزء من موقع الويب الخاص بك الذي يحتوي " "على تفاصيل الاتصال الخاصة بك والمعلومات القانونية." -#: pretix/base/settings.py:2071 +#: pretix/base/settings.py:2109 #, fuzzy #| msgid "Account information" msgid "Accessibility information URL" msgstr "معلومات الحساب" -#: pretix/base/settings.py:2072 +#: pretix/base/settings.py:2110 #, fuzzy #| msgid "" #| "This should point e.g. to a part of your website that has your contact " @@ -10890,7 +11466,7 @@ msgstr "" "ينبغي أن يشير هذا إلى على سبيل المثال جزء من موقع الويب الخاص بك الذي يحتوي " "على تفاصيل الاتصال الخاصة بك والمعلومات القانونية." -#: pretix/base/settings.py:2079 +#: pretix/base/settings.py:2117 #: pretix/presale/templates/pretixpresale/event/base.html:228 #: pretix/presale/templates/pretixpresale/event/base.html:233 #: pretix/presale/templates/pretixpresale/organizers/accessibility.html:6 @@ -10901,23 +11477,23 @@ msgstr "" msgid "Accessibility information" msgstr "معلومات الحساب" -#: pretix/base/settings.py:2083 +#: pretix/base/settings.py:2121 #, fuzzy #| msgid "Account information" msgid "Accessibility information title" msgstr "معلومات الحساب" -#: pretix/base/settings.py:2093 +#: pretix/base/settings.py:2131 #, fuzzy #| msgid "Account information" msgid "Accessibility information text" msgstr "معلومات الحساب" -#: pretix/base/settings.py:2114 +#: pretix/base/settings.py:2152 msgid "Attach ticket files" msgstr "إرفق ملفات التذكرة" -#: pretix/base/settings.py:2116 +#: pretix/base/settings.py:2154 #, python-brace-format msgid "" "Tickets will never be attached if they're larger than {size} to avoid email " @@ -10926,36 +11502,36 @@ msgstr "" "لن يتم إرفاق التذاكر أبدا إذا كان حجمها أكبر من {size} لتجنب مشاكل إرسال " "البريد الإلكتروني." -#: pretix/base/settings.py:2127 pretix/plugins/sendmail/forms.py:201 +#: pretix/base/settings.py:2165 pretix/plugins/sendmail/forms.py:201 #: pretix/plugins/sendmail/models.py:270 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:66 msgid "Attach calendar files" msgstr "إرفق ملفات التقويم" -#: pretix/base/settings.py:2128 +#: pretix/base/settings.py:2166 msgid "" "If enabled, we will attach an .ics calendar file to order confirmation " "emails." msgstr "" "في حالة التمكين، سنرفق ملف تقويم ics. لرسائل البريد الإلكتروني لتأكيد الطلب." -#: pretix/base/settings.py:2137 +#: pretix/base/settings.py:2175 msgid "Attach calendar files only after order has been paid" msgstr "" -#: pretix/base/settings.py:2138 +#: pretix/base/settings.py:2176 msgid "" "Use this if you e.g. put a private access link into the calendar file to " "make sure people only receive it after their payment was confirmed." msgstr "" -#: pretix/base/settings.py:2147 +#: pretix/base/settings.py:2185 #, fuzzy #| msgid "Product description" msgid "Event description" msgstr "وصف المنتج" -#: pretix/base/settings.py:2150 +#: pretix/base/settings.py:2188 msgid "" "You can use this to share information with your attendees, such as travel " "information or the link to a digital event. If you keep it empty, we will " @@ -10965,11 +11541,11 @@ msgid "" "people." msgstr "" -#: pretix/base/settings.py:2163 +#: pretix/base/settings.py:2201 msgid "Subject prefix" msgstr "الرمز الذي يسبق الموضوع" -#: pretix/base/settings.py:2164 +#: pretix/base/settings.py:2202 msgid "" "This will be prepended to the subject of all outgoing emails, formatted as " "[prefix]. Choose, for example, a short form of your event name." @@ -10977,23 +11553,23 @@ msgstr "" "سيتم إضافة هذا مسبقا إلى موضوع جميع رسائل البريد الإلكتروني الصادرة ، محدد " "مثل [prefix]. اختر ، على سبيل المثال ، مسمى قصير لاسم الفعالية الخاصة بك." -#: pretix/base/settings.py:2178 pretix/control/forms/mailsetup.py:37 +#: pretix/base/settings.py:2216 pretix/control/forms/mailsetup.py:37 #: pretix/control/forms/mailsetup.py:119 #: pretix/control/templates/pretixcontrol/event/mail.html:39 #: pretix/control/templates/pretixcontrol/organizers/mail.html:40 msgid "Sender address" msgstr "عنوان المرسل" -#: pretix/base/settings.py:2179 pretix/control/forms/mailsetup.py:38 +#: pretix/base/settings.py:2217 pretix/control/forms/mailsetup.py:38 #: pretix/control/forms/mailsetup.py:120 msgid "Sender address for outgoing emails" msgstr "عنوان المرسل لرسائل البريد الإلكتروني الصادرة" -#: pretix/base/settings.py:2188 +#: pretix/base/settings.py:2226 msgid "Sender name" msgstr "اسم المرسل" -#: pretix/base/settings.py:2189 +#: pretix/base/settings.py:2227 msgid "" "Sender name used in conjunction with the sender address for outgoing emails. " "Defaults to your event name." @@ -11001,20 +11577,20 @@ msgstr "" "يتم استخدام اسم المرسل مع عنوان المرسل لرسائل البريد الإلكتروني الصادرة. " "افتراضات لاسم الفعالية الخاصة بك." -#: pretix/base/settings.py:2207 pretix/base/settings.py:2264 -#: pretix/base/settings.py:2281 pretix/base/settings.py:2299 +#: pretix/base/settings.py:2245 pretix/base/settings.py:2302 +#: pretix/base/settings.py:2319 pretix/base/settings.py:2337 #, python-brace-format msgid "Your order: {code}" msgstr "طلبك هو: {code}" -#: pretix/base/settings.py:2211 pretix/base/settings.py:2244 -#: pretix/base/settings.py:2349 pretix/base/settings.py:2582 -#: pretix/base/settings.py:2619 +#: pretix/base/settings.py:2249 pretix/base/settings.py:2282 +#: pretix/base/settings.py:2387 pretix/base/settings.py:2620 +#: pretix/base/settings.py:2657 #, python-brace-format msgid "Your event registration: {code}" msgstr "تسجيل الفعالية الخاصة بك:{code}" -#: pretix/base/settings.py:2215 +#: pretix/base/settings.py:2253 #, python-brace-format msgid "" "Hello,\n" @@ -11039,12 +11615,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2228 +#: pretix/base/settings.py:2266 #, python-brace-format msgid "Your orders for {event}" msgstr "طلباتكم ل{event}" -#: pretix/base/settings.py:2232 +#: pretix/base/settings.py:2270 #, python-brace-format msgid "" "Hello,\n" @@ -11067,7 +11643,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2248 +#: pretix/base/settings.py:2286 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -11090,7 +11666,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2268 +#: pretix/base/settings.py:2306 #, python-brace-format msgid "" "Hello,\n" @@ -11115,7 +11691,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2285 +#: pretix/base/settings.py:2323 #, python-brace-format msgid "" "Hello,\n" @@ -11142,7 +11718,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2303 +#: pretix/base/settings.py:2341 #, python-brace-format msgid "" "Hello,\n" @@ -11172,13 +11748,13 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2321 +#: pretix/base/settings.py:2359 #, fuzzy #| msgid "Split into new order" msgid "Attachment for new orders" msgstr "تنقسم إلى النظام الجديد" -#: pretix/base/settings.py:2326 +#: pretix/base/settings.py:2364 #, python-brace-format msgid "" "This file will be attached to the first email that we send for every new " @@ -11190,7 +11766,7 @@ msgid "" "vital email going to spam, you can only upload PDF files of up to {size} MB." msgstr "" -#: pretix/base/settings.py:2353 +#: pretix/base/settings.py:2391 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -11213,12 +11789,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2365 +#: pretix/base/settings.py:2403 #, python-brace-format msgid "Your order has been changed: {code}" msgstr "تم تغيير طلبك: {code}" -#: pretix/base/settings.py:2369 +#: pretix/base/settings.py:2407 #, python-brace-format msgid "" "Hello,\n" @@ -11241,12 +11817,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2381 +#: pretix/base/settings.py:2419 #, python-brace-format msgid "Payment received for your order: {code}" msgstr "تم إستلام الدفع لطلبك: {code}" -#: pretix/base/settings.py:2385 +#: pretix/base/settings.py:2423 #, python-brace-format msgid "" "Hello,\n" @@ -11273,12 +11849,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2403 +#: pretix/base/settings.py:2441 #, python-brace-format msgid "Event registration confirmed: {code}" msgstr "تم تأكيد تسجيل الفعالية: {code}" -#: pretix/base/settings.py:2407 +#: pretix/base/settings.py:2445 #, python-brace-format msgid "" "Hello {attendee_name},\n" @@ -11301,12 +11877,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2424 pretix/control/forms/event.py:1136 -#: pretix/control/forms/event.py:1236 pretix/plugins/sendmail/models.py:275 +#: pretix/base/settings.py:2462 pretix/control/forms/event.py:1129 +#: pretix/control/forms/event.py:1243 pretix/plugins/sendmail/models.py:275 msgid "Number of days" msgstr "عدد الأيام" -#: pretix/base/settings.py:2426 pretix/control/forms/event.py:1139 +#: pretix/base/settings.py:2464 pretix/control/forms/event.py:1132 msgid "" "This email will be sent out this many days before the order expires. If the " "value is 0, the mail will never be sent." @@ -11314,12 +11890,12 @@ msgstr "" "سيتم إرسال هذا البريد الإلكتروني من هذا عدة أيام قبل انتهاء صلاحية النظام. " "إذا كانت القيمة 0، لن يتم إرسال البريد." -#: pretix/base/settings.py:2434 +#: pretix/base/settings.py:2472 #, python-brace-format msgid "Your order is about to expire: {code}" msgstr "طلبك على وشك الانتهاء: {code}" -#: pretix/base/settings.py:2438 +#: pretix/base/settings.py:2476 #, python-brace-format msgid "" "Hello,\n" @@ -11346,12 +11922,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2452 +#: pretix/base/settings.py:2490 #, python-brace-format msgid "Your order is pending payment: {code}" msgstr "طلبك في انتظار الدفع: {code}" -#: pretix/base/settings.py:2456 +#: pretix/base/settings.py:2494 #, fuzzy, python-brace-format #| msgid "" #| "Hello,\n" @@ -11389,13 +11965,13 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2469 +#: pretix/base/settings.py:2507 #, fuzzy, python-brace-format #| msgid "Payment received for your order: {code}" msgid "Incomplete payment received: {code}" msgstr "تم إستلام الدفع لطلبك: {code}" -#: pretix/base/settings.py:2473 +#: pretix/base/settings.py:2511 #, fuzzy, python-brace-format #| msgid "" #| "Hello,\n" @@ -11436,13 +12012,13 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2489 +#: pretix/base/settings.py:2527 #, fuzzy, python-brace-format #| msgid "Payment received for your order: {code}" msgid "Payment failed for your order: {code}" msgstr "تم إستلام الدفع لطلبك: {code}" -#: pretix/base/settings.py:2493 +#: pretix/base/settings.py:2531 #, fuzzy, python-brace-format #| msgid "" #| "Hello,\n" @@ -11483,12 +12059,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2507 +#: pretix/base/settings.py:2545 #, python-brace-format msgid "You have been selected from the waitinglist for {event}" msgstr "لقد تم اختيارك من قائمة الانتظار ل{event}" -#: pretix/base/settings.py:2511 +#: pretix/base/settings.py:2549 #, fuzzy, python-brace-format #| msgid "" #| "Hello,\n" @@ -11560,12 +12136,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2540 +#: pretix/base/settings.py:2578 #, python-brace-format msgid "Order canceled: {code}" msgstr "تم إلغاء الطلب: {code}" -#: pretix/base/settings.py:2544 +#: pretix/base/settings.py:2582 #, python-brace-format msgid "" "Hello,\n" @@ -11592,12 +12168,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2558 +#: pretix/base/settings.py:2596 #, python-brace-format msgid "Order approved and awaiting payment: {code}" msgstr "تمت الموافقة على الطلب وفي انتظار الدفع: {code}" -#: pretix/base/settings.py:2562 +#: pretix/base/settings.py:2600 #, python-brace-format msgid "" "Hello,\n" @@ -11627,7 +12203,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2586 pretix/base/settings.py:2623 +#: pretix/base/settings.py:2624 pretix/base/settings.py:2661 #, fuzzy, python-brace-format #| msgid "" #| "Hello {attendee_name},\n" @@ -11660,12 +12236,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2598 +#: pretix/base/settings.py:2636 #, python-brace-format msgid "Order approved and confirmed: {code}" msgstr "تمت الموافقة على الطلب وتأكيده: {code}" -#: pretix/base/settings.py:2602 +#: pretix/base/settings.py:2640 #, python-brace-format msgid "" "Hello,\n" @@ -11690,12 +12266,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2635 +#: pretix/base/settings.py:2673 #, python-brace-format msgid "Order denied: {code}" msgstr "الطلب مرفوض: {code}" -#: pretix/base/settings.py:2639 +#: pretix/base/settings.py:2677 #, python-brace-format msgid "" "Hello,\n" @@ -11724,7 +12300,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2654 +#: pretix/base/settings.py:2692 #, python-brace-format msgid "" "Hello,\n" @@ -11743,12 +12319,50 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2672 pretix/base/settings.py:2688 +#: pretix/base/settings.py:2702 +#, fuzzy, python-brace-format +#| msgid "Invoice number" +msgid "Invoice {invoice_number}" +msgstr "رقم الفاتورة" + +#: pretix/base/settings.py:2706 +#, fuzzy, python-brace-format +#| msgid "" +#| "Hello,\n" +#| "\n" +#| "somebody requested a list of your orders for {event}.\n" +#| "The list is as follows:\n" +#| "\n" +#| "{orders}\n" +#| "\n" +#| "Best regards, \n" +#| "Your {event} team" +msgid "" +"Hello,\n" +"\n" +"please find attached a new invoice for order {code} for {event}. This order " +"has been placed by {order_email}.\n" +"\n" +"Best regards, \n" +"\n" +"Your {event} team" +msgstr "" +"مرحبا،\n" +"\n" +"طلب شخص ما قائمة طلباتك ل{event}.\n" +"\n" +"القائمة هي كما يلي:\n" +"{orders}\n" +"\n" +"تحياتنا،\n" +"فريق {event}" + +#: pretix/base/settings.py:2724 pretix/base/settings.py:2740 #, python-brace-format msgid "Your ticket is ready for download: {code}" msgstr "تذكرتك جاهزة للتنزيل: {code}" -#: pretix/base/settings.py:2676 +#: pretix/base/settings.py:2728 #, fuzzy, python-brace-format #| msgid "" #| "Hello {attendee_name},\n" @@ -11781,7 +12395,7 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2692 +#: pretix/base/settings.py:2744 #, python-brace-format msgid "" "Hello,\n" @@ -11804,12 +12418,12 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/base/settings.py:2704 +#: pretix/base/settings.py:2756 #, python-brace-format msgid "Activate your account at {organizer}" msgstr "قم بتفعيل حسابك على {organizer}" -#: pretix/base/settings.py:2708 +#: pretix/base/settings.py:2760 #, python-brace-format msgid "" "Hello {name},\n" @@ -11844,12 +12458,12 @@ msgstr "" "\n" "فريق {organizer} الخاص بك" -#: pretix/base/settings.py:2726 +#: pretix/base/settings.py:2778 #, python-brace-format msgid "Confirm email address for your account at {organizer}" msgstr "تأكيد عنوان البريد الإلكتروني لحسابك على {organizer}" -#: pretix/base/settings.py:2730 +#: pretix/base/settings.py:2782 #, python-brace-format msgid "" "Hello {name},\n" @@ -11884,12 +12498,12 @@ msgstr "" "\n" "فريق {organizer} الخاص بك" -#: pretix/base/settings.py:2748 +#: pretix/base/settings.py:2800 #, python-brace-format msgid "Set a new password for your account at {organizer}" msgstr "قم بتعيين كلمة مرور جديدة لحسابك على {organizer}" -#: pretix/base/settings.py:2752 +#: pretix/base/settings.py:2804 #, python-brace-format msgid "" "Hello {name},\n" @@ -11924,57 +12538,57 @@ msgstr "" "\n" "فريق {organizer} الخاص بك" -#: pretix/base/settings.py:2804 pretix/base/settings.py:2811 -#: pretix/base/settings.py:2825 pretix/base/settings.py:2833 -#: pretix/base/settings.py:2847 pretix/base/settings.py:2855 -#: pretix/base/settings.py:2869 pretix/base/settings.py:2876 +#: pretix/base/settings.py:2856 pretix/base/settings.py:2863 +#: pretix/base/settings.py:2877 pretix/base/settings.py:2885 +#: pretix/base/settings.py:2899 pretix/base/settings.py:2907 +#: pretix/base/settings.py:2921 pretix/base/settings.py:2928 msgid "Please enter the hexadecimal code of a color, e.g. #990000." msgstr "الرجاء إدخال رمز عشري للون على سبيل المثال # 990000." -#: pretix/base/settings.py:2808 +#: pretix/base/settings.py:2860 msgid "Primary color" msgstr "لون أساسي" -#: pretix/base/settings.py:2829 +#: pretix/base/settings.py:2881 msgid "Accent color for success" msgstr "درجة لون لنجاح العملية" -#: pretix/base/settings.py:2830 +#: pretix/base/settings.py:2882 msgid "We strongly suggest to use a shade of green." msgstr "نقترح بشدة استخدام الظل الأخضر." -#: pretix/base/settings.py:2851 +#: pretix/base/settings.py:2903 msgid "Accent color for errors" msgstr "درجة لون الأخطاء" -#: pretix/base/settings.py:2852 +#: pretix/base/settings.py:2904 msgid "We strongly suggest to use a shade of red." msgstr "نقترح بشدة استخدام الظل الأحمر." -#: pretix/base/settings.py:2873 +#: pretix/base/settings.py:2925 msgid "Page background color" msgstr "لون خلفية الصفحة" -#: pretix/base/settings.py:2888 +#: pretix/base/settings.py:2940 msgid "Use round edges" msgstr "استخدم حواف مستديرة" -#: pretix/base/settings.py:2897 +#: pretix/base/settings.py:2949 msgid "" "Use native spinners in the widget instead of custom ones for numeric inputs " "such as quantity." msgstr "" -#: pretix/base/settings.py:2908 +#: pretix/base/settings.py:2960 msgid "Only respected by modern browsers." msgstr "يستخدم للمتصفحات الحديثة فقط." -#: pretix/base/settings.py:2919 pretix/base/settings.py:2963 +#: pretix/base/settings.py:2971 pretix/base/settings.py:3015 #: pretix/control/forms/organizer.py:523 msgid "Header image" msgstr "صورة رأسية" -#: pretix/base/settings.py:2922 +#: pretix/base/settings.py:2974 #, fuzzy #| msgid "" #| "If you provide a logo image, we will by default not show your event name " @@ -11994,26 +12608,26 @@ msgstr "" "120 بكسل. يمكنك زيادة الحجم من خلال الإعداد أدناه. نوصي بعدم استخدام " "التفاصيل الصغيرة على الصورة حيث سيتغير حجمها على الشاشات الصغيرة." -#: pretix/base/settings.py:2943 pretix/base/settings.py:2986 +#: pretix/base/settings.py:2995 pretix/base/settings.py:3038 msgid "Use header image in its full size" msgstr "استخدم الصورة الرأسية بحجمها الكامل" -#: pretix/base/settings.py:2944 pretix/base/settings.py:2987 +#: pretix/base/settings.py:2996 pretix/base/settings.py:3039 msgid "We recommend to upload a picture at least 1170 pixels wide." msgstr "نوصي بتحميل صورة لا يقل عرضها عن 1170 بكسل." -#: pretix/base/settings.py:2953 +#: pretix/base/settings.py:3005 msgid "Show event title even if a header image is present" msgstr "أعرض عنوان الفعالية حتى إذا كانت الصورة الرأسية موجودة" -#: pretix/base/settings.py:2954 +#: pretix/base/settings.py:3006 msgid "" "The title will only be shown on the event front page. If no header image is " "uploaded for the event, but the header image from the organizer profile is " "used, this option will be ignored and the event title will always be shown." msgstr "" -#: pretix/base/settings.py:2966 pretix/control/forms/organizer.py:527 +#: pretix/base/settings.py:3018 pretix/control/forms/organizer.py:527 #, fuzzy #| msgid "" #| "If you provide a logo image, we will by default not show your " @@ -12033,15 +12647,15 @@ msgstr "" "الحجم من الإعداد أدناه. نوصي بعدم استخدام التفاصيل الصغيرة على الصورة حيث " "سيتم تغيير حجمها على الشاشات الصغيرة." -#: pretix/base/settings.py:2996 +#: pretix/base/settings.py:3048 msgid "Use header image also for events without an individually uploaded logo" msgstr "" -#: pretix/base/settings.py:3004 +#: pretix/base/settings.py:3056 msgid "Favicon" msgstr "فافيكون" -#: pretix/base/settings.py:3007 +#: pretix/base/settings.py:3059 msgid "" "If you provide a favicon, we will show it instead of the default pretix " "icon. We recommend a size of at least 200x200px to accommodate most devices." @@ -12049,11 +12663,11 @@ msgstr "" "إذا قمت بتوفير فافيكون، وسوف نعرض بدلا من الافتراضي pretix رمز. نوصي حجم " "200x200px على الأقل لاستيعاب معظم الأجهزة." -#: pretix/base/settings.py:3023 +#: pretix/base/settings.py:3075 msgid "Social media image" msgstr "صورة وسائل التواصل الاجتماعي" -#: pretix/base/settings.py:3026 +#: pretix/base/settings.py:3078 msgid "" "This picture will be used as a preview if you post links to your ticket shop " "on social media. Facebook advises to use a picture size of 1200 x 630 " @@ -12067,19 +12681,19 @@ msgstr "" "لذلك نوصي بالتأكد من أنها لا تزال تبدو جيدة في حال كان المربع الأوسط هو الذي " "يظهر فقط. إذا لم تقم بملء هذا ، فسنستخدم الشعار المقدم أعلاه." -#: pretix/base/settings.py:3044 +#: pretix/base/settings.py:3096 msgid "Logo image" msgstr "صورة الشعار" -#: pretix/base/settings.py:3048 +#: pretix/base/settings.py:3100 msgid "We will show your logo with a maximal height and width of 2.5 cm." msgstr "سنعرض شعارك بارتفاع وعرض 2.5 سم كحد أقصى." -#: pretix/base/settings.py:3074 pretix/base/settings.py:3180 +#: pretix/base/settings.py:3126 pretix/base/settings.py:3232 msgid "Info text" msgstr "معلومات النص" -#: pretix/base/settings.py:3077 pretix/base/settings.py:3182 +#: pretix/base/settings.py:3129 pretix/base/settings.py:3234 msgid "" "Not displayed anywhere by default, but if you want to, you can use this e.g. " "in ticket templates." @@ -12087,11 +12701,11 @@ msgstr "" "لا يتم عرضه في أي مكان بشكل افتراضي ، ولكن إذا كنت ترغب في ذلك ، يمكنك " "استخدام هذا على سبيل المثال في قوالب التذاكر." -#: pretix/base/settings.py:3086 +#: pretix/base/settings.py:3138 msgid "Banner text (top)" msgstr "نص الشعار (أعلى)" -#: pretix/base/settings.py:3089 +#: pretix/base/settings.py:3141 msgid "" "This text will be shown above every page of your shop. Please only use this " "for very important messages." @@ -12099,11 +12713,11 @@ msgstr "" "سيظهر هذا النص فوق كل صفحة من صفحات متجرك. الرجاء استخدام هذا فقط للرسائل " "الهامة جدا." -#: pretix/base/settings.py:3099 +#: pretix/base/settings.py:3151 msgid "Banner text (bottom)" msgstr "نص الشعار (أسفل)" -#: pretix/base/settings.py:3102 +#: pretix/base/settings.py:3154 msgid "" "This text will be shown below every page of your shop. Please only use this " "for very important messages." @@ -12111,11 +12725,11 @@ msgstr "" "سيظهر هذا النص أسفل كل صفحة من صفحات متجرك. الرجاء استخدام هذا فقط للرسائل " "الهامة جدا." -#: pretix/base/settings.py:3112 +#: pretix/base/settings.py:3164 msgid "Voucher explanation" msgstr "تفسير لكود الخصم" -#: pretix/base/settings.py:3115 +#: pretix/base/settings.py:3167 msgid "" "This text will be shown next to the input for a voucher code. You can use it " "e.g. to explain how to obtain a voucher code." @@ -12123,11 +12737,11 @@ msgstr "" "سيظهر هذا النص بجانب إدخال رمز كود الخصم. يمكنك استخدامه على سبيل المثال " "لشرح كيفية الحصول على رمز قسيمة." -#: pretix/base/settings.py:3125 +#: pretix/base/settings.py:3177 msgid "Attendee data explanation" msgstr "شرح بيانات الحضور" -#: pretix/base/settings.py:3128 +#: pretix/base/settings.py:3180 #, fuzzy #| msgid "" #| "This text will be shown above the questions asked for every admission " @@ -12140,11 +12754,11 @@ msgstr "" "سيتم عرض هذا النص فوق الأسئلة المطروحة لكل منتج مدخل. يمكنك استخدامه على " "سبيل المثال لشرح سبب حاجتك إلى معلومات منهم." -#: pretix/base/settings.py:3138 +#: pretix/base/settings.py:3190 msgid "Additional success message" msgstr "رسالة نجاح إضافية" -#: pretix/base/settings.py:3139 +#: pretix/base/settings.py:3191 msgid "" "This message will be shown after an order has been created successfully. It " "will be shown in additional to the default text." @@ -12152,11 +12766,11 @@ msgstr "" "ستظهر هذه الرسالة بعد إنشاء الطلب بنجاح. سيتم عرضه بالإضافة إلى النص " "الافتراضي." -#: pretix/base/settings.py:3151 +#: pretix/base/settings.py:3203 msgid "Help text of the phone number field" msgstr "نص المساعدة لحقل رقم الهاتف" -#: pretix/base/settings.py:3158 +#: pretix/base/settings.py:3210 msgid "" "Make sure to enter a valid email address. We will send you an order " "confirmation including a link that you need to access your order later." @@ -12164,15 +12778,15 @@ msgstr "" "تأكد من إدخال عنوان بريد إلكتروني صالح. سنرسل إليك تأكيدا لطلبك يتضمن رابطا " "تحتاجه للوصول إلى طلبك لاحقا." -#: pretix/base/settings.py:3165 +#: pretix/base/settings.py:3217 msgid "Help text of the email field" msgstr "نص المساعدة لحقل البريد الإلكتروني" -#: pretix/base/settings.py:3191 +#: pretix/base/settings.py:3243 msgid "Allow creating a new team during event creation" msgstr "السماح بإنشاء فريق جديد أثناء إنشاء الفعالية" -#: pretix/base/settings.py:3192 +#: pretix/base/settings.py:3244 msgid "" "Users that do not have access to all events under this organizer, must " "select one of their teams to have access to the created event. This setting " @@ -12184,36 +12798,37 @@ msgstr "" "الإعداد للمستخدمين بإنشاء فريق محدد للفعاية أثناء التنقل ، حتى عندما لا يكون " "لديهم إذن \"إمكانية تغيير الفرق والتصاريح\"." -#: pretix/base/settings.py:3264 pretix/base/settings.py:3274 +#: pretix/base/settings.py:3316 pretix/base/settings.py:3326 msgid "Event start time (descending)" msgstr "وقت بدء الفعالية (تنازلي)" -#: pretix/base/settings.py:3266 pretix/base/settings.py:3276 +#: pretix/base/settings.py:3318 pretix/base/settings.py:3328 msgid "Name (descending)" msgstr "الاسم (تنازلي)" -#: pretix/base/settings.py:3271 +#: pretix/base/settings.py:3323 msgctxt "subevent" msgid "Date ordering" msgstr "ترتيب التاريخ" -#: pretix/base/settings.py:3287 +#: pretix/base/settings.py:3339 msgid "Link back to organizer overview on all event pages" msgstr "قم بنظرة عامة للمنظم للاطلاع على جميع صفحات الفعالية" -#: pretix/base/settings.py:3296 +#: pretix/base/settings.py:3348 msgid "Homepage text" msgstr "نص الصفحة الرئيسية" -#: pretix/base/settings.py:3298 +#: pretix/base/settings.py:3350 msgid "This will be displayed on the organizer homepage." msgstr "سيتم عرض هذا على الصفحة الرئيسية للمنظم." -#: pretix/base/settings.py:3313 +#: pretix/base/settings.py:3365 msgid "Length of gift card codes" msgstr "طول رموز بطاقات الهدايا" -#: pretix/base/settings.py:3314 +#: pretix/base/settings.py:3366 +#, python-brace-format msgid "" "The system generates by default {}-character long gift card codes. However, " "if a different length is required, it can be set here." @@ -12221,11 +12836,11 @@ msgstr "" "ينشئ النظام افتراضيا رموز بطاقات هدايا طويلة مكونة من {}-حرف. ومع ذلك ، إذا " "تم طلب طول مختلف، فيمكن تعيينه هنا." -#: pretix/base/settings.py:3330 +#: pretix/base/settings.py:3382 msgid "Validity of gift card codes in years" msgstr "صلاحية رموز بطاقات الهدايا بالسنوات" -#: pretix/base/settings.py:3331 +#: pretix/base/settings.py:3383 msgid "" "If you set a number here, gift cards will by default expire at the end of " "the year after this many years. If you keep it empty, gift cards do not have " @@ -12235,23 +12850,23 @@ msgstr "" "العام بعد هذه السنوات العديدة. إذا أبقيت الخانة فارغة ، فلن يكون لبطاقات " "الهدايا تاريخ انتهاء صلاحية صريح." -#: pretix/base/settings.py:3342 +#: pretix/base/settings.py:3394 msgid "Enable cookie consent management features" msgstr "" -#: pretix/base/settings.py:3348 +#: pretix/base/settings.py:3400 msgid "" "By clicking \"Accept all cookies\", you agree to the storing of cookies and " "use of similar technologies on your device." msgstr "" -#: pretix/base/settings.py:3355 +#: pretix/base/settings.py:3407 #, fuzzy #| msgid "Additional text" msgid "Dialog text" msgstr "نص إضافي" -#: pretix/base/settings.py:3362 +#: pretix/base/settings.py:3414 msgid "" "We use cookies and similar technologies to gather data that allows us to " "improve this website and our offerings. If you do not agree, we will only " @@ -12259,49 +12874,49 @@ msgid "" "offers." msgstr "" -#: pretix/base/settings.py:3370 +#: pretix/base/settings.py:3422 msgid "Secondary dialog text" msgstr "" -#: pretix/base/settings.py:3376 +#: pretix/base/settings.py:3428 #, fuzzy #| msgid "Price settings" msgid "Privacy settings" msgstr "ضبط الأسعار" -#: pretix/base/settings.py:3381 +#: pretix/base/settings.py:3433 #, fuzzy #| msgid "Allowed titles" msgid "Dialog title" msgstr "عناوين سمح" -#: pretix/base/settings.py:3387 +#: pretix/base/settings.py:3439 msgid "Accept all cookies" msgstr "" -#: pretix/base/settings.py:3392 +#: pretix/base/settings.py:3444 #, fuzzy #| msgid "Product variation description" msgid "\"Accept\" button description" msgstr "وصف نوع المنتج" -#: pretix/base/settings.py:3398 +#: pretix/base/settings.py:3450 #, fuzzy #| msgid "Required question" msgid "Required cookies only" msgstr "سؤال مطلوب" -#: pretix/base/settings.py:3403 +#: pretix/base/settings.py:3455 #, fuzzy #| msgid "Product variation description" msgid "\"Reject\" button description" msgstr "وصف نوع المنتج" -#: pretix/base/settings.py:3413 +#: pretix/base/settings.py:3465 msgid "Customers can choose their own seats" msgstr "يمكن للعملاء اختيار مقاعدهم الخاصة" -#: pretix/base/settings.py:3414 +#: pretix/base/settings.py:3466 msgid "" "If disabled, you will need to manually assign seats in the backend. Note " "that this can mean people will not know their seat after their purchase and " @@ -12311,176 +12926,159 @@ msgstr "" "لاحظ أن هذا قد يعني أن الأشخاص لن يعرفوا مقعدهم بعد شرائه وقد لا يكون مكتوبا " "على تذكرتهم." -#: pretix/base/settings.py:3440 +#: pretix/base/settings.py:3492 msgid "Show button to copy user input from other products" msgstr "أظهر الزر لنسخ مدخلات المستخدم من المنتجات الأخرى" -#: pretix/base/settings.py:3450 +#: pretix/base/settings.py:3502 msgid "Most common English titles" msgstr "العناوين الإنجليزية الأكثر شيوعا" -#: pretix/base/settings.py:3460 +#: pretix/base/settings.py:3512 msgid "Most common German titles" msgstr "العناوين الألمانية الأكثر شيوعا" -#: pretix/base/settings.py:3473 +#: pretix/base/settings.py:3525 msgctxt "person_name_salutation" msgid "Ms" msgstr "آنسة" -#: pretix/base/settings.py:3474 +#: pretix/base/settings.py:3526 msgctxt "person_name_salutation" msgid "Mr" msgstr "السيد" -#: pretix/base/settings.py:3475 +#: pretix/base/settings.py:3527 msgctxt "person_name_salutation" msgid "Mx" msgstr "السيد\\السيدة" -#: pretix/base/settings.py:3507 pretix/base/settings.py:3520 -#: pretix/base/settings.py:3536 pretix/base/settings.py:3586 -#: pretix/base/settings.py:3599 pretix/base/settings.py:3613 -#: pretix/base/settings.py:3666 pretix/base/settings.py:3687 -#: pretix/base/settings.py:3709 -msgid "Given name" -msgstr "الاسم الاول" - -#: pretix/base/settings.py:3508 pretix/base/settings.py:3521 -#: pretix/base/settings.py:3537 pretix/base/settings.py:3553 -#: pretix/base/settings.py:3570 pretix/base/settings.py:3585 -#: pretix/base/settings.py:3600 pretix/base/settings.py:3614 -#: pretix/base/settings.py:3667 pretix/base/settings.py:3688 -#: pretix/base/settings.py:3710 -msgid "Family name" -msgstr "اسم العائلة" - -#: pretix/base/settings.py:3512 pretix/base/settings.py:3528 -#: pretix/base/settings.py:3544 pretix/base/settings.py:3559 -#: pretix/base/settings.py:3577 pretix/base/settings.py:3592 -#: pretix/base/settings.py:3622 pretix/base/settings.py:3646 -#: pretix/base/settings.py:3678 pretix/base/settings.py:3700 -#: pretix/base/settings.py:3731 +#: pretix/base/settings.py:3564 pretix/base/settings.py:3580 +#: pretix/base/settings.py:3596 pretix/base/settings.py:3611 +#: pretix/base/settings.py:3629 pretix/base/settings.py:3644 +#: pretix/base/settings.py:3674 pretix/base/settings.py:3698 +#: pretix/base/settings.py:3730 pretix/base/settings.py:3752 +#: pretix/base/settings.py:3783 msgctxt "person_name_sample" msgid "John" msgstr "جون" -#: pretix/base/settings.py:3513 pretix/base/settings.py:3529 -#: pretix/base/settings.py:3545 pretix/base/settings.py:3561 -#: pretix/base/settings.py:3579 pretix/base/settings.py:3593 -#: pretix/base/settings.py:3623 pretix/base/settings.py:3679 -#: pretix/base/settings.py:3701 pretix/base/settings.py:3732 +#: pretix/base/settings.py:3565 pretix/base/settings.py:3581 +#: pretix/base/settings.py:3597 pretix/base/settings.py:3613 +#: pretix/base/settings.py:3631 pretix/base/settings.py:3645 +#: pretix/base/settings.py:3675 pretix/base/settings.py:3731 +#: pretix/base/settings.py:3753 pretix/base/settings.py:3784 msgctxt "person_name_sample" msgid "Doe" msgstr "دو" -#: pretix/base/settings.py:3519 pretix/base/settings.py:3535 -#: pretix/base/settings.py:3567 pretix/base/settings.py:3686 -#: pretix/base/settings.py:3708 +#: pretix/base/settings.py:3571 pretix/base/settings.py:3587 +#: pretix/base/settings.py:3619 pretix/base/settings.py:3738 +#: pretix/base/settings.py:3760 msgctxt "person_name" msgid "Title" msgstr "عنوان" -#: pretix/base/settings.py:3527 pretix/base/settings.py:3543 -#: pretix/base/settings.py:3576 pretix/base/settings.py:3699 -#: pretix/base/settings.py:3730 +#: pretix/base/settings.py:3579 pretix/base/settings.py:3595 +#: pretix/base/settings.py:3628 pretix/base/settings.py:3751 +#: pretix/base/settings.py:3782 msgctxt "person_name_sample" msgid "Dr" msgstr "الدكتور" -#: pretix/base/settings.py:3551 pretix/base/settings.py:3568 +#: pretix/base/settings.py:3603 pretix/base/settings.py:3620 msgid "First name" msgstr "الاسم الاول" -#: pretix/base/settings.py:3552 pretix/base/settings.py:3569 +#: pretix/base/settings.py:3604 pretix/base/settings.py:3621 msgid "Middle name" msgstr "الاسم الأوسط" -#: pretix/base/settings.py:3633 pretix/base/settings.py:3645 -#: pretix/control/forms/organizer.py:655 +#: pretix/base/settings.py:3685 pretix/base/settings.py:3697 +#: pretix/control/forms/organizer.py:658 msgctxt "person_name_sample" msgid "John Doe" msgstr "جون دو" -#: pretix/base/settings.py:3639 +#: pretix/base/settings.py:3691 msgid "Calling name" msgstr "اسم النداء" -#: pretix/base/settings.py:3653 +#: pretix/base/settings.py:3705 msgid "Latin transcription" msgstr "الإملاء بالحروف اللاتينية" -#: pretix/base/settings.py:3665 pretix/base/settings.py:3685 -#: pretix/base/settings.py:3707 +#: pretix/base/settings.py:3717 pretix/base/settings.py:3737 +#: pretix/base/settings.py:3759 msgctxt "person_name" msgid "Salutation" msgstr "تحية" -#: pretix/base/settings.py:3677 pretix/base/settings.py:3698 -#: pretix/base/settings.py:3729 +#: pretix/base/settings.py:3729 pretix/base/settings.py:3750 +#: pretix/base/settings.py:3781 msgctxt "person_name_sample" msgid "Mr" msgstr "السيد" -#: pretix/base/settings.py:3711 +#: pretix/base/settings.py:3763 msgctxt "person_name" msgid "Degree (after name)" msgstr "الدرجة (بعد الاسم)" -#: pretix/base/settings.py:3733 +#: pretix/base/settings.py:3785 msgctxt "person_name_sample" msgid "MA" msgstr "MA" -#: pretix/base/settings.py:3759 pretix/base/settings.py:3761 +#: pretix/base/settings.py:3811 pretix/base/settings.py:3813 #, fuzzy #| msgid "Product name" msgctxt "address" msgid "Province" msgstr "اسم المنتج" -#: pretix/base/settings.py:3760 +#: pretix/base/settings.py:3812 #, fuzzy #| msgid "Use feature" msgctxt "address" msgid "Prefecture" msgstr "استخدام ميزة" -#: pretix/base/settings.py:3849 pretix/control/forms/event.py:229 +#: pretix/base/settings.py:3901 pretix/control/forms/event.py:228 msgid "" "Your default locale must also be enabled for your event (see box above)." msgstr "يجب أيضا تمكين لغتك الافتراضية للفعالية الخاصة بك (انظر المربع أعلاه)." -#: pretix/base/settings.py:3853 +#: pretix/base/settings.py:3905 msgid "" "You cannot require specifying attendee names if you do not ask for them." msgstr "لا يمكنك طلب تحديد أسماء الحضور إذا لم تطلبها." -#: pretix/base/settings.py:3857 +#: pretix/base/settings.py:3909 msgid "You have to ask for attendee emails if you want to make them required." msgstr "" "عليك أن تطلب رسائل البريد الإلكتروني للحضور إذا كنت ترغب في جعلها إلزامية." -#: pretix/base/settings.py:3861 +#: pretix/base/settings.py:3913 msgid "" "You have to ask for invoice addresses if you want to make them required." msgstr "عليك أن تطلب عناوين الفواتير إذا كنت ترغب في جعلها إلزامية." -#: pretix/base/settings.py:3865 +#: pretix/base/settings.py:3917 msgid "You have to require invoice addresses to require for company names." msgstr "عليك أن تطلب عنوان الفاتورة لطلب أسماء الشركات." -#: pretix/base/settings.py:3872 +#: pretix/base/settings.py:3924 msgid "The last payment date cannot be before the end of presale." msgstr "لا يمكن أن يكون تاريخ الدفع الأخير قبل نهاية فترة عرض البيع المسبق." -#: pretix/base/settings.py:3880 +#: pretix/base/settings.py:3932 #, fuzzy, python-brace-format #| msgid "Please enter a valid sales channel." msgid "The value \"{identifier}\" is not a valid sales channel." msgstr "الرجاء إدخال قناة بيع صالحة." -#: pretix/base/settings.py:3895 +#: pretix/base/settings.py:3947 msgid "This needs to be disabled if other NFC-based types are active." msgstr "" @@ -12551,18 +13149,18 @@ msgstr "" "سيؤدي هذا إلى إزالة جميع عناوين الفواتير من الطلبات ، بالإضافة إلى التغييرات " "المسجلة عليها." -#: pretix/base/shredder.py:535 +#: pretix/base/shredder.py:538 msgid "Question answers" msgstr "إجابات السؤال" -#: pretix/base/shredder.py:537 +#: pretix/base/shredder.py:540 msgid "" "This will remove all answers to questions, as well as logged changes to them." msgstr "" "سيؤدي هذا إلى إزالة جميع الإجابات على الأسئلة ، بالإضافة إلى التغييرات " "المسجلة عليها." -#: pretix/base/shredder.py:579 +#: pretix/base/shredder.py:582 msgid "" "This will remove all invoice PDFs, as well as any of their text content that " "might contain personal data from the database. Invoice numbers and totals " @@ -12572,16 +13170,16 @@ msgstr "" "محتوياتها النصية التي قد تحتوي على بيانات شخصية من قاعدة البيانات. سيتم " "الاحتفاظ بأرقام ومجاميع الفواتير." -#: pretix/base/shredder.py:608 +#: pretix/base/shredder.py:612 msgid "Cached ticket files" msgstr "ملفات التذاكر المخزنة مؤقتا" -#: pretix/base/shredder.py:610 +#: pretix/base/shredder.py:614 msgid "This will remove all cached ticket files. No download will be offered." msgstr "" "سيؤدي هذا إلى إزالة جميع ملفات التذاكر المخزنة مؤقتا. لن يتم عرض أي تنزيل." -#: pretix/base/shredder.py:632 +#: pretix/base/shredder.py:636 msgid "" "This will remove payment-related information. Depending on the payment " "method, all data will be removed or personal data only. No download will be " @@ -12670,7 +13268,7 @@ msgid "You do not have access to this page." msgstr "ليس لديك صلاحية الوصول إلى هذه الصفحة." #: pretix/base/templates/403.html:20 pretix/base/templates/404.html:19 -#: pretix/control/templates/pretixcontrol/base.html:197 +#: pretix/control/templates/pretixcontrol/base.html:195 #: pretix/control/templates/pretixcontrol/user/staff_session_start.html:4 #: pretix/control/templates/pretixcontrol/user/staff_session_start.html:6 #: pretix/presale/templates/pretixpresale/event/offline.html:21 @@ -12795,7 +13393,7 @@ msgid "Event:" msgstr "فعالية:" #: pretix/base/templates/pretixbase/email/order_details.html:23 -#: pretix/base/templates/pretixbase/email/order_details.html:74 +#: pretix/base/templates/pretixbase/email/order_details.html:80 msgid "Order code:" msgstr "رمز الطلب:" @@ -12804,7 +13402,7 @@ msgid "created by" msgstr "أنشئ من قبل" #: pretix/base/templates/pretixbase/email/order_details.html:34 -#: pretix/base/templates/pretixbase/email/order_details.html:126 +#: pretix/base/templates/pretixbase/email/order_details.html:132 msgid "Contact:" msgstr "جهة اتصال:" @@ -12814,7 +13412,7 @@ msgid "" "event:" msgstr "تتلقى هذا البريد الإلكتروني لأنك قدمت طلبا للفعالية التالية:" -#: pretix/base/templates/pretixbase/email/order_details.html:83 +#: pretix/base/templates/pretixbase/email/order_details.html:89 msgid "Details:" msgstr "تفاصيل:" @@ -13416,14 +14014,18 @@ msgid "Support for check-in questions" msgstr "آلية الدخول" #: pretix/control/forms/checkin.py:197 pretix/control/forms/checkin.py:213 -#: pretix/control/forms/filter.py:2395 pretix/control/forms/filter.py:2437 -#: pretix/control/forms/filter.py:2602 +#: pretix/control/forms/filter.py:2391 pretix/control/forms/filter.py:2433 +#: pretix/control/forms/filter.py:2598 #, fuzzy #| msgctxt "subevent" #| msgid "All dates" msgid "All gates" msgstr "كل التواريخ" +#: pretix/control/forms/checkin.py:222 +msgid "I am sure that the check-in state of the entire event should be reset." +msgstr "" + #: pretix/control/forms/event.py:91 msgid "Use languages" msgstr "استخدام اللغات" @@ -13436,28 +14038,28 @@ msgstr "اختيار جميع اللغات التي ينبغي أن يكون ه msgid "This is an event series" msgstr "هذه هي سلسلة من الأحداث" -#: pretix/control/forms/event.py:132 +#: pretix/control/forms/event.py:131 msgid "" "You already used this slug for a different event. Please choose a new one." msgstr "استخدمته بالفعل هذا سبيكة لحدث آخر. الرجاء اختيار واحدة جديدة." -#: pretix/control/forms/event.py:136 pretix/control/forms/event.py:520 +#: pretix/control/forms/event.py:135 pretix/control/forms/event.py:519 msgid "Event timezone" msgstr "توقيت الحدث" -#: pretix/control/forms/event.py:143 +#: pretix/control/forms/event.py:142 msgid "I don't want to specify taxes now" msgstr "" -#: pretix/control/forms/event.py:144 +#: pretix/control/forms/event.py:143 msgid "You can always configure tax rates later." msgstr "" -#: pretix/control/forms/event.py:148 +#: pretix/control/forms/event.py:147 msgid "Sales tax rate" msgstr "معدل ضريبة المبيعات" -#: pretix/control/forms/event.py:149 +#: pretix/control/forms/event.py:148 msgid "" "Do you need to pay sales tax on your tickets? In this case, please enter the " "applicable tax rate here in percent. If you have a more complicated tax " @@ -13467,22 +14069,22 @@ msgstr "" "يرجى إدخال معدل الضريبة المطبقة هنا في المئة. إذا كان لديك الوضع الضريبي " "أكثر تعقيدا، يمكنك إضافة المزيد من معدلات الضرائب وتكوين مفصل لاحقا." -#: pretix/control/forms/event.py:158 +#: pretix/control/forms/event.py:157 msgid "Grant access to team" msgstr "" -#: pretix/control/forms/event.py:159 +#: pretix/control/forms/event.py:158 msgid "" "You are allowed to create events under this organizer, however you do not " "have permission to edit all events under this organizer. Please select one " "of your existing teams that will be granted access to this event." msgstr "" -#: pretix/control/forms/event.py:164 +#: pretix/control/forms/event.py:163 msgid "Create a new team for this event with me as the only member" msgstr "" -#: pretix/control/forms/event.py:208 pretix/control/forms/event.py:379 +#: pretix/control/forms/event.py:207 pretix/control/forms/event.py:378 msgid "" "Sample Conference Center\n" "Heidelberg, Germany" @@ -13490,66 +14092,66 @@ msgstr "" "مركز المؤتمرات عينة\n" "هايدلبرغ، ألمانيا" -#: pretix/control/forms/event.py:233 +#: pretix/control/forms/event.py:232 msgid "Your default locale must be specified." msgstr "يجب تحديد اللغة الافتراضية." -#: pretix/control/forms/event.py:237 +#: pretix/control/forms/event.py:236 #, python-brace-format msgid "" "You have not specified a tax rate. If you do not want us to compute sales " "taxes, please check \"{field}\" above." msgstr "" -#: pretix/control/forms/event.py:312 +#: pretix/control/forms/event.py:311 msgid "Copy configuration from" msgstr "تكوين نسخة من" -#: pretix/control/forms/event.py:318 pretix/control/forms/event.py:321 -#: pretix/control/forms/item.py:414 +#: pretix/control/forms/event.py:317 pretix/control/forms/event.py:320 +#: pretix/control/forms/item.py:413 msgid "Do not copy" msgstr "لا تنسخ" -#: pretix/control/forms/event.py:337 pretix/control/forms/item.py:1300 -#: pretix/control/forms/subevents.py:414 +#: pretix/control/forms/event.py:336 pretix/control/forms/item.py:1301 +#: pretix/control/forms/subevents.py:410 #, python-brace-format msgid "Default ({value})" msgstr "تلقائي ({value})" -#: pretix/control/forms/event.py:385 pretix/control/forms/event.py:398 +#: pretix/control/forms/event.py:384 pretix/control/forms/event.py:397 msgid "Domain" msgstr "" -#: pretix/control/forms/event.py:389 +#: pretix/control/forms/event.py:388 #, fuzzy #| msgid "The selected product is not active or has no price set." msgid "You can configure this in your organizer settings." msgstr "المنتج المحدد غير نشط أو ليس له سعر محدد." -#: pretix/control/forms/event.py:399 +#: pretix/control/forms/event.py:398 #, fuzzy #| msgid "You can now login using your new password." msgid "You can add more domains in your organizer account." msgstr "يمكنك الآن تسجيل الدخول باستخدام كلمة المرور الجديدة." -#: pretix/control/forms/event.py:400 +#: pretix/control/forms/event.py:399 #, fuzzy #| msgid "Organizer account" msgid "Same as organizer account" msgstr "حساب منظم" -#: pretix/control/forms/event.py:505 +#: pretix/control/forms/event.py:504 #, python-brace-format msgid "" "A validation error has occurred on a setting that is not part of this form: " "{error}" msgstr "" -#: pretix/control/forms/event.py:523 pretix/control/forms/organizer.py:461 +#: pretix/control/forms/event.py:522 pretix/control/forms/organizer.py:461 msgid "Name format" msgstr "تنسيق اسم" -#: pretix/control/forms/event.py:524 pretix/control/forms/organizer.py:462 +#: pretix/control/forms/event.py:523 pretix/control/forms/organizer.py:462 msgid "" "This defines how pretix will ask for human names. Changing this after you " "already received orders might lead to unexpected behavior when sorting or " @@ -13558,11 +14160,11 @@ msgstr "" "هذا يعرف كيف pretix سيطلب أسماء الإنسان. تغيير هذا بعد تلقي أوامر بالفعل قد " "يؤدي إلى سلوك غير متوقع عندما يكون الترتيب أو تغيير أسماء." -#: pretix/control/forms/event.py:529 pretix/control/forms/organizer.py:467 +#: pretix/control/forms/event.py:528 pretix/control/forms/organizer.py:467 msgid "Allowed titles" msgstr "عناوين سمح" -#: pretix/control/forms/event.py:530 pretix/control/forms/organizer.py:468 +#: pretix/control/forms/event.py:529 pretix/control/forms/organizer.py:468 msgid "" "If the naming scheme you defined above allows users to input a title, you " "can use this to restrict the set of selectable titles." @@ -13570,53 +14172,40 @@ msgstr "" "إذا كان نظام تسمية قمت بتعريفه فوق يتيح للمستخدمين إدخال العنوان، يمكنك " "استخدام هذا للحد من مجموعة من العناوين اختيار." -#: pretix/control/forms/event.py:649 pretix/control/forms/organizer.py:542 +#: pretix/control/forms/event.py:648 pretix/control/forms/organizer.py:542 #, python-brace-format msgid "Ask for {fields}, display like {example}" msgstr "طلب {fields}، العرض مثل {example}" -#: pretix/control/forms/event.py:655 pretix/control/forms/organizer.py:548 +#: pretix/control/forms/event.py:654 pretix/control/forms/organizer.py:548 msgid "Free text input" msgstr "إدخال النص الحر" -#: pretix/control/forms/event.py:691 +#: pretix/control/forms/event.py:690 msgid "Do not ask" msgstr "لا تسأل" -#: pretix/control/forms/event.py:692 +#: pretix/control/forms/event.py:691 msgid "Ask, but do not require input" msgstr "" -#: pretix/control/forms/event.py:693 +#: pretix/control/forms/event.py:692 #: pretix/control/templates/pretixcontrol/event/settings.html:76 msgid "Ask and require input" msgstr "" #: pretix/control/forms/event.py:770 +#, python-brace-format msgid "" "You have configured gift cards to be valid {} years plus the year the gift " "card is issued in." msgstr "" -#: pretix/control/forms/event.py:789 -msgid "Tax rule for payment fees" -msgstr "حكم الضرائب لدفع الرسوم" - -#: pretix/control/forms/event.py:791 -msgid "" -"The tax rule that applies for additional fees you configured for single " -"payment methods. This will set the tax rate and reverse charge rules, other " -"settings of the tax rule are ignored." -msgstr "" -"حكم الضرائب التي تنطبق على الرسوم الإضافية التي تم تكوينها لطرق الدفع احدة. " -"هذا وسوف يحدد معدل الضريبة وقواعد المحاسبة العكسية، يتم تجاهل إعدادات أخرى " -"للحكم الضرائب." - -#: pretix/control/forms/event.py:897 +#: pretix/control/forms/event.py:887 msgid "Generate invoices for Sales channels" msgstr "توليد الفواتير للقنوات المبيعات" -#: pretix/control/forms/event.py:900 +#: pretix/control/forms/event.py:890 msgid "" "If you have enabled invoice generation in the previous setting, you can " "limit it here to specific sales channels." @@ -13624,105 +14213,107 @@ msgstr "" "إذا قمت بتمكين الجيل الفاتورة في الإعداد السابق، يمكنك تحديد هنا لقنوات " "البيع المحددة." -#: pretix/control/forms/event.py:904 +#: pretix/control/forms/event.py:894 msgid "Invoice style" msgstr "النمط فاتورة" -#: pretix/control/forms/event.py:910 +#: pretix/control/forms/event.py:900 msgid "Invoice language" msgstr "اللغة فاتورة" -#: pretix/control/forms/event.py:911 pretix/control/forms/event.py:926 +#: pretix/control/forms/event.py:901 pretix/control/forms/event.py:916 msgid "The user's language" msgstr "لغة المستخدم" -#: pretix/control/forms/event.py:934 +#: pretix/control/forms/event.py:924 #, python-brace-format msgid "" "An invoice will be issued before payment if the customer selects one of the " "following payment methods: {list}" msgstr "" -#: pretix/control/forms/event.py:938 +#: pretix/control/forms/event.py:928 msgid "" "None of the currently configured payment methods will cause an invoice to be " "issued before payment." msgstr "" -#: pretix/control/forms/event.py:947 +#: pretix/control/forms/event.py:937 #, fuzzy #| msgid "Split into new order" msgid "Recommended" msgstr "تنقسم إلى النظام الجديد" -#: pretix/control/forms/event.py:959 +#: pretix/control/forms/event.py:949 msgid "The online shop must be selected to receive these emails." msgstr "" -#: pretix/control/forms/event.py:975 +#: pretix/control/forms/event.py:965 #, fuzzy #| msgid "Sales channels to automatically check in" msgid "Sales channels for checkout emails" msgstr "قنوات البيع للبريد الإلكتروني الخاص بالدفع" -#: pretix/control/forms/event.py:976 +#: pretix/control/forms/event.py:966 msgid "" "The order placed and paid emails will only be send to orders from these " "sales channels. The online shop must be enabled." msgstr "" -#: pretix/control/forms/event.py:987 +#: pretix/control/forms/event.py:977 msgid "" "This email will only be send to orders from these sales channels. The online " "shop must be enabled." msgstr "" -#: pretix/control/forms/event.py:995 pretix/control/forms/organizer.py:583 +#: pretix/control/forms/event.py:985 pretix/control/forms/organizer.py:583 msgid "Bcc address" msgstr "عنوان مخفية" -#: pretix/control/forms/event.py:996 pretix/control/forms/organizer.py:584 -msgid "All emails will be sent to this address as a Bcc copy" +#: pretix/control/forms/event.py:987 pretix/control/forms/organizer.py:585 +#, fuzzy +#| msgid "All emails will be sent to this address as a Bcc copy" +msgid "All emails will be sent to this address as a Bcc copy." msgstr "سيتم إرسال جميع رسائل البريد الإلكتروني إلى هذا العنوان كنسخة مخفية" -#: pretix/control/forms/event.py:1002 pretix/control/forms/organizer.py:590 +#: pretix/control/forms/event.py:995 pretix/control/forms/organizer.py:593 msgid "Signature" msgstr "التوقيع" -#: pretix/control/forms/event.py:1005 +#: pretix/control/forms/event.py:998 #, python-brace-format msgid "This will be attached to every email. Available placeholders: {event}" msgstr "وسيلحق هذا على كل البريد الإلكتروني. النائبة المتاحة: {event}" -#: pretix/control/forms/event.py:1010 pretix/control/forms/organizer.py:598 +#: pretix/control/forms/event.py:1003 pretix/control/forms/organizer.py:601 msgid "e.g. your contact details" msgstr "مثلا تفاصيل الاتصال الخاصة بك" -#: pretix/control/forms/event.py:1015 +#: pretix/control/forms/event.py:1008 msgid "HTML mail renderer" msgstr "HTML العارض الإلكتروني" -#: pretix/control/forms/event.py:1020 pretix/control/forms/event.py:1047 -#: pretix/control/forms/event.py:1074 pretix/control/forms/event.py:1210 +#: pretix/control/forms/event.py:1013 pretix/control/forms/event.py:1040 +#: pretix/control/forms/event.py:1067 pretix/control/forms/event.py:1217 #, fuzzy #| msgid "Text sent to order contact address" msgid "Subject sent to order contact address" msgstr "إرسالها إلى عنوان النص أمر الاتصال" -#: pretix/control/forms/event.py:1025 pretix/control/forms/event.py:1052 -#: pretix/control/forms/event.py:1079 pretix/control/forms/event.py:1215 +#: pretix/control/forms/event.py:1018 pretix/control/forms/event.py:1045 +#: pretix/control/forms/event.py:1072 pretix/control/forms/event.py:1222 msgid "Text sent to order contact address" msgstr "إرسالها إلى عنوان النص أمر الاتصال" -#: pretix/control/forms/event.py:1030 pretix/control/forms/event.py:1057 -#: pretix/control/forms/event.py:1084 pretix/control/forms/event.py:1220 -#: pretix/control/forms/event.py:1265 pretix/control/forms/event.py:1295 +#: pretix/control/forms/event.py:1023 pretix/control/forms/event.py:1050 +#: pretix/control/forms/event.py:1077 pretix/control/forms/event.py:1227 +#: pretix/control/forms/event.py:1272 pretix/control/forms/event.py:1302 msgid "Send an email to attendees" msgstr "إرسال بريد إلكتروني إلى الحضور" -#: pretix/control/forms/event.py:1031 pretix/control/forms/event.py:1058 -#: pretix/control/forms/event.py:1085 pretix/control/forms/event.py:1221 -#: pretix/control/forms/event.py:1266 pretix/control/forms/event.py:1296 +#: pretix/control/forms/event.py:1024 pretix/control/forms/event.py:1051 +#: pretix/control/forms/event.py:1078 pretix/control/forms/event.py:1228 +#: pretix/control/forms/event.py:1273 pretix/control/forms/event.py:1303 msgid "" "If the order contains attendees with email addresses different from the " "person who orders the tickets, the following email will be sent out to the " @@ -13731,84 +14322,85 @@ msgstr "" "إذا كان النظام يحتوي على الحضور مع عناوين البريد الإلكتروني المختلفة من " "الشخص الذي يأمر التذاكر، سيتم إرسال البريد الإلكتروني التالي إلى الحضور." -#: pretix/control/forms/event.py:1036 pretix/control/forms/event.py:1063 -#: pretix/control/forms/event.py:1090 pretix/control/forms/event.py:1226 -#: pretix/control/forms/event.py:1271 pretix/control/forms/event.py:1301 +#: pretix/control/forms/event.py:1029 pretix/control/forms/event.py:1056 +#: pretix/control/forms/event.py:1083 pretix/control/forms/event.py:1233 +#: pretix/control/forms/event.py:1278 pretix/control/forms/event.py:1308 #, fuzzy #| msgid "Text sent to attendees" msgid "Subject sent to attendees" msgstr "إرسالها النص إلى الحضور" -#: pretix/control/forms/event.py:1041 pretix/control/forms/event.py:1068 -#: pretix/control/forms/event.py:1095 pretix/control/forms/event.py:1231 -#: pretix/control/forms/event.py:1276 pretix/control/forms/event.py:1306 +#: pretix/control/forms/event.py:1034 pretix/control/forms/event.py:1061 +#: pretix/control/forms/event.py:1088 pretix/control/forms/event.py:1238 +#: pretix/control/forms/event.py:1283 pretix/control/forms/event.py:1313 msgid "Text sent to attendees" msgstr "إرسالها النص إلى الحضور" -#: pretix/control/forms/event.py:1106 pretix/control/forms/event.py:1180 -#: pretix/control/forms/event.py:1190 pretix/control/forms/event.py:1200 -#: pretix/control/forms/event.py:1205 pretix/control/forms/organizer.py:609 -#: pretix/control/forms/organizer.py:619 pretix/control/forms/organizer.py:629 +#: pretix/control/forms/event.py:1099 pretix/control/forms/event.py:1173 +#: pretix/control/forms/event.py:1183 pretix/control/forms/event.py:1193 +#: pretix/control/forms/event.py:1198 pretix/control/forms/event.py:1210 +#: pretix/control/forms/organizer.py:612 pretix/control/forms/organizer.py:622 +#: pretix/control/forms/organizer.py:632 #: pretix/control/templates/pretixcontrol/event/mail.html:88 #: pretix/control/templates/pretixcontrol/organizers/giftcard.html:111 msgid "Text" msgstr "نص" -#: pretix/control/forms/event.py:1111 +#: pretix/control/forms/event.py:1104 #, fuzzy #| msgid "Text (sent by admin)" msgid "Subject (sent by admin)" msgstr "النص (أرسلت بواسطة admin)" -#: pretix/control/forms/event.py:1116 +#: pretix/control/forms/event.py:1109 #, fuzzy #| msgid "Text sent to attendees" msgid "Subject (sent by admin to attendee)" msgstr "إرسالها النص إلى الحضور" -#: pretix/control/forms/event.py:1121 +#: pretix/control/forms/event.py:1114 msgid "Text (sent by admin)" msgstr "النص (أرسلت بواسطة admin)" -#: pretix/control/forms/event.py:1126 +#: pretix/control/forms/event.py:1119 #, fuzzy #| msgid "Text (requested by user)" msgid "Subject (requested by user)" msgstr "النص (عن طريق المستخدم المطلوب)" -#: pretix/control/forms/event.py:1131 +#: pretix/control/forms/event.py:1124 msgid "Text (requested by user)" msgstr "النص (عن طريق المستخدم المطلوب)" -#: pretix/control/forms/event.py:1143 +#: pretix/control/forms/event.py:1136 msgid "Text (if order will expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1148 +#: pretix/control/forms/event.py:1141 msgid "Subject (if order will expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1153 +#: pretix/control/forms/event.py:1146 msgid "Text (if order will not expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1158 +#: pretix/control/forms/event.py:1151 msgid "Subject (if order will not expire automatically)" msgstr "" -#: pretix/control/forms/event.py:1163 +#: pretix/control/forms/event.py:1156 #, fuzzy #| msgid "Payment received for your order: {code}" msgid "Subject (if an incomplete payment was received)" msgstr "تم إستلام الدفع لطلبك: {code}" -#: pretix/control/forms/event.py:1168 +#: pretix/control/forms/event.py:1161 #, fuzzy #| msgid "Payment received for your order: {code}" msgid "Text (if an incomplete payment was received)" msgstr "تم إستلام الدفع لطلبك: {code}" -#: pretix/control/forms/event.py:1171 +#: pretix/control/forms/event.py:1164 #, fuzzy #| msgid "This plugin allows you to receive payments via bank transfer." msgid "" @@ -13816,7 +14408,13 @@ msgid "" "payments, such as bank transfer." msgstr "يسمح لك هذا المكون الإضافي بتلقي المدفوعات عبر التحويل المصرفي." -#: pretix/control/forms/event.py:1239 +#: pretix/control/forms/event.py:1206 pretix/control/forms/event.py:1213 +msgid "" +"This will only be used if the invoice is sent to a different email address " +"or at a different time than the order confirmation." +msgstr "" + +#: pretix/control/forms/event.py:1246 msgid "" "This email will be sent out this many days before the order event starts. If " "the field is empty, the mail will never be sent." @@ -13824,31 +14422,31 @@ msgstr "" "سيتم إرسال هذا البريد الإلكتروني من هذا عدة أيام قبل أن يبدأ الحدث النظام. " "إذا كان الحقل فارغا، لن يتم إرسال البريد." -#: pretix/control/forms/event.py:1243 +#: pretix/control/forms/event.py:1250 #, fuzzy #| msgid "Received order" msgid "Subject for received order" msgstr "النظام وردت" -#: pretix/control/forms/event.py:1248 +#: pretix/control/forms/event.py:1255 #, fuzzy #| msgid "Received order" msgid "Text for received order" msgstr "النظام وردت" -#: pretix/control/forms/event.py:1253 +#: pretix/control/forms/event.py:1260 #, fuzzy #| msgid "Yes, approve order" msgid "Subject for approved order" msgstr "نعم، والموافقة على النظام" -#: pretix/control/forms/event.py:1258 +#: pretix/control/forms/event.py:1265 #, fuzzy #| msgid "Yes, approve order" msgid "Text for approved order" msgstr "نعم، والموافقة على النظام" -#: pretix/control/forms/event.py:1261 pretix/control/forms/event.py:1279 +#: pretix/control/forms/event.py:1268 pretix/control/forms/event.py:1286 msgid "" "This will only be sent out for non-free orders. Free orders will receive the " "free order template from below instead." @@ -13856,19 +14454,19 @@ msgstr "" "سيتم ارسال هذا للطلبات غير المجانية فقط. وسوف يتلقى أصحاب الطلبات المجانية " "بدلا من ذلك نموذج الطلب المجاني كما هو في الأسفل." -#: pretix/control/forms/event.py:1283 +#: pretix/control/forms/event.py:1290 #, fuzzy #| msgid "Approved free order" msgid "Subject for approved free order" msgstr "طلب مجاني معتمد" -#: pretix/control/forms/event.py:1288 +#: pretix/control/forms/event.py:1295 #, fuzzy #| msgid "Approved free order" msgid "Text for approved free order" msgstr "طلب مجاني معتمد" -#: pretix/control/forms/event.py:1291 pretix/control/forms/event.py:1309 +#: pretix/control/forms/event.py:1298 pretix/control/forms/event.py:1316 msgid "" "This will only be sent out for free orders. Non-free orders will receive the " "non-free order template from above instead." @@ -13876,103 +14474,103 @@ msgstr "" "سيتم ارسال هذا إلى الطلبات المجانية فقط. سيستلم أصحاب الطلبات غير المجانية " "نموذج الطلب غير المجاني كما هو في الأعلى." -#: pretix/control/forms/event.py:1313 +#: pretix/control/forms/event.py:1320 #, fuzzy #| msgid "Received order" msgid "Subject for denied order" msgstr "النظام وردت" -#: pretix/control/forms/event.py:1318 +#: pretix/control/forms/event.py:1325 #, fuzzy #| msgid "Denied order" msgid "Text for denied order" msgstr "أمر مرفوض" -#: pretix/control/forms/event.py:1411 +#: pretix/control/forms/event.py:1420 #, fuzzy #| msgid "Ticket code" msgid "Ticket code generator" msgstr "إنشاء رمز التذكرة" -#: pretix/control/forms/event.py:1412 +#: pretix/control/forms/event.py:1421 msgid "For advanced users, usually does not need to be changed." msgstr "" -#: pretix/control/forms/event.py:1469 +#: pretix/control/forms/event.py:1478 msgid "Any country" msgstr "أي بلد" -#: pretix/control/forms/event.py:1470 +#: pretix/control/forms/event.py:1479 msgid "European Union" msgstr "الإتحاد الأوربي" -#: pretix/control/forms/event.py:1496 +#: pretix/control/forms/event.py:1505 msgid "Any customer" msgstr "أي زبون" -#: pretix/control/forms/event.py:1497 +#: pretix/control/forms/event.py:1506 msgid "Individual" msgstr "فرد" -#: pretix/control/forms/event.py:1498 +#: pretix/control/forms/event.py:1507 msgid "Business" msgstr "اعمال" -#: pretix/control/forms/event.py:1499 +#: pretix/control/forms/event.py:1508 msgid "Business with valid VAT ID" msgstr "العمل مع معرف الضريبة على القيمة المضافة" -#: pretix/control/forms/event.py:1505 +#: pretix/control/forms/event.py:1514 msgid "Charge VAT" msgstr "تكلفة ضريبة القيمة المضافة" -#: pretix/control/forms/event.py:1507 +#: pretix/control/forms/event.py:1516 msgid "No VAT" msgstr "لا ضريبه للقيمه المضافه" -#: pretix/control/forms/event.py:1508 +#: pretix/control/forms/event.py:1517 msgid "Sale not allowed" msgstr "غير مسموح بالبيع" -#: pretix/control/forms/event.py:1509 +#: pretix/control/forms/event.py:1518 #, fuzzy #| msgid "New order requires approval" msgid "Order requires approval" msgstr "طلب جديد يتطلب الموافقة." -#: pretix/control/forms/event.py:1514 +#: pretix/control/forms/event.py:1523 #, fuzzy #| msgid "Default price" msgid "Default tax code" msgstr "السعر الافتراضي" -#: pretix/control/forms/event.py:1518 +#: pretix/control/forms/event.py:1527 #, fuzzy #| msgid "Sales tax rate" msgid "Deviating tax rate" msgstr "معدل ضريبة المبيعات" -#: pretix/control/forms/event.py:1523 pretix/control/forms/event.py:1527 +#: pretix/control/forms/event.py:1532 pretix/control/forms/event.py:1536 msgid "Text on invoice" msgstr "النص على الفاتورة" -#: pretix/control/forms/event.py:1547 +#: pretix/control/forms/event.py:1556 msgid "" "A combination of this calculation mode with a non-zero tax rate does not " "make sense." msgstr "" -#: pretix/control/forms/event.py:1552 pretix/control/forms/event.py:1556 +#: pretix/control/forms/event.py:1561 pretix/control/forms/event.py:1565 #, fuzzy #| msgid "This combination of credentials is not known to our system." msgid "This combination of calculation mode and tax code does not make sense." msgstr "مجموعة بيانات الاعتماد هذه غير معروفة لدى نظامنا." -#: pretix/control/forms/event.py:1621 +#: pretix/control/forms/event.py:1630 msgid "Pre-selected voucher" msgstr "قسيمة المختارة مسبقا" -#: pretix/control/forms/event.py:1623 +#: pretix/control/forms/event.py:1632 msgid "" "If set, the widget will show products as if this voucher has been entered " "and when a product is bought via the widget, this voucher will be used. This " @@ -13983,11 +14581,11 @@ msgstr "" "شراء المنتج عن طريق القطعة، سيتم استخدام هذه القسائم. يمكن استخدام هذا يمكن " "على سبيل المثال لتوفير الحاجيات التي تعطي تخفيض أو إلغاء المنتجات سرية." -#: pretix/control/forms/event.py:1628 +#: pretix/control/forms/event.py:1637 msgid "Compatibility mode" msgstr "وضع التوافق" -#: pretix/control/forms/event.py:1630 +#: pretix/control/forms/event.py:1639 msgid "" "Our regular widget doesn't work in all website builders. If you run into " "trouble, try using this compatibility mode." @@ -13995,28 +14593,28 @@ msgstr "" "لا تعمل لدينا القطعة العادية في جميع بناة الموقع. إذا واجهت مشكلة، حاول " "استخدام هذا الوضع التوافق." -#: pretix/control/forms/event.py:1651 +#: pretix/control/forms/event.py:1660 msgid "The given voucher code does not exist." msgstr "لا وجود رمز قسيمة معين." -#: pretix/control/forms/event.py:1658 pretix/control/forms/organizer.py:112 +#: pretix/control/forms/event.py:1667 pretix/control/forms/organizer.py:112 #: pretix/control/views/shredder.py:179 msgid "The slug you entered was not correct." msgstr "وكانت سبيكة التي أدخلتها غير صحيحة." -#: pretix/control/forms/event.py:1693 +#: pretix/control/forms/event.py:1702 msgid "Ticket downloads" msgstr "التنزيلات تذكرة" -#: pretix/control/forms/event.py:1694 +#: pretix/control/forms/event.py:1703 msgid "Your customers will be able to download their tickets in PDF format." msgstr "زبائنك سوف تكون قادرة على تحميل تذاكرهم في شكل PDF." -#: pretix/control/forms/event.py:1698 +#: pretix/control/forms/event.py:1707 msgid "Require all attendees to fill in their names" msgstr "يتطلب من جميع الحضور لملء في أسمائها" -#: pretix/control/forms/event.py:1699 +#: pretix/control/forms/event.py:1708 msgid "" "By default, we will ask for names but not require them. You can turn this " "off completely in the settings." @@ -14024,11 +14622,11 @@ msgstr "" "افتراضيا، ونحن سوف تسأل عن الأسماء ولكن لا تتطلب منهم. يمكنك إيقاف هذا تماما " "في الإعدادات." -#: pretix/control/forms/event.py:1725 +#: pretix/control/forms/event.py:1734 msgid "Payment via Stripe" msgstr "الدفع عن طريق الشريط" -#: pretix/control/forms/event.py:1726 +#: pretix/control/forms/event.py:1735 msgid "" "Stripe is an online payments processor supporting credit cards and lots of " "other payment options. To accept payments via Stripe, you will need to set " @@ -14039,11 +14637,11 @@ msgstr "" "خيارات الدفع الأخرى. لقبول الدفع عن طريق الشريط، وسوف تحتاج إلى إعداد حساب " "معهم، والتي تأخذ أقل من خمس دقائق باستخدام واجهة بسيطة بهم." -#: pretix/control/forms/event.py:1732 +#: pretix/control/forms/event.py:1741 msgid "Payment by bank transfer" msgstr "الدفع عن طريق التحويل المصرفي" -#: pretix/control/forms/event.py:1733 +#: pretix/control/forms/event.py:1742 msgid "" "Your customers will be instructed to wire the money to your account. You can " "then import your bank statements to process the payments within pretix, or " @@ -14053,16 +14651,16 @@ msgstr "" "المصرفية الخاصة بك لمعالجة المدفوعات في غضون pretix، أو وضع علامة عليها كما " "تدفع يدويا." -#: pretix/control/forms/event.py:1772 +#: pretix/control/forms/event.py:1781 #: pretix/control/templates/pretixcontrol/event/quick_setup.html:45 msgid "Price (optional)" msgstr "السعر (اختياري)" -#: pretix/control/forms/event.py:1777 +#: pretix/control/forms/event.py:1786 msgid "Free" msgstr "حر" -#: pretix/control/forms/event.py:1782 +#: pretix/control/forms/event.py:1791 msgid "Quantity available" msgstr "الكمية متاحة" @@ -14100,10 +14698,11 @@ msgid "Paid or confirmed" msgstr "تم تاكيد الطلب" #: pretix/control/forms/filter.py:217 +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:47 #: pretix/control/templates/pretixcontrol/items/question.html:28 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:19 #: pretix/control/templates/pretixcontrol/orders/overview.html:87 -#: pretix/plugins/reports/exporters.py:386 +#: pretix/plugins/reports/exporters.py:397 msgid "Pending" msgstr "قيد الانتظار" @@ -14181,7 +14780,7 @@ msgstr "موافق عليها، الدفع معلق" #: pretix/control/forms/filter.py:238 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:8 #: pretix/control/templates/pretixcontrol/orders/overview.html:79 -#: pretix/plugins/reports/exporters.py:380 +#: pretix/plugins/reports/exporters.py:391 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7 msgid "Approval pending" msgstr "في انتظار الموافقة" @@ -14194,28 +14793,28 @@ msgstr "" msgid "Follow-up due" msgstr "" -#: pretix/control/forms/filter.py:462 pretix/control/forms/filter.py:1898 -#: pretix/control/forms/filter.py:2153 pretix/control/forms/filter.py:2457 -#: pretix/control/forms/filter.py:2476 pretix/control/forms/vouchers.py:152 +#: pretix/control/forms/filter.py:462 pretix/control/forms/filter.py:1894 +#: pretix/control/forms/filter.py:2149 pretix/control/forms/filter.py:2453 +#: pretix/control/forms/filter.py:2472 pretix/control/forms/vouchers.py:151 #: pretix/control/templates/pretixcontrol/items/question.html:38 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:119 #: pretix/plugins/sendmail/models.py:251 msgid "All products" msgstr "جميع المنتجات" -#: pretix/control/forms/filter.py:466 pretix/control/forms/filter.py:2157 -#: pretix/control/forms/filter.py:2461 pretix/control/forms/vouchers.py:140 +#: pretix/control/forms/filter.py:466 pretix/control/forms/filter.py:2153 +#: pretix/control/forms/filter.py:2457 pretix/control/forms/vouchers.py:139 #: pretix/control/views/typeahead.py:657 pretix/control/views/typeahead.py:774 #, python-brace-format msgid "{product} – Any variation" msgstr "{product} - أي تباين" -#: pretix/control/forms/filter.py:530 pretix/control/forms/orders.py:852 +#: pretix/control/forms/filter.py:530 pretix/control/forms/orders.py:862 msgctxt "subevent" msgid "All dates starting at or after" msgstr "" -#: pretix/control/forms/filter.py:536 pretix/control/forms/orders.py:859 +#: pretix/control/forms/filter.py:536 pretix/control/forms/orders.py:869 msgctxt "subevent" msgid "All dates starting before" msgstr "" @@ -14256,11 +14855,11 @@ msgstr "" #: pretix/control/forms/filter.py:891 pretix/control/forms/filter.py:896 #: pretix/control/forms/filter.py:1009 pretix/control/forms/filter.py:1014 -#: pretix/control/forms/filter.py:1685 pretix/control/forms/filter.py:1690 +#: pretix/control/forms/filter.py:1683 pretix/control/forms/filter.py:1688 msgid "All organizers" msgstr "جميع المنظمين" -#: pretix/control/forms/filter.py:1001 pretix/control/forms/filter.py:1669 +#: pretix/control/forms/filter.py:1001 pretix/control/forms/filter.py:1667 msgid "All events" msgstr "كل الأحداث" @@ -14294,22 +14893,22 @@ msgstr "من تاريخ" msgid "Paid until" msgstr "حتى تاريخ" -#: pretix/control/forms/filter.py:1202 pretix/control/forms/filter.py:1671 +#: pretix/control/forms/filter.py:1202 pretix/control/forms/filter.py:1669 msgid "Shop live and presale running" msgstr "تسوق الحية و[خبر] تشغيل" -#: pretix/control/forms/filter.py:1203 pretix/control/forms/filter.py:2011 +#: pretix/control/forms/filter.py:1203 pretix/control/forms/filter.py:2007 msgid "Inactive" msgstr "غير نشط" -#: pretix/control/forms/filter.py:1204 pretix/control/forms/filter.py:1673 +#: pretix/control/forms/filter.py:1204 pretix/control/forms/filter.py:1671 #: pretix/control/templates/pretixcontrol/events/index.html:153 #: pretix/control/templates/pretixcontrol/organizers/detail.html:117 #: pretix/control/templates/pretixcontrol/subevents/index.html:170 msgid "Presale not started" msgstr "لم يبدأ البيع الأولي بعد" -#: pretix/control/forms/filter.py:1205 pretix/control/forms/filter.py:1674 +#: pretix/control/forms/filter.py:1205 pretix/control/forms/filter.py:1672 #: pretix/control/templates/pretixcontrol/events/index.html:151 #: pretix/control/templates/pretixcontrol/organizers/detail.html:115 #: pretix/control/templates/pretixcontrol/subevents/index.html:168 @@ -14317,15 +14916,15 @@ msgid "Presale over" msgstr "انتهى البيع الأولي" #: pretix/control/forms/filter.py:1210 pretix/control/forms/filter.py:1213 -#: pretix/control/forms/filter.py:1702 pretix/control/forms/filter.py:1705 -#: pretix/control/forms/filter.py:2335 +#: pretix/control/forms/filter.py:1698 pretix/control/forms/filter.py:1701 +#: pretix/control/forms/filter.py:2331 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html:84 msgid "Date from" msgstr "التاريخ من" #: pretix/control/forms/filter.py:1217 pretix/control/forms/filter.py:1220 -#: pretix/control/forms/filter.py:1709 pretix/control/forms/filter.py:1712 -#: pretix/control/forms/filter.py:2340 +#: pretix/control/forms/filter.py:1705 pretix/control/forms/filter.py:1708 +#: pretix/control/forms/filter.py:2336 msgid "Date until" msgstr "التاريخ وحتى" @@ -14346,16 +14945,16 @@ msgstr "التاريخ وحتى" msgid "Weekday" msgstr "يوم من أيام الأسبوع" -#: pretix/control/forms/filter.py:1437 pretix/control/forms/filter.py:1439 -#: pretix/control/forms/filter.py:1488 pretix/control/forms/filter.py:1490 -#: pretix/control/forms/filter.py:1560 pretix/control/forms/filter.py:1562 -#: pretix/control/forms/filter.py:1614 pretix/control/forms/filter.py:1616 -#: pretix/control/forms/filter.py:2025 pretix/control/forms/filter.py:2027 -#: pretix/control/forms/filter.py:2593 pretix/control/forms/filter.py:2595 +#: pretix/control/forms/filter.py:1435 pretix/control/forms/filter.py:1437 +#: pretix/control/forms/filter.py:1486 pretix/control/forms/filter.py:1488 +#: pretix/control/forms/filter.py:1558 pretix/control/forms/filter.py:1560 +#: pretix/control/forms/filter.py:1612 pretix/control/forms/filter.py:1614 +#: pretix/control/forms/filter.py:2021 pretix/control/forms/filter.py:2023 +#: pretix/control/forms/filter.py:2589 pretix/control/forms/filter.py:2591 msgid "Search query" msgstr "البحث في الاستفسارات" -#: pretix/control/forms/filter.py:1499 pretix/control/forms/filter.py:1571 +#: pretix/control/forms/filter.py:1497 pretix/control/forms/filter.py:1569 #: pretix/control/templates/pretixcontrol/organizers/customer.html:46 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:47 #: pretix/control/templates/pretixcontrol/organizers/giftcard_acceptance_list.html:54 @@ -14367,14 +14966,14 @@ msgstr "البحث في الاستفسارات" msgid "active" msgstr "غير نشط" -#: pretix/control/forms/filter.py:1501 +#: pretix/control/forms/filter.py:1499 #: pretix/control/templates/pretixcontrol/organizers/customer.html:44 #, fuzzy #| msgid "Deactivate" msgid "not yet activated" msgstr "إلغاء تنشيط" -#: pretix/control/forms/filter.py:1505 +#: pretix/control/forms/filter.py:1503 #: pretix/control/templates/pretixcontrol/organizers/customer.html:110 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:6 #: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:12 @@ -14382,261 +14981,265 @@ msgstr "إلغاء تنشيط" msgid "Memberships" msgstr "العضويات" -#: pretix/control/forms/filter.py:1509 +#: pretix/control/forms/filter.py:1507 #, fuzzy #| msgid "Team memberships" msgid "Has no memberships" msgstr "عضوية فريق" -#: pretix/control/forms/filter.py:1510 +#: pretix/control/forms/filter.py:1508 #, fuzzy #| msgid "Team memberships" msgid "Has any membership" msgstr "عضوية فريق" -#: pretix/control/forms/filter.py:1511 +#: pretix/control/forms/filter.py:1509 #, fuzzy #| msgid "Require a valid membership" msgid "Has valid membership" msgstr "يتتطلب عضوية سارية المفعول" -#: pretix/control/forms/filter.py:1670 +#: pretix/control/forms/filter.py:1668 msgid "Shop live" msgstr "متجر على الهواء مباشرة" -#: pretix/control/forms/filter.py:1672 +#: pretix/control/forms/filter.py:1670 msgid "Shop not live" msgstr "تسوق لا يعيش" -#: pretix/control/forms/filter.py:1675 +#: pretix/control/forms/filter.py:1673 msgid "Single event running or in the future" msgstr "حدث واحد قيد التشغيل أو في المستقبل" -#: pretix/control/forms/filter.py:1676 +#: pretix/control/forms/filter.py:1674 msgid "Single event in the past" msgstr "حدث واحد في الماضي" -#: pretix/control/forms/filter.py:1877 pretix/control/forms/filter.py:1879 +#: pretix/control/forms/filter.py:1873 pretix/control/forms/filter.py:1875 msgid "Search attendee…" msgstr "بحث الحضور ..." -#: pretix/control/forms/filter.py:1884 -#: pretix/plugins/checkinlists/exporters.py:105 +#: pretix/control/forms/filter.py:1880 +#: pretix/plugins/checkinlists/exporters.py:106 msgid "Check-in status" msgstr "تحقق ذات المركز" -#: pretix/control/forms/filter.py:1886 -#: pretix/plugins/checkinlists/exporters.py:107 +#: pretix/control/forms/filter.py:1882 +#: pretix/plugins/checkinlists/exporters.py:108 msgid "All attendees" msgstr "جميع الحاضرين" -#: pretix/control/forms/filter.py:1887 +#: pretix/control/forms/filter.py:1883 #: pretix/control/templates/pretixcontrol/checkin/index.html:183 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:96 -#: pretix/plugins/checkinlists/exporters.py:108 -#: pretix/plugins/checkinlists/exporters.py:499 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:103 +#: pretix/plugins/checkinlists/exporters.py:109 +#: pretix/plugins/checkinlists/exporters.py:500 msgid "Checked in" msgstr "إيداعه" -#: pretix/control/forms/filter.py:1888 -#: pretix/plugins/checkinlists/exporters.py:109 +#: pretix/control/forms/filter.py:1884 +#: pretix/plugins/checkinlists/exporters.py:110 msgctxt "checkin state" msgid "Present" msgstr "حاضر" -#: pretix/control/forms/filter.py:1889 -#: pretix/plugins/checkinlists/exporters.py:110 +#: pretix/control/forms/filter.py:1885 +#: pretix/plugins/checkinlists/exporters.py:111 msgctxt "checkin state" msgid "Checked in but left" msgstr "سجل لكنه غادر" -#: pretix/control/forms/filter.py:1890 +#: pretix/control/forms/filter.py:1886 #: pretix/control/templates/pretixcontrol/checkin/index.html:178 -#: pretix/plugins/checkinlists/exporters.py:111 +#: pretix/plugins/checkinlists/exporters.py:112 msgid "Not checked in" msgstr "غير محددة في" -#: pretix/control/forms/filter.py:1909 +#: pretix/control/forms/filter.py:1905 #, fuzzy #| msgid "Date from" msgctxt "subevent" msgid "Date start from" msgstr "التاريخ من" -#: pretix/control/forms/filter.py:1915 +#: pretix/control/forms/filter.py:1911 #, fuzzy #| msgid "Date until" msgctxt "subevent" msgid "Date start until" msgstr "التاريخ وحتى" -#: pretix/control/forms/filter.py:2016 pretix/control/forms/filter.py:2019 +#: pretix/control/forms/filter.py:2012 pretix/control/forms/filter.py:2015 #: pretix/control/templates/pretixcontrol/users/index.html:52 msgid "Administrator" msgstr "مدير" -#: pretix/control/forms/filter.py:2020 +#: pretix/control/forms/filter.py:2016 msgid "No administrator" msgstr "لا المسؤول" -#: pretix/control/forms/filter.py:2090 +#: pretix/control/forms/filter.py:2086 msgid "Valid" msgstr "ساري المفعول" -#: pretix/control/forms/filter.py:2091 +#: pretix/control/forms/filter.py:2087 msgid "Unredeemed" msgstr "غير معوض" -#: pretix/control/forms/filter.py:2092 +#: pretix/control/forms/filter.py:2088 msgid "Redeemed at least once" msgstr "افتدى على الأقل مرة واحدة" -#: pretix/control/forms/filter.py:2093 +#: pretix/control/forms/filter.py:2089 msgid "Fully redeemed" msgstr "افتدى بالكامل" -#: pretix/control/forms/filter.py:2095 +#: pretix/control/forms/filter.py:2091 msgid "Redeemed and checked in with ticket" msgstr "مطفأة وإيداعه مع تذكرة" -#: pretix/control/forms/filter.py:2100 +#: pretix/control/forms/filter.py:2096 msgid "Quota handling" msgstr "التعامل مع الحصص" -#: pretix/control/forms/filter.py:2104 +#: pretix/control/forms/filter.py:2100 msgid "Allow to ignore quota" msgstr "السماح لتجاهل الحصص" -#: pretix/control/forms/filter.py:2109 pretix/control/forms/filter.py:2111 +#: pretix/control/forms/filter.py:2105 pretix/control/forms/filter.py:2107 msgid "Filter by tag" msgstr "تصفية حسب العلامة" -#: pretix/control/forms/filter.py:2116 pretix/control/forms/filter.py:2118 +#: pretix/control/forms/filter.py:2112 pretix/control/forms/filter.py:2114 msgid "Search voucher" msgstr "بحث قسيمة" -#: pretix/control/forms/filter.py:2163 pretix/control/forms/vouchers.py:131 +#: pretix/control/forms/filter.py:2159 pretix/control/forms/vouchers.py:130 #: pretix/control/views/typeahead.py:782 pretix/control/views/typeahead.py:786 #: pretix/control/views/vouchers.py:132 #, python-brace-format msgid "Any product in quota \"{quota}\"" msgstr "أي منتج في الحصص \"{quota}\"" -#: pretix/control/forms/filter.py:2285 +#: pretix/control/forms/filter.py:2281 msgid "Refund status" msgstr "حالة إعادة الأموال" -#: pretix/control/forms/filter.py:2287 +#: pretix/control/forms/filter.py:2283 msgid "All open refunds" msgstr "كل مبلغ معاد المفتوحة" -#: pretix/control/forms/filter.py:2288 +#: pretix/control/forms/filter.py:2284 msgid "All refunds" msgstr "كل مبلغ معاد" -#: pretix/control/forms/filter.py:2326 pretix/plugins/reports/exporters.py:688 +#: pretix/control/forms/filter.py:2322 pretix/plugins/reports/exporters.py:699 msgid "Date filter" msgstr "تاريخ فلتر" -#: pretix/control/forms/filter.py:2328 pretix/plugins/reports/exporters.py:690 +#: pretix/control/forms/filter.py:2324 pretix/plugins/reports/exporters.py:701 msgid "Filter by…" msgstr "مصنف بواسطة…" -#: pretix/control/forms/filter.py:2330 pretix/plugins/reports/exporters.py:692 +#: pretix/control/forms/filter.py:2326 pretix/plugins/reports/exporters.py:703 msgid "Date of last successful payment" msgstr "تاريخ الدفع الناجح الماضي" -#: pretix/control/forms/filter.py:2370 +#: pretix/control/forms/filter.py:2366 #, fuzzy #| msgid "All check-in lists" msgid "All check-ins" msgstr "جميع قوائم التسجيل" -#: pretix/control/forms/filter.py:2371 +#: pretix/control/forms/filter.py:2367 #, fuzzy #| msgid "Successful payments" msgid "Successful check-ins" msgstr "المدفوعات ناجحة" -#: pretix/control/forms/filter.py:2372 +#: pretix/control/forms/filter.py:2368 #, fuzzy #| msgid "Only successful payments" msgid "Unsuccessful check-ins" msgstr "المدفوعات الناجحة فقط" -#: pretix/control/forms/filter.py:2377 +#: pretix/control/forms/filter.py:2373 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:64 -#: pretix/plugins/checkinlists/exporters.py:755 +#: pretix/plugins/checkinlists/exporters.py:756 msgid "Scan type" msgstr "نوع المسح الضوئي" -#: pretix/control/forms/filter.py:2379 +#: pretix/control/forms/filter.py:2375 #, fuzzy #| msgid "All actions" msgid "All directions" msgstr "جميع الإجراءات" -#: pretix/control/forms/filter.py:2388 pretix/control/forms/filter.py:2428 +#: pretix/control/forms/filter.py:2384 pretix/control/forms/filter.py:2424 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:67 -#: pretix/plugins/checkinlists/exporters.py:761 +#: pretix/plugins/checkinlists/exporters.py:762 msgid "Device" msgstr "جهاز" -#: pretix/control/forms/filter.py:2389 pretix/control/forms/filter.py:2424 -#: pretix/control/forms/filter.py:2615 +#: pretix/control/forms/filter.py:2385 pretix/control/forms/filter.py:2420 +#: pretix/control/forms/filter.py:2611 #, fuzzy #| msgid "All invoices" msgid "All devices" msgstr "جميع الفواتير" -#: pretix/control/forms/filter.py:2403 +#: pretix/control/forms/filter.py:2399 #, fuzzy #| msgid "Start date" msgctxt "filter" msgid "Start date" msgstr "تاريخ البداية" -#: pretix/control/forms/filter.py:2409 +#: pretix/control/forms/filter.py:2405 #, fuzzy #| msgid "End date" msgctxt "filter" msgid "End date" msgstr "تاريخ الإنتهاء" -#: pretix/control/forms/filter.py:2451 pretix/control/forms/filter.py:2455 +#: pretix/control/forms/filter.py:2447 +#: pretix/plugins/checkinlists/exporters.py:880 +msgid "All check-in lists" +msgstr "جميع قوائم التسجيل" + +#: pretix/control/forms/filter.py:2451 #: pretix/control/templates/pretixcontrol/checkin/checkins.html:64 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:10 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:25 -#: pretix/plugins/autocheckin/forms.py:179 -#: pretix/plugins/autocheckin/forms.py:183 +#: pretix/plugins/autocheckin/forms.py:182 #: pretix/plugins/autocheckin/models.py:46 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/index.html:29 -#: pretix/plugins/checkinlists/exporters.py:80 -#: pretix/plugins/checkinlists/exporters.py:153 -#: pretix/plugins/checkinlists/exporters.py:474 -#: pretix/plugins/checkinlists/exporters.py:754 -#: pretix/plugins/checkinlists/exporters.py:842 +#: pretix/plugins/checkinlists/exporters.py:81 +#: pretix/plugins/checkinlists/exporters.py:154 +#: pretix/plugins/checkinlists/exporters.py:475 +#: pretix/plugins/checkinlists/exporters.py:755 +#: pretix/plugins/checkinlists/exporters.py:843 msgid "Check-in list" msgstr "تحقق في قائمة" -#: pretix/control/forms/filter.py:2606 +#: pretix/control/forms/filter.py:2602 #: pretix/control/templates/pretixcontrol/organizers/devices.html:82 msgid "Software" msgstr "البرمجيات" -#: pretix/control/forms/filter.py:2613 +#: pretix/control/forms/filter.py:2609 #, fuzzy #| msgid "Devices" msgid "Device status" msgstr "الأجهزة" -#: pretix/control/forms/filter.py:2616 +#: pretix/control/forms/filter.py:2612 #, fuzzy #| msgid "All invoices" msgid "Active devices" msgstr "جميع الفواتير" -#: pretix/control/forms/filter.py:2617 +#: pretix/control/forms/filter.py:2613 #, fuzzy #| msgid "Revoke device access:" msgid "Revoked devices" @@ -14849,20 +15452,20 @@ msgid "" "plugins. This will be publicly available. Make sure to keep it up to date!" msgstr "" -#: pretix/control/forms/item.py:100 +#: pretix/control/forms/item.py:98 #, fuzzy #| msgid "Products in this category are add-on products" msgid "" "Products in this category are regular products displayed on the front page." msgstr "المنتجات في هذه الفئة هي منتجات إضافية" -#: pretix/control/forms/item.py:103 +#: pretix/control/forms/item.py:101 #, fuzzy #| msgid "Product category" msgid "Add-on product category" msgstr "فئة المنتج" -#: pretix/control/forms/item.py:104 +#: pretix/control/forms/item.py:102 #, fuzzy #| msgid "Products in this category are add-on products" msgid "" @@ -14870,33 +15473,38 @@ msgid "" "ons." msgstr "المنتجات في هذه الفئة هي منتجات إضافية" -#: pretix/control/forms/item.py:108 +#: pretix/control/forms/item.py:106 msgid "" "Products in this category are regular products, but are only shown in the " "cross-selling step, according to the configuration below." msgstr "" -#: pretix/control/forms/item.py:113 +#: pretix/control/forms/item.py:111 msgid "" "Products in this category are regular products displayed on the front page, " "but are additionally shown in the cross-selling step, according to the " "configuration below." msgstr "" -#: pretix/control/forms/item.py:142 pretix/control/forms/item.py:218 +#: pretix/control/forms/item.py:140 pretix/control/forms/item.py:216 msgid "This field is required" msgstr "هذه الخانة مطلوبه" -#: pretix/control/forms/item.py:220 +#: pretix/control/forms/item.py:218 msgid "Dependencies between questions are not supported during check-in." msgstr "غير معتمدة تبعيات بين الأسئلة أثناء التسجيل في مكتب الاستقبال." -#: pretix/control/forms/item.py:315 +#: pretix/control/forms/item.py:313 #, fuzzy #| msgid "All products" msgid "No products" msgstr "جميع المنتجات" +#: pretix/control/forms/item.py:353 +#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:11 +msgid "Unlimited" +msgstr "غير محدود" + #: pretix/control/forms/item.py:381 msgid "The product should exist in multiple variations" msgstr "يجب أن تكون موجودة المنتج في أشكال مختلفة" @@ -14909,72 +15517,72 @@ msgstr "" "حدد هذا الخيار على سبيل المثال للالقمصان التي تأتي في أحجام متعددة. يمكنك " "تحديد الاختلافات في الخطوة التالية." -#: pretix/control/forms/item.py:402 pretix/control/forms/item.py:727 +#: pretix/control/forms/item.py:402 pretix/control/forms/item.py:728 msgid "No category" msgstr "ليس هناك فئة" -#: pretix/control/forms/item.py:409 -msgid "No taxation" -msgstr "لا ضرائب" - -#: pretix/control/forms/item.py:411 +#: pretix/control/forms/item.py:410 msgid "Copy product information" msgstr "معلومات عن المنتج نسخة" -#: pretix/control/forms/item.py:422 +#: pretix/control/forms/item.py:419 +msgid "No taxation" +msgstr "لا ضرائب" + +#: pretix/control/forms/item.py:423 msgid "Do not add to a quota now" msgstr "لا تضيف إلى الحصة الآن" -#: pretix/control/forms/item.py:423 +#: pretix/control/forms/item.py:424 msgid "Add product to an existing quota" msgstr "إضافة منتج إلى الحصة الحالية" -#: pretix/control/forms/item.py:424 +#: pretix/control/forms/item.py:425 msgid "Create a new quota for this product" msgstr "إنشاء حصص جديدة لهذا المنتج" -#: pretix/control/forms/item.py:430 +#: pretix/control/forms/item.py:431 msgid "Quota options" msgstr "خيارات الحصص" -#: pretix/control/forms/item.py:438 +#: pretix/control/forms/item.py:439 msgid "Add to existing quota" msgstr "إضافة إلى الحصص الحالية" -#: pretix/control/forms/item.py:447 +#: pretix/control/forms/item.py:448 msgid "New quota name" msgstr "اسم الحصص الجديد" -#: pretix/control/forms/item.py:453 +#: pretix/control/forms/item.py:454 msgid "Size" msgstr "بحجم" -#: pretix/control/forms/item.py:454 +#: pretix/control/forms/item.py:455 msgid "Number of tickets" msgstr "عدد التذاكر" -#: pretix/control/forms/item.py:586 +#: pretix/control/forms/item.py:587 msgid "Quota name is required." msgstr "مطلوب اسم الحصص." -#: pretix/control/forms/item.py:591 +#: pretix/control/forms/item.py:592 msgid "Please select a quota." msgstr "يرجى تحديد الحصص." -#: pretix/control/forms/item.py:613 pretix/plugins/badges/forms.py:85 +#: pretix/control/forms/item.py:614 pretix/plugins/badges/forms.py:85 #: pretix/plugins/ticketoutputpdf/forms.py:55 msgid "(Event default)" msgstr "(الافتراضي الأحداث)" -#: pretix/control/forms/item.py:623 +#: pretix/control/forms/item.py:624 msgid "Choose automatically depending on event settings" msgstr "اختيار تلقائيا اعتمادا على إعدادات الحدث" -#: pretix/control/forms/item.py:624 +#: pretix/control/forms/item.py:625 msgid "Yes, if ticket generation is enabled in general" msgstr "نعم، يتم تمكين إذا الجيل تذكرة في عام" -#: pretix/control/forms/item.py:642 +#: pretix/control/forms/item.py:643 msgid "" "e.g. This reduced price is available for full-time students, jobless and " "people over 65. This ticket includes access to all parts of the event, " @@ -14983,27 +15591,27 @@ msgstr "" "مثلا هذا السعر المخفض متاح للطلاب بدوام كامل، والعاطلين عن العمل والناس على " "65. هذه التذكرة تشمل الوصول إلى جميع أجزاء من هذا الحدث، باستثناء منطقة VIP." -#: pretix/control/forms/item.py:686 +#: pretix/control/forms/item.py:687 msgid "" "This option is deprecated. For new products, use the newer option below that " "refers to another product instead of a quota." msgstr "" -#: pretix/control/forms/item.py:697 pretix/control/forms/item.py:713 +#: pretix/control/forms/item.py:698 pretix/control/forms/item.py:714 msgid "Shown independently of other products" msgstr "" -#: pretix/control/forms/item.py:738 +#: pretix/control/forms/item.py:739 #, fuzzy #| msgid "Canceled by customer" msgid "Date chosen by customer" msgstr "تم الإلغاء من قبل العميل" -#: pretix/control/forms/item.py:747 +#: pretix/control/forms/item.py:748 msgid "No membership granted" msgstr "" -#: pretix/control/forms/item.py:766 +#: pretix/control/forms/item.py:767 #, fuzzy #| msgid "" #| "Gift card products should not be associated with non-zero tax rates since " @@ -15015,20 +15623,20 @@ msgstr "" "يجب ألا ترتبط منتجات بطاقات الهدايا بمعدلات ضريبية غير صفرية حيث سيتم تطبيق " "ضريبة المبيعات عند استرداد بطاقة الهدايا." -#: pretix/control/forms/item.py:772 +#: pretix/control/forms/item.py:773 msgid "" "Do not set a specific validity for gift card products as it will not " "restrict the validity of the gift card. A validity of gift cards can be set " "in your organizer settings." msgstr "" -#: pretix/control/forms/item.py:791 pretix/control/forms/item.py:1058 +#: pretix/control/forms/item.py:792 pretix/control/forms/item.py:1059 msgid "" "If a valid membership is required, at least one valid membership type needs " "to be selected." msgstr "" -#: pretix/control/forms/item.py:802 +#: pretix/control/forms/item.py:803 msgid "" "Your product grants a non-transferable membership and should therefore be a " "personalized admission ticket. Otherwise customers might not be able to use " @@ -15036,19 +15644,19 @@ msgid "" "the membership type to be transferable." msgstr "" -#: pretix/control/forms/item.py:811 +#: pretix/control/forms/item.py:812 #, fuzzy #| msgid "The last payment date cannot be before the end of presale." msgid "The start of validity must be before the end of validity." msgstr "لا يمكن أن يكون تاريخ الدفع الأخير قبل نهاية فترة عرض البيع المسبق." -#: pretix/control/forms/item.py:818 +#: pretix/control/forms/item.py:819 msgid "" "You have selected dynamic validity but have not entered a time period. This " "would render the tickets unusable." msgstr "" -#: pretix/control/forms/item.py:923 +#: pretix/control/forms/item.py:924 #, python-format msgid "" "The variation \"%s\" cannot be deleted because it has already been ordered " @@ -15058,21 +15666,21 @@ msgstr "" "الاختلاف \"%s\" لا يمكن حذفها لأنه قد تم بالفعل أمر بذلك من قبل مستخدم أو " "حاليا هي في عربة المستخدم. الرجاء ضبط التباين بأنه \"غير نشطة\" بدلا من ذلك." -#: pretix/control/forms/item.py:1000 +#: pretix/control/forms/item.py:1001 #, fuzzy #| msgid "Calculate from product" msgid "Use value from product" msgstr "احسب من المنتج" -#: pretix/control/forms/item.py:1085 +#: pretix/control/forms/item.py:1086 msgid "Add-ons" msgstr "إضافات" -#: pretix/control/forms/item.py:1109 +#: pretix/control/forms/item.py:1110 msgid "You added the same add-on category twice" msgstr "لقد قمت بإضافة نفس إضافة على فئة مرتين" -#: pretix/control/forms/item.py:1154 +#: pretix/control/forms/item.py:1155 msgid "" "Be aware that setting a minimal number makes it impossible to buy this " "product if all available add-ons are sold out." @@ -15080,22 +15688,22 @@ msgstr "" "كن على علم أن تحديد أقل عدد ممكن يجعل من المستحيل لشراء هذا المنتج إذا بعت " "كل ما هو متاح من الإضافات بها." -#: pretix/control/forms/item.py:1161 +#: pretix/control/forms/item.py:1162 msgid "Bundled products" msgstr "المنتجات المجمعة" -#: pretix/control/forms/item.py:1211 +#: pretix/control/forms/item.py:1212 msgid "You added the same bundled product twice." msgstr "لقد قمت بإضافة نفس حزمة المنتج مرتين" -#: pretix/control/forms/item.py:1217 +#: pretix/control/forms/item.py:1218 #: pretix/control/templates/pretixcontrol/item/include_bundles.html:23 #: pretix/control/templates/pretixcontrol/item/include_bundles.html:50 msgid "Bundled product" msgstr "المنتجات المجمعة" -#: pretix/control/forms/item.py:1242 pretix/control/forms/orders.py:367 -#: pretix/control/forms/orders.py:557 +#: pretix/control/forms/item.py:1243 pretix/control/forms/orders.py:379 +#: pretix/control/forms/orders.py:568 msgid "inactive" msgstr "غير نشط" @@ -15153,35 +15761,78 @@ msgstr "" msgid "We were unable to resolve this hostname." msgstr "لم نتمكن من تحليل طلبك." -#: pretix/control/forms/modelimport.py:49 +#: pretix/control/forms/mapping.py:40 +#, fuzzy +#| msgid "Overview" +msgid "Overwrite" +msgstr "نظرة عامة" + +#: pretix/control/forms/mapping.py:41 +msgid "Fill if new" +msgstr "" + +#: pretix/control/forms/mapping.py:42 +msgid "Fill if empty" +msgstr "" + +#: pretix/control/forms/mapping.py:43 +#, fuzzy +#| msgid "Add me to the list" +msgid "Add to list" +msgstr "أضفني إلى القائمة" + +#: pretix/control/forms/mapping.py:50 +#, fuzzy +#| msgid "pretix Logo" +msgid "pretix field" +msgstr "pretix شعار" + +#: pretix/control/forms/modelimport.py:50 #, python-brace-format msgid "CSV column: \"{name}\"" msgstr "" -#: pretix/control/forms/modelimport.py:74 +#: pretix/control/forms/modelimport.py:76 msgid "Import mode" msgstr "وضع الاستيراد" -#: pretix/control/forms/modelimport.py:76 +#: pretix/control/forms/modelimport.py:78 msgid "Create a separate order for each line" msgstr "" -#: pretix/control/forms/modelimport.py:77 +#: pretix/control/forms/modelimport.py:79 msgid "Create one order with one position per line" msgstr "" -#: pretix/control/forms/modelimport.py:83 +#: pretix/control/forms/modelimport.py:80 +msgid "" +"Group multiple lines together into the same order based on a grouping column" +msgstr "" + +#: pretix/control/forms/modelimport.py:87 msgid "Create orders as fully paid" msgstr "أنشئ الطلبات المدفوعة كليا" -#: pretix/control/forms/modelimport.py:84 +#: pretix/control/forms/modelimport.py:88 msgid "Create orders as pending and still require payment" msgstr "" -#: pretix/control/forms/modelimport.py:88 +#: pretix/control/forms/modelimport.py:93 msgid "Create orders as test mode orders" msgstr "أنشئ الطلبات في وضع الإختبار" +#: pretix/control/forms/modelimport.py:112 +#, fuzzy +#| msgid "You cannot generate an invoice for this order." +msgid "A grouping cannot be specified for this import mode." +msgstr "لا يمكن انشاء فاتورة لهذا الطلب." + +#: pretix/control/forms/modelimport.py:114 +#, fuzzy +#| msgid "A variation needs to be set for this item." +msgid "A grouping needs to be specified for this import mode." +msgstr "يجب تعيين نوع لهذا العنصر." + #: pretix/control/forms/orders.py:85 #, fuzzy #| msgid "Confirm payment" @@ -15226,8 +15877,8 @@ msgstr "" "مكتظا بالنزلاء وكنت بعد أن باعت تذاكر أكثر مما تعدون! كما سيتم تنفيذ العملية " "بغض النظر عن إعدادات المدفوعات المتأخرة." -#: pretix/control/forms/orders.py:167 pretix/control/forms/orders.py:214 -#: pretix/control/forms/orders.py:228 +#: pretix/control/forms/orders.py:167 pretix/control/forms/orders.py:226 +#: pretix/control/forms/orders.py:240 msgid "Notify customer by email" msgstr "تنبيه العميل عن طريق البريد الإلكتروني" @@ -15247,76 +15898,93 @@ msgid "" "If you keep a fee, all positions within this order will be canceled and the " "order will be reduced to a cancellation fee. Payment and shipping fees will " "be canceled as well, so include them in your cancellation fee if you want to " -"keep them. Please always enter a gross value, tax will be calculated " -"automatically." +"keep them." msgstr "" "اذا واصلتم رسم، سيتم إلغاء جميع المناصب داخل هذا النظام وسيتم تخفيض لرسوم " "الإلغاء المدفوعة. سيتم إلغاء دفع رسوم الشحن وكذلك، لذلك تضمينها في رسوم على " "إلغاء الحجز الخاص بك إذا كنت ترغب في الاحتفاظ بها. يرجى دائما إدخال قيمة " "الإجمالية، وسيتم احتساب الضرائب تلقائيا." -#: pretix/control/forms/orders.py:181 +#: pretix/control/forms/orders.py:180 msgid "Generate cancellation for invoice" msgstr "إنشاء الإلغاء للفواتير" -#: pretix/control/forms/orders.py:186 pretix/control/forms/orders.py:218 +#: pretix/control/forms/orders.py:185 pretix/control/forms/orders.py:230 msgid "Comment (will be sent to the user)" msgstr "تعليق (سيتم إرسالها إلى المستخدم)" -#: pretix/control/forms/orders.py:187 pretix/control/forms/orders.py:219 +#: pretix/control/forms/orders.py:186 pretix/control/forms/orders.py:231 msgid "" "Will be included in the notification email when the respective placeholder " "is present in the configured email text." msgstr "" -#: pretix/control/forms/orders.py:229 +#: pretix/control/forms/orders.py:204 +msgid "" +"Please enter a gross amount. As per your event settings, the taxes will be " +"split the same way as the order positions." +msgstr "" + +#: pretix/control/forms/orders.py:209 +msgid "" +"Please enter a gross amount. As per your event settings, the default tax " +"rate will be charged." +msgstr "" + +#: pretix/control/forms/orders.py:213 +#, fuzzy +#| msgid "The event settings have been changed." +msgid "As per your event settings, no tax will be charged." +msgstr "تم تغيير إعدادات الحدث." + +#: pretix/control/forms/orders.py:241 msgid "A mail will only be sent if the order is fully paid after this." msgstr "" -#: pretix/control/forms/orders.py:236 +#: pretix/control/forms/orders.py:248 msgid "Payment amount" msgstr "دفع المبلغ" -#: pretix/control/forms/orders.py:240 +#: pretix/control/forms/orders.py:252 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:24 -#: pretix/plugins/reports/exporters.py:499 -#: pretix/plugins/reports/exporters.py:561 -#: pretix/plugins/reports/exporters.py:681 -#: pretix/plugins/reports/exporters.py:886 +#: pretix/plugins/reports/exporters.py:510 +#: pretix/plugins/reports/exporters.py:572 +#: pretix/plugins/reports/exporters.py:692 +#: pretix/plugins/reports/exporters.py:897 msgid "Payment date" msgstr "يوم الدفع او الاستحقاق" -#: pretix/control/forms/orders.py:264 +#: pretix/control/forms/orders.py:276 #, fuzzy #| msgid "Please select a valid seat." msgid "Please select some events." msgstr "الرجاء اختيار مقعد صالح." -#: pretix/control/forms/orders.py:285 +#: pretix/control/forms/orders.py:297 msgid "Re-calculate taxes" msgstr "الضرائب إعادة حساب" -#: pretix/control/forms/orders.py:288 +#: pretix/control/forms/orders.py:300 msgid "Do not re-calculate taxes" msgstr "لا تقم باعادة احتساب الضرائب" -#: pretix/control/forms/orders.py:289 +#: pretix/control/forms/orders.py:301 msgid "" "Re-calculate taxes based on address and product settings, keep gross amount " "the same." msgstr "" -#: pretix/control/forms/orders.py:290 +#: pretix/control/forms/orders.py:302 msgid "" "Re-calculate taxes based on address and product settings, keep net amount " "the same." msgstr "" -#: pretix/control/forms/orders.py:295 +#: pretix/control/forms/orders.py:307 msgid "Issue a new invoice if required" msgstr "إصدار فاتورة جديدة إذا لزم الأمر" -#: pretix/control/forms/orders.py:299 +#: pretix/control/forms/orders.py:311 msgid "" "If an invoice exists for this order and this operation would change its " "contents, the old invoice will be canceled and a new invoice will be issued." @@ -15324,33 +15992,33 @@ msgstr "" "في حالة وجود فاتورة لهذا النظام وهذا من شأنه أن عملية تغيير محتوياته، سيتم " "إلغاء الفاتورة القديمة وسيتم إصدار فاتورة جديدة." -#: pretix/control/forms/orders.py:304 +#: pretix/control/forms/orders.py:316 msgid "Notify user" msgstr "إبلاغ المستخدم" -#: pretix/control/forms/orders.py:308 +#: pretix/control/forms/orders.py:320 msgid "" "Send an email to the customer notifying that their order has been changed." msgstr "إرسال بريد إلكتروني إلى إخطار العملاء التي تم تغيير ترتيبها." -#: pretix/control/forms/orders.py:312 +#: pretix/control/forms/orders.py:324 msgid "Allow to overbook quotas when performing this operation" msgstr "السماح لحصص حجز إضافي عند تنفيذ هذه العملية" -#: pretix/control/forms/orders.py:328 +#: pretix/control/forms/orders.py:340 msgid "Add-on to" msgstr "إضافة إلى" -#: pretix/control/forms/orders.py:333 +#: pretix/control/forms/orders.py:345 #: pretix/control/templates/pretixcontrol/checkin/index.html:104 #: pretix/control/templates/pretixcontrol/order/change.html:127 #: pretix/control/views/vouchers.py:120 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:23 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:99 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:101 msgid "Seat" msgstr "مقعد" -#: pretix/control/forms/orders.py:336 +#: pretix/control/forms/orders.py:348 #: pretix/control/templates/pretixcontrol/order/change.html:182 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:5 #: pretix/control/templates/pretixcontrol/organizers/customer_membership.html:9 @@ -15360,81 +16028,81 @@ msgstr "مقعد" msgid "Membership" msgstr "عضويات" -#: pretix/control/forms/orders.py:344 +#: pretix/control/forms/orders.py:356 msgid "Including taxes, if any. Keep empty for the product's default price" msgstr "" "بما في ذلك الضرائب، إن وجدت. تبقي فارغة للحصول على السعر الافتراضي المنتج" -#: pretix/control/forms/orders.py:459 pretix/control/forms/orders.py:463 -#: pretix/control/forms/orders.py:491 pretix/control/forms/orders.py:533 -#: pretix/control/forms/orders.py:552 pretix/control/forms/orders.py:570 -#: pretix/control/forms/orders.py:598 +#: pretix/control/forms/orders.py:470 pretix/control/forms/orders.py:474 +#: pretix/control/forms/orders.py:502 pretix/control/forms/orders.py:544 +#: pretix/control/forms/orders.py:563 pretix/control/forms/orders.py:581 +#: pretix/control/forms/orders.py:609 msgid "(Unchanged)" msgstr "(دون تغيير)" -#: pretix/control/forms/orders.py:469 pretix/control/forms/orders.py:593 +#: pretix/control/forms/orders.py:480 pretix/control/forms/orders.py:604 msgid "New price (gross)" msgstr "السعر الجديد (إجمالي)" -#: pretix/control/forms/orders.py:473 +#: pretix/control/forms/orders.py:484 #, fuzzy #| msgid "Client secret" msgid "Ticket is blocked" msgstr "كلمة سر التذكرة" -#: pretix/control/forms/orders.py:478 +#: pretix/control/forms/orders.py:489 msgid "Validity start" msgstr "" -#: pretix/control/forms/orders.py:483 +#: pretix/control/forms/orders.py:494 #, fuzzy #| msgid "Valid until" msgid "Validity end" msgstr "حتى تاريخ" -#: pretix/control/forms/orders.py:495 +#: pretix/control/forms/orders.py:506 msgid "Generate a new secret" msgstr "توليد سر جديدة" -#: pretix/control/forms/orders.py:496 +#: pretix/control/forms/orders.py:507 msgid "" "This affects both the ticket secret (often used as a QR code) as well as the " "link used to individually access the ticket." msgstr "" -#: pretix/control/forms/orders.py:501 +#: pretix/control/forms/orders.py:512 msgid "Cancel this position" msgstr "إلغاء هذا المنصب" -#: pretix/control/forms/orders.py:505 +#: pretix/control/forms/orders.py:516 msgid "Split into new order" msgstr "تنقسم إلى النظام الجديد" -#: pretix/control/forms/orders.py:571 +#: pretix/control/forms/orders.py:582 msgid "(No membership)" msgstr "(لا توجد عضوية)" -#: pretix/control/forms/orders.py:602 +#: pretix/control/forms/orders.py:613 msgid "Remove this fee" msgstr "" -#: pretix/control/forms/orders.py:620 +#: pretix/control/forms/orders.py:631 msgid "" "Note that payment fees have a special semantic and might automatically be " "changed if the payment method of the order is changed." msgstr "" -#: pretix/control/forms/orders.py:628 +#: pretix/control/forms/orders.py:639 #: pretix/control/templates/pretixcontrol/order/change.html:214 #: pretix/control/templates/pretixcontrol/order/change.html:438 msgid "including all taxes" msgstr "بما في ذلك جميع الضرائب" -#: pretix/control/forms/orders.py:666 +#: pretix/control/forms/orders.py:677 msgid "Invalidate secrets" msgstr "أسرار يبطل" -#: pretix/control/forms/orders.py:667 +#: pretix/control/forms/orders.py:678 msgid "" "Regenerates the order and ticket secrets. You will need to re-send the link " "to the order page to the user and the user will need to download his tickets " @@ -15444,80 +16112,81 @@ msgstr "" "للمستخدم وسوف يحتاج المستخدم إلى تحميل تذاكر له مرة أخرى. سوف الإصدارات " "القديمة تكون غير صالحة." -#: pretix/control/forms/orders.py:724 pretix/plugins/sendmail/forms.py:196 +#: pretix/control/forms/orders.py:734 pretix/plugins/sendmail/forms.py:196 #, fuzzy #| msgid "Attach ticket files" msgid "Attach tickets" msgstr "إرفق ملفات التذكرة" -#: pretix/control/forms/orders.py:725 pretix/plugins/sendmail/forms.py:197 +#: pretix/control/forms/orders.py:735 pretix/plugins/sendmail/forms.py:197 msgid "" "Will be ignored if tickets exceed a given size limit to ensure email " "deliverability." msgstr "" -#: pretix/control/forms/orders.py:732 +#: pretix/control/forms/orders.py:742 #, fuzzy #| msgid "Attach invoices to emails" msgid "Attach invoices" msgstr "إرفق الفواتير في رسائل البريد الإلكتروني" -#: pretix/control/forms/orders.py:753 +#: pretix/control/forms/orders.py:763 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_inspect.html:20 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:30 msgid "Recipient" msgstr "مستلم" -#: pretix/control/forms/orders.py:768 +#: pretix/control/forms/orders.py:778 #, fuzzy, python-brace-format #| msgid "Attach ticket files" msgid "Attach {file}" msgstr "إرفق ملفات التذكرة" -#: pretix/control/forms/orders.py:796 +#: pretix/control/forms/orders.py:806 msgid "" "Cancel the order. All tickets will no longer work. This can not be reverted." msgstr "الغي الطلب. وجميع التذاكر لم تعد تعمل. هذا لا يمكن عاد." -#: pretix/control/forms/orders.py:797 +#: pretix/control/forms/orders.py:807 msgid "" "Mark the order as pending and allow the user to pay the open amount with " "another payment method." msgstr "" "نحتفل النظام كما المعلقة وتسمح للمستخدم لدفع المبلغ مفتوح مع طريقة دفع أخرى." -#: pretix/control/forms/orders.py:799 +#: pretix/control/forms/orders.py:809 msgid "Do nothing and keep the order as it is." msgstr "لا تفعل شيئا والحفاظ على النظام كما هو عليه." -#: pretix/control/forms/orders.py:826 +#: pretix/control/forms/orders.py:836 +#, python-brace-format msgid "The refund amount needs to be positive and less than {}." msgstr "احتياجات المبلغ المسترد لتكون إيجابية وأقل من {}." -#: pretix/control/forms/orders.py:832 +#: pretix/control/forms/orders.py:842 msgid "You need to specify an amount for a partial refund." msgstr "تحتاج إلى تحديد مبلغ للحصول على رد جزئي." -#: pretix/control/forms/orders.py:844 +#: pretix/control/forms/orders.py:854 msgid "Cancel all dates" msgstr "إلغاء جميع التواريخ" -#: pretix/control/forms/orders.py:863 +#: pretix/control/forms/orders.py:873 msgid "Automatically refund money if possible" msgstr "استرد المبلغ تلقائيا إن أمكن الأمر" -#: pretix/control/forms/orders.py:866 +#: pretix/control/forms/orders.py:876 msgid "" "Only available for payment method that support automatic refunds. Tickets " "that have been blocked (manually or by a plugin) are not auto-canceled and " "you will need to deal with them manually." msgstr "" -#: pretix/control/forms/orders.py:870 +#: pretix/control/forms/orders.py:880 msgid "Create refund in the manual refund to-do list" msgstr "" -#: pretix/control/forms/orders.py:873 +#: pretix/control/forms/orders.py:883 msgid "" "Manual refunds will be created which will be listed in the manual refund to-" "do list. When combined with the automatic refund functionally, only payments " @@ -15526,29 +16195,29 @@ msgid "" "orders by offsetting with different orders or issuing gift cards." msgstr "" -#: pretix/control/forms/orders.py:879 +#: pretix/control/forms/orders.py:889 msgid "" "Refund order value to a gift card instead instead of the original payment " "method" msgstr "" -#: pretix/control/forms/orders.py:885 +#: pretix/control/forms/orders.py:895 msgid "Gift card validity" msgstr "صلاحية بطاقة هدية" -#: pretix/control/forms/orders.py:904 +#: pretix/control/forms/orders.py:914 msgid "Keep a fixed cancellation fee per ticket" msgstr "الحفاظ على رسوم إلغاء الثابتة للتذكرة" -#: pretix/control/forms/orders.py:905 +#: pretix/control/forms/orders.py:915 msgid "Free tickets and add-on products are not counted" msgstr "لا يتم احتساب التذاكر المجانية والمنتجات المضافة" -#: pretix/control/forms/orders.py:915 +#: pretix/control/forms/orders.py:925 msgid "Keep fees" msgstr "احتفظ بالرسوم" -#: pretix/control/forms/orders.py:918 +#: pretix/control/forms/orders.py:928 msgid "" "The selected types of fees will not be refunded but instead added to the " "cancellation fee. Fees are never refunded in when an order in an event " @@ -15556,20 +16225,20 @@ msgid "" "dates." msgstr "" -#: pretix/control/forms/orders.py:924 +#: pretix/control/forms/orders.py:934 msgid "Send information via email" msgstr "أرسل المعلومات إلى البريد الإلكتروني" -#: pretix/control/forms/orders.py:930 +#: pretix/control/forms/orders.py:940 msgid "Send information to waiting list" msgstr "أرسم المعلومات إلى قائمة الإنتظار" -#: pretix/control/forms/orders.py:945 pretix/control/forms/orders.py:971 +#: pretix/control/forms/orders.py:955 pretix/control/forms/orders.py:981 #, python-brace-format msgid "Canceled: {event}" msgstr "ملغية: {event}" -#: pretix/control/forms/orders.py:956 +#: pretix/control/forms/orders.py:966 #, python-brace-format msgid "" "Hello,\n" @@ -15600,7 +16269,7 @@ msgstr "" "\n" "فريق {event}" -#: pretix/control/forms/orders.py:983 +#: pretix/control/forms/orders.py:993 #, python-brace-format msgid "" "Hello,\n" @@ -15623,24 +16292,24 @@ msgstr "" "\n" "فريق الفعالية {event}" -#: pretix/control/forms/orders.py:1015 pretix/plugins/sendmail/forms.py:115 +#: pretix/control/forms/orders.py:1025 pretix/plugins/sendmail/forms.py:115 #: pretix/plugins/sendmail/forms.py:208 msgctxt "subevent" msgid "Please either select a specific date or a date range, not both." msgstr "الرجاء اختيار يوم محدد أو تواريخ تقريبية وليس الإثنان معا." -#: pretix/control/forms/orders.py:1017 +#: pretix/control/forms/orders.py:1027 msgctxt "subevent" msgid "Please either select all dates or a date range, not both." msgstr "الرجاء اختيار كافة الأيام أو تاريخ تقريبي وليس الإثنان معا." -#: pretix/control/forms/orders.py:1019 pretix/plugins/sendmail/forms.py:117 +#: pretix/control/forms/orders.py:1029 pretix/plugins/sendmail/forms.py:117 #: pretix/plugins/sendmail/forms.py:210 msgctxt "subevent" msgid "If you set a date range, please set both a start and an end." msgstr "" -#: pretix/control/forms/orders.py:1021 +#: pretix/control/forms/orders.py:1031 msgid "Please confirm that you want to cancel ALL dates in this event series." msgstr "" @@ -15704,90 +16373,90 @@ msgid "" "limited use cases and might change at any point." msgstr "" -#: pretix/control/forms/organizer.py:593 +#: pretix/control/forms/organizer.py:596 msgid "This will be attached to every email." msgstr "سيرفق هذا مع كل بريد إلكتروني." -#: pretix/control/forms/organizer.py:685 +#: pretix/control/forms/organizer.py:688 msgctxt "webhooks" msgid "Event types" msgstr "أنواع الأحداث" -#: pretix/control/forms/organizer.py:717 +#: pretix/control/forms/organizer.py:722 msgid "Gift card value" msgstr "قيمة بطاقة هدية" -#: pretix/control/forms/organizer.py:790 +#: pretix/control/forms/organizer.py:794 #, fuzzy #| msgid "An account with this email address is already registered." msgid "An medium with this type and identifier is already registered." msgstr "هناك حساب مرتبط بهذا البريد الإلكتروني مسبقا." -#: pretix/control/forms/organizer.py:891 +#: pretix/control/forms/organizer.py:892 #, fuzzy #| msgid "An account with this email address is already registered." msgid "An account with this customer ID is already registered." msgstr "هناك حساب مرتبط بهذا البريد الإلكتروني مسبقا." -#: pretix/control/forms/organizer.py:908 +#: pretix/control/forms/organizer.py:909 #: pretix/control/templates/pretixcontrol/organizers/customer.html:61 #: pretix/presale/forms/customer.py:169 pretix/presale/forms/customer.py:493 msgid "Phone" msgstr "" -#: pretix/control/forms/organizer.py:1015 +#: pretix/control/forms/organizer.py:1016 #, fuzzy #| msgid "Target URL" msgctxt "sso_oidc" msgid "Base URL" msgstr "الرابط المستهدف" -#: pretix/control/forms/organizer.py:1019 +#: pretix/control/forms/organizer.py:1020 #, fuzzy #| msgid "Client ID" msgctxt "sso_oidc" msgid "Client ID" msgstr "هوية العميل" -#: pretix/control/forms/organizer.py:1023 +#: pretix/control/forms/organizer.py:1024 #, fuzzy #| msgid "Client secret" msgctxt "sso_oidc" msgid "Client secret" msgstr "سر العميل" -#: pretix/control/forms/organizer.py:1027 +#: pretix/control/forms/organizer.py:1028 msgctxt "sso_oidc" msgid "Scope" msgstr "" -#: pretix/control/forms/organizer.py:1028 +#: pretix/control/forms/organizer.py:1029 msgctxt "sso_oidc" msgid "Multiple scopes separated with spaces." msgstr "" -#: pretix/control/forms/organizer.py:1032 +#: pretix/control/forms/organizer.py:1033 #, fuzzy #| msgid "User profile only" msgctxt "sso_oidc" msgid "User ID field" msgstr "ملف تعريف المستخدم فقط" -#: pretix/control/forms/organizer.py:1033 +#: pretix/control/forms/organizer.py:1034 msgctxt "sso_oidc" msgid "" "We will assume that the contents of the user ID fields are unique and can " "never change for a user." msgstr "" -#: pretix/control/forms/organizer.py:1039 +#: pretix/control/forms/organizer.py:1040 #, fuzzy #| msgid "All invoices" msgctxt "sso_oidc" msgid "Email field" msgstr "جميع الفواتير" -#: pretix/control/forms/organizer.py:1040 +#: pretix/control/forms/organizer.py:1041 msgctxt "sso_oidc" msgid "" "We will assume that all email addresses received from the SSO provider are " @@ -15795,19 +16464,19 @@ msgid "" "security issues might arise." msgstr "" -#: pretix/control/forms/organizer.py:1047 +#: pretix/control/forms/organizer.py:1048 #, fuzzy #| msgid "Phone number" msgctxt "sso_oidc" msgid "Phone field" msgstr "رقم الجوال" -#: pretix/control/forms/organizer.py:1051 +#: pretix/control/forms/organizer.py:1052 msgctxt "sso_oidc" msgid "Query parameters" msgstr "" -#: pretix/control/forms/organizer.py:1052 +#: pretix/control/forms/organizer.py:1053 #, python-brace-format msgctxt "sso_oidc" msgid "" @@ -15815,25 +16484,25 @@ msgid "" "endpoint. Enter as: {example}" msgstr "" -#: pretix/control/forms/organizer.py:1113 +#: pretix/control/forms/organizer.py:1114 #, fuzzy #| msgid "A new client secret has been generated and is now effective." msgid "Invalidate old client secret and generate a new one" msgstr "تم إنشاء سر عميل جديد، وهو الآن فعال." -#: pretix/control/forms/organizer.py:1146 +#: pretix/control/forms/organizer.py:1147 #, fuzzy #| msgid "Organizer name" msgid "Organizer short name" msgstr "اسم المنظم" -#: pretix/control/forms/organizer.py:1150 +#: pretix/control/forms/organizer.py:1151 #, fuzzy #| msgid "Disable selected" msgid "Allow access to reusable media" msgstr "تعطيل المختارة" -#: pretix/control/forms/organizer.py:1151 +#: pretix/control/forms/organizer.py:1152 msgid "" "This is required if you want the other organizer to participate in a shared " "system with e.g. NFC payment chips. You should only use this option for " @@ -15842,24 +16511,28 @@ msgid "" "to interact with the media type." msgstr "" -#: pretix/control/forms/organizer.py:1167 +#: pretix/control/forms/organizer.py:1168 #, fuzzy #| msgid "The selected date does not exist in this event series." msgid "The selected organizer does not exist or cannot be invited." msgstr "التاريخ المحدد غير موجود في سلسلة الفعاليات هذه." -#: pretix/control/forms/organizer.py:1169 +#: pretix/control/forms/organizer.py:1170 #, fuzzy #| msgid "The selected organizer was not found." msgid "The selected organizer has already been invited." msgstr "لم يتم العثور على المنظم المحدد." -#: pretix/control/forms/organizer.py:1204 +#: pretix/control/forms/organizer.py:1205 #, fuzzy #| msgid "A voucher with this code already exists." msgid "A sales channel with the same identifier already exists." msgstr "يوجد كود الخصم مسبقا يحمل هذا الرمز." +#: pretix/control/forms/organizer.py:1217 +msgid "Events with active plugin" +msgstr "" + #: pretix/control/forms/renderers.py:56 #: pretix/control/templates/pretixcontrol/items/question_edit.html:139 msgctxt "form" @@ -15938,23 +16611,23 @@ msgstr "يوم عطلة نهاية الأسبوع" msgid "Keep the current values" msgstr "احتفظ بالقيمة الحالية" -#: pretix/control/forms/subevents.py:135 pretix/control/forms/subevents.py:143 +#: pretix/control/forms/subevents.py:135 pretix/control/forms/subevents.py:141 msgid "Selection contains various values" msgstr "" -#: pretix/control/forms/subevents.py:292 pretix/control/forms/subevents.py:321 +#: pretix/control/forms/subevents.py:288 pretix/control/forms/subevents.py:317 #, fuzzy #| msgid "The end of the event has to be later than its start." msgid "The end of availability should be after the start of availability." msgstr "نهاية الفعالية يجب أن تكون في وقت لاحق بعد بدايتها." -#: pretix/control/forms/subevents.py:354 +#: pretix/control/forms/subevents.py:350 #, fuzzy #| msgid "Available until" msgid "Available_until" msgstr "متاحة حتى" -#: pretix/control/forms/subevents.py:473 +#: pretix/control/forms/subevents.py:469 msgid "Exclude these dates instead of adding them." msgstr "استبعاد هذه التواريخ بدلا من إضافتها." @@ -15962,42 +16635,42 @@ msgstr "استبعاد هذه التواريخ بدلا من إضافتها." msgid "Your changes could not be saved. See below for details." msgstr "لا يمكن حفظ التغييرات. انظر أدناه للحصول على التفاصيل." -#: pretix/control/forms/vouchers.py:160 +#: pretix/control/forms/vouchers.py:159 msgid "Specific seat ID" msgstr "" -#: pretix/control/forms/vouchers.py:201 pretix/presale/forms/waitinglist.py:103 +#: pretix/control/forms/vouchers.py:200 pretix/presale/forms/waitinglist.py:103 msgid "Invalid product selected." msgstr "منتج غير صالح المحدد." -#: pretix/control/forms/vouchers.py:223 +#: pretix/control/forms/vouchers.py:225 msgid "" "The voucher only matches hidden products but you have not selected that it " "should show them." msgstr "" "قسيمة مباريات فقط المنتجات المخفية ولكن لم تقم بتحديد أنه ينبغي أن نظهر لهم." -#: pretix/control/forms/vouchers.py:262 +#: pretix/control/forms/vouchers.py:271 msgid "Codes" msgstr "رموز" -#: pretix/control/forms/vouchers.py:264 +#: pretix/control/forms/vouchers.py:273 msgid "" "Add one voucher code per line. We suggest that you copy this list and save " "it into a file." msgstr "" "إضافة رمز قسيمة واحدة في كل سطر. نقترح أن تقوم بنسخ هذه القائمة وحفظه في ملف." -#: pretix/control/forms/vouchers.py:269 +#: pretix/control/forms/vouchers.py:278 msgid "Send vouchers via email" msgstr "" -#: pretix/control/forms/vouchers.py:276 +#: pretix/control/forms/vouchers.py:285 #, python-brace-format msgid "Your voucher for {event}" msgstr "" -#: pretix/control/forms/vouchers.py:282 +#: pretix/control/forms/vouchers.py:291 #, fuzzy, python-brace-format #| msgid "" #| "Hello,\n" @@ -16039,109 +16712,109 @@ msgstr "" "تحياتنا،\n" "فريق {event}" -#: pretix/control/forms/vouchers.py:288 +#: pretix/control/forms/vouchers.py:297 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:28 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:42 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:25 msgid "Recipients" msgstr "" -#: pretix/control/forms/vouchers.py:292 +#: pretix/control/forms/vouchers.py:301 msgid "or" msgstr "" -#: pretix/control/forms/vouchers.py:296 +#: pretix/control/forms/vouchers.py:305 msgid "" "You can either supply a list of email addresses with one email address per " -"line, or the contents of a CSV file with a title column and one or more of " -"the columns \"email\", \"number\", \"name\", or \"tag\"." +"line, or the contents of a CSV file with a title row and one or more of the " +"columns \"email\", \"number\", \"name\", or \"tag\"." msgstr "" -#: pretix/control/forms/vouchers.py:330 +#: pretix/control/forms/vouchers.py:339 msgid "Maximum usages per voucher" msgstr "أقصى عدد للإستخدام لكل قسيمة" -#: pretix/control/forms/vouchers.py:333 +#: pretix/control/forms/vouchers.py:342 msgid "Number of times times EACH of these vouchers can be redeemed." msgstr "عدد مرات مرات كل من هذه القسائم يمكن استبدال." -#: pretix/control/forms/vouchers.py:347 +#: pretix/control/forms/vouchers.py:356 msgid "Specific seat IDs" msgstr "" -#: pretix/control/forms/vouchers.py:364 +#: pretix/control/forms/vouchers.py:373 msgid "CSV input needs to contain a header row in the first line." msgstr "" -#: pretix/control/forms/vouchers.py:369 +#: pretix/control/forms/vouchers.py:378 #, python-brace-format msgid "CSV parsing failed: {error}." msgstr "" -#: pretix/control/forms/vouchers.py:371 +#: pretix/control/forms/vouchers.py:380 msgid "" "CSV input was not recognized to have multiple columns, maybe you have some " "invalid quoted field in your input." msgstr "" -#: pretix/control/forms/vouchers.py:373 +#: pretix/control/forms/vouchers.py:382 #, python-brace-format msgid "CSV input needs to contain a field with the header \"{header}\"." msgstr "" -#: pretix/control/forms/vouchers.py:376 +#: pretix/control/forms/vouchers.py:385 #, python-brace-format msgid "CSV input contains an unknown field with the header \"{header}\"." msgstr "" -#: pretix/control/forms/vouchers.py:381 pretix/control/forms/vouchers.py:396 +#: pretix/control/forms/vouchers.py:390 pretix/control/forms/vouchers.py:405 #, python-brace-format msgid "{value} is not a valid email address." msgstr "" -#: pretix/control/forms/vouchers.py:390 +#: pretix/control/forms/vouchers.py:399 #, python-brace-format msgid "Invalid value in row {number}." msgstr "" -#: pretix/control/forms/vouchers.py:409 +#: pretix/control/forms/vouchers.py:418 msgid "A voucher with one of these codes already exists." msgstr "قسيمة مع واحد من هذه الرموز موجودة بالفعل." -#: pretix/control/forms/vouchers.py:416 +#: pretix/control/forms/vouchers.py:425 #, python-brace-format msgid "" "The voucher code {code} is too short. Make sure all voucher codes are at " "least {min_length} characters long." msgstr "" -#: pretix/control/forms/vouchers.py:423 +#: pretix/control/forms/vouchers.py:432 #, fuzzy, python-brace-format #| msgid "The given voucher code does not exist." msgid "The voucher code {code} appears in your list twice." msgstr "لا وجود رمز قسيمة معين." -#: pretix/control/forms/vouchers.py:427 +#: pretix/control/forms/vouchers.py:436 msgid "" "If vouchers should be sent by email, subject, message and recipients need to " "be specified." msgstr "" -#: pretix/control/forms/vouchers.py:434 +#: pretix/control/forms/vouchers.py:443 #, python-brace-format msgid "" "You generated {codes} vouchers, but entered recipients for {recp} vouchers." msgstr "" -#: pretix/control/forms/vouchers.py:439 +#: pretix/control/forms/vouchers.py:448 msgid "You need to specify as many seats as voucher codes." msgstr "" -#: pretix/control/logdisplay.py:71 pretix/control/logdisplay.py:81 +#: pretix/control/logdisplay.py:73 pretix/control/logdisplay.py:83 msgid "The order has been changed:" msgstr "تم تغيير الترتيب:" -#: pretix/control/logdisplay.py:98 +#: pretix/control/logdisplay.py:100 #, python-brace-format msgid "" "Position #{posid}: {old_item} ({old_price}) changed to {new_item} " @@ -16149,17 +16822,17 @@ msgid "" msgstr "" "موقف # {posid}: {old_item} ({old_price}) تغيرت إلى {new_item} ({new_price})." -#: pretix/control/logdisplay.py:109 +#: pretix/control/logdisplay.py:111 #, python-brace-format msgid "Position #{posid}: Used membership changed." msgstr "حالة # {posid}: تم تغيير العضوية المستخدمة." -#: pretix/control/logdisplay.py:115 +#: pretix/control/logdisplay.py:117 #, python-brace-format msgid "Position #{posid}: Seat \"{old_seat}\" changed to \"{new_seat}\"." msgstr "موقف # {posid}: مقعد \"{old_seat}\" تغير إلى \"{new_seat}\"." -#: pretix/control/logdisplay.py:125 +#: pretix/control/logdisplay.py:127 #, python-brace-format msgid "" "Position #{posid}: Event date \"{old_event}\" ({old_price}) changed to " @@ -16168,96 +16841,96 @@ msgstr "" "موقف # {posid}: تاريخ الحدث \"{old_event}\" ({old_price}) تغير الى " "\"{new_event}\" ({new_price})." -#: pretix/control/logdisplay.py:139 +#: pretix/control/logdisplay.py:141 #, python-brace-format msgid "Price of position #{posid} changed from {old_price} to {new_price}." msgstr "سعر موقف # {posid} تغير من {old_price} إلى {new_price}." -#: pretix/control/logdisplay.py:152 +#: pretix/control/logdisplay.py:154 #, python-brace-format msgid "Tax rule of position #{posid} changed from {old_rule} to {new_rule}." msgstr "وضع الضريبة {posid} تغير من {old_rule}إلى{new_rule}" -#: pretix/control/logdisplay.py:158 +#: pretix/control/logdisplay.py:160 #, python-brace-format msgid "Tax rule of fee #{fee} changed from {old_rule} to {new_rule}." msgstr "رسوم الضريبة {fee}تغيرت من {old_rule}إلى{new_rule}." -#: pretix/control/logdisplay.py:168 +#: pretix/control/logdisplay.py:170 msgid "A fee has been added" msgstr "تمت إضافة رسوم" -#: pretix/control/logdisplay.py:176 +#: pretix/control/logdisplay.py:178 #, python-brace-format msgid "A fee was changed from {old_price} to {new_price}." msgstr "" -#: pretix/control/logdisplay.py:187 +#: pretix/control/logdisplay.py:189 #, python-brace-format msgid "A fee of {old_price} was removed." msgstr "" -#: pretix/control/logdisplay.py:200 +#: pretix/control/logdisplay.py:202 #, python-brace-format msgid "Position #{posid} ({old_item}, {old_price}) canceled." msgstr "موقف # {posid} ({old_item}، {old_price}) الملغاة." -#: pretix/control/logdisplay.py:217 +#: pretix/control/logdisplay.py:219 #, python-brace-format msgid "" "Position #{posid} created: {item} ({price}) as an add-on to position " "#{addon_to}." msgstr "موقف # {posid} الانشاء: {item} ({price}) كإضافة إلى موقف # {addon_to}." -#: pretix/control/logdisplay.py:223 +#: pretix/control/logdisplay.py:225 #, python-brace-format msgid "Position #{posid} created: {item} ({price})." msgstr "موقف # {posid} الانشاء: {item} ({price})." -#: pretix/control/logdisplay.py:233 +#: pretix/control/logdisplay.py:235 #, python-brace-format msgid "A new secret has been generated for position #{posid}." msgstr "تم إنشاء سر جديد لموقف # {posid}." -#: pretix/control/logdisplay.py:241 +#: pretix/control/logdisplay.py:243 #, fuzzy, python-brace-format #| msgid "This order position has been canceled." msgid "" "The validity start date for position #{posid} has been changed to {value}." msgstr "تم إلغاء وضع الطلب هذا." -#: pretix/control/logdisplay.py:253 +#: pretix/control/logdisplay.py:255 #, fuzzy, python-brace-format #| msgid "This order position has been canceled." msgid "" "The validity end date for position #{posid} has been changed to {value}." msgstr "تم إلغاء وضع الطلب هذا." -#: pretix/control/logdisplay.py:262 +#: pretix/control/logdisplay.py:264 #, fuzzy, python-brace-format #| msgid "A new secret has been generated for position #{posid}." msgid "A block has been added for position #{posid}." msgstr "تم إنشاء سر جديد لموقف # {posid}." -#: pretix/control/logdisplay.py:268 +#: pretix/control/logdisplay.py:270 #, fuzzy, python-brace-format #| msgid "A new secret has been generated for position #{posid}." msgid "A block has been removed for position #{posid}." msgstr "تم إنشاء سر جديد لموقف # {posid}." -#: pretix/control/logdisplay.py:285 +#: pretix/control/logdisplay.py:287 #, python-brace-format msgid "" "Position #{posid} ({old_item}, {old_price}) split into new order: {order}" msgstr "" "موقف #{posid} ({old_item}، {old_price}) تنقسم إلى النظام الجديد: {order}" -#: pretix/control/logdisplay.py:304 +#: pretix/control/logdisplay.py:306 #, python-brace-format msgid "This order has been created by splitting the order {order}" msgstr "تم إنشاء هذا النظام من خلال تقسيم ترتيب {order}" -#: pretix/control/logdisplay.py:311 +#: pretix/control/logdisplay.py:313 #, python-brace-format msgid "" "Unknown scan of code \"{barcode}…\" at {datetime} for list \"{list}\", type " @@ -16266,13 +16939,13 @@ msgstr "" "تم مسح رمز غير محدد\"{barcode}...\" في \"{datetime}\"لقائمة\"{list}" "\"نوع\"{type}\"." -#: pretix/control/logdisplay.py:312 +#: pretix/control/logdisplay.py:314 #, python-brace-format msgid "" "Unknown scan of code \"{barcode}…\" for list \"{list}\", type \"{type}\"." msgstr "تم مسح رمز غير معروف\"{barcode}...\" لقائمة{list}، نوع\"{type}\"." -#: pretix/control/logdisplay.py:315 +#: pretix/control/logdisplay.py:317 #, fuzzy, python-brace-format #| msgid "" #| "Scan scan of revoked code \"{barcode}…\" at {datetime} for list \"{list}" @@ -16284,14 +16957,14 @@ msgstr "" "تم تحديث مسح الرمز الملغي\"{barcode}...\"في {datetime}للقائمة\"{list}\"، " "نوع\"{type}\"." -#: pretix/control/logdisplay.py:316 +#: pretix/control/logdisplay.py:318 #, python-brace-format msgid "" "Scan of revoked code \"{barcode}\" for list \"{list}\", type \"{type}\", was " "uploaded." msgstr "تم تحديث مسح رمز ملغى\"{barcode}\"لقائمة\"{list}\"، نوع\"{type}\"" -#: pretix/control/logdisplay.py:319 +#: pretix/control/logdisplay.py:321 #, python-brace-format msgid "" "Denied scan of position #{posid} at {datetime} for list \"{list}\", type " @@ -16300,7 +16973,7 @@ msgstr "" "تم رفض مسح الحالة#{posid}في{datetime}لقائمة\"{list}\"نوع\"{type}\"خطأ " "الرمز\"{errorcode}\"." -#: pretix/control/logdisplay.py:320 +#: pretix/control/logdisplay.py:322 #, python-brace-format msgid "" "Denied scan of position #{posid} for list \"{list}\", type \"{type}\", error " @@ -16308,39 +16981,83 @@ msgid "" msgstr "" "رفض نسح الحالة#{posid}قائمة\"{list}\"،نوع\"{type}\"خطأ الرمز\"{errorcode}\"." -#: pretix/control/logdisplay.py:322 pretix/control/logdisplay.py:323 +#: pretix/control/logdisplay.py:325 +#, fuzzy, python-brace-format +#| msgid "" +#| "Denied scan of position #{posid} at {datetime} for list \"{list}\", type " +#| "\"{type}\", error code \"{errorcode}\"." +msgid "" +"Annulled scan of position #{posid} at {datetime} for list \"{list}\", type " +"\"{type}\"." +msgstr "" +"تم رفض مسح الحالة#{posid}في{datetime}لقائمة\"{list}\"نوع\"{type}\"خطأ " +"الرمز\"{errorcode}\"." + +#: pretix/control/logdisplay.py:326 +#, fuzzy, python-brace-format +#| msgid "" +#| "Denied scan of position #{posid} for list \"{list}\", type \"{type}\", " +#| "error code \"{errorcode}\"." +msgid "" +"Annulled scan of position #{posid} for list \"{list}\", type \"{type}\"." +msgstr "" +"رفض نسح الحالة#{posid}قائمة\"{list}\"،نوع\"{type}\"خطأ الرمز\"{errorcode}\"." + +#: pretix/control/logdisplay.py:329 +#, fuzzy, python-brace-format +#| msgid "" +#| "Denied scan of position #{posid} at {datetime} for list \"{list}\", type " +#| "\"{type}\", error code \"{errorcode}\"." +msgid "" +"Ignored annulment of position #{posid} at {datetime} for list \"{list}\", " +"type \"{type}\"." +msgstr "" +"تم رفض مسح الحالة#{posid}في{datetime}لقائمة\"{list}\"نوع\"{type}\"خطأ " +"الرمز\"{errorcode}\"." + +#: pretix/control/logdisplay.py:330 +#, fuzzy, python-brace-format +#| msgid "" +#| "Denied scan of position #{posid} for list \"{list}\", type \"{type}\", " +#| "error code \"{errorcode}\"." +msgid "" +"Ignored annulment of position #{posid} for list \"{list}\", type \"{type}\"." +msgstr "" +"رفض نسح الحالة#{posid}قائمة\"{list}\"،نوع\"{type}\"خطأ الرمز\"{errorcode}\"." + +#: pretix/control/logdisplay.py:332 pretix/control/logdisplay.py:333 #, python-brace-format msgid "The check-in of position #{posid} on list \"{list}\" has been reverted." msgstr "في الاختيار من موقف # {posid} على قائمة \"{list}\" وقد عادت." -#: pretix/control/logdisplay.py:343 pretix/control/logdisplay.py:345 -#: pretix/control/logdisplay.py:887 pretix/control/logdisplay.py:889 +#: pretix/control/logdisplay.py:353 pretix/control/logdisplay.py:355 +#: pretix/control/logdisplay.py:968 pretix/control/logdisplay.py:970 msgid "(unknown)" msgstr "(غير معروف)" -#: pretix/control/logdisplay.py:365 +#: pretix/control/logdisplay.py:375 #, python-brace-format msgid "" "Position #{posid} has been checked out at {datetime} for list \"{list}\"." msgstr "حالة # {posid} تم التحقق في {datetime} للقائمة \"{list}\"." -#: pretix/control/logdisplay.py:366 +#: pretix/control/logdisplay.py:376 #, python-brace-format msgid "Position #{posid} has been checked out for list \"{list}\"." msgstr "حالة # {posid} تم التحقق للقائمة \"{list}\"." -#: pretix/control/logdisplay.py:370 +#: pretix/control/logdisplay.py:380 #, python-brace-format msgid "" "Position #{posid} has been checked in at {datetime} for list \"{list}\"." msgstr "موقف # {posid} تم إيداعه في {datetime} لقائمة \"{list}\"." -#: pretix/control/logdisplay.py:371 +#: pretix/control/logdisplay.py:381 #, python-brace-format msgid "Position #{posid} has been checked in for list \"{list}\"." msgstr "وقد تم التحقق من موقف # {posid} في لائحة \"{list}\"." -#: pretix/control/logdisplay.py:375 +#: pretix/control/logdisplay.py:385 #, python-brace-format msgid "" "A scan for position #{posid} at {datetime} for list \"{list}\" has been " @@ -16349,7 +17066,7 @@ msgstr "" "تفحص لموقف #{posid} في{datetime} لقائمة \"{list}\" تم تحميلها حتى لو تم " "مسحها بالفعل." -#: pretix/control/logdisplay.py:381 +#: pretix/control/logdisplay.py:391 #, python-brace-format msgid "" "Position #{posid} has been scanned and rejected because it has already been " @@ -16358,199 +17075,252 @@ msgstr "" "موقف #{posid} تم مسحها ضوئيا ورفض لأنه قد تم فحصها من قبل على قائمة \"{list}" "\"." -#: pretix/control/logdisplay.py:392 +#: pretix/control/logdisplay.py:402 +#, python-brace-format msgid "The user confirmed the following message: \"{}\"" msgstr "أكد المستخدم الرسالة التالية: \"{}\"" -#: pretix/control/logdisplay.py:404 +#: pretix/control/logdisplay.py:414 #, fuzzy, python-brace-format #| msgid "The order has been denied." msgid "The order has been canceled (comment: \"{comment}\")." msgstr "تم رفض الطلب." -#: pretix/control/logdisplay.py:406 pretix/control/views/orders.py:1574 +#: pretix/control/logdisplay.py:416 pretix/control/views/orders.py:1561 #: pretix/presale/views/order.py:1049 msgid "The order has been canceled." msgstr "تم إلغاء هذا الأمر." -#: pretix/control/logdisplay.py:414 +#: pretix/control/logdisplay.py:424 #, fuzzy, python-brace-format #| msgid "" #| "Position #{posid} has been checked in at {datetime} for list \"{list}\"." msgid "Position #{posid} has been printed at {datetime} with type \"{type}\"." msgstr "موقف # {posid} تم إيداعه في {datetime} لقائمة \"{list}\"." -#: pretix/control/logdisplay.py:428 pretix/control/logdisplay.py:737 +#: pretix/control/logdisplay.py:446 +#, python-brace-format +msgid "Data successfully transferred to {provider_display_name}." +msgstr "" + +#: pretix/control/logdisplay.py:465 +#, python-brace-format +msgid "" +"Transferring data to {provider_display_name} failed due to invalid " +"configuration:" +msgstr "" + +#: pretix/control/logdisplay.py:466 +#, python-brace-format +msgid "" +"Maximum number of retries exceeded while transferring data to " +"{provider_display_name}:" +msgstr "" + +#: pretix/control/logdisplay.py:467 +#, python-brace-format +msgid "Error while transferring data to {provider_display_name}:" +msgstr "" + +#: pretix/control/logdisplay.py:468 pretix/control/logdisplay.py:469 +#, python-brace-format +msgid "Internal error while transferring data to {provider_display_name}." +msgstr "" + +#: pretix/control/logdisplay.py:483 pretix/control/logdisplay.py:818 msgid "The settings of a payment provider have been changed." msgstr "تم تغيير الإعدادات من مقدم الدفع." -#: pretix/control/logdisplay.py:431 pretix/control/logdisplay.py:736 +#: pretix/control/logdisplay.py:486 pretix/control/logdisplay.py:817 msgid "The settings of a ticket output provider have been changed." msgstr "تم تغيير إعدادات مزود الناتج التذاكر." -#: pretix/control/logdisplay.py:437 +#: pretix/control/logdisplay.py:492 #, fuzzy #| msgid "Blocked Seats" msgid "Blocked manually" msgstr "المقاعد المحجوبة" -#: pretix/control/logdisplay.py:439 +#: pretix/control/logdisplay.py:494 msgid "Blocked because of an API integration" msgstr "" -#: pretix/control/logdisplay.py:443 +#: pretix/control/logdisplay.py:498 #, python-brace-format msgid "The test mode order {code} has been deleted." msgstr "تم حذف أجل وضع الاختبار {code}." -#: pretix/control/logdisplay.py:444 +#: pretix/control/logdisplay.py:499 msgid "The order details have been changed." msgstr "تم تغيير تفاصيل النظام." -#: pretix/control/logdisplay.py:445 +#: pretix/control/logdisplay.py:500 msgid "The order has been marked as unpaid." msgstr "تم وضع علامة على النظام وبدون أجر." -#: pretix/control/logdisplay.py:446 +#: pretix/control/logdisplay.py:501 msgid "The order's secret has been changed." msgstr "تم تغيير سر النظام و." -#: pretix/control/logdisplay.py:447 +#: pretix/control/logdisplay.py:502 msgid "The order's expiry date has been changed." msgstr "تم تغيير تاريخ انتهاء النظام و." -#: pretix/control/logdisplay.py:448 +#: pretix/control/logdisplay.py:503 #, fuzzy #| msgid "The order has been marked as paid." msgid "The order has been set to be usable before it is paid." msgstr "تم وضع علامة على الترتيب كما المدفوعة." -#: pretix/control/logdisplay.py:449 +#: pretix/control/logdisplay.py:504 #, fuzzy #| msgid "The voucher has been sent to {recipient}." msgid "The order has been set to require payment before use." msgstr "تم إرسال كود الخصم إلى {recipient}." -#: pretix/control/logdisplay.py:450 pretix/control/views/orders.py:1579 +#: pretix/control/logdisplay.py:505 pretix/control/views/orders.py:1566 msgid "The order has been marked as expired." msgstr "تم وضع علامة على النظام ومنتهية الصلاحية." -#: pretix/control/logdisplay.py:451 pretix/control/views/orders.py:1477 +#: pretix/control/logdisplay.py:506 pretix/control/views/orders.py:1465 msgid "The order has been marked as paid." msgstr "تم وضع علامة على الترتيب كما المدفوعة." -#: pretix/control/logdisplay.py:452 +#: pretix/control/logdisplay.py:507 msgid "The cancellation request has been deleted." msgstr "تم حذف طلب الإلغاء." -#: pretix/control/logdisplay.py:453 +#: pretix/control/logdisplay.py:508 msgid "The order has been refunded." msgstr "وقد تم ترتيب ردها." -#: pretix/control/logdisplay.py:454 pretix/control/views/orders.py:1862 +#: pretix/control/logdisplay.py:509 pretix/control/views/orders.py:1882 msgid "The order has been reactivated." msgstr "تم إعادة تنشيط الطلب." -#: pretix/control/logdisplay.py:455 +#: pretix/control/logdisplay.py:510 msgid "The order has been created." msgstr "تم إنشاء هذا الأمر." -#: pretix/control/logdisplay.py:457 +#: pretix/control/logdisplay.py:512 msgid "The order requires approval before it can continue to be processed." msgstr "الأمر يتطلب موافقة قبل أن تتمكن من الاستمرار في معالجتها." -#: pretix/control/logdisplay.py:458 pretix/control/views/orders.py:801 +#: pretix/control/logdisplay.py:513 pretix/control/views/orders.py:786 msgid "The order has been approved." msgstr "تمت الموافقة على النظام." -#: pretix/control/logdisplay.py:459 +#: pretix/control/logdisplay.py:514 #, fuzzy, python-brace-format #| msgid "The order has been denied." msgid "The order has been denied (comment: \"{comment}\")." msgstr "تم رفض الطلب." -#: pretix/control/logdisplay.py:460 +#: pretix/control/logdisplay.py:515 #, python-brace-format msgid "" "The email address has been changed from \"{old_email}\" to \"{new_email}\"." msgstr "" "تم تغيير عنوان البريد الإلكتروني من \"{old_email}\" إلى \"{new_email}\"." -#: pretix/control/logdisplay.py:463 +#: pretix/control/logdisplay.py:518 msgid "" "The email address has been confirmed to be working (the user clicked on a " "link in the email for the first time)." msgstr "" -#: pretix/control/logdisplay.py:465 +#: pretix/control/logdisplay.py:520 #, python-brace-format msgid "" "The phone number has been changed from \"{old_phone}\" to \"{new_phone}\"." msgstr "تم تغيير رقم الهاتف من\"{old_phone}\"إلى\"{new_phone}\"." -#: pretix/control/logdisplay.py:467 +#: pretix/control/logdisplay.py:522 msgid "The customer account has been changed." msgstr "تم تغيير حساب العميل." -#: pretix/control/logdisplay.py:468 +#: pretix/control/logdisplay.py:523 msgid "The order locale has been changed." msgstr "تم تغيير لغة النظام." -#: pretix/control/logdisplay.py:469 pretix/control/views/orders.py:1618 +#: pretix/control/logdisplay.py:524 pretix/control/views/orders.py:1605 #: pretix/presale/views/order.py:741 pretix/presale/views/order.py:814 msgid "The invoice has been generated." msgstr "تم إنشاء الفاتورة." -#: pretix/control/logdisplay.py:470 pretix/control/views/orders.py:1689 +#: pretix/control/logdisplay.py:525 pretix/control/views/orders.py:1678 msgid "The invoice has been regenerated." msgstr "تم إعادة إنشاء الفاتورة." -#: pretix/control/logdisplay.py:471 pretix/control/views/orders.py:1720 +#: pretix/control/logdisplay.py:526 pretix/control/views/orders.py:1740 #: pretix/presale/views/order.py:827 msgid "The invoice has been reissued." msgstr "تم إعادة إصدار الفاتورة." -#: pretix/control/logdisplay.py:472 +#: pretix/control/logdisplay.py:527 +#, fuzzy, python-brace-format +#| msgid "The invite has been resent." +msgid "The invoice {full_invoice_no} has been sent." +msgstr "وكان يستاء دعوة." + +#: pretix/control/logdisplay.py:528 +#, python-brace-format +msgid "The transmission of invoice {full_invoice_no} has failed." +msgstr "" + +#: pretix/control/logdisplay.py:529 +#, python-brace-format +msgid "" +"Invoice {full_invoice_no} has not been transmitted because the transmission " +"provider does not support test mode invoices." +msgstr "" + +#: pretix/control/logdisplay.py:531 +#, python-brace-format +msgid "The invoice {full_invoice_no} has been scheduled for retransmission." +msgstr "" + +#: pretix/control/logdisplay.py:532 msgid "The order's internal comment has been updated." msgstr "تم تحديث تعليق الداخلي النظام و." -#: pretix/control/logdisplay.py:473 +#: pretix/control/logdisplay.py:533 #, fuzzy #| msgid "The order of items has been updated." msgid "The order's follow-up date has been updated." msgstr "تم تحديث ترتيب العناصر." -#: pretix/control/logdisplay.py:474 +#: pretix/control/logdisplay.py:534 msgid "The order's flag to require attention at check-in has been toggled." msgstr "تم تبديل عند النقر علم النظام وبحاجة إلى اهتمام في الاختيار." -#: pretix/control/logdisplay.py:476 +#: pretix/control/logdisplay.py:536 #, fuzzy #| msgid "The order's secret has been changed." msgid "The order's check-in text has been changed." msgstr "تم تغيير سر النظام و." -#: pretix/control/logdisplay.py:477 +#: pretix/control/logdisplay.py:537 #, fuzzy #| msgid "The order's flag to require attention at check-in has been toggled." msgid "" "The order's flag to be considered valid even if unpaid has been toggled." msgstr "تم تبديل عند النقر علم النظام وبحاجة إلى اهتمام في الاختيار." -#: pretix/control/logdisplay.py:479 +#: pretix/control/logdisplay.py:539 #, python-brace-format msgid "A new payment {local_id} has been started instead of the previous one." msgstr "وقد بدأ دفعة جديدة {local_id} بدلا من سابقتها." -#: pretix/control/logdisplay.py:480 +#: pretix/control/logdisplay.py:540 msgid "An unidentified type email has been sent." msgstr "تم ارسال نوع البريد الإلكتروني مجهول." -#: pretix/control/logdisplay.py:481 pretix/control/logdisplay.py:666 +#: pretix/control/logdisplay.py:541 pretix/control/logdisplay.py:727 msgid "Sending of an email has failed." msgstr "ارسال بريد الكتروني قد فشلت." -#: pretix/control/logdisplay.py:482 +#: pretix/control/logdisplay.py:542 #, fuzzy #| msgid "" #| "The email has been sent without attachments since they would have been " @@ -16562,62 +17332,68 @@ msgstr "" "تم إرسال البريد الإلكتروني دون المرفقات لأنها كان يمكن أن يكون كبيرا جدا " "ليكون من المرجح أن يصل." -#: pretix/control/logdisplay.py:484 +#: pretix/control/logdisplay.py:544 +#, fuzzy +#| msgid "A custom email has been sent." +msgid "An invoice email has been sent." +msgstr "تم إرسال البريد الإلكتروني المخصص." + +#: pretix/control/logdisplay.py:545 msgid "A custom email has been sent." msgstr "تم إرسال البريد الإلكتروني المخصص." -#: pretix/control/logdisplay.py:485 +#: pretix/control/logdisplay.py:546 msgid "A custom email has been sent to an attendee." msgstr "تم إرسال البريد الإلكتروني المخصص لحاضر." -#: pretix/control/logdisplay.py:486 +#: pretix/control/logdisplay.py:547 msgid "" "An email has been sent with a reminder that the ticket is available for " "download." msgstr "وقد أرسلت رسالة بالبريد الالكتروني مع التذكير بأن تذكرة يتوفر للتحميل." -#: pretix/control/logdisplay.py:488 +#: pretix/control/logdisplay.py:549 msgid "" "An email has been sent with a warning that the order is about to expire." msgstr "" "وقد أرسلت رسالة بالبريد الالكتروني مع تحذير بأن النظام على وشك الانتهاء." -#: pretix/control/logdisplay.py:491 +#: pretix/control/logdisplay.py:552 msgid "" "An email has been sent to notify the user that the order has been canceled." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم التي تم إلغاء الطلب." -#: pretix/control/logdisplay.py:492 +#: pretix/control/logdisplay.py:553 msgid "" "An email has been sent to notify the user that the event has been canceled." msgstr "تم إرسال بريد إلكتروني لإعلام المستخدم بإلغاء الفعالية." -#: pretix/control/logdisplay.py:495 +#: pretix/control/logdisplay.py:556 msgid "" "An email has been sent to notify the user that the order has been changed." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم التي تم تغيير النظام." -#: pretix/control/logdisplay.py:497 +#: pretix/control/logdisplay.py:558 msgid "" "An email has been sent to notify the user that the order has been received." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم الذي تم استلام النظام." -#: pretix/control/logdisplay.py:499 +#: pretix/control/logdisplay.py:560 msgid "" "An email has been sent to notify the user that payment has been received." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم الذي تم استلام المبلغ." -#: pretix/control/logdisplay.py:501 +#: pretix/control/logdisplay.py:562 msgid "" "An email has been sent to notify the user that the order has been denied." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم التي تم رفض الطلب." -#: pretix/control/logdisplay.py:502 +#: pretix/control/logdisplay.py:563 msgid "" "An email has been sent to notify the user that the order has been approved." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم أن تمت الموافقة على النظام." -#: pretix/control/logdisplay.py:505 +#: pretix/control/logdisplay.py:566 msgid "" "An email has been sent to notify the user that the order has been received " "and requires payment." @@ -16625,7 +17401,7 @@ msgstr "" "وقد تم إرسال بريد إلكتروني لإعلام المستخدم الذي تم استلام النظام ويتطلب " "الدفع." -#: pretix/control/logdisplay.py:506 +#: pretix/control/logdisplay.py:567 msgid "" "An email has been sent to notify the user that the order has been received " "and requires approval." @@ -16633,29 +17409,25 @@ msgstr "" "وقد تم إرسال بريد إلكتروني لإعلام المستخدم الذي تم استلام النظام، ويتطلب " "موافقة عليها." -#: pretix/control/logdisplay.py:509 +#: pretix/control/logdisplay.py:570 msgid "" "An email with a link to the order detail page has been resent to the user." msgstr "" "وكانت رسائل البريد الإلكتروني مع رابط إلى صفحة التفاصيل النظام تستاء إلى " "المستخدم." -#: pretix/control/logdisplay.py:510 +#: pretix/control/logdisplay.py:571 #, fuzzy #| msgid "" #| "An email has been sent to notify the user that payment has been received." msgid "An email has been sent to notify the user that the payment failed." msgstr "وقد تم إرسال بريد إلكتروني لإعلام المستخدم الذي تم استلام المبلغ." -#: pretix/control/logdisplay.py:517 +#: pretix/control/logdisplay.py:578 msgid "The voucher has been created." msgstr "تم إنشاء قسيمة." -#: pretix/control/logdisplay.py:519 -msgid "The voucher has been created and sent to a person on the waiting list." -msgstr "تم إنشاء قسيمة وإرسالها إلى شخص على قائمة الانتظار." - -#: pretix/control/logdisplay.py:521 +#: pretix/control/logdisplay.py:581 #, fuzzy #| msgid "A voucher has been sent to a person on the waiting list." msgid "" @@ -16663,838 +17435,853 @@ msgid "" "from the waiting list." msgstr "تم إرسال قسيمة لشخص على قائمة الانتظار." -#: pretix/control/logdisplay.py:522 +#: pretix/control/logdisplay.py:582 msgid "The voucher has been changed." msgstr "تم تغيير قسيمة." -#: pretix/control/logdisplay.py:523 +#: pretix/control/logdisplay.py:583 msgid "The voucher has been deleted." msgstr "تم حذف قسيمة." -#: pretix/control/logdisplay.py:532 +#: pretix/control/logdisplay.py:584 +#, fuzzy, python-brace-format +#| msgid "A voucher has been sent to a person on the waiting list." +msgid "The voucher has been sent to {email} through the waiting list." +msgstr "تم إرسال قسيمة لشخص على قائمة الانتظار." + +#: pretix/control/logdisplay.py:593 #, python-brace-format msgid "The voucher has been redeemed in order {order_code}." msgstr "تم استبدال القسيمة من أجل {order_code}." -#: pretix/control/logdisplay.py:547 +#: pretix/control/logdisplay.py:608 msgid "The category has been added." msgstr "تمت إضافة فئة." -#: pretix/control/logdisplay.py:548 +#: pretix/control/logdisplay.py:609 msgid "The category has been deleted." msgstr "تم حذف الفئة." -#: pretix/control/logdisplay.py:549 +#: pretix/control/logdisplay.py:610 msgid "The category has been changed." msgstr "تم تغيير الفئة." -#: pretix/control/logdisplay.py:550 +#: pretix/control/logdisplay.py:611 #, fuzzy #| msgid "The category has been deleted." msgid "The category has been reordered." msgstr "تم حذف الفئة." -#: pretix/control/logdisplay.py:557 +#: pretix/control/logdisplay.py:618 msgid "The tax rule has been added." msgstr "تمت إضافة القاعدة الضريبية." -#: pretix/control/logdisplay.py:558 +#: pretix/control/logdisplay.py:619 msgid "The tax rule has been deleted." msgstr "تم حذف حكم الضرائب." -#: pretix/control/logdisplay.py:559 +#: pretix/control/logdisplay.py:620 msgid "The tax rule has been changed." msgstr "تم تغيير القاعدة الضريبية." -#: pretix/control/logdisplay.py:571 +#: pretix/control/logdisplay.py:632 #, python-brace-format msgid "{user} has been added to the team." msgstr "{user} قد أضيفت إلى الفريق." -#: pretix/control/logdisplay.py:572 +#: pretix/control/logdisplay.py:633 #, python-brace-format msgid "{user} has been removed from the team." msgstr "{user} تمت إزالته من الفريق." -#: pretix/control/logdisplay.py:573 +#: pretix/control/logdisplay.py:634 #, python-brace-format msgid "{user} has been invited to the team." msgstr "{user} وقد وجهت الدعوة للفريق." -#: pretix/control/logdisplay.py:574 +#: pretix/control/logdisplay.py:635 #, python-brace-format msgid "Invite for {user} has been resent." msgstr "دعوة ل{user} لديه كان يستاء." -#: pretix/control/logdisplay.py:585 +#: pretix/control/logdisplay.py:646 #, python-brace-format msgid "{user} has joined the team using the invite sent to {email}." msgstr "{user} انضم إلى الفريق باستخدام دعوة إرسالها إلى {email}." -#: pretix/control/logdisplay.py:595 +#: pretix/control/logdisplay.py:656 msgid "Your account settings have been changed." msgstr "تم تغيير إعدادات حسابك." -#: pretix/control/logdisplay.py:598 pretix/control/views/user.py:253 +#: pretix/control/logdisplay.py:659 pretix/control/views/user.py:253 #, python-brace-format msgid "Your email address has been changed to {email}." msgstr "تم تغيير عنوان البريد الإلكتروني الخاص بك إلى {email}." -#: pretix/control/logdisplay.py:600 pretix/control/views/user.py:250 +#: pretix/control/logdisplay.py:661 pretix/control/views/user.py:250 msgid "Your password has been changed." msgstr "تم تغيير كلمة السر الخاصة بك." -#: pretix/control/logdisplay.py:602 +#: pretix/control/logdisplay.py:663 msgid "Your account has been enabled." msgstr "تم تمكين حسابك." -#: pretix/control/logdisplay.py:604 +#: pretix/control/logdisplay.py:665 msgid "Your account has been disabled." msgstr "تم تعطيل حسابك." -#: pretix/control/logdisplay.py:614 +#: pretix/control/logdisplay.py:675 +#, python-brace-format msgid "You impersonated {}." msgstr "كنت انتحاله {}." -#: pretix/control/logdisplay.py:615 +#: pretix/control/logdisplay.py:676 +#, python-brace-format msgid "You stopped impersonating {}." msgstr "قمت بإيقاف انتحال {}." -#: pretix/control/logdisplay.py:622 +#: pretix/control/logdisplay.py:683 msgid "This object has been created by cloning." msgstr "تم إنشاء هذا الكائن عبر النسخ." -#: pretix/control/logdisplay.py:623 +#: pretix/control/logdisplay.py:684 msgid "The organizer has been changed." msgstr "تم تغيير المنظم." -#: pretix/control/logdisplay.py:624 +#: pretix/control/logdisplay.py:685 msgid "The organizer settings have been changed." msgstr "تم تغيير إعدادات المنظم." -#: pretix/control/logdisplay.py:625 pretix/control/logdisplay.py:744 +#: pretix/control/logdisplay.py:686 pretix/control/logdisplay.py:825 #, fuzzy #| msgid "The order details have been changed." msgid "The footer links have been changed." msgstr "تم تغيير تفاصيل النظام." -#: pretix/control/logdisplay.py:626 pretix/control/logdisplay.py:672 +#: pretix/control/logdisplay.py:687 pretix/control/logdisplay.py:733 #, fuzzy #| msgid "The quota has been added." msgid "A scheduled export has been added." msgstr "تمت إضافة الحصص." -#: pretix/control/logdisplay.py:627 pretix/control/logdisplay.py:673 +#: pretix/control/logdisplay.py:688 pretix/control/logdisplay.py:734 #, fuzzy #| msgid "The product has been changed." msgid "A scheduled export has been changed." msgstr "تم تغيير المنتج." -#: pretix/control/logdisplay.py:628 pretix/control/logdisplay.py:674 +#: pretix/control/logdisplay.py:689 pretix/control/logdisplay.py:735 #, fuzzy #| msgid "The selected product has been deleted." msgid "A scheduled export has been deleted." msgstr "تم حذف المنتج المحدد." -#: pretix/control/logdisplay.py:629 pretix/control/logdisplay.py:675 +#: pretix/control/logdisplay.py:690 pretix/control/logdisplay.py:736 #, fuzzy #| msgid "The selected product has been deleted." msgid "A scheduled export has been executed." msgstr "تم حذف المنتج المحدد." -#: pretix/control/logdisplay.py:630 pretix/control/logdisplay.py:676 +#: pretix/control/logdisplay.py:691 pretix/control/logdisplay.py:737 #, python-brace-format msgid "A scheduled export has failed: {reason}." msgstr "" -#: pretix/control/logdisplay.py:631 +#: pretix/control/logdisplay.py:692 msgid "Gift card acceptance for another organizer has been added." msgstr "تم إضافة قبول بطاقة الهدية لمنظم آخر." -#: pretix/control/logdisplay.py:632 +#: pretix/control/logdisplay.py:693 msgid "Gift card acceptance for another organizer has been removed." msgstr "تم إزالة قبول بطاقة هدية لمنظم آخر." -#: pretix/control/logdisplay.py:633 +#: pretix/control/logdisplay.py:694 #, fuzzy #| msgid "The gift card has been created." msgid "A new gift card acceptor has been invited." msgstr "تم إنشاء بطاقة هدية." -#: pretix/control/logdisplay.py:634 +#: pretix/control/logdisplay.py:695 #, fuzzy #| msgid "The gift card has been created." msgid "A gift card acceptor has been removed." msgstr "تم إنشاء بطاقة هدية." -#: pretix/control/logdisplay.py:635 +#: pretix/control/logdisplay.py:696 #, fuzzy #| msgid "The selected gift card issuer has been removed." msgid "A gift card issuer has been removed or declined." msgstr "تمت إزالة مصدر البطاقة هدية المحدد." -#: pretix/control/logdisplay.py:636 +#: pretix/control/logdisplay.py:697 #, fuzzy #| msgid "The selected gift card issuer has been added." msgid "A new gift card issuer has been accepted." msgstr "تمت إضافة مصدر البطاقة هدية المحدد." -#: pretix/control/logdisplay.py:637 +#: pretix/control/logdisplay.py:698 msgid "The webhook has been created." msgstr "تم إنشاء خطاف الويب." -#: pretix/control/logdisplay.py:638 +#: pretix/control/logdisplay.py:699 msgid "The webhook has been changed." msgstr "تم تغيير خطاف الويب." -#: pretix/control/logdisplay.py:639 +#: pretix/control/logdisplay.py:700 msgid "The webhook call retry jobs have been manually expedited." msgstr "" -#: pretix/control/logdisplay.py:640 +#: pretix/control/logdisplay.py:701 #, fuzzy #| msgid "The webhook has been created." msgid "The webhook call retry jobs have been dropped." msgstr "تم إنشاء خطاف الويب." -#: pretix/control/logdisplay.py:641 +#: pretix/control/logdisplay.py:702 #, fuzzy #| msgid "The order has been created." msgid "The SSO provider has been created." msgstr "تم إنشاء هذا الأمر." -#: pretix/control/logdisplay.py:642 +#: pretix/control/logdisplay.py:703 #, fuzzy #| msgid "The order has been changed." msgid "The SSO provider has been changed." msgstr "تم تغيير النظام." -#: pretix/control/logdisplay.py:643 +#: pretix/control/logdisplay.py:704 #, fuzzy #| msgid "The order has been deleted." msgid "The SSO provider has been deleted." msgstr "تم حذف هذا الأمر." -#: pretix/control/logdisplay.py:644 +#: pretix/control/logdisplay.py:705 #, fuzzy #| msgid "The event has been created." msgid "The SSO client has been created." msgstr "تم إنشاء هذا الحدث." -#: pretix/control/logdisplay.py:645 +#: pretix/control/logdisplay.py:706 #, fuzzy #| msgid "The account has been changed." msgid "The SSO client has been changed." msgstr "تم تغيير الحساب." -#: pretix/control/logdisplay.py:646 +#: pretix/control/logdisplay.py:707 #, fuzzy #| msgid "The event has been deleted." msgid "The SSO client has been deleted." msgstr "الحدث تم الغائه." -#: pretix/control/logdisplay.py:647 pretix/control/views/organizer.py:2346 +#: pretix/control/logdisplay.py:708 pretix/control/views/organizer.py:2615 msgid "The membership type has been created." msgstr "تم انشاء نوع العضوية." -#: pretix/control/logdisplay.py:648 +#: pretix/control/logdisplay.py:709 msgid "The membership type has been changed." msgstr "تم تغيير نوع العضوية." -#: pretix/control/logdisplay.py:649 +#: pretix/control/logdisplay.py:710 msgid "The membership type has been deleted." msgstr "تم حذف نوع العضوية." -#: pretix/control/logdisplay.py:650 pretix/control/views/organizer.py:3184 +#: pretix/control/logdisplay.py:711 pretix/control/views/organizer.py:3453 #, fuzzy #| msgctxt "subevent" #| msgid "The new date has been created." msgid "The sales channel has been created." msgstr "تم إنشاء الموعد الجديد." -#: pretix/control/logdisplay.py:651 +#: pretix/control/logdisplay.py:712 #, fuzzy #| msgid "The device has been changed." msgid "The sales channel has been changed." msgstr "تم تغيير الجهاز." -#: pretix/control/logdisplay.py:652 +#: pretix/control/logdisplay.py:713 #, fuzzy #| msgid "The selected list has been deleted." msgid "The sales channel has been deleted." msgstr "تم حذف القائمة المحددة." -#: pretix/control/logdisplay.py:653 +#: pretix/control/logdisplay.py:714 msgid "The account has been created." msgstr "تم إنشاء الحساب." -#: pretix/control/logdisplay.py:654 +#: pretix/control/logdisplay.py:715 msgid "The account has been changed." msgstr "تم تغيير الحساب." -#: pretix/control/logdisplay.py:655 +#: pretix/control/logdisplay.py:716 msgid "A membership for this account has been added." msgstr "تم إضافة عضوية لهذا الحساب." -#: pretix/control/logdisplay.py:656 +#: pretix/control/logdisplay.py:717 msgid "A membership of this account has been changed." msgstr "تم تغيير العضوية لهذا الحساب." -#: pretix/control/logdisplay.py:657 +#: pretix/control/logdisplay.py:718 msgid "A membership of this account has been deleted." msgstr "تم حذف عضوية هذا الحساب." -#: pretix/control/logdisplay.py:658 +#: pretix/control/logdisplay.py:719 #, fuzzy #| msgid "Your account has been disabled." msgid "The account has been disabled and anonymized." msgstr "تم تعطيل الحساب وأصبح مجهول المصدر." -#: pretix/control/logdisplay.py:659 +#: pretix/control/logdisplay.py:720 msgid "A new password has been requested." msgstr "تم طلب تعيين كلمة المرور جديدة." -#: pretix/control/logdisplay.py:660 +#: pretix/control/logdisplay.py:721 msgid "A new password has been set." msgstr "تم تعيين كلمة المرور جديدة." -#: pretix/control/logdisplay.py:661 +#: pretix/control/logdisplay.py:722 #, fuzzy #| msgid "The team has been created." msgid "The reusable medium has been created." msgstr "تم إنشاء فريق." -#: pretix/control/logdisplay.py:662 +#: pretix/control/logdisplay.py:723 #, fuzzy #| msgid "The payment has been created successfully." msgid "The reusable medium has been created automatically." msgstr "تم إنشاء دفع بنجاح." -#: pretix/control/logdisplay.py:663 +#: pretix/control/logdisplay.py:724 #, fuzzy #| msgid "The tax rule has been changed." msgid "The reusable medium has been changed." msgstr "تم تغيير القاعدة الضريبية." -#: pretix/control/logdisplay.py:664 +#: pretix/control/logdisplay.py:725 #, fuzzy #| msgid "The email has been queued to be sent." msgid "The medium has been connected to a new ticket." msgstr "وقد تم في قائمة الانتظار البريد الإلكتروني لإرسالها." -#: pretix/control/logdisplay.py:665 +#: pretix/control/logdisplay.py:726 #, fuzzy #| msgid "The email has been queued to be sent." msgid "The medium has been connected to a new gift card." msgstr "وقد تم في قائمة الانتظار البريد الإلكتروني لإرسالها." -#: pretix/control/logdisplay.py:667 +#: pretix/control/logdisplay.py:728 msgid "The event's internal comment has been updated." msgstr "تم تحديث التعليق الداخلي للحدث." -#: pretix/control/logdisplay.py:668 +#: pretix/control/logdisplay.py:729 msgid "The event has been canceled." msgstr "تم إلغاء الفعالية." -#: pretix/control/logdisplay.py:669 +#: pretix/control/logdisplay.py:730 msgid "An event has been deleted." msgstr "تم حذف فعالية." -#: pretix/control/logdisplay.py:670 +#: pretix/control/logdisplay.py:731 msgid "A removal process for personal data has been started." msgstr "" -#: pretix/control/logdisplay.py:671 +#: pretix/control/logdisplay.py:732 msgid "A removal process for personal data has been completed." msgstr "" -#: pretix/control/logdisplay.py:677 +#: pretix/control/logdisplay.py:738 msgid "The user has been created." msgstr "تم إنشاء المستخدم." -#: pretix/control/logdisplay.py:678 +#: pretix/control/logdisplay.py:739 #, python-brace-format msgid "" "A first login using {agent_type} on {os_type} from {country} has been " "detected." msgstr "" -#: pretix/control/logdisplay.py:680 pretix/control/views/user.py:490 +#: pretix/control/logdisplay.py:741 pretix/control/views/user.py:490 #: pretix/control/views/user.py:550 pretix/control/views/user.py:609 msgid "Two-factor authentication has been enabled." msgstr "تم تمكين مصادقة اثنين عامل." -#: pretix/control/logdisplay.py:681 pretix/control/views/user.py:393 +#: pretix/control/logdisplay.py:742 pretix/control/views/user.py:393 #: pretix/control/views/user.py:625 msgid "Two-factor authentication has been disabled." msgstr "تم تعطيل المصادقة اثنين عامل." -#: pretix/control/logdisplay.py:682 pretix/control/views/user.py:642 +#: pretix/control/logdisplay.py:743 pretix/control/views/user.py:642 msgid "Your two-factor emergency codes have been regenerated." msgstr "وقد جددت بك رموز الطوارئ اثنين عامل." -#: pretix/control/logdisplay.py:683 +#: pretix/control/logdisplay.py:744 #, fuzzy #| msgid "Your two-factor emergency codes have been regenerated." msgid "A two-factor emergency code has been generated." msgstr "وقد جددت بك رموز الطوارئ اثنين عامل." -#: pretix/control/logdisplay.py:684 +#: pretix/control/logdisplay.py:745 #, python-brace-format msgid "" "A new two-factor authentication device \"{name}\" has been added to your " "account." msgstr "A اثنين عامل جهاز التوثيق جديد \"{name}\" قد أضيفت إلى حسابك." -#: pretix/control/logdisplay.py:686 +#: pretix/control/logdisplay.py:747 #, python-brace-format msgid "" "The two-factor authentication device \"{name}\" has been removed from your " "account." msgstr "الجهاز اثنين عامل التوثيق \"{name}\" تمت إزالة من حسابك." -#: pretix/control/logdisplay.py:688 +#: pretix/control/logdisplay.py:749 msgid "Notifications have been enabled." msgstr "تم تمكين الإشعارات." -#: pretix/control/logdisplay.py:689 +#: pretix/control/logdisplay.py:750 msgid "Notifications have been disabled." msgstr "تم تعطيل الإشعارات." -#: pretix/control/logdisplay.py:690 +#: pretix/control/logdisplay.py:751 msgid "Your notification settings have been changed." msgstr "تم تغيير إعدادات الإشعار." -#: pretix/control/logdisplay.py:691 +#: pretix/control/logdisplay.py:752 msgid "This user has been anonymized." msgstr "تم طمس هويتها لهذا المستخدم." -#: pretix/control/logdisplay.py:694 +#: pretix/control/logdisplay.py:755 msgid "Password reset mail sent." msgstr "إرسال كلمة المرور الإلكتروني إعادة تعيين." -#: pretix/control/logdisplay.py:695 +#: pretix/control/logdisplay.py:756 msgid "The password has been reset." msgstr "وقد تم إعادة تعيين كلمة المرور." -#: pretix/control/logdisplay.py:696 +#: pretix/control/logdisplay.py:757 msgid "" "A repeated password reset has been denied, as the last request was less than " "24 hours ago." msgstr "" -#: pretix/control/logdisplay.py:698 +#: pretix/control/logdisplay.py:759 #, python-brace-format msgid "The organizer \"{name}\" has been deleted." msgstr "منظم \"{name}\" تم حذفها." -#: pretix/control/logdisplay.py:699 pretix/control/logdisplay.py:905 +#: pretix/control/logdisplay.py:760 pretix/control/logdisplay.py:986 msgid "A voucher has been sent to a person on the waiting list." msgstr "تم إرسال قسيمة لشخص على قائمة الانتظار." -#: pretix/control/logdisplay.py:700 +#: pretix/control/logdisplay.py:761 #, fuzzy #| msgid "An entry has been added to the waiting list." msgid "An entry has been transferred to another waiting list." msgstr "تمت إضافة إدخال إلى قائمة الانتظار." -#: pretix/control/logdisplay.py:701 +#: pretix/control/logdisplay.py:762 msgid "The team has been created." msgstr "تم إنشاء فريق." -#: pretix/control/logdisplay.py:702 +#: pretix/control/logdisplay.py:763 msgid "The team settings have been changed." msgstr "تم تغيير إعدادات الفريق." -#: pretix/control/logdisplay.py:703 +#: pretix/control/logdisplay.py:764 msgid "The team has been deleted." msgstr "تم حذف الفريق." -#: pretix/control/logdisplay.py:704 pretix/control/views/organizer.py:2012 +#: pretix/control/logdisplay.py:765 pretix/control/views/organizer.py:2281 msgid "The gate has been created." msgstr "تم إنشاء البوابة." -#: pretix/control/logdisplay.py:705 +#: pretix/control/logdisplay.py:766 msgid "The gate has been changed." msgstr "تم تغيير البوابة." -#: pretix/control/logdisplay.py:706 +#: pretix/control/logdisplay.py:767 msgid "The gate has been deleted." msgstr "تم حذف البوابة." -#: pretix/control/logdisplay.py:707 +#: pretix/control/logdisplay.py:768 msgctxt "subevent" msgid "The event date has been deleted." msgstr "تم حذف تاريخ الحدث." -#: pretix/control/logdisplay.py:708 +#: pretix/control/logdisplay.py:769 msgctxt "subevent" msgid "The event date has been canceled." msgstr "تم تغيير تاريخ الفعالية." -#: pretix/control/logdisplay.py:709 +#: pretix/control/logdisplay.py:770 msgctxt "subevent" msgid "The event date has been changed." msgstr "تم تغيير تاريخ الحدث." -#: pretix/control/logdisplay.py:710 +#: pretix/control/logdisplay.py:771 msgctxt "subevent" msgid "The event date has been created." msgstr "تم إنشاء تاريخ الحدث." -#: pretix/control/logdisplay.py:711 +#: pretix/control/logdisplay.py:772 msgctxt "subevent" msgid "A quota has been added to the event date." msgstr "تمت إضافة الحصص لتاريخ الحدث." -#: pretix/control/logdisplay.py:712 +#: pretix/control/logdisplay.py:773 msgctxt "subevent" msgid "A quota has been changed on the event date." msgstr "تم تغيير الحصص في تاريخ الحدث." -#: pretix/control/logdisplay.py:713 +#: pretix/control/logdisplay.py:774 msgctxt "subevent" msgid "A quota has been removed from the event date." msgstr "تمت إزالة حصة من تاريخ الحدث." -#: pretix/control/logdisplay.py:714 +#: pretix/control/logdisplay.py:775 msgid "The device has been created." msgstr "تم إنشاء الجهاز." -#: pretix/control/logdisplay.py:715 +#: pretix/control/logdisplay.py:776 msgid "The device has been changed." msgstr "تم تغيير الجهاز." -#: pretix/control/logdisplay.py:716 +#: pretix/control/logdisplay.py:777 msgid "Access of the device has been revoked." msgstr "تم إبطال الوصول للجهاز." -#: pretix/control/logdisplay.py:717 +#: pretix/control/logdisplay.py:778 msgid "The device has been initialized." msgstr "تم تهيئة الجهاز." -#: pretix/control/logdisplay.py:718 +#: pretix/control/logdisplay.py:779 msgid "The access token of the device has been regenerated." msgstr "تم إعادة إنشاء الوصول رمزية للجهاز." -#: pretix/control/logdisplay.py:719 +#: pretix/control/logdisplay.py:780 msgid "The device has notified the server of an hardware or software update." msgstr "وقد أخطرت جهاز الخادم من تحديث الأجهزة أو البرامج." -#: pretix/control/logdisplay.py:720 +#: pretix/control/logdisplay.py:781 msgid "The gift card has been created." msgstr "تم إنشاء بطاقة هدية." -#: pretix/control/logdisplay.py:721 pretix/control/views/organizer.py:1656 +#: pretix/control/logdisplay.py:782 pretix/control/views/organizer.py:1925 msgid "The gift card has been changed." msgstr "تم تغيير بطاقة الهدية." -#: pretix/control/logdisplay.py:722 +#: pretix/control/logdisplay.py:783 msgid "A manual transaction has been performed." msgstr "تم إجراء عملية يدوية." -#: pretix/control/logdisplay.py:723 +#: pretix/control/logdisplay.py:784 #, python-brace-format msgid "The token \"{name}\" has been created." msgstr "ورمزي \"{name}\" تم إنشاؤه." -#: pretix/control/logdisplay.py:724 +#: pretix/control/logdisplay.py:785 #, python-brace-format msgid "The token \"{name}\" has been revoked." msgstr "ورمزي \"{name}\" تم إبطال." -#: pretix/control/logdisplay.py:731 +#: pretix/control/logdisplay.py:786 +#, fuzzy +#| msgid "The check-in list has been deleted." +msgid "The check-in and print log state has been reset." +msgstr "تم حذف الاختيار في القائمة." + +#: pretix/control/logdisplay.py:793 pretix/control/logdisplay.py:852 +#, fuzzy +#| msgid "A plugin has been enabled." +msgid "The plugin has been enabled." +msgstr "تم تمكين البرنامج المساعد." + +#: pretix/control/logdisplay.py:794 pretix/control/logdisplay.py:853 +#: pretix/control/views/event.py:490 pretix/control/views/organizer.py:753 +#, fuzzy +#| msgid "A plugin has been disabled." +msgid "The plugin has been disabled." +msgstr "تم تعطيل البرنامج المساعد." + +#: pretix/control/logdisplay.py:797 pretix/control/logdisplay.py:856 +#, fuzzy, python-brace-format +#| msgid "Question {val}" +msgid "Plugin {val}" +msgstr "سؤال{val}" + +#: pretix/control/logdisplay.py:812 #, fuzzy #| msgid "A user has been added to the event team." msgid "A meta property has been added to this event." msgstr "تمت إضافة المستخدم إلى فريق الحدث." -#: pretix/control/logdisplay.py:732 +#: pretix/control/logdisplay.py:813 #, fuzzy #| msgid "A user has been removed from the event team." msgid "A meta property has been removed from this event." msgstr "تمت إزالة مستخدم من فريق الحدث." -#: pretix/control/logdisplay.py:733 +#: pretix/control/logdisplay.py:814 #, fuzzy #| msgctxt "subevent" #| msgid "A quota has been changed on the event date." msgid "A meta property has been changed on this event." msgstr "تم تغيير الحصص في تاريخ الحدث." -#: pretix/control/logdisplay.py:734 +#: pretix/control/logdisplay.py:815 msgid "The event settings have been changed." msgstr "تم تغيير إعدادات الحدث." -#: pretix/control/logdisplay.py:735 +#: pretix/control/logdisplay.py:816 msgid "The ticket download settings have been changed." msgstr "تم تغيير إعدادات تذكرة تنزيل." -#: pretix/control/logdisplay.py:738 +#: pretix/control/logdisplay.py:819 msgid "The shop has been taken live." msgstr "وقد اتخذت المحل الحية." -#: pretix/control/logdisplay.py:739 +#: pretix/control/logdisplay.py:820 msgid "The shop has been taken offline." msgstr "وقد اتخذت المحل حاليا." -#: pretix/control/logdisplay.py:740 +#: pretix/control/logdisplay.py:821 msgid "The shop has been taken into test mode." msgstr "وقد اتخذت المحل في وضع الاختبار." -#: pretix/control/logdisplay.py:741 +#: pretix/control/logdisplay.py:822 msgid "The test mode has been disabled." msgstr "تم تعطيل وضع الاختبار." -#: pretix/control/logdisplay.py:742 +#: pretix/control/logdisplay.py:823 msgid "The event has been created." msgstr "تم إنشاء هذا الحدث." -#: pretix/control/logdisplay.py:743 +#: pretix/control/logdisplay.py:824 msgid "The event details have been changed." msgstr "تم تغيير تفاصيل الفعالية." -#: pretix/control/logdisplay.py:745 +#: pretix/control/logdisplay.py:826 msgid "An answer option has been added to the question." msgstr "تمت إضافة خيار الإجابة على السؤال." -#: pretix/control/logdisplay.py:746 +#: pretix/control/logdisplay.py:827 msgid "An answer option has been removed from the question." msgstr "تمت إزالة خيار الإجابة عن السؤال." -#: pretix/control/logdisplay.py:747 +#: pretix/control/logdisplay.py:828 msgid "An answer option has been changed." msgstr "تم تغيير خيار الإجابة." -#: pretix/control/logdisplay.py:748 +#: pretix/control/logdisplay.py:829 msgid "A user has been added to the event team." msgstr "تمت إضافة المستخدم إلى فريق الحدث." -#: pretix/control/logdisplay.py:749 +#: pretix/control/logdisplay.py:830 msgid "A user has been invited to the event team." msgstr "وقد وجهت الدعوة للمستخدم لفريق الحدث." -#: pretix/control/logdisplay.py:750 +#: pretix/control/logdisplay.py:831 msgid "A user's permissions have been changed." msgstr "تم تغيير الأذونات للمستخدم." -#: pretix/control/logdisplay.py:751 +#: pretix/control/logdisplay.py:832 msgid "A user has been removed from the event team." msgstr "تمت إزالة مستخدم من فريق الحدث." -#: pretix/control/logdisplay.py:758 +#: pretix/control/logdisplay.py:839 msgid "The check-in list has been added." msgstr "تمت إضافة الاختيار في القائمة." -#: pretix/control/logdisplay.py:759 pretix/control/logdisplay.py:760 +#: pretix/control/logdisplay.py:840 pretix/control/logdisplay.py:841 msgid "The check-in list has been deleted." msgstr "تم حذف الاختيار في القائمة." -#: pretix/control/logdisplay.py:761 +#: pretix/control/logdisplay.py:842 msgid "The check-in list has been changed." msgstr "تم تغيير الاختيار في القائمة." -#: pretix/control/logdisplay.py:764 +#: pretix/control/logdisplay.py:845 #, fuzzy, python-brace-format #| msgid "Check-in list" msgid "Check-in list {val}" msgstr "تحقق في قائمة" -#: pretix/control/logdisplay.py:771 -#, fuzzy -#| msgid "A plugin has been enabled." -msgid "The plugin has been enabled." -msgstr "تم تمكين البرنامج المساعد." - -#: pretix/control/logdisplay.py:772 pretix/control/views/event.py:464 -#, fuzzy -#| msgid "A plugin has been disabled." -msgid "The plugin has been disabled." -msgstr "تم تعطيل البرنامج المساعد." - -#: pretix/control/logdisplay.py:775 -#, fuzzy, python-brace-format -#| msgid "Question {val}" -msgid "Plugin {val}" -msgstr "سؤال{val}" - -#: pretix/control/logdisplay.py:791 +#: pretix/control/logdisplay.py:872 msgid "The product has been created." msgstr "تم إنشاء المنتج." -#: pretix/control/logdisplay.py:792 +#: pretix/control/logdisplay.py:873 msgid "The product has been changed." msgstr "تم تغيير المنتج." -#: pretix/control/logdisplay.py:793 +#: pretix/control/logdisplay.py:874 #, fuzzy #| msgid "The product has been created." msgid "The product has been reordered." msgstr "تم إنشاء المنتج." -#: pretix/control/logdisplay.py:794 +#: pretix/control/logdisplay.py:875 msgid "The product has been deleted." msgstr "تم حذف المنتج." -#: pretix/control/logdisplay.py:795 +#: pretix/control/logdisplay.py:876 msgid "An add-on has been added to this product." msgstr "تمت إضافة وظيفة إضافية على هذا المنتج." -#: pretix/control/logdisplay.py:796 +#: pretix/control/logdisplay.py:877 msgid "An add-on has been removed from this product." msgstr "تمت إزالة وظيفة إضافية على من هذا المنتج." -#: pretix/control/logdisplay.py:797 +#: pretix/control/logdisplay.py:878 msgid "An add-on has been changed on this product." msgstr "تم تغيير وظيفة إضافية على على هذا المنتج." -#: pretix/control/logdisplay.py:798 +#: pretix/control/logdisplay.py:879 msgid "A bundled item has been added to this product." msgstr "تمت إضافة بند المجمعة لهذا المنتج." -#: pretix/control/logdisplay.py:799 +#: pretix/control/logdisplay.py:880 msgid "A bundled item has been removed from this product." msgstr "تمت إزالة عنصر المجمعة من هذا المنتج." -#: pretix/control/logdisplay.py:800 +#: pretix/control/logdisplay.py:881 msgid "A bundled item has been changed on this product." msgstr "تم تغيير عنصر المجمعة لهذا المنتج." -#: pretix/control/logdisplay.py:807 +#: pretix/control/logdisplay.py:888 #, python-brace-format msgid "The variation \"{value}\" has been created." msgstr "الاختلاف \"{value}\" تم إنشاؤه." -#: pretix/control/logdisplay.py:808 +#: pretix/control/logdisplay.py:889 #, python-brace-format msgid "The variation \"{value}\" has been deleted." msgstr "الاختلاف \"{value}\" تم حذفها." -#: pretix/control/logdisplay.py:809 +#: pretix/control/logdisplay.py:890 #, python-brace-format msgid "The variation \"{value}\" has been changed." msgstr "الاختلاف \"{value}\" تم تغيير." -#: pretix/control/logdisplay.py:826 +#: pretix/control/logdisplay.py:907 #, python-brace-format msgid "Payment {local_id} has been confirmed." msgstr "وقد تم تأكيد الدفع {local_id}." -#: pretix/control/logdisplay.py:827 +#: pretix/control/logdisplay.py:908 #, python-brace-format msgid "Payment {local_id} has been canceled." msgstr "تم إلغاء الدفع {local_id}." -#: pretix/control/logdisplay.py:828 +#: pretix/control/logdisplay.py:909 #, python-brace-format msgid "Canceling payment {local_id} has failed." msgstr "فشل إلغاء الدفع {local_id}." -#: pretix/control/logdisplay.py:829 +#: pretix/control/logdisplay.py:910 #, python-brace-format msgid "Payment {local_id} has been started." msgstr "وقد بدأ الدفع {local_id}." -#: pretix/control/logdisplay.py:830 +#: pretix/control/logdisplay.py:911 #, python-brace-format msgid "Payment {local_id} has failed." msgstr "فشلت الدفع {local_id}." -#: pretix/control/logdisplay.py:831 +#: pretix/control/logdisplay.py:912 #, python-brace-format msgid "The order could not be marked as paid: {message}" msgstr "لا يمكن أن تكون وضعت النظام كما المدفوعة: {message}" -#: pretix/control/logdisplay.py:832 +#: pretix/control/logdisplay.py:913 msgid "The order has been overpaid." msgstr "وقد تم ترتيب زائدة." -#: pretix/control/logdisplay.py:833 +#: pretix/control/logdisplay.py:914 #, python-brace-format msgid "Refund {local_id} has been created." msgstr "تم إنشاء استرداد {local_id}." -#: pretix/control/logdisplay.py:834 +#: pretix/control/logdisplay.py:915 #, python-brace-format msgid "Refund {local_id} has been created by an external entity." msgstr "تم إنشاء استرداد {local_id} كيان خارجي." -#: pretix/control/logdisplay.py:835 +#: pretix/control/logdisplay.py:916 msgid "The customer requested you to issue a refund." msgstr "طلب لك العملاء لإصدار رد." -#: pretix/control/logdisplay.py:836 +#: pretix/control/logdisplay.py:917 #, python-brace-format msgid "Refund {local_id} has been completed." msgstr "وقد تم الانتهاء استرداد {local_id}." -#: pretix/control/logdisplay.py:837 +#: pretix/control/logdisplay.py:918 #, python-brace-format msgid "Refund {local_id} has been canceled." msgstr "تم إلغاء استرداد {local_id}." -#: pretix/control/logdisplay.py:838 +#: pretix/control/logdisplay.py:919 #, python-brace-format msgid "Refund {local_id} has failed." msgstr "فشل استرداد {local_id}." -#: pretix/control/logdisplay.py:845 +#: pretix/control/logdisplay.py:926 msgid "The quota has been added." msgstr "تمت إضافة الحصص." -#: pretix/control/logdisplay.py:846 +#: pretix/control/logdisplay.py:927 msgid "The quota has been deleted." msgstr "تم حذف الحصص." -#: pretix/control/logdisplay.py:847 +#: pretix/control/logdisplay.py:928 msgid "The quota has been changed." msgstr "تم تغيير الحصص." -#: pretix/control/logdisplay.py:848 +#: pretix/control/logdisplay.py:929 msgid "The quota has closed." msgstr "وقد أغلقت الحصص." -#: pretix/control/logdisplay.py:849 pretix/control/views/item.py:1081 +#: pretix/control/logdisplay.py:930 pretix/control/views/item.py:1081 msgid "The quota has been re-opened." msgstr "وكانت الحصة إعادة فتح." -#: pretix/control/logdisplay.py:856 +#: pretix/control/logdisplay.py:937 msgid "The question has been added." msgstr "تمت إضافة هذا السؤال." -#: pretix/control/logdisplay.py:857 +#: pretix/control/logdisplay.py:938 msgid "The question has been deleted." msgstr "تم حذف السؤال." -#: pretix/control/logdisplay.py:858 +#: pretix/control/logdisplay.py:939 msgid "The question has been changed." msgstr "تم تغيير السؤال." -#: pretix/control/logdisplay.py:859 +#: pretix/control/logdisplay.py:940 #, fuzzy #| msgid "The question has been deleted." msgid "The question has been reordered." msgstr "تم حذف السؤال." -#: pretix/control/logdisplay.py:866 +#: pretix/control/logdisplay.py:947 #, fuzzy #| msgid "The quota has been added." msgid "The discount has been added." msgstr "تمت إضافة الحصص." -#: pretix/control/logdisplay.py:867 +#: pretix/control/logdisplay.py:948 #, fuzzy #| msgid "The product has been deleted." msgid "The discount has been deleted." msgstr "تم حذف المنتج." -#: pretix/control/logdisplay.py:868 +#: pretix/control/logdisplay.py:949 #, fuzzy #| msgid "The account has been changed." msgid "The discount has been changed." msgstr "تم تغيير الحساب." -#: pretix/control/logdisplay.py:892 +#: pretix/control/logdisplay.py:973 #, python-brace-format msgid "" "Position #{posid} has been checked in manually at {datetime} on list \"{list}" @@ -17502,7 +18289,7 @@ msgid "" msgstr "" "وقد تم التحقق من موقف # {posid} في يدويا في{datetime} على قائمة \"{list}\"." -#: pretix/control/logdisplay.py:897 +#: pretix/control/logdisplay.py:978 #, python-brace-format msgid "" "Position #{posid} has been checked in again at {datetime} on list \"{list}\"." @@ -17510,15 +18297,15 @@ msgstr "" "وقد تم التحقق من موقف # {posid} الدخول مرة أخرى في{datetime} على قائمة " "\"{list}\"." -#: pretix/control/logdisplay.py:906 +#: pretix/control/logdisplay.py:987 msgid "An entry has been removed from the waiting list." msgstr "تمت إزالة إدخال من قائمة الانتظار." -#: pretix/control/logdisplay.py:907 +#: pretix/control/logdisplay.py:988 msgid "An entry has been changed on the waiting list." msgstr "تم تغيير دخول على قائمة الانتظار." -#: pretix/control/logdisplay.py:908 +#: pretix/control/logdisplay.py:989 msgid "An entry has been added to the waiting list." msgstr "تمت إضافة إدخال إلى قائمة الانتظار." @@ -17541,7 +18328,7 @@ msgid "Dashboard" msgstr "لوحة القيادة" #: pretix/control/navigation.py:49 pretix/control/navigation.py:382 -#: pretix/control/navigation.py:487 +#: pretix/control/navigation.py:492 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:38 #: pretix/control/templates/pretixcontrol/event/mail.html:14 #: pretix/control/templates/pretixcontrol/event/tax_edit.html:25 @@ -17557,19 +18344,20 @@ msgstr "جنرال لواء" #: pretix/control/navigation.py:57 #: pretix/control/templates/pretixcontrol/event/quick_setup.html:151 -#: pretix/control/templates/pretixcontrol/order/index.html:838 +#: pretix/control/templates/pretixcontrol/order/index.html:890 #: pretix/control/templates/pretixcontrol/order/refund_choose.html:37 #: pretix/plugins/banktransfer/apps.py:42 #: pretix/plugins/manualpayment/apps.py:39 pretix/plugins/paypal2/apps.py:45 #: pretix/plugins/stripe/apps.py:44 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:43 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:42 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:11 #: pretix/presale/templates/pretixpresale/event/order.html:86 msgid "Payment" msgstr "دفع" -#: pretix/control/navigation.py:73 pretix/control/views/event.py:1520 -#: pretix/control/views/event.py:1522 pretix/control/views/event.py:1554 -#: pretix/control/views/event.py:1559 pretix/control/views/subevents.py:293 +#: pretix/control/navigation.py:73 pretix/control/views/event.py:1610 +#: pretix/control/views/event.py:1612 pretix/control/views/event.py:1644 +#: pretix/control/views/event.py:1649 pretix/control/views/subevents.py:293 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:60 #: pretix/plugins/ticketoutputpdf/apps.py:55 #: pretix/plugins/ticketoutputpdf/exporters.py:68 @@ -17600,9 +18388,11 @@ msgid "Widget" msgstr "القطعة" #: pretix/control/navigation.py:126 pretix/control/navigation.py:435 -#: pretix/control/navigation.py:480 +#: pretix/control/navigation.py:485 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:138 #: pretix/control/templates/pretixcontrol/event/payment.html:47 -#: pretix/control/templates/pretixcontrol/event/plugins.html:106 +#: pretix/control/templates/pretixcontrol/event/plugins.html:117 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:135 #: pretix/control/templates/pretixcontrol/waitinglist/index.html:12 #: pretix/plugins/returnurl/apps.py:40 #: pretix/plugins/ticketoutputpdf/apps.py:55 @@ -17624,11 +18414,11 @@ msgid "Overview" msgstr "نظرة عامة" #: pretix/control/navigation.py:221 -#: pretix/control/templates/pretixcontrol/order/index.html:825 +#: pretix/control/templates/pretixcontrol/order/index.html:877 #: pretix/control/templates/pretixcontrol/orders/refunds.html:7 #: pretix/control/templates/pretixcontrol/orders/refunds.html:9 -#: pretix/plugins/reports/accountingreport.py:497 -#: pretix/plugins/reports/accountingreport.py:684 +#: pretix/plugins/reports/accountingreport.py:498 +#: pretix/plugins/reports/accountingreport.py:685 #: pretix/presale/templates/pretixpresale/event/order.html:137 msgid "Refunds" msgstr "المستردة" @@ -17661,16 +18451,17 @@ msgstr "تحقق في قائمة" #: pretix/control/navigation.py:356 #: pretix/control/templates/pretixcontrol/event/plugins.html:20 #: pretix/control/templates/pretixcontrol/orders/search.html:20 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:20 #, fuzzy #| msgid "Search" msgid "Search" msgstr "بحث" #: pretix/control/navigation.py:368 -#: pretix/control/templates/pretixcontrol/order/index.html:731 -#: pretix/plugins/reports/accountingreport.py:496 -#: pretix/plugins/reports/accountingreport.py:677 -#: pretix/plugins/reports/accountingreport.py:871 +#: pretix/control/templates/pretixcontrol/order/index.html:783 +#: pretix/plugins/reports/accountingreport.py:497 +#: pretix/plugins/reports/accountingreport.py:678 +#: pretix/plugins/reports/accountingreport.py:872 msgid "Payments" msgstr "المدفوعات" @@ -17731,35 +18522,39 @@ msgstr "فحص الرخصة" msgid "System report" msgstr "مسألة الحذف" -#: pretix/control/navigation.py:494 +#: pretix/control/navigation.py:455 pretix/control/navigation.py:675 +msgid "Data sync problems" +msgstr "" + +#: pretix/control/navigation.py:506 #: pretix/control/templates/pretixcontrol/organizers/properties.html:5 msgid "Event metadata" msgstr "الفوقية الحدث" -#: pretix/control/navigation.py:515 +#: pretix/control/navigation.py:527 #: pretix/control/templates/pretixcontrol/organizers/webhooks.html:6 msgid "Webhooks" msgstr "Webhooks" -#: pretix/control/navigation.py:548 +#: pretix/control/navigation.py:560 #, fuzzy #| msgid "Accept anyway" msgid "Acceptance" msgstr "اقبل على أي حال" -#: pretix/control/navigation.py:569 +#: pretix/control/navigation.py:581 #: pretix/control/templates/pretixcontrol/organizers/customers.html:6 #: pretix/control/templates/pretixcontrol/organizers/customers.html:9 msgid "Customers" msgstr "عملاء" -#: pretix/control/navigation.py:588 +#: pretix/control/navigation.py:600 #: pretix/control/templates/pretixcontrol/organizers/ssoclients.html:4 #: pretix/control/templates/pretixcontrol/organizers/ssoclients.html:6 msgid "SSO clients" msgstr "" -#: pretix/control/navigation.py:597 +#: pretix/control/navigation.py:609 #: pretix/control/templates/pretixcontrol/organizers/ssoproviders.html:4 #: pretix/control/templates/pretixcontrol/organizers/ssoproviders.html:6 #, fuzzy @@ -17767,7 +18562,7 @@ msgstr "" msgid "SSO providers" msgstr "مزودي خدمات الدفع" -#: pretix/control/navigation.py:626 pretix/control/navigation.py:633 +#: pretix/control/navigation.py:638 pretix/control/navigation.py:645 msgid "Devices" msgstr "الأجهزة" @@ -17776,14 +18571,14 @@ msgstr "الأجهزة" msgid "You do not have permission to view this content." msgstr "ليس لديك إذن لعرض هذا المحتوى." -#: pretix/control/templates/pretixcontrol/auth/base.html:44 -#: pretix/control/templates/pretixcontrol/base.html:360 +#: pretix/control/templates/pretixcontrol/auth/base.html:42 +#: pretix/control/templates/pretixcontrol/base.html:358 #, python-format msgid "You are currently working on behalf of %(user)s." msgstr "كنت أعمل حاليا باسم%(user)s." -#: pretix/control/templates/pretixcontrol/auth/base.html:49 -#: pretix/control/templates/pretixcontrol/base.html:365 +#: pretix/control/templates/pretixcontrol/auth/base.html:47 +#: pretix/control/templates/pretixcontrol/base.html:363 msgid "Stop impersonating" msgstr "توقف انتحالا للشخصية" @@ -17875,10 +18670,10 @@ msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:11 #: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html:45 #: pretix/presale/templates/pretixpresale/event/checkout_addons.html:90 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:125 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:126 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:80 -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:130 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:192 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:131 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:194 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:53 #: pretix/presale/templates/pretixpresale/event/order_change.html:27 #: pretix/presale/templates/pretixpresale/event/order_pay.html:28 @@ -17934,9 +18729,9 @@ msgstr "كلمة المرور الجديدة تعيين" #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:124 #: pretix/control/templates/pretixcontrol/email_setup_simple.html:82 #: pretix/control/templates/pretixcontrol/email_setup_smtp.html:38 -#: pretix/control/templates/pretixcontrol/event/cancel.html:90 -#: pretix/control/templates/pretixcontrol/event/invoicing.html:68 -#: pretix/control/templates/pretixcontrol/event/mail.html:132 +#: pretix/control/templates/pretixcontrol/event/cancel.html:91 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:162 +#: pretix/control/templates/pretixcontrol/event/mail.html:135 #: pretix/control/templates/pretixcontrol/event/payment.html:88 #: pretix/control/templates/pretixcontrol/event/payment_provider.html:36 #: pretix/control/templates/pretixcontrol/event/quick_setup.html:201 @@ -17954,7 +18749,7 @@ msgstr "كلمة المرور الجديدة تعيين" #: pretix/control/templates/pretixcontrol/oauth/app_update.html:12 #: pretix/control/templates/pretixcontrol/order/change_contact.html:28 #: pretix/control/templates/pretixcontrol/order/change_locale.html:33 -#: pretix/control/templates/pretixcontrol/order/change_questions.html:86 +#: pretix/control/templates/pretixcontrol/order/change_questions.html:87 #: pretix/control/templates/pretixcontrol/order/extend.html:28 #: pretix/control/templates/pretixcontrol/orders/export_form.html:45 #: pretix/control/templates/pretixcontrol/organizers/channel_add.html:22 @@ -17972,13 +18767,14 @@ msgstr "كلمة المرور الجديدة تعيين" #: pretix/control/templates/pretixcontrol/organizers/giftcard_edit.html:21 #: pretix/control/templates/pretixcontrol/organizers/mail.html:73 #: pretix/control/templates/pretixcontrol/organizers/membershiptype_edit.html:15 +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:41 #: pretix/control/templates/pretixcontrol/organizers/property_edit.html:103 #: pretix/control/templates/pretixcontrol/organizers/reusable_medium_edit.html:28 #: pretix/control/templates/pretixcontrol/organizers/ssoclient_edit.html:15 #: pretix/control/templates/pretixcontrol/organizers/ssoprovider_edit.html:28 #: pretix/control/templates/pretixcontrol/organizers/team_edit.html:47 #: pretix/control/templates/pretixcontrol/organizers/webhook_edit.html:21 -#: pretix/control/templates/pretixcontrol/pdf/index.html:544 +#: pretix/control/templates/pretixcontrol/pdf/index.html:46 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:630 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:368 #: pretix/control/templates/pretixcontrol/subevents/detail.html:287 @@ -18006,76 +18802,76 @@ msgstr "احفظ" msgid "Create a new account" msgstr "انشاء حساب جديد" -#: pretix/control/templates/pretixcontrol/base.html:103 +#: pretix/control/templates/pretixcontrol/base.html:101 msgid "Toggle navigation" msgstr "تبديل الملاحة" -#: pretix/control/templates/pretixcontrol/base.html:118 -#: pretix/control/templates/pretixcontrol/base.html:141 -#: pretix/control/templates/pretixcontrol/base.html:145 -#: pretix/control/templates/pretixcontrol/base.html:146 +#: pretix/control/templates/pretixcontrol/base.html:116 +#: pretix/control/templates/pretixcontrol/base.html:139 +#: pretix/control/templates/pretixcontrol/base.html:143 +#: pretix/control/templates/pretixcontrol/base.html:144 msgid "Go to shop" msgstr "الذهاب للتسوق" -#: pretix/control/templates/pretixcontrol/base.html:124 -#: pretix/control/templates/pretixcontrol/base.html:152 -#: pretix/control/templates/pretixcontrol/base.html:153 +#: pretix/control/templates/pretixcontrol/base.html:122 +#: pretix/control/templates/pretixcontrol/base.html:150 +#: pretix/control/templates/pretixcontrol/base.html:151 msgid "Public profile" msgstr "حساب عام" -#: pretix/control/templates/pretixcontrol/base.html:204 +#: pretix/control/templates/pretixcontrol/base.html:202 msgid "End admin session" msgstr "إنهاء جلسة مشرف" -#: pretix/control/templates/pretixcontrol/base.html:216 +#: pretix/control/templates/pretixcontrol/base.html:214 msgid "Account Settings" msgstr "إعدادت الحساب" +#: pretix/control/templates/pretixcontrol/base.html:219 #: pretix/control/templates/pretixcontrol/base.html:221 -#: pretix/control/templates/pretixcontrol/base.html:223 #: pretix/presale/templates/pretixpresale/fragment_login_status.html:14 msgid "Log out" msgstr "الخروج" -#: pretix/control/templates/pretixcontrol/base.html:249 +#: pretix/control/templates/pretixcontrol/base.html:247 msgid "Organizer account" msgstr "حساب منظم" -#: pretix/control/templates/pretixcontrol/base.html:272 +#: pretix/control/templates/pretixcontrol/base.html:270 msgid "Search for events" msgstr "البحث عن الأحداث" -#: pretix/control/templates/pretixcontrol/base.html:329 -#: pretix/presale/templates/pretixpresale/base.html:54 +#: pretix/control/templates/pretixcontrol/base.html:327 +#: pretix/presale/templates/pretixpresale/base.html:51 msgid "" "We've detected that you are using Microsoft Internet Explorer." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:332 -#: pretix/presale/templates/pretixpresale/base.html:57 +#: pretix/control/templates/pretixcontrol/base.html:330 +#: pretix/presale/templates/pretixpresale/base.html:54 msgid "" "Internet Explorer is an old browser that does not support lots of recent web-" "based technologies and is no longer supported by this website." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:336 -#: pretix/presale/templates/pretixpresale/base.html:61 +#: pretix/control/templates/pretixcontrol/base.html:334 +#: pretix/presale/templates/pretixpresale/base.html:58 msgid "" "We kindly ask you to move to one of our supported browsers, such as " "Microsoft Edge, Mozilla Firefox, Google Chrome, or Safari." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:345 +#: pretix/control/templates/pretixcontrol/base.html:343 msgid "" "Please leave a short comment on what you did in the following admin sessions:" msgstr "يرجى ترك تعليق قصير على ما فعلتم في دورات المشرف التالية:" -#: pretix/control/templates/pretixcontrol/base.html:376 +#: pretix/control/templates/pretixcontrol/base.html:374 msgid "Read more" msgstr "اقرأ أكثر" -#: pretix/control/templates/pretixcontrol/base.html:393 +#: pretix/control/templates/pretixcontrol/base.html:391 msgid "" "Your event contains test mode orders even though " "test mode has been disabled. You should delete those orders " @@ -18086,11 +18882,11 @@ msgstr "" "من أن وضع على اختبار تم تعطيل . يجب حذف تلك الأوامر للتأكد " "من أنها لا تظهر في التقارير والإحصاءات وكتلة الناس من شراء تذاكر الواقع." -#: pretix/control/templates/pretixcontrol/base.html:400 +#: pretix/control/templates/pretixcontrol/base.html:398 msgid "Show all test mode orders" msgstr "عرض كل أوامر وضع الاختبار" -#: pretix/control/templates/pretixcontrol/base.html:408 +#: pretix/control/templates/pretixcontrol/base.html:406 msgid "" "Starting with version 1.2.0, pretix automatically checks for updates in the " "background. During this check, anonymous data is transmitted to servers " @@ -18104,20 +18900,20 @@ msgstr "" "الإلكتروني للحصول على إشعار عبر البريد الإلكتروني في حالة وصول التحديث " "الجديد. وسوف تختفي هذه الرسالة بمجرد النقر فوقه." -#: pretix/control/templates/pretixcontrol/base.html:421 +#: pretix/control/templates/pretixcontrol/base.html:419 msgid "" "Click here to do a license compliance check to make sure your usage of " "pretix is in line with pretix' license." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:430 +#: pretix/control/templates/pretixcontrol/base.html:428 msgid "" "The cronjob component of pretix was not executed in the last hours. Please " "check that you have completed all installation steps and your cronjob is " "executed correctly." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:439 +#: pretix/control/templates/pretixcontrol/base.html:437 msgid "" "pretix is running in debug mode. For security reasons, please never run " "debug mode on a production instance." @@ -18125,22 +18921,22 @@ msgstr "" "يشغل pretix في وضع التصحيح. لأسباب أمنية، من فضلك لا تشغيل وضع التصحيح على " "نسخة الإنتاج." -#: pretix/control/templates/pretixcontrol/base.html:445 +#: pretix/control/templates/pretixcontrol/base.html:443 msgid "" "For security reasons, please change your password before you continue. " "Afterwards you will be redirected to your original destination." msgstr "" -#: pretix/control/templates/pretixcontrol/base.html:457 +#: pretix/control/templates/pretixcontrol/base.html:455 #, python-format msgid "Times displayed in %(tz)s" msgstr "عرض مرة في %(tz)s" -#: pretix/control/templates/pretixcontrol/base.html:463 +#: pretix/control/templates/pretixcontrol/base.html:461 msgid "running in development mode" msgstr "يعمل في نمط التنمية" -#: pretix/control/templates/pretixcontrol/base.html:472 +#: pretix/control/templates/pretixcontrol/base.html:470 #: pretix/presale/templates/pretixpresale/fragment_modals.html:38 #: pretix/presale/templates/pretixpresale/postmessage.html:27 #: pretix/presale/templates/pretixpresale/waiting.html:42 @@ -18269,8 +19065,8 @@ msgid "Transaction ID" msgstr "المعاملات" #: pretix/control/templates/pretixcontrol/boxoffice/payment.html:98 -#: pretix/plugins/banktransfer/payment.py:463 -#: pretix/plugins/banktransfer/payment.py:472 +#: pretix/plugins/banktransfer/payment.py:297 +#: pretix/plugins/banktransfer/payment.py:306 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:32 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:33 msgid "Reference" @@ -18336,8 +19132,10 @@ msgstr[5] "" #: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:24 #: pretix/control/templates/pretixcontrol/checkin/list_delete.html:18 +#: pretix/control/templates/pretixcontrol/checkin/reset.html:43 +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:20 #: pretix/control/templates/pretixcontrol/email_setup_simple.html:76 -#: pretix/control/templates/pretixcontrol/event/tax_delete.html:17 +#: pretix/control/templates/pretixcontrol/event/tax_delete.html:16 #: pretix/control/templates/pretixcontrol/item/delete.html:11 #: pretix/control/templates/pretixcontrol/item/delete.html:38 #: pretix/control/templates/pretixcontrol/items/category_delete.html:14 @@ -18351,7 +19149,7 @@ msgstr[5] "" #: pretix/control/templates/pretixcontrol/order/change.html:543 #: pretix/control/templates/pretixcontrol/order/change_contact.html:25 #: pretix/control/templates/pretixcontrol/order/change_locale.html:30 -#: pretix/control/templates/pretixcontrol/order/change_questions.html:83 +#: pretix/control/templates/pretixcontrol/order/change_questions.html:84 #: pretix/control/templates/pretixcontrol/order/extend.html:25 #: pretix/control/templates/pretixcontrol/order/pay.html:34 #: pretix/control/templates/pretixcontrol/order/pay_complete.html:34 @@ -18375,7 +19173,7 @@ msgstr[5] "" #: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html:16 #: pretix/control/templates/pretixcontrol/organizers/team_delete.html:10 #: pretix/control/templates/pretixcontrol/organizers/team_delete.html:21 -#: pretix/control/templates/pretixcontrol/pdf/index.html:77 +#: pretix/control/templates/pretixcontrol/pdf/index.html:153 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:378 #: pretix/control/templates/pretixcontrol/subevents/delete.html:12 #: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html:41 @@ -18397,7 +19195,7 @@ msgstr[5] "" #: pretix/plugins/stripe/templates/pretixplugins/stripe/sca.html:38 #: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/delete.html:12 #: pretix/presale/templates/pretixpresale/event/order_change.html:22 -#: pretix/presale/templates/pretixpresale/event/order_modify.html:79 +#: pretix/presale/templates/pretixpresale/event/order_modify.html:80 #: pretix/presale/templates/pretixpresale/event/order_pay.html:23 #: pretix/presale/templates/pretixpresale/event/order_pay_change.html:60 #: pretix/presale/templates/pretixpresale/event/order_pay_confirm.html:40 @@ -18409,7 +19207,7 @@ msgstr "قم بالإلغاء" #: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:27 #: pretix/control/templates/pretixcontrol/checkin/list_delete.html:24 #: pretix/control/templates/pretixcontrol/event/delete.html:30 -#: pretix/control/templates/pretixcontrol/event/tax_delete.html:21 +#: pretix/control/templates/pretixcontrol/event/tax_delete.html:20 #: pretix/control/templates/pretixcontrol/item/delete.html:41 #: pretix/control/templates/pretixcontrol/items/categories.html:60 #: pretix/control/templates/pretixcontrol/items/category_delete.html:17 @@ -18431,7 +19229,7 @@ msgstr "قم بالإلغاء" #: pretix/control/templates/pretixcontrol/organizers/ssoclient_delete.html:20 #: pretix/control/templates/pretixcontrol/organizers/ssoprovider_delete.html:20 #: pretix/control/templates/pretixcontrol/organizers/team_delete.html:24 -#: pretix/control/templates/pretixcontrol/pdf/index.html:167 +#: pretix/control/templates/pretixcontrol/pdf/index.html:111 #: pretix/control/templates/pretixcontrol/subevents/delete.html:15 #: pretix/control/templates/pretixcontrol/subevents/delete_bulk.html:44 #: pretix/control/templates/pretixcontrol/user/2fa_delete.html:21 @@ -18440,7 +19238,7 @@ msgstr "قم بالإلغاء" #: pretix/control/templates/pretixcontrol/vouchers/delete_carts.html:16 #: pretix/control/templates/pretixcontrol/waitinglist/delete.html:15 #: pretix/control/templates/pretixcontrol/waitinglist/delete_bulk.html:36 -#: pretix/control/views/orders.py:382 +#: pretix/control/views/orders.py:387 #: pretix/plugins/autocheckin/templates/pretixplugins/autocheckin/delete.html:15 #: pretix/plugins/badges/templates/pretixplugins/badges/delete.html:16 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_delete.html:15 @@ -18522,19 +19320,19 @@ msgstr "اسم البنك" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:65 #: pretix/control/templates/pretixcontrol/checkin/simulator.html:49 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:14 -#: pretix/plugins/checkinlists/exporters.py:766 +#: pretix/plugins/checkinlists/exporters.py:767 msgid "Result" msgstr "النتيجة" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:78 -#: pretix/control/templates/pretixcontrol/order/index.html:392 +#: pretix/control/templates/pretixcontrol/order/index.html:432 #, fuzzy, python-format #| msgid "Automatically checked in: %(date)s" msgid "Automatically marked not present: %(date)s" msgstr "التحقق تلقائيا في: %(date)s" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:82 -#: pretix/control/templates/pretixcontrol/order/index.html:397 +#: pretix/control/templates/pretixcontrol/order/index.html:437 #, fuzzy, python-format #| msgid "First scanned: %(date)s" msgid "Additional entry scan: %(date)s" @@ -18547,7 +19345,7 @@ msgid "Offline scan. Upload time: %(date)s" msgstr "الممسوحة ضوئيا أولا: %(date)s" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:88 -#: pretix/control/templates/pretixcontrol/order/index.html:399 +#: pretix/control/templates/pretixcontrol/order/index.html:439 #, python-format msgid "Automatically checked in: %(date)s" msgstr "التحقق تلقائيا في: %(date)s" @@ -18574,6 +19372,8 @@ msgstr "أمر مرفوض" #: pretix/control/templates/pretixcontrol/checkin/checkins.html:152 #: pretix/control/templates/pretixcontrol/event/index.html:24 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:27 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:33 msgid "Copy to clipboard" msgstr "" @@ -18593,7 +19393,7 @@ msgstr "تعديل تشكيل القائمة" #: pretix/control/templates/pretixcontrol/checkin/index.html:22 #: pretix/control/templates/pretixcontrol/checkin/list_edit.html:21 -#: pretix/control/templates/pretixcontrol/checkin/lists.html:160 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:167 #: pretix/control/templates/pretixcontrol/checkin/simulator.html:8 #: pretix/control/templates/pretixcontrol/checkin/simulator.html:20 #, fuzzy @@ -18616,6 +19416,7 @@ msgid "No attendee record was found." msgstr "لم يتم العثور على سجل الحضور." #: pretix/control/templates/pretixcontrol/checkin/index.html:91 +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:19 #: pretix/control/templates/pretixcontrol/orders/index.html:127 #: pretix/control/templates/pretixcontrol/organizers/devices.html:68 #: pretix/control/templates/pretixcontrol/subevents/index.html:89 @@ -18823,7 +19624,15 @@ msgstr "إنشاء الاختيار في قائمة جديدة" msgid "Connected devices" msgstr "الأجهزة المتصلة" -#: pretix/control/templates/pretixcontrol/checkin/lists.html:156 +#: pretix/control/templates/pretixcontrol/checkin/lists.html:90 +#: pretix/control/templates/pretixcontrol/checkin/reset.html:4 +#: pretix/control/templates/pretixcontrol/checkin/reset.html:6 +#, fuzzy +#| msgid "Delete check-in list" +msgid "Reset check-in" +msgstr "الاختيار في حذف قائمة" + +#: pretix/control/templates/pretixcontrol/checkin/lists.html:163 #: pretix/control/templates/pretixcontrol/items/categories.html:57 #: pretix/control/templates/pretixcontrol/items/discounts.html:149 #: pretix/control/templates/pretixcontrol/items/index.html:165 @@ -18834,6 +19643,57 @@ msgstr "الأجهزة المتصلة" msgid "Clone" msgstr "استنساخ" +#: pretix/control/templates/pretixcontrol/checkin/reset.html:10 +msgid "" +"With this feature, you can reset the entire check-in state of the event. " +"This will delete all check-in records as well as all records of printed " +"tickets or badges. We recommend to use this feature after testing your " +"hardware setup but only before your event started, and you admitted any real " +"attendees or printed any real badges or tickets." +msgstr "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:18 +#, python-format +msgid "This will permanently delete 1 check-in." +msgid_plural "" +"This will permanently delete %(count)s check-ins." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:23 +#, python-format +msgid "Additionally, 1 print log will be deleted." +msgid_plural "" +"Additionally, %(count)s print logs will be deleted." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:30 +#, fuzzy +#| msgid "The pretix.eu server could not be reached." +msgid "This cannot be reverted!" +msgstr "ولم يتسن الوصول الى خادم pretix.eu." + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:34 +msgid "" +"The deleted entries will still show up in the \"Order history\" section, but " +"for all other purposes the system will behave as if they never existed." +msgstr "" + +#: pretix/control/templates/pretixcontrol/checkin/reset.html:46 +#, fuzzy +#| msgid "Proceed with checkout" +msgid "Proceed with reset" +msgstr "إتمام عملية الدفع" + #: pretix/control/templates/pretixcontrol/checkin/simulator.html:22 msgid "" "This tool allows you to validate your check-in configuration. You can enter " @@ -18911,6 +19771,120 @@ msgstr "عرض جميع سلسلة الحدث" msgid "Other features" msgstr "ميزات أخرى" +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:8 +#, fuzzy +#| msgid "Transfer to other order" +msgid "Data transfer to external systems" +msgstr "نقل إلى أمر آخر" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:18 +#: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:22 +#, fuzzy +#| msgid "Retry" +msgid "Retry now" +msgstr "أعد المحاولة" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:22 +#, fuzzy +#| msgid "Pay now" +msgid "Sync now" +msgstr "ادفع الآن" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:31 +#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:16 +#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:19 +#, fuzzy +#| msgid "Error:" +msgid "Error" +msgstr "خطأ:" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:34 +#, python-format +msgid "Error. Retry %(num)s of %(max)s." +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:38 +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:43 +#, fuzzy, python-format +#| msgid "Admission: %(datetime)s" +msgid "Waiting until %(datetime)s" +msgstr "القبول: %(datetime)s" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:49 +#, fuzzy, python-format +#| msgid "Admission: %(datetime)s" +msgid "triggered at %(datetime)s" +msgstr "القبول: %(datetime)s" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:62 +#, fuzzy +#| msgid "Internal identifier" +msgid "identified by" +msgstr "معرف داخلي" + +#: pretix/control/templates/pretixcontrol/datasync/control_order_info.html:68 +#, fuzzy +#| msgctxt "subevent" +#| msgid "No date selected." +msgid "No data transmitted." +msgstr "لم يتم تحديد تاريخ." + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:5 +msgid "Sync problems" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:7 +msgid "" +"On this page, we provide a list of orders where data synchronization to an " +"external system has failed. You can start another attempt to sync them " +"manually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:24 +#, fuzzy +#| msgid "Payment provider" +msgid "Sync provider" +msgstr "مقدم خدمة السداد" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:26 +#, fuzzy +#| msgid "Failed" +msgid "Failure mode" +msgstr "فشل" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:51 +#, python-format +msgid "Temporary error, will retry after %(datetime)s" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:63 +#, fuzzy +#| msgid "All products" +msgid "No problems." +msgstr "جميع المنتجات" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:74 +#, fuzzy +#| msgid "Delete selected" +msgid "Retry selected" +msgstr "احذف المختار" + +#: pretix/control/templates/pretixcontrol/datasync/failed_jobs.html:75 +#, fuzzy +#| msgid "Cancel event" +msgid "Cancel selected" +msgstr "حذف فعالية" + +#: pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html:31 +#: pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html:62 +msgid "Edit value mapping" +msgstr "" + +#: pretix/control/templates/pretixcontrol/datasync/property_mappings_formset.html:76 +#: pretix/control/templates/pretixcontrol/event/settings.html:487 +msgid "Add property" +msgstr "إضافة خاصية" + #: pretix/control/templates/pretixcontrol/email/email_setup.txt:1 #, python-format msgid "" @@ -19163,7 +20137,7 @@ msgstr "إعدادات إلغاء" msgid "Unpaid or free orders" msgstr "أوامر غير المدفوعة أو المجانية" -#: pretix/control/templates/pretixcontrol/event/cancel.html:39 +#: pretix/control/templates/pretixcontrol/event/cancel.html:40 msgid "" "If a user requests cancels a paid order and the money can not be refunded " "automatically, e.g. due to the selected payment method, you will need to " @@ -19174,67 +20148,67 @@ msgstr "" "سبيل المثال ويرجع ذلك إلى طريقة الدفع المختارة، وسوف تحتاج إلى اتخاذ إجراءات " "اليدوي. ومع ذلك، كنت قد تحولت حاليا من الإشعارات لهذا الحدث." -#: pretix/control/templates/pretixcontrol/event/cancel.html:45 +#: pretix/control/templates/pretixcontrol/event/cancel.html:46 #: pretix/control/templates/pretixcontrol/user/settings.html:29 msgid "Change notification settings" msgstr "إعدادات تغيير الإعلام" -#: pretix/control/templates/pretixcontrol/event/cancel.html:51 +#: pretix/control/templates/pretixcontrol/event/cancel.html:52 msgid "Order changes" msgstr "الترتيب يتغير" -#: pretix/control/templates/pretixcontrol/event/cancel.html:54 +#: pretix/control/templates/pretixcontrol/event/cancel.html:55 msgid "" "Allowing customers to change their own orders is a complex process due to " "the many different options pretix provides. Therefore, this feature " "currently has the following limitations:" msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:60 +#: pretix/control/templates/pretixcontrol/event/cancel.html:61 msgid "" "It is possible to switch to a different variation of the same product, but " "not to an entirely different product (except for add-on products)." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:61 +#: pretix/control/templates/pretixcontrol/event/cancel.html:62 msgid "" "Changing the seat or the event date in an event series will become available " "in the future, but is not possible now." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:62 +#: pretix/control/templates/pretixcontrol/event/cancel.html:63 msgid "" "If a change leads to a price change, there will not be a change to fees such " "as payment, service, or shipping fees, even though an additional payment " "might be required." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:63 +#: pretix/control/templates/pretixcontrol/event/cancel.html:64 msgid "" "If an add-on product is newly added, the system currently does not validate " "if there are required questions or fields that need to be filled out." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:64 +#: pretix/control/templates/pretixcontrol/event/cancel.html:65 msgid "" "Customers currently cannot switch to a product variation or add an add-on " "product that requires them to use a voucher or membership." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:65 +#: pretix/control/templates/pretixcontrol/event/cancel.html:66 msgid "" "Additional constraints and validation steps added by plugins are not " "enforced." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:76 +#: pretix/control/templates/pretixcontrol/event/cancel.html:77 msgid "" "If the change leads to a price reduction and automatic refunds are enabled " "for self-service cancellations, the system will try to refund the money " "automatically." msgstr "" -#: pretix/control/templates/pretixcontrol/event/cancel.html:80 +#: pretix/control/templates/pretixcontrol/event/cancel.html:81 msgid "" "Refunds can be issued as a gift card if the respective option is set, but " "there is no customer choice between gift card and direct refund." @@ -19499,42 +20473,115 @@ msgstr "" msgid "Show affected orders" msgstr "تظهر أوامر المتضررين" -#: pretix/control/templates/pretixcontrol/event/index.html:142 -#: pretix/control/templates/pretixcontrol/order/index.html:1004 +#: pretix/control/templates/pretixcontrol/event/index.html:84 +msgid "" +"Orders in this event could not be synced to an external system as configured." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/index.html:88 +msgid "Show sync problems" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/index.html:151 +#: pretix/control/templates/pretixcontrol/order/index.html:1062 msgid "Update comment" msgstr "تحديث تعليق" -#: pretix/control/templates/pretixcontrol/event/index.html:152 +#: pretix/control/templates/pretixcontrol/event/index.html:161 #: pretix/control/templates/pretixcontrol/event/logs.html:4 #: pretix/control/templates/pretixcontrol/event/logs.html:6 msgid "Event logs" msgstr "سجلات الأحداث" -#: pretix/control/templates/pretixcontrol/event/index.html:162 +#: pretix/control/templates/pretixcontrol/event/index.html:171 msgid "Show more logs" msgstr "عرض المزيد من السجلات" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:5 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:6 msgid "Invoice settings" msgstr "ضبط فاتورة" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:11 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:12 msgid "Invoice generation" msgstr "جيل فاتورة" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:26 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:27 msgid "Address form" msgstr "شكل عنوان" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:39 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:40 msgid "Issuer details" msgstr "تفاصيل المصدر" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:49 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:50 msgid "Invoice customization" msgstr "فاتورة التخصيص" -#: pretix/control/templates/pretixcontrol/event/invoicing.html:65 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:64 +#, fuzzy +#| msgid "Invoice generation" +msgid "Invoice transmission" +msgstr "جيل فاتورة" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:66 +msgid "" +"pretix can transmit invoices using different transmission methods. Different " +"transmission methods might be required depending on country and industry. By " +"default, sending invoices as PDF files via email is always available. Other " +"types of transmission can be added by plugins." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:73 +msgid "" +"Whether a transmission method listed here is actually selectable for " +"customers may depend on the country of the customer or whether the customer " +"is entering a business address." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:82 +#, fuzzy +#| msgid "Transaction Code" +msgid "Transmission method" +msgstr "كود المعاملة" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:98 +#: pretix/control/templates/pretixcontrol/event/invoicing.html:125 +#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:109 +#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:111 +msgid "Available" +msgstr "متاح" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:100 +msgid "" +"When this type is available for an invoice address, no other type can be " +"selected." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:101 +msgid "(exclusive)" +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:108 +#, fuzzy +#| msgid "Available" +msgid "Unavailable" +msgstr "متاح" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:130 +#, fuzzy +#| msgctxt "payment_state" +#| msgid "confirmed" +msgid "Not configured" +msgstr "تم التأكيد" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:152 +#, fuzzy +#| msgid "Enable waiting list" +msgid "Enable additional invoice transmission plugins" +msgstr "تمكين قائمة الانتظار" + +#: pretix/control/templates/pretixcontrol/event/invoicing.html:159 msgid "Save and show preview" msgstr "حفظ وعرض المعاينة" @@ -19675,9 +20722,9 @@ msgstr "تم إجراء هذا التغيير من قبل مسؤول pretix." #: pretix/control/templates/pretixcontrol/event/logs.html:86 #: pretix/control/templates/pretixcontrol/event/logs_embed.html:47 #: pretix/control/templates/pretixcontrol/includes/logs.html:42 -#: pretix/control/templates/pretixcontrol/order/index.html:793 -#: pretix/control/templates/pretixcontrol/order/index.html:805 -#: pretix/control/templates/pretixcontrol/order/index.html:910 +#: pretix/control/templates/pretixcontrol/order/index.html:845 +#: pretix/control/templates/pretixcontrol/order/index.html:857 +#: pretix/control/templates/pretixcontrol/order/index.html:962 #: pretix/control/templates/pretixcontrol/organizers/device_logs.html:42 #: pretix/control/templates/pretixcontrol/organizers/logs.html:72 #: pretix/control/templates/pretixcontrol/search/payments.html:147 @@ -19727,7 +20774,7 @@ msgstr "البريد الإلكتروني تصميم" #: pretix/control/templates/pretixcontrol/event/mail.html:79 #: pretix/control/templates/pretixcontrol/event/mail_settings_fragment.html:29 #: pretix/control/templates/pretixcontrol/event/tickets.html:35 -#: pretix/control/templates/pretixcontrol/pdf/index.html:540 +#: pretix/control/templates/pretixcontrol/pdf/index.html:41 #: pretix/control/templates/pretixcontrol/vouchers/bulk.html:97 #: pretix/control/templates/pretixcontrol/vouchers/bulk.html:120 msgid "Preview" @@ -19752,7 +20799,7 @@ msgstr "طلب مجاني" #: pretix/control/templates/pretixcontrol/event/mail.html:99 #: pretix/control/templates/pretixcontrol/order/index.html:249 -#: pretix/control/templates/pretixcontrol/order/index.html:532 +#: pretix/control/templates/pretixcontrol/order/index.html:584 msgid "Resend link" msgstr "رابط إعادة إرسال" @@ -19774,15 +20821,15 @@ msgstr "في انتظار إخطار قائمة" msgid "Order custom mail" msgstr "النظام الإلكتروني المخصص" -#: pretix/control/templates/pretixcontrol/event/mail.html:120 +#: pretix/control/templates/pretixcontrol/event/mail.html:123 msgid "Reminder to download tickets" msgstr "تذكير تذاكر تحميل" -#: pretix/control/templates/pretixcontrol/event/mail.html:123 +#: pretix/control/templates/pretixcontrol/event/mail.html:126 msgid "Order approval process" msgstr "عملية الموافقة أجل" -#: pretix/control/templates/pretixcontrol/event/mail.html:126 +#: pretix/control/templates/pretixcontrol/event/mail.html:129 #, fuzzy #| msgid "Attachment" msgid "Attachments" @@ -19858,6 +20905,7 @@ msgstr "" "ولا يمكن ان تمر على لعملائك." #: pretix/control/templates/pretixcontrol/event/plugins.html:6 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:6 #, fuzzy #| msgid "Available languages" msgid "Available plugins" @@ -19871,34 +20919,36 @@ msgid "" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:15 -#: pretix/control/views/checkin.py:423 pretix/control/views/discounts.py:113 -#: pretix/control/views/event.py:239 pretix/control/views/event.py:548 -#: pretix/control/views/event.py:587 pretix/control/views/event.py:734 -#: pretix/control/views/event.py:963 pretix/control/views/event.py:1334 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:15 +#: pretix/control/views/checkin.py:424 pretix/control/views/discounts.py:113 +#: pretix/control/views/event.py:246 pretix/control/views/event.py:576 +#: pretix/control/views/event.py:615 pretix/control/views/event.py:778 +#: pretix/control/views/event.py:1007 pretix/control/views/event.py:1380 +#: pretix/control/views/event.py:1420 #: pretix/control/views/global_settings.py:65 #: pretix/control/views/global_settings.py:88 pretix/control/views/item.py:264 #: pretix/control/views/item.py:795 pretix/control/views/item.py:1121 #: pretix/control/views/item.py:1299 pretix/control/views/item.py:1449 #: pretix/control/views/mailsetup.py:151 pretix/control/views/mailsetup.py:163 #: pretix/control/views/mailsetup.py:190 pretix/control/views/mailsetup.py:258 -#: pretix/control/views/organizer.py:260 pretix/control/views/organizer.py:288 -#: pretix/control/views/organizer.py:504 pretix/control/views/organizer.py:676 -#: pretix/control/views/organizer.py:1071 -#: pretix/control/views/organizer.py:1169 -#: pretix/control/views/organizer.py:1333 -#: pretix/control/views/organizer.py:2052 -#: pretix/control/views/organizer.py:2189 -#: pretix/control/views/organizer.py:2386 -#: pretix/control/views/organizer.py:2502 -#: pretix/control/views/organizer.py:2631 -#: pretix/control/views/organizer.py:2825 -#: pretix/control/views/organizer.py:2854 -#: pretix/control/views/organizer.py:2894 -#: pretix/control/views/organizer.py:2971 -#: pretix/control/views/organizer.py:3068 -#: pretix/control/views/organizer.py:3097 -#: pretix/control/views/organizer.py:3235 pretix/control/views/subevents.py:525 -#: pretix/control/views/subevents.py:1590 pretix/control/views/user.py:236 +#: pretix/control/views/organizer.py:272 pretix/control/views/organizer.py:300 +#: pretix/control/views/organizer.py:516 pretix/control/views/organizer.py:850 +#: pretix/control/views/organizer.py:945 pretix/control/views/organizer.py:1340 +#: pretix/control/views/organizer.py:1438 +#: pretix/control/views/organizer.py:1602 +#: pretix/control/views/organizer.py:2321 +#: pretix/control/views/organizer.py:2458 +#: pretix/control/views/organizer.py:2655 +#: pretix/control/views/organizer.py:2771 +#: pretix/control/views/organizer.py:2900 +#: pretix/control/views/organizer.py:3094 +#: pretix/control/views/organizer.py:3123 +#: pretix/control/views/organizer.py:3163 +#: pretix/control/views/organizer.py:3240 +#: pretix/control/views/organizer.py:3337 +#: pretix/control/views/organizer.py:3366 +#: pretix/control/views/organizer.py:3504 pretix/control/views/subevents.py:525 +#: pretix/control/views/subevents.py:1597 pretix/control/views/user.py:236 #: pretix/control/views/users.py:114 pretix/control/views/vouchers.py:305 #: pretix/plugins/autocheckin/views.py:164 pretix/plugins/badges/views.py:157 #: pretix/plugins/sendmail/views.py:645 pretix/plugins/stripe/views.py:679 @@ -19908,44 +20958,72 @@ msgid "Your changes have been saved." msgstr "تم حفظ التغييرات." #: pretix/control/templates/pretixcontrol/event/plugins.html:34 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:34 #, fuzzy #| msgid "Check results" msgid "Search results" msgstr "تأكد من النتائج" #: pretix/control/templates/pretixcontrol/event/plugins.html:56 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:56 msgid "Top recommendation" msgstr "" #: pretix/control/templates/pretixcontrol/event/plugins.html:60 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:60 #, fuzzy #| msgid "Features" msgid "Experimental feature" msgstr "المميزات" #: pretix/control/templates/pretixcontrol/event/plugins.html:83 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:106 msgid "Incompatible" msgstr "غير متوافق" #: pretix/control/templates/pretixcontrol/event/plugins.html:87 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:110 msgid "Not available" msgstr "غير متاح" #: pretix/control/templates/pretixcontrol/event/plugins.html:93 -#: pretix/control/templates/pretixcontrol/event/plugins.html:105 +#, fuzzy +#| msgid "This plugin cannot be enabled for the following reasons:" +msgid "This plugin can only be disabled for the entire organizer account." +msgstr "هذا البرنامج المساعد لا يمكن تمكين للأسباب التالية:" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:98 +msgid "" +"After disabling this plugin, some functionality may remain active in the " +"organizer account." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:104 +#: pretix/control/templates/pretixcontrol/event/plugins.html:116 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:122 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:134 #, fuzzy #| msgid "Login settings" msgid "Open plugin settings" msgstr "إعدادات تسجيل الدخول" -#: pretix/control/templates/pretixcontrol/event/plugins.html:94 +#: pretix/control/templates/pretixcontrol/event/plugins.html:105 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:123 #, fuzzy #| msgid "Go to shop" msgid "Go to" msgstr "الذهاب للتسوق" -#: pretix/control/templates/pretixcontrol/event/plugins.html:116 +#: pretix/control/templates/pretixcontrol/event/plugins.html:130 +#: pretix/control/templates/pretixcontrol/event/plugins.html:147 +#, fuzzy +#| msgid "Organizer settings" +msgid "Open in organizer settings" +msgstr "ضبط منظم" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:134 #: pretix/control/templates/pretixcontrol/oauth/app_delete.html:15 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:145 #: pretix/control/templates/pretixcontrol/user/2fa_disable.html:20 #: pretix/control/templates/pretixcontrol/user/2fa_main.html:79 #: pretix/control/templates/pretixcontrol/user/2fa_main.html:83 @@ -19954,7 +21032,22 @@ msgstr "الذهاب للتسوق" msgid "Disable" msgstr "تعطيل" -#: pretix/control/templates/pretixcontrol/event/plugins.html:121 +#: pretix/control/templates/pretixcontrol/event/plugins.html:141 +#: pretix/control/views/organizer.py:807 +#, fuzzy +#| msgid "This plugin cannot be enabled for the following reasons:" +msgid "This plugin can only be enabled for the entire organizer account." +msgstr "هذا البرنامج المساعد لا يمكن تمكين للأسباب التالية:" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:154 +msgid "" +"Enabling this plugin will enable some of its functionality for the entire " +"organizer account." +msgstr "" + +#: pretix/control/templates/pretixcontrol/event/plugins.html:159 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:157 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:177 #: pretix/control/templates/pretixcontrol/user/2fa_enable.html:21 #: pretix/control/templates/pretixcontrol/user/2fa_main.html:99 #: pretix/control/templates/pretixcontrol/user/notifications.html:23 @@ -20024,11 +21117,6 @@ msgstr "" "وذلك في قسم \"المنتجات\" في الملاحة. لا تقلق، يمكنك تغيير كل شيء يمكنك إدخال " "هنا." -#: pretix/control/templates/pretixcontrol/event/quick_setup.html:132 -#: pretix/control/views/event.py:381 -msgid "Features" -msgstr "المميزات" - #: pretix/control/templates/pretixcontrol/event/quick_setup.html:134 msgid "" "We recommend that you take some time to go through the \"Settings\" part of " @@ -20168,7 +21256,7 @@ msgid "Shop design" msgstr "تصميم متجر" #: pretix/control/templates/pretixcontrol/event/settings.html:232 -#: pretix/control/templates/pretixcontrol/events/create_basics.html:56 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:59 #: pretix/control/templates/pretixcontrol/subevents/bulk.html:411 #: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:96 #: pretix/control/templates/pretixcontrol/subevents/detail.html:54 @@ -20206,12 +21294,6 @@ msgctxt "subevents" msgid "Calendar and list views" msgstr "إعادة إرسال دعوة" -#: pretix/control/templates/pretixcontrol/event/settings.html:280 -#: pretix/control/templates/pretixcontrol/order/index.html:176 -#: pretix/presale/templates/pretixpresale/event/order.html:22 -msgid "Order details" -msgstr "تفاصيل الطلب" - #: pretix/control/templates/pretixcontrol/event/settings.html:284 msgid "Other settings" msgstr "إعدادات أخرى" @@ -20297,10 +21379,6 @@ msgstr "" msgid "Property" msgstr "إضافة خاصية" -#: pretix/control/templates/pretixcontrol/event/settings.html:487 -msgid "Add property" -msgstr "إضافة خاصية" - #: pretix/control/templates/pretixcontrol/event/settings.html:505 #: pretix/control/templates/pretixcontrol/events/index.html:165 #: pretix/control/templates/pretixcontrol/organizers/detail.html:130 @@ -20332,9 +21410,13 @@ msgstr "" "هل أنت متأكد أنك تريد حذف القاعدة الضريبية على %(taxrule)s؟" #: pretix/control/templates/pretixcontrol/event/tax_delete.html:12 +#, fuzzy +#| msgid "" +#| "You cannot delete a tax rule that is in use for a product or has been in " +#| "use for any existing orders." msgid "" -"You cannot delete a tax rule that is in use for a product or has been in use " -"for any existing orders." +"You cannot delete a tax rule that is in use for a product, has been in use " +"for any existing orders, or is the default tax rule of the event." msgstr "" "لا يمكنك حذف قاعدة الضريبية التي قيد الاستخدام لمنتج أو التي تم فيها استخدام " "أية أوامر القائمة." @@ -20418,16 +21500,22 @@ msgstr "لم تقم بإنشاء أي القواعد الضريبية حتى ا msgid "Create a new tax rule" msgstr "إنشاء قاعدة ضريبية جديدة" -#: pretix/control/templates/pretixcontrol/event/tax_index.html:27 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:28 msgid "Rate" msgstr "معدل" -#: pretix/control/templates/pretixcontrol/event/tax_index.html:41 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:51 +#: pretix/plugins/badges/templates/pretixplugins/badges/index.html:63 +#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:60 +msgid "Make default" +msgstr "وضع افتراضي" + +#: pretix/control/templates/pretixcontrol/event/tax_index.html:58 #, python-format msgid "incl. %(rate)s %%" msgstr "بما في ذلك %(rate)s%%" -#: pretix/control/templates/pretixcontrol/event/tax_index.html:43 +#: pretix/control/templates/pretixcontrol/event/tax_index.html:60 #, python-format msgid "excl. %(rate)s %%" msgstr "بما في ذلك%(rate)s%%" @@ -20561,7 +21649,7 @@ msgstr "معلومات عامة" msgid "Set to random" msgstr "تعيين إلى عشوائي" -#: pretix/control/templates/pretixcontrol/events/create_basics.html:18 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:21 #, fuzzy #| msgid "" #| "This is the address users can buy your tickets at. Should be short, only " @@ -20581,7 +21669,7 @@ msgstr "" "الأحداث. نوصي نوع من اختصار أو موعد مع أقل من 10 الأحرف التي يمكن تذكرها " "بسهولة، ولكن يمكنك أيضا اختيار لاستخدام قيمة عشوائية." -#: pretix/control/templates/pretixcontrol/events/create_basics.html:26 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:29 msgid "" "We will also use this in some places like order codes, invoice numbers or " "bank transfer references as an abbreviation to reference this event." @@ -20589,12 +21677,12 @@ msgstr "" "ونحن أيضا استخدام هذا في بعض الأماكن مثل رموز النظام، وأرقام الفواتير أو " "مراجع التحويل المصرفي كاختصار لمرجع هذا الحدث." -#: pretix/control/templates/pretixcontrol/events/create_basics.html:32 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:35 msgid "" "We strongly recommend against using short forms of more then 16 characters." msgstr "ونحن نوصي بشدة بعدم استخدام أشكال قصيرة من أكثر من 16 حرفا." -#: pretix/control/templates/pretixcontrol/events/create_basics.html:50 +#: pretix/control/templates/pretixcontrol/events/create_basics.html:53 msgid "Display settings" msgstr "اعدادات العرض" @@ -20682,7 +21770,7 @@ msgstr "تذاكر مدفوعة الأجر في الحصص" #: pretix/control/templates/pretixcontrol/events/index.html:121 #: pretix/control/templates/pretixcontrol/organizers/detail.html:97 -#: pretix/control/views/dashboards.py:519 pretix/control/views/typeahead.py:89 +#: pretix/control/views/dashboards.py:523 pretix/control/views/typeahead.py:89 msgctxt "subevent" msgid "No dates" msgstr "لا مواعيد" @@ -20694,14 +21782,14 @@ msgstr "المزيد من الحصص" #: pretix/control/templates/pretixcontrol/events/index.html:149 #: pretix/control/templates/pretixcontrol/organizers/detail.html:113 -#: pretix/control/views/dashboards.py:532 +#: pretix/control/views/dashboards.py:536 msgid "Shop disabled" msgstr "البيع متوقف الآن" #: pretix/control/templates/pretixcontrol/events/index.html:155 #: pretix/control/templates/pretixcontrol/organizers/detail.html:119 #: pretix/control/templates/pretixcontrol/subevents/index.html:172 -#: pretix/control/views/dashboards.py:538 +#: pretix/control/views/dashboards.py:542 msgid "On sale" msgstr "للبيع" @@ -21572,10 +22660,6 @@ msgstr "بيعت (في انتظار أوامر)" msgid "%(num)s available" msgstr "%(num)s هو متاح" -#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:11 -msgid "Unlimited" -msgstr "غير محدود" - #: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:14 msgid "Fully reserved" msgstr "محفوظة بالكامل" @@ -21661,8 +22745,8 @@ msgid "Can only be bought using a voucher" msgstr "لا يمكن إلا أن يكون اشترى استخدام قسيمة" #: pretix/control/templates/pretixcontrol/items/index.html:149 -#: pretix/control/templates/pretixcontrol/order/index.html:616 -#: pretix/control/templates/pretixcontrol/order/index.html:656 +#: pretix/control/templates/pretixcontrol/order/index.html:668 +#: pretix/control/templates/pretixcontrol/order/index.html:708 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:360 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:415 #, python-format @@ -21670,8 +22754,8 @@ msgid "plus %(rate)s%% %(taxname)s" msgstr " زائد %(rate)s%% %(taxname)s" #: pretix/control/templates/pretixcontrol/items/index.html:153 -#: pretix/control/templates/pretixcontrol/order/index.html:626 -#: pretix/control/templates/pretixcontrol/order/index.html:666 +#: pretix/control/templates/pretixcontrol/order/index.html:678 +#: pretix/control/templates/pretixcontrol/order/index.html:718 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:370 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:425 #, python-format @@ -21694,9 +22778,9 @@ msgstr "تحرير مسألة" #: pretix/control/templates/pretixcontrol/items/question.html:26 #: pretix/control/templates/pretixcontrol/orders/fragment_order_status.html:31 #: pretix/control/templates/pretixcontrol/orders/overview.html:88 -#: pretix/plugins/checkinlists/exporters.py:502 -#: pretix/plugins/checkinlists/exporters.py:696 -#: pretix/plugins/reports/exporters.py:386 +#: pretix/plugins/checkinlists/exporters.py:503 +#: pretix/plugins/checkinlists/exporters.py:697 +#: pretix/plugins/reports/exporters.py:397 #: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:23 msgid "Paid" msgstr "مدفوع" @@ -21727,9 +22811,9 @@ msgstr "عدد التذاكر" #: pretix/control/templates/pretixcontrol/items/question.html:112 #: pretix/control/templates/pretixcontrol/order/transactions.html:67 -#: pretix/plugins/reports/accountingreport.py:408 -#: pretix/plugins/reports/accountingreport.py:441 -#: pretix/plugins/reports/accountingreport.py:565 +#: pretix/plugins/reports/accountingreport.py:409 +#: pretix/plugins/reports/accountingreport.py:442 +#: pretix/plugins/reports/accountingreport.py:566 msgid "Sum" msgstr "" @@ -22104,7 +23188,7 @@ msgstr "نعم، والموافقة على النظام" #: pretix/control/templates/pretixcontrol/order/cancel.html:10 #: pretix/control/templates/pretixcontrol/order/index.html:68 #: pretix/control/templates/pretixcontrol/order/index.html:166 -#: pretix/presale/templates/pretixpresale/event/order.html:479 +#: pretix/presale/templates/pretixpresale/event/order.html:483 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:7 msgid "Cancel order" msgstr "الغاء الطلب" @@ -22287,7 +23371,7 @@ msgid "Validity time" msgstr "حتى تاريخ" #: pretix/control/templates/pretixcontrol/order/change.html:247 -#: pretix/control/templates/pretixcontrol/order/index.html:455 +#: pretix/control/templates/pretixcontrol/order/index.html:495 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:107 #, fuzzy, python-format #| msgid "Admission: %(datetime)s" @@ -22295,7 +23379,7 @@ msgid "Valid from %(datetime)s" msgstr "القبول: %(datetime)s" #: pretix/control/templates/pretixcontrol/order/change.html:255 -#: pretix/control/templates/pretixcontrol/order/index.html:459 +#: pretix/control/templates/pretixcontrol/order/index.html:499 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:111 #, fuzzy, python-format #| msgid "Admission: %(datetime)s" @@ -22348,7 +23432,7 @@ msgid "Add fee" msgstr "رسوم إضافية" #: pretix/control/templates/pretixcontrol/order/change.html:520 -#: pretix/control/templates/pretixcontrol/order/change_questions.html:65 +#: pretix/control/templates/pretixcontrol/order/change_questions.html:66 msgid "Other operations" msgstr "عمليات أخرى" @@ -22379,8 +23463,8 @@ msgid "Change order information" msgstr "المعلومات تغيير النظام" #: pretix/control/templates/pretixcontrol/order/change_questions.html:25 -#: pretix/control/templates/pretixcontrol/order/index.html:940 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:75 +#: pretix/control/templates/pretixcontrol/order/index.html:992 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:74 #: pretix/presale/templates/pretixpresale/event/checkout_questions.html:35 #: pretix/presale/templates/pretixpresale/event/order_modify.html:29 msgid "Invoice information" @@ -22432,13 +23516,13 @@ msgstr "تفاصيل الطلب: %(code)s" #: pretix/control/templates/pretixcontrol/order/index.html:46 #: pretix/control/templates/pretixcontrol/orders/index.html:297 -#: pretix/control/views/orders.py:310 +#: pretix/control/views/orders.py:311 msgid "Approve" msgstr "يوافق" #: pretix/control/templates/pretixcontrol/order/index.html:51 #: pretix/control/templates/pretixcontrol/orders/index.html:304 -#: pretix/control/views/orders.py:324 +#: pretix/control/views/orders.py:325 msgid "Deny" msgstr "أنكر" @@ -22483,7 +23567,7 @@ msgstr "" "المجانية، يمكنك وضع علامة على أنها منتهية الصلاحية يدويا." #: pretix/control/templates/pretixcontrol/order/index.html:116 -#: pretix/control/views/orders.py:372 +#: pretix/control/views/orders.py:373 #, fuzzy #| msgid "Refund order" msgid "Refund for overpayment" @@ -22563,137 +23647,181 @@ msgstr "" "ونحن نعلم أن عنوان البريد الإلكتروني هذا يعمل لأن المستخدم النقر على الرابط " "أرسلنا لهم." -#: pretix/control/templates/pretixcontrol/order/index.html:276 +#: pretix/control/templates/pretixcontrol/order/index.html:278 msgid "" "We don't know if this invoice was emailed to the customer since it was " "created before our system tracked this information" msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:281 +#: pretix/control/templates/pretixcontrol/order/index.html:283 #, fuzzy #| msgid "Canceled by customer" msgid "Invoice was emailed to customer" msgstr "تم الإلغاء من قبل العميل" -#: pretix/control/templates/pretixcontrol/order/index.html:286 +#: pretix/control/templates/pretixcontrol/order/index.html:288 #, fuzzy #| msgid "Ticket download is not (yet) enabled for this order." msgid "Invoice was not yet emailed to customer" msgstr "لم يتم تمكين تنزيل التذاكر (حتى الآن) لهذا الطلب." -#: pretix/control/templates/pretixcontrol/order/index.html:296 +#: pretix/control/templates/pretixcontrol/order/index.html:294 +#, fuzzy +#| msgid "The webhook has been created." +msgid "Invoice is scheduled to be transmitted" +msgstr "تم إنشاء خطاف الويب." + +#: pretix/control/templates/pretixcontrol/order/index.html:299 +#, fuzzy +#| msgid "Ticket download is not (yet) enabled for this order." +msgid "Invoice is not yet transmitted" +msgstr "لم يتم تمكين تنزيل التذاكر (حتى الآن) لهذا الطلب." + +#: pretix/control/templates/pretixcontrol/order/index.html:302 +#, fuzzy +#| msgid "This ticket shop is currently disabled." +msgid "Invoice is currently in transmission" +msgstr "متجر التذاكر هذا معطل حاليا." + +#: pretix/control/templates/pretixcontrol/order/index.html:307 +#, fuzzy +#| msgid "live and in test mode" +msgid "Invoice not transmitted in test mode" +msgstr "يعيش وفي وضع الاختبار" + +#: pretix/control/templates/pretixcontrol/order/index.html:312 +#, fuzzy +#| msgid "Device registration failed." +msgid "Invoice transmission failed" +msgstr "فشل تسجيل الجهاز." + +#: pretix/control/templates/pretixcontrol/order/index.html:317 +#, fuzzy +#| msgid "An invoice has been generated." +msgid "Invoice has been transmitted" +msgstr "تم إنشاء فاتورة." + +#: pretix/control/templates/pretixcontrol/order/index.html:329 +#, fuzzy +#| msgctxt "refund_state" +#| msgid "in transit" +msgid "Transmit" +msgstr "قيد الإرسال" + +#: pretix/control/templates/pretixcontrol/order/index.html:331 +#, fuzzy +#| msgctxt "refund_state" +#| msgid "in transit" +msgid "Retransmit" +msgstr "قيد الإرسال" + +#: pretix/control/templates/pretixcontrol/order/index.html:342 msgid "Rebuild the invoice with updated data but the same invoice number." msgstr "إعادة بناء الفاتورة مع البيانات المحدثة ولكن نفس رقم الفاتورة." -#: pretix/control/templates/pretixcontrol/order/index.html:297 +#: pretix/control/templates/pretixcontrol/order/index.html:343 #: pretix/control/templates/pretixcontrol/user/2fa_regenemergency.html:20 msgid "Regenerate" msgstr "تجديد" -#: pretix/control/templates/pretixcontrol/order/index.html:308 +#: pretix/control/templates/pretixcontrol/order/index.html:354 msgid "" "Generate a cancellation document for this invoice and create a new invoice " "with a new invoice number." msgstr "" "توليد وثيقة الإلغاء لهذه الفاتورة وإنشاء فاتورة جديدة مع رقم الفاتورة الجديد." -#: pretix/control/templates/pretixcontrol/order/index.html:311 +#: pretix/control/templates/pretixcontrol/order/index.html:357 msgid "Generate cancellation" msgstr "توليد إلغاء" -#: pretix/control/templates/pretixcontrol/order/index.html:313 +#: pretix/control/templates/pretixcontrol/order/index.html:359 msgid "Cancel and reissue" msgstr "إلغاء وإعادة إصدار" -#: pretix/control/templates/pretixcontrol/order/index.html:326 -#, fuzzy -#| msgid "All invoices" -msgid "Email invoices" -msgstr "جميع الفواتير" - -#: pretix/control/templates/pretixcontrol/order/index.html:335 -#: pretix/control/templates/pretixcontrol/order/index.html:347 +#: pretix/control/templates/pretixcontrol/order/index.html:375 +#: pretix/control/templates/pretixcontrol/order/index.html:387 msgid "Generate invoice" msgstr "توليد فاتورة" -#: pretix/control/templates/pretixcontrol/order/index.html:361 +#: pretix/control/templates/pretixcontrol/order/index.html:401 msgid "Change answers" msgstr "الإجابات التغيير" -#: pretix/control/templates/pretixcontrol/order/index.html:365 +#: pretix/control/templates/pretixcontrol/order/index.html:405 msgid "Change products" msgstr "منتجات التغيير" -#: pretix/control/templates/pretixcontrol/order/index.html:370 +#: pretix/control/templates/pretixcontrol/order/index.html:410 #: pretix/presale/templates/pretixpresale/event/order.html:197 msgid "Ordered items" msgstr "تفاصيل الطلب" -#: pretix/control/templates/pretixcontrol/order/index.html:389 +#: pretix/control/templates/pretixcontrol/order/index.html:429 #, fuzzy, python-format #| msgid "First scanned: %(date)s" msgid "Denied scan: %(date)s" msgstr "الممسوحة ضوئيا أولا: %(date)s" -#: pretix/control/templates/pretixcontrol/order/index.html:394 +#: pretix/control/templates/pretixcontrol/order/index.html:434 #, fuzzy, python-format #| msgid "First scanned: %(date)s" msgid "Exit scan: %(date)s" msgstr "الممسوحة ضوئيا أولا: %(date)s" -#: pretix/control/templates/pretixcontrol/order/index.html:401 +#: pretix/control/templates/pretixcontrol/order/index.html:441 #, fuzzy, python-format #| msgid "First scanned: %(date)s" msgid "Entry scan: %(date)s" msgstr "الممسوحة ضوئيا أولا: %(date)s" -#: pretix/control/templates/pretixcontrol/order/index.html:420 +#: pretix/control/templates/pretixcontrol/order/index.html:460 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:55 msgid "Voucher code used:" msgstr "كود القسيمة المستخدمة:" -#: pretix/control/templates/pretixcontrol/order/index.html:422 +#: pretix/control/templates/pretixcontrol/order/index.html:462 #, fuzzy, python-format #| msgid "Maximum discount budget" msgid "Used %(amount)s discount from budget" msgstr "الحد الأقصى للخصم" -#: pretix/control/templates/pretixcontrol/order/index.html:439 +#: pretix/control/templates/pretixcontrol/order/index.html:479 msgid "" "The price of this product was reduced because of an automatic discount or " "this product was part of the discount calculation for a different product in " "this order." msgstr "" -#: pretix/control/templates/pretixcontrol/order/index.html:451 +#: pretix/control/templates/pretixcontrol/order/index.html:491 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:103 #, fuzzy, python-format #| msgid "Admission: %(datetime)s" msgid "Valid %(datetime_range)s" msgstr "القبول: %(datetime)s" -#: pretix/control/templates/pretixcontrol/order/index.html:497 +#: pretix/control/templates/pretixcontrol/order/index.html:537 #, fuzzy #| msgid "Client secret" msgid "Ticket page" msgstr "كلمة سر الزبون" -#: pretix/control/templates/pretixcontrol/order/index.html:516 -#: pretix/control/templates/pretixcontrol/order/index.html:537 -#: pretix/control/templates/pretixcontrol/order/index.html:546 -#: pretix/control/templates/pretixcontrol/order/index.html:560 +#: pretix/control/templates/pretixcontrol/order/index.html:568 +#: pretix/control/templates/pretixcontrol/order/index.html:589 #: pretix/control/templates/pretixcontrol/order/index.html:598 -#: pretix/control/templates/pretixcontrol/order/index.html:605 +#: pretix/control/templates/pretixcontrol/order/index.html:612 +#: pretix/control/templates/pretixcontrol/order/index.html:650 +#: pretix/control/templates/pretixcontrol/order/index.html:657 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:228 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:234 msgid "not answered" msgstr "بلا جواب" -#: pretix/control/templates/pretixcontrol/order/index.html:570 +#: pretix/control/templates/pretixcontrol/order/index.html:622 msgid "This question will be asked during check-in." msgstr "سوف يتم طرح هذا السؤال أثناء التسجيل في مكتب الاستقبال." -#: pretix/control/templates/pretixcontrol/order/index.html:582 +#: pretix/control/templates/pretixcontrol/order/index.html:634 msgid "" "This file has been uploaded by a user and could contain viruses or other " "malicious content." @@ -22701,43 +23829,43 @@ msgstr "" "وقد تم تحميل هذا الملف من قبل المستخدم، ويمكن أن تحتوي على فيروسات أو غيرها " "من المحتويات الضارة." -#: pretix/control/templates/pretixcontrol/order/index.html:583 +#: pretix/control/templates/pretixcontrol/order/index.html:635 msgid "UNSAFE" msgstr "UNSAFE" -#: pretix/control/templates/pretixcontrol/order/index.html:687 +#: pretix/control/templates/pretixcontrol/order/index.html:739 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:453 msgid "Taxes" msgstr "الضرائب" -#: pretix/control/templates/pretixcontrol/order/index.html:696 +#: pretix/control/templates/pretixcontrol/order/index.html:748 #: pretix/control/templates/pretixcontrol/orders/overview.html:89 #: pretix/control/templates/pretixcontrol/orders/overview.html:177 -#: pretix/plugins/reports/accountingreport.py:498 -#: pretix/plugins/reports/exporters.py:386 -#: pretix/plugins/reports/exporters.py:435 -#: pretix/plugins/reports/exporters.py:627 -#: pretix/plugins/reports/exporters.py:957 +#: pretix/plugins/reports/accountingreport.py:499 +#: pretix/plugins/reports/exporters.py:397 +#: pretix/plugins/reports/exporters.py:446 +#: pretix/plugins/reports/exporters.py:638 +#: pretix/plugins/reports/exporters.py:968 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:465 msgid "Total" msgstr "المجموع" -#: pretix/control/templates/pretixcontrol/order/index.html:706 +#: pretix/control/templates/pretixcontrol/order/index.html:758 #: pretix/presale/templates/pretixpresale/event/order.html:210 msgid "Successful payments" msgstr "المدفوعات ناجحة" -#: pretix/control/templates/pretixcontrol/order/index.html:715 +#: pretix/control/templates/pretixcontrol/order/index.html:767 #: pretix/presale/templates/pretixpresale/event/order.html:219 msgid "Pending total" msgstr "مجموعه انتظار" -#: pretix/control/templates/pretixcontrol/order/index.html:741 +#: pretix/control/templates/pretixcontrol/order/index.html:793 #: pretix/control/templates/pretixcontrol/search/payments.html:88 msgid "Confirmation date" msgstr "تاريخ تأكيدا" -#: pretix/control/templates/pretixcontrol/order/index.html:754 +#: pretix/control/templates/pretixcontrol/order/index.html:806 #: pretix/control/templates/pretixcontrol/search/payments.html:125 msgid "" "This payment was created with an older version of pretix, therefore accurate " @@ -22746,71 +23874,71 @@ msgstr "" "تم إنشاء هذا المبلغ مع نسخة قديمة من pretix، وبالتالي قد لا تكون البيانات " "دقيقة المتاحة." -#: pretix/control/templates/pretixcontrol/order/index.html:755 +#: pretix/control/templates/pretixcontrol/order/index.html:807 #: pretix/control/templates/pretixcontrol/search/payments.html:126 msgid "MIGRATED" msgstr "هاجر" -#: pretix/control/templates/pretixcontrol/order/index.html:767 +#: pretix/control/templates/pretixcontrol/order/index.html:819 #: pretix/control/templates/pretixcontrol/order/pay_cancel.html:4 #: pretix/control/templates/pretixcontrol/order/pay_cancel.html:8 msgid "Cancel payment" msgstr "الغاء الدفع" -#: pretix/control/templates/pretixcontrol/order/index.html:772 +#: pretix/control/templates/pretixcontrol/order/index.html:824 msgid "Confirm as paid" msgstr "تأكيد كما المدفوعة" -#: pretix/control/templates/pretixcontrol/order/index.html:815 +#: pretix/control/templates/pretixcontrol/order/index.html:867 msgid "Create a refund" msgstr "إنشاء استرداد" -#: pretix/control/templates/pretixcontrol/order/index.html:836 +#: pretix/control/templates/pretixcontrol/order/index.html:888 #: pretix/control/templates/pretixcontrol/orders/refunds.html:60 msgid "Source" msgstr "مصدر" -#: pretix/control/templates/pretixcontrol/order/index.html:869 +#: pretix/control/templates/pretixcontrol/order/index.html:921 msgid "Cancel transfer" msgstr "إلغاء نقل" -#: pretix/control/templates/pretixcontrol/order/index.html:874 +#: pretix/control/templates/pretixcontrol/order/index.html:926 #: pretix/control/templates/pretixcontrol/orders/refunds.html:112 msgid "Confirm as done" msgstr "تأكيد كما القيام به" -#: pretix/control/templates/pretixcontrol/order/index.html:881 +#: pretix/control/templates/pretixcontrol/order/index.html:933 #: pretix/control/templates/pretixcontrol/orders/refunds.html:118 msgid "Ignore" msgstr "تجاهل" -#: pretix/control/templates/pretixcontrol/order/index.html:887 +#: pretix/control/templates/pretixcontrol/order/index.html:939 #: pretix/control/templates/pretixcontrol/order/refund_process.html:58 #: pretix/control/templates/pretixcontrol/orders/refunds.html:123 msgid "Process refund" msgstr "عملية استرداد الأموال" -#: pretix/control/templates/pretixcontrol/order/index.html:935 +#: pretix/control/templates/pretixcontrol/order/index.html:987 #: pretix/presale/templates/pretixpresale/event/base.html:141 #: pretix/presale/templates/pretixpresale/event/timemachine.html:30 msgid "Change" msgstr "يتغيرون" -#: pretix/control/templates/pretixcontrol/order/index.html:951 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:91 +#: pretix/control/templates/pretixcontrol/order/index.html:1003 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:90 #: pretix/presale/templates/pretixpresale/event/order.html:318 msgid "ZIP code and city" msgstr "الرمز البريدي والمدينة" -#: pretix/control/templates/pretixcontrol/order/index.html:964 +#: pretix/control/templates/pretixcontrol/order/index.html:1016 msgid "Valid EU VAT ID" msgstr "صحيح معرف ضريبة القيمة المضافة في الاتحاد الأوروبي" -#: pretix/control/templates/pretixcontrol/order/index.html:970 +#: pretix/control/templates/pretixcontrol/order/index.html:1022 msgid "Check" msgstr "التحقق من" -#: pretix/control/templates/pretixcontrol/order/index.html:1018 +#: pretix/control/templates/pretixcontrol/order/index.html:1076 msgid "Order history" msgstr "تاريخ الطلب" @@ -23676,14 +24804,14 @@ msgid "Select action" msgstr "اختر ولايه" #: pretix/control/templates/pretixcontrol/orders/index.html:311 -#: pretix/control/views/orders.py:356 +#: pretix/control/views/orders.py:357 #, fuzzy #| msgid "Refund full paid amount" msgid "Refund overpaid amount" msgstr "برد المبلغ المدفوع كاملا" #: pretix/control/templates/pretixcontrol/orders/index.html:319 -#: pretix/control/views/orders.py:341 +#: pretix/control/views/orders.py:342 msgid "Mark as expired if overdue" msgstr "" @@ -23711,7 +24839,7 @@ msgid "Revenue (net)" msgstr "الإيرادات (صافي)" #: pretix/control/templates/pretixcontrol/orders/overview.html:49 -#: pretix/plugins/reports/exporters.py:465 +#: pretix/plugins/reports/exporters.py:476 msgid "" "Filtering this report by date is not recommended as it might lead to " "misleading information since this report only sees the current state of any " @@ -23730,7 +24858,7 @@ msgstr "" "والتي تعود التي ينتمون إليها." #: pretix/control/templates/pretixcontrol/orders/overview.html:80 -#: pretix/plugins/reports/exporters.py:382 +#: pretix/plugins/reports/exporters.py:393 msgid "Purchased" msgstr "اشترى" @@ -24049,11 +25177,11 @@ msgstr "" msgid "System URL:" msgstr "URL النظام:" -#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:25 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:30 msgid "Token:" msgstr "رمز:" -#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:31 +#: pretix/control/templates/pretixcontrol/organizers/device_connect.html:40 msgid "Device overview" msgstr "نظرة عامة الجهاز" @@ -24580,6 +25708,79 @@ msgid "" "This can be used to enable products like year passes, tickets of ten, etc." msgstr "" +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:6 +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:12 +#, fuzzy, python-format +#| msgid "Event timezone" +msgid "Events with plugin %(name)s" +msgstr "توقيت الحدث" + +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:18 +#, python-format +msgid "" +"The plugin \"%(name)s\" can be enabled or disabled for every event " +"individually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:24 +#, python-format +msgid "" +"The plugin \"%(name)s\" is enabled for your organizer account, but also " +"needs to be enabled for the specific events you want to use it with." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugin_events.html:31 +msgid "" +"Using this form, you can quickly enable or disable it for many events. Note " +"that it might still be necessary to configure the plugin for each event " +"individually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:8 +msgid "" +"On this page, you can choose plugins you want to enable for your organizer " +"account. Plugins might bring additional software functionality, connect your " +"events to third-party services, or apply other forms of customizations." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:80 +#, fuzzy +#| msgid "All events" +msgid "Active (all events)" +msgstr "كل الأحداث" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:85 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:94 +#, fuzzy, python-format +#| msgid "%(count)s elements" +msgid "Active (%(count)s event)" +msgid_plural "Active (%(count)s events)" +msgstr[0] "%(count)s العناصر" +msgstr[1] "%(count)s العناصر" +msgstr[2] "%(count)s العناصر" +msgstr[3] "%(count)s العناصر" +msgstr[4] "%(count)s العناصر" +msgstr[5] "%(count)s العناصر" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:116 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:173 +msgid "" +"Parts of this plugin can be enabled or disabled for events individually." +msgstr "" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:149 +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:167 +#, fuzzy +#| msgid "Upcoming events" +msgid "Manage events" +msgstr "الفعاليات القادمة" + +#: pretix/control/templates/pretixcontrol/organizers/plugins.html:162 +#, fuzzy +#| msgid "This plugin cannot be enabled for the following reasons:" +msgid "This plugin can be enabled or disabled for events individually." +msgstr "هذا البرنامج المساعد لا يمكن تمكين للأسباب التالية:" + #: pretix/control/templates/pretixcontrol/organizers/properties.html:7 msgid "" "You can here define a set of metadata properties (i.e. variables) that you " @@ -24907,12 +26108,6 @@ msgstr[3] "تم إنشاء خطاف الويب." msgstr[4] "تم إنشاء خطاف الويب." msgstr[5] "تم إنشاء خطاف الويب." -#: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:22 -#, fuzzy -#| msgid "Retry" -msgid "Retry now" -msgstr "أعد المحاولة" - #: pretix/control/templates/pretixcontrol/organizers/webhook_logs.html:25 #, fuzzy #| msgid "Stop impersonating" @@ -25012,35 +26207,76 @@ msgstr "تظهر في الصفحة:" msgid "Page %(page)s" msgstr "الصفحة %(page)s" -#: pretix/control/templates/pretixcontrol/pdf/index.html:5 -#: pretix/control/templates/pretixcontrol/pdf/index.html:15 +#: pretix/control/templates/pretixcontrol/pdf/index.html:6 +#: pretix/control/templates/pretixcontrol/pdf/index.html:16 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:5 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:15 msgid "PDF Editor" msgstr "PDF محرر" -#: pretix/control/templates/pretixcontrol/pdf/index.html:31 +#: pretix/control/templates/pretixcontrol/pdf/index.html:36 #: pretix/plugins/banktransfer/refund_export.py:46 msgid "Code" msgstr "الشفرة" -#: pretix/control/templates/pretixcontrol/pdf/index.html:35 -msgid "Paste" -msgstr "معجون" +#: pretix/control/templates/pretixcontrol/pdf/index.html:52 +#, fuzzy +#| msgid "Text color" +msgid "Text box" +msgstr "لون الخط" -#: pretix/control/templates/pretixcontrol/pdf/index.html:39 +#: pretix/control/templates/pretixcontrol/pdf/index.html:59 +#, fuzzy +#| msgid "Code" +msgid "QR Code" +msgstr "الشفرة" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:64 +msgid "QR code for Check-In" +msgstr "رمز الاستجابة السريعة لتسلم الغرف" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:71 +msgid "QR code for Lead Scanning" +msgstr "رمز الاستجابة السريعة لالضوئي الرصاص" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:78 +#, fuzzy +#| msgid "Order code" +msgid "Other QR code" +msgstr "رمز الطلب" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:87 +msgid "Image" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:92 +msgid "" +"You can use this to add user-uploaded pictures from questions or pictures " +"generated by plugins. If you want to embed a logo or other images, use a " +"custom background instead." +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:93 +msgid "Dynamic image" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:100 +msgid "pretix Logo" +msgstr "pretix شعار" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:107 +msgid "Duplicate" +msgstr "" + +#: pretix/control/templates/pretixcontrol/pdf/index.html:117 msgid "Undo" msgstr "تراجع" -#: pretix/control/templates/pretixcontrol/pdf/index.html:43 +#: pretix/control/templates/pretixcontrol/pdf/index.html:121 msgid "Redo" msgstr "الإعادة" -#: pretix/control/templates/pretixcontrol/pdf/index.html:48 -msgid "Editor" -msgstr "محرر" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:66 +#: pretix/control/templates/pretixcontrol/pdf/index.html:142 msgid "" "This feature is only intended for advanced users. We recommend to only use " "it to copy and share ticket designs, not to modify the design source code." @@ -25048,19 +26284,19 @@ msgstr "" "والغرض من هذه الميزة فقط للمستخدمين المتقدمين. من المستحسن استخدامه فقط لنسخ " "والتصاميم حصة التذاكر، وليس لتعديل التعليمات البرمجية المصدر التصميم." -#: pretix/control/templates/pretixcontrol/pdf/index.html:80 +#: pretix/control/templates/pretixcontrol/pdf/index.html:156 msgid "Apply" msgstr "تطبيق" -#: pretix/control/templates/pretixcontrol/pdf/index.html:88 +#: pretix/control/templates/pretixcontrol/pdf/index.html:164 msgid "Uploading new PDF background…" msgstr "تحميل خلفية PDF جديدة ..." -#: pretix/control/templates/pretixcontrol/pdf/index.html:96 +#: pretix/control/templates/pretixcontrol/pdf/index.html:172 msgid "Welcome to the PDF ticket editor!" msgstr "أهلا وسهلا بك إلى المحرر PDF تذكرة!" -#: pretix/control/templates/pretixcontrol/pdf/index.html:98 +#: pretix/control/templates/pretixcontrol/pdf/index.html:174 msgid "" "This editor allows you to create a design for the PDF tickets of your event. " "You can upload a background PDF and then use this tool to place texts and a " @@ -25070,7 +26306,7 @@ msgstr "" "تحميل خلفية PDF ومن ثم استخدام هذه الأداة لنصوص المكان ورمز الاستجابة " "السريعة على التذكرة." -#: pretix/control/templates/pretixcontrol/pdf/index.html:109 +#: pretix/control/templates/pretixcontrol/pdf/index.html:185 msgid "" "Please note that the editor can only provide a rough preview. Some details, " "for example in text rendering, might look slightly different in the final " @@ -25081,7 +26317,7 @@ msgstr "" "المثال في تقديم النص، قد تبدو مختلفة قليلا في تذاكر النهائي. يمكنك استخدام " "زر \"معاينة\" على اليمين لمعاينة أكثر دقة." -#: pretix/control/templates/pretixcontrol/pdf/index.html:123 +#: pretix/control/templates/pretixcontrol/pdf/index.html:199 msgid "" "The editor is tested with recent versions of Google Chrome, Mozilla Firefox " "and Opera. Other browsers, especially Internet Explorer or Microsoft Edge, " @@ -25092,7 +26328,7 @@ msgstr "" "وأوبرا. المتصفحات الأخرى، وخاصة برنامج Internet Explorer أو Microsoft " "الحافة، قد تواجه مشاكل في عرض خلفيتك PDF أو تحميل الخطوط الصحيحة." -#: pretix/control/templates/pretixcontrol/pdf/index.html:131 +#: pretix/control/templates/pretixcontrol/pdf/index.html:207 msgid "" "The editor requires JavaScript to work. Please enable JavaScript in your " "browser to continue." @@ -25100,101 +26336,92 @@ msgstr "" "يتطلب محرر جافا سكريبت لعمل. الرجاء تمكين جافا سكريبت في المتصفح الخاص بك " "للمتابعة." -#: pretix/control/templates/pretixcontrol/pdf/index.html:141 -#: pretix/control/templates/pretixcontrol/pdf/index.html:173 +#: pretix/control/templates/pretixcontrol/pdf/index.html:217 +#: pretix/control/templates/pretixcontrol/pdf/index.html:233 msgid "Loading…" msgstr "جار التحميل…" -#: pretix/control/templates/pretixcontrol/pdf/index.html:144 +#: pretix/control/templates/pretixcontrol/pdf/index.html:220 msgid "Start editing" msgstr "بدء التعديل" -#: pretix/control/templates/pretixcontrol/pdf/index.html:159 -msgid "Cut" -msgstr "يقطع" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:163 -#: pretix/control/templates/pretixcontrol/vouchers/detail.html:54 -msgid "Copy" -msgstr "نسخ" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:180 +#: pretix/control/templates/pretixcontrol/pdf/index.html:240 #, fuzzy #| msgid "Seat name" msgid "Layout name" msgstr "اسم المقعد" -#: pretix/control/templates/pretixcontrol/pdf/index.html:187 +#: pretix/control/templates/pretixcontrol/pdf/index.html:247 #, fuzzy #| msgid "Use languages" msgid "Preferred language" msgstr "استخدام اللغات" -#: pretix/control/templates/pretixcontrol/pdf/index.html:200 -#: pretix/control/templates/pretixcontrol/pdf/index.html:210 +#: pretix/control/templates/pretixcontrol/pdf/index.html:260 +#: pretix/control/templates/pretixcontrol/pdf/index.html:270 #, fuzzy #| msgid "Upload custom background" msgid "Upload PDF as background" msgstr "خلفية مخصصة تحميل" -#: pretix/control/templates/pretixcontrol/pdf/index.html:202 +#: pretix/control/templates/pretixcontrol/pdf/index.html:262 msgid "" "You can upload a PDF to use as a custom background. The paper size will " "match the PDF." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:217 +#: pretix/control/templates/pretixcontrol/pdf/index.html:277 #, fuzzy #| msgid "Upload custom background" msgid "Download current background" msgstr "خلفية مخصصة تحميل" -#: pretix/control/templates/pretixcontrol/pdf/index.html:224 +#: pretix/control/templates/pretixcontrol/pdf/index.html:284 #, fuzzy #| msgid "Canceled by customer" msgid "Or choose custom paper size" msgstr "تم الإلغاء من قبل العميل" -#: pretix/control/templates/pretixcontrol/pdf/index.html:226 +#: pretix/control/templates/pretixcontrol/pdf/index.html:286 msgid "" "To manually change the paper size, you need to create a new, empty " "background." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:234 -#: pretix/control/templates/pretixcontrol/pdf/index.html:321 -#: pretix/control/templates/pretixcontrol/pdf/index.html:363 +#: pretix/control/templates/pretixcontrol/pdf/index.html:294 +#: pretix/control/templates/pretixcontrol/pdf/index.html:381 +#: pretix/control/templates/pretixcontrol/pdf/index.html:423 msgid "Width (mm)" msgstr "العرض (مم)" -#: pretix/control/templates/pretixcontrol/pdf/index.html:238 -#: pretix/control/templates/pretixcontrol/pdf/index.html:326 +#: pretix/control/templates/pretixcontrol/pdf/index.html:298 +#: pretix/control/templates/pretixcontrol/pdf/index.html:386 msgid "Height (mm)" msgstr "الارتفاع (مم)" -#: pretix/control/templates/pretixcontrol/pdf/index.html:247 +#: pretix/control/templates/pretixcontrol/pdf/index.html:307 msgid "Create empty background" msgstr "إنشاء خلفية فارغة" -#: pretix/control/templates/pretixcontrol/pdf/index.html:254 +#: pretix/control/templates/pretixcontrol/pdf/index.html:314 msgid "Style" msgstr "قلم المدقة" -#: pretix/control/templates/pretixcontrol/pdf/index.html:256 +#: pretix/control/templates/pretixcontrol/pdf/index.html:316 msgid "Dark" msgstr "داكن" -#: pretix/control/templates/pretixcontrol/pdf/index.html:257 +#: pretix/control/templates/pretixcontrol/pdf/index.html:317 msgid "Light" msgstr "ضوء" -#: pretix/control/templates/pretixcontrol/pdf/index.html:263 +#: pretix/control/templates/pretixcontrol/pdf/index.html:323 #, fuzzy #| msgid "Email content" msgid "Image content" msgstr "البريد الإلكتروني المحتوى" -#: pretix/control/templates/pretixcontrol/pdf/index.html:274 +#: pretix/control/templates/pretixcontrol/pdf/index.html:334 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:20 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_update.html:34 #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/send_form.html:29 @@ -25203,138 +26430,93 @@ msgstr "البريد الإلكتروني المحتوى" msgid "Content" msgstr "جهة اتصال:" -#: pretix/control/templates/pretixcontrol/pdf/index.html:283 +#: pretix/control/templates/pretixcontrol/pdf/index.html:343 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:50 msgid "Event attribute:" msgstr "السمة الحدث:" -#: pretix/control/templates/pretixcontrol/pdf/index.html:288 +#: pretix/control/templates/pretixcontrol/pdf/index.html:348 #: pretix/control/templates/pretixcontrol/pdf/placeholders.html:59 #, fuzzy #| msgid "Event attribute:" msgid "Item attribute:" msgstr "السمة الحدث:" -#: pretix/control/templates/pretixcontrol/pdf/index.html:291 +#: pretix/control/templates/pretixcontrol/pdf/index.html:351 msgid "Other… (multilingual)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:292 +#: pretix/control/templates/pretixcontrol/pdf/index.html:352 msgid "Other…" msgstr "آخر…" -#: pretix/control/templates/pretixcontrol/pdf/index.html:302 +#: pretix/control/templates/pretixcontrol/pdf/index.html:362 #, fuzzy #| msgid "Available placeholders: {list}" msgid "Show available placeholders" msgstr "النائبة المتاحة: {list}" -#: pretix/control/templates/pretixcontrol/pdf/index.html:309 +#: pretix/control/templates/pretixcontrol/pdf/index.html:369 msgid "x (mm)" msgstr "س (مم)" -#: pretix/control/templates/pretixcontrol/pdf/index.html:314 +#: pretix/control/templates/pretixcontrol/pdf/index.html:374 msgid "y (mm)" msgstr "ص (مم)" -#: pretix/control/templates/pretixcontrol/pdf/index.html:333 +#: pretix/control/templates/pretixcontrol/pdf/index.html:393 msgid "Size (mm)" msgstr "حجم (مم)" -#: pretix/control/templates/pretixcontrol/pdf/index.html:340 +#: pretix/control/templates/pretixcontrol/pdf/index.html:400 #, fuzzy #| msgid "Text color" msgid "QR color" msgstr "لون الخط" -#: pretix/control/templates/pretixcontrol/pdf/index.html:355 +#: pretix/control/templates/pretixcontrol/pdf/index.html:415 msgid "Render without whitespace" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:357 +#: pretix/control/templates/pretixcontrol/pdf/index.html:417 msgid "" "Required for consistent size across platforms. Supported on Android starting " "with pretixPRINT 2.3.3 and on Desktop with pretixSCAN 1.9.3." msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:368 +#: pretix/control/templates/pretixcontrol/pdf/index.html:428 msgid "Rotation (°)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:387 +#: pretix/control/templates/pretixcontrol/pdf/index.html:447 msgid "Font size (pt)" msgstr "حجم الخط (نقطة)" -#: pretix/control/templates/pretixcontrol/pdf/index.html:392 +#: pretix/control/templates/pretixcontrol/pdf/index.html:452 #, fuzzy #| msgid "Light" msgid "Line height" msgstr "ضوء" -#: pretix/control/templates/pretixcontrol/pdf/index.html:399 +#: pretix/control/templates/pretixcontrol/pdf/index.html:459 msgid "Text color" msgstr "لون الخط" -#: pretix/control/templates/pretixcontrol/pdf/index.html:422 +#: pretix/control/templates/pretixcontrol/pdf/index.html:482 msgid "Flow multiple lines downward from specified position" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:476 +#: pretix/control/templates/pretixcontrol/pdf/index.html:536 #, fuzzy #| msgid "Automatically refund money if possible" msgid "Automatically reduce font size to fit content" msgstr "استرد المبلغ تلقائيا إن أمكن الأمر" -#: pretix/control/templates/pretixcontrol/pdf/index.html:482 +#: pretix/control/templates/pretixcontrol/pdf/index.html:542 msgid "Allow long words to be split (preview is not accurate)" msgstr "" -#: pretix/control/templates/pretixcontrol/pdf/index.html:493 -msgid "Add a new object" -msgstr "إضافة وجوه جديدة" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:498 -#, fuzzy -#| msgid "Text color" -msgid "Text box" -msgstr "لون الخط" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:502 -#, fuzzy -#| msgid "Event created" -msgid "Text (deprecated)" -msgstr "تم إنشاء الفعالية" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:506 -msgid "QR code for Check-In" -msgstr "رمز الاستجابة السريعة لتسلم الغرف" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:512 -msgid "QR code for Lead Scanning" -msgstr "رمز الاستجابة السريعة لالضوئي الرصاص" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:518 -#, fuzzy -#| msgid "Order code" -msgid "Other QR code" -msgstr "رمز الطلب" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:524 -msgid "pretix Logo" -msgstr "pretix شعار" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:527 -msgid "" -"You can use this to add user-uploaded pictures from questions or pictures " -"generated by plugins. If you want to embed a logo or other images, use a " -"custom background instead." -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:529 -msgid "Dynamic image" -msgstr "" - -#: pretix/control/templates/pretixcontrol/pdf/index.html:550 +#: pretix/control/templates/pretixcontrol/pdf/index.html:553 #, python-format msgid "" "This layout uses new features. If you print from your device, make sure you " @@ -25767,7 +26949,7 @@ msgid "Create many new dates" msgstr "إنشاء العديد من المواعيد الجديدة" #: pretix/control/templates/pretixcontrol/subevents/index.html:96 -#: pretix/plugins/reports/accountingreport.py:120 +#: pretix/plugins/reports/accountingreport.py:121 msgid "Begin" msgstr "ابدأ" @@ -26421,6 +27603,10 @@ msgstr "حالات سلة التسوق" msgid "Voucher link" msgstr "رابط قسيمة" +#: pretix/control/templates/pretixcontrol/vouchers/detail.html:54 +msgid "Copy" +msgstr "نسخ" + #: pretix/control/templates/pretixcontrol/vouchers/detail.html:116 msgid "Voucher history" msgstr "تاريخ قسيمة" @@ -26794,16 +27980,19 @@ msgstr "" "إلى شريط العنوان وتأكد من أنه هو الصحيح وأن الارتباط لم تستخدم من قبل." #: pretix/control/views/auth.py:252 +#, python-brace-format msgid "" "You cannot accept the invitation for \"{}\" as you already are part of this " "team." msgstr "لا يمكنك قبول الدعوة ل \"{}\" كما كنت بالفعل جزءا من هذا الفريق." #: pretix/control/views/auth.py:266 +#, python-brace-format msgid "You are now part of the team \"{}\"." msgstr "أنت الآن جزءا من الفريق \"{}\"." #: pretix/control/views/auth.py:296 +#, python-brace-format msgid "Welcome to pretix! You are now part of the team \"{}\"." msgstr "مرحبا بكم في pretix! أنت الآن جزءا من الفريق \"{}\"." @@ -26860,38 +28049,38 @@ msgstr "حاول مرة اخرى." msgid "Invalid code, please try again." msgstr "رمز غير صالح، يرجى المحاولة مرة أخرى." -#: pretix/control/views/checkin.py:280 +#: pretix/control/views/checkin.py:281 msgid "The selected check-ins have been reverted." msgstr "وقد عادت الإضافية الاختيار المحددة." -#: pretix/control/views/checkin.py:282 +#: pretix/control/views/checkin.py:283 #, fuzzy #| msgid "The selected tickets have been marked as checked in." msgid "The selected tickets have been marked as checked out." msgstr "وقد اتسمت تذاكر اختياره إيداعه." -#: pretix/control/views/checkin.py:284 +#: pretix/control/views/checkin.py:285 msgid "The selected tickets have been marked as checked in." msgstr "وقد اتسمت تذاكر اختياره إيداعه." -#: pretix/control/views/checkin.py:373 +#: pretix/control/views/checkin.py:374 msgid "The new check-in list has been created." msgstr "تم إنشاء الاختيار في قائمة جديدة." -#: pretix/control/views/checkin.py:380 pretix/control/views/checkin.py:440 +#: pretix/control/views/checkin.py:381 pretix/control/views/checkin.py:441 #: pretix/control/views/discounts.py:134 pretix/control/views/discounts.py:182 -#: pretix/control/views/event.py:268 pretix/control/views/event.py:551 -#: pretix/control/views/event.py:590 pretix/control/views/event.py:737 -#: pretix/control/views/event.py:929 pretix/control/views/event.py:1287 -#: pretix/control/views/event.py:1353 pretix/control/views/event.py:1461 +#: pretix/control/views/event.py:275 pretix/control/views/event.py:579 +#: pretix/control/views/event.py:618 pretix/control/views/event.py:781 +#: pretix/control/views/event.py:973 pretix/control/views/event.py:1333 +#: pretix/control/views/event.py:1399 pretix/control/views/event.py:1551 #: pretix/control/views/item.py:280 pretix/control/views/item.py:327 #: pretix/control/views/item.py:805 pretix/control/views/item.py:831 #: pretix/control/views/item.py:951 pretix/control/views/item.py:1155 #: pretix/control/views/item.py:1321 pretix/control/views/item.py:1506 -#: pretix/control/views/organizer.py:263 pretix/control/views/organizer.py:291 -#: pretix/control/views/organizer.py:1188 pretix/control/views/subevents.py:504 -#: pretix/control/views/subevents.py:630 pretix/control/views/subevents.py:1039 -#: pretix/control/views/subevents.py:1498 pretix/control/views/user.py:358 +#: pretix/control/views/organizer.py:275 pretix/control/views/organizer.py:303 +#: pretix/control/views/organizer.py:1457 pretix/control/views/subevents.py:504 +#: pretix/control/views/subevents.py:630 pretix/control/views/subevents.py:1046 +#: pretix/control/views/subevents.py:1505 pretix/control/views/user.py:358 #: pretix/control/views/vouchers.py:277 pretix/control/views/vouchers.py:351 #: pretix/control/views/vouchers.py:534 pretix/control/views/waitinglist.py:420 #: pretix/plugins/autocheckin/views.py:112 @@ -26902,11 +28091,11 @@ msgstr "تم إنشاء الاختيار في قائمة جديدة." msgid "We could not save your changes. See below for details." msgstr "لم نتمكن من حفظ التغييرات الخاصة بك. انظر أدناه للحصول على التفاصيل." -#: pretix/control/views/checkin.py:419 pretix/control/views/checkin.py:456 +#: pretix/control/views/checkin.py:420 pretix/control/views/checkin.py:457 msgid "The requested list does not exist." msgstr "عدم وجود قائمة المطلوب." -#: pretix/control/views/checkin.py:465 +#: pretix/control/views/checkin.py:466 msgid "The selected list has been deleted." msgstr "تم حذف القائمة المحددة." @@ -26990,7 +28179,7 @@ msgstr "" msgid "Set up event" msgstr "اقامة الحدث" -#: pretix/control/views/dashboards.py:534 +#: pretix/control/views/dashboards.py:538 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:110 #: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:116 #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:47 @@ -26999,7 +28188,7 @@ msgstr "اقامة الحدث" msgid "Sale over" msgstr "انتهت فترة البيع" -#: pretix/control/views/dashboards.py:536 +#: pretix/control/views/dashboards.py:540 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:119 #: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:123 #: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:86 @@ -27007,7 +28196,7 @@ msgstr "انتهت فترة البيع" msgid "Soon" msgstr "هكذا" -#: pretix/control/views/dashboards.py:561 +#: pretix/control/views/dashboards.py:565 #, python-brace-format msgid "{num} order" msgid_plural "{num} orders" @@ -27018,6 +28207,44 @@ msgstr[3] "" msgstr[4] "" msgstr[5] "" +#: pretix/control/views/datasync.py:82 +#, fuzzy +#| msgid "The quota has been re-opened and will not close again." +msgid "The sync job has been enqueued and will run in the next minutes." +msgstr "وكانت الحصة إعادة فتحها وسوف يتم إغلاق مرة أخرى." + +#: pretix/control/views/datasync.py:89 pretix/control/views/datasync.py:99 +#, fuzzy +#| msgid "The invoice has already been canceled." +msgid "The sync job is already in progress." +msgstr "وقد تم بالفعل إلغاء الفاتورة." + +#: pretix/control/views/datasync.py:92 +#, fuzzy +#| msgid "The order has been canceled." +msgid "The sync job has been canceled." +msgstr "تم إلغاء هذا الأمر." + +#: pretix/control/views/datasync.py:105 +#, fuzzy +#| msgid "The voucher has been sent to {recipient}." +msgid "The sync job has been set to run as soon as possible." +msgstr "تم إرسال كود الخصم إلى {recipient}." + +#: pretix/control/views/datasync.py:136 +#, fuzzy +#| msgctxt "subevent" +#| msgid "The selected dates have been deleted or disabled." +msgid "The selected jobs have been set to run as soon as possible." +msgstr "تم حذف المواعيد المحددة أو تعطيل." + +#: pretix/control/views/datasync.py:139 +#, fuzzy +#| msgctxt "subevent" +#| msgid "The selected dates have been disabled." +msgid "The selected jobs have been canceled." +msgstr "تم تعطيل التواريخ المحددة." + #: pretix/control/views/discounts.py:67 pretix/control/views/discounts.py:109 #: pretix/control/views/discounts.py:214 #, fuzzy @@ -27052,8 +28279,8 @@ msgstr "تم تحديث ترتيب العناصر." #: pretix/control/views/discounts.py:260 pretix/control/views/item.py:190 #: pretix/control/views/item.py:402 pretix/control/views/item.py:536 -#: pretix/control/views/organizer.py:2272 -#: pretix/control/views/organizer.py:3330 +#: pretix/control/views/organizer.py:2541 +#: pretix/control/views/organizer.py:3599 #, fuzzy #| msgid "Some of the provided question ids are invalid." msgid "Some of the provided object ids are invalid." @@ -27065,78 +28292,63 @@ msgstr "بعض معرفات السؤال المقدمة غير صالحة." msgid "Not all discounts have been selected." msgstr "تم حذف السؤال." -#: pretix/control/views/event.py:383 +#: pretix/control/views/event.py:454 #, fuzzy -#| msgid "Invoice generation" -msgid "Integrations" -msgstr "جيل فاتورة" +#| msgid "You do not have permission to perform this action." +msgid "" +"You do not have sufficient permission to enable plugins that need to be " +"enabled for the entire organizer account." +msgstr "ليس لديك إذن لتنفيذ هذا الإجراء." -#: pretix/control/views/event.py:384 -#, fuzzy -#| msgid "Customer actions" -msgid "Customizations" -msgstr "إجراءات العملاء" - -#: pretix/control/views/event.py:385 -#, fuzzy -#| msgid "Export format" -msgid "Output and export formats" -msgstr "تنسيق التصدير" - -#: pretix/control/views/event.py:386 -#, fuzzy -#| msgid "Features" -msgid "API features" -msgstr "المميزات" - -#: pretix/control/views/event.py:447 +#: pretix/control/views/event.py:473 pretix/control/views/organizer.py:713 +#, python-brace-format msgid "The plugin {} is now active, you can configure it here:" msgstr "" -#: pretix/control/views/event.py:456 -#, fuzzy +#: pretix/control/views/event.py:482 pretix/control/views/organizer.py:722 +#, fuzzy, python-brace-format #| msgid "The selected ticket shop is currently not available." msgid "The plugin {} is now active." msgstr "متجر التذاكر المختار غير متوفر حاليا." -#: pretix/control/views/event.py:519 +#: pretix/control/views/event.py:547 msgid "" "This payment provider does not exist or the respective plugin is disabled." msgstr "عدم وجود هذا مزود خدمة الدفع أو تعطيل البرنامج المساعد المعني." -#: pretix/control/views/event.py:776 pretix/control/views/organizer.py:344 +#: pretix/control/views/event.py:820 pretix/control/views/organizer.py:356 #: pretix/control/views/vouchers.py:561 msgid "invalid item" msgstr "البند غير صالح" -#: pretix/control/views/event.py:851 +#: pretix/control/views/event.py:895 #, fuzzy, python-format #| msgid "Your order: {code}" msgid "Your order: %(code)s" msgstr "طلبك هو: {code}" -#: pretix/control/views/event.py:860 +#: pretix/control/views/event.py:904 msgid "Unknown email renderer." msgstr "غير معروف العارض البريد الإلكتروني." -#: pretix/control/views/event.py:876 pretix/control/views/orders.py:693 +#: pretix/control/views/event.py:920 pretix/control/views/orders.py:678 #: pretix/presale/views/order.py:1088 pretix/presale/views/order.py:1095 msgid "You requested an invalid ticket output type." msgstr "لقد طلبت صالح نوع الانتاج التذاكر." -#: pretix/control/views/event.py:1024 +#: pretix/control/views/event.py:1068 msgid "Your shop is live now!" msgstr "متجرك مباشرة الآن!" -#: pretix/control/views/event.py:1032 +#: pretix/control/views/event.py:1076 msgid "We've taken your shop down. You can re-enable it whenever you want!" msgstr "لقد اتخذنا متجر أسفل الخاص بك. يمكنك إعادة تمكينها وقتما تشاء!" -#: pretix/control/views/event.py:1040 +#: pretix/control/views/event.py:1084 msgid "Your shop is now in test mode!" msgstr "متجر الخاص بك هو الآن في وضع الاختبار!" -#: pretix/control/views/event.py:1057 +#: pretix/control/views/event.py:1101 msgid "" "An order could not be deleted as some constraints (e.g. data created by plug-" "ins) do not allow it." @@ -27144,19 +28356,19 @@ msgstr "" "لا يمكن حذف أمر وبعض القيود (مثل البيانات التي تم إنشاؤها من قبل المكونات " "الإضافية) لا تسمح بذلك." -#: pretix/control/views/event.py:1063 +#: pretix/control/views/event.py:1107 msgid "We've disabled test mode for you. Let's sell some real tickets!" msgstr "لقد تعطيل وضع الاختبار بالنسبة لك. دعونا بيع بعض التذاكر الحقيقية!" -#: pretix/control/views/event.py:1085 +#: pretix/control/views/event.py:1129 msgid "This event can not be deleted." msgstr "لا يمكن حذف هذا الحدث." -#: pretix/control/views/event.py:1108 +#: pretix/control/views/event.py:1152 msgid "The event has been deleted." msgstr "الحدث تم الغائه." -#: pretix/control/views/event.py:1111 +#: pretix/control/views/event.py:1155 msgid "" "The event could not be deleted as some constraints (e.g. data created by " "plug-ins) do not allow it." @@ -27164,46 +28376,47 @@ msgstr "" "لا يمكن حذف الحدث عن بعض القيود (مثل البيانات التي تم إنشاؤها من قبل " "المكونات الإضافية) لا تسمح بذلك." -#: pretix/control/views/event.py:1127 +#: pretix/control/views/event.py:1171 #, python-brace-format msgid "" "Specifically, the following plugins still contain data depends on this " "event: {plugin_names}" msgstr "" -#: pretix/control/views/event.py:1207 pretix/control/views/orders.py:782 +#: pretix/control/views/event.py:1251 pretix/control/views/orders.py:767 msgid "The comment has been updated." msgstr "تم تحديث التعليق." -#: pretix/control/views/event.py:1209 pretix/control/views/orders.py:784 +#: pretix/control/views/event.py:1253 pretix/control/views/orders.py:769 msgid "Could not update the comment." msgstr "لا يمكن تحديث للتعليق." -#: pretix/control/views/event.py:1247 pretix/control/views/main.py:330 +#: pretix/control/views/event.py:1291 pretix/control/views/main.py:337 msgid "VAT" msgstr "ضريبة" -#: pretix/control/views/event.py:1281 +#: pretix/control/views/event.py:1327 msgid "The new tax rule has been created." msgstr "تم إنشاء القاعدة الضريبية الجديدة." -#: pretix/control/views/event.py:1304 pretix/control/views/event.py:1369 +#: pretix/control/views/event.py:1350 pretix/control/views/event.py:1413 +#: pretix/control/views/event.py:1459 msgid "The requested tax rule does not exist." msgstr "عدم وجود حكم الضرائب المطلوبة." -#: pretix/control/views/event.py:1378 +#: pretix/control/views/event.py:1468 msgid "The selected tax rule has been deleted." msgstr "تم حذف قاعدة الضريبة المحدد." -#: pretix/control/views/event.py:1380 +#: pretix/control/views/event.py:1470 msgid "The selected tax rule can not be deleted." msgstr "لا يمكن حذف القاعدة الضريبية المحدد." -#: pretix/control/views/event.py:1431 +#: pretix/control/views/event.py:1521 msgid "Your event is not empty, you need to set it up manually." msgstr "لم يتم تفريغ هذا الحدث الخاص بك، تحتاج إلى إعداده يدويا." -#: pretix/control/views/event.py:1566 +#: pretix/control/views/event.py:1656 msgid "" "Your changes have been saved. You can now go on with looking at the details " "or take your event live to start selling!" @@ -27211,11 +28424,11 @@ msgstr "" "تم حفظ التغييرات. يمكنك الذهاب الآن فصاعدا مع النظر في التفاصيل أو يأخذ " "الحدث على الهواء مباشرة لبدء بيع!" -#: pretix/control/views/event.py:1585 +#: pretix/control/views/event.py:1675 msgid "Regular ticket" msgstr "تذكرة العادية" -#: pretix/control/views/event.py:1590 +#: pretix/control/views/event.py:1680 msgid "Reduced ticket" msgstr "تذكرة مخفضة" @@ -27321,8 +28534,8 @@ msgid "The order of categories has been updated." msgstr "تم تحديث ترتيب الفئات." #: pretix/control/views/item.py:405 pretix/control/views/item.py:539 -#: pretix/control/views/organizer.py:2275 -#: pretix/control/views/organizer.py:3333 +#: pretix/control/views/organizer.py:2544 +#: pretix/control/views/organizer.py:3602 #, fuzzy #| msgid "The question has been deleted." msgid "Not all objects have been selected." @@ -27481,11 +28694,11 @@ msgid "" "period." msgstr "" -#: pretix/control/views/main.py:217 +#: pretix/control/views/main.py:218 msgid "You do not have permission to clone this event." msgstr "ليس لديك إذن لاستنساخ هذا الحدث." -#: pretix/control/views/main.py:283 +#: pretix/control/views/main.py:284 #, python-brace-format msgid "Team {event}" msgstr "فريق {event}" @@ -27542,73 +28755,39 @@ msgstr "" msgid "Access for the selected application has been revoked." msgstr "تم إبطال وصول التطبيق المحدد." -#: pretix/control/views/orders.py:192 +#: pretix/control/views/orders.py:193 #, fuzzy #| msgid "We could not save your changes. See below for details." msgid "We could not process your input. See below for details." msgstr "لم نتمكن من حفظ التغييرات الخاصة بك. انظر أدناه للحصول على التفاصيل." -#: pretix/control/views/orders.py:265 +#: pretix/control/views/orders.py:266 #, python-brace-format msgid "" "Successfully executed the action \"{label}\" on {success} of {total} orders." msgstr "" -#: pretix/control/views/orders.py:557 -#, fuzzy -#| msgid "All invoices" -msgid "Your invoice" -msgid_plural "Your invoices" -msgstr[0] "جميع الفواتير" -msgstr[1] "جميع الفواتير" -msgstr[2] "جميع الفواتير" -msgstr[3] "جميع الفواتير" -msgstr[4] "جميع الفواتير" -msgstr[5] "جميع الفواتير" - -#: pretix/control/views/orders.py:559 -#, python-brace-format -msgid "" -"Hello,\n" -"\n" -"please find your invoice attached to this email.\n" -"\n" -"Your {event} team" -msgid_plural "" -"Hello,\n" -"\n" -"please find your invoices attached to this email.\n" -"\n" -"Your {event} team" -msgstr[0] "" -msgstr[1] "" -msgstr[2] "" -msgstr[3] "" -msgstr[4] "" -msgstr[5] "" - -#: pretix/control/views/orders.py:695 pretix/plugins/banktransfer/views.py:901 -#: pretix/presale/views/order.py:158 pretix/presale/views/order.py:240 -#: pretix/presale/views/order.py:334 pretix/presale/views/order.py:361 -#: pretix/presale/views/order.py:429 pretix/presale/views/order.py:496 -#: pretix/presale/views/order.py:542 pretix/presale/views/order.py:728 -#: pretix/presale/views/order.py:841 pretix/presale/views/order.py:913 -#: pretix/presale/views/order.py:928 pretix/presale/views/order.py:977 -#: pretix/presale/views/order.py:982 pretix/presale/views/order.py:1097 -#: pretix/presale/views/order.py:1270 pretix/presale/views/order.py:1662 -#: pretix/presale/views/order.py:1693 +#: pretix/control/views/orders.py:680 pretix/presale/views/order.py:158 +#: pretix/presale/views/order.py:240 pretix/presale/views/order.py:334 +#: pretix/presale/views/order.py:361 pretix/presale/views/order.py:429 +#: pretix/presale/views/order.py:496 pretix/presale/views/order.py:542 +#: pretix/presale/views/order.py:728 pretix/presale/views/order.py:841 +#: pretix/presale/views/order.py:913 pretix/presale/views/order.py:928 +#: pretix/presale/views/order.py:977 pretix/presale/views/order.py:982 +#: pretix/presale/views/order.py:1097 pretix/presale/views/order.py:1270 +#: pretix/presale/views/order.py:1662 pretix/presale/views/order.py:1693 msgid "Unknown order code or not authorized to access this order." msgstr "كود أجل غير معروف أو غير مخول للوصول إلى هذا النظام." -#: pretix/control/views/orders.py:697 pretix/presale/views/order.py:1102 +#: pretix/control/views/orders.py:682 pretix/presale/views/order.py:1102 msgid "Ticket download is not enabled for this product." msgstr "لم يتم تمكين حمل تذكرة لهذا المنتج." -#: pretix/control/views/orders.py:818 +#: pretix/control/views/orders.py:803 msgid "The order has been deleted." msgstr "تم حذف هذا الأمر." -#: pretix/control/views/orders.py:825 +#: pretix/control/views/orders.py:810 msgid "" "The order could not be deleted as some constraints (e.g. data created by " "plug-ins) do not allow it." @@ -27616,55 +28795,55 @@ msgstr "" "لا يمكن حذف النظام كما بعض القيود (مثل البيانات التي تم إنشاؤها من قبل " "المكونات الإضافية) لا تسمح بذلك." -#: pretix/control/views/orders.py:833 +#: pretix/control/views/orders.py:818 msgid "Only orders created in test mode can be deleted." msgstr "أوامر الوحيدة التي تم إنشاؤها في وضع الاختبار يمكن حذفها." -#: pretix/control/views/orders.py:854 +#: pretix/control/views/orders.py:839 msgid "The order has been denied and is therefore now canceled." msgstr "تم رفض الطلب، وبالتالي يتم إلغاء الآن." -#: pretix/control/views/orders.py:894 +#: pretix/control/views/orders.py:879 msgid "This payment has been canceled." msgstr "تم إلغاء هذا الدفع." -#: pretix/control/views/orders.py:896 +#: pretix/control/views/orders.py:881 msgid "This payment can not be canceled at the moment." msgstr "لا يمكن إلغاء هذه الدفعة في الوقت الراهن." -#: pretix/control/views/orders.py:922 +#: pretix/control/views/orders.py:907 msgid "The refund has been canceled." msgstr "تم إلغاء استرداد." -#: pretix/control/views/orders.py:924 +#: pretix/control/views/orders.py:909 msgid "This refund can not be canceled at the moment." msgstr "لا يمكن إلغاء هذا رد في الوقت الراهن." -#: pretix/control/views/orders.py:958 +#: pretix/control/views/orders.py:943 msgid "The refund has been processed." msgstr "تم معالجة استرداد." -#: pretix/control/views/orders.py:960 pretix/control/views/orders.py:986 +#: pretix/control/views/orders.py:945 pretix/control/views/orders.py:971 msgid "This refund can not be processed at the moment." msgstr "لا يمكن معالجة هذا رد في الوقت الراهن." -#: pretix/control/views/orders.py:984 +#: pretix/control/views/orders.py:969 msgid "The refund has been marked as done." msgstr "تم وضع علامة على المبلغ في القيام به." -#: pretix/control/views/orders.py:1010 +#: pretix/control/views/orders.py:995 #, fuzzy #| msgid "The device has been verified and can now be used." msgid "The request has been removed. If you want, you can now inform the user." msgstr "تم التحقق من الجهاز ويمكن الآن أن تستخدم." -#: pretix/control/views/orders.py:1017 +#: pretix/control/views/orders.py:1002 #, fuzzy #| msgid "Cancellation fee" msgid "Your cancellation request" msgstr "رسوم الإلغاء" -#: pretix/control/views/orders.py:1018 +#: pretix/control/views/orders.py:1003 #, python-brace-format msgid "" "Hello,\n" @@ -27680,7 +28859,7 @@ msgstr "" "\n" "فريق فعاليتك{event}" -#: pretix/control/views/orders.py:1074 +#: pretix/control/views/orders.py:1059 msgid "" "The payment has been marked as complete, but we were unable to send a " "confirmation mail." @@ -27688,41 +28867,42 @@ msgstr "" "تم وضع علامة الدفع على النحو الكامل، ولكن لم نتمكن من إرسال البريد " "الإلكتروني تأكيد." -#: pretix/control/views/orders.py:1077 +#: pretix/control/views/orders.py:1062 msgid "The payment has been marked as complete." msgstr "تم وضع علامة الدفع على النحو الكامل." -#: pretix/control/views/orders.py:1079 +#: pretix/control/views/orders.py:1064 msgid "This payment can not be confirmed at the moment." msgstr "لا يمكن تأكيد هذه الدفعة في الوقت الراهن." -#: pretix/control/views/orders.py:1170 +#: pretix/control/views/orders.py:1155 msgid "" "The refund was prevented due to a refund already being processed at the same " "time. Please have a look at the order details and check if your refund is " "still necessary." msgstr "" -#: pretix/control/views/orders.py:1270 +#: pretix/control/views/orders.py:1255 #, fuzzy #| msgid "You entered an order that could not be found." msgid "You entered an order in an event with a different currency." msgstr "لقد أدخلت طلبا لا يمكن العثور عليه." -#: pretix/control/views/orders.py:1321 +#: pretix/control/views/orders.py:1306 msgid "" "You can not refund more than the amount of a payment that is not yet " "refunded." msgstr "لا يمكنك استرداد أكثر من مبلغ الدفعة التي لم يتم ردها حتى الان." -#: pretix/control/views/orders.py:1326 +#: pretix/control/views/orders.py:1311 msgid "" "You selected a partial refund for a payment method that only supports full " "refunds." msgstr "" "لقد حددت استرداد جزئي لطريقة الدفع التي تدعم فقط المبالغ المستردة كامل." -#: pretix/control/views/orders.py:1356 +#: pretix/control/views/orders.py:1341 +#, python-brace-format msgid "" "One of the refunds failed to be processed. You should retry to refund in a " "different way. The error message was: {}" @@ -27730,11 +28910,13 @@ msgstr "" "فشل في معالجتها واحدة من المبالغ المستردة. يجب عليك إعادة المحاولة لاسترداد " "بطريقة مختلفة. وكانت رسالة الخطأ: {}" -#: pretix/control/views/orders.py:1362 +#: pretix/control/views/orders.py:1347 +#, python-brace-format msgid "A refund of {} has been processed." msgstr "وقد تم تجهيز واسترداد {}." -#: pretix/control/views/orders.py:1366 +#: pretix/control/views/orders.py:1351 +#, python-brace-format msgid "" "A refund of {} has been saved, but not yet fully executed. You can mark it " "as complete below." @@ -27742,16 +28924,16 @@ msgstr "" "تم حفظ استرداد {}، ولكن لم يتم تنفيذها بالكامل. يمكنك وضع علامة على أنها " "كاملة أدناه." -#: pretix/control/views/orders.py:1395 +#: pretix/control/views/orders.py:1380 msgid "" "A new gift card was created. You can now send the user their gift card code." msgstr "" -#: pretix/control/views/orders.py:1403 +#: pretix/control/views/orders.py:1388 msgid "Your gift card code" msgstr "" -#: pretix/control/views/orders.py:1405 +#: pretix/control/views/orders.py:1390 #, python-brace-format msgid "" "Hello,\n" @@ -27764,22 +28946,22 @@ msgid "" "Your {event} team" msgstr "" -#: pretix/control/views/orders.py:1416 +#: pretix/control/views/orders.py:1401 msgid "The refunds you selected do not match the selected total refund amount." msgstr "المبالغ المستردة التي حددتها لا تتطابق إجمالي استرداد المبلغ المحدد." -#: pretix/control/views/orders.py:1544 +#: pretix/control/views/orders.py:1531 msgid "" "The order has been marked as paid, but we were unable to send a confirmation " "mail." msgstr "" "تم وضع علامة على النظام ودفع، ولكن لم نتمكن من إرسال البريد الإلكتروني تأكيد." -#: pretix/control/views/orders.py:1547 +#: pretix/control/views/orders.py:1534 msgid "The payment has been created successfully." msgstr "تم إنشاء دفع بنجاح." -#: pretix/control/views/orders.py:1561 +#: pretix/control/views/orders.py:1548 msgid "" "The order has been canceled. You can now select how you want to transfer the " "money back to the user." @@ -27787,22 +28969,22 @@ msgstr "" "تم إلغاء هذا الأمر. يمكنك الآن تحديد كيف تريد لنقل الجزء الخلفي المال " "للمستخدم." -#: pretix/control/views/orders.py:1632 pretix/control/views/orders.py:1636 +#: pretix/control/views/orders.py:1619 pretix/control/views/orders.py:1623 msgid "No VAT ID specified." msgstr "يتم تحديد معرف ضريبة القيمة المضافة." -#: pretix/control/views/orders.py:1640 +#: pretix/control/views/orders.py:1627 msgid "No country specified." msgstr "تحديد أي بلد." -#: pretix/control/views/orders.py:1644 +#: pretix/control/views/orders.py:1631 #, fuzzy #| msgid "" #| "VAT ID could not be checked since a non-EU country has been specified." msgid "VAT ID could not be checked since this country is not supported." msgstr "ولم يتسن التحقق VAT ID منذ تم تحديد بلد خارج الاتحاد الأوروبي." -#: pretix/control/views/orders.py:1655 +#: pretix/control/views/orders.py:1642 msgid "" "The VAT ID could not be checked, as the VAT checking service of the country " "is currently not available." @@ -27810,51 +28992,68 @@ msgstr "" "ولم يتسن التحقق من هوية ضريبة القيمة المضافة، مثل خدمة فحص ضريبة القيمة " "المضافة من البلاد غير متوفرة حاليا." -#: pretix/control/views/orders.py:1658 +#: pretix/control/views/orders.py:1645 msgid "This VAT ID is valid." msgstr "هذا ID VAT صالح." -#: pretix/control/views/orders.py:1672 pretix/control/views/orders.py:1705 +#: pretix/control/views/orders.py:1659 pretix/control/views/orders.py:1693 +#: pretix/control/views/orders.py:1725 msgid "Unknown invoice." msgstr "فاتورة غير معروفة." -#: pretix/control/views/orders.py:1675 +#: pretix/control/views/orders.py:1662 msgid "Invoices may not be changed after they are created." msgstr "" -#: pretix/control/views/orders.py:1677 pretix/control/views/orders.py:1708 +#: pretix/control/views/orders.py:1664 +msgid "Invoices may not be changed after they are transmitted." +msgstr "" + +#: pretix/control/views/orders.py:1666 pretix/control/views/orders.py:1728 msgid "The invoice has already been canceled." msgstr "وقد تم بالفعل إلغاء الفاتورة." -#: pretix/control/views/orders.py:1679 +#: pretix/control/views/orders.py:1668 #, fuzzy #| msgid "The invoice has already been canceled." msgid "The invoice file has already been exported." msgstr "وقد تم بالفعل إلغاء الفاتورة." -#: pretix/control/views/orders.py:1681 +#: pretix/control/views/orders.py:1670 #, fuzzy #| msgid "The invoice has been regenerated." msgid "The invoice file is too old to be regenerated." msgstr "تم إعادة إنشاء الفاتورة." -#: pretix/control/views/orders.py:1683 pretix/control/views/orders.py:1710 +#: pretix/control/views/orders.py:1672 pretix/control/views/orders.py:1730 msgid "The invoice has been cleaned of personal data." msgstr "وقد تم تنظيف الفاتورة البيانات الشخصية." -#: pretix/control/views/orders.py:1741 +#: pretix/control/views/orders.py:1697 +msgid "" +"The invoice is currently being transmitted. You can start a new attempt " +"after the current one has been completed." +msgstr "" + +#: pretix/control/views/orders.py:1704 +#, fuzzy +#| msgid "The invoice has been cleaned of personal data." +msgid "The invoice has been scheduled for retransmission." +msgstr "وقد تم تنظيف الفاتورة البيانات الشخصية." + +#: pretix/control/views/orders.py:1761 msgid "The email has been queued to be sent." msgstr "وقد تم في قائمة الانتظار البريد الإلكتروني لإرسالها." -#: pretix/control/views/orders.py:1765 pretix/presale/views/order.py:1279 +#: pretix/control/views/orders.py:1785 pretix/presale/views/order.py:1279 msgid "This invoice has not been found" msgstr "لم يتم العثور على هذه الفاتورة" -#: pretix/control/views/orders.py:1772 pretix/presale/views/order.py:1286 +#: pretix/control/views/orders.py:1792 pretix/presale/views/order.py:1286 msgid "The invoice file is no longer stored on the server." msgstr "لم يعد تخزين الملف فاتورة على الخادم." -#: pretix/control/views/orders.py:1777 pretix/presale/views/order.py:1291 +#: pretix/control/views/orders.py:1797 pretix/presale/views/order.py:1291 msgid "" "The invoice file has not yet been generated, we will generate it for you " "now. Please try again in a few seconds." @@ -27862,105 +29061,107 @@ msgstr "" "لم يتم إنشاء ملف الفاتورة، وسوف تولد لانها لكم الآن. يرجى المحاولة مرة أخرى " "في بضع ثوان." -#: pretix/control/views/orders.py:1805 +#: pretix/control/views/orders.py:1825 msgid "The payment term has been changed." msgstr "تم تغيير مصطلح الدفع." -#: pretix/control/views/orders.py:1810 pretix/control/views/orders.py:1867 +#: pretix/control/views/orders.py:1830 pretix/control/views/orders.py:1887 msgid "" "We were not able to process the request completely as the server was too " "busy." msgstr "لم نكن قادرين على معالجة الطلب تماما كما كان الملقم مشغول جدا." -#: pretix/control/views/orders.py:1818 +#: pretix/control/views/orders.py:1838 msgid "This action is only allowed for pending orders." msgstr "يسمح هذا الإجراء فقط لانتظار أوامر." -#: pretix/control/views/orders.py:1873 +#: pretix/control/views/orders.py:1893 #, fuzzy #| msgid "This action is only allowed for pending orders." msgid "This action is only allowed for canceled orders." msgstr "يسمح هذا الإجراء فقط لانتظار أوامر." -#: pretix/control/views/orders.py:2130 pretix/presale/views/order.py:1565 +#: pretix/control/views/orders.py:2150 pretix/presale/views/order.py:1565 msgid "An error occurred. Please see the details below." msgstr "حدث خطأ. يرجى الاطلاع على التفاصيل أدناه." -#: pretix/control/views/orders.py:2138 +#: pretix/control/views/orders.py:2158 msgid "The order has been changed and the user has been notified." msgstr "تم تغيير النظام وتم إعلام المستخدم." -#: pretix/control/views/orders.py:2140 pretix/control/views/orders.py:2276 -#: pretix/control/views/orders.py:2313 pretix/presale/views/order.py:1600 +#: pretix/control/views/orders.py:2160 pretix/control/views/orders.py:2296 +#: pretix/control/views/orders.py:2333 pretix/presale/views/order.py:1600 msgid "The order has been changed." msgstr "تم تغيير النظام." -#: pretix/control/views/orders.py:2167 pretix/presale/checkoutflow.py:945 +#: pretix/control/views/orders.py:2187 pretix/presale/checkoutflow.py:945 #: pretix/presale/views/order.py:783 pretix/presale/views/order.py:888 msgid "" "We had difficulties processing your input. Please review the errors below." msgstr "كان لدينا صعوبات معالجة المدخلات الخاصة بك. يرجى مراجعة الأخطاء أدناه." -#: pretix/control/views/orders.py:2278 +#: pretix/control/views/orders.py:2298 msgid "Nothing about the order had to be changed." msgstr "كان شيئا عن هذا الأمر يجب أن يتغير." -#: pretix/control/views/orders.py:2359 pretix/plugins/sendmail/views.py:176 +#: pretix/control/views/orders.py:2379 pretix/plugins/sendmail/views.py:176 msgid "We could not send the email. See below for details." msgstr "لم نتمكن من إرسال البريد الإلكتروني. انظر أدناه للحصول على التفاصيل." -#: pretix/control/views/orders.py:2375 pretix/control/views/orders.py:2445 +#: pretix/control/views/orders.py:2395 pretix/control/views/orders.py:2465 #: pretix/plugins/sendmail/views.py:204 pretix/plugins/sendmail/views.py:671 #, python-brace-format msgid "Subject: {subject}" msgstr "الموضوع: {subject}" -#: pretix/control/views/orders.py:2394 pretix/control/views/orders.py:2465 +#: pretix/control/views/orders.py:2414 pretix/control/views/orders.py:2485 +#, python-brace-format msgid "Your message has been queued and will be sent to {}." msgstr "وقد اصطف رسالتك وسوف يتم ارسالهم الى {}." -#: pretix/control/views/orders.py:2398 pretix/control/views/orders.py:2468 +#: pretix/control/views/orders.py:2418 pretix/control/views/orders.py:2488 +#, python-brace-format msgid "Failed to send mail to the following user: {}" msgstr "فشل في إرسال البريد الإلكتروني للمستخدم التالية: {}" -#: pretix/control/views/orders.py:2521 pretix/presale/views/order.py:1062 +#: pretix/control/views/orders.py:2541 pretix/presale/views/order.py:1062 msgid "" "This link is no longer valid. Please go back, refresh the page, and try " "again." msgstr "هذا الرابط لم يعد صالحا. يرجى العودة، بتحديث الصفحة وحاول مرة أخرى." -#: pretix/control/views/orders.py:2597 +#: pretix/control/views/orders.py:2617 msgid "There is no order with the given order code." msgstr "لا يوجد أي ترتيب مع رمز ترتيب معين." -#: pretix/control/views/orders.py:2703 pretix/control/views/organizer.py:1805 +#: pretix/control/views/orders.py:2723 pretix/control/views/organizer.py:2074 msgid "The selected exporter was not found." msgstr "لم يتم العثور على مصدر المحدد." -#: pretix/control/views/orders.py:2713 pretix/control/views/organizer.py:1815 +#: pretix/control/views/orders.py:2733 pretix/control/views/organizer.py:2084 msgid "There was a problem processing your input. See below for error details." msgstr "" "كانت هناك مشكلة معالجة المدخلات الخاصة بك. انظر أدناه للحصول على تفاصيل " "الخطأ." -#: pretix/control/views/orders.py:2748 pretix/control/views/organizer.py:1858 +#: pretix/control/views/orders.py:2768 pretix/control/views/organizer.py:2127 #, python-brace-format msgid "" "Your export schedule has been saved. The next export will start around " "{datetime}." msgstr "" -#: pretix/control/views/orders.py:2753 pretix/control/views/organizer.py:1863 +#: pretix/control/views/orders.py:2773 pretix/control/views/organizer.py:2132 msgid "Your export schedule has been saved, but no next export is planned." msgstr "" -#: pretix/control/views/orders.py:2792 pretix/control/views/organizer.py:1903 +#: pretix/control/views/orders.py:2812 pretix/control/views/organizer.py:2172 #, fuzzy, python-brace-format #| msgid "Export date" msgid "Export: {title}" msgstr "تاريخ التصدير" -#: pretix/control/views/orders.py:2793 pretix/control/views/organizer.py:1905 +#: pretix/control/views/orders.py:2813 pretix/control/views/organizer.py:2174 #, python-brace-format msgid "" "Hello,\n" @@ -27968,45 +29169,45 @@ msgid "" "attached to this email, you can find a new scheduled report for {name}." msgstr "" -#: pretix/control/views/orders.py:2861 pretix/control/views/organizer.py:1973 +#: pretix/control/views/orders.py:2881 pretix/control/views/organizer.py:2242 msgid "" "Your export is queued to start soon. The results will be send via email. " "Depending on system load and type and size of export, this may take a few " "minutes." msgstr "" -#: pretix/control/views/orders.py:2940 +#: pretix/control/views/orders.py:2960 #, fuzzy #| msgid "The order has been canceled." msgid "All orders have been canceled." msgstr "تم إلغاء هذا الأمر." -#: pretix/control/views/orders.py:2942 +#: pretix/control/views/orders.py:2962 #, python-brace-format msgid "" "The orders have been canceled. An error occurred with {count} orders, please " "check all uncanceled orders." msgstr "" -#: pretix/control/views/orders.py:2963 +#: pretix/control/views/orders.py:2983 #, fuzzy #| msgid "Your input was invalid, please try again." msgid "Your input was not valid." msgstr "كان الإدخال غير صالحة، يرجى المحاولة مرة أخرى." -#: pretix/control/views/organizer.py:162 +#: pretix/control/views/organizer.py:174 msgid "Token name" msgstr "اسم رمزي" -#: pretix/control/views/organizer.py:390 +#: pretix/control/views/organizer.py:402 msgid "This organizer can not be deleted." msgstr "لا يمكن حذف هذا منظم." -#: pretix/control/views/organizer.py:413 +#: pretix/control/views/organizer.py:425 msgid "The organizer has been deleted." msgstr "تم حذف منظم." -#: pretix/control/views/organizer.py:417 +#: pretix/control/views/organizer.py:429 msgid "" "The organizer could not be deleted as some constraints (e.g. data created by " "plug-ins) do not allow it." @@ -28014,56 +29215,75 @@ msgstr "" "لا يمكن حذف منظم وبعض القيود (مثل البيانات التي تم إنشاؤها من قبل المكونات " "الإضافية) لا تسمح بذلك." -#: pretix/control/views/organizer.py:427 +#: pretix/control/views/organizer.py:439 #, python-brace-format msgid "" "The following database models still contain data that cannot be deleted " "automatically: {affected_models}" msgstr "" -#: pretix/control/views/organizer.py:567 +#: pretix/control/views/organizer.py:579 msgid "The new organizer has been created." msgstr "تم إنشاء منظم جديد." -#: pretix/control/views/organizer.py:570 +#: pretix/control/views/organizer.py:582 msgid "Administrators" msgstr "المسؤولين" -#: pretix/control/views/organizer.py:633 +#: pretix/control/views/organizer.py:803 +#, fuzzy +#| msgid "Unknown plugin: '{name}'." +msgid "Unknown plugin." +msgstr "إضافة غير معروفة: '{name}'." + +#: pretix/control/views/organizer.py:809 +#, fuzzy +#| msgid "The selected ticket shop is currently not available." +msgid "This plugin is currently not active on the organizer account." +msgstr "متجر التذاكر المختار غير متوفر حاليا." + +#: pretix/control/views/organizer.py:813 +#, fuzzy +#| msgid "A payment is currently pending for this order." +msgid "This plugin is currently not allowed for this organizer account." +msgstr "دفعة سداد معلقة حاليا لهذا الطلب." + +#: pretix/control/views/organizer.py:902 msgid "The team has been created. You can now add members to the team." msgstr "تم إنشاء فريق. يمكنك الآن إضافة أعضاء للفريق." -#: pretix/control/views/organizer.py:644 pretix/control/views/organizer.py:680 -#: pretix/control/views/organizer.py:916 pretix/control/views/organizer.py:1004 -#: pretix/control/views/organizer.py:1075 -#: pretix/control/views/organizer.py:1294 -#: pretix/control/views/organizer.py:1337 -#: pretix/control/views/organizer.py:2021 -#: pretix/control/views/organizer.py:2056 -#: pretix/control/views/organizer.py:2162 -#: pretix/control/views/organizer.py:2193 -#: pretix/control/views/organizer.py:2355 -#: pretix/control/views/organizer.py:2390 -#: pretix/control/views/organizer.py:2464 -#: pretix/control/views/organizer.py:2506 -#: pretix/control/views/organizer.py:2586 -#: pretix/control/views/organizer.py:2636 -#: pretix/control/views/organizer.py:3195 -#: pretix/control/views/organizer.py:3239 +#: pretix/control/views/organizer.py:913 pretix/control/views/organizer.py:949 +#: pretix/control/views/organizer.py:1185 +#: pretix/control/views/organizer.py:1273 +#: pretix/control/views/organizer.py:1344 +#: pretix/control/views/organizer.py:1563 +#: pretix/control/views/organizer.py:1606 +#: pretix/control/views/organizer.py:2290 +#: pretix/control/views/organizer.py:2325 +#: pretix/control/views/organizer.py:2431 +#: pretix/control/views/organizer.py:2462 +#: pretix/control/views/organizer.py:2624 +#: pretix/control/views/organizer.py:2659 +#: pretix/control/views/organizer.py:2733 +#: pretix/control/views/organizer.py:2775 +#: pretix/control/views/organizer.py:2855 +#: pretix/control/views/organizer.py:2905 +#: pretix/control/views/organizer.py:3464 +#: pretix/control/views/organizer.py:3508 msgid "Your changes could not be saved." msgstr "لا يمكن حفظ التغييرات الخاصة بك." -#: pretix/control/views/organizer.py:713 +#: pretix/control/views/organizer.py:982 msgid "The selected team cannot be deleted." msgstr "لا يمكن حذف الفريق المحدد." -#: pretix/control/views/organizer.py:725 +#: pretix/control/views/organizer.py:994 msgid "" "The team could not be deleted because the team or one of its API tokens is " "part of historical audit logs." msgstr "" -#: pretix/control/views/organizer.py:733 +#: pretix/control/views/organizer.py:1002 #, fuzzy #| msgid "" #| "The event could not be deleted as some constraints (e.g. data created by " @@ -28075,11 +29295,11 @@ msgstr "" "لا يمكن حذف الحدث عن بعض القيود (مثل البيانات التي تم إنشاؤها من قبل " "المكونات الإضافية) لا تسمح بذلك." -#: pretix/control/views/organizer.py:739 +#: pretix/control/views/organizer.py:1008 msgid "The selected team has been deleted." msgstr "تم حذف فريق المحدد." -#: pretix/control/views/organizer.py:803 +#: pretix/control/views/organizer.py:1072 msgid "" "You cannot remove the last member from this team as no one would be left " "with the permission to change teams." @@ -28087,43 +29307,45 @@ msgstr "" "لا يمكنك إزالة آخر عضو من هذا الفريق كما هو ترك أي واحد مع الإذن لفرق " "التغيير." -#: pretix/control/views/organizer.py:814 +#: pretix/control/views/organizer.py:1083 msgid "The member has been removed from the team." msgstr "تمت إزالة عضو من الفريق." -#: pretix/control/views/organizer.py:821 pretix/control/views/organizer.py:837 +#: pretix/control/views/organizer.py:1090 +#: pretix/control/views/organizer.py:1106 msgid "Invalid invite selected." msgstr "غير صالح مع المدعوين المحدد." -#: pretix/control/views/organizer.py:830 +#: pretix/control/views/organizer.py:1099 msgid "The invite has been revoked." msgstr "تم إبطال الدعوة." -#: pretix/control/views/organizer.py:846 +#: pretix/control/views/organizer.py:1115 msgid "The invite has been resent." msgstr "وكان يستاء دعوة." -#: pretix/control/views/organizer.py:853 +#: pretix/control/views/organizer.py:1122 msgid "Invalid token selected." msgstr "رمز غير صالح المحدد." -#: pretix/control/views/organizer.py:863 +#: pretix/control/views/organizer.py:1132 msgid "The token has been revoked." msgstr "تم إبطال الرمز المميز." -#: pretix/control/views/organizer.py:875 +#: pretix/control/views/organizer.py:1144 msgid "Users need to have a pretix account before they can be invited." msgstr "يحتاج المستخدمون إلى لديك حساب pretix قبل أن يتمكنوا من المدعوين." -#: pretix/control/views/organizer.py:885 +#: pretix/control/views/organizer.py:1154 msgid "The new member has been invited to the team." msgstr "وقد دعا عضو جديد إلى الفريق." -#: pretix/control/views/organizer.py:900 +#: pretix/control/views/organizer.py:1169 msgid "The new member has been added to the team." msgstr "تمت إضافة عضو جديد إلى الفريق." -#: pretix/control/views/organizer.py:911 +#: pretix/control/views/organizer.py:1180 +#, python-brace-format msgid "" "A new API token has been created with the following secret: {}\n" "Please copy this secret to a safe place. You will not be able to view it " @@ -28132,132 +29354,132 @@ msgstr "" "تم إنشاء رمز API جديدة مع سر التالية: {}\n" "يرجى نسخ هذا السر إلى مكان آمن. فلن تكون قادرا على مشاهدته مرة أخرى هنا." -#: pretix/control/views/organizer.py:1208 +#: pretix/control/views/organizer.py:1477 msgid "This device has been set up successfully." msgstr "تم تعيين هذا الجهاز تصل بنجاح." -#: pretix/control/views/organizer.py:1236 +#: pretix/control/views/organizer.py:1505 msgid "This device currently does not have access." msgstr "هذا الجهاز حاليا لا يستطيعون الوصول." -#: pretix/control/views/organizer.py:1248 +#: pretix/control/views/organizer.py:1517 msgid "Access for this device has been revoked." msgstr "تم إلغاء الوصول لهذا الجهاز." -#: pretix/control/views/organizer.py:1369 +#: pretix/control/views/organizer.py:1638 msgid "" "All requests will now be scheduled for an immediate attempt. Please allow " "for a few minutes before they are processed." msgstr "" -#: pretix/control/views/organizer.py:1376 +#: pretix/control/views/organizer.py:1645 msgid "All unprocessed webhooks have been stopped from retrying." msgstr "" -#: pretix/control/views/organizer.py:1408 +#: pretix/control/views/organizer.py:1677 #, fuzzy #| msgid "The selected organizer was not found." msgid "The selected organizer has been invited." msgstr "لم يتم العثور على المنظم المحدد." -#: pretix/control/views/organizer.py:1445 -#: pretix/control/views/organizer.py:1456 +#: pretix/control/views/organizer.py:1714 +#: pretix/control/views/organizer.py:1725 #, fuzzy #| msgid "The selected gift card issuer has been removed." msgid "The selected connection has been removed." msgstr "تمت إزالة مصدر البطاقة هدية المحدد." -#: pretix/control/views/organizer.py:1467 +#: pretix/control/views/organizer.py:1736 #, fuzzy #| msgid "The selected question has been deleted." msgid "The selected connection has been accepted." msgstr "تم حذف السؤال المحدد." -#: pretix/control/views/organizer.py:1525 -#: pretix/control/views/organizer.py:1562 +#: pretix/control/views/organizer.py:1794 +#: pretix/control/views/organizer.py:1831 msgid "Gift cards are not allowed to have negative values." msgstr "لا يسمح بطاقات هدية لديها قيم سلبية." -#: pretix/control/views/organizer.py:1552 +#: pretix/control/views/organizer.py:1821 #, fuzzy #| msgid "The pretix.eu server could not be reached." msgid "The transaction could not be reversed." msgstr "ولم يتسن الوصول الى خادم pretix.eu." -#: pretix/control/views/organizer.py:1554 +#: pretix/control/views/organizer.py:1823 #, fuzzy #| msgid "The manual transaction has been saved." msgid "The transaction has been reversed." msgstr "تم حفظ المعاملة اليدوية." -#: pretix/control/views/organizer.py:1559 +#: pretix/control/views/organizer.py:1828 msgid "Your input was invalid, please try again." msgstr "كان الإدخال غير صالحة، يرجى المحاولة مرة أخرى." -#: pretix/control/views/organizer.py:1577 +#: pretix/control/views/organizer.py:1846 msgid "The manual transaction has been saved." msgstr "تم حفظ المعاملة اليدوية." -#: pretix/control/views/organizer.py:1619 +#: pretix/control/views/organizer.py:1888 msgid "The gift card has been created and can now be used." msgstr "تم إنشاء بطاقة هدية، ويمكن الآن استخدامها." -#: pretix/control/views/organizer.py:1713 +#: pretix/control/views/organizer.py:1982 msgid "All events (that I have access to)" msgstr "" -#: pretix/control/views/organizer.py:2080 +#: pretix/control/views/organizer.py:2349 #, fuzzy #| msgctxt "subevent" #| msgid "The selected date has been deleted." msgid "The selected gate has been deleted." msgstr "تم حذف التاريخ المحدد." -#: pretix/control/views/organizer.py:2123 +#: pretix/control/views/organizer.py:2392 msgid "You cannot set a default value that is not a valid value." msgstr "لا يمكنك تعيين قيمة افتراضية غير صالحة." -#: pretix/control/views/organizer.py:2150 +#: pretix/control/views/organizer.py:2419 #, fuzzy #| msgid "The product has been created." msgid "The property has been created." msgstr "تم إنشاء المنتج." -#: pretix/control/views/organizer.py:2217 +#: pretix/control/views/organizer.py:2486 #, fuzzy #| msgid "The selected product has been deleted." msgid "The selected property has been deleted." msgstr "تم حذف المنتج المحدد." -#: pretix/control/views/organizer.py:2241 +#: pretix/control/views/organizer.py:2510 #, fuzzy #| msgid "The order of items has been updated." msgid "The order of properties has been updated." msgstr "تم تحديث ترتيب العناصر." -#: pretix/control/views/organizer.py:2420 -#: pretix/control/views/organizer.py:2536 -#: pretix/control/views/organizer.py:2666 -#: pretix/control/views/organizer.py:2932 +#: pretix/control/views/organizer.py:2689 +#: pretix/control/views/organizer.py:2805 +#: pretix/control/views/organizer.py:2935 +#: pretix/control/views/organizer.py:3201 #, fuzzy #| msgid "The selected product has been deleted." msgid "The selected object has been deleted." msgstr "تم حذف المنتج المحدد." -#: pretix/control/views/organizer.py:2455 +#: pretix/control/views/organizer.py:2724 #, fuzzy #| msgid "The order has been created." msgid "The provider has been created." msgstr "تم إنشاء هذا الأمر." -#: pretix/control/views/organizer.py:2575 +#: pretix/control/views/organizer.py:2844 #, python-brace-format msgid "" "The SSO client has been created. Please note down the following client " "secret, it will never be shown again: {secret}" msgstr "" -#: pretix/control/views/organizer.py:2625 +#: pretix/control/views/organizer.py:2894 #, fuzzy, python-brace-format #| msgid "" #| "Your changes have been saved. Please note that it can take a short period " @@ -28269,7 +29491,7 @@ msgstr "" "تم حفظ التغييرات. يرجى ملاحظة أنه يمكن أن يستغرق فترة قصيرة من الزمن حتى " "تصبح التغييرات نشطة." -#: pretix/control/views/organizer.py:2734 +#: pretix/control/views/organizer.py:3003 #, fuzzy #| msgid "" #| "We've sent you an email with further instructions on resetting your " @@ -28281,25 +29503,25 @@ msgstr "" "لقد أرسلنا إليك بريدا إلكترونيا يحتوي على مزيد من الإرشادات حول إعادة تعيين " "كلمة المرور الخاصة بك." -#: pretix/control/views/organizer.py:2997 +#: pretix/control/views/organizer.py:3266 #, fuzzy #| msgid "This user has been anonymized." msgid "The customer account has been anonymized." msgstr "تم طمس هويتها لهذا المستخدم." -#: pretix/control/views/organizer.py:3267 +#: pretix/control/views/organizer.py:3536 #, fuzzy #| msgid "This organizer can not be deleted." msgid "This channel can not be deleted." msgstr "لا يمكن حذف هذا منظم." -#: pretix/control/views/organizer.py:3272 +#: pretix/control/views/organizer.py:3541 #, fuzzy #| msgid "The selected list has been deleted." msgid "The selected sales channel has been deleted." msgstr "تم حذف القائمة المحددة." -#: pretix/control/views/organizer.py:3274 +#: pretix/control/views/organizer.py:3543 #, fuzzy #| msgid "" #| "The event could not be deleted as some constraints (e.g. data created by " @@ -28311,7 +29533,7 @@ msgstr "" "لا يمكن حذف الحدث عن بعض القيود (مثل البيانات التي تم إنشاؤها من قبل " "المكونات الإضافية) لا تسمح بذلك." -#: pretix/control/views/organizer.py:3299 +#: pretix/control/views/organizer.py:3568 #, fuzzy #| msgid "The order of items has been updated." msgid "The order of sales channels has been updated." @@ -28380,11 +29602,12 @@ msgctxt "subevent" msgid "The selected dates have been deleted or disabled." msgstr "تم حذف المواعيد المحددة أو تعطيل." -#: pretix/control/views/subevents.py:894 +#: pretix/control/views/subevents.py:901 msgid "Please do not create more than 100.000 dates at once." msgstr "" -#: pretix/control/views/subevents.py:1030 +#: pretix/control/views/subevents.py:1037 +#, python-brace-format msgctxt "subevent" msgid "{} new dates have been created." msgstr "وقد تم إنشاء {} مواعيد جديدة." @@ -28394,10 +29617,12 @@ msgid "Series:" msgstr "سلسلة:" #: pretix/control/views/typeahead.py:115 +#, python-brace-format msgid "Order {}" msgstr "طلب {}" #: pretix/control/views/typeahead.py:128 +#, python-brace-format msgid "Voucher {}" msgstr "إيصال {}" @@ -28613,6 +29838,24 @@ msgstr "هذه ليست سلسلة فعالية." msgid "The waitinglist entry has been transferred." msgstr "تم نقل إدخال قائمة الانتظار إلى الأعلى." +#: pretix/helpers/countries.py:128 +msgid "Belarus" +msgstr "" + +#: pretix/helpers/countries.py:129 +#, fuzzy +#| msgid "French" +msgid "French Guiana" +msgstr "الفرنسية" + +#: pretix/helpers/countries.py:130 +msgid "North Macedonia" +msgstr "" + +#: pretix/helpers/countries.py:131 +msgid "Macao" +msgstr "" + #: pretix/helpers/daterange.py:56 pretix/helpers/daterange.py:118 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:77 #: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:46 @@ -28742,7 +29985,7 @@ msgstr "جميع مزودي خدمات السداد" msgid "All variations" msgstr "جميع الإجراءات" -#: pretix/plugins/autocheckin/forms.py:248 +#: pretix/plugins/autocheckin/forms.py:247 msgid "" "When restricting by payment method, the rule should run after the payment " "was received." @@ -28997,9 +30240,9 @@ msgid "Only include tickets for dates on or before this date." msgstr "قم بتضمين تذاكر لفترة في هذا التاريخ أو قبله فقط." #: pretix/plugins/badges/exporters.py:493 -#: pretix/plugins/checkinlists/exporters.py:117 -#: pretix/plugins/reports/exporters.py:495 -#: pretix/plugins/reports/exporters.py:677 +#: pretix/plugins/checkinlists/exporters.py:118 +#: pretix/plugins/reports/exporters.py:506 +#: pretix/plugins/reports/exporters.py:688 #: pretix/plugins/ticketoutputpdf/exporters.py:92 msgid "Sort by" msgstr "ترتيب حسب" @@ -29118,11 +30361,6 @@ msgstr "لم تقم بإنشاء أي تخطيطات شارة حتى الآن." msgid "Create a new badge layout" msgstr "قم بإنشاء تخطيط شارة جديد" -#: pretix/plugins/badges/templates/pretixplugins/badges/index.html:63 -#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/index.html:60 -msgid "Make default" -msgstr "وضع افتراضي" - #: pretix/plugins/badges/views.py:89 msgid "The new badge layout has been created." msgstr "تم إنشاء تخطيط الشارة الجديد." @@ -29137,6 +30375,7 @@ msgid "The selected badge layout been deleted." msgstr "تم حذف تخطيط الشارة المحدد." #: pretix/plugins/badges/views.py:217 +#, python-brace-format msgid "Badge layout: {}" msgstr "تخطيط الشارة: {}" @@ -29145,9 +30384,9 @@ msgstr "تخطيط الشارة: {}" #: pretix/plugins/banktransfer/apps.py:42 #: pretix/plugins/banktransfer/apps.py:45 #: pretix/plugins/banktransfer/apps.py:46 -#: pretix/plugins/banktransfer/payment.py:67 -#: pretix/plugins/banktransfer/signals.py:50 -#: pretix/plugins/banktransfer/signals.py:87 +#: pretix/plugins/banktransfer/payment.py:60 +#: pretix/plugins/banktransfer/signals.py:48 +#: pretix/plugins/banktransfer/signals.py:85 msgid "Bank transfer" msgstr "تحويل مصرفي" @@ -29158,8 +30397,8 @@ msgid "" msgstr "" #: pretix/plugins/banktransfer/apps.py:45 -#: pretix/plugins/banktransfer/signals.py:58 -#: pretix/plugins/banktransfer/signals.py:94 +#: pretix/plugins/banktransfer/signals.py:56 +#: pretix/plugins/banktransfer/signals.py:92 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_base.html:4 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_base.html:7 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_base_organizer.html:4 @@ -29168,8 +30407,8 @@ msgid "Import bank data" msgstr "قم باستيراد بيانات البنك" #: pretix/plugins/banktransfer/apps.py:46 -#: pretix/plugins/banktransfer/signals.py:66 -#: pretix/plugins/banktransfer/signals.py:102 +#: pretix/plugins/banktransfer/signals.py:64 +#: pretix/plugins/banktransfer/signals.py:100 msgid "Export refunds" msgstr "قم بتصدير المبالغ المستردة" @@ -29178,7 +30417,7 @@ msgid "" "Install the python package 'chardet' for better CSV import capabilities." msgstr "قم بتثبيت حزمة python 'chardet' لتحسين إمكانات استيراد ملفات CSV." -#: pretix/plugins/banktransfer/payment.py:75 +#: pretix/plugins/banktransfer/payment.py:68 msgid "" "I have understood that people will pay the ticket price directly to my bank " "account and pretix cannot automatically know what payments arrived. " @@ -29191,56 +30430,57 @@ msgstr "" "يدويا ، أو سأستورد بانتظام كشف حساب بنكي رقمي من أجل إعطاء pretix المعلومات " "المطلوبة." -#: pretix/plugins/banktransfer/payment.py:82 +#: pretix/plugins/banktransfer/payment.py:75 msgid "Bank account type" msgstr "نوع الحساب المصرفي" -#: pretix/plugins/banktransfer/payment.py:85 +#: pretix/plugins/banktransfer/payment.py:78 msgid "SEPA bank account" msgstr "حساب مصرفي SEPA" -#: pretix/plugins/banktransfer/payment.py:86 +#: pretix/plugins/banktransfer/payment.py:79 msgid "Other bank account" msgstr "حساب مصرفي آخر" -#: pretix/plugins/banktransfer/payment.py:91 +#: pretix/plugins/banktransfer/payment.py:84 msgid "Name of account holder" msgstr "اسم صاحب الحساب" -#: pretix/plugins/banktransfer/payment.py:93 +#: pretix/plugins/banktransfer/payment.py:86 msgid "" "Please note: special characters other than letters, numbers, and some " "punctuation can cause problems with some banks." msgstr "" -#: pretix/plugins/banktransfer/payment.py:103 -#: pretix/plugins/banktransfer/payment.py:466 -#: pretix/plugins/banktransfer/payment.py:657 +#: pretix/plugins/banktransfer/payment.py:96 +#: pretix/plugins/banktransfer/payment.py:300 +#: pretix/plugins/banktransfer/payment.py:490 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:15 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:15 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:14 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:50 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html:6 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:24 msgid "IBAN" msgstr "رقم الحساب المصرفي الدولي IBAN" -#: pretix/plugins/banktransfer/payment.py:113 -#: pretix/plugins/banktransfer/payment.py:467 +#: pretix/plugins/banktransfer/payment.py:106 +#: pretix/plugins/banktransfer/payment.py:301 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:16 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:16 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:15 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:66 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:25 msgid "BIC" msgstr "رمز معرف الأعمال BIC" -#: pretix/plugins/banktransfer/payment.py:123 +#: pretix/plugins/banktransfer/payment.py:116 msgid "Name of bank" msgstr "اسم البنك" -#: pretix/plugins/banktransfer/payment.py:133 +#: pretix/plugins/banktransfer/payment.py:126 msgid "Bank account details" msgstr "تفاصيل الحساب المصرفي" -#: pretix/plugins/banktransfer/payment.py:136 +#: pretix/plugins/banktransfer/payment.py:129 msgid "" "Include everything else that your customers might need to send you a bank " "transfer payment. If you have lots of international customers, they might " @@ -29250,7 +30490,7 @@ msgstr "" "كان لديك الكثير من العملاء الدوليين ، فقد يحتاجون إلى عنوانك الكامل وعنوان " "البنك الذي تتعامل معه." -#: pretix/plugins/banktransfer/payment.py:142 +#: pretix/plugins/banktransfer/payment.py:135 msgid "" "For SEPA accounts, you can leave this empty. Otherwise, please add " "everything that your customers need to transfer the money, e.g. account " @@ -29260,38 +30500,38 @@ msgstr "" "يحتاجه عملاؤك لتحويل المبالغ ، على سبيل المثال أرقام الحسابات وأرقام التوجيه " "والعناوين وما إلى ذلك." -#: pretix/plugins/banktransfer/payment.py:161 +#: pretix/plugins/banktransfer/payment.py:154 msgid "Do not include hyphens in the payment reference." msgstr "لا تقم بتضمين الشرطات في مرجع الدفع." -#: pretix/plugins/banktransfer/payment.py:162 +#: pretix/plugins/banktransfer/payment.py:155 msgid "This is required in some countries." msgstr "هذا مطلوب في بعض البلدان." -#: pretix/plugins/banktransfer/payment.py:166 +#: pretix/plugins/banktransfer/payment.py:159 msgid "Include invoice number in the payment reference." msgstr "قم بتضمين رقم الفاتورة في مرجع الدفع." -#: pretix/plugins/banktransfer/payment.py:170 +#: pretix/plugins/banktransfer/payment.py:163 msgid "Prefix for the payment reference" msgstr "الرمز الذي يسق مرجع الدفع" -#: pretix/plugins/banktransfer/payment.py:174 +#: pretix/plugins/banktransfer/payment.py:167 msgid "Additional text to show on pending orders" msgstr "نص إضافي لإظهاره في الطلبات المعلقة" -#: pretix/plugins/banktransfer/payment.py:175 +#: pretix/plugins/banktransfer/payment.py:168 msgid "" "This text will be shown on the order confirmation page for pending orders in " "addition to the standard text." msgstr "" "سيظهر هذا النص في صفحة تأكيد الطلب للأوامر المعلقة بالإضافة إلى النص المعتاد." -#: pretix/plugins/banktransfer/payment.py:184 +#: pretix/plugins/banktransfer/payment.py:177 msgid "IBAN blocklist for refunds" msgstr "قائمة حظر IBAN للمبالغ المستردة" -#: pretix/plugins/banktransfer/payment.py:187 +#: pretix/plugins/banktransfer/payment.py:180 #, fuzzy #| msgid "" #| "Put one IBAN or IBAN prefix per line. The system will not attempt to send " @@ -29314,90 +30554,47 @@ msgstr "" "لجهة خارجية. يمكنك أيضا سرد رموز البلدان مثل \"GB\" إذا كنت لا ترغب أبدا في " "إرسال المبالغ المستردة إلى أرقام IBAN من بلد معين." -#: pretix/plugins/banktransfer/payment.py:218 -msgid "" -"Allow users to enter an additional email address that the invoice will be " -"sent to." -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:220 -msgid "" -"This requires that the invoice creation settings allow the invoice to be " -"created right after the payment method was chosen. Only the invoice will be " -"sent to this email address, subsequent invoice corrections will not be sent " -"automatically. Only the invoice will be sent, no additional information." -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:229 -#, fuzzy -#| msgid "Email was sent" -msgid "Invoice email subject" -msgstr "تم إرسال البريد الإلكتروني" - -#: pretix/plugins/banktransfer/payment.py:241 -#, fuzzy -#| msgctxt "invoice" -#| msgid "Invoice date" -msgid "Invoice email text" -msgstr "تاريخ الفاتورة" - -#: pretix/plugins/banktransfer/payment.py:256 +#: pretix/plugins/banktransfer/payment.py:207 #, fuzzy #| msgid "Business customers" msgid "Restrict to business customers" msgstr "عملاء قطاع الأعمال" -#: pretix/plugins/banktransfer/payment.py:257 +#: pretix/plugins/banktransfer/payment.py:208 msgid "" "Only allow choosing this payment provider for customers who enter an invoice " "address and select \"Business or institutional customer\"." msgstr "" -#: pretix/plugins/banktransfer/payment.py:288 +#: pretix/plugins/banktransfer/payment.py:238 msgid "Please fill out your bank account details." msgstr "يرجى ملء تفاصيل حسابك المصرفي." -#: pretix/plugins/banktransfer/payment.py:292 +#: pretix/plugins/banktransfer/payment.py:242 msgid "Please enter your bank account details." msgstr "الرجاء إدخال تفاصيل حسابك المصرفي." -#: pretix/plugins/banktransfer/payment.py:332 -msgid "" -"Please additionally send my invoice directly to our accounting department" -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:336 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:161 -#, fuzzy -msgid "Invoice recipient email" -msgstr "مستلم الفاتورة:" - -#: pretix/plugins/banktransfer/payment.py:338 -msgid "" -"The invoice recipient will receive an email which includes the invoice and " -"your email address so they know who placed this order." -msgstr "" - -#: pretix/plugins/banktransfer/payment.py:457 +#: pretix/plugins/banktransfer/payment.py:291 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:15 msgid "Please transfer the full amount to the following bank account:" msgstr "يرجى تحويل المبلغ كاملا إلى الحساب المصرفي التالي:" -#: pretix/plugins/banktransfer/payment.py:465 -#: pretix/plugins/banktransfer/payment.py:654 +#: pretix/plugins/banktransfer/payment.py:299 +#: pretix/plugins/banktransfer/payment.py:487 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:14 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:14 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:13 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html:5 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:23 -#: pretix/plugins/banktransfer/views.py:835 +#: pretix/plugins/banktransfer/views.py:829 #: pretix/plugins/stripe/payment.py:1458 #: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_confirm.html:32 #: pretix/plugins/stripe/templates/pretixplugins/stripe/checkout_payment_confirm.html:35 msgid "Account holder" msgstr "صاحب الحساب" -#: pretix/plugins/banktransfer/payment.py:468 +#: pretix/plugins/banktransfer/payment.py:302 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:17 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:17 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:16 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:26 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:23 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:31 @@ -29407,24 +30604,25 @@ msgstr "صاحب الحساب" msgid "Bank" msgstr "مصرف" -#: pretix/plugins/banktransfer/payment.py:548 +#: pretix/plugins/banktransfer/payment.py:381 msgid "Invalid IBAN/BIC" msgstr "رقم IBAN/BIC غير صالح" -#: pretix/plugins/banktransfer/payment.py:624 +#: pretix/plugins/banktransfer/payment.py:457 #, python-brace-format msgid "Bank account {iban}" msgstr "الحساب المصرفي{iban}" -#: pretix/plugins/banktransfer/payment.py:640 +#: pretix/plugins/banktransfer/payment.py:473 msgid "Can only create a bank transfer refund from an existing payment." msgstr "يمكن فقط إنشاء تحويل مصرفي مسترد من دفعة موجودة." -#: pretix/plugins/banktransfer/payment.py:660 +#: pretix/plugins/banktransfer/payment.py:493 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/new_refund_control_form.html:7 msgid "BIC (optional)" msgstr "رقم BIC (اختياري)" -#: pretix/plugins/banktransfer/payment.py:699 +#: pretix/plugins/banktransfer/payment.py:532 msgid "Your input was invalid, please see below for details." msgstr "الإدخالات الخاصة بك غير صالحة ، الرجاء انظر أدناه للحصول على التفاصيل." @@ -29441,52 +30639,12 @@ msgstr "المسدد" msgid "Refund" msgstr "إعادة مال" -#: pretix/plugins/banktransfer/signals.py:126 +#: pretix/plugins/banktransfer/signals.py:125 #, fuzzy #| msgid "Please enter the same email address twice." msgid "The invoice was sent to the designated email address." msgstr "الرجاء إدخال نفس عنوان البريد الإلكتروني مرتين." -#: pretix/plugins/banktransfer/signals.py:132 -#, fuzzy, python-brace-format -#| msgid "Invoice number" -msgid "Invoice {invoice_number}" -msgstr "رقم الفاتورة" - -#: pretix/plugins/banktransfer/signals.py:137 -#, fuzzy, python-brace-format -#| msgid "" -#| "Hello,\n" -#| "\n" -#| "you receive this message because you asked us to send you the link\n" -#| "to your order for {event}.\n" -#| "\n" -#| "You can change your order details and view the status of your order at\n" -#| "{url}\n" -#| "\n" -#| "Best regards, \n" -#| "Your {event} team" -msgid "" -"Hello,\n" -"\n" -"you receive this message because an order for {event} was placed by " -"{order_email} and we have been asked to forward the invoice to you.\n" -"\n" -"Best regards, \n" -"\n" -"Your {event} team" -msgstr "" -"مرحبا،\n" -"\n" -"تلقيت هذه الرسالة لأنك طلبت منا أن نرسل لك الرابط\n" -"لطلبك {event}.\n" -"\n" -"يمكنك تغيير تفاصيل طلبك وعرض حالة طلبك في\n" -"{url}\n" -"\n" -"تحياتنا،\n" -"فريق {event}" - #: pretix/plugins/banktransfer/tasks.py:171 msgid "Automatic split to multiple orders not possible." msgstr "التقسيم التلقائي للطلبات المتعددة غير ممكن." @@ -29496,13 +30654,13 @@ msgid "The order has already been canceled." msgstr "تم إلغاء الطلب سابقا." #: pretix/plugins/banktransfer/tasks.py:193 -#: pretix/plugins/banktransfer/views.py:106 -#: pretix/plugins/banktransfer/views.py:193 +#: pretix/plugins/banktransfer/views.py:100 +#: pretix/plugins/banktransfer/views.py:187 msgid "Currencies do not match." msgstr "" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:6 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:6 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:5 msgid "" "After completing your purchase, we will ask you to transfer the money to the " "following bank account, using a personal reference code:" @@ -29511,7 +30669,7 @@ msgstr "" "باستخدام رمز مرجعي شخصي:" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:11 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:11 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:10 #, fuzzy #| msgid "" #| "We will assign you a personal reference code to use after you completed " @@ -29522,20 +30680,20 @@ msgid "" msgstr "سنخصص لك رمزا مرجعيا شخصيا لاستخدامه بعد إتمام الطلب." #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:26 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:26 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:25 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:39 msgid "Reference code (important):" msgstr "الرمز المرجعي (مهم):" #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:31 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:31 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:30 msgid "" "We will assign you a personal reference code to use after you completed the " "order." msgstr "سنخصص لك رمزا مرجعيا شخصيا لاستخدامه بعد إتمام الطلب." #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:36 -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:36 +#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_payment_form.html:35 #, fuzzy #| msgid "" #| "After completing your purchase, we will ask you to transfer the money to " @@ -29547,11 +30705,6 @@ msgstr "" "بعد إتمام عملية الشراء ، سنطلب منك تحويل الأموال إلى الحساب المصرفي التالي ، " "باستخدام رمز مرجعي شخصي:" -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/checkout_confirm.html:43 -#, python-format -msgid "We will send a copy of your invoice directly to %(recipient)s." -msgstr "" - #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/control.html:6 #, fuzzy #| msgctxt "invoice" @@ -29620,7 +30773,7 @@ msgid "" msgstr "حاليا ، هذه الميزة تدعم ملفات .csv والملفات بصيغة MT940." #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html:29 -#: pretix/plugins/banktransfer/views.py:561 +#: pretix/plugins/banktransfer/views.py:555 msgid "" "An import is currently being processed, please try again in a few minutes." msgstr "" @@ -29744,29 +30897,6 @@ msgstr "" msgid "Scan the QR code with your banking app" msgstr "" -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:141 -#, python-format -msgid "At your request, we sent the invoice directly to %(recipient)s." -msgstr "" - -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:146 -#, fuzzy -#| msgid "Log in as someone else" -msgid "Send again or somewhere else" -msgstr "تسجيل الدخول باسم شخص آخر" - -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:155 -msgid "" -"To send the invoice directly to your accounting department, please enter " -"their email address:" -msgstr "" - -#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:168 -#, fuzzy -#| msgid "Send information via email" -msgid "Send invoice via email" -msgstr "أرسل المعلومات إلى البريد الإلكتروني" - #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:5 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:7 #: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/sepa_export.html:7 @@ -29930,7 +31060,7 @@ msgstr "تم دفع الطلب مسبقا" msgid "Discard" msgstr "تجاهل" -#: pretix/plugins/banktransfer/views.py:146 +#: pretix/plugins/banktransfer/views.py:140 msgid "" "Negative amount but refund can't be logged, please create manual refund " "first." @@ -29938,79 +31068,79 @@ msgstr "" "مبلغ سلبي ولكن لا يمكن تسجيل استرداد المبالغ ، يرجى إنشاء استرداد المبالغ " "يدويا أولا." -#: pretix/plugins/banktransfer/views.py:172 +#: pretix/plugins/banktransfer/views.py:166 msgid "Problem sending email." msgstr "مشكلة في إرسال البريد الإلكتروني." -#: pretix/plugins/banktransfer/views.py:198 +#: pretix/plugins/banktransfer/views.py:192 msgid "Unknown order code" msgstr "رمز طلب غير معروف" -#: pretix/plugins/banktransfer/views.py:355 +#: pretix/plugins/banktransfer/views.py:349 msgid "Search text" msgstr "نص البحث" -#: pretix/plugins/banktransfer/views.py:356 +#: pretix/plugins/banktransfer/views.py:350 msgid "min" msgstr "أدنى" -#: pretix/plugins/banktransfer/views.py:357 +#: pretix/plugins/banktransfer/views.py:351 msgid "max" msgstr "أقصى" -#: pretix/plugins/banktransfer/views.py:366 +#: pretix/plugins/banktransfer/views.py:360 msgid "Filter form is not valid." msgstr "نموذج التصنيف غير صالح." -#: pretix/plugins/banktransfer/views.py:409 +#: pretix/plugins/banktransfer/views.py:403 msgid "All unresolved transactions have been discarded." msgstr "تم تجاهل جميع المعاملات التي لم يتم حلها." -#: pretix/plugins/banktransfer/views.py:429 +#: pretix/plugins/banktransfer/views.py:423 msgid "You must choose a file to import." msgstr "يجب عليك اختيار ملف لاستيراده." -#: pretix/plugins/banktransfer/views.py:433 +#: pretix/plugins/banktransfer/views.py:427 msgid "" "We were unable to detect the file type of this import. Please contact " "support for help." msgstr "" "لم نتمكن من الكشف عن نوع ملف هذا الاستيراد. الرجاء الاتصال بالدعم للمساعدة." -#: pretix/plugins/banktransfer/views.py:446 -#: pretix/plugins/banktransfer/views.py:495 +#: pretix/plugins/banktransfer/views.py:440 +#: pretix/plugins/banktransfer/views.py:489 msgid "We were unable to process your input." msgstr "لم نتمكن من معالجة المدخلات الخاصة بك." -#: pretix/plugins/banktransfer/views.py:460 +#: pretix/plugins/banktransfer/views.py:454 msgid "" "I'm sorry, but we were unable to import this CSV file. Please contact " "support for help." msgstr "" "نأسف ، لم نتمكن من استيراد ملف CSV هذا. الرجاء الاتصال بالدعم للمساعدة." -#: pretix/plugins/banktransfer/views.py:465 +#: pretix/plugins/banktransfer/views.py:459 msgid "" "I'm sorry, but we detected this file as empty. Please contact support for " "help." msgstr "" "نأسف ، لكننا اكتشفنا أن هذا الملف فارغ. الرجاء الاتصال بالدعم للمساعدة." -#: pretix/plugins/banktransfer/views.py:485 +#: pretix/plugins/banktransfer/views.py:479 msgid "Invalid input data." msgstr "بيانات الإدخال غير صالحة." -#: pretix/plugins/banktransfer/views.py:489 +#: pretix/plugins/banktransfer/views.py:483 msgid "You need to select the column containing the payment reference." msgstr "تحتاج إلى تحديد العمود الذي يحتوي على مرجع الدفع." -#: pretix/plugins/banktransfer/views.py:570 +#: pretix/plugins/banktransfer/views.py:564 #, fuzzy #| msgid "The question has been deleted." msgid "No currency has been selected." msgstr "تم حذف السؤال." -#: pretix/plugins/banktransfer/views.py:718 +#: pretix/plugins/banktransfer/views.py:712 #, python-brace-format msgid "" "We could not find bank account information for the refund {refund_id}. It " @@ -30019,36 +31149,10 @@ msgstr "" "لم نتمكن من العثور على معلومات الحساب المصرفي لعملية استرداد المبالغ " "{refund_id}. تم وضع علامة عليه على أنه لم يتم." -#: pretix/plugins/banktransfer/views.py:751 +#: pretix/plugins/banktransfer/views.py:745 msgid "No valid orders have been found." msgstr "لم يتم العثور على طلبات صالحة." -#: pretix/plugins/banktransfer/views.py:905 pretix/presale/checkoutflow.py:1016 -#: pretix/presale/checkoutflow.py:1022 -msgid "Please enter a valid email address." -msgstr "الرجاء قم بإدخال بريد الكتروني صحيح." - -#: pretix/plugins/banktransfer/views.py:912 -msgid "" -"No pending bank transfer payment found. Maybe the order has been paid " -"already?" -msgstr "" - -#: pretix/plugins/banktransfer/views.py:915 -#, fuzzy -#| msgid "This order is not yet approved by the event organizer." -msgid "Sending invoices via email is disabled by the event organizer." -msgstr "لم تتم الموافقة على هذا الطلب بعد من قبل منظم الفعالية." - -#: pretix/plugins/banktransfer/views.py:920 -msgid "No invoice found, please request an invoice first." -msgstr "" - -#: pretix/plugins/banktransfer/views.py:932 -#, python-brace-format -msgid "Sending the latest invoice via email to {email}." -msgstr "" - #: pretix/plugins/checkinlists/apps.py:47 msgid "Check-in list exporter" msgstr "تحقق في قائمة المصدر" @@ -30057,141 +31161,137 @@ msgstr "تحقق في قائمة المصدر" msgid "This plugin allows you to generate check-in lists for your conference." msgstr "يتيح لك هذا المكون الإضافي إنشاء قوائم التسجيل لمؤتمرك." -#: pretix/plugins/checkinlists/exporters.py:91 +#: pretix/plugins/checkinlists/exporters.py:92 #: pretix/plugins/ticketoutputpdf/exporters.py:88 #, fuzzy #| msgid "Only include tickets for dates on or after this date." msgid "Only include tickets for dates within this range." msgstr "قم بتضمين تذاكر لفترة في هذا التاريخ أو بعده فقط." -#: pretix/plugins/checkinlists/exporters.py:95 +#: pretix/plugins/checkinlists/exporters.py:96 msgid "Include QR-code secret" msgstr "قم بتضمين رمز سري للاستجابة السريعة" -#: pretix/plugins/checkinlists/exporters.py:100 +#: pretix/plugins/checkinlists/exporters.py:101 msgid "Only tickets requiring special attention" msgstr "التذاكر التي تتطلب اهتماما خاصا فقط" -#: pretix/plugins/checkinlists/exporters.py:133 +#: pretix/plugins/checkinlists/exporters.py:134 msgid "Include questions" msgstr "قم بتضمين الأسئلة" -#: pretix/plugins/checkinlists/exporters.py:303 +#: pretix/plugins/checkinlists/exporters.py:304 msgid "Check-in list (PDF)" msgstr "قائمة التسجيل (PDF)" -#: pretix/plugins/checkinlists/exporters.py:304 -#: pretix/plugins/checkinlists/exporters.py:475 -#: pretix/plugins/checkinlists/exporters.py:672 -#: pretix/plugins/checkinlists/exporters.py:742 +#: pretix/plugins/checkinlists/exporters.py:305 +#: pretix/plugins/checkinlists/exporters.py:476 +#: pretix/plugins/checkinlists/exporters.py:673 +#: pretix/plugins/checkinlists/exporters.py:743 #, fuzzy #| msgid "Check-in" msgctxt "export_category" msgid "Check-in" msgstr "التسجيل" -#: pretix/plugins/checkinlists/exporters.py:305 +#: pretix/plugins/checkinlists/exporters.py:306 msgid "" "Download a PDF version of a check-in list that can be used to check people " "in at the event without digital methods." msgstr "" #. Translators: maximum 5 characters -#: pretix/plugins/checkinlists/exporters.py:373 +#: pretix/plugins/checkinlists/exporters.py:374 msgctxt "tablehead" msgid "paid" msgstr "مدفوع" -#: pretix/plugins/checkinlists/exporters.py:476 +#: pretix/plugins/checkinlists/exporters.py:477 msgid "" "Download a spreadsheet with all attendees that are included in a check-in " "list." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:499 +#: pretix/plugins/checkinlists/exporters.py:500 msgid "Checked out" msgstr "تسجيل خروج" -#: pretix/plugins/checkinlists/exporters.py:499 -#: pretix/plugins/checkinlists/exporters.py:764 +#: pretix/plugins/checkinlists/exporters.py:500 +#: pretix/plugins/checkinlists/exporters.py:765 msgid "Automatically checked in" msgstr "تم التسجيل تلقائيا" -#: pretix/plugins/checkinlists/exporters.py:505 -#: pretix/plugins/checkinlists/exporters.py:693 -#: pretix/plugins/checkinlists/exporters.py:758 -#: pretix/plugins/paypal/payment.py:123 pretix/plugins/paypal2/payment.py:120 +#: pretix/plugins/checkinlists/exporters.py:506 +#: pretix/plugins/checkinlists/exporters.py:694 +#: pretix/plugins/checkinlists/exporters.py:759 +#: pretix/plugins/paypal/payment.py:124 pretix/plugins/paypal2/payment.py:121 msgid "Secret" msgstr "سري" -#: pretix/plugins/checkinlists/exporters.py:671 +#: pretix/plugins/checkinlists/exporters.py:672 #, fuzzy #| msgid "All check-in lists" msgid "Valid check-in codes" msgstr "جميع قوائم التسجيل" -#: pretix/plugins/checkinlists/exporters.py:673 +#: pretix/plugins/checkinlists/exporters.py:674 msgid "" "Download a spreadsheet with all valid check-in barcodes e.g. for import into " "a different system. Does not included blocked codes or personal data." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:741 +#: pretix/plugins/checkinlists/exporters.py:742 #, fuzzy #| msgid "Check-in log (all successful scans)" msgid "Check-in log (all scans)" msgstr "تسجيل الدخول (جميع عمليات الفحص الناجحة)" -#: pretix/plugins/checkinlists/exporters.py:743 +#: pretix/plugins/checkinlists/exporters.py:744 msgid "" "Download a spreadsheet with one line for every scan that happened at your " "check-in stations." msgstr "" -#: pretix/plugins/checkinlists/exporters.py:762 +#: pretix/plugins/checkinlists/exporters.py:763 #, fuzzy #| msgid "Go offline" msgid "Offline" msgstr "العودة متواجد حاليا" -#: pretix/plugins/checkinlists/exporters.py:763 +#: pretix/plugins/checkinlists/exporters.py:764 msgid "Offline override" msgstr "تجاوز وضع عدم الاتصال" -#: pretix/plugins/checkinlists/exporters.py:767 +#: pretix/plugins/checkinlists/exporters.py:768 #: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:83 msgid "Error message" msgstr "رسالة خاطئة" -#: pretix/plugins/checkinlists/exporters.py:768 +#: pretix/plugins/checkinlists/exporters.py:769 #, fuzzy #| msgid "Download date" msgid "Upload date" msgstr "تاريخ التنزيل" -#: pretix/plugins/checkinlists/exporters.py:769 +#: pretix/plugins/checkinlists/exporters.py:770 #, fuzzy #| msgid "Download time" msgid "Upload time" msgstr "وقت التنزيل" -#: pretix/plugins/checkinlists/exporters.py:826 +#: pretix/plugins/checkinlists/exporters.py:827 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:519 #: pretix/presale/templates/pretixpresale/fragment_modals.html:52 #: pretix/presale/templates/pretixpresale/fragment_modals.html:148 msgid "OK" msgstr "" -#: pretix/plugins/checkinlists/exporters.py:858 +#: pretix/plugins/checkinlists/exporters.py:859 #, fuzzy #| msgid "Successful payments" msgid "Successful scans only" msgstr "المدفوعات ناجحة" -#: pretix/plugins/checkinlists/exporters.py:879 -msgid "All check-in lists" -msgstr "جميع قوائم التسجيل" - #: pretix/plugins/manualpayment/apps.py:37 #, fuzzy #| msgid "" @@ -30200,10 +31300,10 @@ msgid "A fully customizable payment method for manual processing." msgstr "يضيف هذا البرنامج المساعد طريقة دفع قابلة للتخصيص والمعالجة اليدوية." #: pretix/plugins/paypal/apps.py:44 pretix/plugins/paypal/apps.py:47 -#: pretix/plugins/paypal/payment.py:75 pretix/plugins/paypal2/apps.py:45 -#: pretix/plugins/paypal2/payment.py:82 pretix/plugins/paypal2/payment.py:138 -#: pretix/plugins/paypal2/payment.py:1096 -#: pretix/plugins/paypal2/payment.py:1097 pretix/plugins/stripe/payment.py:1816 +#: pretix/plugins/paypal/payment.py:76 pretix/plugins/paypal2/apps.py:45 +#: pretix/plugins/paypal2/payment.py:83 pretix/plugins/paypal2/payment.py:139 +#: pretix/plugins/paypal2/payment.py:1097 +#: pretix/plugins/paypal2/payment.py:1098 pretix/plugins/stripe/payment.py:1816 msgid "PayPal" msgstr "PayPal" @@ -30213,7 +31313,7 @@ msgid "" "payment methods world-wide." msgstr "" -#: pretix/plugins/paypal/payment.py:91 pretix/plugins/paypal2/payment.py:376 +#: pretix/plugins/paypal/payment.py:92 pretix/plugins/paypal2/payment.py:377 msgid "" "The PayPal sandbox is being used, you can test without actually sending " "money but you will need a PayPal sandbox user to log in." @@ -30221,30 +31321,30 @@ msgstr "" "يتم استخدام PayPal sandbox ، يمكنك الاختبار دون إرسال المبالغ فعليًا ولكنك " "ستحتاج إلى مستخدم PayPal sandbox لتسجيل الدخول." -#: pretix/plugins/paypal/payment.py:103 +#: pretix/plugins/paypal/payment.py:104 msgid "PayPal account" msgstr "حساب PayPal" -#: pretix/plugins/paypal/payment.py:116 pretix/plugins/paypal2/payment.py:113 +#: pretix/plugins/paypal/payment.py:117 pretix/plugins/paypal2/payment.py:114 #, python-brace-format msgid "{text}" msgstr "{text}" -#: pretix/plugins/paypal/payment.py:117 pretix/plugins/paypal2/payment.py:114 +#: pretix/plugins/paypal/payment.py:118 pretix/plugins/paypal2/payment.py:115 msgid "Click here for a tutorial on how to obtain the required keys" msgstr "" "انقر هنا للحصول على برنامج تعليمي حول كيفية الحصول على المفاتيح المطلوبة" -#: pretix/plugins/paypal/payment.py:129 pretix/plugins/paypal2/payment.py:126 +#: pretix/plugins/paypal/payment.py:130 pretix/plugins/paypal2/payment.py:127 #: pretix/plugins/stripe/payment.py:258 msgid "Endpoint" msgstr "نقطة النهاية" -#: pretix/plugins/paypal/payment.py:141 pretix/plugins/paypal2/payment.py:200 +#: pretix/plugins/paypal/payment.py:142 pretix/plugins/paypal2/payment.py:201 msgid "Reference prefix" msgstr "رمز يسبق المرجع" -#: pretix/plugins/paypal/payment.py:142 pretix/plugins/paypal2/payment.py:201 +#: pretix/plugins/paypal/payment.py:143 pretix/plugins/paypal2/payment.py:202 msgid "" "Any value entered here will be added in front of the regular booking " "reference containing the order number." @@ -30252,13 +31352,13 @@ msgstr "" "ستتم إضافة أي قيمة يتم إدخالها هنا أمام مرجع الحجز العادي الذي يحتوي على رقم " "الطلب." -#: pretix/plugins/paypal/payment.py:148 pretix/plugins/paypal2/payment.py:207 +#: pretix/plugins/paypal/payment.py:149 pretix/plugins/paypal2/payment.py:208 #, fuzzy #| msgid "Reference prefix" msgid "Reference postfix" msgstr "رمز يسبق المرجع" -#: pretix/plugins/paypal/payment.py:149 pretix/plugins/paypal2/payment.py:208 +#: pretix/plugins/paypal/payment.py:150 pretix/plugins/paypal2/payment.py:209 #, fuzzy #| msgid "" #| "Any value entered here will be added in front of the regular booking " @@ -30270,63 +31370,64 @@ msgstr "" "ستتم إضافة أي قيمة يتم إدخالها هنا أمام مرجع الحجز العادي الذي يحتوي على رقم " "الطلب." -#: pretix/plugins/paypal/payment.py:187 pretix/plugins/paypal2/payment.py:261 +#: pretix/plugins/paypal/payment.py:188 pretix/plugins/paypal2/payment.py:262 msgid "Disconnect from PayPal" msgstr "اقطع الاتصال ب PayPal" -#: pretix/plugins/paypal/payment.py:241 pretix/plugins/paypal/payment.py:307 -#: pretix/plugins/paypal/payment.py:345 pretix/plugins/paypal/payment.py:360 -#: pretix/plugins/paypal/payment.py:428 pretix/plugins/paypal/payment.py:431 -#: pretix/plugins/paypal/payment.py:589 pretix/plugins/paypal/payment.py:666 -#: pretix/plugins/paypal2/payment.py:470 pretix/plugins/paypal2/payment.py:480 -#: pretix/plugins/paypal2/payment.py:602 pretix/plugins/paypal2/payment.py:606 -#: pretix/plugins/paypal2/payment.py:675 pretix/plugins/paypal2/payment.py:739 -#: pretix/plugins/paypal2/payment.py:1020 -#: pretix/plugins/paypal2/payment.py:1030 -#: pretix/plugins/paypal2/payment.py:1126 +#: pretix/plugins/paypal/payment.py:242 pretix/plugins/paypal/payment.py:308 +#: pretix/plugins/paypal/payment.py:346 pretix/plugins/paypal/payment.py:361 +#: pretix/plugins/paypal/payment.py:429 pretix/plugins/paypal/payment.py:432 +#: pretix/plugins/paypal/payment.py:590 pretix/plugins/paypal/payment.py:667 +#: pretix/plugins/paypal2/payment.py:471 pretix/plugins/paypal2/payment.py:481 +#: pretix/plugins/paypal2/payment.py:603 pretix/plugins/paypal2/payment.py:607 +#: pretix/plugins/paypal2/payment.py:676 pretix/plugins/paypal2/payment.py:740 +#: pretix/plugins/paypal2/payment.py:1021 +#: pretix/plugins/paypal2/payment.py:1031 +#: pretix/plugins/paypal2/payment.py:1127 msgid "We had trouble communicating with PayPal" msgstr "كانت لدينا مشكلة في التواصل مع PayPal" -#: pretix/plugins/paypal/payment.py:374 pretix/plugins/paypal/payment.py:383 -#: pretix/plugins/paypal/payment.py:457 pretix/plugins/paypal2/payment.py:651 -#: pretix/plugins/paypal2/payment.py:692 pretix/plugins/paypal2/payment.py:754 -#: pretix/plugins/paypal2/payment.py:785 pretix/plugins/paypal2/payment.py:810 +#: pretix/plugins/paypal/payment.py:375 pretix/plugins/paypal/payment.py:384 +#: pretix/plugins/paypal/payment.py:458 pretix/plugins/paypal2/payment.py:652 +#: pretix/plugins/paypal2/payment.py:693 pretix/plugins/paypal2/payment.py:755 +#: pretix/plugins/paypal2/payment.py:786 pretix/plugins/paypal2/payment.py:811 msgid "" "We were unable to process your payment. See below for details on how to " "proceed." msgstr "" "لم نتمكن من معالجة الدفع. انظر أدناه للحصول على تفاصيل حول كيفية المتابعة." -#: pretix/plugins/paypal/payment.py:438 pretix/plugins/paypal/payment.py:447 -#: pretix/plugins/paypal2/payment.py:797 +#: pretix/plugins/paypal/payment.py:439 pretix/plugins/paypal/payment.py:448 +#: pretix/plugins/paypal2/payment.py:798 msgid "" "PayPal has not yet approved the payment. We will inform you as soon as the " "payment completed." msgstr "لم يوافق PayPal على الدفع بعد. سنبلغك بمجرد إتمام عملية الدفع." -#: pretix/plugins/paypal/payment.py:472 pretix/plugins/paypal2/payment.py:825 +#: pretix/plugins/paypal/payment.py:473 pretix/plugins/paypal2/payment.py:826 #: pretix/plugins/stripe/payment.py:985 msgid "There was an error sending the confirmation mail." msgstr "حدث خطأ في إرسال بريد التأكيد." -#: pretix/plugins/paypal/payment.py:565 pretix/plugins/paypal/payment.py:572 -#: pretix/plugins/paypal2/payment.py:978 pretix/plugins/paypal2/payment.py:999 +#: pretix/plugins/paypal/payment.py:566 pretix/plugins/paypal/payment.py:573 +#: pretix/plugins/paypal2/payment.py:979 pretix/plugins/paypal2/payment.py:1000 +#, python-brace-format msgid "Refunding the amount via PayPal failed: {}" msgstr "فشل رد المبلغ عبر PayPal: {}" -#: pretix/plugins/paypal/payment.py:707 pretix/plugins/paypal/payment.py:715 -#: pretix/plugins/paypal2/payment.py:1076 -#: pretix/plugins/paypal2/payment.py:1084 -msgid "The payment for this invoice has already been received." -msgstr "تم إستلام قيمة هذه الفاتورة مسبقا." - #: pretix/plugins/paypal/payment.py:708 pretix/plugins/paypal/payment.py:716 #: pretix/plugins/paypal2/payment.py:1077 #: pretix/plugins/paypal2/payment.py:1085 +msgid "The payment for this invoice has already been received." +msgstr "تم إستلام قيمة هذه الفاتورة مسبقا." + +#: pretix/plugins/paypal/payment.py:709 pretix/plugins/paypal/payment.py:717 +#: pretix/plugins/paypal2/payment.py:1078 +#: pretix/plugins/paypal2/payment.py:1086 msgid "PayPal payment ID" msgstr "رقم مرجع سداد PayPal" -#: pretix/plugins/paypal/payment.py:710 pretix/plugins/paypal2/payment.py:1079 +#: pretix/plugins/paypal/payment.py:711 pretix/plugins/paypal2/payment.py:1080 msgid "PayPal sale ID" msgstr "رقم مرجع البيع في PayPal" @@ -30423,26 +31524,26 @@ msgid "" "methods world-wide." msgstr "" -#: pretix/plugins/paypal2/payment.py:99 +#: pretix/plugins/paypal2/payment.py:100 #, fuzzy #| msgid "PayPal payment ID" msgid "PayPal Merchant ID" msgstr "رقم مرجع سداد PayPal" -#: pretix/plugins/paypal2/payment.py:141 +#: pretix/plugins/paypal2/payment.py:142 msgid "" "Even if a customer chooses an Alternative Payment Method, they will always " "have the option to revert back to paying with their PayPal account. For this " "reason, this payment method is always active." msgstr "" -#: pretix/plugins/paypal2/payment.py:149 +#: pretix/plugins/paypal2/payment.py:150 #, fuzzy #| msgid "Enable payment method" msgid "Alternative Payment Methods" msgstr "تفعيل طريقة الدفع" -#: pretix/plugins/paypal2/payment.py:151 +#: pretix/plugins/paypal2/payment.py:152 msgid "" "In addition to payments through a PayPal account, you can also offer your " "customers the option to pay with credit cards and other, local payment " @@ -30452,11 +31553,11 @@ msgid "" "PayPal Plus." msgstr "" -#: pretix/plugins/paypal2/payment.py:166 +#: pretix/plugins/paypal2/payment.py:167 msgid "Disable SEPA Direct Debit" msgstr "" -#: pretix/plugins/paypal2/payment.py:168 +#: pretix/plugins/paypal2/payment.py:169 msgid "" "While most payment methods cannot be recalled by a customer without " "outlining their exact grief with the merchants, SEPA Direct Debit can be " @@ -30465,30 +31566,30 @@ msgid "" "Debit payments in order to reduce the risk of costly chargebacks." msgstr "" -#: pretix/plugins/paypal2/payment.py:182 +#: pretix/plugins/paypal2/payment.py:183 msgid "Enable Buy Now Pay Later" msgstr "" -#: pretix/plugins/paypal2/payment.py:184 +#: pretix/plugins/paypal2/payment.py:185 msgid "" "Offer your customers the possibility to buy now (up to a certain limit) and " "pay in multiple installments or within 30 days. You, as the merchant, are " "getting your money right away." msgstr "" -#: pretix/plugins/paypal2/payment.py:216 +#: pretix/plugins/paypal2/payment.py:217 #, fuzzy #| msgid "Customer actions" msgid "-- Automatic --" msgstr "إجراءات العملاء" -#: pretix/plugins/paypal2/payment.py:222 +#: pretix/plugins/paypal2/payment.py:223 #, fuzzy #| msgid "Any country" msgid "Buyer country" msgstr "أي بلد" -#: pretix/plugins/paypal2/payment.py:246 +#: pretix/plugins/paypal2/payment.py:247 #, fuzzy #| msgid "" #| "To accept payments via PayPal, you will need an account at PayPal. By " @@ -30502,12 +31603,12 @@ msgstr "" "لقبول المدفوعات عبر PayPal ، ستحتاج إلى حساب في PayPal. من خلال النقر على " "الزر التالي ، يمكنك إما إنشاء حساب PayPal جديد يربط pretix بحساب موجود." -#: pretix/plugins/paypal2/payment.py:251 +#: pretix/plugins/paypal2/payment.py:252 #, python-brace-format msgid "Connect with {icon} PayPal" msgstr "اتصل مع {icon} PayPal" -#: pretix/plugins/paypal2/payment.py:265 +#: pretix/plugins/paypal2/payment.py:266 msgid "" "Please configure a PayPal Webhook to the following endpoint in order to " "automatically cancel orders when payments are refunded externally." @@ -30515,16 +31616,16 @@ msgstr "" "يرجى إعداد PayPal Webhook إلى نقطة النهاية التالية لإلغاء الطلبات تلقائيا " "عند رد المدفوعات خارجيا." -#: pretix/plugins/paypal2/payment.py:276 +#: pretix/plugins/paypal2/payment.py:277 msgid "PayPal does not process payments in your event's currency." msgstr "لا يعالج PayPal المدفوعات بعملة الفعالية الخاصة بك." -#: pretix/plugins/paypal2/payment.py:277 +#: pretix/plugins/paypal2/payment.py:278 msgid "" "Please check this PayPal page for a complete list of supported currencies." msgstr "يرجى مراجعة صفحة PayPal هذه للحصول على قائمة كاملة بالعملات المدعومة." -#: pretix/plugins/paypal2/payment.py:282 +#: pretix/plugins/paypal2/payment.py:283 msgid "" "Your event's currency is supported by PayPal as a payment and balance " "currency for in-country accounts only. This means, that the receiving as " @@ -30536,13 +31637,13 @@ msgstr "" "هذا يعني أنه يجب إنشاء حساب PayPal المستلم وكذلك حساب المرسل في نفس البلد " "واستخدام نفس العملة. لن تتمكن الحسابات خارج الدولة من إرسال أي مدفوعات." -#: pretix/plugins/paypal2/payment.py:334 pretix/plugins/paypal2/views.py:250 +#: pretix/plugins/paypal2/payment.py:335 pretix/plugins/paypal2/views.py:250 msgid "An error occurred during connecting with PayPal, please try again." msgstr "حدث خطأ أثناء الاتصال ب PayPal ، يرجى المحاولة مرة أخرى." -#: pretix/plugins/paypal2/payment.py:466 pretix/plugins/paypal2/payment.py:598 -#: pretix/plugins/paypal2/payment.py:672 pretix/plugins/paypal2/payment.py:735 -#: pretix/plugins/paypal2/payment.py:780 pretix/plugins/paypal2/payment.py:1015 +#: pretix/plugins/paypal2/payment.py:467 pretix/plugins/paypal2/payment.py:599 +#: pretix/plugins/paypal2/payment.py:673 pretix/plugins/paypal2/payment.py:736 +#: pretix/plugins/paypal2/payment.py:781 pretix/plugins/paypal2/payment.py:1016 #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pending.html:5 msgid "" "Your payment has failed due to a known issue within PayPal. Please try " @@ -30550,32 +31651,32 @@ msgid "" "attempt. You can also try other payment methods, if available." msgstr "" -#: pretix/plugins/paypal2/payment.py:476 pretix/plugins/paypal2/payment.py:1026 +#: pretix/plugins/paypal2/payment.py:477 pretix/plugins/paypal2/payment.py:1027 #, fuzzy #| msgid "This gift card was used in the meantime. Please try again." msgid "" "Something went wrong when requesting the payment status. Please try again." msgstr "تم استخدام بطاقة الهدايا هذه في هذه الأثناء. حاول مرة اخرى." -#: pretix/plugins/paypal2/payment.py:485 pretix/plugins/paypal2/payment.py:1035 +#: pretix/plugins/paypal2/payment.py:486 pretix/plugins/paypal2/payment.py:1036 #, fuzzy #| msgid "You may need to enable JavaScript for Stripe payments." msgid "You may need to enable JavaScript for PayPal payments." msgstr "قد تحتاج إلى تمكين JavaScript لمدفوعات Stripe." -#: pretix/plugins/paypal2/payment.py:969 +#: pretix/plugins/paypal2/payment.py:970 msgid "" "Refunding the amount via PayPal failed: The original payment does not " "contain the required information to issue an automated refund." msgstr "" -#: pretix/plugins/paypal2/payment.py:1103 +#: pretix/plugins/paypal2/payment.py:1104 #, fuzzy #| msgid "PayPal" msgid "PayPal APM" msgstr "PayPal" -#: pretix/plugins/paypal2/payment.py:1104 +#: pretix/plugins/paypal2/payment.py:1105 #, fuzzy #| msgid "Link to enable payment method" msgid "PayPal Alternative Payment Methods" @@ -30629,6 +31730,7 @@ msgid "Capture pending." msgstr "الرسوم معلقة" #: pretix/plugins/paypal2/signals.py:75 +#, python-brace-format msgid "PayPal reported an event: {}" msgstr "أبلغ PayPal عن حادثة: {}" @@ -30712,13 +31814,6 @@ msgid "" "different payment method, if you prefer." msgstr "" -#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:16 -#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:19 -#, fuzzy -#| msgid "Error:" -msgid "Error" -msgstr "خطأ:" - #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control.html:24 #, fuzzy #| msgid "Order status" @@ -30753,7 +31848,7 @@ msgid "Please turn on JavaScript." msgstr "حاول مرة اخرى." #: pretix/plugins/paypal2/templates/pretixplugins/paypal2/pay.html:29 -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:56 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:57 msgid "Please select how you want to pay." msgstr "يرجى اختيار طريقة الدفع." @@ -30819,47 +31914,47 @@ msgstr "" "يسمح لك هذا المكون الإضافي باستخدام تطبيقات preixdroid و premixdesk للفعالية " "الخاصة بك." -#: pretix/plugins/reports/accountingreport.py:58 +#: pretix/plugins/reports/accountingreport.py:59 #, fuzzy #| msgid "Account information" msgid "Accounting report" msgstr "معلومات الحساب" -#: pretix/plugins/reports/accountingreport.py:60 +#: pretix/plugins/reports/accountingreport.py:61 msgid "" "Download a PDF report of all sales and payments within a given time frame." msgstr "" -#: pretix/plugins/reports/accountingreport.py:62 -#: pretix/plugins/reports/exporters.py:246 +#: pretix/plugins/reports/accountingreport.py:63 +#: pretix/plugins/reports/exporters.py:257 msgctxt "export_category" msgid "Analysis" msgstr "" -#: pretix/plugins/reports/accountingreport.py:82 +#: pretix/plugins/reports/accountingreport.py:83 #, fuzzy #| msgid "Show all test mode orders" msgid "Ignore test mode orders" msgstr "عرض كل أوامر وضع الاختبار" -#: pretix/plugins/reports/accountingreport.py:90 +#: pretix/plugins/reports/accountingreport.py:91 #, fuzzy #| msgctxt "subevent" #| msgid "Event series date added" msgid "Split event series by date" msgstr "تمت إضافة تاريخ سلسلة الفعاليات" -#: pretix/plugins/reports/accountingreport.py:128 +#: pretix/plugins/reports/accountingreport.py:129 #, fuzzy #| msgid "Enabled" msgid "End" msgstr "تمكين" -#: pretix/plugins/reports/accountingreport.py:139 +#: pretix/plugins/reports/accountingreport.py:140 msgid "Report includes test orders which may be deleted later!" msgstr "" -#: pretix/plugins/reports/accountingreport.py:144 +#: pretix/plugins/reports/accountingreport.py:145 msgid "" "The report time frame includes data generated with an old software version " "that did not yet store all data required to create this report. The report " @@ -30867,32 +31962,32 @@ msgid "" "the time frame." msgstr "" -#: pretix/plugins/reports/accountingreport.py:644 -#: pretix/plugins/reports/accountingreport.py:694 +#: pretix/plugins/reports/accountingreport.py:645 +#: pretix/plugins/reports/accountingreport.py:695 #, fuzzy, python-brace-format #| msgid "Extend payment term" msgid "Pending payments at {datetime}" msgstr "تمديد فترة السداد" -#: pretix/plugins/reports/accountingreport.py:751 -#: pretix/plugins/reports/accountingreport.py:789 +#: pretix/plugins/reports/accountingreport.py:752 +#: pretix/plugins/reports/accountingreport.py:790 #, python-brace-format msgid "Total gift card value at {datetime}" msgstr "" -#: pretix/plugins/reports/accountingreport.py:770 +#: pretix/plugins/reports/accountingreport.py:771 #, fuzzy #| msgid "Gift card redemptions" msgid "Gift card transactions (credit)" msgstr "استرداد بطاقة هدية" -#: pretix/plugins/reports/accountingreport.py:780 +#: pretix/plugins/reports/accountingreport.py:781 #, fuzzy #| msgid "Gift card redemptions" msgid "Gift card transactions (debit)" msgstr "استرداد بطاقة هدية" -#: pretix/plugins/reports/accountingreport.py:882 +#: pretix/plugins/reports/accountingreport.py:883 #, fuzzy #| msgid "Ordered items" msgid "Open items" @@ -30909,108 +32004,108 @@ msgstr "مصدر التقرير" msgid "Generate printable reports about your sales." msgstr "يتيح لك هذا المكون الإضافي إنشاء تقارير قابلة للطباعة حول مبيعاتك." -#: pretix/plugins/reports/exporters.py:97 +#: pretix/plugins/reports/exporters.py:99 #, fuzzy, python-format #| msgctxt "invoice" #| msgid "Page %d of %d" msgid "Page %d of %d" msgstr "صفحة %d من %d" -#: pretix/plugins/reports/exporters.py:200 +#: pretix/plugins/reports/exporters.py:211 #, python-format msgid "Page %d" msgstr "الصفحة %d" -#: pretix/plugins/reports/exporters.py:202 +#: pretix/plugins/reports/exporters.py:213 #, python-format msgid "Created: %s" msgstr "تم الإنشاء:%s" -#: pretix/plugins/reports/exporters.py:245 +#: pretix/plugins/reports/exporters.py:256 msgid "Order overview (PDF)" msgstr "نظرة عامة على الطلب (PDF)" -#: pretix/plugins/reports/exporters.py:247 +#: pretix/plugins/reports/exporters.py:258 msgid "Download a PDF version of the key sales numbers per ticket type." msgstr "" -#: pretix/plugins/reports/exporters.py:275 +#: pretix/plugins/reports/exporters.py:286 #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:58 msgid "Orders by product" msgstr "الطلبات حسب المنتج" -#: pretix/plugins/reports/exporters.py:275 +#: pretix/plugins/reports/exporters.py:286 msgid "(excl. taxes)" msgstr "(باستثناء الضرائب)" -#: pretix/plugins/reports/exporters.py:275 +#: pretix/plugins/reports/exporters.py:286 msgid "(incl. taxes)" msgstr "(شامل الضرائب)" -#: pretix/plugins/reports/exporters.py:285 -#: pretix/plugins/reports/exporters.py:304 +#: pretix/plugins/reports/exporters.py:296 +#: pretix/plugins/reports/exporters.py:315 #, python-brace-format msgid "{axis} between {start} and {end}" msgstr "{axis} بين {start} و {end}" -#: pretix/plugins/reports/exporters.py:390 -#: pretix/plugins/reports/exporters.py:391 -#: pretix/plugins/reports/exporters.py:392 -#: pretix/plugins/reports/exporters.py:393 -#: pretix/plugins/reports/exporters.py:394 -#: pretix/plugins/reports/exporters.py:395 +#: pretix/plugins/reports/exporters.py:401 +#: pretix/plugins/reports/exporters.py:402 +#: pretix/plugins/reports/exporters.py:403 +#: pretix/plugins/reports/exporters.py:404 +#: pretix/plugins/reports/exporters.py:405 +#: pretix/plugins/reports/exporters.py:406 msgid "#" msgstr "#" -#: pretix/plugins/reports/exporters.py:477 +#: pretix/plugins/reports/exporters.py:488 #, fuzzy #| msgid "Check-in list (PDF)" msgid "Tax split list (PDF)" msgstr "قائمة التسجيل (PDF)" -#: pretix/plugins/reports/exporters.py:479 +#: pretix/plugins/reports/exporters.py:490 msgid "Download a PDF list with the tax amounts included in each order." msgstr "" -#: pretix/plugins/reports/exporters.py:556 +#: pretix/plugins/reports/exporters.py:567 #, python-brace-format msgid "Orders by tax rate ({currency})" msgstr "أوامر حسب معدل الضريبة ({currency})" -#: pretix/plugins/reports/exporters.py:565 -#: pretix/plugins/reports/exporters.py:794 -#: pretix/plugins/reports/exporters.py:846 -#: pretix/plugins/reports/exporters.py:887 +#: pretix/plugins/reports/exporters.py:576 +#: pretix/plugins/reports/exporters.py:805 +#: pretix/plugins/reports/exporters.py:857 +#: pretix/plugins/reports/exporters.py:898 msgid "Gross" msgstr "الإجمالي" -#: pretix/plugins/reports/exporters.py:565 -#: pretix/plugins/reports/exporters.py:795 -#: pretix/plugins/reports/exporters.py:847 -#: pretix/plugins/reports/exporters.py:887 +#: pretix/plugins/reports/exporters.py:576 +#: pretix/plugins/reports/exporters.py:806 +#: pretix/plugins/reports/exporters.py:858 +#: pretix/plugins/reports/exporters.py:898 msgid "Tax" msgstr "ضريبة" -#: pretix/plugins/reports/exporters.py:650 +#: pretix/plugins/reports/exporters.py:661 #, fuzzy #| msgid "Default list" msgid "Tax split list" msgstr "القائمة الافتراضية" -#: pretix/plugins/reports/exporters.py:652 +#: pretix/plugins/reports/exporters.py:663 msgid "Download a spreadsheet with the tax amounts included in each order." msgstr "" -#: pretix/plugins/reports/exporters.py:658 +#: pretix/plugins/reports/exporters.py:669 msgid "Taxes by country" msgstr "الضرائب حسب البلد" -#: pretix/plugins/reports/exporters.py:659 +#: pretix/plugins/reports/exporters.py:670 msgid "Business customers" msgstr "عملاء قطاع الأعمال" -#: pretix/plugins/reports/exporters.py:791 -#: pretix/plugins/reports/exporters.py:836 +#: pretix/plugins/reports/exporters.py:802 +#: pretix/plugins/reports/exporters.py:847 msgid "Country code" msgstr "رمز البلد" @@ -31077,7 +32172,7 @@ msgid "Waiting for" msgstr "انتظار" #: pretix/plugins/sendmail/forms.py:97 pretix/plugins/sendmail/forms.py:171 -#: pretix/plugins/sendmail/forms.py:349 +#: pretix/plugins/sendmail/forms.py:348 #, fuzzy #| msgid "Restrict to specific sales channels" msgctxt "sendmail_form" @@ -31165,21 +32260,21 @@ msgstr "" msgid "Attachment of tickets is disabled in this event's email settings." msgstr "" -#: pretix/plugins/sendmail/forms.py:234 pretix/plugins/sendmail/forms.py:388 +#: pretix/plugins/sendmail/forms.py:234 pretix/plugins/sendmail/forms.py:386 #: pretix/plugins/sendmail/views.py:267 #, fuzzy #| msgid "payment pending (except unapproved)" msgid "payment pending but already confirmed" msgstr "الدفع معلق (باستثناء غير الموافق عليه)" -#: pretix/plugins/sendmail/forms.py:235 pretix/plugins/sendmail/forms.py:390 +#: pretix/plugins/sendmail/forms.py:235 pretix/plugins/sendmail/forms.py:388 #: pretix/plugins/sendmail/views.py:268 #, fuzzy #| msgid "payment pending (except unapproved)" msgid "payment pending (except unapproved or already confirmed)" msgstr "الدفع معلق (باستثناء غير الموافق عليه)" -#: pretix/plugins/sendmail/forms.py:239 pretix/plugins/sendmail/forms.py:394 +#: pretix/plugins/sendmail/forms.py:239 pretix/plugins/sendmail/forms.py:392 #: pretix/plugins/sendmail/views.py:266 msgid "pending with payment overdue" msgstr "معلقة مع تأخر السداد" @@ -31198,60 +32293,60 @@ msgctxt "sendmail_form" msgid "Restrict to recipients with check-in on list" msgstr "يقتصر على قنوات بيع محددة" -#: pretix/plugins/sendmail/forms.py:373 +#: pretix/plugins/sendmail/forms.py:371 msgid "Type of schedule time" msgstr "" -#: pretix/plugins/sendmail/forms.py:376 +#: pretix/plugins/sendmail/forms.py:374 #, fuzzy #| msgid "Absolute value" msgid "Absolute" msgstr "قيمه مطلقه" -#: pretix/plugins/sendmail/forms.py:377 +#: pretix/plugins/sendmail/forms.py:375 #, fuzzy #| msgid "Required for events" msgid "Relative, before event start" msgstr "مطلوب للفعاليات" -#: pretix/plugins/sendmail/forms.py:378 +#: pretix/plugins/sendmail/forms.py:376 #, fuzzy #| msgid "Required for events" msgid "Relative, before event end" msgstr "مطلوب للفعاليات" -#: pretix/plugins/sendmail/forms.py:379 +#: pretix/plugins/sendmail/forms.py:377 #, fuzzy #| msgid "Required for events" msgid "Relative, after event start" msgstr "مطلوب للفعاليات" -#: pretix/plugins/sendmail/forms.py:380 +#: pretix/plugins/sendmail/forms.py:378 #, fuzzy #| msgid "Relative date:" msgid "Relative, after event end" msgstr "تاريخ نسبي:" -#: pretix/plugins/sendmail/forms.py:397 +#: pretix/plugins/sendmail/forms.py:395 #, fuzzy #| msgid "List of orders with taxes" msgctxt "sendmail_from" msgid "Restrict to orders with status" msgstr "قائمة الطلبات مع الضرائب" -#: pretix/plugins/sendmail/forms.py:412 +#: pretix/plugins/sendmail/forms.py:410 #, fuzzy #| msgid "Please choose a later date." msgid "Please specify the send date" msgstr "الرجاء اختيار تاريخ لاحق." -#: pretix/plugins/sendmail/forms.py:417 +#: pretix/plugins/sendmail/forms.py:415 #, fuzzy #| msgid "Please enter the same password twice" msgid "Please specify the offset days and time" msgstr "الرجاء إدخال نفس كلمة المرور مرتين" -#: pretix/plugins/sendmail/forms.py:428 +#: pretix/plugins/sendmail/forms.py:426 #, fuzzy #| msgid "Please select a quota." msgid "Please specify a product" @@ -31263,13 +32358,6 @@ msgstr "يرجى تحديد الحصص." msgid "scheduled" msgstr "تذكرة مخفضة" -#: pretix/plugins/sendmail/models.py:52 -#, fuzzy -#| msgctxt "payment_state" -#| msgid "failed" -msgid "failed" -msgstr "فشل" - #: pretix/plugins/sendmail/models.py:53 #, fuzzy #| msgid "Completed:" @@ -31590,12 +32678,6 @@ msgstr "تاريخ بدء الفعالية" msgid "Next execution:" msgstr "اختيار البيانات" -#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:56 -#, fuzzy -#| msgid "(unknown)" -msgid "unknown" -msgstr "(غير معروف)" - #: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:60 #, fuzzy #| msgid "Data selection" @@ -31784,11 +32866,6 @@ msgstr "الأرباح المحتملة" msgid "Minimum Price" msgstr "أدنى سعر" -#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:109 -#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:111 -msgid "Available" -msgstr "متاح" - #: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:116 msgid "On Sale" msgstr "للبيع" @@ -32436,26 +33513,27 @@ msgid "Payment authorization failed." msgstr "فشل إذن الدفع." #: pretix/plugins/stripe/signals.py:104 -#, fuzzy +#, fuzzy, python-brace-format msgid "Charge failed. Reason: {}" msgstr "فشل سداد الرسوم. السبب: {}" #: pretix/plugins/stripe/signals.py:106 -#, fuzzy +#, fuzzy, python-brace-format msgid "Dispute created. Reason: {}" msgstr "تم إنشاء النزاع. سبب: {}" #: pretix/plugins/stripe/signals.py:108 -#, fuzzy +#, fuzzy, python-brace-format msgid "Dispute updated. Reason: {}" msgstr "تم تحديث النزاع. سبب: {}" #: pretix/plugins/stripe/signals.py:110 -#, fuzzy +#, fuzzy, python-brace-format msgid "Dispute closed. Status: {}" msgstr "النزاع مغلق. حالة: {}" #: pretix/plugins/stripe/signals.py:113 +#, python-brace-format msgid "Stripe reported an event: {}" msgstr "أبلغ Stripe عن فعالية: {}" @@ -32716,6 +33794,7 @@ msgid "An error occurred during connecting with Stripe, please try again." msgstr "حدث خطأ أثناء الاتصال ب Stripe ، يرجى المحاولة مرة أخرى." #: pretix/plugins/stripe/views.py:157 pretix/plugins/stripe/views.py:159 +#, python-brace-format msgid "Stripe returned an error: {}" msgstr "قام Stripe بإرجاع خطأ: {}" @@ -32909,6 +33988,7 @@ msgid "The selected ticket layout been deleted." msgstr "تم حذف نسق التذكرة المحدد." #: pretix/plugins/ticketoutputpdf/views.py:250 +#, python-brace-format msgid "Ticket PDF layout: {}" msgstr "نسق PDF للتذكرة: {}" @@ -32971,7 +34051,7 @@ msgctxt "checkoutflow" msgid "Your information" msgstr "معلوماتك" -#: pretix/presale/checkoutflow.py:990 +#: pretix/presale/checkoutflow.py:994 msgid "" "Unfortunately, based on the invoice address you entered, we're not able to " "sell you the selected products for tax-related legal reasons." @@ -32979,7 +34059,7 @@ msgstr "" "للأسف ، بناء على عنوان الفاتورة التي أدخلتها ، لا يمكننا بيع المنتجات " "المحددة لك لأسباب قانونية متعلقة بالضرائب." -#: pretix/presale/checkoutflow.py:996 +#: pretix/presale/checkoutflow.py:1000 msgid "" "Due to the invoice address you entered, we need to apply a different tax " "rate to your purchase and the price of the products in your cart has changed " @@ -32988,27 +34068,31 @@ msgstr "" "نظرا لعنوان الفاتورة الذي أدخلته ، نحتاج إلى تطبيق معدل ضريبة مختلف على " "مشترياتك وتغير سعر المنتجات في سلة التسوق وفقا لذلك." -#: pretix/presale/checkoutflow.py:1029 +#: pretix/presale/checkoutflow.py:1024 pretix/presale/checkoutflow.py:1030 +msgid "Please enter a valid email address." +msgstr "الرجاء قم بإدخال بريد الكتروني صحيح." + +#: pretix/presale/checkoutflow.py:1037 msgid "Please enter your invoicing address." msgstr "الرجاء إدخال عنوان الفواتير الخاص بك." -#: pretix/presale/checkoutflow.py:1033 +#: pretix/presale/checkoutflow.py:1041 msgid "Please enter your name." msgstr "يرجى إدخال اسمك." -#: pretix/presale/checkoutflow.py:1068 pretix/presale/checkoutflow.py:1073 -#: pretix/presale/checkoutflow.py:1078 pretix/presale/checkoutflow.py:1083 -#: pretix/presale/checkoutflow.py:1088 +#: pretix/presale/checkoutflow.py:1076 pretix/presale/checkoutflow.py:1081 +#: pretix/presale/checkoutflow.py:1086 pretix/presale/checkoutflow.py:1091 +#: pretix/presale/checkoutflow.py:1096 msgid "Please fill in answers to all required questions." msgstr "يرجى ملء الإجابات على جميع الأسئلة المطلوبة." -#: pretix/presale/checkoutflow.py:1249 +#: pretix/presale/checkoutflow.py:1259 msgctxt "checkoutflow" msgid "Payment" msgstr "المبلغ" -#: pretix/presale/checkoutflow.py:1362 -#, fuzzy +#: pretix/presale/checkoutflow.py:1372 +#, fuzzy, python-brace-format #| msgid "" #| "Your gift card has been applied, but {} still need to be paid. Please " #| "select a payment method." @@ -33019,32 +34103,32 @@ msgstr "" "تم استعمال بطاقة الهدايا الخاصة بك، ولكن {} لا تزال بحاجة إلى أن يتم سدادها. " "الرجاء اختيار طريقة الدفع." -#: pretix/presale/checkoutflow.py:1387 pretix/presale/views/order.py:676 +#: pretix/presale/checkoutflow.py:1397 pretix/presale/views/order.py:676 msgid "Please select a payment method." msgstr "الرجاء اختيار طريقة الدفع." -#: pretix/presale/checkoutflow.py:1414 pretix/presale/checkoutflow.py:1428 -#: pretix/presale/checkoutflow.py:1439 +#: pretix/presale/checkoutflow.py:1424 pretix/presale/checkoutflow.py:1438 +#: pretix/presale/checkoutflow.py:1449 #, fuzzy #| msgid "Please select a payment method." msgid "Please select a payment method to proceed." msgstr "الرجاء اختيار طريقة الدفع." -#: pretix/presale/checkoutflow.py:1444 pretix/presale/views/order.py:435 +#: pretix/presale/checkoutflow.py:1454 pretix/presale/views/order.py:435 #: pretix/presale/views/order.py:502 msgid "The payment information you entered was incomplete." msgstr "معلومات الدفع التي أدخلتها غير مكتملة." -#: pretix/presale/checkoutflow.py:1489 +#: pretix/presale/checkoutflow.py:1499 msgctxt "checkoutflow" msgid "Review order" msgstr "مراجعة الطلب" -#: pretix/presale/checkoutflow.py:1583 +#: pretix/presale/checkoutflow.py:1593 msgid "You need to check all checkboxes on the bottom of the page." msgstr "تحتاج إلى تحديد جميع مربعات الاختيار أسفل الصفحة." -#: pretix/presale/checkoutflow.py:1638 +#: pretix/presale/checkoutflow.py:1648 msgid "" "There was an error sending the confirmation mail. Please try again later." msgstr "حدث خطأ في إرسال بريد التأكيد. الرجاء معاودة المحاولة في وقت لاحق." @@ -33204,8 +34288,8 @@ msgstr "" #: pretix/presale/forms/order.py:113 pretix/presale/forms/order.py:121 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:171 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:311 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:186 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:339 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:188 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:341 #: pretix/presale/templates/pretixpresale/event/voucher.html:198 #: pretix/presale/templates/pretixpresale/event/voucher.html:353 msgid "plus taxes" @@ -33257,20 +34341,20 @@ msgstr "القبول: {datetime}" msgid "Organizer: {organizer}" msgstr "منظم: {organizer}" -#: pretix/presale/templates/pretixpresale/base.html:47 +#: pretix/presale/templates/pretixpresale/base.html:44 #, fuzzy #| msgid "Send links" msgctxt "skip-to-main-nav" msgid "Skip link" msgstr "قم بإرسال روابط" -#: pretix/presale/templates/pretixpresale/base.html:48 +#: pretix/presale/templates/pretixpresale/base.html:45 #, fuzzy #| msgid "Email content" msgid "Skip to main content" msgstr "البريد الإلكتروني المحتوى" -#: pretix/presale/templates/pretixpresale/base.html:76 +#: pretix/presale/templates/pretixpresale/base.html:75 #, fuzzy #| msgid "Toggle navigation" msgid "Footer Navigation" @@ -33385,8 +34469,10 @@ msgstr "تأكيدات" #: pretix/presale/templates/pretixpresale/event/base.html:222 #: pretix/presale/templates/pretixpresale/organizers/base.html:100 -msgid "Contact event organizer" -msgstr "اتصل بمنظم الفعالية" +#, fuzzy +#| msgid "Contact:" +msgid "Contact" +msgstr "جهة اتصال:" #: pretix/presale/templates/pretixpresale/event/base.html:225 #: pretix/presale/templates/pretixpresale/fragment_modals.html:118 @@ -33445,11 +34531,11 @@ msgid "Our recommendations" msgstr "ملاحظات الطلب" #: pretix/presale/templates/pretixpresale/event/checkout_addons.html:85 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:202 -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:120 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:205 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:121 #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:75 -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:125 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:187 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:126 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:189 #: pretix/presale/templates/pretixpresale/organizers/customer_address_delete.html:28 #: pretix/presale/templates/pretixpresale/organizers/customer_profile_delete.html:28 msgid "Go back" @@ -33462,20 +34548,19 @@ msgstr "خطوة %(current)s of %(total)s: %(label)s" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:12 #: pretix/presale/templates/pretixpresale/event/checkout_base.html:56 -#: pretix/presale/templates/pretixpresale/event/checkout_base.html:57 msgid "Checkout" msgstr "الدفع" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:15 #: pretix/presale/templates/pretixpresale/event/checkout_base.html:21 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:18 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:17 #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:9 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:11 msgid "Your cart" msgstr "عربتك" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:28 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:28 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:27 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:18 msgid "Cart expired" msgstr "انتهت صلاحية عربة التسوق" @@ -33487,57 +34572,56 @@ msgid "Show full cart" msgstr "مزيد من المعلومات" #: pretix/presale/templates/pretixpresale/event/checkout_base.html:52 -#: pretix/presale/templates/pretixpresale/event/index.html:87 +#: pretix/presale/templates/pretixpresale/event/index.html:86 msgid "Add tickets for a different date" msgstr "أضف تذاكر لتاريخ مختلف" #: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:8 #: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:10 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:11 msgid "Review order" msgstr "قم بمراجعة الطلب" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:13 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:12 msgid "Please review the details below and confirm your order." msgstr "يرجى مراجعة التفاصيل أدناه وتأكيد طلبك." -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:20 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:19 msgid "Add or remove tickets" msgstr "إضافة أو إزالة التذاكر" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:37 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:36 msgid "Please hang tight, we're finalizing your order!" msgstr "يرجى الانتظار ، نحن بصدد إنهاء طلبك!" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:45 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:44 msgid "Modify payment" msgstr "تعديل الدفع" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:46 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:77 -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:126 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:45 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:76 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:129 msgid "Modify" msgstr "تعديل" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:76 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:75 msgid "Modify invoice information" msgstr "تعديل معلومات الفاتورة" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:124 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:127 #: pretix/presale/templates/pretixpresale/event/checkout_questions.html:19 #: pretix/presale/templates/pretixpresale/event/order_modify.html:33 msgid "Contact information" msgstr "معلومات التواصل" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:125 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:128 msgid "Modify contact information" msgstr "تعديل معلومات الاتصال" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:168 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:171 msgid "Confirmations" msgstr "تأكيدات" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:186 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:189 #, fuzzy #| msgid "" #| "Your order requires approval by the event organizer before it can be " @@ -33548,7 +34632,7 @@ msgid "" "contract." msgstr "يتطلب طلبك موافقة منظم الفعالية قبل تأكيده." -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:188 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:191 #, fuzzy #| msgid "" #| "We will sent you an email as soon as the event organizer approved or " @@ -33561,7 +34645,7 @@ msgstr "" "سنرسل إليك بريدا إلكترونيا بمجرد أن يوافق منظم الفعالية على طلبك أو يرفضه. " "إذا تمت الموافقة على طلبك ، فسنرسل لك رابطا يمكنك استخدامه للدفع." -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:192 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:195 #, fuzzy #| msgid "" #| "We will sent you an email as soon as the event organizer approved or " @@ -33573,23 +34657,23 @@ msgstr "" "سنرسل إليك بريدا إلكترونيا بمجرد أن يوافق منظم الفعالية على طلبك أو يرفضه. " "إذا تمت الموافقة على طلبك ، فسنرسل لك رابطا يمكنك استخدامه للدفع." -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:208 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:211 msgid "Place binding order" msgstr "تأكيد الطلب" -#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:210 +#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:213 msgid "Submit registration" msgstr "قم بإرسال تسجيل" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:18 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:19 msgid "Log in with a customer account" msgstr "تسجيل الدخول بحساب العميل" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:25 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:26 msgid "You are currently logged in with the following credentials." msgstr "لقد قمت بتسجيل الدخول حاليا باستخدام بيانات الاعتماد التالية." -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:43 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:44 #, python-format msgid "" "If you created a customer account at %(org)s before, you can log in now and " @@ -33600,11 +34684,11 @@ msgstr "" "طلبك بحسابك. سيسمح لك ذلك بمشاهدة جميع طلباتك في مكان واحد والوصول إليها في " "أي وقت." -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:76 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:77 msgid "Create a new customer account" msgstr "قم بإنشاء حساب عميل جديد" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:83 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:84 #, python-format msgid "" "We will send you an email with a link to activate your account and set a " @@ -33615,11 +34699,11 @@ msgstr "" "تتمكن من استخدام الحساب للطلبات المستقبلية على%(org)s ولا يزال بإمكانك المضي " "قدما في عملية الشراء هذه قبل أن تتلقى البريد الإلكتروني." -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:100 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:101 msgid "Continue as a guest" msgstr "الاستمر كزائر" -#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:106 +#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:107 msgid "" "You are not required to create an account. If you proceed as a guest, you " "will be able to access the details and status of your order any time through " @@ -33638,7 +34722,7 @@ msgstr "" "عضوية نشطة في حسابك." #: pretix/presale/templates/pretixpresale/event/checkout_membership.html:34 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:110 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:112 msgid "Selected add-ons" msgstr "إضافات تم اختيارها" @@ -33649,59 +34733,59 @@ msgid "" "product." msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:12 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:13 #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:30 #, fuzzy #| msgid "Please confirm the following payment details." msgid "You already selected the following payment methods:" msgstr "يرجى تأكيد تفاصيل الدفع التالية." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:29 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:30 #, fuzzy #| msgctxt "invoice" #| msgid "Received payments" msgid "Remove payment" msgstr "المدفوعات المستلمة" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:39 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:40 #, fuzzy #| msgid "Pending amount" msgid "Remaining balance" msgstr "مبالغ متأخرة" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:40 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:41 #, fuzzy #| msgid "Please select a payment method." msgid "Please select a payment method below." msgstr "الرجاء اختيار طريقة الدفع." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:53 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:54 #, fuzzy #| msgid "Please select how you want to pay." msgid "Please select how you want to pay the remaining balance:" msgstr "يرجى اختيار طريقة الدفع." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:91 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:92 msgid "This sales channel does not provide support for test mode." msgstr "لا توفر قناة المبيعات هذه دعما لوضع الاختبار." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:93 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:94 msgid "If you continue, you might pay an actual order with non-existing money!" msgstr "إذا تابعت ، فقد تدفع طلبا فعليا بمبلغ غير موجود!" -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:101 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:102 msgid "This payment provider does not provide support for test mode." msgstr "لا يوفر مزود الدفع هذا دعما لوضع الاختبار." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:103 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:104 msgid "If you continue, actual money might be transferred." msgstr "إذا قمت بالمتابعة، قد يتم تحويل المبلغ الفعلي." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:114 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:115 msgid "There are no payment providers enabled." msgstr "لم يتم تمكين مزودي الدفع." -#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:116 +#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:117 msgid "" "Please go to the payment settings and activate one or more payment providers." msgstr "يرجى الذهاب إلى إعدادات الدفع وتفعيل واحد أو أكثر من مزودي الدفع." @@ -33710,23 +34794,23 @@ msgstr "يرجى الذهاب إلى إعدادات الدفع وتفعيل وا msgid "Before we continue, we need you to answer some questions." msgstr "قبل أن نواصل ، نحتاج منك الإجابة على بعض الأسئلة." -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:47 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:49 #, fuzzy #| msgid "Email address" msgid "Auto-fill with address" msgstr "عنوان البريد الإلكتروني" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:54 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:157 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:56 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:159 msgid "Fill form" msgstr "" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:91 -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:168 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:93 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:170 msgid "Copy answers from above" msgstr "انسخ الإجابات من الأعلى" -#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:148 +#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:150 #, fuzzy #| msgid "Public profile" msgid "Auto-fill with profile" @@ -33803,7 +34887,7 @@ msgstr "يمكنك الاختيار بين%(min_count)s و %(max_count)s من ه #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:64 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:258 #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:55 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:277 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:279 #: pretix/presale/templates/pretixpresale/event/voucher.html:293 #, python-format msgid "minimum amount to order: %(num)s" @@ -33814,9 +34898,9 @@ msgstr "المبلغ الأدنى للطلب: %(num)s" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:185 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:300 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:325 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:76 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:174 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:327 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:77 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:176 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:329 #: pretix/presale/templates/pretixpresale/event/voucher.html:117 #: pretix/presale/templates/pretixpresale/event/voucher.html:186 #: pretix/presale/templates/pretixpresale/event/voucher.html:341 @@ -33838,21 +34922,21 @@ msgid "from %(from_price)s to %(to_price)s" msgstr "من %(minprice)s" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:98 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:103 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:105 #, fuzzy #| msgid "Show variants" msgid "Hide variants" msgstr "قم بعرض الأنواع" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:102 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:107 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:109 msgid "Show variants" msgstr "قم بعرض الأنواع" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:129 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:271 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:133 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:288 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:135 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:290 #: pretix/presale/templates/pretixpresale/event/voucher.html:147 #: pretix/presale/templates/pretixpresale/event/voucher.html:304 #, fuzzy @@ -33862,8 +34946,8 @@ msgstr "السعر الأصلي" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:136 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:278 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:143 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:298 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:145 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:300 #: pretix/presale/templates/pretixpresale/event/voucher.html:157 #: pretix/presale/templates/pretixpresale/event/voucher.html:314 #, fuzzy @@ -33875,10 +34959,10 @@ msgstr "السعر الصافي" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:150 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:289 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:291 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:160 #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:162 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:314 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:164 #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:316 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:318 #: pretix/presale/templates/pretixpresale/event/voucher.html:173 #: pretix/presale/templates/pretixpresale/event/voucher.html:175 #: pretix/presale/templates/pretixpresale/event/voucher.html:328 @@ -33890,9 +34974,9 @@ msgstr "تعديل السعر ل%(item)s" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:153 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:294 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:149 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:165 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:319 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:151 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:167 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:321 #: pretix/presale/templates/pretixpresale/event/voucher.html:163 #: pretix/presale/templates/pretixpresale/event/voucher.html:178 #: pretix/presale/templates/pretixpresale/event/voucher.html:333 @@ -33902,8 +34986,8 @@ msgstr "تعديل السعر ل%(item)s" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:173 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:313 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:188 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:341 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:190 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:343 #: pretix/presale/templates/pretixpresale/event/voucher.html:200 #: pretix/presale/templates/pretixpresale/event/voucher.html:355 msgid "incl. taxes" @@ -33911,8 +34995,8 @@ msgstr "بما في ذلك. الضرائب" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:176 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:316 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:192 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:345 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:194 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:347 #: pretix/presale/templates/pretixpresale/event/voucher.html:204 #: pretix/presale/templates/pretixpresale/event/voucher.html:359 #, python-format @@ -33921,8 +35005,8 @@ msgstr " زائد %(rate)s%% %(name)s" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:180 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:320 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:198 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:351 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:200 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:353 #: pretix/presale/templates/pretixpresale/event/voucher.html:210 #: pretix/presale/templates/pretixpresale/event/voucher.html:365 #, python-format @@ -33931,8 +35015,8 @@ msgstr "بما في ذلك %(rate)s%% %(name)s" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:203 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:349 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:219 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:371 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:221 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:373 #: pretix/presale/templates/pretixpresale/event/voucher.html:230 #: pretix/presale/templates/pretixpresale/event/voucher.html:385 #, fuzzy @@ -33944,8 +35028,8 @@ msgstr "اختر ولايه" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:208 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:354 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:224 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:376 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:226 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:378 #: pretix/presale/templates/pretixpresale/event/voucher.html:235 #: pretix/presale/templates/pretixpresale/event/voucher.html:390 #, fuzzy @@ -33955,8 +35039,8 @@ msgstr "كمية" #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:218 #: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:364 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:235 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:388 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:237 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:390 #: pretix/presale/templates/pretixpresale/event/voucher.html:242 #: pretix/presale/templates/pretixpresale/event/voucher.html:398 #, fuzzy @@ -33988,17 +35072,17 @@ msgid "Not available any more." msgstr "غير متاح" #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:23 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:87 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:89 msgid "SOLD OUT" msgstr "تم بيعه" #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:25 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:85 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:87 msgid "FULLY BOOKED" msgstr "محجوزة بالكامل" #: pretix/presale/templates/pretixpresale/event/fragment_availability.html:37 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:95 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:97 #: pretix/presale/templates/pretixpresale/fragment_calendar.html:99 #: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:104 #: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:30 @@ -34137,7 +35221,7 @@ msgid "We're trying to reserve another one for you!" msgstr "نحاول حجز واحدة أخرى لك!" #: pretix/presale/templates/pretixpresale/event/fragment_cart.html:304 -#: pretix/presale/templates/pretixpresale/event/index.html:187 +#: pretix/presale/templates/pretixpresale/event/index.html:186 #: pretix/presale/templates/pretixpresale/event/seatingplan.html:24 #: pretix/presale/templates/pretixpresale/event/voucher.html:62 #, python-format @@ -34234,7 +35318,7 @@ msgid "Empty cart" msgstr "إلغاء الطلبات" #: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:68 -#: pretix/presale/templates/pretixpresale/event/index.html:249 +#: pretix/presale/templates/pretixpresale/event/index.html:248 #: pretix/presale/templates/pretixpresale/event/voucher_form.html:16 msgid "Redeem a voucher" msgstr "استخدم كود خصم" @@ -34348,9 +35432,9 @@ msgid "" msgstr "" #: pretix/presale/templates/pretixpresale/event/fragment_change_confirm.html:152 -#: pretix/presale/templates/pretixpresale/event/order.html:391 -#: pretix/presale/templates/pretixpresale/event/order.html:427 -#: pretix/presale/templates/pretixpresale/event/order.html:448 +#: pretix/presale/templates/pretixpresale/event/order.html:395 +#: pretix/presale/templates/pretixpresale/event/order.html:431 +#: pretix/presale/templates/pretixpresale/event/order.html:452 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:113 msgid "" "The refund will be issued in form of a gift card that you can use for " @@ -34531,15 +35615,15 @@ msgid "Uncategorized items" msgstr "غير مصنف" #: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:40 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:259 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:261 #: pretix/presale/templates/pretixpresale/event/voucher.html:94 #: pretix/presale/templates/pretixpresale/event/voucher.html:275 #, python-format msgid "Show full-size image of %(item)s" msgstr "أظهر صورة بالحجم الكبير ل %(item)s" -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:191 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:344 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:193 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:346 #: pretix/presale/templates/pretixpresale/event/voucher.html:203 #: pretix/presale/templates/pretixpresale/event/voucher.html:358 #, fuzzy, python-format @@ -34547,8 +35631,8 @@ msgstr "أظهر صورة بالحجم الكبير ل %(item)s" msgid "%(value)s incl. taxes" msgstr "(شامل الضرائب)" -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:197 -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:350 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:199 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:352 #: pretix/presale/templates/pretixpresale/event/voucher.html:209 #: pretix/presale/templates/pretixpresale/event/voucher.html:364 #, fuzzy, python-format @@ -34556,7 +35640,7 @@ msgstr "(شامل الضرائب)" msgid "%(value)s without taxes" msgstr "القيمة الإجمالية (بدون الضرائب)" -#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:304 +#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:306 #: pretix/presale/templates/pretixpresale/event/voucher.html:320 #, fuzzy, python-format #| msgid "Modify price for %(item)s" @@ -34665,55 +35749,46 @@ msgid "" " " msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:50 -msgid "Your cart, general information, add products to your cart" -msgstr "" -"عربة التسوق الخاصة بك ، معلومات عامة ، أضف منتجات إلى عربة التسوق الخاصة بك" - -#: pretix/presale/templates/pretixpresale/event/index.html:50 -msgid "General information, add products to your cart" -msgstr "معلومات عامة ، أضف منتجات إلى سلة التسوق الخاصة بك" - -#: pretix/presale/templates/pretixpresale/event/index.html:70 +#: pretix/presale/templates/pretixpresale/event/index.html:69 msgid "Please select a date to redeem your voucher." msgstr "الرجاء تحديد تاريخ استرداد كود الخصم الخاصة بك." -#: pretix/presale/templates/pretixpresale/event/index.html:89 +#: pretix/presale/templates/pretixpresale/event/index.html:88 msgid "View other date" msgstr "عرض تاريخ آخر" -#: pretix/presale/templates/pretixpresale/event/index.html:92 +#: pretix/presale/templates/pretixpresale/event/index.html:91 msgid "Choose date to book a ticket" msgstr "اختر تاريخا لحجز تذكرة" -#: pretix/presale/templates/pretixpresale/event/index.html:156 +#: pretix/presale/templates/pretixpresale/event/index.html:155 #: pretix/presale/views/waiting.py:141 pretix/presale/views/widget.py:774 #, fuzzy #| msgid "The presale period for this event is over." msgid "The booking period for this event is over." msgstr "انتهت فترة العرض ما قبل البيع لهذه الفعالية." -#: pretix/presale/templates/pretixpresale/event/index.html:164 +#: pretix/presale/templates/pretixpresale/event/index.html:163 #: pretix/presale/views/widget.py:776 #, fuzzy, python-format #| msgid "The presale for this event will start on %(date)s at %(time)s." msgid "The booking period for this event will start on %(date)s at %(time)s." msgstr "سيبدأ البيع المسبق لهذه الفعالية في%(date)s عند %(time)s." -#: pretix/presale/templates/pretixpresale/event/index.html:186 +#: pretix/presale/templates/pretixpresale/event/index.html:185 #: pretix/presale/templates/pretixpresale/event/seatingplan.html:23 #: pretix/presale/templates/pretixpresale/event/voucher.html:61 msgid "We're now trying to reserve this for you!" msgstr "نحاول الآن الحجز لك!" -#: pretix/presale/templates/pretixpresale/event/index.html:205 +#: pretix/presale/templates/pretixpresale/event/index.html:204 msgid "" "Some of the categories in the seating plan above are currently sold out. If " "you want, you can add yourself to the waiting list. We will then notify if " "seats are available again." msgstr "" -#: pretix/presale/templates/pretixpresale/event/index.html:214 +#: pretix/presale/templates/pretixpresale/event/index.html:213 #, fuzzy #| msgid "Enable waiting list" msgid "Join waiting list" @@ -34730,11 +35805,11 @@ msgstr "التسجيل" msgid "Add to cart" msgstr "أضف إلى سلة التسوق" -#: pretix/presale/templates/pretixpresale/event/index.html:256 +#: pretix/presale/templates/pretixpresale/event/index.html:255 msgid "If you have already ordered a ticket" msgstr "إذا كنت قد طلبت تذكرة سابقا" -#: pretix/presale/templates/pretixpresale/event/index.html:260 +#: pretix/presale/templates/pretixpresale/event/index.html:259 msgid "" "If you want to see or change the status and details of your order, click on " "the link in one of the emails we sent you during the order process. If you " @@ -34746,7 +35821,7 @@ msgstr "" "من العثور على الرابط ، فانقر فوق الزر التالي للحصول على الرابط الخاص بطلبك " "وليتم إرساله إليك مرة أخرى." -#: pretix/presale/templates/pretixpresale/event/index.html:269 +#: pretix/presale/templates/pretixpresale/event/index.html:268 msgid "Resend order link" msgstr "إعادة إرسال روابط الطلب" @@ -34774,26 +35849,26 @@ msgid "Please try again later." msgstr "حاول مرة اخرى." #: pretix/presale/templates/pretixpresale/event/order.html:13 -#: pretix/presale/templates/pretixpresale/event/order.html:30 +#: pretix/presale/templates/pretixpresale/event/order.html:29 msgid "Thank you!" msgstr "شكرا لك!" #: pretix/presale/templates/pretixpresale/event/order.html:15 -#: pretix/presale/templates/pretixpresale/event/order.html:33 +#: pretix/presale/templates/pretixpresale/event/order.html:32 msgid "Your order has been placed successfully. See below for details." msgstr "تم وضع طلبك بنجاح. انظر أدناه للحصول على التفاصيل." #: pretix/presale/templates/pretixpresale/event/order.html:17 -#: pretix/presale/templates/pretixpresale/event/order.html:49 +#: pretix/presale/templates/pretixpresale/event/order.html:48 msgid "Your order has been processed successfully! See below for details." msgstr "تمت معالجة طلبك بنجاح! انظر أدناه للحصول على التفاصيل." #: pretix/presale/templates/pretixpresale/event/order.html:19 -#: pretix/presale/templates/pretixpresale/event/order.html:51 +#: pretix/presale/templates/pretixpresale/event/order.html:50 msgid "We successfully received your payment. See below for details." msgstr "تم الدفع بنجاح، تجد التفاصيل في الأسفل." -#: pretix/presale/templates/pretixpresale/event/order.html:36 +#: pretix/presale/templates/pretixpresale/event/order.html:35 #, fuzzy #| msgid "" #| "Please note that we still await approval by the event organizer before " @@ -34805,7 +35880,7 @@ msgstr "" "يرجى ملاحظة أننا ما زلنا ننتظر موافقة منظم الفعالية قبل أن تتمكن من الدفع " "وإكمال هذا الطلب." -#: pretix/presale/templates/pretixpresale/event/order.html:40 +#: pretix/presale/templates/pretixpresale/event/order.html:39 msgid "" "Please note that we still await approval by the event organizer before you " "can pay and complete this order." @@ -34813,23 +35888,32 @@ msgstr "" "يرجى ملاحظة أننا ما زلنا ننتظر موافقة منظم الفعالية قبل أن تتمكن من الدفع " "وإكمال هذا الطلب." -#: pretix/presale/templates/pretixpresale/event/order.html:44 +#: pretix/presale/templates/pretixpresale/event/order.html:43 msgid "Please note that we still await your payment to complete the process." msgstr "يرجى ملاحظة أننا ما زلنا ننتظر دفعتك لإكمال العملية." -#: pretix/presale/templates/pretixpresale/event/order.html:56 +#: pretix/presale/templates/pretixpresale/event/order.html:55 +#, fuzzy +#| msgid "" +#| "Please bookmark or save the link to this exact page if you want to access " +#| "your order later. We also sent you an email containing the link to the " +#| "address you specified." msgid "" "Please bookmark or save the link to this exact page if you want to access " -"your order later. We also sent you an email containing the link to the " -"address you specified." +"your order later. We also sent you an email to the address you specified " +"containing the link to this page." msgstr "" "تم إرسال رابط الطلب إلى بريدك الإلكتروني. كما يمكنك حفظ رابط هذه الصفحة إذا " "أردت الوصول إلى طلبك لاحقا." #: pretix/presale/templates/pretixpresale/event/order.html:59 +#, fuzzy +#| msgid "" +#| "Please save the following link if you want to access your order later. We " +#| "also sent you an email containing the link to the address you specified." msgid "" "Please save the following link if you want to access your order later. We " -"also sent you an email containing the link to the address you specified." +"also sent you an email to the address you specified containing the link." msgstr "" "يرجى حفظ الرابط التالي إذا كنت تريد الوصول إلى طلبك لاحقا. لقد أرسلنا لك " "أيضا رسالة بريد إلكتروني تحتوي على رابط العنوان الذي حددته." @@ -34917,7 +36001,7 @@ msgstr "تحتاج إلى تحديد طريقة دفع أعلاه قبل أن ت #: pretix/presale/templates/pretixpresale/event/order.html:268 #: pretix/presale/templates/pretixpresale/event/order.html:275 -#: pretix/presale/templates/pretixpresale/event/order_modify.html:85 +#: pretix/presale/templates/pretixpresale/event/order_modify.html:86 msgid "Request invoice" msgstr "اطلب فاتورة" @@ -34933,26 +36017,26 @@ msgstr "قم بتغيير بياناتك" msgid "Internal Reference" msgstr "المرجع الداخلي" -#: pretix/presale/templates/pretixpresale/event/order.html:350 +#: pretix/presale/templates/pretixpresale/event/order.html:354 msgctxt "action" msgid "Change or cancel your order" msgstr "قم بتعديل أو إلغاء طلبك" -#: pretix/presale/templates/pretixpresale/event/order.html:352 +#: pretix/presale/templates/pretixpresale/event/order.html:356 #, fuzzy #| msgid "Change order" msgctxt "action" msgid "Change your order" msgstr "قم بتغيير الطلب" -#: pretix/presale/templates/pretixpresale/event/order.html:354 +#: pretix/presale/templates/pretixpresale/event/order.html:358 #, fuzzy #| msgid "Cancel order" msgctxt "action" msgid "Cancel your order" msgstr "الغاء الطلب" -#: pretix/presale/templates/pretixpresale/event/order.html:362 +#: pretix/presale/templates/pretixpresale/event/order.html:366 msgid "" "If you want to make changes to the products you bought, you can click on the " "button to change your order." @@ -34960,18 +36044,18 @@ msgstr "" "إذا كنت ترغب في إجراء تغييرات على المنتجات التي اشتريتها ، يمكنك النقر فوق " "الزر لتغيير طلبك." -#: pretix/presale/templates/pretixpresale/event/order.html:370 +#: pretix/presale/templates/pretixpresale/event/order.html:374 msgid "Change order" msgstr "قم بتغيير الطلب" -#: pretix/presale/templates/pretixpresale/event/order.html:382 +#: pretix/presale/templates/pretixpresale/event/order.html:386 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:27 #, fuzzy #| msgid "You cannot cancel this order." msgid "You can request to cancel this order." msgstr "لا يمكنك إلغاء هذا الطلب." -#: pretix/presale/templates/pretixpresale/event/order.html:385 +#: pretix/presale/templates/pretixpresale/event/order.html:389 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:30 msgid "" "If your request is approved, the organizer will determine if you will " @@ -34979,39 +36063,39 @@ msgid "" "their cancellation policy." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:393 -#: pretix/presale/templates/pretixpresale/event/order.html:429 -#: pretix/presale/templates/pretixpresale/event/order.html:450 +#: pretix/presale/templates/pretixpresale/event/order.html:397 +#: pretix/presale/templates/pretixpresale/event/order.html:433 +#: pretix/presale/templates/pretixpresale/event/order.html:454 msgid "" "The refund can be issued to your original payment method or as a gift card." msgstr "" "يمكن إصدار المبلغ المسترد عبر طريقة الدفع الأصلية أو في صورة بطاقة هدايا." -#: pretix/presale/templates/pretixpresale/event/order.html:395 -#: pretix/presale/templates/pretixpresale/event/order.html:431 -#: pretix/presale/templates/pretixpresale/event/order.html:452 +#: pretix/presale/templates/pretixpresale/event/order.html:399 +#: pretix/presale/templates/pretixpresale/event/order.html:435 +#: pretix/presale/templates/pretixpresale/event/order.html:456 msgid "The refund will be issued to your original payment method." msgstr "سيتم إصدار المبلغ المسترد عبر وسيلة الدفع الأصلية الخاصة بك." -#: pretix/presale/templates/pretixpresale/event/order.html:397 -#: pretix/presale/templates/pretixpresale/event/order.html:410 -#: pretix/presale/templates/pretixpresale/event/order.html:433 -#: pretix/presale/templates/pretixpresale/event/order.html:454 -#: pretix/presale/templates/pretixpresale/event/order.html:466 -#: pretix/presale/templates/pretixpresale/event/order.html:471 +#: pretix/presale/templates/pretixpresale/event/order.html:401 +#: pretix/presale/templates/pretixpresale/event/order.html:414 +#: pretix/presale/templates/pretixpresale/event/order.html:437 +#: pretix/presale/templates/pretixpresale/event/order.html:458 +#: pretix/presale/templates/pretixpresale/event/order.html:470 +#: pretix/presale/templates/pretixpresale/event/order.html:475 msgid "This will invalidate all tickets in this order." msgstr "سيؤدي هذا إلى إلغاء جميع التذاكر في هذا الطلب." -#: pretix/presale/templates/pretixpresale/event/order.html:402 +#: pretix/presale/templates/pretixpresale/event/order.html:406 msgid "" "You can request to cancel this order, but you will not receive a refund." msgstr "يمكنك طلب إلغاء هذا الطلب ، لكنك لن تسترد المبلغ." -#: pretix/presale/templates/pretixpresale/event/order.html:406 +#: pretix/presale/templates/pretixpresale/event/order.html:410 msgid "You can cancel this order, but you will not receive a refund." msgstr "يمكنك إلغاء هذا الطلب ، لكنك لن تسترد المبلغ." -#: pretix/presale/templates/pretixpresale/event/order.html:415 +#: pretix/presale/templates/pretixpresale/event/order.html:419 #, python-format msgid "" "You can request to cancel this order. If your request is approved, a " @@ -35021,7 +36105,7 @@ msgstr "" "يمكنك طلب إلغاء هذا الطلب. وإذا تمت الموافقة على طلبك ، فسيتم الاحتفاظ برسوم " "إلغاء قدرها %(fee)sوستسترد المبلغ المتبقي." -#: pretix/presale/templates/pretixpresale/event/order.html:421 +#: pretix/presale/templates/pretixpresale/event/order.html:425 #, python-format msgid "" "You can cancel this order. In this case, a cancellation fee of " @@ -35031,7 +36115,7 @@ msgstr "" "يمكنك إلغاء هذا الطلب. في هذه الحالة ، سيتم الاحتفاظ برسوم إلغاء قدرها " "%(fee)s وستسترد المبلغ المتبقي." -#: pretix/presale/templates/pretixpresale/event/order.html:438 +#: pretix/presale/templates/pretixpresale/event/order.html:442 msgid "" "You can request to cancel this order. If your request is approved, you get a " "full refund." @@ -35039,11 +36123,11 @@ msgstr "" "يمكنك طلب إلغاء هذا الطلب. إذا تمت الموافقة على طلبك ، فستسترد المبلغ " "بالكامل." -#: pretix/presale/templates/pretixpresale/event/order.html:443 +#: pretix/presale/templates/pretixpresale/event/order.html:447 msgid "You can cancel this order and receive a full refund." msgstr "يمكنك إلغاء هذا الطلب واسترداد المبلغ بالكامل." -#: pretix/presale/templates/pretixpresale/event/order.html:462 +#: pretix/presale/templates/pretixpresale/event/order.html:466 #: pretix/presale/templates/pretixpresale/event/order_cancel.html:54 #, python-format msgid "" @@ -35051,7 +36135,7 @@ msgid "" "required to pay a cancellation fee of %(fee)s." msgstr "" -#: pretix/presale/templates/pretixpresale/event/order.html:468 +#: pretix/presale/templates/pretixpresale/event/order.html:472 msgid "You can cancel this order using the following button." msgstr "يمكنك إلغاء هذا الطلب باستخدام الزر التالي." @@ -35156,7 +36240,7 @@ msgstr "" "لن يؤدي تعديل عنوان الفاتورة إلى إنشاء فاتورة جديدة تلقائيا. يرجى الاتصال " "بنا إذا كنت بحاجة إلى فاتورة جديدة." -#: pretix/presale/templates/pretixpresale/event/order_modify.html:87 +#: pretix/presale/templates/pretixpresale/event/order_modify.html:88 #: pretix/presale/templates/pretixpresale/event/position_modify.html:49 msgid "Save changes" msgstr "احفظ التغييرات" @@ -36295,22 +37379,163 @@ msgstr "التاريخ المحدد غير موجود في سلسلة الفعا msgid "from %(start_date)s" msgstr "من %(start_date)s" -#: pretix/settings.py:789 +#: pretix/settings.py:792 msgid "User profile only" msgstr "ملف تعريف المستخدم فقط" -#: pretix/settings.py:790 +#: pretix/settings.py:793 msgid "Read access" msgstr "الوصول إلى القراءة" -#: pretix/settings.py:791 +#: pretix/settings.py:794 msgid "Write access" msgstr "الوصول إلى الكتابة" -#: pretix/settings.py:802 +#: pretix/settings.py:805 msgid "Kosovo" msgstr "كوسوفو" +#, fuzzy +#~| msgid "Order code" +#~ msgid "Order language code" +#~ msgstr "رمز الطلب" + +#, fuzzy +#~| msgid "Order" +#~ msgid "Order URL" +#~ msgstr "الطلب" + +#, fuzzy +#~| msgid "Ticket" +#~ msgid "Ticket URL" +#~ msgstr "تذكرة" + +#, fuzzy +#~| msgid "All invoices" +#~ msgid "Email invoices" +#~ msgstr "جميع الفواتير" + +#, fuzzy +#~| msgid "All invoices" +#~ msgid "Your invoice" +#~ msgid_plural "Your invoices" +#~ msgstr[0] "جميع الفواتير" +#~ msgstr[1] "جميع الفواتير" +#~ msgstr[2] "جميع الفواتير" +#~ msgstr[3] "جميع الفواتير" +#~ msgstr[4] "جميع الفواتير" +#~ msgstr[5] "جميع الفواتير" + +#, fuzzy +#~| msgid "Email was sent" +#~ msgid "Invoice email subject" +#~ msgstr "تم إرسال البريد الإلكتروني" + +#, fuzzy +#~| msgctxt "invoice" +#~| msgid "Invoice date" +#~ msgid "Invoice email text" +#~ msgstr "تاريخ الفاتورة" + +#, fuzzy +#~ msgid "Invoice recipient email" +#~ msgstr "مستلم الفاتورة:" + +#, fuzzy, python-brace-format +#~| msgid "" +#~| "Hello,\n" +#~| "\n" +#~| "you receive this message because you asked us to send you the link\n" +#~| "to your order for {event}.\n" +#~| "\n" +#~| "You can change your order details and view the status of your order at\n" +#~| "{url}\n" +#~| "\n" +#~| "Best regards, \n" +#~| "Your {event} team" +#~ msgid "" +#~ "Hello,\n" +#~ "\n" +#~ "you receive this message because an order for {event} was placed by " +#~ "{order_email} and we have been asked to forward the invoice to you.\n" +#~ "\n" +#~ "Best regards, \n" +#~ "\n" +#~ "Your {event} team" +#~ msgstr "" +#~ "مرحبا،\n" +#~ "\n" +#~ "تلقيت هذه الرسالة لأنك طلبت منا أن نرسل لك الرابط\n" +#~ "لطلبك {event}.\n" +#~ "\n" +#~ "يمكنك تغيير تفاصيل طلبك وعرض حالة طلبك في\n" +#~ "{url}\n" +#~ "\n" +#~ "تحياتنا،\n" +#~ "فريق {event}" + +#, fuzzy +#~| msgid "Log in as someone else" +#~ msgid "Send again or somewhere else" +#~ msgstr "تسجيل الدخول باسم شخص آخر" + +#, fuzzy +#~| msgid "Send information via email" +#~ msgid "Send invoice via email" +#~ msgstr "أرسل المعلومات إلى البريد الإلكتروني" + +#, fuzzy +#~| msgid "This order is not yet approved by the event organizer." +#~ msgid "Sending invoices via email is disabled by the event organizer." +#~ msgstr "لم تتم الموافقة على هذا الطلب بعد من قبل منظم الفعالية." + +#~ msgid "" +#~ "The voucher has been created and sent to a person on the waiting list." +#~ msgstr "تم إنشاء قسيمة وإرسالها إلى شخص على قائمة الانتظار." + +#, fuzzy, python-brace-format +#~| msgctxt "subevent" +#~| msgid "Date {val}" +#~ msgid "{val}" +#~ msgstr "تاريخ {val}" + +#~ msgid "" +#~ "The tax rule that applies for additional fees you configured for single " +#~ "payment methods. This will set the tax rate and reverse charge rules, " +#~ "other settings of the tax rule are ignored." +#~ msgstr "" +#~ "حكم الضرائب التي تنطبق على الرسوم الإضافية التي تم تكوينها لطرق الدفع " +#~ "احدة. هذا وسوف يحدد معدل الضريبة وقواعد المحاسبة العكسية، يتم تجاهل " +#~ "إعدادات أخرى للحكم الضرائب." + +#~ msgid "Paste" +#~ msgstr "معجون" + +#~ msgid "Editor" +#~ msgstr "محرر" + +#~ msgid "Cut" +#~ msgstr "يقطع" + +#~ msgid "Add a new object" +#~ msgstr "إضافة وجوه جديدة" + +#, fuzzy +#~| msgid "Event created" +#~ msgid "Text (deprecated)" +#~ msgstr "تم إنشاء الفعالية" + +#~ msgid "Contact event organizer" +#~ msgstr "اتصل بمنظم الفعالية" + +#~ msgid "Your cart, general information, add products to your cart" +#~ msgstr "" +#~ "عربة التسوق الخاصة بك ، معلومات عامة ، أضف منتجات إلى عربة التسوق الخاصة " +#~ "بك" + +#~ msgid "General information, add products to your cart" +#~ msgstr "معلومات عامة ، أضف منتجات إلى سلة التسوق الخاصة بك" + #, fuzzy #~| msgid "Please enter a shorter name." #~ msgid "Please enter the code of your gift card." diff --git a/src/pretix/locale/ar/LC_MESSAGES/djangojs.po b/src/pretix/locale/ar/LC_MESSAGES/djangojs.po index f794fa9fd..76c5ffc80 100644 --- a/src/pretix/locale/ar/LC_MESSAGES/djangojs.po +++ b/src/pretix/locale/ar/LC_MESSAGES/djangojs.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-06-26 09:11+0000\n" +"POT-Creation-Date: 2025-08-19 16:02+0000\n" "PO-Revision-Date: 2021-09-15 11:22+0000\n" "Last-Translator: Mohamed Tawfiq \n" "Language-Team: Arabic \n" "Language-Team: Azerbaijani

    ', + ] + [ + format_html('{} ', url, text) + for url, text in links + ] + ['