mirror of
https://github.com/pretix/pretix.git
synced 2026-01-14 23:02:26 +00:00
Compare commits
40 Commits
sendmail_p
...
mapping-js
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44ef67077a | ||
|
|
d5bccf8726 | ||
|
|
d768c46fa1 | ||
|
|
5a506bfbd6 | ||
|
|
3508d22591 | ||
|
|
4a6dd12884 | ||
|
|
60b906d8b7 | ||
|
|
4285612162 | ||
|
|
a3b1e4d208 | ||
|
|
3a6d7b8e92 | ||
|
|
a5d01aa2d1 | ||
|
|
89d8ca0fc2 | ||
|
|
34b656989f | ||
|
|
154f10af8f | ||
|
|
782d659c59 | ||
|
|
1b4308e101 | ||
|
|
9a119c35a8 | ||
|
|
a8ac1b1a94 | ||
|
|
6338dceb9e | ||
|
|
e4a171c11f | ||
|
|
e9edcfdfdc | ||
|
|
ef3ff52be3 | ||
|
|
a8f74d87ec | ||
|
|
6f920e6bcd | ||
|
|
a6201c841f | ||
|
|
b5ac28e36c | ||
|
|
bf5e1aeaff | ||
|
|
3f6d230c01 | ||
|
|
a4aa3cbd3b | ||
|
|
8ee90cd1c4 | ||
|
|
8d1e679a84 | ||
|
|
87f829f4d2 | ||
|
|
75dcb920a7 | ||
|
|
e68f0a7402 | ||
|
|
4255dbfb83 | ||
|
|
9def5cc7b2 | ||
|
|
17a467887c | ||
|
|
0736babf3c | ||
|
|
a5b773924c | ||
|
|
391918afe7 |
200
doc/development/api/datasync.rst
Normal file
200
doc/development/api/datasync.rst
Normal file
@@ -0,0 +1,200 @@
|
||||
.. 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.
|
||||
|
||||
An :class:`OutboundSyncProvider` for registering event participants in a mailing list could start
|
||||
like this, for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from pretix.base.datasync.datasync import OutboundSyncProvider
|
||||
|
||||
class MyListSyncProvider(OutboundSyncProvider):
|
||||
identifier = "my_list"
|
||||
display_name = "My Mailing List Service"
|
||||
# ...c
|
||||
|
||||
|
||||
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")
|
||||
|
||||
|
||||
Furthermore, 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
|
||||
|
||||
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
|
||||
@@ -18,5 +18,6 @@ Contents:
|
||||
customview
|
||||
cookieconsent
|
||||
auth
|
||||
datasync
|
||||
general
|
||||
quality
|
||||
|
||||
@@ -33,10 +33,10 @@ dependencies = [
|
||||
"celery==5.5.*",
|
||||
"chardet==5.2.*",
|
||||
"cryptography>=44.0.0",
|
||||
"css-inline==0.16.*",
|
||||
"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",
|
||||
@@ -81,17 +81,17 @@ dependencies = [
|
||||
"pycountry",
|
||||
"pycparser==2.22",
|
||||
"pycryptodome==3.23.*",
|
||||
"pypdf==5.8.*",
|
||||
"pypdf==5.9.*",
|
||||
"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.3.*",
|
||||
"reportlab==4.4.*",
|
||||
"requests==2.31.*",
|
||||
"sentry-sdk==2.31.*",
|
||||
"sentry-sdk==2.34.*",
|
||||
"sepaxml==2.6.*",
|
||||
"stripe==7.9.*",
|
||||
"text-unidecode==1.*",
|
||||
|
||||
@@ -46,7 +46,7 @@ class PretixBaseConfig(AppConfig):
|
||||
from . import invoice # 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
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
21
src/pretix/base/datasync/__init__.py
Normal file
21
src/pretix/base/datasync/__init__.py
Normal file
@@ -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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
436
src/pretix/base/datasync/datasync.py
Normal file
436
src/pretix/base/datasync/datasync.py
Normal file
@@ -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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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 EventPluginRegistry
|
||||
from pretix.helpers import OF_SELF
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
datasync_providers = EventPluginRegistry({"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
|
||||
534
src/pretix/base/datasync/sourcefields.py
Normal file
534
src/pretix/base/datasync/sourcefields.py
Normal file
@@ -0,0 +1,534 @@
|
||||
#
|
||||
# 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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from collections import namedtuple
|
||||
from functools import partial
|
||||
|
||||
from django.db.models import Max, Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from pretix.base.models import Checkin, InvoiceAddress, Order, Question
|
||||
from pretix.base.settings import PERSON_NAME_SCHEMES
|
||||
|
||||
|
||||
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 ""
|
||||
|
||||
|
||||
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),
|
||||
}
|
||||
|
||||
|
||||
DataFieldInfo = namedtuple(
|
||||
'DataFieldInfo',
|
||||
field_names=('required_input', '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,
|
||||
"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,
|
||||
"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,
|
||||
"attendee_email",
|
||||
_("Attendee email"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda position: position.attendee_email
|
||||
or (position.addon_to.attendee_email if position.addon_to else None),
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER_POSITION,
|
||||
"attendee_or_order_email",
|
||||
_("Attendee or order email"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda position: position.attendee_email
|
||||
or (position.addon_to.attendee_email if position.addon_to else None)
|
||||
or position.order.email,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER_POSITION,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"invoice_address_company",
|
||||
_("Invoice address company"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: get_invoice_address_or_empty(order).company,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"invoice_address_name",
|
||||
_("Invoice address name"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: get_invoice_address_or_empty(order).name,
|
||||
),
|
||||
]
|
||||
+ [
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"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,
|
||||
"invoice_address_street",
|
||||
_("Invoice address street"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: get_invoice_address_or_empty(order).street,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"invoice_address_zipcode",
|
||||
_("Invoice address ZIP code"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: get_invoice_address_or_empty(order).zipcode,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"invoice_address_city",
|
||||
_("Invoice address city"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: get_invoice_address_or_empty(order).city,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"invoice_address_country",
|
||||
_("Invoice address country"),
|
||||
Question.TYPE_COUNTRYCODE,
|
||||
None,
|
||||
lambda order: str(get_invoice_address_or_empty(order).country),
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"email",
|
||||
_("Order email"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: order.email,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"order_code",
|
||||
_("Order code"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: order.code,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"event_order_code",
|
||||
_("Event and order code"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda order: order.full_code,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"order_total",
|
||||
_("Order total"),
|
||||
Question.TYPE_NUMBER,
|
||||
None,
|
||||
lambda order: str(order.total),
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER_POSITION,
|
||||
"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,
|
||||
"product_id",
|
||||
_("Product ID"),
|
||||
Question.TYPE_NUMBER,
|
||||
None,
|
||||
lambda position: str(position.item.pk),
|
||||
),
|
||||
DataFieldInfo(
|
||||
EVENT,
|
||||
"event_slug",
|
||||
_("Event short form"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda event: str(event.slug),
|
||||
),
|
||||
DataFieldInfo(
|
||||
EVENT,
|
||||
"event_name",
|
||||
_("Event name"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda event: str(event.name),
|
||||
),
|
||||
DataFieldInfo(
|
||||
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,
|
||||
"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,
|
||||
"voucher_code",
|
||||
_("Voucher code"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda position: position.voucher.code if position.voucher_id else "",
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER_POSITION,
|
||||
"ticket_id",
|
||||
_("Order code and position number"),
|
||||
Question.TYPE_STRING,
|
||||
None,
|
||||
lambda position: position.code,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER_POSITION,
|
||||
"ticket_price",
|
||||
_("Ticket price"),
|
||||
Question.TYPE_NUMBER,
|
||||
None,
|
||||
lambda position: str(position.price),
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"order_status",
|
||||
_("Order status"),
|
||||
Question.TYPE_CHOICE,
|
||||
Order.STATUS_CHOICE,
|
||||
lambda order: [order.status],
|
||||
),
|
||||
DataFieldInfo(
|
||||
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,
|
||||
"order_date",
|
||||
_("Order date and time"),
|
||||
Question.TYPE_DATETIME,
|
||||
None,
|
||||
lambda order: order.datetime.isoformat(),
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"payment_date",
|
||||
_("Payment date and time"),
|
||||
Question.TYPE_DATETIME,
|
||||
None,
|
||||
get_payment_date,
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER,
|
||||
"order_locale",
|
||||
_("Order language code"),
|
||||
Question.TYPE_CHOICE,
|
||||
[(lc, lc) for lc in event.settings.locales],
|
||||
lambda order: [order.locale],
|
||||
),
|
||||
DataFieldInfo(
|
||||
ORDER_POSITION,
|
||||
"position_id",
|
||||
_("Order position ID"),
|
||||
Question.TYPE_NUMBER,
|
||||
None,
|
||||
lambda op: str(op.pk),
|
||||
),
|
||||
]
|
||||
+ [
|
||||
DataFieldInfo(
|
||||
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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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,
|
||||
"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
|
||||
123
src/pretix/base/datasync/utils.py
Normal file
123
src/pretix/base/datasync/utils.py
Normal file
@@ -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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
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
|
||||
@@ -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')},
|
||||
},
|
||||
),
|
||||
]
|
||||
149
src/pretix/base/models/datasync.py
Normal file
149
src/pretix/base/models/datasync.py
Normal file
@@ -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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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,
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
83
src/pretix/base/services/datasync.py
Normal file
83
src/pretix/base/services/datasync.py
Normal file
@@ -0,0 +1,83 @@
|
||||
#
|
||||
# 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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
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')
|
||||
|
||||
|
||||
@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]
|
||||
)
|
||||
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
|
||||
OrderSyncQueue.objects.filter(pk__in=[sq.pk for sq in queued_orders]).delete()
|
||||
|
||||
with scope(organizer=event.organizer):
|
||||
with target_cls(event=event) as p:
|
||||
p.sync_queued_orders(queued_orders)
|
||||
@@ -257,8 +257,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):
|
||||
@@ -333,6 +339,23 @@ class EventPluginRegistry(Registry):
|
||||
def __init__(self, keys):
|
||||
super().__init__({"plugin": lambda o: get_defining_app(o), **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
|
||||
|
||||
|
||||
event_live_issues = EventPluginSignal()
|
||||
"""
|
||||
|
||||
@@ -60,11 +60,17 @@
|
||||
</td>
|
||||
<td>
|
||||
{{ event.name }}
|
||||
{% if not event.has_subevents and event.settings.show_dates_on_frontpage %}
|
||||
<br>
|
||||
{{ event.get_date_range_display }}
|
||||
{% if event.settings.show_times %}
|
||||
{{ event.date_from|date:"TIME_FORMAT" }}
|
||||
{% if not event.has_subevents %}
|
||||
{% if event.settings.show_dates_on_frontpage %}
|
||||
<br>
|
||||
{{ event.get_date_range_display }}
|
||||
{% if event.settings.show_times %}
|
||||
{{ event.date_from|date:"TIME_FORMAT" }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if event.location %}
|
||||
<br>
|
||||
{{ event.location|oneline }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
@@ -42,3 +42,4 @@ class PretixControlConfig(AppConfig):
|
||||
def ready(self):
|
||||
from .views import dashboards # noqa
|
||||
from . import logdisplay # noqa
|
||||
from .views import datasync # noqa
|
||||
|
||||
123
src/pretix/control/forms/mapping.py
Normal file
123
src/pretix/control/forms/mapping.py
Normal file
@@ -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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
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):
|
||||
return [
|
||||
(f.key, f.label + " [" + QUESTION_TYPE_LABELS[f.type] + "]")
|
||||
for f in pretix_fields
|
||||
if not f.deprecated or f.key == initial_choice
|
||||
]
|
||||
@@ -303,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')
|
||||
|
||||
@@ -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,
|
||||
@@ -421,6 +423,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("<p>" + link + "</p>" 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("<p>" + escape(msg) + "</p>" for msg in errmes))
|
||||
|
||||
|
||||
@receiver(signal=logentry_display, dispatch_uid="pretixcontrol_logentry_display")
|
||||
def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
|
||||
|
||||
|
||||
@@ -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'),
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
@@ -655,6 +660,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)),
|
||||
[]),
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
</li>
|
||||
{% elif request.user.is_staff and staff_session %}
|
||||
<li>
|
||||
<a href="{% url 'control:user.sudo.stop' %}" class="danger">
|
||||
<a href="{% url 'control:user.sudo.stop' %}" class="danger admin-only">
|
||||
<i class="fa fa-id-card"></i> {% trans "End admin session" %}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
{% load i18n %}
|
||||
{% load eventurl %}
|
||||
{% load bootstrap3 %}
|
||||
{% load escapejson %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
{% trans "Data transfer to external systems" %}
|
||||
</h3>
|
||||
</div>
|
||||
<ul class="list-group">
|
||||
{% for identifier, display_name, pending, objects in providers %}
|
||||
<li class="list-group-item">
|
||||
<form action="{% url "control:event.order.sync_job" organizer=event.organizer.slug event=event.slug code=order.code provider=identifier %}" method="post" class="form-inline pull-right">
|
||||
{% csrf_token %}
|
||||
{% if pending %}
|
||||
{% if pending.not_before > now or pending.need_manual_retry %}
|
||||
<button type="submit" name="run_job_now" value="{{ pending.pk }}" class="btn btn-default"><i class="fa fa-refresh"></i> {% trans "Retry now" %}</button>
|
||||
{% endif %}
|
||||
<button type="submit" name="cancel_job" value="{{ pending.pk }}" class="btn btn-danger"><i class="fa fa-times"></i> {% trans "Cancel" %}</button>
|
||||
{% else %}
|
||||
<button type="submit" class="btn btn-default"><i class="fa fa-refresh"></i> {% trans "Sync now" %}</button>
|
||||
<input type="hidden" name="queue_sync" value="true">
|
||||
{% endif %}
|
||||
</form>
|
||||
<p><b>{{ display_name }}</b></p>
|
||||
{% if pending %}
|
||||
<p>
|
||||
{% if pending.need_manual_retry %}
|
||||
<i class="fa fa-warning"></i>
|
||||
{% trans "Error" %}: {{ pending.get_need_manual_retry_display }}
|
||||
{% elif pending.failed_attempts %}
|
||||
<i class="fa fa-warning"></i>
|
||||
{% 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 %}
|
||||
<i class="fa fa-hourglass"></i> {% trans "Pending" %}
|
||||
{% endif %}
|
||||
<span class="text-muted">({% blocktrans trimmed with datetime=pending.triggered|date:"SHORT_DATETIME_FORMAT" %}triggered at {{ datetime }}
|
||||
{% endblocktrans %})</span>
|
||||
<!-- {{ pending.triggered_by }} / {{ pending.triggered }} -->
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<ul>
|
||||
{% for obj in objects %}
|
||||
<li>
|
||||
{% if obj.external_link_html %}
|
||||
{{ obj.external_link_html }}
|
||||
{% else %}
|
||||
{{ obj.external_object_type }}
|
||||
{% trans "identified by" %} {{ obj.external_id_field }}
|
||||
<em>{{ obj.id_value }}</em>
|
||||
{% endif %}
|
||||
<time class="text-muted" datetime="{{ obj.transmitted.isoformat }}">{{ obj.transmitted|date:"SHORT_DATETIME_FORMAT" }}</time>
|
||||
</li>
|
||||
{% empty %}
|
||||
<li>{% trans "No data transmitted." %}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
@@ -0,0 +1,86 @@
|
||||
{% extends "pretixcontrol/event/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans "Sync problems" %}</h2>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
On this page, we provide a list of orders where data synchronisation to an external system has failed.
|
||||
You can start another attempt to sync them manually.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
{% if queue_items %}
|
||||
<label aria-label="{% trans "select all rows for batch-operation" %}"
|
||||
class="batch-select-label"><input type="checkbox" data-toggle-table/></label>
|
||||
{% endif %}
|
||||
</th>
|
||||
<th>{% trans "Order" %}</th>
|
||||
<th>{% trans "Sync provider" %}</th>
|
||||
<th>{% trans "Date" %}</th>
|
||||
<th>{% trans "Failure mode" %}</th>
|
||||
{% if staff_session %}
|
||||
<th>in_flight</th><th>retry</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in queue_items %}
|
||||
<tr>
|
||||
<td><input type="checkbox" name="idlist" value="{{ item.pk }}"></td>
|
||||
<td>
|
||||
{% if staff_session %}{{ item.order.event.organizer.slug }} -{% endif %}
|
||||
<a href="{% url "control:event.order" event=item.order.event.slug organizer=item.order.event.organizer.slug code=item.order.code %}">
|
||||
{{ item.order.full_code }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ item.provider_display_name }}</td>
|
||||
<td>
|
||||
{{ item.triggered }}
|
||||
{% if staff_session %}({{ item.triggered_by }}){% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% 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 %}
|
||||
</td>
|
||||
{% if staff_session %}
|
||||
<td>{{ item.in_flight }} ({{ item.in_flight_since }})</td><td>{{ item.failed_attempts }} / {{ item.max_retry_attempts }} ({{ item.not_before }})</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="5" class="text-center">{% trans "No problems." %}</td>
|
||||
{% if staff_session %}
|
||||
<td></td><td></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% if queue_items %}
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<button type="submit" name="action" value="retry" class="btn btn-primary"><i class="fa fa-refresh"></i> {% trans "Retry selected" %}</button>
|
||||
<button type="submit" name="action" value="cancel" class="btn btn-danger"><i class="fa fa-times"></i> {% trans "Cancel selected" %}</button>
|
||||
</td>
|
||||
{% if staff_session %}
|
||||
<td></td><td></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</tfoot>
|
||||
{% endif %}
|
||||
</table>
|
||||
</form>
|
||||
{% include "pretixcontrol/pagination.html" %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,81 @@
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load escapejson %}
|
||||
{% load formset_tags %}
|
||||
<div class="formset" data-formset data-formset-prefix="{{ formset.prefix }}">
|
||||
{{ formset.management_form }}
|
||||
{% bootstrap_formset_errors formset %}
|
||||
<div data-formset-body>
|
||||
{% for f in formset %}
|
||||
{% bootstrap_form_errors f %}
|
||||
<div class="row formset-row" data-formset-form>
|
||||
<div class="sr-only">
|
||||
{{ f.id }}
|
||||
{% bootstrap_field f.DELETE form_group_class="" layout="inline" %}
|
||||
{% bootstrap_field f.ORDER form_group_class="" layout="inline" %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% bootstrap_field f.pretix_field layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% bootstrap_field f.external_field layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
{% bootstrap_field f.overwrite layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
{{ f.value_map.as_hidden }}
|
||||
<div class="col-md-2 text-right flip">
|
||||
<i class="fa fa-warning hidden" data-toggle="tooltip" title=""></i>
|
||||
|
||||
<button type="button" class="btn btn-default hidden" data-edit-value-map data-toggle="modal"
|
||||
data-target="#editValueMapModal" title="{% trans "Edit value mapping" %}">
|
||||
<i class="fa fa-edit"></i></button>
|
||||
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
||||
<i class="fa fa-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
||||
<i class="fa fa-arrow-down"></i></button>
|
||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
||||
<i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<script type="form-template" data-formset-empty-form>
|
||||
{% escapescript %}
|
||||
<div class="row formset-row" data-formset-form>
|
||||
<div class="sr-only">
|
||||
{% bootstrap_field formset.empty_form.DELETE form_group_class="" layout="inline" %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% bootstrap_field formset.empty_form.pretix_field layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% bootstrap_field formset.empty_form.external_field layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
{% bootstrap_field formset.empty_form.overwrite layout='inline' form_group_class="" %}
|
||||
</div>
|
||||
{{ f.value_map.as_hidden }}
|
||||
<div class="col-md-2 text-right flip">
|
||||
<i class="fa fa-warning hidden" data-toggle="tooltip" title=""></i>
|
||||
<button type="button" class="btn btn-default hidden" data-edit-value-map data-toggle="modal"
|
||||
data-target="#editValueMapModal" title="{% trans "Edit value mapping" %}">
|
||||
<i class="fa fa-edit"></i></button>
|
||||
<button type="button" class="btn btn-default" data-formset-move-up-button>
|
||||
<i class="fa fa-arrow-up"></i></button>
|
||||
<button type="button" class="btn btn-default" data-formset-move-down-button>
|
||||
<i class="fa fa-arrow-down"></i></button>
|
||||
<button type="button" class="btn btn-danger" data-formset-delete-button>
|
||||
<i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endescapescript %}
|
||||
</script>
|
||||
<p>
|
||||
<button type="button" class="btn btn-default" data-formset-add>
|
||||
<i class="fa fa-plus"></i> {% trans "Add property" %}</button>
|
||||
</p>
|
||||
</div>
|
||||
{% if external_fields %}
|
||||
{{ external_fields|json_script:external_fields_id }}
|
||||
{% endif %}
|
||||
@@ -79,6 +79,15 @@
|
||||
class="btn btn-primary">{% trans "Show affected orders" %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if has_sync_problems %}
|
||||
<div class="alert alert-warning">
|
||||
{% blocktrans trimmed %}
|
||||
Orders in this event could not be <strong>synced to an external system</strong> as configured.
|
||||
{% endblocktrans %}
|
||||
<a href="{% url "control:event.datasync.failedjobs" event=request.event.slug organizer=request.event.organizer.slug %}"
|
||||
class="btn btn-primary">{% trans "Show sync problems" %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% eventsignal request.event "pretix.control.signals.event_dashboard_top" request=request %}
|
||||
|
||||
{% if request.event.has_subevents %}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
<div class="col-lg-6 col-sm-12 col-xs-12">
|
||||
{{ log.display }}
|
||||
{% if staff_session %}
|
||||
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandlogs data-id="{{ log.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="col-lg-6 col-sm-12 col-xs-12">
|
||||
{{ log.display }}
|
||||
{% if staff_session %}
|
||||
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandlogs data-id="{{ log.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
|
||||
@@ -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." %}
|
||||
</div>
|
||||
{% if staff_session %}
|
||||
<a href="{% url "control:organizers.add" %}" class="btn btn-default">
|
||||
<a href="{% url "control:organizers.add" %}" class="btn btn-default admin-only">
|
||||
{% trans "Create a new organizer" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<p>
|
||||
{{ log.display }}
|
||||
{% if staff_session %}
|
||||
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandlogs data-id="{{ log.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
|
||||
@@ -800,7 +800,7 @@
|
||||
{{ p.html_info|safe }}
|
||||
{% if staff_session %}
|
||||
<p>
|
||||
<a href="" class="btn btn-default btn-xs" data-expandpayment data-id="{{ p.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandpayment data-id="{{ p.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
@@ -812,7 +812,7 @@
|
||||
<tr>
|
||||
<td colspan="1"></td>
|
||||
<td colspan="5">
|
||||
<a href="" class="btn btn-default btn-xs" data-expandpayment data-id="{{ p.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandpayment data-id="{{ p.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
@@ -916,7 +916,7 @@
|
||||
{% endif %}
|
||||
{% if staff_session %}
|
||||
<p>
|
||||
<a href="" class="btn btn-default btn-xs" data-expandrefund
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandrefund
|
||||
data-id="{{ r.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
<div class="col-lg-6 col-sm-12 col-xs-12">
|
||||
{{ log.display }}
|
||||
{% if staff_session %}
|
||||
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandlogs data-id="{{ log.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
{% blocktrans with name=organizer.name %}Organizer settings{% endblocktrans %}
|
||||
{% if request.user.is_staff and staff_session %}
|
||||
<a href="{% url "control:organizer.delete" organizer=organizer.slug %}"
|
||||
class="btn btn-danger hidden-print">
|
||||
class="btn btn-danger hidden-print admin-only">
|
||||
<span class="fa fa-trash"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
</button>
|
||||
{% endif %}
|
||||
{% if staff_session and t.info %}
|
||||
<pre><code>{{ t.info|pprint }}</code></pre>
|
||||
<pre class="admin-only"><code>{{ t.info|pprint }}</code></pre>
|
||||
{% endif %}
|
||||
{% if t.acceptor and t.acceptor != request.organizer %}
|
||||
<span class="text-muted">
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
{% if staff_session %}
|
||||
<p>
|
||||
<a href="{% url "control:organizers.add" %}" class="btn btn-default">
|
||||
<a href="{% url "control:organizers.add" %}" class="btn btn-default admin-only">
|
||||
<span class="fa fa-plus"></span>
|
||||
{% trans "Create a new organizer" %}
|
||||
</a>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<div class="col-lg-6 col-sm-12 col-xs-12">
|
||||
{{ log.display }}
|
||||
{% if staff_session %}
|
||||
<a href="" class="btn btn-default btn-xs" data-expandlogs data-id="{{ log.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandlogs data-id="{{ log.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
<tr>
|
||||
<td colspan="1"></td>
|
||||
<td colspan="6">
|
||||
<a href="" class="btn btn-default btn-xs" data-expandpayment data-id="{{ p.pk }}">
|
||||
<a href="" class="btn btn-default btn-xs admin-only" data-expandpayment data-id="{{ p.pk }}">
|
||||
<span class="fa-eye fa fa-fw"></span>
|
||||
{% trans "Inspect" %}
|
||||
</a>
|
||||
|
||||
@@ -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'),
|
||||
@@ -248,6 +249,7 @@ urlpatterns = [
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/export/(?P<pk>[^/]+)/delete$', organizer.DeleteScheduledExportView.as_view(),
|
||||
name='organizer.export.scheduled.delete'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/ticket_select2$', typeahead.ticket_select2, name='organizer.ticket_select2'),
|
||||
re_path(r'^organizer/(?P<organizer>[^/]+)/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'),
|
||||
@@ -428,6 +430,8 @@ urlpatterns = [
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/cancellationrequests/(?P<req>\d+)/delete$',
|
||||
orders.OrderCancellationRequestDelete.as_view(),
|
||||
name='event.order.cancellationrequests.delete'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/sync_job/(?P<provider>[^/]+)/$', datasync.ControlSyncJob.as_view(),
|
||||
name='event.order.sync_job'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/transactions/$', orders.OrderTransactions.as_view(), name='event.order.transactions'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/$', orders.OrderDetail.as_view(), name='event.order'),
|
||||
re_path(r'^invoice/(?P<invoice>[^/]+)$', orders.InvoiceDownload.as_view(),
|
||||
@@ -474,6 +478,7 @@ urlpatterns = [
|
||||
name='event.orders.checkinlists.edit'),
|
||||
re_path(r'^checkinlists/(?P<list>\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<organizer>[^/]+)/$', RedirectView.as_view(pattern_name='control:organizer'), name='event.organizerredirect'),
|
||||
]
|
||||
|
||||
@@ -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'] = [
|
||||
{
|
||||
|
||||
150
src/pretix/control/views/datasync.py
Normal file
150
src/pretix/control/views/datasync.py
Normal file
@@ -0,0 +1,150 @@
|
||||
#
|
||||
# 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 <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# 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
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from itertools import groupby
|
||||
|
||||
from django.contrib import messages
|
||||
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.control.permissions import (
|
||||
AdministratorPermissionRequiredMixin, EventPermissionRequiredMixin,
|
||||
OrganizerPermissionRequiredMixin,
|
||||
)
|
||||
from pretix.control.signals import order_info
|
||||
from pretix.control.views.orders import OrderView
|
||||
|
||||
|
||||
@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"):
|
||||
job = self.order.queued_sync_jobs.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"):
|
||||
job = self.order.queued_sync_jobs.get(pk=self.request.POST.get("run_job_now"))
|
||||
job.not_before = now()
|
||||
job.need_manual_retry = None
|
||||
job.save()
|
||||
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
|
||||
)
|
||||
@@ -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"),
|
||||
]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
|
||||
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
|
||||
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -587,52 +587,52 @@ msgstr "QR الدخول"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "لا يمكن تحميل ملف PDF الخلفية للأسباب التالية:"
|
||||
|
||||
#: 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
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "عنصر نص"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
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"
|
||||
|
||||
#: 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 "حصل خطأ أثناء رفع ملف PDF الخاص بك، يرجى المحاولة مرة أخرى."
|
||||
|
||||
#: 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 "هل تريد أن تغادر المحرر دون حفظ التعديلات؟"
|
||||
|
||||
@@ -668,40 +668,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 "لم تقم بحفظ التعديلات!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
||||
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -560,48 +560,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 "Disseny del tiquet"
|
||||
|
||||
#: 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 ""
|
||||
|
||||
@@ -633,40 +633,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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-05-16 17:00+0000\n"
|
||||
"Last-Translator: David <davemachala@gmail.com>\n"
|
||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -578,52 +578,52 @@ msgstr "Check-in QR kód"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "Pozadí PDF nemohl být načten:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Skupina objektů"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Textový objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Textový objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Oblast s QR kódem"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Oblast obrazu"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Poháněno společností pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Design vstupenky"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Uložení se nepodařilo."
|
||||
|
||||
#: 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 "Při nahrávání souboru PDF došlo k problému, zkuste to prosím znovu."
|
||||
|
||||
#: 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 "Opravdu chcete opustit editor bez uložení změn?"
|
||||
|
||||
@@ -660,40 +660,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 "Hledaný výraz"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Všechny"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Žádný"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Pouze vybrané"
|
||||
|
||||
#: 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 "Interně používat jiný název"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Kliknutím zavřete"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Máte neuložené změny!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -558,48 +558,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 ""
|
||||
|
||||
@@ -631,40 +631,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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2024-07-10 15:00+0000\n"
|
||||
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
|
||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -600,54 +600,54 @@ msgstr "Check-in QR"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "Baggrunds-pdf'en kunne ikke hentes af følgende grund:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppe af objekter"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Tekstobjekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Tekstobjekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "QR-kode-område"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
#, fuzzy
|
||||
#| msgid "Barcode area"
|
||||
msgid "Image area"
|
||||
msgstr "QR-kode-område"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Drevet af pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Billetdesign"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Gem fejlede."
|
||||
|
||||
#: 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 "Fejl under upload af pdf. Prøv venligt igen."
|
||||
|
||||
#: 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 ""
|
||||
"Er du sikker på at du vil forlade editoren uden at gemme dine ændringer?"
|
||||
@@ -680,40 +680,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 "Alle"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Ingen"
|
||||
|
||||
#: 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 "Klik for at lukke"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du har ændringer, der ikke er gemt!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-05-30 11:08+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -573,49 +573,49 @@ msgstr "Check-in-QR-Code"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppe von Objekten"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Text-Objekt (veraltet)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
msgid "Text box"
|
||||
msgstr "Textbox"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "QR-Code-Bereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Bildbereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Event-Ticketshop von pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Ticket-Design"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Speichern fehlgeschlagen."
|
||||
|
||||
#: 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 ""
|
||||
"Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen."
|
||||
|
||||
#: 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 ""
|
||||
"Möchten Sie den Editor wirklich schließen ohne Ihre Änderungen zu speichern?"
|
||||
@@ -653,40 +653,40 @@ msgstr ""
|
||||
"Diese Farbe hat keinen ausreichenden Kontrast zu weiß. Die Barrierefreiheit "
|
||||
"der Seite ist eingeschränkt."
|
||||
|
||||
#: 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 "Suchbegriff"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Nur ausgewählte"
|
||||
|
||||
#: 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 "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:814
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:815
|
||||
msgid "Invalid page number."
|
||||
msgstr "Ungültige Seitenzahl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:972
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:973
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Intern einen anderen Namen verwenden"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Klicken zum Schließen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Sie haben ungespeicherte Änderungen!"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Apps
|
||||
APM
|
||||
as
|
||||
Aufbuchungen
|
||||
aufeinanderfolgenden
|
||||
Aufteilungsliste
|
||||
aufzubuchen
|
||||
auschecken
|
||||
@@ -44,6 +45,7 @@ Bcc
|
||||
BCC
|
||||
Beispielevent
|
||||
Beispielproduktvariantenbeschreibung
|
||||
Belarus
|
||||
Benachrichtigungs
|
||||
Benachrichtigungsart
|
||||
Benachrichtigungsarten
|
||||
@@ -146,6 +148,8 @@ GiroCode
|
||||
giropay
|
||||
GPL
|
||||
Grants
|
||||
Gruppierungswert
|
||||
Gruppierungsspalte
|
||||
Guide
|
||||
Gutscheineinlöser
|
||||
herunterscrollen
|
||||
@@ -194,6 +198,7 @@ Logindaten
|
||||
Lösch
|
||||
loszulegen
|
||||
Ltd
|
||||
Macau
|
||||
max
|
||||
MariaDB
|
||||
MapQuest
|
||||
@@ -318,6 +323,7 @@ Stornobedingungen
|
||||
Stornobeleg
|
||||
Stornodatum
|
||||
Stornogebühr
|
||||
Stornogebühren
|
||||
Stornos
|
||||
Strg
|
||||
Stripe
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-05-30 11:07+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||
@@ -573,49 +573,49 @@ msgstr "Check-in-QR-Code"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "Die Hintergrund-PDF-Datei konnte nicht geladen werden:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppe von Objekten"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Text-Objekt (veraltet)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
msgid "Text box"
|
||||
msgstr "Textbox"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "QR-Code-Bereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Bildbereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Event-Ticketshop von pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Ticket-Design"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Speichern fehlgeschlagen."
|
||||
|
||||
#: 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 ""
|
||||
"Es gab ein Problem beim Hochladen der PDF-Datei, bitte erneut versuchen."
|
||||
|
||||
#: 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 ""
|
||||
"Möchtest du den Editor wirklich schließen ohne Ihre Änderungen zu speichern?"
|
||||
@@ -653,40 +653,40 @@ msgstr ""
|
||||
"Diese Farbe hat keinen ausreichenden Kontrast zu weiß. Die Barrierefreiheit "
|
||||
"der Seite ist eingeschränkt."
|
||||
|
||||
#: 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 "Suchbegriff"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Nur ausgewählte"
|
||||
|
||||
#: 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 "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:814
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:815
|
||||
msgid "Invalid page number."
|
||||
msgstr "Ungültige Seitenzahl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:972
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:973
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Intern einen anderen Namen verwenden"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Klicken zum Schließen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du hast ungespeicherte Änderungen!"
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ Apps
|
||||
APM
|
||||
as
|
||||
Aufbuchungen
|
||||
aufeinanderfolgenden
|
||||
Aufteilungsliste
|
||||
aufzubuchen
|
||||
auschecken
|
||||
@@ -44,6 +45,7 @@ Bcc
|
||||
BCC
|
||||
Beispielevent
|
||||
Beispielproduktvariantenbeschreibung
|
||||
Belarus
|
||||
Benachrichtigungs
|
||||
Benachrichtigungsart
|
||||
Benachrichtigungsarten
|
||||
@@ -146,6 +148,8 @@ GiroCode
|
||||
giropay
|
||||
GPL
|
||||
Grants
|
||||
Gruppierungswert
|
||||
Gruppierungsspalte
|
||||
Guide
|
||||
Gutscheineinlöser
|
||||
herunterscrollen
|
||||
@@ -194,6 +198,7 @@ Logindaten
|
||||
Lösch
|
||||
loszulegen
|
||||
Ltd
|
||||
Macau
|
||||
max
|
||||
MariaDB
|
||||
MapQuest
|
||||
@@ -318,6 +323,7 @@ Stornobedingungen
|
||||
Stornobeleg
|
||||
Stornodatum
|
||||
Stornogebühr
|
||||
Stornogebühren
|
||||
Stornos
|
||||
Strg
|
||||
Stripe
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-05 07:29+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2024-12-22 00:00+0000\n"
|
||||
"Last-Translator: Dimitris Tsimpidis <tsimpidisd@gmail.com>\n"
|
||||
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -606,54 +606,54 @@ msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
"Το αρχείο φόντου PDF δεν ήταν δυνατό να φορτωθεί για τον ακόλουθο λόγο:"
|
||||
|
||||
#: 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
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Αντικείμενο κειμένου"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Αντικείμενο κειμένου"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Περιοχή Barcode"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
#, fuzzy
|
||||
#| msgid "Barcode area"
|
||||
msgid "Image area"
|
||||
msgstr "Περιοχή Barcode"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Υποστηρίζεται από το Pretix"
|
||||
|
||||
#: 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 "Σφάλμα κατά τη μεταφόρτωση του αρχείου PDF, δοκιμάστε ξανά."
|
||||
|
||||
#: 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 ""
|
||||
"Θέλετε πραγματικά να αφήσετε τον επεξεργαστή χωρίς να αποθηκεύσετε τις "
|
||||
@@ -694,40 +694,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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-05-30 11:15+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -571,50 +571,50 @@ msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
"El archivo PDF de fondo no ha podido ser cargado debido al siguiente motivo:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Grupo de objetos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Objeto texto (obsoleto)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
msgid "Text box"
|
||||
msgstr "Campo de texto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Área para código de barras"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Área de imagen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Proveído por pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objeto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Diseño del entrada"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "El guardado falló."
|
||||
|
||||
#: 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 ""
|
||||
"Ha habido un error mientras se cargaba el archivo PDF, por favor, intente de "
|
||||
"nuevo."
|
||||
|
||||
#: 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 "¿Realmente desea salir del editor sin haber guardado sus cambios?"
|
||||
|
||||
@@ -651,40 +651,40 @@ msgstr ""
|
||||
"El color no tiene suficiente contraste con el blanco. La accesibilidad de su "
|
||||
"sitio se verá afectada."
|
||||
|
||||
#: 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 "Consulta de búsqueda"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Solamente seleccionados"
|
||||
|
||||
#: 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 "Introduce un número de página entre 1 y %(max)s."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:814
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:815
|
||||
msgid "Invalid page number."
|
||||
msgstr "Número de página inválido."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:972
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:973
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Usar un nombre diferente internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Click para cerrar"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "¡Tienes cambios sin guardar!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1156
src/pretix/locale/es_419/LC_MESSAGES/djangojs.po
Normal file
1156
src/pretix/locale/es_419/LC_MESSAGES/djangojs.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
|
||||
"Last-Translator: Albizuri <oier@puntu.eus>\n"
|
||||
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -570,48 +570,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 "Sarrera diseinua"
|
||||
|
||||
#: 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 ""
|
||||
|
||||
@@ -643,40 +643,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 "Guztiak"
|
||||
|
||||
#: 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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
|
||||
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
||||
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -582,54 +582,54 @@ 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
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Tekstiobjekti"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Tekstiobjekti"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Viivakoodialue"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
#, fuzzy
|
||||
#| msgid "Barcode area"
|
||||
msgid "Image area"
|
||||
msgstr "Viivakoodialue"
|
||||
|
||||
#: 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 "Tallennus epäonnistui."
|
||||
|
||||
#: 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 ""
|
||||
|
||||
@@ -661,40 +661,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 "Kaikki"
|
||||
|
||||
#: 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 "Käytä toista nimeä sisäisesti"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Sulje klikkaamalla"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Sinulla on tallentamattomia muutoksia!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: French\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-05-30 11:06+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -573,49 +573,49 @@ msgstr ""
|
||||
"Le fichier PDF généré en arrière-plan n'a pas pu être chargé pour la raison "
|
||||
"suivante :"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Groupe d'objets"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Objet textuel (obsolète)"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
msgid "Text box"
|
||||
msgstr "Zone de texte"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Zone de code-barres"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Zone d'image"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Propulsé par pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objet"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Conception des billets"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "L'enregistrement a échoué."
|
||||
|
||||
#: 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 ""
|
||||
"Erreur lors du téléchargement de votre fichier PDF, veuillez réessayer."
|
||||
|
||||
#: 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 ""
|
||||
"Voulez-vous vraiment quitter l'éditeur sans sauvegarder vos modifications ?"
|
||||
@@ -653,40 +653,40 @@ msgstr ""
|
||||
"Votre choix de couleur n'est pas assez contrastée par rapport au blanc. "
|
||||
"L'accessibilité de votre site en sera affectée."
|
||||
|
||||
#: 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 "Requête de recherche"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Tous"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Aucun"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Seuls les sélectionnés"
|
||||
|
||||
#: 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 "Saisir le numéro de page entre 1 et %(max)s."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:814
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:815
|
||||
msgid "Invalid page number."
|
||||
msgstr "Numéro de page invalide."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:972
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:973
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Utiliser un nom différent en interne"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Cliquez pour fermer"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Vous avez des modifications non sauvegardées !"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
||||
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
||||
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -584,53 +584,53 @@ msgstr "QR de validación"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "O arquivo PDF de fondo non se puido cargar polo motivo seguinte:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Grupo de obxectos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Obxecto de texto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Obxecto de texto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Área para código de barras"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Área de imaxe"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Desenvolto por Pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Obxecto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Deseño do tícket"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "O gardado fallou."
|
||||
|
||||
#: 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 ""
|
||||
"Houbo un erro mentres se cargaba o arquivo PDF. Por favor, inténteo de novo."
|
||||
|
||||
#: 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 "Realmente desexa saír do editor sen gardar os cambios?"
|
||||
|
||||
@@ -668,40 +668,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 "Consultar unha procura"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Ningún"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Soamente seleccionados"
|
||||
|
||||
#: 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 "Usar un nome diferente internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Click para cerrar"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Tes cambios sen gardar!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
|
||||
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
|
||||
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -565,48 +565,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 ""
|
||||
|
||||
@@ -638,40 +638,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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-03-16 10:17+0000\n"
|
||||
"Last-Translator: Robert Rigo <kontakt@bicikli.hr>\n"
|
||||
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -559,48 +559,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 ""
|
||||
|
||||
@@ -632,40 +632,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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2024-11-28 06:00+0000\n"
|
||||
"Last-Translator: Patrick Chilton <chpatrick@gmail.com>\n"
|
||||
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -599,54 +599,54 @@ msgstr "Check in QR"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "A PDF háttér fájl nem tölthető be a következők miatt:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "tárgy csoport"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Szöveg"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Szöveg"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Vonalkód terület"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
#, fuzzy
|
||||
#| msgid "Barcode area"
|
||||
msgid "Image area"
|
||||
msgstr "Vonalkód terület"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "pretix által működtetett"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "objektum"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Jegy design"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Mentés sikertelen."
|
||||
|
||||
#: 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 "Hiba a PDF fájl feltöltése közben, próbálja újra."
|
||||
|
||||
#: 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 "Biztosan ki akar lépni a szerkesztőből a változtatások mentése nélkül?"
|
||||
|
||||
@@ -683,40 +683,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 "Összes"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Semmi"
|
||||
|
||||
#: 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 "Használj másik nevet"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Bezárásért kattints"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Mentetlen változtatások!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 14:01+0000\n"
|
||||
"Last-Translator: Mahdia Aliyy <mahdlyy.k@gmail.com>\n"
|
||||
"Language-Team: Indonesian <https://translate.pretix.eu/projects/pretix/"
|
||||
@@ -584,52 +584,52 @@ msgstr "QR masuk"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "File latar belakang PDF tidak dapat dimuat karena alasan berikut:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Sekelompok objek"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Objek teks"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Objek teks"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Area kode batang"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Daerah gambar"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Didukung oleh pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Obyek"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Desain tiket"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Gagal menyimpan."
|
||||
|
||||
#: 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 "Terjadi kesalahan saat mengunggah file PDF Anda, coba lagi."
|
||||
|
||||
#: 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 ""
|
||||
"Apakah Anda benar-benar ingin keluar dari editor tanpa menyimpan perubahan?"
|
||||
@@ -667,40 +667,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 "Permintaan pencarian"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Semua"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Tidak ada"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Hanya dipilih"
|
||||
|
||||
#: 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 "Gunakan nama yang berbeda secara internal"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Klik untuk menutup"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Anda memiliki perubahan yang belum disimpan!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-05-05 09:40+0000\n"
|
||||
"Last-Translator: \"Luca Martinelli [Sannita]\" <sannita@gmail.com>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -581,52 +581,52 @@ msgstr "Check-in con QR"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "Il file PDF di sfondo non può essere caricato per le seguenti ragioni:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppo di oggetti"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Oggetto testo"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Oggetto testo"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Area codice a barra"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Area immagini"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Powered by Pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Oggetto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Design biglietto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Salvataggio fallito."
|
||||
|
||||
#: 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 "Errore durante il caricamento del tuo file PDF, prova di nuovo."
|
||||
|
||||
#: 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 "Vuoi davvero abbandonare l'editor senza salvare le modifiche?"
|
||||
|
||||
@@ -663,40 +663,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 "Chiave di ricerca"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Tutto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Nessuno"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Solo i selezionati"
|
||||
|
||||
#: 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 "Utilizza un nome diverso internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Clicca per chiudere"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Hai cambiamenti non salvati!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"PO-Revision-Date: 2025-06-02 09:00+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-07-23 01:00+0000\n"
|
||||
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
|
||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/ja/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 5.11.4\n"
|
||||
"X-Generator: Weblate 5.12.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -401,7 +401,7 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:210
|
||||
msgid "We are processing your request …"
|
||||
msgstr "リクエストを処理しています…"
|
||||
msgstr "リクエストを処理中です …"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:213
|
||||
msgid ""
|
||||
@@ -415,7 +415,7 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:270
|
||||
msgid "If this takes longer than a few minutes, please contact us."
|
||||
msgstr ""
|
||||
msgstr "数分以上かかる場合は、お問い合わせください。"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:325
|
||||
msgid "Close message"
|
||||
@@ -569,48 +569,48 @@ msgstr "チェックイン用QRコード"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "以下の理由によりPDFファイルの読み込みに失敗しました:"
|
||||
|
||||
#: 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のイベントチケット売り場"
|
||||
|
||||
#: 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 "PDFのアップロード中に問題が発生しました。再試行してください。"
|
||||
|
||||
#: 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 "変更内容を保存せずに編集を終了しますか?"
|
||||
|
||||
@@ -627,18 +627,18 @@ msgid "Unknown error."
|
||||
msgstr "不明なエラー。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:292
|
||||
#, fuzzy
|
||||
#| msgid "Your color has great contrast and is very easy to read!"
|
||||
msgid "Your color has great contrast and will provide excellent accessibility."
|
||||
msgstr "色彩のコントラストが良く読みやすいです!"
|
||||
msgstr ""
|
||||
"あなたの色は素晴らしいコントラストを持ち、優れたアクセシビリティを提供しま"
|
||||
"す。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:296
|
||||
#, fuzzy
|
||||
#| msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgid ""
|
||||
"Your color has decent contrast and is sufficient for minimum accessibility "
|
||||
"requirements."
|
||||
msgstr "色彩のコントラストは読むのに十分です!"
|
||||
msgstr ""
|
||||
"あなたの色は適切なコントラストを持ち、最小限のアクセシビリティ要件に十分で"
|
||||
"す。"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:300
|
||||
msgid ""
|
||||
@@ -646,40 +646,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
|
||||
msgid "All"
|
||||
msgstr "全"
|
||||
msgstr "検索クエリ"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "全て"
|
||||
|
||||
#: 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 "1以上%(max)s以下のページ番号を入力。"
|
||||
|
||||
#: 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 "保存されていない変更があります!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2025-06-25 06:56+0000\n"
|
||||
"Last-Translator: 조정화 <junghwa.jo@om.org>\n"
|
||||
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -579,48 +579,48 @@ msgstr "체크인 QR"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "다음과 같은 이유로 PDF 배경 파일을 로드할 수 없습니다:"
|
||||
|
||||
#: 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 "PDF 파일을 업로드하는 동안 오류가 발생했습니다. 다시 시도해 주세요."
|
||||
|
||||
#: 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 "변경 사항을 저장하지 않고 편집 기능을 나가고 싶으신가요?"
|
||||
|
||||
@@ -652,40 +652,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 "페이지 번호를 1에서 %(최대)초 사이로 입력합니다."
|
||||
|
||||
#: 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 "귀하는 변경을 저장하지 않았습니다"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -559,48 +559,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 ""
|
||||
|
||||
@@ -632,40 +632,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 ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-26 09:11+0000\n"
|
||||
"POT-Creation-Date: 2025-08-04 12:44+0000\n"
|
||||
"PO-Revision-Date: 2022-04-06 03:00+0000\n"
|
||||
"Last-Translator: Liga V <lerning_by_dreaming@gmx.de>\n"
|
||||
"Language-Team: Latvian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -585,53 +585,53 @@ msgstr "Reģistrācijas QR"
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "Fona PDF fails nevarēja ielādēties sekojoša iemesla dēļ:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:904
|
||||
msgid "Group of objects"
|
||||
msgstr "Objektu grupa"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:908
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Teksta objekts"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:910
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Teksta objekts"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:912
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
msgid "Barcode area"
|
||||
msgstr "Svītru koda lauks"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:914
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:915
|
||||
msgid "Image area"
|
||||
msgstr "Attēla lauks"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:916
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:917
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Pretix atbalstīts"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:918
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:919
|
||||
msgid "Object"
|
||||
msgstr "Objekts"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:922
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:923
|
||||
msgid "Ticket design"
|
||||
msgstr "Biļešu dizains"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1258
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1292
|
||||
msgid "Saving failed."
|
||||
msgstr "Saglabāšana neizdevās."
|
||||
|
||||
#: 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 ""
|
||||
"Radusies kļūda augšupielādējot jūsu PDF failu, lūdzu, mēģiniet vēlreiz."
|
||||
|
||||
#: 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 ""
|
||||
"Vai jūs tiešām vēlaties iziet no rediģēšanas lauka bez veikto izmaiņu "
|
||||
@@ -671,40 +671,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 "Meklēšanas pieprasījums"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:434
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
msgid "All"
|
||||
msgstr "Visi"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:435
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:436
|
||||
msgid "None"
|
||||
msgstr "Neviens"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:439
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:440
|
||||
msgid "Selected only"
|
||||
msgstr "Tikai atzīmētos"
|
||||
|
||||
#: 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 "Izmantojiet citu nosaukumu iekšēji"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1012
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1013
|
||||
msgid "Click to close"
|
||||
msgstr "Noklikšķiniet, lai aizvērtu"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1093
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1094
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Jums ir nesaglabātas izmaiņas!"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user