forked from CGM_Public/pretix_original
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ceea9d0c9 |
@@ -22,7 +22,6 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Tests
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ["3.9", "3.10", "3.11"]
|
||||
database: [sqlite, postgres]
|
||||
@@ -65,7 +64,7 @@ jobs:
|
||||
run: make all compress
|
||||
- name: Run tests
|
||||
working-directory: ./src
|
||||
run: PRETIX_CONFIG_FILE=tests/travis_${{ matrix.database }}.cfg py.test -vv -n 3 -p no:sugar --cov=./ --cov-report=xml --reruns 3 tests --maxfail=100
|
||||
run: PRETIX_CONFIG_FILE=tests/travis_${{ matrix.database }}.cfg py.test -n 3 -p no:sugar --cov=./ --cov-report=xml --reruns 3 tests --maxfail=100
|
||||
- name: Run concurrency tests
|
||||
working-directory: ./src
|
||||
run: PRETIX_CONFIG_FILE=tests/travis_${{ matrix.database }}.cfg py.test tests/concurrency_tests/ --reruns 0 --reuse-db
|
||||
|
||||
@@ -294,10 +294,6 @@ Example::
|
||||
setting is not provided, pretix will generate a random secret on the first start
|
||||
and will store it in the filesystem for later usage.
|
||||
|
||||
``secret_fallback0`` ... ``secret_fallback9``
|
||||
Prior versions of the secret to be used by Django for signing and verification purposes that will still
|
||||
be accepted but no longer be used for new signing.
|
||||
|
||||
``debug``
|
||||
Whether or not to run in debug mode. Default is ``False``.
|
||||
|
||||
|
||||
@@ -23,22 +23,6 @@ position integer An integer, use
|
||||
is_addon boolean If ``true``, items within this category are not on sale
|
||||
on their own but the category provides a source for
|
||||
defining add-ons for other products.
|
||||
cross_selling_mode string If ``null``, cross-selling is disabled for this category.
|
||||
If ``"only"``, it is only visible in the cross-selling
|
||||
step.
|
||||
If ``"both"``, it is visible on the normal index page
|
||||
as well.
|
||||
Only available if ``is_addon`` is ``false``.
|
||||
cross_selling_condition string Only relevant if ``cross_selling_mode`` is not ``null``.
|
||||
If ``"always"``, always show in cross-selling step.
|
||||
If ``"products"``, only show if the cart contains one of
|
||||
the products listed in ``cross_selling_match_products``.
|
||||
If ``"discounts"``, only show products that qualify for
|
||||
a discount according to discount rules.
|
||||
cross_selling_match_products list of integer Only relevant if ``cross_selling_condition`` is
|
||||
``"products"``. Internal ID of the items of which at
|
||||
least one needs to be in the cart for this category to
|
||||
be shown.
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
@@ -76,10 +60,7 @@ Endpoints
|
||||
"internal_name": "",
|
||||
"description": {"en": "Tickets are what you need to get in."},
|
||||
"position": 1,
|
||||
"is_addon": false,
|
||||
"cross_selling_mode": null,
|
||||
"cross_selling_condition": null,
|
||||
"cross_selling_match_products": []
|
||||
"is_addon": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -121,10 +102,7 @@ Endpoints
|
||||
"internal_name": "",
|
||||
"description": {"en": "Tickets are what you need to get in."},
|
||||
"position": 1,
|
||||
"is_addon": false,
|
||||
"cross_selling_mode": null,
|
||||
"cross_selling_condition": null,
|
||||
"cross_selling_match_products": []
|
||||
"is_addon": false
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
@@ -152,10 +130,7 @@ Endpoints
|
||||
"internal_name": "",
|
||||
"description": {"en": "Tickets are what you need to get in."},
|
||||
"position": 1,
|
||||
"is_addon": false,
|
||||
"cross_selling_mode": null,
|
||||
"cross_selling_condition": null,
|
||||
"cross_selling_match_products": []
|
||||
"is_addon": false
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
@@ -172,10 +147,7 @@ Endpoints
|
||||
"internal_name": "",
|
||||
"description": {"en": "Tickets are what you need to get in."},
|
||||
"position": 1,
|
||||
"is_addon": false,
|
||||
"cross_selling_mode": null,
|
||||
"cross_selling_condition": null,
|
||||
"cross_selling_match_products": []
|
||||
"is_addon": false
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer of the event to create a category for
|
||||
@@ -221,10 +193,7 @@ Endpoints
|
||||
"internal_name": "",
|
||||
"description": {"en": "Tickets are what you need to get in."},
|
||||
"position": 1,
|
||||
"is_addon": true,
|
||||
"cross_selling_mode": null,
|
||||
"cross_selling_condition": null,
|
||||
"cross_selling_match_products": []
|
||||
"is_addon": true
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to modify
|
||||
|
||||
@@ -203,8 +203,7 @@ checkins list of objects List of **succe
|
||||
├ datetime datetime Time of check-in
|
||||
├ type string Type of scan (defaults to ``entry``)
|
||||
├ gate integer Internal ID of the gate. Can be ``null``.
|
||||
├ device integer Internal ID of the device. Can be ``null``. **Deprecated**, since this ID is not otherwise used in the API and is therefore not very useful.
|
||||
├ device_id integer Attribute ``device_id`` of the device. Can be ``null``.
|
||||
├ device integer Internal ID of the device. Can be ``null``.
|
||||
└ auto_checked_in boolean Indicates if this check-in been performed automatically by the system
|
||||
downloads list of objects List of ticket download options
|
||||
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
|
||||
|
||||
@@ -51,7 +51,7 @@ Endpoints
|
||||
"results": [
|
||||
{
|
||||
"identifier": "web",
|
||||
"label": {
|
||||
"name": {
|
||||
"en": "Online shop"
|
||||
},
|
||||
"type": "web",
|
||||
@@ -88,7 +88,7 @@ Endpoints
|
||||
|
||||
{
|
||||
"identifier": "web",
|
||||
"label": {
|
||||
"name": {
|
||||
"en": "Online shop"
|
||||
},
|
||||
"type": "web",
|
||||
@@ -116,7 +116,7 @@ Endpoints
|
||||
|
||||
{
|
||||
"identifier": "api.custom",
|
||||
"label": {
|
||||
"name": {
|
||||
"en": "Custom integration"
|
||||
},
|
||||
"type": "api",
|
||||
@@ -133,7 +133,7 @@ Endpoints
|
||||
|
||||
{
|
||||
"identifier": "api.custom",
|
||||
"label": {
|
||||
"name": {
|
||||
"en": "Custom integration"
|
||||
},
|
||||
"type": "api",
|
||||
@@ -178,7 +178,7 @@ Endpoints
|
||||
|
||||
{
|
||||
"identifier": "web",
|
||||
"label": {
|
||||
"name": {
|
||||
"en": "Online shop"
|
||||
},
|
||||
"type": "web",
|
||||
|
||||
@@ -136,7 +136,6 @@ Endpoints
|
||||
}
|
||||
|
||||
:query page: The page number in case of a multi-page result set, default is 1
|
||||
:query is_public: If set to ``true``/``false``, only subevents with a matching value of ``is_public`` are returned.
|
||||
:query active: If set to ``true``/``false``, only events with a matching value of ``active`` are returned.
|
||||
:query is_future: If set to ``true`` (``false``), only events that happen currently or in the future are (not) returned.
|
||||
:query is_past: If set to ``true`` (``false``), only events that are over are (not) returned.
|
||||
@@ -468,7 +467,6 @@ Endpoints
|
||||
}
|
||||
|
||||
:query page: The page number in case of a multi-page result set, default is 1
|
||||
:query is_public: If set to ``true``/``false``, only subevents with a matching value of ``is_public`` are returned.
|
||||
:query active: If set to ``true``/``false``, only events with a matching value of ``active`` are returned.
|
||||
:query event__live: If set to ``true``/``false``, only events with a matching value of ``live`` on the parent event are returned.
|
||||
:query is_future: If set to ``true`` (``false``), only events that happen currently or in the future are (not) returned.
|
||||
|
||||
@@ -20,9 +20,8 @@ internal_name string An optional nam
|
||||
rate decimal (string) Tax rate in percent
|
||||
price_includes_tax boolean If ``true`` (default), tax is assumed to be included in
|
||||
the specified product price
|
||||
eu_reverse_charge boolean **DEPRECATED**. If ``true``, EU reverse charge rules
|
||||
are applied. Will be ignored if custom rules are set.
|
||||
Use custom rules instead.
|
||||
eu_reverse_charge boolean If ``true``, EU reverse charge rules are applied. Will
|
||||
be ignored if custom rules are set.
|
||||
home_country string Merchant country (required for reverse charge), can be
|
||||
``null`` or empty string
|
||||
keep_gross_if_rate_changes boolean If ``true``, changes of the tax rate based on custom
|
||||
|
||||
@@ -14,7 +14,7 @@ Core
|
||||
:members: periodic_task, event_live_issues, event_copy_data, email_filter, register_notification_types, notification,
|
||||
item_copy_data, register_sales_channel_types, register_global_settings, quota_availability, global_email_filter,
|
||||
register_ticket_secret_generators, gift_card_transaction_display,
|
||||
register_text_placeholders, register_mail_placeholders, device_info_updated
|
||||
register_text_placeholders, register_mail_placeholders
|
||||
|
||||
Order events
|
||||
""""""""""""
|
||||
|
||||
@@ -29,8 +29,8 @@ item_assignments list of objects Products this l
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
Layout endpoints
|
||||
----------------
|
||||
Endpoints
|
||||
---------
|
||||
|
||||
.. http:get:: /api/v1/organizers/(organizer)/events/(event)/ticketlayouts/
|
||||
|
||||
@@ -268,75 +268,5 @@ Layout endpoints
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to delete this resource.
|
||||
|
||||
Ticket rendering endpoint
|
||||
-----------------------------
|
||||
|
||||
.. http:post:: /api/v1/organizers/(organizer)/events/(event)/ticketpdfrenderer/render_batch/
|
||||
|
||||
With this API call, you can instruct the system to render a set of tickets into one combined PDF file. To specify
|
||||
which tickets to render, you need to submit a list of "parts". For every part, the following fields are supported:
|
||||
|
||||
* ``orderposition`` (``integer``, required): The ID of the order position to render.
|
||||
* ``override_channel`` (``string``, optional): The sales channel ID to be used for layout selection instead of the
|
||||
original channel of the order.
|
||||
* ``override_layout`` (``integer``, optional): The ticket layout ID to be used instead of the auto-selected one.
|
||||
|
||||
If your input parameters validate correctly, a ``202 Accepted`` status code is returned.
|
||||
The body points you to the download URL of the result. Running a ``GET`` request on that result URL will
|
||||
yield one of the following status codes:
|
||||
|
||||
* ``200 OK`` – The export succeeded. The body will be your resulting file. Might be large!
|
||||
* ``409 Conflict`` – Your export is still running. The body will be JSON with the structure ``{"status": "running"}``. ``status`` can be ``waiting`` before the task is actually being processed. Please retry, but wait at least one second before you do.
|
||||
* ``410 Gone`` – Running the export has failed permanently. The body will be JSON with the structure ``{"status": "failed", "message": "Error message"}``
|
||||
* ``404 Not Found`` – The export does not exist / is expired.
|
||||
|
||||
.. warning:: This endpoint is considered **experimental**. It might change at any time without prior notice.
|
||||
|
||||
.. note:: To avoid performance issues, a maximum number of 1000 parts is currently allowed.
|
||||
|
||||
**Example request**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
POST /api/v1/organizers/bigevents/events/sampleconf/ticketpdfrenderer/render_batch/ HTTP/1.1
|
||||
Host: pretix.eu
|
||||
Accept: application/json, text/javascript
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"parts": [
|
||||
{
|
||||
"orderposition": 55412
|
||||
},
|
||||
{
|
||||
"orderposition": 55412,
|
||||
"override_channel": "web"
|
||||
},
|
||||
{
|
||||
"orderposition": 55412,
|
||||
"override_layout": 56
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
**Example response**:
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Vary: Accept
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"download": "https://pretix.eu/api/v1/organizers/bigevents/events/sampleconf/ticketpdfrenderer/download/29891ede-196f-4942-9e26-d055a36e98b8/3f279f13-c198-4137-b49b-9b360ce9fcce/"
|
||||
}
|
||||
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
:param event: The ``slug`` field of the event to fetch
|
||||
:statuscode 202: no error
|
||||
:statuscode 400: Invalid input options
|
||||
:statuscode 401: Authentication failure
|
||||
:statuscode 403: The requested organizer/event does not exist **or** you have no permission to view this resource.
|
||||
|
||||
|
||||
.. _here: https://github.com/pretix/pretix/blob/master/src/pretix/static/schema/pdf-layout.schema.json
|
||||
|
||||
@@ -175,7 +175,7 @@ without any special behavior.
|
||||
Connecting SSO providers (pretix as the SSO client)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To connect an external application as a SSO provider, go to "Customer accounts" → "SSO providers" → "Create a new SSO provider"
|
||||
To connect an external application as a SSO client, go to "Customer accounts" → "SSO providers" → "Create a new SSO provider"
|
||||
in your organizer account.
|
||||
|
||||
.. thumbnail:: ../../screens/organizer/customer_ssoprovider_add.png
|
||||
|
||||
+9
-9
@@ -36,7 +36,7 @@ dependencies = [
|
||||
"css-inline==0.14.*",
|
||||
"defusedcsv>=1.1.0",
|
||||
"Django[argon2]==4.2.*,>=4.2.15",
|
||||
"django-bootstrap3==24.3",
|
||||
"django-bootstrap3==24.2",
|
||||
"django-compressor==4.5.1",
|
||||
"django-countries==7.6.*",
|
||||
"django-filter==24.3",
|
||||
@@ -55,7 +55,7 @@ dependencies = [
|
||||
"django-scopes==2.0.*",
|
||||
"django-statici18n==2.5.*",
|
||||
"djangorestframework==3.15.*",
|
||||
"dnspython==2.7.*",
|
||||
"dnspython==2.6.*",
|
||||
"drf_ujson2==1.7.*",
|
||||
"geoip2==4.*",
|
||||
"importlib_metadata==8.*", # Polyfill, we can probably drop this once we require Python 3.10+
|
||||
@@ -76,22 +76,22 @@ dependencies = [
|
||||
"phonenumberslite==8.13.*",
|
||||
"Pillow==10.4.*",
|
||||
"pretix-plugin-build",
|
||||
"protobuf==5.28.*",
|
||||
"protobuf==5.27.*",
|
||||
"psycopg2-binary",
|
||||
"pycountry",
|
||||
"pycparser==2.22",
|
||||
"pycryptodome==3.21.*",
|
||||
"pypdf==5.0.*",
|
||||
"pycryptodome==3.20.*",
|
||||
"pypdf==4.3.*",
|
||||
"python-bidi==0.6.*", # Support for Arabic in reportlab
|
||||
"python-dateutil==2.9.*",
|
||||
"pytz",
|
||||
"pytz-deprecation-shim==0.1.*",
|
||||
"pyuca",
|
||||
"qrcode==8.0",
|
||||
"redis==5.1.*",
|
||||
"qrcode==7.4.*",
|
||||
"redis==5.0.*",
|
||||
"reportlab==4.2.*",
|
||||
"requests==2.31.*",
|
||||
"sentry-sdk==2.17.*",
|
||||
"sentry-sdk==2.13.*",
|
||||
"sepaxml==2.6.*",
|
||||
"slimit",
|
||||
"stripe==7.9.*",
|
||||
@@ -111,7 +111,7 @@ dev = [
|
||||
"aiohttp==3.10.*",
|
||||
"coverage",
|
||||
"coveralls",
|
||||
"fakeredis==2.26.*",
|
||||
"fakeredis==2.23.*",
|
||||
"flake8==7.1.*",
|
||||
"freezegun",
|
||||
"isort==5.13.*",
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
# 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/>.
|
||||
#
|
||||
__version__ = "2024.10.0.dev0"
|
||||
__version__ = "2024.8.0.dev0"
|
||||
|
||||
@@ -80,7 +80,6 @@ ALL_LANGUAGES = [
|
||||
('de', _('German')),
|
||||
('de-informal', _('German (informal)')),
|
||||
('ar', _('Arabic')),
|
||||
('eu', _('Basque')),
|
||||
('ca', _('Catalan')),
|
||||
('zh-hans', _('Chinese (simplified)')),
|
||||
('zh-hant', _('Chinese (traditional)')),
|
||||
|
||||
@@ -88,20 +88,16 @@ class SalesChannelMigrationMixin:
|
||||
}
|
||||
|
||||
if data.get("all_sales_channels") and set(data["sales_channels"]) != all_channels:
|
||||
raise ValidationError({
|
||||
"limit_sales_channels": [
|
||||
"If 'all_sales_channels' is set, the legacy attribute 'sales_channels' must not be set or set to "
|
||||
"the list of all sales channels."
|
||||
]
|
||||
})
|
||||
raise ValidationError(
|
||||
"If 'all_sales_channels' is set, the legacy attribute 'sales_channels' must not be set or set to "
|
||||
"the list of all sales channels."
|
||||
)
|
||||
|
||||
if data.get("limit_sales_channels") and set(data["sales_channels"]) != set(data["limit_sales_channels"]):
|
||||
raise ValidationError({
|
||||
"limit_sales_channels": [
|
||||
"If 'limit_sales_channels' is set, the legacy attribute 'sales_channels' must not be set or set to "
|
||||
"the same list."
|
||||
]
|
||||
})
|
||||
raise ValidationError(
|
||||
"If 'limit_sales_channels' is set, the legacy attribute 'sales_channels' must not be set or set to "
|
||||
"the same list."
|
||||
)
|
||||
|
||||
if data["sales_channels"] == all_channels:
|
||||
data["all_sales_channels"] = True
|
||||
@@ -110,10 +106,6 @@ class SalesChannelMigrationMixin:
|
||||
data["all_sales_channels"] = False
|
||||
data["limit_sales_channels"] = data["sales_channels"]
|
||||
del data["sales_channels"]
|
||||
|
||||
if data.get("all_sales_channels"):
|
||||
data["limit_sales_channels"] = []
|
||||
|
||||
return super().to_internal_value(data)
|
||||
|
||||
def to_representation(self, value):
|
||||
|
||||
@@ -772,7 +772,6 @@ class EventSettingsSerializer(SettingsSerializer):
|
||||
'invoice_address_company_required',
|
||||
'invoice_address_beneficiary',
|
||||
'invoice_address_custom_field',
|
||||
'invoice_address_custom_field_helptext',
|
||||
'invoice_name_required',
|
||||
'invoice_address_not_asked_free',
|
||||
'invoice_show_payments',
|
||||
@@ -897,7 +896,6 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer):
|
||||
'locale',
|
||||
'last_order_modification_date',
|
||||
'show_quota_left',
|
||||
'show_dates_on_frontpage',
|
||||
'max_items_per_order',
|
||||
'attendee_names_asked',
|
||||
'attendee_names_required',
|
||||
@@ -917,7 +915,6 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer):
|
||||
'invoice_address_company_required',
|
||||
'invoice_address_beneficiary',
|
||||
'invoice_address_custom_field',
|
||||
'invoice_address_custom_field_helptext',
|
||||
'invoice_name_required',
|
||||
'invoice_address_not_asked_free',
|
||||
'invoice_address_from_name',
|
||||
|
||||
@@ -369,7 +369,7 @@ class ItemSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
|
||||
require_membership_types = validated_data.pop('require_membership_types', [])
|
||||
limit_sales_channels = validated_data.pop('limit_sales_channels', [])
|
||||
item = Item.objects.create(**validated_data)
|
||||
if limit_sales_channels and not validated_data.get('all_sales_channels'):
|
||||
if limit_sales_channels:
|
||||
item.limit_sales_channels.add(*limit_sales_channels)
|
||||
if picture:
|
||||
item.picture.save(os.path.basename(picture.name), picture)
|
||||
@@ -441,22 +441,7 @@ class ItemCategorySerializer(I18nAwareModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = ItemCategory
|
||||
fields = (
|
||||
'id', 'name', 'internal_name', 'description', 'position',
|
||||
'is_addon', 'cross_selling_mode',
|
||||
'cross_selling_condition', 'cross_selling_match_products'
|
||||
)
|
||||
|
||||
def validate(self, data):
|
||||
data = super().validate(data)
|
||||
|
||||
full_data = self.to_internal_value(self.to_representation(self.instance)) if self.instance else {}
|
||||
full_data.update(data)
|
||||
|
||||
if full_data.get('is_addon') and full_data.get('cross_selling_mode'):
|
||||
raise ValidationError('is_addon and cross_selling_mode are mutually exclusive')
|
||||
|
||||
return data
|
||||
fields = ('id', 'name', 'internal_name', 'description', 'position', 'is_addon')
|
||||
|
||||
|
||||
class QuestionOptionSerializer(I18nAwareModelSerializer):
|
||||
|
||||
@@ -273,15 +273,9 @@ class AnswerSerializer(I18nAwareModelSerializer):
|
||||
|
||||
|
||||
class CheckinSerializer(I18nAwareModelSerializer):
|
||||
device_id = serializers.SlugRelatedField(
|
||||
source='device',
|
||||
slug_field='device_id',
|
||||
read_only=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Checkin
|
||||
fields = ('id', 'datetime', 'list', 'auto_checked_in', 'gate', 'device', 'device_id', 'type')
|
||||
fields = ('id', 'datetime', 'list', 'auto_checked_in', 'gate', 'device', 'type')
|
||||
|
||||
|
||||
class FailedCheckinSerializer(I18nAwareModelSerializer):
|
||||
|
||||
@@ -377,7 +377,7 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
||||
Prefetch(
|
||||
'positions',
|
||||
OrderPosition.objects.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
'item', 'variation', 'answers', 'answers__options', 'answers__question',
|
||||
)
|
||||
)
|
||||
|
||||
@@ -200,11 +200,6 @@ class UpdateView(APIView):
|
||||
device.save()
|
||||
device.log_action('pretix.device.updated', data=serializer.validated_data, auth=device)
|
||||
|
||||
from ...base.signals import device_info_updated
|
||||
device_info_updated.send(
|
||||
sender=Device, old_device=request.auth, new_device=device
|
||||
)
|
||||
|
||||
serializer = DeviceSerializer(device)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
@@ -297,8 +297,7 @@ class EventViewSet(viewsets.ModelViewSet):
|
||||
|
||||
if 'all_sales_channels' in serializer.validated_data and 'sales_channels' in serializer.validated_data:
|
||||
new_event.all_sales_channels = serializer.validated_data['all_sales_channels']
|
||||
if not new_event.all_sales_channels:
|
||||
new_event.limit_sales_channels.set(serializer.validated_data['limit_sales_channels'])
|
||||
new_event.limit_sales_channels.set(serializer.validated_data['limit_sales_channels'])
|
||||
else:
|
||||
serializer.instance.set_defaults()
|
||||
|
||||
@@ -371,7 +370,7 @@ with scopes_disabled():
|
||||
|
||||
class Meta:
|
||||
model = SubEvent
|
||||
fields = ['is_public', 'active', 'event__live']
|
||||
fields = ['active', 'event__live']
|
||||
|
||||
def ends_after_qs(self, queryset, name, value):
|
||||
expr = Q(
|
||||
|
||||
@@ -78,7 +78,7 @@ class ReusableMediaViewSet(viewsets.ModelViewSet):
|
||||
queryset=OrderPosition.objects.select_related(
|
||||
'order', 'order__event', 'order__event__organizer', 'seat',
|
||||
).prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
'answers', 'answers__options', 'answers__question',
|
||||
)
|
||||
),
|
||||
|
||||
@@ -258,7 +258,7 @@ class OrderViewSetMixin:
|
||||
return Prefetch(
|
||||
'positions',
|
||||
opq.all().prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'), to_attr='meta_values_cached')
|
||||
)),
|
||||
@@ -279,7 +279,7 @@ class OrderViewSetMixin:
|
||||
return Prefetch(
|
||||
'positions',
|
||||
opq.all().prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
'item', 'variation',
|
||||
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options', 'question').order_by('question__position')),
|
||||
'seat',
|
||||
@@ -1092,7 +1092,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
||||
'item_meta_properties',
|
||||
)
|
||||
qs = qs.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'),
|
||||
to_attr='meta_values_cached')
|
||||
@@ -1111,7 +1111,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
||||
Prefetch(
|
||||
'positions',
|
||||
qs.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'),
|
||||
to_attr='meta_values_cached')
|
||||
@@ -1135,7 +1135,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
||||
)
|
||||
else:
|
||||
qs = qs.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
'answers', 'answers__options', 'answers__question',
|
||||
).select_related(
|
||||
'item', 'order', 'order__event', 'order__event__organizer', 'seat'
|
||||
|
||||
+1
-63
@@ -32,16 +32,13 @@
|
||||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
import string
|
||||
from collections import OrderedDict
|
||||
from importlib import import_module
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate
|
||||
from django.contrib.auth.hashers import check_password, make_password
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _, ngettext
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
def get_auth_backends():
|
||||
@@ -163,62 +160,3 @@ class NativeAuthBackend(BaseAuthBackend):
|
||||
u = authenticate(request=request, email=form_data['email'].lower(), password=form_data['password'])
|
||||
if u and u.auth_backend == self.identifier:
|
||||
return u
|
||||
|
||||
|
||||
class NumericAndAlphabeticPasswordValidator:
|
||||
|
||||
def validate(self, password, user=None):
|
||||
has_numeric = any(c in string.digits for c in password)
|
||||
has_alpha = any(c in string.ascii_letters for c in password)
|
||||
if not has_numeric or not has_alpha:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Your password must contain both numeric and alphabetic characters.",
|
||||
),
|
||||
code="password_numeric_and_alphabetic",
|
||||
)
|
||||
|
||||
def get_help_text(self):
|
||||
return _(
|
||||
"Your password must contain both numeric and alphabetic characters.",
|
||||
)
|
||||
|
||||
|
||||
class HistoryPasswordValidator:
|
||||
|
||||
def __init__(self, history_length=4):
|
||||
self.history_length = history_length
|
||||
|
||||
def validate(self, password, user=None):
|
||||
from pretix.base.models import User
|
||||
|
||||
if not user or not user.pk or not isinstance(user, User):
|
||||
return
|
||||
|
||||
for hp in user.historic_passwords.order_by("-created")[:self.history_length]:
|
||||
if check_password(password, hp.password):
|
||||
raise ValidationError(
|
||||
ngettext(
|
||||
"Your password may not be the same as your previous password.",
|
||||
"Your password may not be the same as one of your %(history_length)s previous passwords.",
|
||||
self.history_length,
|
||||
),
|
||||
code="password_history",
|
||||
params={"history_length": self.history_length},
|
||||
)
|
||||
|
||||
def get_help_text(self):
|
||||
return ngettext(
|
||||
"Your password may not be the same as your previous password.",
|
||||
"Your password may not be the same as one of your %(history_length)s previous passwords.",
|
||||
self.history_length,
|
||||
) % {"history_length": self.history_length}
|
||||
|
||||
def password_changed(self, password, user=None):
|
||||
if not user:
|
||||
pass
|
||||
|
||||
user.historic_passwords.create(password=make_password(password))
|
||||
user.historic_passwords.filter(
|
||||
pk__in=user.historic_passwords.order_by("-created")[self.history_length:].values_list("pk", flat=True),
|
||||
).delete()
|
||||
|
||||
@@ -46,8 +46,6 @@ This module contains utilities for implementing OpenID Connect for customer auth
|
||||
as well as an OpenID Provider (OP).
|
||||
"""
|
||||
|
||||
pretix_token_endpoint_auth_methods = ['client_secret_basic', 'client_secret_post']
|
||||
|
||||
|
||||
def _urljoin(base, path):
|
||||
if not base.endswith("/"):
|
||||
@@ -129,16 +127,6 @@ def oidc_validate_and_complete_config(config):
|
||||
fields=", ".join(provider_config.get("claims_supported", []))
|
||||
))
|
||||
|
||||
if "token_endpoint_auth_methods_supported" in provider_config:
|
||||
token_endpoint_auth_methods_supported = provider_config.get("token_endpoint_auth_methods_supported",
|
||||
["client_secret_basic"])
|
||||
if not any(x in pretix_token_endpoint_auth_methods for x in token_endpoint_auth_methods_supported):
|
||||
raise ValidationError(
|
||||
_(f'No supported Token Endpoint Auth Methods supported: {token_endpoint_auth_methods_supported}').format(
|
||||
token_endpoint_auth_methods_supported=", ".join(token_endpoint_auth_methods_supported)
|
||||
)
|
||||
)
|
||||
|
||||
config['provider_config'] = provider_config
|
||||
return config
|
||||
|
||||
@@ -159,18 +147,6 @@ def oidc_authorize_url(provider, state, redirect_uri):
|
||||
|
||||
def oidc_validate_authorization(provider, code, redirect_uri):
|
||||
endpoint = provider.configuration['provider_config']['token_endpoint']
|
||||
|
||||
# Wall of shame and RFC ignorant IDPs
|
||||
if endpoint == 'https://www.linkedin.com/oauth/v2/accessToken':
|
||||
token_endpoint_auth_method = 'client_secret_post'
|
||||
else:
|
||||
token_endpoint_auth_methods = provider.configuration['provider_config'].get(
|
||||
'token_endpoint_auth_methods_supported', ['client_secret_basic']
|
||||
)
|
||||
token_endpoint_auth_method = [
|
||||
x for x in pretix_token_endpoint_auth_methods if x in token_endpoint_auth_methods
|
||||
][0]
|
||||
|
||||
params = {
|
||||
# https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
|
||||
# https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
|
||||
@@ -178,11 +154,6 @@ def oidc_validate_authorization(provider, code, redirect_uri):
|
||||
'code': code,
|
||||
'redirect_uri': redirect_uri,
|
||||
}
|
||||
|
||||
if token_endpoint_auth_method == 'client_secret_post':
|
||||
params['client_id'] = provider.configuration['client_id']
|
||||
params['client_secret'] = provider.configuration['client_secret']
|
||||
|
||||
try:
|
||||
resp = requests.post(
|
||||
endpoint,
|
||||
@@ -190,10 +161,7 @@ def oidc_validate_authorization(provider, code, redirect_uri):
|
||||
headers={
|
||||
'Accept': 'application/json',
|
||||
},
|
||||
auth=(
|
||||
provider.configuration['client_id'],
|
||||
provider.configuration['client_secret']
|
||||
) if token_endpoint_auth_method == 'client_secret_basic' else None,
|
||||
auth=(provider.configuration['client_id'], provider.configuration['client_secret']),
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
|
||||
@@ -1122,7 +1122,6 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
||||
|
||||
if event.settings.invoice_address_custom_field:
|
||||
self.fields['custom_field'].label = event.settings.invoice_address_custom_field
|
||||
self.fields['custom_field'].help_text = event.settings.invoice_address_custom_field_helptext
|
||||
else:
|
||||
del self.fields['custom_field']
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import time
|
||||
import traceback
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.dispatch.dispatcher import NO_RECEIVERS
|
||||
|
||||
@@ -51,23 +50,17 @@ class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('--tasks', action='store', type=str, help='Only execute the tasks with this name '
|
||||
'(dotted path, comma separation)')
|
||||
parser.add_argument('--list-tasks', action='store_true', help='Only list all tasks')
|
||||
parser.add_argument('--exclude', action='store', type=str, help='Exclude the tasks with this name '
|
||||
'(dotted path, comma separation)')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
verbosity = int(options['verbosity'])
|
||||
|
||||
cache.set("pretix_runperiodic_executed", True, 3600 * 12)
|
||||
|
||||
if not periodic_task.receivers or periodic_task.sender_receivers_cache.get(self) is NO_RECEIVERS:
|
||||
return
|
||||
|
||||
for receiver in periodic_task._live_receivers(self):
|
||||
name = f'{receiver.__module__}.{receiver.__name__}'
|
||||
if options['list_tasks']:
|
||||
print(name)
|
||||
continue
|
||||
if options.get('tasks'):
|
||||
if name not in options.get('tasks').split(','):
|
||||
continue
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Generated by Django 4.2.15 on 2024-09-16 15:10
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0269_order_api_meta"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="HistoricPassword",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True, primary_key=True, serialize=False
|
||||
),
|
||||
),
|
||||
("created", models.DateTimeField(auto_now_add=True)),
|
||||
("password", models.CharField(max_length=128)),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="historic_passwords",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,32 +0,0 @@
|
||||
# Generated by Django 4.2.11 on 2024-05-27 13:19
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.orders
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0270_historicpassword"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="itemcategory",
|
||||
name="cross_selling_condition",
|
||||
field=models.CharField(null=True, max_length=10),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="itemcategory",
|
||||
name="cross_selling_mode",
|
||||
field=models.CharField(null=True, max_length=5),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="itemcategory",
|
||||
name="cross_selling_match_products",
|
||||
field=models.ManyToManyField(
|
||||
related_name="matched_by_cross_selling_categories", to="pretixbase.item"
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -213,13 +213,7 @@ class DatetimeColumnMixin:
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
d = datetime.datetime.fromisoformat(value)
|
||||
if not d.tzinfo:
|
||||
d = d.replace(tzinfo=self.timezone)
|
||||
return d
|
||||
except (ValueError, TypeError):
|
||||
raise ValidationError(_("Could not parse {value} as a date and time.").format(value=value))
|
||||
raise ValidationError(_("Could not parse {value} as a date and time.").format(value=value))
|
||||
|
||||
|
||||
class DecimalColumnMixin:
|
||||
|
||||
@@ -40,8 +40,8 @@ from phonenumbers import SUPPORTED_REGIONS
|
||||
|
||||
from pretix.base.forms.questions import guess_country
|
||||
from pretix.base.modelimport import (
|
||||
BooleanColumnMixin, DatetimeColumnMixin, DecimalColumnMixin, ImportColumn,
|
||||
SubeventColumnMixin, i18n_flat,
|
||||
DatetimeColumnMixin, DecimalColumnMixin, ImportColumn, SubeventColumnMixin,
|
||||
i18n_flat,
|
||||
)
|
||||
from pretix.base.models import (
|
||||
Customer, ItemVariation, OrderPosition, Question, QuestionAnswer,
|
||||
@@ -604,22 +604,6 @@ class Comment(ImportColumn):
|
||||
order.comment = value or ''
|
||||
|
||||
|
||||
class CheckinAttentionColumn(BooleanColumnMixin, ImportColumn):
|
||||
identifier = 'checkin_attention'
|
||||
verbose_name = gettext_lazy('Requires special attention')
|
||||
|
||||
def assign(self, value, order, position, invoice_address, **kwargs):
|
||||
order.checkin_attention = value
|
||||
|
||||
|
||||
class CheckinTextColumn(ImportColumn):
|
||||
identifier = 'checkin_text'
|
||||
verbose_name = gettext_lazy('Check-in text')
|
||||
|
||||
def assign(self, value, order, position, invoice_address, **kwargs):
|
||||
order.checkin_text = value
|
||||
|
||||
|
||||
class QuestionColumn(ImportColumn):
|
||||
def __init__(self, event, q):
|
||||
self.q = q
|
||||
@@ -758,8 +742,6 @@ def get_order_import_columns(event):
|
||||
ValidUntil(event),
|
||||
Locale(event),
|
||||
Saleschannel(event),
|
||||
CheckinAttentionColumn(event),
|
||||
CheckinTextColumn(event),
|
||||
Expires(event),
|
||||
Comment(event),
|
||||
]
|
||||
|
||||
@@ -571,23 +571,13 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
|
||||
|
||||
def get_session_auth_hash(self):
|
||||
"""
|
||||
Return an HMAC that needs to be the same throughout the session, used e.g. for forced
|
||||
logout after every password change.
|
||||
"""
|
||||
return self._get_session_auth_hash(secret=settings.SECRET_KEY)
|
||||
|
||||
def get_session_auth_fallback_hash(self):
|
||||
for fallback_secret in settings.SECRET_KEY_FALLBACKS:
|
||||
yield self._get_session_auth_hash(secret=fallback_secret)
|
||||
|
||||
def _get_session_auth_hash(self, secret):
|
||||
"""
|
||||
Return an HMAC that needs to
|
||||
"""
|
||||
key_salt = "pretix.base.models.User.get_session_auth_hash"
|
||||
payload = self.password
|
||||
payload += self.email
|
||||
payload += self.session_token
|
||||
return salted_hmac(key_salt, payload, secret=secret).hexdigest()
|
||||
return salted_hmac(key_salt, payload).hexdigest()
|
||||
|
||||
def update_session_token(self):
|
||||
self.session_token = generate_session_token()
|
||||
@@ -664,9 +654,3 @@ class WebAuthnDevice(Device):
|
||||
@property
|
||||
def webauthnpubkey(self):
|
||||
return websafe_decode(self.pub_key)
|
||||
|
||||
|
||||
class HistoricPassword(models.Model):
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="historic_passwords")
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
password = models.CharField(verbose_name=_("Password"), max_length=128)
|
||||
|
||||
@@ -219,24 +219,13 @@ class Customer(LoggedModel):
|
||||
return is_password_usable(self.password)
|
||||
|
||||
def get_session_auth_hash(self):
|
||||
"""
|
||||
Return an HMAC that needs to be the same throughout the session, used e.g. for forced
|
||||
logout after every password change.
|
||||
"""
|
||||
return self._get_session_auth_hash(secret=settings.SECRET_KEY)
|
||||
|
||||
def get_session_auth_fallback_hash(self):
|
||||
for fallback_secret in settings.SECRET_KEY_FALLBACKS:
|
||||
yield self._get_session_auth_hash(secret=fallback_secret)
|
||||
|
||||
def _get_session_auth_hash(self, secret):
|
||||
"""
|
||||
Return an HMAC of the password field.
|
||||
"""
|
||||
key_salt = "pretix.base.models.customers.Customer.get_session_auth_hash"
|
||||
payload = self.password
|
||||
payload += self.email
|
||||
return salted_hmac(key_salt, payload, secret=secret).hexdigest()
|
||||
return salted_hmac(key_salt, payload).hexdigest()
|
||||
|
||||
def get_email_context(self):
|
||||
from pretix.base.settings import get_name_parts_localized
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from collections import defaultdict, namedtuple
|
||||
from collections import defaultdict
|
||||
from decimal import Decimal
|
||||
from itertools import groupby
|
||||
from math import ceil, inf
|
||||
from typing import Dict
|
||||
from math import ceil
|
||||
from typing import Dict, Optional, Tuple
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import MinValueValidator
|
||||
@@ -36,8 +36,6 @@ from django_scopes import ScopedManager
|
||||
from pretix.base.decimal import round_decimal
|
||||
from pretix.base.models.base import LoggedModel
|
||||
|
||||
PositionInfo = namedtuple('PositionInfo', ['item_id', 'subevent_id', 'line_price_gross', 'is_addon_to', 'voucher_discount'])
|
||||
|
||||
|
||||
class Discount(LoggedModel):
|
||||
SUBEVENT_MODE_MIXED = 'mixed'
|
||||
@@ -247,26 +245,22 @@ class Discount(LoggedModel):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _apply_min_value(self, positions, condition_idx_group, benefit_idx_group, result, collect_potential_discounts, subevent_id):
|
||||
if self.condition_min_value and sum(positions[idx].line_price_gross for idx in condition_idx_group) < self.condition_min_value:
|
||||
def _apply_min_value(self, positions, condition_idx_group, benefit_idx_group, result):
|
||||
if self.condition_min_value and sum(positions[idx][2] for idx in condition_idx_group) < self.condition_min_value:
|
||||
return
|
||||
|
||||
if self.condition_min_count or self.benefit_only_apply_to_cheapest_n_matches:
|
||||
raise ValueError('Validation invariant violated.')
|
||||
|
||||
for idx in benefit_idx_group:
|
||||
previous_price = positions[idx].line_price_gross
|
||||
previous_price = positions[idx][2]
|
||||
new_price = round_decimal(
|
||||
previous_price * (Decimal('100.00') - self.benefit_discount_matching_percent) / Decimal('100.00'),
|
||||
self.event.currency,
|
||||
)
|
||||
result[idx] = new_price
|
||||
|
||||
if collect_potential_discounts is not None:
|
||||
for idx in condition_idx_group:
|
||||
collect_potential_discounts[idx] = [(self, inf, -1, subevent_id)]
|
||||
|
||||
def _apply_min_count(self, positions, condition_idx_group, benefit_idx_group, result, collect_potential_discounts, subevent_id):
|
||||
def _apply_min_count(self, positions, condition_idx_group, benefit_idx_group, result):
|
||||
if len(condition_idx_group) < self.condition_min_count:
|
||||
return
|
||||
|
||||
@@ -274,53 +268,23 @@ class Discount(LoggedModel):
|
||||
raise ValueError('Validation invariant violated.')
|
||||
|
||||
if self.benefit_only_apply_to_cheapest_n_matches:
|
||||
# sort by line_price
|
||||
condition_idx_group = sorted(condition_idx_group, key=lambda idx: (positions[idx].line_price_gross, -idx))
|
||||
benefit_idx_group = sorted(benefit_idx_group, key=lambda idx: (positions[idx].line_price_gross, -idx))
|
||||
if not self.condition_min_count:
|
||||
raise ValueError('Validation invariant violated.')
|
||||
|
||||
condition_idx_group = sorted(condition_idx_group, key=lambda idx: (positions[idx][2], -idx)) # sort by line_price
|
||||
benefit_idx_group = sorted(benefit_idx_group, key=lambda idx: (positions[idx][2], -idx)) # sort by line_price
|
||||
|
||||
# Prevent over-consuming of items, i.e. if our discount is "buy 2, get 1 free", we only
|
||||
# want to match multiples of 3
|
||||
|
||||
# how many discount applications are allowed according to condition products in cart
|
||||
possible_applications_cond = len(condition_idx_group) // self.condition_min_count
|
||||
|
||||
# how many discount applications are possible according to benefitting products in cart
|
||||
possible_applications_benefit = ceil(len(benefit_idx_group) / self.benefit_only_apply_to_cheapest_n_matches)
|
||||
|
||||
n_groups = min(possible_applications_cond, possible_applications_benefit)
|
||||
n_groups = min(len(condition_idx_group) // self.condition_min_count, ceil(len(benefit_idx_group) / self.benefit_only_apply_to_cheapest_n_matches))
|
||||
consume_idx = condition_idx_group[:n_groups * self.condition_min_count]
|
||||
benefit_idx = benefit_idx_group[:n_groups * self.benefit_only_apply_to_cheapest_n_matches]
|
||||
|
||||
if collect_potential_discounts is not None:
|
||||
if n_groups * self.benefit_only_apply_to_cheapest_n_matches > len(benefit_idx_group):
|
||||
# partially used discount ("for each 1 ticket you buy, get 50% on 2 t-shirts", cart content: 1 ticket
|
||||
# but only 1 t-shirt) -> 1 shirt definitiv potential discount
|
||||
for idx in consume_idx:
|
||||
collect_potential_discounts[idx] = [
|
||||
(self, n_groups * self.benefit_only_apply_to_cheapest_n_matches - len(benefit_idx_group), -1, subevent_id)
|
||||
]
|
||||
|
||||
if possible_applications_cond * self.benefit_only_apply_to_cheapest_n_matches > len(benefit_idx_group):
|
||||
# unused discount ("for each 1 ticket you buy, get 50% on 2 t-shirts", cart content: 1 ticket
|
||||
# but 0 t-shirts) -> 2 shirt maybe potential discount (if the 1 ticket is not consumed by a later discount)
|
||||
for i, idx in enumerate(condition_idx_group[
|
||||
n_groups * self.condition_min_count:
|
||||
possible_applications_cond * self.condition_min_count
|
||||
]):
|
||||
collect_potential_discounts[idx] += [
|
||||
(self, self.benefit_only_apply_to_cheapest_n_matches, i // self.condition_min_count, subevent_id)
|
||||
]
|
||||
|
||||
else:
|
||||
consume_idx = condition_idx_group
|
||||
benefit_idx = benefit_idx_group
|
||||
|
||||
if collect_potential_discounts is not None:
|
||||
for idx in consume_idx:
|
||||
collect_potential_discounts[idx] = [(self, inf, -1, subevent_id)]
|
||||
|
||||
for idx in benefit_idx:
|
||||
previous_price = positions[idx].line_price_gross
|
||||
previous_price = positions[idx][2]
|
||||
new_price = round_decimal(
|
||||
previous_price * (Decimal('100.00') - self.benefit_discount_matching_percent) / Decimal('100.00'),
|
||||
self.event.currency,
|
||||
@@ -328,16 +292,15 @@ class Discount(LoggedModel):
|
||||
result[idx] = new_price
|
||||
|
||||
for idx in consume_idx:
|
||||
result.setdefault(idx, positions[idx].line_price_gross)
|
||||
result.setdefault(idx, positions[idx][2])
|
||||
|
||||
def apply(self, positions: Dict[int, PositionInfo],
|
||||
collect_potential_discounts=None) -> Dict[int, Decimal]:
|
||||
def apply(self, positions: Dict[int, Tuple[int, Optional[int], Decimal, bool, Decimal]]) -> Dict[int, Decimal]:
|
||||
"""
|
||||
Tries to apply this discount to a cart
|
||||
|
||||
:param positions: Dictionary mapping IDs to PositionInfo tuples.
|
||||
:param positions: Dictionary mapping IDs to tuples of the form
|
||||
``(item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount)``.
|
||||
Bundled positions may not be included.
|
||||
:param collect_potential_discounts: For detailed description, see pretix.base.services.pricing.apply_discounts
|
||||
|
||||
:return: A dictionary mapping keys from the input dictionary to new prices. All positions
|
||||
contained in this dictionary are considered "consumed" and should not be considered
|
||||
@@ -379,13 +342,13 @@ class Discount(LoggedModel):
|
||||
|
||||
if self.subevent_mode == self.SUBEVENT_MODE_MIXED: # also applies to non-series events
|
||||
if self.condition_min_count:
|
||||
self._apply_min_count(positions, condition_candidates, benefit_candidates, result, collect_potential_discounts, None)
|
||||
self._apply_min_count(positions, condition_candidates, benefit_candidates, result)
|
||||
else:
|
||||
self._apply_min_value(positions, condition_candidates, benefit_candidates, result, collect_potential_discounts, None)
|
||||
self._apply_min_value(positions, condition_candidates, benefit_candidates, result)
|
||||
|
||||
elif self.subevent_mode == self.SUBEVENT_MODE_SAME:
|
||||
def key(idx):
|
||||
return positions[idx].subevent_id or 0
|
||||
return positions[idx][1] or 0 # subevent_id
|
||||
|
||||
# Build groups of candidates with the same subevent, then apply our regular algorithm
|
||||
# to each group
|
||||
@@ -394,11 +357,11 @@ class Discount(LoggedModel):
|
||||
candidate_groups = [(k, list(g)) for k, g in _groups]
|
||||
|
||||
for subevent_id, g in candidate_groups:
|
||||
benefit_g = [idx for idx in benefit_candidates if positions[idx].subevent_id == subevent_id]
|
||||
benefit_g = [idx for idx in benefit_candidates if positions[idx][1] == subevent_id]
|
||||
if self.condition_min_count:
|
||||
self._apply_min_count(positions, g, benefit_g, result, collect_potential_discounts, subevent_id)
|
||||
self._apply_min_count(positions, g, benefit_g, result)
|
||||
else:
|
||||
self._apply_min_value(positions, g, benefit_g, result, collect_potential_discounts, subevent_id)
|
||||
self._apply_min_value(positions, g, benefit_g, result)
|
||||
|
||||
elif self.subevent_mode == self.SUBEVENT_MODE_DISTINCT:
|
||||
if self.condition_min_value or not self.benefit_same_products:
|
||||
@@ -414,9 +377,9 @@ class Discount(LoggedModel):
|
||||
# Build a list of subevent IDs in descending order of frequency
|
||||
subevent_to_idx = defaultdict(list)
|
||||
for idx, p in positions.items():
|
||||
subevent_to_idx[p.subevent_id].append(idx)
|
||||
subevent_to_idx[p[1]].append(idx)
|
||||
for v in subevent_to_idx.values():
|
||||
v.sort(key=lambda idx: positions[idx].line_price_gross)
|
||||
v.sort(key=lambda idx: positions[idx][2])
|
||||
subevent_order = sorted(list(subevent_to_idx.keys()), key=lambda s: len(subevent_to_idx[s]), reverse=True)
|
||||
|
||||
# Build groups of exactly condition_min_count distinct subevents
|
||||
@@ -431,7 +394,7 @@ class Discount(LoggedModel):
|
||||
l = [ll for ll in l if ll in condition_candidates and ll not in current_group]
|
||||
if cardinality and len(l) != cardinality:
|
||||
continue
|
||||
if se not in {positions[idx].subevent_id for idx in current_group}:
|
||||
if se not in {positions[idx][1] for idx in current_group}:
|
||||
candidates += l
|
||||
cardinality = len(l)
|
||||
|
||||
@@ -440,7 +403,7 @@ class Discount(LoggedModel):
|
||||
|
||||
# Sort the list by prices, then pick one. For "buy 2 get 1 free" we apply a "pick 1 from the start
|
||||
# and 2 from the end" scheme to optimize price distribution among groups
|
||||
candidates = sorted(candidates, key=lambda idx: positions[idx].line_price_gross)
|
||||
candidates = sorted(candidates, key=lambda idx: positions[idx][2])
|
||||
if len(current_group) < (self.benefit_only_apply_to_cheapest_n_matches or 0):
|
||||
candidate = candidates[0]
|
||||
else:
|
||||
@@ -452,14 +415,14 @@ class Discount(LoggedModel):
|
||||
if len(current_group) >= max(self.condition_min_count, 1):
|
||||
candidate_groups.append(current_group)
|
||||
for c in current_group:
|
||||
subevent_to_idx[positions[c].subevent_id].remove(c)
|
||||
subevent_to_idx[positions[c][1]].remove(c)
|
||||
current_group = []
|
||||
|
||||
# Distribute "leftovers"
|
||||
for se in subevent_order:
|
||||
if subevent_to_idx[se]:
|
||||
for group in candidate_groups:
|
||||
if se not in {positions[idx].subevent_id for idx in group}:
|
||||
if se not in {positions[idx][1] for idx in group}:
|
||||
group.append(subevent_to_idx[se].pop())
|
||||
if not subevent_to_idx[se]:
|
||||
break
|
||||
@@ -469,8 +432,6 @@ class Discount(LoggedModel):
|
||||
positions,
|
||||
[idx for idx in g if idx in condition_candidates],
|
||||
[idx for idx in g if idx in benefit_candidates],
|
||||
result,
|
||||
None,
|
||||
None
|
||||
result
|
||||
)
|
||||
return result
|
||||
|
||||
@@ -60,6 +60,7 @@ from django.urls import reverse
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import format_html
|
||||
from django.utils.timezone import make_aware, now
|
||||
from django.utils.translation import gettext, gettext_lazy as _
|
||||
from django_scopes import ScopedManager, scopes_disabled
|
||||
@@ -179,10 +180,14 @@ class EventMixin:
|
||||
"""
|
||||
tz = tz or self.timezone
|
||||
if (not self.settings.show_date_to and not force_show_end) or not self.date_to:
|
||||
df, dt = self.date_from, self.date_from
|
||||
else:
|
||||
df, dt = self.date_from, self.date_to
|
||||
return daterange(df.astimezone(tz), dt.astimezone(tz), as_html)
|
||||
if as_html:
|
||||
return format_html(
|
||||
"<time datetime=\"{}\">{}</time>",
|
||||
_date(self.date_from.astimezone(tz), "Y-m-d"),
|
||||
_date(self.date_from.astimezone(tz), "DATE_FORMAT"),
|
||||
)
|
||||
return _date(self.date_from.astimezone(tz), "DATE_FORMAT")
|
||||
return daterange(self.date_from.astimezone(tz), self.date_to.astimezone(tz), as_html)
|
||||
|
||||
def get_date_range_display_as_html(self, tz=None, force_show_end=False) -> str:
|
||||
return self.get_date_range_display(tz, force_show_end, as_html=True)
|
||||
@@ -870,12 +875,10 @@ class Event(EventMixin, LoggedModel):
|
||||
for i in Item.objects.filter(event=other).prefetch_related(
|
||||
'variations', 'limit_sales_channels', 'require_membership_types',
|
||||
'variations__limit_sales_channels', 'variations__require_membership_types',
|
||||
'matched_by_cross_selling_categories',
|
||||
):
|
||||
vars = list(i.variations.all())
|
||||
require_membership_types = list(i.require_membership_types.all())
|
||||
limit_sales_channels = list(i.limit_sales_channels.all())
|
||||
matched_by_cross_selling_categories = list(i.matched_by_cross_selling_categories.all())
|
||||
item_map[i.pk] = i
|
||||
i.pk = None
|
||||
i.event = self
|
||||
@@ -913,9 +916,6 @@ class Event(EventMixin, LoggedModel):
|
||||
if not v.all_sales_channels:
|
||||
v.limit_sales_channels.set(self.organizer.sales_channels.filter(identifier__in=[s.identifier for s in limit_sales_channels]))
|
||||
|
||||
if matched_by_cross_selling_categories:
|
||||
i.matched_by_cross_selling_categories.set([category_map[c.pk] for c in matched_by_cross_selling_categories])
|
||||
|
||||
for i in self.items.filter(hidden_if_item_available__isnull=False):
|
||||
i.hidden_if_item_available = item_map[i.hidden_if_item_available_id]
|
||||
i.save()
|
||||
|
||||
@@ -63,13 +63,14 @@ from django_countries.fields import Country
|
||||
from django_scopes import ScopedManager
|
||||
from i18nfield.fields import I18nCharField, I18nTextField
|
||||
|
||||
from pretix.base.media import MEDIA_TYPES
|
||||
from pretix.base.models import Event, SubEvent
|
||||
from pretix.base.models.base import LoggedModel
|
||||
from pretix.base.models.fields import MultiStringField
|
||||
from pretix.base.models.tax import TaxedPrice
|
||||
from pretix.base.timemachine import time_machine_now
|
||||
from pretix.helpers.images import ImageSizeValidator
|
||||
|
||||
from ...helpers.images import ImageSizeValidator
|
||||
from ..media import MEDIA_TYPES
|
||||
from .event import Event, SubEvent
|
||||
|
||||
|
||||
class ItemCategory(LoggedModel):
|
||||
@@ -110,33 +111,6 @@ class ItemCategory(LoggedModel):
|
||||
'only be bought in combination with a product that has this category configured as a possible '
|
||||
'source for add-ons.')
|
||||
)
|
||||
CROSS_SELLING_MODES = (
|
||||
(None, _('Normal category')),
|
||||
('both', _('Normal + cross-selling category')),
|
||||
('only', _('Cross-selling category')),
|
||||
)
|
||||
cross_selling_mode = models.CharField(
|
||||
choices=CROSS_SELLING_MODES,
|
||||
null=True,
|
||||
max_length=5
|
||||
)
|
||||
CROSS_SELLING_CONDITION = (
|
||||
('always', _('Always show in cross-selling step')),
|
||||
('discounts', _('Only show products that qualify for a discount according to discount rules')),
|
||||
('products', _('Only show if the cart contains one of the following products')),
|
||||
)
|
||||
cross_selling_condition = models.CharField(
|
||||
verbose_name=_("Cross-selling condition"),
|
||||
choices=CROSS_SELLING_CONDITION,
|
||||
null=True,
|
||||
max_length=10,
|
||||
)
|
||||
cross_selling_match_products = models.ManyToManyField(
|
||||
'pretixbase.Item',
|
||||
blank=True,
|
||||
verbose_name=_("Cross-selling condition products"),
|
||||
related_name="matched_by_cross_selling_categories",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Product category")
|
||||
@@ -145,31 +119,19 @@ class ItemCategory(LoggedModel):
|
||||
|
||||
def __str__(self):
|
||||
name = self.internal_name or self.name
|
||||
if self.category_type != 'normal':
|
||||
return _('{category} ({category_type})').format(category=str(name),
|
||||
category_type=self.get_category_type_display())
|
||||
if self.is_addon:
|
||||
return _('{category} (Add-On products)').format(category=str(name))
|
||||
return str(name)
|
||||
|
||||
def get_category_type_display(self):
|
||||
if self.is_addon:
|
||||
return _('Add-on category')
|
||||
elif self.cross_selling_mode:
|
||||
return self.get_cross_selling_mode_display()
|
||||
return _('Add-On products')
|
||||
else:
|
||||
return _('Normal category')
|
||||
return None
|
||||
|
||||
@property
|
||||
def category_type(self):
|
||||
return 'addon' if self.is_addon else self.cross_selling_mode or 'normal'
|
||||
|
||||
@category_type.setter
|
||||
def category_type(self, new_value):
|
||||
if new_value == 'addon':
|
||||
self.is_addon = True
|
||||
self.cross_selling_mode = None
|
||||
else:
|
||||
self.is_addon = False
|
||||
self.cross_selling_mode = None if new_value == 'normal' else new_value
|
||||
return 'addon' if self.is_addon else 'normal'
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
super().delete(*args, **kwargs)
|
||||
@@ -308,7 +270,7 @@ class SubEventItemVariation(models.Model):
|
||||
return True
|
||||
|
||||
|
||||
def filter_available(qs, channel='web', voucher=None, allow_addons=False, allow_cross_sell=False):
|
||||
def filter_available(qs, channel='web', voucher=None, allow_addons=False):
|
||||
# Channel can currently be a SalesChannel or a str, since we need that compatibility, but a SalesChannel
|
||||
# makes the query SIGNIFICANTLY faster
|
||||
from .organizer import SalesChannel
|
||||
@@ -329,8 +291,6 @@ def filter_available(qs, channel='web', voucher=None, allow_addons=False, allow_
|
||||
|
||||
if not allow_addons:
|
||||
q &= Q(Q(category__isnull=True) | Q(category__is_addon=False))
|
||||
if not allow_cross_sell:
|
||||
q &= Q(Q(category__isnull=True) | ~Q(category__cross_selling_mode='only'))
|
||||
|
||||
if voucher:
|
||||
if voucher.item_id:
|
||||
@@ -344,8 +304,8 @@ def filter_available(qs, channel='web', voucher=None, allow_addons=False, allow_
|
||||
|
||||
|
||||
class ItemQuerySet(models.QuerySet):
|
||||
def filter_available(self, channel='web', voucher=None, allow_addons=False, allow_cross_sell=False):
|
||||
return filter_available(self, channel, voucher, allow_addons, allow_cross_sell)
|
||||
def filter_available(self, channel='web', voucher=None, allow_addons=False):
|
||||
return filter_available(self, channel, voucher, allow_addons)
|
||||
|
||||
|
||||
class ItemQuerySetManager(ScopedManager(organizer='event__organizer').__class__):
|
||||
@@ -353,8 +313,8 @@ class ItemQuerySetManager(ScopedManager(organizer='event__organizer').__class__)
|
||||
super().__init__()
|
||||
self._queryset_class = ItemQuerySet
|
||||
|
||||
def filter_available(self, channel='web', voucher=None, allow_addons=False, allow_cross_sell=False):
|
||||
return filter_available(self.get_queryset(), channel, voucher, allow_addons, allow_cross_sell)
|
||||
def filter_available(self, channel='web', voucher=None, allow_addons=False):
|
||||
return filter_available(self.get_queryset(), channel, voucher, allow_addons)
|
||||
|
||||
|
||||
class Item(LoggedModel):
|
||||
|
||||
@@ -40,7 +40,6 @@ import json
|
||||
import logging
|
||||
import operator
|
||||
import string
|
||||
import warnings
|
||||
from collections import Counter
|
||||
from datetime import datetime, time, timedelta
|
||||
from decimal import Decimal
|
||||
@@ -382,28 +381,8 @@ class Order(LockModel, LoggedModel):
|
||||
self.event.cache.delete('complain_testmode_orders')
|
||||
self.delete()
|
||||
|
||||
def email_confirm_secret(self):
|
||||
return self.tagged_secret("email_confirm", 9)
|
||||
|
||||
def email_confirm_hash(self):
|
||||
warnings.warn('Use email_confirm_secret() instead of email_confirm_hash().',
|
||||
DeprecationWarning)
|
||||
return self.email_confirm_secret()
|
||||
|
||||
def check_email_confirm_secret(self, received_secret):
|
||||
return (
|
||||
hmac.compare_digest(
|
||||
self.tagged_secret("email_confirm", 9),
|
||||
received_secret[:9].lower()
|
||||
) or any(
|
||||
# TODO: remove this clause after a while (compatibility with old secrets currently in flight)
|
||||
hmac.compare_digest(
|
||||
hashlib.sha256(sk.encode() + self.secret.encode()).hexdigest()[:9],
|
||||
received_secret
|
||||
)
|
||||
for sk in [settings.SECRET_KEY, *settings.SECRET_KEY_FALLBACKS]
|
||||
)
|
||||
)
|
||||
return hashlib.sha256(settings.SECRET_KEY.encode() + self.secret.encode()).hexdigest()[:9]
|
||||
|
||||
def get_extended_status_display(self):
|
||||
# Changes in this method should to be replicated in pretixcontrol/orders/fragment_order_status.html
|
||||
@@ -2856,14 +2835,6 @@ class OrderPosition(AbstractPosition):
|
||||
(self.order.event.settings.change_allow_user_addons and ItemAddOn.objects.filter(base_item_id__in=[op.item_id for op in positions]).exists())
|
||||
)
|
||||
|
||||
@property
|
||||
def code(self):
|
||||
"""
|
||||
A ticket code which is unique among all events of a single organizer,
|
||||
built by the order code and the position number.
|
||||
"""
|
||||
return '{order_code}-{position}'.format(order_code=self.order.code, position=self.positionid)
|
||||
|
||||
|
||||
class Transaction(models.Model):
|
||||
"""
|
||||
|
||||
@@ -29,8 +29,6 @@ from django.core.validators import MaxValueValidator, MinValueValidator
|
||||
from django.db import models
|
||||
from django.utils.deconstruct import deconstructible
|
||||
from django.utils.formats import localize
|
||||
from django.utils.functional import lazy
|
||||
from django.utils.html import format_html
|
||||
from django.utils.translation import gettext_lazy as _, pgettext
|
||||
from i18nfield.fields import I18nCharField
|
||||
from i18nfield.strings import LazyI18nString
|
||||
@@ -122,8 +120,6 @@ EU_CURRENCIES = {
|
||||
}
|
||||
VAT_ID_COUNTRIES = EU_COUNTRIES | {'CH', 'NO'}
|
||||
|
||||
format_html_lazy = lazy(format_html, str)
|
||||
|
||||
|
||||
def is_eu_country(cc):
|
||||
cc = str(cc)
|
||||
@@ -197,17 +193,11 @@ class TaxRule(LoggedModel):
|
||||
eu_reverse_charge = models.BooleanField(
|
||||
verbose_name=_("Use EU reverse charge taxation rules"),
|
||||
default=False,
|
||||
help_text=format_html_lazy(
|
||||
'<span class="label label-warning" data-toggle="tooltip" title="{}">{}</span> {}',
|
||||
_('This feature will be removed in the future as it does not handle VAT for non-business customers in '
|
||||
'other EU countries in a way that works for all organizers. Use custom rules instead.'),
|
||||
_('DEPRECATED'),
|
||||
_("Not recommended. Most events will NOT be qualified for reverse charge since the place of "
|
||||
"taxation is the location of the event. This option disables charging VAT for all customers "
|
||||
"outside the EU and for business customers in different EU countries who entered a valid EU VAT "
|
||||
"ID. Only enable this option after consulting a tax counsel. No warranty given for correct tax "
|
||||
"calculation. USE AT YOUR OWN RISK.")
|
||||
),
|
||||
help_text=_("Not recommended. Most events will NOT be qualified for reverse charge since the place of "
|
||||
"taxation is the location of the event. This option disables charging VAT for all customers "
|
||||
"outside the EU and for business customers in different EU countries who entered a valid EU VAT "
|
||||
"ID. Only enable this option after consulting a tax counsel. No warranty given for correct tax "
|
||||
"calculation. USE AT YOUR OWN RISK.")
|
||||
)
|
||||
home_country = FastCountryField(
|
||||
verbose_name=_('Merchant country'),
|
||||
@@ -304,24 +294,10 @@ class TaxRule(LoggedModel):
|
||||
subtract_from_gross = Decimal('0.00')
|
||||
rate = adjust_rate
|
||||
|
||||
def _limit_subtract(base_price, subtract_from_gross):
|
||||
if not subtract_from_gross:
|
||||
return base_price
|
||||
if base_price >= Decimal('0.00'):
|
||||
# For positive prices, make sure they don't go negative because of bundles
|
||||
return max(Decimal('0.00'), base_price - subtract_from_gross)
|
||||
else:
|
||||
# If the price is already negative, we don't really care any more
|
||||
return base_price - subtract_from_gross
|
||||
|
||||
if rate == Decimal('0.00'):
|
||||
gross = _limit_subtract(base_price, subtract_from_gross)
|
||||
return TaxedPrice(
|
||||
net=gross,
|
||||
gross=gross,
|
||||
tax=Decimal('0.00'),
|
||||
rate=rate,
|
||||
name=self.name,
|
||||
net=base_price - subtract_from_gross, gross=base_price - subtract_from_gross, tax=Decimal('0.00'),
|
||||
rate=rate, name=self.name
|
||||
)
|
||||
|
||||
if base_price_is == 'auto':
|
||||
@@ -331,14 +307,19 @@ class TaxRule(LoggedModel):
|
||||
base_price_is = 'net'
|
||||
|
||||
if base_price_is == 'gross':
|
||||
gross = _limit_subtract(base_price, subtract_from_gross)
|
||||
if base_price >= Decimal('0.00'):
|
||||
# For positive prices, make sure they don't go negative because of bundles
|
||||
gross = max(Decimal('0.00'), base_price - subtract_from_gross)
|
||||
else:
|
||||
# If the price is already negative, we don't really care any more
|
||||
gross = base_price - subtract_from_gross
|
||||
net = round_decimal(gross - (gross * (1 - 100 / (100 + rate))),
|
||||
currency)
|
||||
elif base_price_is == 'net':
|
||||
net = base_price
|
||||
gross = round_decimal((net * (1 + rate / 100)), currency)
|
||||
if subtract_from_gross:
|
||||
gross = _limit_subtract(gross, subtract_from_gross)
|
||||
gross -= subtract_from_gross
|
||||
net = round_decimal(gross - (gross * (1 - 100 / (100 + rate))),
|
||||
currency)
|
||||
else:
|
||||
|
||||
@@ -1542,9 +1542,10 @@ def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None, lo
|
||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
|
||||
def apply_voucher(self, event: Event, voucher: str, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> None:
|
||||
"""
|
||||
Removes a list of items from a user's cart.
|
||||
:param event: The event ID in question
|
||||
:param voucher: A voucher code
|
||||
:param cart_id: The cart ID of the cart to modify
|
||||
:param session: Session ID of a guest
|
||||
"""
|
||||
with language(locale), time_machine_now_assigned(override_now_dt):
|
||||
try:
|
||||
@@ -1565,10 +1566,10 @@ def apply_voucher(self, event: Event, voucher: str, cart_id: str=None, locale='e
|
||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
|
||||
def remove_cart_position(self, event: Event, position: int, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> None:
|
||||
"""
|
||||
Removes an item specified by its position ID from a user's cart.
|
||||
Removes a list of items from a user's cart.
|
||||
:param event: The event ID in question
|
||||
:param position: A cart position ID
|
||||
:param cart_id: The cart ID of the cart to modify
|
||||
:param session: Session ID of a guest
|
||||
"""
|
||||
with language(locale), time_machine_now_assigned(override_now_dt):
|
||||
try:
|
||||
@@ -1589,9 +1590,9 @@ def remove_cart_position(self, event: Event, position: int, cart_id: str=None, l
|
||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
|
||||
def clear_cart(self, event: Event, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> None:
|
||||
"""
|
||||
Removes all items from a user's cart.
|
||||
Removes a list of items from a user's cart.
|
||||
:param event: The event ID in question
|
||||
:param cart_id: The cart ID of the cart to modify
|
||||
:param session: Session ID of a guest
|
||||
"""
|
||||
with language(locale), time_machine_now_assigned(override_now_dt):
|
||||
try:
|
||||
@@ -1610,15 +1611,13 @@ def clear_cart(self, event: Event, cart_id: str=None, locale='en', sales_channel
|
||||
|
||||
|
||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
|
||||
def set_cart_addons(self, event: Event, addons: List[dict], add_to_cart_items: List[dict], cart_id: str=None, locale='en',
|
||||
def set_cart_addons(self, event: Event, addons: List[dict], cart_id: str=None, locale='en',
|
||||
invoice_address: int=None, sales_channel='web', override_now_dt: datetime=None) -> None:
|
||||
"""
|
||||
Assigns addons to eligible products in a user's cart, adding and removing the addon products as necessary to
|
||||
ensure the requested addon state.
|
||||
Removes a list of items from a user's cart.
|
||||
:param event: The event ID in question
|
||||
:param addons: A list of dicts with the keys addon_to, item, variation
|
||||
:param add_to_cart_items: A list of dicts with the keys item, variation, count, custom_price, voucher, seat ID
|
||||
:param cart_id: The cart ID of the cart to modify
|
||||
:param session: Session ID of a guest
|
||||
"""
|
||||
with language(locale), time_machine_now_assigned(override_now_dt):
|
||||
ia = False
|
||||
@@ -1636,7 +1635,6 @@ def set_cart_addons(self, event: Event, addons: List[dict], add_to_cart_items: L
|
||||
try:
|
||||
cm = CartManager(event=event, cart_id=cart_id, invoice_address=ia, sales_channel=sales_channel)
|
||||
cm.set_addons(addons)
|
||||
cm.add_new_items(add_to_cart_items)
|
||||
cm.commit()
|
||||
except LockTimeoutException:
|
||||
self.retry()
|
||||
|
||||
@@ -1182,11 +1182,10 @@ def process_exit_all(sender, **kwargs):
|
||||
positions = cl.positions_inside_query(ignore_status=True, at_time=cl.exit_all_at)
|
||||
for p in positions:
|
||||
with scope(organizer=cl.event.organizer):
|
||||
ci, created = Checkin.objects.get_or_create(
|
||||
ci = Checkin.objects.create(
|
||||
position=p, list=cl, auto_checked_in=True, type=Checkin.TYPE_EXIT, datetime=cl.exit_all_at
|
||||
)
|
||||
if created:
|
||||
checkin_created.send(cl.event, checkin=ci)
|
||||
checkin_created.send(cl.event, checkin=ci)
|
||||
d = cl.exit_all_at.astimezone(cl.event.timezone)
|
||||
if cl.event.settings.get(f'autocheckin_dst_hack_{cl.pk}'): # move time back if yesterday was DST switch
|
||||
d -= timedelta(hours=1)
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
#
|
||||
# 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 defaultdict
|
||||
from decimal import Decimal
|
||||
from itertools import groupby
|
||||
from math import inf
|
||||
from typing import List
|
||||
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from pretix.base.models import CartPosition, ItemCategory, SalesChannel
|
||||
from pretix.presale.views.event import get_grouped_items
|
||||
|
||||
|
||||
class DummyCategory:
|
||||
"""
|
||||
Used to create fake category objects for displaying the same cross-selling category multiple times,
|
||||
once for each subevent
|
||||
"""
|
||||
|
||||
def __init__(self, category: ItemCategory, subevent):
|
||||
self.id = category.id
|
||||
self.name = str(category.name)
|
||||
self.subevent_name = str(subevent)
|
||||
self.description = category.description
|
||||
|
||||
|
||||
class CrossSellingService:
|
||||
def __init__(self, event, sales_channel: SalesChannel, cartpositions: List[CartPosition], customer):
|
||||
self.event = event
|
||||
self.sales_channel = sales_channel
|
||||
self.cartpositions = cartpositions
|
||||
self.customer = customer
|
||||
|
||||
def get_data(self):
|
||||
if self.event.has_subevents:
|
||||
subevents = set(pos.subevent for pos in self.cartpositions)
|
||||
result = (
|
||||
(DummyCategory(category, subevent),
|
||||
self._prepare_items(subevent, items_qs, discount_info),
|
||||
f'subevent_{subevent.pk}_')
|
||||
for subevent in subevents
|
||||
for (category, items_qs, discount_info) in self._applicable_categories(subevent.pk)
|
||||
)
|
||||
else:
|
||||
result = (
|
||||
(category,
|
||||
self._prepare_items(None, items_qs, discount_info),
|
||||
'')
|
||||
for (category, items_qs, discount_info) in self._applicable_categories(0)
|
||||
)
|
||||
result = [(category, items, form_prefix) for (category, items, form_prefix) in result if len(items) > 0]
|
||||
for category, items, form_prefix in result:
|
||||
category.category_has_discount = any(item.original_price or (
|
||||
item.has_variations and any(var.original_price for var in item.available_variations)
|
||||
) for item in items)
|
||||
return result
|
||||
|
||||
def _applicable_categories(self, subevent_id):
|
||||
return [
|
||||
(c, products_qs, discount_info) for (c, products_qs, discount_info) in
|
||||
(
|
||||
(c, *self._get_visible_items_for_category(subevent_id, c))
|
||||
for c in self.event.categories.filter(cross_selling_mode__isnull=False).prefetch_related('items')
|
||||
)
|
||||
if products_qs is not None
|
||||
]
|
||||
|
||||
def _get_visible_items_for_category(self, filter_subevent_id, category: ItemCategory):
|
||||
"""
|
||||
If this category should be visible in the cross-selling step for a given cart and sales_channel, this method
|
||||
returns a queryset of the items that should be displayed, as well as a dict giving additional information on them.
|
||||
|
||||
:returns: (QuerySet<Item>, dict<(subevent_id, item_pk): (max_count, discount_rule)>)
|
||||
max_count is `inf` if the item should not be limited
|
||||
discount_rule is None if the item will not be discounted
|
||||
"""
|
||||
if category.cross_selling_mode is None:
|
||||
return None, {}
|
||||
if category.cross_selling_condition == 'always':
|
||||
return category.items.all(), {}
|
||||
if category.cross_selling_condition == 'products':
|
||||
match = set(match.pk for match in category.cross_selling_match_products.only('pk')) # TODO prefetch this
|
||||
return (category.items.all(), {}) if any(pos.item.pk in match for pos in self.cartpositions) else (None, {})
|
||||
if category.cross_selling_condition == 'discounts':
|
||||
my_item_pks = [item.id for item in category.items.all()]
|
||||
potential_discount_items = {
|
||||
item.pk: (max_count, discount_rule)
|
||||
for subevent_id, item, max_count, discount_rule in self._potential_discounts_by_subevent_and_item_for_current_cart
|
||||
if max_count > 0 and item.pk in my_item_pks and item.is_available() and (subevent_id == filter_subevent_id or subevent_id is None)
|
||||
}
|
||||
return category.items.filter(pk__in=potential_discount_items), potential_discount_items
|
||||
|
||||
@cached_property
|
||||
def _potential_discounts_by_subevent_and_item_for_current_cart(self):
|
||||
potential_discounts_by_cartpos = defaultdict(list)
|
||||
|
||||
from ..services.pricing import apply_discounts
|
||||
self._discounted_prices = apply_discounts(
|
||||
self.event,
|
||||
self.sales_channel,
|
||||
[
|
||||
(cp.item_id, cp.subevent_id, cp.line_price_gross, bool(cp.addon_to), cp.is_bundled,
|
||||
cp.listed_price - cp.price_after_voucher)
|
||||
for cp in self.cartpositions
|
||||
],
|
||||
collect_potential_discounts=potential_discounts_by_cartpos
|
||||
)
|
||||
|
||||
# flatten potential_discounts_by_cartpos (a dict of lists of potential discounts) into a set of potential discounts
|
||||
# (which is technically stored as a dict, but we use it as an OrderedSet here)
|
||||
potential_discount_set = dict.fromkeys(
|
||||
info for lst in potential_discounts_by_cartpos.values() for info in lst)
|
||||
|
||||
# sum up the max_counts and pass them on (also pass on the discount_rules so we can calculate actual discounted prices later):
|
||||
# group by benefit product
|
||||
# - max_count for product: sum up max_counts
|
||||
# - discount_rule for product: take first discount_rule
|
||||
|
||||
def discount_info(subevent_id, item, infos_for_item):
|
||||
infos_for_item = list(infos_for_item)
|
||||
return (
|
||||
subevent_id,
|
||||
item,
|
||||
sum(max_count for (subevent_id, item, discount_rule, max_count, i) in infos_for_item),
|
||||
next(discount_rule for (subevent_id, item, discount_rule, max_count, i) in infos_for_item),
|
||||
)
|
||||
|
||||
return [
|
||||
discount_info(subevent_id, item, infos_for_item) for (subevent_id, item), infos_for_item in
|
||||
groupby(
|
||||
sorted(
|
||||
(
|
||||
(subevent_id, item, discount_rule, max_count, i)
|
||||
for (discount_rule, max_count, i, subevent_id) in potential_discount_set.keys()
|
||||
for item in discount_rule.benefit_limit_products.all()
|
||||
),
|
||||
key=lambda tup: (tup[0], tup[1].pk)
|
||||
),
|
||||
lambda tup: (tup[0], tup[1]))
|
||||
]
|
||||
|
||||
def _prepare_items(self, subevent, items_qs, discount_info):
|
||||
items, _btn = get_grouped_items(
|
||||
self.event,
|
||||
subevent=subevent,
|
||||
voucher=None,
|
||||
channel=self.sales_channel,
|
||||
base_qs=items_qs,
|
||||
allow_addons=False,
|
||||
allow_cross_sell=True,
|
||||
memberships=(
|
||||
self.customer.usable_memberships(
|
||||
for_event=subevent or self.event,
|
||||
testmode=self.event.testmode
|
||||
)
|
||||
if self.customer else None
|
||||
),
|
||||
)
|
||||
new_items = list()
|
||||
for item in items:
|
||||
max_count = inf
|
||||
if item.pk in discount_info:
|
||||
(max_count, discount_rule) = discount_info[item.pk]
|
||||
|
||||
# only benefit_only_apply_to_cheapest_n_matches discounted items have a max_count, all others get 'inf'
|
||||
if not max_count:
|
||||
max_count = inf
|
||||
|
||||
# calculate discounted price
|
||||
if discount_rule and discount_rule.benefit_discount_matching_percent > 0:
|
||||
if not item.has_variations:
|
||||
item.original_price = item.original_price or item.display_price
|
||||
previous_price = item.display_price
|
||||
new_price = (
|
||||
previous_price * (
|
||||
(Decimal('100.00') - discount_rule.benefit_discount_matching_percent) / Decimal('100.00'))
|
||||
)
|
||||
item.display_price = new_price
|
||||
else:
|
||||
# discounts always match "whole" items, not specific variations -> we apply the discount to all
|
||||
# available variations of the item
|
||||
for var in item.available_variations:
|
||||
var.original_price = var.original_price or var.display_price
|
||||
previous_price = var.display_price
|
||||
new_price = (
|
||||
previous_price * (
|
||||
(Decimal('100.00') - discount_rule.benefit_discount_matching_percent) / Decimal('100.00'))
|
||||
)
|
||||
var.display_price = new_price
|
||||
|
||||
if not item.has_variations:
|
||||
# reduce order_max by number of items already in cart (prevent recommending a product the user can't add anyway)
|
||||
item.order_max = min(
|
||||
item.order_max - sum(1 for pos in self.cartpositions if pos.item_id == item.pk),
|
||||
max_count
|
||||
)
|
||||
if item.order_max > 0:
|
||||
new_items.append(item)
|
||||
else:
|
||||
new_vars = list()
|
||||
for var in item.available_variations:
|
||||
# reduce order_max by number of items already in cart (prevent recommending a product the user can't add anyway)
|
||||
var.order_max = min(
|
||||
var.order_max - sum(1 for pos in self.cartpositions if pos.item_id == item.pk and pos.variation_id == var.pk),
|
||||
max_count
|
||||
)
|
||||
if var.order_max > 0:
|
||||
new_vars.append(var)
|
||||
if len(new_vars):
|
||||
item.available_variations = new_vars
|
||||
new_items.append(item)
|
||||
|
||||
return new_items
|
||||
@@ -58,7 +58,6 @@ from django.core.mail import (
|
||||
from django.core.mail.message import SafeMIMEText
|
||||
from django.db import transaction
|
||||
from django.template.loader import get_template
|
||||
from django.utils.html import escape
|
||||
from django.utils.timezone import now, override
|
||||
from django.utils.translation import gettext as _, pgettext
|
||||
from django_scopes import scope, scopes_disabled
|
||||
@@ -110,22 +109,6 @@ def clean_sender_name(sender_name: str) -> str:
|
||||
return sender_name
|
||||
|
||||
|
||||
def prefix_subject(settings_holder, subject, highlight=False):
|
||||
prefix = settings_holder.settings.get('mail_prefix')
|
||||
if prefix and prefix.startswith('[') and prefix.endswith(']'):
|
||||
prefix = prefix[1:-1]
|
||||
if prefix:
|
||||
prefix = f"[{prefix}]"
|
||||
if highlight:
|
||||
prefix = '<span class="placeholder" title="{}">{}</span>'.format(
|
||||
_('This prefix has been set in your event or organizer settings.'),
|
||||
escape(prefix)
|
||||
)
|
||||
|
||||
subject = f"{prefix} {subject}"
|
||||
return subject
|
||||
|
||||
|
||||
def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, LazyI18nString],
|
||||
context: Dict[str, Any] = None, event: Event = None, locale: str = None, order: Order = None,
|
||||
position: OrderPosition = None, *, headers: dict = None, sender: str = None, organizer: Organizer = None,
|
||||
@@ -257,7 +240,11 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
||||
and settings_holder.settings.contact_mail and not headers.get('Reply-To'):
|
||||
headers['Reply-To'] = settings_holder.settings.contact_mail
|
||||
|
||||
subject = prefix_subject(settings_holder, subject)
|
||||
prefix = settings_holder.settings.get('mail_prefix')
|
||||
if prefix and prefix.startswith('[') and prefix.endswith(']'):
|
||||
prefix = prefix[1:-1]
|
||||
if prefix:
|
||||
subject = "[%s] %s" % (prefix, subject)
|
||||
|
||||
body_plain += "\r\n\r\n-- \r\n"
|
||||
|
||||
@@ -301,7 +288,7 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
|
||||
order.event, 'presale:event.order.open', kwargs={
|
||||
'order': order.code,
|
||||
'secret': order.secret,
|
||||
'hash': order.email_confirm_secret()
|
||||
'hash': order.email_confirm_hash()
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -262,7 +262,7 @@ def base_placeholders(sender, **kwargs):
|
||||
'presale:event.order.open', kwargs={
|
||||
'order': order.code,
|
||||
'secret': order.secret,
|
||||
'hash': order.email_confirm_secret()
|
||||
'hash': order.email_confirm_hash()
|
||||
}
|
||||
), lambda event: build_absolute_uri(
|
||||
event,
|
||||
@@ -443,7 +443,7 @@ def base_placeholders(sender, **kwargs):
|
||||
'organizer': event.organizer.slug,
|
||||
'order': order.code,
|
||||
'secret': order.secret,
|
||||
'hash': order.email_confirm_secret(),
|
||||
'hash': order.email_confirm_hash(),
|
||||
}),
|
||||
)
|
||||
for order in orders
|
||||
|
||||
@@ -20,9 +20,8 @@
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from decimal import Decimal
|
||||
from typing import List, Optional, Tuple, Union
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from django import forms
|
||||
from django.db.models import Q
|
||||
@@ -32,7 +31,6 @@ from pretix.base.models import (
|
||||
AbstractPosition, InvoiceAddress, Item, ItemAddOn, ItemVariation,
|
||||
SalesChannel, Voucher,
|
||||
)
|
||||
from pretix.base.models.discount import Discount, PositionInfo
|
||||
from pretix.base.models.event import Event, SubEvent
|
||||
from pretix.base.models.tax import TAXED_ZERO, TaxedPrice, TaxRule
|
||||
from pretix.base.timemachine import time_machine_now
|
||||
@@ -157,22 +155,14 @@ def get_line_price(price_after_voucher: Decimal, custom_price_input: Decimal, cu
|
||||
return price
|
||||
|
||||
|
||||
def apply_discounts(event: Event, sales_channel: Union[str, SalesChannel],
|
||||
positions: List[Tuple[int, Optional[int], Decimal, bool, bool, Decimal]],
|
||||
collect_potential_discounts: Optional[defaultdict]=None) -> List[Tuple[Decimal, Optional[Discount]]]:
|
||||
def apply_discounts(event: Event, sales_channel: str,
|
||||
positions: List[Tuple[int, Optional[int], Decimal, bool, bool]]) -> List[Decimal]:
|
||||
"""
|
||||
Applies any dynamic discounts to a cart
|
||||
|
||||
:param event: Event the cart belongs to
|
||||
:param sales_channel: Sales channel the cart was created with
|
||||
:param positions: Tuple of the form ``(item_id, subevent_id, line_price_gross, is_addon_to, is_bundled, voucher_discount)``
|
||||
:param collect_potential_discounts: If a `defaultdict(list)` is supplied, all discounts that could be applied to the cart
|
||||
based on the "consumed" items, but lack matching "benefitting" items will be collected therein.
|
||||
The dict will contain a mapping from index in the `positions` list of the item that could be consumed, to a list
|
||||
of tuples describing the discounts that could be applied in the form `(discount, max_count, grouping_id)`.
|
||||
`max_count` is either the maximum number of benefitting items that the discount would apply to, or `inf` if that number
|
||||
is not limited. The `grouping_id` can be used to distinguish several occurrences of the same discount.
|
||||
|
||||
:return: A list of ``(new_gross_price, discount)`` tuples in the same order as the input
|
||||
"""
|
||||
if isinstance(sales_channel, SalesChannel):
|
||||
@@ -187,10 +177,10 @@ def apply_discounts(event: Event, sales_channel: Union[str, SalesChannel],
|
||||
).prefetch_related('condition_limit_products', 'benefit_limit_products').order_by('position', 'pk')
|
||||
for discount in discount_qs:
|
||||
result = discount.apply({
|
||||
idx: PositionInfo(item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount)
|
||||
idx: (item_id, subevent_id, line_price_gross, is_addon_to, voucher_discount)
|
||||
for idx, (item_id, subevent_id, line_price_gross, is_addon_to, is_bundled, voucher_discount) in enumerate(positions)
|
||||
if not is_bundled and idx not in new_prices
|
||||
}, collect_potential_discounts)
|
||||
})
|
||||
for k in result.keys():
|
||||
result[k] = (result[k], discount)
|
||||
new_prices.update(result)
|
||||
|
||||
@@ -53,7 +53,7 @@ def vouchers_send(event: Event, vouchers: list, subject: str, message: str, reci
|
||||
v.tag = r.get('tag')
|
||||
if v.comment:
|
||||
v.comment += '\n\n'
|
||||
v.comment += gettext('The voucher has been sent to {recipient}.').format(recipient=r['email'])
|
||||
v.comment = gettext('The voucher has been sent to {recipient}.').format(recipient=r['email'])
|
||||
logs.append(v.log_action(
|
||||
'pretix.voucher.sent',
|
||||
user=user,
|
||||
|
||||
@@ -571,7 +571,7 @@ DEFAULTS = {
|
||||
'form_class': I18nFormField,
|
||||
'serializer_class': I18nField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Custom recipient field label"),
|
||||
label=_("Custom recipient field"),
|
||||
widget=I18nTextInput,
|
||||
help_text=_("If you want to add a custom text field, e.g. for a country-specific registration number, to "
|
||||
"your invoice address form, please fill in the label here. This label will both be used for "
|
||||
@@ -580,18 +580,6 @@ DEFAULTS = {
|
||||
"The field will not be required.")
|
||||
)
|
||||
},
|
||||
'invoice_address_custom_field_helptext': {
|
||||
'default': '',
|
||||
'type': LazyI18nString,
|
||||
'form_class': I18nFormField,
|
||||
'serializer_class': I18nField,
|
||||
'form_kwargs': dict(
|
||||
label=_("Custom recipient field help text"),
|
||||
widget=I18nTextInput,
|
||||
help_text=_("If you use the custom recipient field, you can specify a help text which will be displayed "
|
||||
"underneath the field. It will not be displayed on the invoice.")
|
||||
)
|
||||
},
|
||||
'invoice_address_vatid': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
@@ -1307,8 +1295,7 @@ DEFAULTS = {
|
||||
'form_kwargs': dict(
|
||||
label=_("Show event times and dates on the ticket shop"),
|
||||
help_text=_("If disabled, no date or time will be shown on the ticket shop's front page. This settings "
|
||||
"also affects a few other locations, however it should not be expected that the date of the "
|
||||
"event is shown nowhere to users."),
|
||||
"does however not affect the display in other locations."),
|
||||
)
|
||||
},
|
||||
'show_date_to': {
|
||||
|
||||
@@ -838,12 +838,3 @@ is given as the first argument.
|
||||
|
||||
The ``sender`` keyword argument will contain the organizer.
|
||||
"""
|
||||
|
||||
device_info_updated = django.dispatch.Signal()
|
||||
"""
|
||||
Arguments: ``old_device``, ``new_device``
|
||||
|
||||
This signal is sent out each time the information for a Device is modified.
|
||||
Both the original and updated versions of the Device are included to allow
|
||||
receivers to see what has been updated.
|
||||
"""
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
</tr>
|
||||
</table>
|
||||
<div class="order-button">
|
||||
<a href="{% abseventurl event "presale:event.order.open" hash=order.email_confirm_secret order=order.code secret=order.secret %}" class="button">
|
||||
<a href="{% abseventurl event "presale:event.order.open" hash=order.email_confirm_hash order=order.code secret=order.secret %}" class="button">
|
||||
{% trans "View order details" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -103,7 +103,7 @@ def timeline_for_event(event, subevent=None):
|
||||
tl.append(TimelineEvent(
|
||||
event=event, subevent=subevent,
|
||||
datetime=rd.datetime(ev),
|
||||
description=pgettext_lazy('timeline', 'Customers can no longer modify their order information'),
|
||||
description=pgettext_lazy('timeline', 'Customers can no longer modify their orders'),
|
||||
edit_url=ev_edit_url
|
||||
))
|
||||
|
||||
@@ -159,18 +159,6 @@ def timeline_for_event(event, subevent=None):
|
||||
})
|
||||
))
|
||||
|
||||
rd = event.settings.get('change_allow_user_until', as_type=RelativeDateWrapper)
|
||||
if rd and event.settings.change_allow_user_until:
|
||||
tl.append(TimelineEvent(
|
||||
event=event, subevent=subevent,
|
||||
datetime=rd.datetime(ev),
|
||||
description=pgettext_lazy('timeline', 'Customers can no longer make changes to their orders'),
|
||||
edit_url=reverse('control:event.settings.cancel', kwargs={
|
||||
'event': event.slug,
|
||||
'organizer': event.organizer.slug
|
||||
})
|
||||
))
|
||||
|
||||
rd = event.settings.get('waiting_list_auto_disable', as_type=RelativeDateWrapper)
|
||||
if rd and event.settings.waiting_list_enabled:
|
||||
tl.append(TimelineEvent(
|
||||
|
||||
@@ -30,9 +30,7 @@ from celery import states
|
||||
from celery.result import AsyncResult
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import (
|
||||
BadRequest, PermissionDenied, ValidationError,
|
||||
)
|
||||
from django.core.exceptions import PermissionDenied, ValidationError
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from django.db import transaction
|
||||
from django.http import HttpResponse, JsonResponse, QueryDict
|
||||
@@ -133,8 +131,6 @@ class AsyncMixin:
|
||||
return data
|
||||
|
||||
def get_result(self, request):
|
||||
if not request.GET.get('async_id'):
|
||||
raise BadRequest("No async_id given")
|
||||
res = AsyncResult(request.GET.get('async_id'))
|
||||
if 'ajax' in self.request.GET:
|
||||
return JsonResponse(self._return_ajax_result(res, timeout=0.25))
|
||||
@@ -144,12 +140,7 @@ class AsyncMixin:
|
||||
return self.success(res.info)
|
||||
else:
|
||||
return self.error(res.info)
|
||||
state, info = res.state, res.info
|
||||
return render(request, 'pretixpresale/waiting.html', {
|
||||
'started': state in ('PROGRESS', 'STARTED'),
|
||||
'percentage': info.get('value', 0) if isinstance(info, dict) else 0,
|
||||
'steps': info.get('steps', []) if isinstance(info, dict) else None,
|
||||
})
|
||||
return render(request, 'pretixpresale/waiting.html')
|
||||
|
||||
def success(self, value):
|
||||
smes = self.get_success_message(value)
|
||||
@@ -217,8 +208,6 @@ class AsyncAction(AsyncMixin):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if 'async_id' in request.GET and settings.HAS_CELERY:
|
||||
if not request.GET.get('async_id'):
|
||||
raise BadRequest("No async_id given")
|
||||
return self.get_result(request)
|
||||
return self.http_method_not_allowed(request)
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ import sys
|
||||
from importlib import import_module
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.db.models import Q
|
||||
from django.urls import Resolver404, get_script_prefix, resolve
|
||||
from django.utils.translation import get_language
|
||||
@@ -153,8 +152,6 @@ def _default_context(request):
|
||||
ctx['warning_update_available'] = True
|
||||
if not gs.settings.update_check_ack and 'runserver' not in sys.argv:
|
||||
ctx['warning_update_check_active'] = True
|
||||
if not cache.get('pretix_runperiodic_executed') and not settings.DEBUG:
|
||||
ctx['warning_cronjob'] = True
|
||||
|
||||
ctx['ie_deprecation_warning'] = 'MSIE' in request.headers.get('User-Agent', '') or 'Trident/' in request.headers.get('User-Agent', '')
|
||||
|
||||
|
||||
@@ -844,7 +844,6 @@ class InvoiceSettingsForm(EventSettingsValidationMixin, SettingsForm):
|
||||
'invoice_address_company_required',
|
||||
'invoice_address_beneficiary',
|
||||
'invoice_address_custom_field',
|
||||
'invoice_address_custom_field_helptext',
|
||||
'invoice_name_required',
|
||||
'invoice_address_not_asked_free',
|
||||
'invoice_include_free',
|
||||
@@ -1144,12 +1143,12 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm):
|
||||
widget=I18nTextInput,
|
||||
)
|
||||
mail_subject_order_incomplete_payment = I18nFormField(
|
||||
label=_("Subject (if an incomplete payment was received)"),
|
||||
label=_("Subject"),
|
||||
required=False,
|
||||
widget=I18nTextInput,
|
||||
)
|
||||
mail_text_order_incomplete_payment = I18nFormField(
|
||||
label=_("Text (if an incomplete payment was received)"),
|
||||
label=_("Text"),
|
||||
required=False,
|
||||
widget=I18nMarkdownTextarea,
|
||||
help_text=_("This email only applies to payment methods that can receive incomplete payments, "
|
||||
|
||||
@@ -40,8 +40,7 @@ from urllib.parse import urlencode
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.models import Max, Q
|
||||
from django.forms import ChoiceField, RadioSelect
|
||||
from django.db.models import Max
|
||||
from django.forms.formsets import DELETION_FIELD_NAME
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
@@ -80,67 +79,11 @@ class CategoryForm(I18nModelForm):
|
||||
'name',
|
||||
'internal_name',
|
||||
'description',
|
||||
'cross_selling_condition',
|
||||
'cross_selling_match_products',
|
||||
'is_addon'
|
||||
]
|
||||
widgets = {
|
||||
'description': I18nMarkdownTextarea,
|
||||
'cross_selling_condition': RadioSelect,
|
||||
}
|
||||
field_classes = {
|
||||
'cross_selling_match_products': SafeModelMultipleChoiceField,
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
tpl = '{} <span class="text-muted">{}</span>'
|
||||
self.fields['category_type'] = ChoiceField(widget=RadioSelect, choices=(
|
||||
('normal', mark_safe(tpl.format(
|
||||
_('Normal category'),
|
||||
_('Products in this category are regular products displayed on the front page.')
|
||||
)),),
|
||||
('addon', mark_safe(tpl.format(
|
||||
_('Add-on product category'),
|
||||
_('Products in this category are add-on products and can only be bought as add-ons.')
|
||||
)),),
|
||||
('only', mark_safe(tpl.format(
|
||||
_('Cross-selling category'),
|
||||
_('Products in this category are regular products, but are only shown in the cross-selling step, '
|
||||
'according to the configuration below.')
|
||||
)),),
|
||||
('both', mark_safe(tpl.format(
|
||||
_('Normal + cross-selling category'),
|
||||
_('Products in this category are regular products displayed on the front page, but are additionally '
|
||||
'shown in the cross-selling step, according to the configuration below.')
|
||||
)),),
|
||||
))
|
||||
self.fields['category_type'].initial = self.instance.category_type
|
||||
|
||||
self.fields['cross_selling_condition'].widget.attrs['data-display-dependency'] = '#id_category_type_2,#id_category_type_3'
|
||||
self.fields['cross_selling_condition'].widget.attrs['data-disable-dependent'] = 'true'
|
||||
self.fields['cross_selling_condition'].widget.choices = self.fields['cross_selling_condition'].widget.choices[1:]
|
||||
self.fields['cross_selling_condition'].required = False
|
||||
|
||||
self.fields['cross_selling_match_products'].widget = forms.CheckboxSelectMultiple(
|
||||
attrs={
|
||||
'class': 'scrolling-multiple-choice',
|
||||
'data-display-dependency': '#id_cross_selling_condition_2'
|
||||
}
|
||||
)
|
||||
self.fields['cross_selling_match_products'].queryset = self.event.items.filter(
|
||||
# don't show products which are only visible in addon/cross-sell step themselves
|
||||
Q(category__isnull=True) | Q(
|
||||
Q(category__is_addon=False) & Q(Q(category__cross_selling_mode='both') | Q(category__cross_selling_mode__isnull=True))
|
||||
)
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
d = super().clean()
|
||||
if d.get('category_type') == 'only' or d.get('category_type') == 'both':
|
||||
if not d.get('cross_selling_condition'):
|
||||
raise ValidationError({'cross_selling_condition': [_('This field is required')]})
|
||||
self.instance.category_type = d.get('category_type')
|
||||
return d
|
||||
|
||||
|
||||
class QuestionForm(I18nModelForm):
|
||||
|
||||
@@ -239,14 +239,11 @@ class VoucherForm(I18nModelForm):
|
||||
self.instance.event, self.instance.quota, self.instance.item, self.instance.variation
|
||||
)
|
||||
Voucher.clean_voucher_code(data, self.instance.event, self.instance.pk)
|
||||
if 'seat' in self.fields:
|
||||
if data.get('seat'):
|
||||
self.instance.seat = Voucher.clean_seat_id(
|
||||
data, self.instance.item, self.instance.quota, self.instance.event, self.instance.pk
|
||||
)
|
||||
self.instance.item = self.instance.seat.product
|
||||
else:
|
||||
self.instance.seat = None
|
||||
if 'seat' in self.fields and data.get('seat'):
|
||||
self.instance.seat = Voucher.clean_seat_id(
|
||||
data, self.instance.item, self.instance.quota, self.instance.event, self.instance.pk
|
||||
)
|
||||
self.instance.item = self.instance.seat.product
|
||||
|
||||
voucher_form_validation.send(sender=self.instance.event, form=self, data=data)
|
||||
|
||||
|
||||
@@ -421,14 +421,6 @@
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if warning_cronjob %}
|
||||
<div class="alert alert-warning">
|
||||
{% blocktrans trimmed %}
|
||||
The cronjob component of pretix was not executed in the last hours. Please check that
|
||||
you have completed all installation steps and your cronjob is executed correctly.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if debug_warning %}
|
||||
<div class="alert alert-danger">
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
{% bootstrap_field form.invoice_address_beneficiary layout="control" %}
|
||||
{% bootstrap_field form.invoice_address_not_asked_free layout="control" %}
|
||||
{% bootstrap_field form.invoice_address_custom_field layout="control" %}
|
||||
{% bootstrap_field form.invoice_address_custom_field_helptext layout="control" %}
|
||||
{% bootstrap_field form.invoice_address_explanation_text layout="control" %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
{% bootstrap_field form.eu_reverse_charge layout="control" %}
|
||||
{% bootstrap_field form.home_country layout="control" %}
|
||||
{% bootstrap_field form.keep_gross_if_rate_changes layout="control" %}
|
||||
<h3>{% trans "Custom rules" %}</h3>
|
||||
<h3>{% trans "Custom taxation rules" %}</h3>
|
||||
<div class="alert alert-warning">
|
||||
{% blocktrans trimmed %}
|
||||
These settings are intended for professional users with very specific taxation situations.
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Product categories" %}</th>
|
||||
<th>{% trans "Category type" %}</th>
|
||||
<th class="action-col-2"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -41,9 +40,6 @@
|
||||
<td>
|
||||
<strong><a href="{% url "control:event.items.categories.edit" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}">{{ c.internal_name|default:c.name }}</a></strong>
|
||||
</td>
|
||||
<td>
|
||||
{{ c.get_category_type_display }}
|
||||
</td>
|
||||
<td class="text-right flip">
|
||||
<button title="{% trans "Move up" %}" formaction="{% url "control:event.items.categories.up" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}" class="btn btn-default btn-sm sortable-up"{% if forloop.counter0 == 0 and not page_obj.has_previous %} disabled{% endif %}><i class="fa fa-arrow-up"></i></button>
|
||||
<button title="{% trans "Move down" %}" formaction="{% url "control:event.items.categories.down" organizer=request.event.organizer.slug event=request.event.slug category=c.id %}" class="btn btn-default btn-sm sortable-down"{% if forloop.revcounter0 == 0 and not page_obj.has_next %} disabled{% endif %}><i class="fa fa-arrow-down"></i></button>
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
{% bootstrap_field form.internal_name layout="control" %}
|
||||
</div>
|
||||
{% bootstrap_field form.description layout="control" %}
|
||||
{% bootstrap_field form.category_type layout="control" horizontal_field_class="big-radio-wrapper col-lg-9" %}
|
||||
{% bootstrap_field form.cross_selling_condition layout="control" horizontal_field_class="col-lg-9" %}
|
||||
{% bootstrap_field form.cross_selling_match_products layout="control" %}
|
||||
{% bootstrap_field form.is_addon layout="control" %}
|
||||
</fieldset>
|
||||
</div>
|
||||
{% if category %}
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
{% endif %}
|
||||
{{ i.default_price|money:request.event.currency }}
|
||||
{% if i.original_price %}<strike class="text-muted">{{ i.original_price|money:request.event.currency }}</strike>{% endif %}
|
||||
{% if i.tax_rule %}
|
||||
{% if i.tax_rule and i.default_price %}
|
||||
<br/>
|
||||
<small class="text-muted">
|
||||
{% if not i.tax_rule.price_includes_tax %}
|
||||
|
||||
@@ -13,52 +13,31 @@
|
||||
{% trans "Edit question" %}
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{% trans "Filter" %}</h3>
|
||||
</div>
|
||||
<form class="panel-body filter-form" action="" method="get">
|
||||
<div class="row">
|
||||
<div class="col-lg-2 col-sm-6 col-xs-6">
|
||||
<select name="status" class="form-control">
|
||||
<option value="" {% if request.GET.status == "" %}selected="selected"{% endif %}>{% trans "All orders" %}</option>
|
||||
<option value="p" {% if request.GET.status == "p" %}selected="selected"{% endif %}>{% trans "Paid" %}</option>
|
||||
<option value="pv" {% if request.GET.status == "pv" %}selected="selected"{% endif %}>{% trans "Paid or confirmed" %}</option>
|
||||
<option value="n" {% if request.GET.status == "n" %}selected="selected"{% endif %}>{% trans "Pending" %}</option>
|
||||
<option value="np" {% if request.GET.status == "np" or "status" not in request.GET %}selected="selected"{% endif %}>{% trans "Pending or paid" %}</option>
|
||||
<option value="o" {% if request.GET.status == "o" %}selected="selected"{% endif %}>{% trans "Pending (overdue)" %}</option>
|
||||
<option value="e" {% if request.GET.status == "e" %}selected="selected"{% endif %}>{% trans "Expired" %}</option>
|
||||
<option value="ne" {% if request.GET.status == "ne" %}selected="selected"{% endif %}>{% trans "Pending or expired" %}</option>
|
||||
<option value="c" {% if request.GET.status == "c" %}selected="selected"{% endif %}>{% trans "Canceled" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-lg-5 col-sm-6 col-xs-6">
|
||||
<select name="item" class="form-control">
|
||||
<option value="">{% trans "All products" %}</option>
|
||||
{% for item in items %}
|
||||
<option value="{{ item.id }}"
|
||||
{% if request.GET.item|add:0 == item.id %}selected="selected"{% endif %}>
|
||||
{{ item.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% if request.event.has_subevents %}
|
||||
<div class="col-lg-5 col-sm-6 col-xs-6">
|
||||
{% include "pretixcontrol/event/fragment_subevent_choice_simple.html" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-primary btn-lg" type="submit">
|
||||
<span class="fa fa-filter"></span>
|
||||
{% trans "Filter" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form class="form-inline helper-display-inline" action="" method="get">
|
||||
<p>
|
||||
<select name="status" class="form-control">
|
||||
<option value="" {% if request.GET.status == "" %}selected="selected"{% endif %}>{% trans "All orders" %}</option>
|
||||
<option value="p" {% if request.GET.status == "p" %}selected="selected"{% endif %}>{% trans "Paid" %}</option>
|
||||
<option value="pv" {% if request.GET.status == "pv" %}selected="selected"{% endif %}>{% trans "Paid or confirmed" %}</option>
|
||||
<option value="n" {% if request.GET.status == "n" %}selected="selected"{% endif %}>{% trans "Pending" %}</option>
|
||||
<option value="np" {% if request.GET.status == "np" or "status" not in request.GET %}selected="selected"{% endif %}>{% trans "Pending or paid" %}</option>
|
||||
<option value="o" {% if request.GET.status == "o" %}selected="selected"{% endif %}>{% trans "Pending (overdue)" %}</option>
|
||||
<option value="e" {% if request.GET.status == "e" %}selected="selected"{% endif %}>{% trans "Expired" %}</option>
|
||||
<option value="ne" {% if request.GET.status == "ne" %}selected="selected"{% endif %}>{% trans "Pending or expired" %}</option>
|
||||
<option value="c" {% if request.GET.status == "c" %}selected="selected"{% endif %}>{% trans "Canceled" %}</option>
|
||||
</select>
|
||||
<select name="item" class="form-control">
|
||||
<option value="">{% trans "All products" %}</option>
|
||||
{% for item in items %}
|
||||
<option value="{{ item.id }}"
|
||||
{% if request.GET.item|add:0 == item.id %}selected="selected"{% endif %}>
|
||||
{{ item.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button class="btn btn-primary" type="submit">{% trans "Filter" %}</button>
|
||||
</p>
|
||||
</form>
|
||||
<div class="row" id="question-stats">
|
||||
{% if not stats %}
|
||||
<div class="empty-collection col-md-10 col-xs-12">
|
||||
@@ -96,7 +75,7 @@
|
||||
{% for stat in stats %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status={{ request.GET.status|default:"np" }}&item={{ request.GET.item }}&subevent={{ request.GET.subevent }}&question={{ question.pk }}&answer={{ stat.alink|default:stat.answer|urlencode }}">
|
||||
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status={{ request.GET.status|default:"np" }}&item={{ request.GET.item }}&question={{ question.pk }}&answer={{ stat.alink|default:stat.answer|urlencode }}">
|
||||
{{ stat.answer }}
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@@ -102,24 +102,16 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for t in tokens %}
|
||||
{% for t in team.active_tokens %}
|
||||
<tr>
|
||||
<td {% if not t.active %}class="text-muted"{% endif %}>
|
||||
{% if not t.active %}
|
||||
<del>
|
||||
{% endif %}
|
||||
<td>
|
||||
{{ t.name }}
|
||||
{% if not t.active %}
|
||||
</del>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-right flip">
|
||||
{% if t.active %}
|
||||
<button type="submit" name="remove-token" value="{{ t.id }}"
|
||||
class="btn btn-danger btn-sm btn-block">
|
||||
<i class="fa fa-times"></i> {% trans "Remove" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type="submit" name="remove-token" value="{{ t.id }}"
|
||||
class="btn btn-danger btn-sm btn-block">
|
||||
<i class="fa fa-times"></i> {% trans "Remove" %}
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
@@ -21,11 +21,6 @@
|
||||
{% trans "The waiting list is no longer active for this event. The waiting list no longer affects quotas and no longer notifies waiting users." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if request.event.settings.hide_sold_out %}
|
||||
<div class="alert alert-warning">
|
||||
{% trans "According to your event settings, sold out products are hidden from customers. This way, customers will not be able to discover the waiting list." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
{% if 'can_change_orders' in request.eventpermset %}
|
||||
<form method="post" class="col-md-6"
|
||||
|
||||
@@ -94,9 +94,7 @@ def process_login(request, user, keep_logged_in):
|
||||
pretix_successful_logins.inc(1)
|
||||
handle_login_source(user, request)
|
||||
auth_login(request, user)
|
||||
t = int(time.time())
|
||||
request.session['pretix_auth_login_time'] = t
|
||||
request.session['pretix_auth_last_used'] = t
|
||||
request.session['pretix_auth_login_time'] = int(time.time())
|
||||
if next_url and url_has_allowed_host_and_scheme(next_url, allowed_hosts=None):
|
||||
return redirect_to_url(next_url)
|
||||
return redirect('control:index')
|
||||
|
||||
@@ -39,7 +39,7 @@ from django.contrib import messages
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db import transaction
|
||||
from django.db.models import Exists, Max, OuterRef, Prefetch, Q, Subquery
|
||||
from django.http import Http404, HttpResponseNotAllowed, HttpResponseRedirect
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
@@ -193,9 +193,6 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList
|
||||
class CheckInListBulkRevertConfirmView(CheckInListQueryMixin, EventPermissionRequiredMixin, TemplateView):
|
||||
template_name = "pretixcontrol/checkin/bulk_revert_confirm.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return HttpResponseNotAllowed(permitted_methods=["POST"])
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.list = get_object_or_404(self.request.event.checkin_lists.all(), pk=kwargs.get("list"))
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
@@ -99,7 +99,6 @@ from ...base.i18n import language
|
||||
from ...base.models.items import (
|
||||
Item, ItemCategory, ItemMetaProperty, Question, Quota,
|
||||
)
|
||||
from ...base.services.mail import prefix_subject
|
||||
from ...base.settings import LazyI18nStringList
|
||||
from ...helpers.compat import CompatDeleteView
|
||||
from ...helpers.format import format_map
|
||||
@@ -748,9 +747,9 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
||||
with language(self.supported_locale[idx], self.request.event.settings.region):
|
||||
try:
|
||||
if k.startswith('mail_subject_'):
|
||||
msgs[self.supported_locale[idx]] = prefix_subject(self.request.event, format_map(
|
||||
msgs[self.supported_locale[idx]] = format_map(
|
||||
bleach.clean(v), self.placeholders(preview_item), raise_on_missing=True
|
||||
), highlight=True)
|
||||
)
|
||||
else:
|
||||
msgs[self.supported_locale[idx]] = markdown_compile_email(
|
||||
format_map(v, self.placeholders(preview_item), raise_on_missing=True)
|
||||
|
||||
@@ -302,8 +302,6 @@ class CategoryCreate(EventPermissionRequiredMixin, CreateView):
|
||||
i = modelcopy(self.copy_from)
|
||||
i.pk = None
|
||||
kwargs['instance'] = i
|
||||
kwargs.setdefault('initial', {})
|
||||
kwargs['initial']['cross_selling_match_products'] = [str(i.pk) for i in self.copy_from.cross_selling_match_products.all()]
|
||||
else:
|
||||
kwargs['instance'] = ItemCategory(event=self.request.event)
|
||||
return kwargs
|
||||
@@ -663,10 +661,6 @@ class QuestionView(EventPermissionRequiredMixin, QuestionMixin, ChartContainingV
|
||||
question=self.object, orderposition__isnull=False,
|
||||
orderposition__order__event=self.request.event
|
||||
)
|
||||
|
||||
if self.request.GET.get("subevent", "") != "":
|
||||
qs = qs.filter(orderposition__subevent=self.request.GET["subevent"])
|
||||
|
||||
s = self.request.GET.get("status", "np")
|
||||
if s != "":
|
||||
if s == 'o':
|
||||
|
||||
@@ -62,9 +62,8 @@ from django.urls import reverse
|
||||
from django.utils import formats
|
||||
from django.utils.formats import date_format, get_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import conditional_escape, escape
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.http import url_has_allowed_host_and_scheme
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.timezone import make_aware, now
|
||||
from django.utils.translation import gettext, gettext_lazy as _, ngettext
|
||||
from django.views.generic import (
|
||||
@@ -95,9 +94,7 @@ from pretix.base.services.invoices import (
|
||||
invoice_qualified, regenerate_invoice,
|
||||
)
|
||||
from pretix.base.services.locking import LockTimeoutException
|
||||
from pretix.base.services.mail import (
|
||||
SendMailException, prefix_subject, render_mail,
|
||||
)
|
||||
from pretix.base.services.mail import SendMailException, render_mail
|
||||
from pretix.base.services.orders import (
|
||||
OrderChangeManager, OrderError, approve_order, cancel_order, deny_order,
|
||||
extend_order, mark_order_expired, mark_order_refunded,
|
||||
@@ -2307,9 +2304,7 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
|
||||
email_content = render_mail(email_template, email_context)
|
||||
if self.request.POST.get('action') == 'preview':
|
||||
self.preview_output = {
|
||||
'subject': mark_safe(_('Subject: {subject}').format(
|
||||
subject=prefix_subject(order.event, escape(email_subject), highlight=True)
|
||||
)),
|
||||
'subject': _('Subject: {subject}').format(subject=email_subject),
|
||||
'html': markdown_compile_email(email_content)
|
||||
}
|
||||
return self.get(self.request, *self.args, **self.kwargs)
|
||||
@@ -2374,9 +2369,7 @@ class OrderPositionSendMail(OrderSendMail):
|
||||
email_content = render_mail(email_template, email_context)
|
||||
if self.request.POST.get('action') == 'preview':
|
||||
self.preview_output = {
|
||||
'subject': mark_safe(_('Subject: {subject}').format(
|
||||
subject=prefix_subject(position.order.event, escape(email_subject), highlight=True))
|
||||
),
|
||||
'subject': _('Subject: {subject}').format(subject=email_subject),
|
||||
'html': markdown_compile_email(email_content)
|
||||
}
|
||||
return self.get(self.request, *self.args, **self.kwargs)
|
||||
|
||||
@@ -90,7 +90,7 @@ from pretix.base.models.orders import CancellationRequest
|
||||
from pretix.base.models.organizer import SalesChannel, TeamAPIToken
|
||||
from pretix.base.payment import PaymentException
|
||||
from pretix.base.services.export import multiexport, scheduled_organizer_export
|
||||
from pretix.base.services.mail import SendMailException, mail, prefix_subject
|
||||
from pretix.base.services.mail import SendMailException, mail
|
||||
from pretix.base.signals import register_multievent_data_exporters
|
||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||
from pretix.base.views.tasks import AsyncAction
|
||||
@@ -351,11 +351,8 @@ class MailSettingsPreview(OrganizerPermissionRequiredMixin, View):
|
||||
if idx in self.supported_locale:
|
||||
with language(self.supported_locale[idx], self.request.organizer.settings.region):
|
||||
if k.startswith('mail_subject_'):
|
||||
msgs[self.supported_locale[idx]] = prefix_subject(
|
||||
self.request.organizer,
|
||||
format_map(bleach.clean(v), self.placeholders(preview_item)),
|
||||
highlight=True,
|
||||
)
|
||||
msgs[self.supported_locale[idx]] = format_map(bleach.clean(v),
|
||||
self.placeholders(preview_item))
|
||||
else:
|
||||
msgs[self.supported_locale[idx]] = markdown_compile_email(
|
||||
format_map(v, self.placeholders(preview_item))
|
||||
@@ -686,24 +683,14 @@ class TeamDeleteView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
|
||||
try:
|
||||
self.object.log_action('pretix.team.deleted', user=self.request.user)
|
||||
self.object.delete()
|
||||
except ProtectedError as e:
|
||||
is_logs = any(isinstance(e, LogEntry) for e in e.protected_objects)
|
||||
if is_logs:
|
||||
messages.error(
|
||||
self.request,
|
||||
_(
|
||||
"The team could not be deleted because the team or one of its API tokens is part of "
|
||||
"historical audit logs."
|
||||
)
|
||||
)
|
||||
else:
|
||||
messages.error(
|
||||
self.request,
|
||||
_(
|
||||
'The team could not be deleted as some constraints (e.g. data created by '
|
||||
'plug-ins) do not allow it.'
|
||||
)
|
||||
except ProtectedError:
|
||||
messages.error(
|
||||
self.request,
|
||||
_(
|
||||
'The team could not be deleted as some constraints (e.g. data created by '
|
||||
'plug-ins) do not allow it.'
|
||||
)
|
||||
)
|
||||
return redirect(success_url)
|
||||
|
||||
messages.success(request, _('The selected team has been deleted.'))
|
||||
@@ -733,7 +720,6 @@ class TeamMemberView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin,
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['add_form'] = self.add_form
|
||||
ctx['add_token_form'] = self.add_token_form
|
||||
ctx['tokens'] = self.object.tokens.order_by("-active", "name", "pk")
|
||||
return ctx
|
||||
|
||||
def _send_invite(self, instance):
|
||||
|
||||
@@ -50,7 +50,7 @@ from django.http import (
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import resolve, reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import escape, format_html
|
||||
from django.utils.html import format_html, escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -64,7 +64,6 @@ from pretix.base.models import (
|
||||
CartPosition, LogEntry, Voucher, WaitingListEntry,
|
||||
)
|
||||
from pretix.base.models.vouchers import generate_codes
|
||||
from pretix.base.services.mail import prefix_subject
|
||||
from pretix.base.services.vouchers import vouchers_send
|
||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||
from pretix.base.views.tasks import AsyncFormView
|
||||
@@ -573,11 +572,7 @@ class VoucherBulkMailPreview(EventPermissionRequiredMixin, View):
|
||||
return HttpResponseBadRequest(_('invalid item'))
|
||||
msgs = {}
|
||||
if "subject" in preview_item:
|
||||
msgs["all"] = prefix_subject(
|
||||
self.request.event,
|
||||
format_map(bleach.clean(request.POST.get(preview_item, "")), self.placeholders(preview_item)),
|
||||
highlight=True
|
||||
)
|
||||
msgs["all"] = format_map(bleach.clean(request.POST.get(preview_item, "")), self.placeholders(preview_item))
|
||||
else:
|
||||
msgs["all"] = markdown_compile_email(
|
||||
format_map(request.POST.get(preview_item), self.placeholders(preview_item))
|
||||
|
||||
@@ -53,14 +53,14 @@ def daterange(df, dt, as_html=False):
|
||||
|
||||
if lng.startswith("de"):
|
||||
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
|
||||
return format_html(base_format, _date(df, "D, j. F Y"))
|
||||
return format_html(base_format, _date(df, "j. F Y"))
|
||||
elif df.year == dt.year and df.month == dt.month:
|
||||
return format_html(base_format, _date(df, "j."), "–", _date(dt, "j. F Y"))
|
||||
elif df.year == dt.year:
|
||||
return format_html(base_format, _date(df, "j. F"), " – ", _date(dt, "j. F Y"))
|
||||
elif lng.startswith("en"):
|
||||
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
|
||||
return format_html(base_format, _date(df, "D, N jS, Y"))
|
||||
return format_html(base_format, _date(df, "N jS, Y"))
|
||||
elif df.year == dt.year and df.month == dt.month:
|
||||
return format_html(base_format, _date(df, "N jS"), " – ", _date(dt, "jS, Y"))
|
||||
elif df.year == dt.year:
|
||||
|
||||
+2106
-2309
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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"
|
||||
@@ -543,56 +543,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
|
||||
@@ -608,54 +604,54 @@ msgstr ""
|
||||
msgid "Unknown error."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+2164
-2438
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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/"
|
||||
@@ -573,60 +573,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "QR الدخول"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr "لا يمكن تحميل ملف PDF الخلفية للأسباب التالية:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "مجموعة من العناصر"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "عنصر نص"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "عنصر نص"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "منطقة باركود"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr "منطقة صورة"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "مدعوم من pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "عنصر"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "تصميم التذكرة"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "فشلت عملية الحفظ."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr "حصل خطأ أثناء رفع ملف PDF الخاص بك، يرجى المحاولة مرة أخرى."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr "هل تريد أن تغادر المحرر دون حفظ التعديلات؟"
|
||||
|
||||
@@ -642,54 +634,54 @@ msgstr "توليد الرسائل …"
|
||||
msgid "Unknown error."
|
||||
msgstr "خطأ غير معروف."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr "اللون يتمتع بتباين كبير وتسهل قراءته!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr "اللون يحظى بتباين معقول ويمكن أن يكون مناسب للقراءة!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr "تباين اللون سيئ للخلفية البيضاء، الرجاء اختيار لون غامق."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr "البحث في الاستفسارات"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "الكل"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "لا شيء"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr "المختارة فقط"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr "قم باستخدم اسم مختلف داخليا"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "اضغط لاغلاق الصفحة"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "لم تقم بحفظ التعديلات!"
|
||||
|
||||
|
||||
+2124
-2401
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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-"
|
||||
@@ -544,56 +544,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Disseny del tiquet"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
|
||||
@@ -609,54 +605,54 @@ msgstr ""
|
||||
msgid "Unknown error."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+2120
-2406
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+0000\n"
|
||||
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
|
||||
"Last-Translator: Michael <michael.happl@gmx.at>\n"
|
||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -564,60 +564,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "Check-in QR kód"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
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:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "Skupina objektů"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "Textový objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Textový objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "Oblast s QR kódem"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr "Oblast obrazu"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Poháněno společností pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Design vstupenky"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "Uložení se nepodařilo."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
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:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr "Opravdu chcete opustit editor bez uložení změn?"
|
||||
|
||||
@@ -633,16 +625,16 @@ msgstr "Vytváření zpráv…"
|
||||
msgid "Unknown error."
|
||||
msgstr "Neznámá chyba."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr "Tato barva má velmi dobrý kontrast a je velmi dobře čitelná!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
"Tato barva má slušný kontrast a pravděpodobně je dostatečně dobře čitelná!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
@@ -650,40 +642,40 @@ msgstr ""
|
||||
"Tato barva je pro text na bílém pozadí špatně kontrastní, zvolte prosím "
|
||||
"tmavší odstín."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr "Hledaný výraz"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Všechny"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "Žádný"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr "Pouze vybrané"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Interně používat jiný název"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "Kliknutím zavřete"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Máte neuložené změny!"
|
||||
|
||||
|
||||
+2111
-2327
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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"
|
||||
@@ -544,56 +544,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
|
||||
@@ -609,54 +605,54 @@ msgstr ""
|
||||
msgid "Unknown error."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+2118
-2395
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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/"
|
||||
@@ -584,62 +584,54 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "Check-in QR"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
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:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppe af objekter"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "Tekstobjekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Tekstobjekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "QR-kode-område"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
#, fuzzy
|
||||
#| msgid "Barcode area"
|
||||
msgid "Image area"
|
||||
msgstr "QR-kode-område"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Drevet af pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Billetdesign"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "Gem fejlede."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
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:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
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?"
|
||||
@@ -656,54 +648,54 @@ msgstr "Opretter beskeder …"
|
||||
msgid "Unknown error."
|
||||
msgstr "Ukendt fejl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "Ingen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "Klik for at lukke"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du har ændringer, der ikke er gemt!"
|
||||
|
||||
|
||||
+2130
-2402
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
||||
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+0000\n"
|
||||
"PO-Revision-Date: 2024-06-30 21:07+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
"de/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7\n"
|
||||
"X-Generator: Weblate 5.6.1\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -559,57 +559,53 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr "abwesend"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "Check-in-QR-Code"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
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:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppe von Objekten"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Text-Objekt (veraltet)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "Text-Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr "Textbox"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "QR-Code-Bereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr "Bildbereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Event-Ticketshop von pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Ticket-Design"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "Speichern fehlgeschlagen."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
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:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
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?"
|
||||
@@ -626,17 +622,17 @@ msgstr "Generiere Nachrichten…"
|
||||
msgid "Unknown error."
|
||||
msgstr "Unbekannter Fehler."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr "Diese Farbe hat einen sehr guten Kontrast und ist sehr gut zu lesen!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
"Diese Farbe hat einen ausreichenden Kontrast und ist wahrscheinlich gut zu "
|
||||
"lesen!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
@@ -644,40 +640,40 @@ msgstr ""
|
||||
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
||||
"Hintergrund. Bitte wählen Sie eine dunklere Farbe."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr "Suchbegriff"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr "Nur ausgewählte"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
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:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr "Ungültige Seitenzahl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Intern einen anderen Namen verwenden"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "Klicken zum Schließen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Sie haben ungespeicherte Änderungen!"
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ AES
|
||||
Absenderadresse
|
||||
Absenderinformation
|
||||
Absendername
|
||||
ABGEKÜNDIGT
|
||||
Admin
|
||||
Adminbereich
|
||||
Affirm
|
||||
@@ -26,7 +25,6 @@ Ausgangsscans
|
||||
ausgeklappt
|
||||
ausgecheckt
|
||||
auswahl
|
||||
Auth
|
||||
Authentication
|
||||
Authenticator
|
||||
Authentifizierungsmechanismus
|
||||
@@ -38,7 +36,6 @@ Bancontact
|
||||
BankID
|
||||
Banking
|
||||
barcodes
|
||||
Baskisch
|
||||
Bcc
|
||||
BCC
|
||||
Beispielevent
|
||||
@@ -82,7 +79,6 @@ Connect
|
||||
Consent
|
||||
Copyleft
|
||||
Cronjob
|
||||
Cross
|
||||
csv
|
||||
Customer
|
||||
CZK
|
||||
@@ -263,7 +259,6 @@ Requests
|
||||
Reservierungszeitraum
|
||||
reverse
|
||||
Revisionssicherheit
|
||||
Revolut
|
||||
rückabgewickelt
|
||||
Rundungsdifferenzen
|
||||
Sa
|
||||
@@ -281,7 +276,6 @@ Scopes
|
||||
sechsstelligen
|
||||
Secret
|
||||
Security
|
||||
Selling
|
||||
SEPA
|
||||
Shirts
|
||||
Signaturverfahren
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
||||
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+0000\n"
|
||||
"PO-Revision-Date: 2024-06-30 21:07+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix-js/de_Informal/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7\n"
|
||||
"X-Generator: Weblate 5.6.1\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -558,57 +558,53 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr "abwesend"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "Check-in-QR-Code"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
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:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "Gruppe von Objekten"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
msgstr "Text-Objekt (veraltet)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "Text-Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr "Textbox"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "QR-Code-Bereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr "Bildbereich"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Event-Ticketshop von pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "Objekt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Ticket-Design"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "Speichern fehlgeschlagen."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
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:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
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?"
|
||||
@@ -625,17 +621,17 @@ msgstr "Generiere Nachrichten…"
|
||||
msgid "Unknown error."
|
||||
msgstr "Unbekannter Fehler."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr "Diese Farbe hat einen sehr guten Kontrast und ist sehr gut zu lesen!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
"Diese Farbe hat einen ausreichenden Kontrast und ist wahrscheinlich gut zu "
|
||||
"lesen!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
@@ -643,40 +639,40 @@ msgstr ""
|
||||
"Diese Farbe hat einen schlechten Kontrast für Text auf einem weißen "
|
||||
"Hintergrund. Bitte wähle eine dunklere Farbe."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr "Suchbegriff"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "Keine"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr "Nur ausgewählte"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
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:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr "Ungültige Seitenzahl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Intern einen anderen Namen verwenden"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "Klicken zum Schließen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du hast ungespeicherte Änderungen!"
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ AES
|
||||
Absenderadresse
|
||||
Absenderinformation
|
||||
Absendername
|
||||
ABGEKÜNDIGT
|
||||
Admin
|
||||
Adminbereich
|
||||
Affirm
|
||||
@@ -26,7 +25,6 @@ Ausgangsscans
|
||||
ausgeklappt
|
||||
ausgecheckt
|
||||
auswahl
|
||||
Auth
|
||||
Authentication
|
||||
Authenticator
|
||||
Authentifizierungsmechanismus
|
||||
@@ -38,7 +36,6 @@ Bancontact
|
||||
BankID
|
||||
Banking
|
||||
barcodes
|
||||
Baskisch
|
||||
Bcc
|
||||
BCC
|
||||
Beispielevent
|
||||
@@ -82,7 +79,6 @@ Connect
|
||||
Consent
|
||||
Copyleft
|
||||
Cronjob
|
||||
Cross
|
||||
csv
|
||||
Customer
|
||||
CZK
|
||||
@@ -263,7 +259,6 @@ Requests
|
||||
Reservierungszeitraum
|
||||
reverse
|
||||
Revisionssicherheit
|
||||
Revolut
|
||||
rückabgewickelt
|
||||
Rundungsdifferenzen
|
||||
Sa
|
||||
@@ -281,7 +276,6 @@ Scopes
|
||||
sechsstelligen
|
||||
Secret
|
||||
Security
|
||||
Selling
|
||||
SEPA
|
||||
Shirts
|
||||
Signaturverfahren
|
||||
|
||||
+2106
-2309
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: 2024-10-15 11:14+0000\n"
|
||||
"POT-Creation-Date: 2024-07-29 10:52+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"
|
||||
@@ -543,56 +543,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
|
||||
@@ -608,54 +604,54 @@ msgstr ""
|
||||
msgid "Unknown error."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+2117
-2393
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+0000\n"
|
||||
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
||||
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
||||
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -593,63 +593,55 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "Έλεγχος QR"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
"Το αρχείο φόντου PDF δεν ήταν δυνατό να φορτωθεί για τον ακόλουθο λόγο:"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "Ομάδα αντικειμένων"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "Αντικείμενο κειμένου"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text box"
|
||||
msgstr "Αντικείμενο κειμένου"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "Περιοχή Barcode"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
#, fuzzy
|
||||
#| msgid "Barcode area"
|
||||
msgid "Image area"
|
||||
msgstr "Περιοχή Barcode"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Υποστηρίζεται από το Pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "Αντικείμενο"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Σχεδιασμός εισιτηρίων"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "Η αποθήκευση απέτυχε."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr "Σφάλμα κατά τη μεταφόρτωση του αρχείου PDF, δοκιμάστε ξανά."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
"Θέλετε πραγματικά να αφήσετε τον επεξεργαστή χωρίς να αποθηκεύσετε τις "
|
||||
@@ -667,18 +659,18 @@ msgstr "Δημιουργία μηνυμάτων …"
|
||||
msgid "Unknown error."
|
||||
msgstr "Άγνωστο σφάλμα."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
"Το χρώμα σας έχει μεγάλη αντίθεση και είναι πολύ εύκολο να το διαβάσετε!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
"Το χρώμα σας έχει αξιοπρεπή αντίθεση και είναι ίσως αρκετά καλό για να "
|
||||
"διαβάσετε!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
@@ -686,40 +678,40 @@ msgstr ""
|
||||
"Το χρώμα σας έχει κακή αντίθεση για κείμενο σε λευκό φόντο, επιλέξτε μια πιο "
|
||||
"σκούρα σκιά."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Όλα"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "Κανένας"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "Κάντε κλικ για να κλείσετε"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+2106
-2309
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: 2024-10-15 11:06+0000\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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"
|
||||
@@ -543,56 +543,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
|
||||
@@ -608,54 +604,54 @@ msgstr ""
|
||||
msgid "Unknown error."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
+3229
-2921
File diff suppressed because it is too large
Load Diff
@@ -7,17 +7,17 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-10-15 11:06+0000\n"
|
||||
"PO-Revision-Date: 2024-10-22 17:00+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/"
|
||||
"pretix-js/es/>\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+0000\n"
|
||||
"PO-Revision-Date: 2024-07-19 08:56+0000\n"
|
||||
"Last-Translator: Reece Needham <nouveaureece@protonmail.com>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/es/>\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7.2\n"
|
||||
"X-Generator: Weblate 5.6.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -556,61 +556,55 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr "ausente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr "QR de Chequeo"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
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:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr "Grupo de objetos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
#, fuzzy
|
||||
#| msgid "Text object"
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr "Objeto de texto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr "Campo de texto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr "Área para código de barras"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr "Área de imagen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr "Proveído por pretix"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr "Objeto"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Diseño del entrada"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr "El guardado falló."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
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:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr "¿Realmente desea salir del editor sin haber guardado sus cambios?"
|
||||
|
||||
@@ -626,17 +620,17 @@ msgstr "Generando mensajes…"
|
||||
msgid "Unknown error."
|
||||
msgstr "Error desconocido."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr "¡Tu color tiene gran contraste y es muy fácil de leer!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
"¡Tu color tiene un contraste decente y es probablemente lo suficientemente "
|
||||
"legible!"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
@@ -644,40 +638,40 @@ msgstr ""
|
||||
"Tu color tiene mal contraste para un texto con fondo blanco, por favor, "
|
||||
"escoge un tono más oscuro."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr "Consultar búsqueda"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr "Ninguno"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr "Solamente seleccionados"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
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:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr "Número de página inválido."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Usar un nombre diferente internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr "Click para cerrar"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "¡Tienes cambios sin guardar!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+4641
-7118
File diff suppressed because it is too large
Load Diff
@@ -3,137 +3,136 @@
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-10-15 11:06+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/"
|
||||
"eu/>\n"
|
||||
"Language: eu\n"
|
||||
"POT-Creation-Date: 2024-07-26 07:19+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"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.7\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:68
|
||||
msgid "Marked as paid"
|
||||
msgstr "Ordaindutzat markatua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:76
|
||||
msgid "Comment:"
|
||||
msgstr "Iruzkina:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
|
||||
msgid "PayPal"
|
||||
msgstr "PayPal"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
|
||||
msgid "Venmo"
|
||||
msgstr "Venmo"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
|
||||
#: pretix/static/pretixpresale/js/walletdetection.js:38
|
||||
msgid "Apple Pay"
|
||||
msgstr "Apple Pay"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
|
||||
msgid "Itaú"
|
||||
msgstr "Itaú"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
|
||||
msgid "PayPal Credit"
|
||||
msgstr "PayPal Credit"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
|
||||
msgid "Credit Card"
|
||||
msgstr "Kreditu txartela"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
|
||||
msgid "PayPal Pay Later"
|
||||
msgstr "PayPal Pay Later"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
|
||||
msgid "iDEAL"
|
||||
msgstr "iDEAL"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
||||
msgid "SEPA Direct Debit"
|
||||
msgstr "SEPA Zuzeneko Zordunketa"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
|
||||
msgid "Bancontact"
|
||||
msgstr "Bancontact"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:44
|
||||
msgid "giropay"
|
||||
msgstr "giropay"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
|
||||
msgid "SOFORT"
|
||||
msgstr "SOFORT"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
|
||||
msgid "eps"
|
||||
msgstr "eps"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
|
||||
msgid "MyBank"
|
||||
msgstr "MyBank"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
|
||||
msgid "Przelewy24"
|
||||
msgstr "Przelewy24"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
|
||||
msgid "Verkkopankki"
|
||||
msgstr "Verkkopankki"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
|
||||
msgid "PayU"
|
||||
msgstr "PayU"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
|
||||
msgid "BLIK"
|
||||
msgstr "BLIK"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
|
||||
msgid "Trustly"
|
||||
msgstr "Trustly"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
|
||||
msgid "Zimpler"
|
||||
msgstr "Zimpler"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
|
||||
msgid "Maxima"
|
||||
msgstr "Maxima"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
|
||||
msgid "OXXO"
|
||||
msgstr "OXXO"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
|
||||
msgid "Boleto"
|
||||
msgstr "Boleto"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
|
||||
msgid "WeChat Pay"
|
||||
msgstr "WeChat Pay"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
|
||||
msgid "Mercado Pago"
|
||||
msgstr "Mercado Pago"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:167
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:50
|
||||
msgid "Continue"
|
||||
msgstr "Jarraitu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:225
|
||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:244
|
||||
@@ -142,207 +141,207 @@ msgstr "Jarraitu"
|
||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:317
|
||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:341
|
||||
msgid "Confirming your payment …"
|
||||
msgstr "Ordainketa egiaztatzen …"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
|
||||
msgid "Payment method unavailable"
|
||||
msgstr "Ordainketa-modu hau ez dago erabilgarri"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||
msgid "Placed orders"
|
||||
msgstr "Egindako eskaerak"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||
msgid "Paid orders"
|
||||
msgstr "Ordaindutako eskaerak"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
|
||||
msgid "Total revenue"
|
||||
msgstr "Diru-sarrerak guztira"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:15
|
||||
msgid "Contacting Stripe …"
|
||||
msgstr "Stripe-ekin kontaktatzen …"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:72
|
||||
msgid "Total"
|
||||
msgstr "Guztira"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:291
|
||||
msgid "Contacting your bank …"
|
||||
msgstr "Zure bankuarekin kontaktatzen …"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
|
||||
msgid "Select a check-in list"
|
||||
msgstr "Hautatu erregistro-zerrenda bat"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
|
||||
msgid "No active check-in lists found."
|
||||
msgstr "Ez da aurkitu erregistro-zerrenda aktiborik."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:32
|
||||
msgid "Switch check-in list"
|
||||
msgstr "Erregistro-zerrenda aldatu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:33
|
||||
msgid "Search results"
|
||||
msgstr "Emaitzak bilatu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:34
|
||||
msgid "No tickets found"
|
||||
msgstr "Ez da tiketik aurkitu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:35
|
||||
msgid "Result"
|
||||
msgstr "Emaitza"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:36
|
||||
msgid "This ticket requires special attention"
|
||||
msgstr "Tiket honek arreta berezia eskatzen du"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:37
|
||||
msgid "Switch direction"
|
||||
msgstr "Helbidea aldatu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:38
|
||||
msgid "Entry"
|
||||
msgstr "Sarbidea"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:39
|
||||
msgid "Exit"
|
||||
msgstr "Irteera"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:40
|
||||
msgid "Scan a ticket or search and press return…"
|
||||
msgstr "Eskaneatu tiket bat edo bilatu eta sakatu itzuli…"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:41
|
||||
msgid "Load more"
|
||||
msgstr "Gehiago kargatu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:42
|
||||
msgid "Valid"
|
||||
msgstr "Baliozkoa"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:43
|
||||
msgid "Unpaid"
|
||||
msgstr "Ordaindu gabea"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:44
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:45
|
||||
msgid "Canceled"
|
||||
msgstr "Ezeztatua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
|
||||
msgid "Confirmed"
|
||||
msgstr "Baieztatua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
|
||||
msgid "Approval pending"
|
||||
msgstr "Onartzeko zain"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
|
||||
msgid "Redeemed"
|
||||
msgstr "Berrerosia"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:49
|
||||
msgid "Cancel"
|
||||
msgstr "Ezeztatu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:51
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:60
|
||||
msgid "Ticket not paid"
|
||||
msgstr "Tiketa ordaindu gabe"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:52
|
||||
msgid "This ticket is not yet paid. Do you want to continue anyways?"
|
||||
msgstr "Tiket hori oraindik ordaindu gabe dago. Jarraitu nahi duzu, dena den?"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:53
|
||||
msgid "Additional information required"
|
||||
msgstr "Beharrezko informazio gehigarria"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:54
|
||||
msgid "Valid ticket"
|
||||
msgstr "Baliozko tiketa"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:55
|
||||
msgid "Exit recorded"
|
||||
msgstr "Irteera erregistratua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:56
|
||||
msgid "Ticket already used"
|
||||
msgstr "Erabilitako tiketa"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:57
|
||||
msgid "Information required"
|
||||
msgstr "Beharrezko informazioa"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:58
|
||||
msgid "Unknown ticket"
|
||||
msgstr "Tiket ezezaguna"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:59
|
||||
msgid "Ticket type not allowed here"
|
||||
msgstr "Tiket mota hau ez da onartzen hemen"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:61
|
||||
msgid "Entry not allowed"
|
||||
msgstr "Ezin da sartu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:62
|
||||
msgid "Ticket code revoked/changed"
|
||||
msgstr "Baliogabetutako/aldatutako tiketaren kodea"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
|
||||
msgid "Ticket blocked"
|
||||
msgstr "Tiketa blokeatuta"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
|
||||
msgid "Ticket not valid at this time"
|
||||
msgstr "Tiketa ez dago erabilgarri momentu honetan"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
|
||||
msgid "Order canceled"
|
||||
msgstr "Eskaera ezeztatua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
|
||||
msgid "Ticket code is ambiguous on list"
|
||||
msgstr "Tiketaren kodea anbiguoa da zerrendan"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
|
||||
msgid "Order not approved"
|
||||
msgstr "Ez da onartu eskaera"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:68
|
||||
msgid "Checked-in Tickets"
|
||||
msgstr "Tiketak erosita"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:69
|
||||
msgid "Valid Tickets"
|
||||
msgstr "Baliozko tiketak"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
|
||||
msgid "Currently inside"
|
||||
msgstr "Barruan orain bertan"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
|
||||
#: pretix/static/pretixcontrol/js/ui/question.js:137
|
||||
#: pretix/static/pretixpresale/js/ui/questions.js:270
|
||||
msgid "Yes"
|
||||
msgstr "Bai"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:72
|
||||
#: pretix/static/pretixcontrol/js/ui/question.js:138
|
||||
#: pretix/static/pretixpresale/js/ui/questions.js:270
|
||||
msgid "No"
|
||||
msgstr "Ez"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/lightbox/js/lightbox.js:96
|
||||
msgid "close"
|
||||
msgstr "itxi"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:58
|
||||
#: pretix/static/pretixbase/js/asynctask.js:135
|
||||
@@ -350,13 +349,11 @@ msgid ""
|
||||
"Your request is currently being processed. Depending on the size of your "
|
||||
"event, this might take up to a few minutes."
|
||||
msgstr ""
|
||||
"Zure eskaera prozesatzen ari dira. Gertaeraren tamainaren arabera, baliteke "
|
||||
"minutu batzuk behar izatea."
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:63
|
||||
#: pretix/static/pretixbase/js/asynctask.js:140
|
||||
msgid "Your request has been queued on the server and will soon be processed."
|
||||
msgstr "Zure eskaera zerbitzarian gorde da eta laster prozesatuko da."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:69
|
||||
#: pretix/static/pretixbase/js/asynctask.js:146
|
||||
@@ -365,41 +362,34 @@ msgid ""
|
||||
"If this takes longer than two minutes, please contact us or go back in your "
|
||||
"browser and try again."
|
||||
msgstr ""
|
||||
"Zure eskaera zerbitzarira iritsi da, baina oraindik prozesatzea espero dugu. "
|
||||
"Bi minutu baino gehiago irauten badu, mesedez, jarri gurekin harremanetan "
|
||||
"edo itzuli zure nabigatzailera eta saiatu berriro."
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:105
|
||||
#: pretix/static/pretixbase/js/asynctask.js:193
|
||||
#: pretix/static/pretixbase/js/asynctask.js:198
|
||||
#: pretix/static/pretixcontrol/js/ui/mail.js:24
|
||||
msgid "An error of type {code} occurred."
|
||||
msgstr "{kode} motako errore bat gertatu da."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:108
|
||||
msgid ""
|
||||
"We currently cannot reach the server, but we keep trying. Last error code: "
|
||||
"{code}"
|
||||
msgstr ""
|
||||
"Orain bertan ezin gara zerbitzarira iritsi, baina saiatzen jarraitzen dugu. "
|
||||
"Azken errore-kodea: {kodea}"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:160
|
||||
#: pretix/static/pretixcontrol/js/ui/mail.js:21
|
||||
msgid "The request took too long. Please try again."
|
||||
msgstr "Gehiegi luzatu da eskaera. Mesedez, saiatu berriro."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:201
|
||||
#: pretix/static/pretixcontrol/js/ui/mail.js:26
|
||||
msgid ""
|
||||
"We currently cannot reach the server. Please try again. Error code: {code}"
|
||||
msgstr ""
|
||||
"Une honetan ezin gara zerbitzarira iritsi. Mesedez, saiatu berriro. Errore-"
|
||||
"kodea: {kodea}"
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:230
|
||||
msgid "We are processing your request …"
|
||||
msgstr "Zure eskaera prozesatzen ari gara …"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:238
|
||||
msgid ""
|
||||
@@ -407,84 +397,81 @@ msgid ""
|
||||
"than one minute, please check your internet connection and then reload this "
|
||||
"page and try again."
|
||||
msgstr ""
|
||||
"Une honetan zure eskaera zerbitzarira bidaltzen ari gara. Honek minutu bat "
|
||||
"baino gehiago irauten badu, mesedez, berrikusi zure Interneteko konexioa eta "
|
||||
"gero kargatu berriro orri hau eta saiatu berriro."
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:301
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:71
|
||||
msgid "Close message"
|
||||
msgstr "Mezua itxi"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/clipboard.js:23
|
||||
msgid "Copied!"
|
||||
msgstr "Kopiatuta!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/clipboard.js:29
|
||||
msgid "Press Ctrl-C to copy!"
|
||||
msgstr "Sakatu Ctrl-C kopiatzeko!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:12
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:18
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:24
|
||||
msgid "is one of"
|
||||
msgstr "-ko bat da"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:30
|
||||
msgid "is before"
|
||||
msgstr "lehenago da"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:34
|
||||
msgid "is after"
|
||||
msgstr "ondoren da"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
|
||||
msgid "="
|
||||
msgstr "="
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
|
||||
msgid "Product"
|
||||
msgstr "Produktua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:103
|
||||
msgid "Product variation"
|
||||
msgstr "Produktuen aniztasuna"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
||||
msgid "Gate"
|
||||
msgstr "Atea"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
||||
msgid "Current date and time"
|
||||
msgstr "Uneko data eta ordua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
||||
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
||||
msgstr "Asteko uneko eguna (1 = astelehena, 7 = igandea)"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
||||
msgid "Current entry status"
|
||||
msgstr "Egungo sarrera-egoera"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
||||
msgid "Number of previous entries"
|
||||
msgstr "Aurreko sarreren kopurua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:127
|
||||
msgid "Number of previous entries since midnight"
|
||||
msgstr "Aurreko sarrera kopurua gauerditik aurrera"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
|
||||
msgid "Number of previous entries since"
|
||||
msgstr "Aurreko sarrera-kopurua, orduz geroztik"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
|
||||
msgid "Number of previous entries before"
|
||||
msgstr "Aurreko sarreren kopurua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:139
|
||||
msgid "Number of days with a previous entry"
|
||||
msgstr "Aurreko sarrera bat duten egunen kopurua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
|
||||
msgid "Number of days with a previous entry since"
|
||||
@@ -512,15 +499,15 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:184
|
||||
msgid "Event start"
|
||||
msgstr "Ekitaldiaren hasiera"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:185
|
||||
msgid "Event end"
|
||||
msgstr "Ekitaldiaren amaiera"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:186
|
||||
msgid "Event admission"
|
||||
msgstr "Ekitaldiaren onarpena"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:187
|
||||
msgid "custom date and time"
|
||||
@@ -540,7 +527,7 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:191
|
||||
msgid "minutes"
|
||||
msgstr "minutuak"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
|
||||
msgid "Duplicate"
|
||||
@@ -556,56 +543,52 @@ msgctxt "entry_status"
|
||||
msgid "absent"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:72
|
||||
msgid "Check-in QR"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:543
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:387
|
||||
msgid "The PDF background file could not be loaded for the following reason:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:894
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:656
|
||||
msgid "Group of objects"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:899
|
||||
msgid "Text object (deprecated)"
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:661
|
||||
msgid "Text object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:901
|
||||
msgid "Text box"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:903
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:663
|
||||
msgid "Barcode area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:905
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:665
|
||||
msgid "Image area"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:907
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:667
|
||||
msgid "Powered by pretix"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:669
|
||||
msgid "Object"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr "Sarrera diseinua"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
msgid "Saving failed."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1319
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1370
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1041
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1091
|
||||
msgid "Error while uploading your PDF file, please try again."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1353
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1074
|
||||
msgid "Do you really want to leave the editor without saving your changes?"
|
||||
msgstr ""
|
||||
|
||||
@@ -621,54 +604,54 @@ msgstr ""
|
||||
msgid "Unknown error."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:318
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||
msgid "Your color has great contrast and is very easy to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:322
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||
msgid "Your color has decent contrast and is probably good-enough to read!"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:326
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:321
|
||||
msgid ""
|
||||
"Your color has bad contrast for text on white background, please choose a "
|
||||
"darker shade."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:475
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:495
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:515
|
||||
msgid "Search query"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:513
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:493
|
||||
msgid "All"
|
||||
msgstr "Guztiak"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:514
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:494
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:518
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:498
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:861
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:828
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:864
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:831
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1022
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:989
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1062
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1029
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1137
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1104
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
@@ -695,19 +678,16 @@ msgid ""
|
||||
"The items in your cart are no longer reserved for you. You can still "
|
||||
"complete your order as long as they’re available."
|
||||
msgstr ""
|
||||
"Zure saskiko produktuak ez daude zuretzat erreserbatuta. Oraindik ere zure "
|
||||
"eskaera bete dezakezu, baldin eta eskuragarri badaude."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
||||
msgid "Cart expired"
|
||||
msgstr "Saskia iraungita"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:50
|
||||
msgid "The items in your cart are reserved for you for one minute."
|
||||
msgid_plural "The items in your cart are reserved for you for {num} minutes."
|
||||
msgstr[0] "Zure saskiko produktuak minutu -ez erreserbatuta daude zuretzat."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
"Zure saskiko produktuak {num} minutuz erreserbatuta daude zuretzat."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:203
|
||||
msgid "The organizer keeps %(currency)s %(amount)s"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user