forked from CGM_Public/pretix_original
Compare commits
29 Commits
order-null
...
fix-tests
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43b9049a12 | ||
|
|
7b16dfefbc | ||
|
|
8a5b13dee9 | ||
|
|
d7dde8c23e | ||
|
|
1e2f93fbc5 | ||
|
|
493fc03686 | ||
|
|
8d6d885f6e | ||
|
|
2aa989c293 | ||
|
|
06b226f40f | ||
|
|
73038b0d97 | ||
|
|
4513e31f0d | ||
|
|
d34175114b | ||
|
|
b2c71b47ce | ||
|
|
a889abc52b | ||
|
|
8c01b2a469 | ||
|
|
720c7fd7bb | ||
|
|
6ae6eba4de | ||
|
|
a173e347ea | ||
|
|
94d13e4cdd | ||
|
|
e618441231 | ||
|
|
cd57f1f024 | ||
|
|
075b9c187f | ||
|
|
d9f46cb817 | ||
|
|
2892d16861 | ||
|
|
9128624d68 | ||
|
|
d2cf8f801d | ||
|
|
682d0f886d | ||
|
|
d2cbd41a19 | ||
|
|
828f4e3168 |
@@ -40,6 +40,11 @@ answers list of objects Answers to user
|
||||
seat objects The assigned seat (or ``null``)
|
||||
├ id integer Internal ID of the seat instance
|
||||
├ name string Human-readable seat name
|
||||
├ zone_name string Name of the zone the seat is in
|
||||
├ row_name string Name/number of the row the seat is in
|
||||
├ row_label string Additional label of the row (or ``null``)
|
||||
├ seat_number string Number of the seat within the row
|
||||
├ seat_label string Additional label of the seat (or ``null``)
|
||||
└ seat_guid string Identifier of the seat within the seating plan
|
||||
===================================== ========================== =======================================================
|
||||
|
||||
|
||||
@@ -96,6 +96,8 @@ Endpoints
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query string secret: Only show gift cards with the given secret.
|
||||
:query string value: Only show gift cards with the given value.
|
||||
:query boolean expired: Filter for gift cards that are (not) expired.
|
||||
:query boolean testmode: Filter for gift cards that are (not) in test mode.
|
||||
:query boolean include_accepted: Also show gift cards issued by other organizers that are accepted by this organizer.
|
||||
:query string expand: If you pass ``"owner_ticket"``, the respective field will be shown as a nested value instead of just an ID.
|
||||
|
||||
@@ -164,6 +164,7 @@ Endpoints
|
||||
}
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query string search: Filter the list by the value of the variation (substring search).
|
||||
:query boolean active: If set to ``true`` or ``false``, only items with this value for the field ``active`` will be
|
||||
returned.
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
|
||||
@@ -392,6 +392,7 @@ Endpoints
|
||||
}
|
||||
|
||||
:query integer page: The page number in case of a multi-page result set, default is 1
|
||||
:query string search: Filter the list by internal name or name of the item (substring search).
|
||||
:query boolean active: If set to ``true`` or ``false``, only items with this value for the field ``active`` will be
|
||||
returned.
|
||||
:query integer category: If set to the ID of a category, only items within that category will be returned.
|
||||
|
||||
@@ -215,6 +215,11 @@ answers list of objects Answers to user
|
||||
seat objects The assigned seat. Can be ``null``.
|
||||
├ id integer Internal ID of the seat instance
|
||||
├ name string Human-readable seat name
|
||||
├ zone_name string Name of the zone the seat is in
|
||||
├ row_name string Name/number of the row the seat is in
|
||||
├ row_label string Additional label of the row (or ``null``)
|
||||
├ seat_number string Number of the seat within the row
|
||||
├ seat_label string Additional label of the seat (or ``null``)
|
||||
└ seat_guid string Identifier of the seat within the seating plan
|
||||
pdf_data object Data object required for ticket PDF generation. By default,
|
||||
this field is missing. It will be added only if you add the
|
||||
@@ -455,10 +460,13 @@ List of all orders
|
||||
:query datetime modified_since: Only return orders that have changed since the given date. Be careful: We only
|
||||
recommend using this in combination with ``testmode=false``, since test mode orders can vanish at any time and
|
||||
you will not notice it using this method.
|
||||
:query datetime created_since: Only return orders that have been created since the given date.
|
||||
:query datetime created_since: Only return orders that have been created since the given date (inclusive).
|
||||
:query datetime created_before: Only return orders that have been created before the given date (exclusive).
|
||||
:query integer subevent: Only return orders with a position that contains this subevent ID. *Warning:* Result will also include orders if they contain mixed subevents, and it will even return orders where the subevent is only contained in a canceled position.
|
||||
:query datetime subevent_after: Only return orders that contain a ticket for a subevent taking place after the given date. This is an exclusive after, and it considers the **end** of the subevent (or its start, if the end is not set).
|
||||
:query datetime subevent_before: Only return orders that contain a ticket for a subevent taking place after the given date. This is an exclusive before, and it considers the **start** of the subevent.
|
||||
:query string sales_channel: Only return orders with the given sales channel identifier (e.g. ``"web"``).
|
||||
:query string payment_provider: Only return orders that contain a payment using the given payment provider. Note that this also searches for partial incomplete, or failed payments within the order and is not useful to get a sum of payment amounts without further processing.
|
||||
:query string exclude: Exclude a field from the output, e.g. ``fees`` or ``positions.downloads``. Can be used as a performance optimization. Can be passed multiple times.
|
||||
:query string include: Include only the given field in the output, e.g. ``fees`` or ``positions.downloads``. Can be used as a performance optimization. Can be passed multiple times. ``include`` is applied before ``exclude``, so ``exclude`` takes precedence.
|
||||
:param organizer: The ``slug`` field of the organizer to fetch
|
||||
|
||||
@@ -35,7 +35,7 @@ Frontend
|
||||
--------
|
||||
|
||||
.. automodule:: pretix.presale.signals
|
||||
:members: html_head, html_footer, footer_link, global_footer_link, front_page_top, front_page_bottom, front_page_bottom_widget, fee_calculation_for_cart, contact_form_fields, question_form_fields, contact_form_fields_overrides, question_form_fields_overrides, checkout_confirm_messages, checkout_confirm_page_content, checkout_all_optional, html_page_header, render_seating_plan, checkout_flow_steps, position_info, position_info_top, item_description, global_html_head, global_html_footer, global_html_page_header
|
||||
:members: html_head, html_footer, footer_link, global_footer_link, front_page_top, front_page_bottom, front_page_bottom_widget, fee_calculation_for_cart, contact_form_fields, question_form_fields, contact_form_fields_overrides, question_form_fields_overrides, checkout_confirm_messages, checkout_confirm_page_content, checkout_all_optional, html_page_header, render_seating_plan, checkout_flow_steps, position_info, position_info_top, item_description, global_html_head, global_html_footer, global_html_page_header, seatingframe_html_head
|
||||
|
||||
|
||||
.. automodule:: pretix.presale.signals
|
||||
|
||||
@@ -17,7 +17,7 @@ The project pretix is split into several components. The main components are:
|
||||
create and manage their events, items, orders and tickets.
|
||||
|
||||
**presale**
|
||||
This is the ticket-shop itself, containing all of the parts visible to the
|
||||
This is the ticket shop itself, containing all of the parts visible to the
|
||||
end user. Also called "frontend" in parts of this documentation.
|
||||
|
||||
**api**
|
||||
|
||||
@@ -75,7 +75,7 @@ dependencies = [
|
||||
"paypal-checkout-serversdk==1.0.*",
|
||||
"PyJWT==2.8.*",
|
||||
"phonenumberslite==8.13.*",
|
||||
"Pillow==10.3.*",
|
||||
"Pillow==10.4.*",
|
||||
"pretix-plugin-build",
|
||||
"protobuf==5.27.*",
|
||||
"psycopg2-binary",
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
#
|
||||
import json
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
|
||||
class AsymmetricField(serializers.Field):
|
||||
|
||||
@@ -281,13 +281,17 @@ class EventSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
|
||||
from pretix.base.plugins import get_all_plugins
|
||||
|
||||
plugins_available = {
|
||||
p.module for p in get_all_plugins(self.instance)
|
||||
p.module: p for p in get_all_plugins(self.instance)
|
||||
if not p.name.startswith('.') and getattr(p, 'visible', True)
|
||||
}
|
||||
settings_holder = self.instance if self.instance and self.instance.pk else self.context['organizer']
|
||||
|
||||
for plugin in value.get('plugins'):
|
||||
if plugin not in plugins_available:
|
||||
raise ValidationError(_('Unknown plugin: \'{name}\'.').format(name=plugin))
|
||||
if getattr(plugins_available[plugin], 'restricted', False):
|
||||
if plugin not in settings_holder.settings.allowed_restricted_plugins:
|
||||
raise ValidationError(_('Restricted plugin: \'{name}\'.').format(name=plugin))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
@@ -76,7 +76,9 @@ class InlineItemVariationSerializer(SalesChannelMigrationMixin, I18nAwareModelSe
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['require_membership_types'].queryset = lazy(lambda: self.context['event'].organizer.membership_types.all(), QuerySet)
|
||||
self.fields['limit_sales_channels'].child_relation.queryset = lazy(lambda: self.context['event'].organizer.sales_channels.all(), QuerySet)
|
||||
self.fields['limit_sales_channels'].child_relation.queryset = (
|
||||
self.context['event'].organizer.sales_channels.all() if 'event' in self.context else SalesChannel.objects.none()
|
||||
)
|
||||
|
||||
def validate_meta_data(self, value):
|
||||
for key in value['meta_data'].keys():
|
||||
@@ -115,11 +117,15 @@ class ItemVariationSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializ
|
||||
def create(self, validated_data):
|
||||
meta_data = validated_data.pop('meta_data', None)
|
||||
require_membership_types = validated_data.pop('require_membership_types', [])
|
||||
limit_sales_channels = validated_data.pop('limit_sales_channels', [])
|
||||
variation = ItemVariation.objects.create(**validated_data)
|
||||
|
||||
if require_membership_types:
|
||||
variation.require_membership_types.add(*require_membership_types)
|
||||
|
||||
if limit_sales_channels:
|
||||
variation.limit_sales_channels.add(*limit_sales_channels)
|
||||
|
||||
# Meta data
|
||||
if meta_data is not None:
|
||||
for key, value in meta_data.items():
|
||||
@@ -284,6 +290,7 @@ class ItemSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
|
||||
self.fields['require_membership_types'].queryset = self.context['event'].organizer.membership_types.all()
|
||||
self.fields['grant_membership_type'].queryset = self.context['event'].organizer.membership_types.all()
|
||||
self.fields['limit_sales_channels'].child_relation.queryset = self.context['event'].organizer.sales_channels.all()
|
||||
self.fields['variations'].child.fields['limit_sales_channels'].child_relation.queryset = self.context['event'].organizer.sales_channels.all()
|
||||
|
||||
def validate(self, data):
|
||||
data = super().validate(data)
|
||||
@@ -371,10 +378,13 @@ class ItemSerializer(SalesChannelMigrationMixin, I18nAwareModelSerializer):
|
||||
|
||||
for variation_data in variations_data:
|
||||
require_membership_types = variation_data.pop('require_membership_types', [])
|
||||
limit_sales_channels = variation_data.pop('limit_sales_channels', [])
|
||||
var_meta_data = variation_data.pop('meta_data', {})
|
||||
v = ItemVariation.objects.create(item=item, **variation_data)
|
||||
if require_membership_types:
|
||||
v.require_membership_types.add(*require_membership_types)
|
||||
if limit_sales_channels:
|
||||
v.limit_sales_channels.add(*limit_sales_channels)
|
||||
|
||||
if var_meta_data is not None:
|
||||
for key, value in var_meta_data.items():
|
||||
|
||||
@@ -165,7 +165,7 @@ class InlineSeatSerializer(I18nAwareModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Seat
|
||||
fields = ('id', 'name', 'seat_guid')
|
||||
fields = ('id', 'name', 'seat_guid', 'zone_name', 'row_name', 'row_label', 'seat_label', 'seat_number')
|
||||
|
||||
|
||||
class AnswerSerializer(I18nAwareModelSerializer):
|
||||
@@ -585,7 +585,7 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
|
||||
self.fields['item'] = ItemSerializer(read_only=True, context=self.context)
|
||||
|
||||
if 'variation' in self.context['expand']:
|
||||
self.fields['variation'] = InlineItemVariationSerializer(read_only=True)
|
||||
self.fields['variation'] = InlineItemVariationSerializer(read_only=True, context=self.context)
|
||||
|
||||
if 'answers.question' in self.context['expand']:
|
||||
self.fields['answers'].child.fields['question'] = QuestionSerializer(read_only=True)
|
||||
|
||||
@@ -406,7 +406,7 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
||||
'item__variations').select_related('item__tax_rule')
|
||||
|
||||
if expand and 'variation' in expand:
|
||||
qs = qs.prefetch_related('variation')
|
||||
qs = qs.prefetch_related('variation', 'variation__meta_values')
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||
from django_scopes import scopes_disabled
|
||||
from rest_framework import serializers, views, viewsets
|
||||
from rest_framework.exceptions import PermissionDenied, ValidationError
|
||||
from rest_framework.generics import get_object_or_404
|
||||
from rest_framework.response import Response
|
||||
|
||||
from pretix.api.auth.permission import EventCRUDPermission
|
||||
@@ -162,7 +163,13 @@ class EventViewSet(viewsets.ModelViewSet):
|
||||
qs = filter_qs_by_attr(qs, self.request)
|
||||
|
||||
if 'with_availability_for' in self.request.GET:
|
||||
qs = Event.annotated(qs, channel=self.request.GET.get('with_availability_for'))
|
||||
qs = Event.annotated(
|
||||
qs,
|
||||
channel=get_object_or_404(
|
||||
self.request.organizer.sales_channels,
|
||||
identifier=self.request.GET.get('with_availability_for')
|
||||
)
|
||||
)
|
||||
|
||||
return qs.prefetch_related(
|
||||
'organizer',
|
||||
@@ -442,7 +449,13 @@ class SubEventViewSet(ConditionalListView, viewsets.ModelViewSet):
|
||||
qs = filter_qs_by_attr(qs, self.request)
|
||||
|
||||
if 'with_availability_for' in self.request.GET:
|
||||
qs = SubEvent.annotated(qs, channel=self.request.GET.get('with_availability_for'))
|
||||
qs = SubEvent.annotated(
|
||||
qs,
|
||||
channel=get_object_or_404(
|
||||
self.request.organizer.sales_channels,
|
||||
identifier=self.request.GET.get('with_availability_for')
|
||||
)
|
||||
)
|
||||
|
||||
return qs.prefetch_related(
|
||||
'event',
|
||||
|
||||
@@ -56,10 +56,17 @@ from pretix.base.models import (
|
||||
)
|
||||
from pretix.base.services.quotas import QuotaAvailability
|
||||
from pretix.helpers.dicts import merge_dicts
|
||||
from pretix.helpers.i18n import i18ncomp
|
||||
|
||||
with scopes_disabled():
|
||||
class ItemFilter(FilterSet):
|
||||
tax_rate = django_filters.CharFilter(method='tax_rate_qs')
|
||||
search = django_filters.CharFilter(method='search_qs')
|
||||
|
||||
def search_qs(self, queryset, name, value):
|
||||
return queryset.filter(
|
||||
Q(internal_name__icontains=value) | Q(name__icontains=i18ncomp(value))
|
||||
)
|
||||
|
||||
def tax_rate_qs(self, queryset, name, value):
|
||||
if value in ("0", "None", "0.00"):
|
||||
@@ -71,6 +78,18 @@ with scopes_disabled():
|
||||
model = Item
|
||||
fields = ['active', 'category', 'admission', 'tax_rate', 'free_price']
|
||||
|
||||
class ItemVariationFilter(FilterSet):
|
||||
search = django_filters.CharFilter(method='search_qs')
|
||||
|
||||
def search_qs(self, queryset, name, value):
|
||||
return queryset.filter(
|
||||
Q(value__icontains=i18ncomp(value))
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = ItemVariation
|
||||
fields = ['active']
|
||||
|
||||
|
||||
class ItemViewSet(ConditionalListView, viewsets.ModelViewSet):
|
||||
serializer_class = ItemSerializer
|
||||
@@ -140,6 +159,7 @@ class ItemVariationViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = ItemVariationSerializer
|
||||
queryset = ItemVariation.objects.none()
|
||||
filter_backends = (DjangoFilterBackend, TotalOrderingFilter,)
|
||||
filterset_class = ItemVariationFilter
|
||||
ordering_fields = ('id', 'position')
|
||||
ordering = ('id',)
|
||||
permission = None
|
||||
|
||||
@@ -108,6 +108,7 @@ with scopes_disabled():
|
||||
status = django_filters.CharFilter(field_name='status', lookup_expr='iexact')
|
||||
modified_since = django_filters.IsoDateTimeFilter(field_name='last_modified', lookup_expr='gte')
|
||||
created_since = django_filters.IsoDateTimeFilter(field_name='datetime', lookup_expr='gte')
|
||||
created_before = django_filters.IsoDateTimeFilter(field_name='datetime', lookup_expr='lt')
|
||||
subevent_after = django_filters.IsoDateTimeFilter(method='subevent_after_qs')
|
||||
subevent_before = django_filters.IsoDateTimeFilter(method='subevent_before_qs')
|
||||
search = django_filters.CharFilter(method='search_qs')
|
||||
@@ -115,6 +116,8 @@ with scopes_disabled():
|
||||
variation = django_filters.CharFilter(field_name='all_positions', lookup_expr='variation_id', distinct=True)
|
||||
subevent = django_filters.CharFilter(field_name='all_positions', lookup_expr='subevent_id', distinct=True)
|
||||
customer = django_filters.CharFilter(field_name='customer__identifier')
|
||||
sales_channel = django_filters.CharFilter(field_name='sales_channel__identifier')
|
||||
payment_provider = django_filters.CharFilter(method='provider_qs')
|
||||
|
||||
class Meta:
|
||||
model = Order
|
||||
@@ -138,6 +141,11 @@ with scopes_disabled():
|
||||
)
|
||||
return qs
|
||||
|
||||
def provider_qs(self, qs, name, value):
|
||||
return qs.filter(Exists(
|
||||
OrderPayment.objects.filter(order=OuterRef('pk'), provider=value)
|
||||
))
|
||||
|
||||
def subevent_before_qs(self, qs, name, value):
|
||||
if getattr(self.request, 'event', None):
|
||||
subevents = self.request.event.subevents
|
||||
|
||||
@@ -24,10 +24,11 @@ from decimal import Decimal
|
||||
import django_filters
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.db import transaction
|
||||
from django.db.models import OuterRef, Subquery, Sum
|
||||
from django.db.models import OuterRef, Q, Subquery, Sum
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||
from django_scopes import scopes_disabled
|
||||
from rest_framework import mixins, serializers, status, views, viewsets
|
||||
@@ -136,11 +137,19 @@ class SeatingPlanViewSet(viewsets.ModelViewSet):
|
||||
with scopes_disabled():
|
||||
class GiftCardFilter(FilterSet):
|
||||
secret = django_filters.CharFilter(field_name='secret', lookup_expr='iexact')
|
||||
expired = django_filters.BooleanFilter(method='expired_qs')
|
||||
value = django_filters.NumberFilter(field_name='cached_value')
|
||||
|
||||
class Meta:
|
||||
model = GiftCard
|
||||
fields = ['secret', 'testmode']
|
||||
|
||||
def expired_qs(self, qs, name, value):
|
||||
if value:
|
||||
return qs.filter(expires__isnull=False, expires__lt=now())
|
||||
else:
|
||||
return qs.filter(Q(expires__isnull=True) | Q(expires__gte=now()))
|
||||
|
||||
|
||||
class GiftCardViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = GiftCardSerializer
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Generated by Django 4.2.8 on 2024-07-01 09:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
import pretix.base.models.orders
|
||||
|
||||
|
||||
|
||||
@@ -304,10 +304,13 @@ class EventMixin:
|
||||
return safe_string(json.dumps(eventdict))
|
||||
|
||||
@classmethod
|
||||
def annotated(cls, qs, channel='web', voucher=None):
|
||||
from pretix.base.models import Item, ItemVariation, Quota
|
||||
def annotated(cls, qs, channel, voucher=None):
|
||||
# Channel can currently be a SalesChannel or a str, since we need that compatibility, but a SalesChannel
|
||||
# makes the query SIGNIFICANTLY faster
|
||||
from pretix.base.models import Item, ItemVariation, Quota, SalesChannel
|
||||
|
||||
assert isinstance(channel, (SalesChannel, str))
|
||||
|
||||
assert isinstance(channel, str)
|
||||
sq_active_item = Item.objects.using(settings.DATABASE_REPLICA).filter_available(channel=channel, voucher=voucher).filter(
|
||||
Q(variations__isnull=True)
|
||||
& Q(quotas__pk=OuterRef('pk'))
|
||||
@@ -317,18 +320,23 @@ class EventMixin:
|
||||
|
||||
q_variation = (
|
||||
Q(active=True)
|
||||
& Q(Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=channel))
|
||||
& Q(Q(available_from__isnull=True) | Q(available_from__lte=time_machine_now()))
|
||||
& Q(Q(available_until__isnull=True) | Q(available_until__gte=time_machine_now()))
|
||||
& Q(item__active=True)
|
||||
& Q(Q(item__available_from__isnull=True) | Q(item__available_from__lte=time_machine_now()))
|
||||
& Q(Q(item__available_until__isnull=True) | Q(item__available_until__gte=time_machine_now()))
|
||||
& Q(Q(item__category__isnull=True) | Q(item__category__is_addon=False))
|
||||
& Q(Q(item__all_sales_channels=True) | Q(item__limit_sales_channels__identifier=channel))
|
||||
& Q(item__require_bundling=False)
|
||||
& Q(quotas__pk=OuterRef('pk'))
|
||||
)
|
||||
|
||||
if isinstance(channel, str):
|
||||
q_variation &= Q(Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=channel))
|
||||
q_variation &= Q(Q(item__all_sales_channels=True) | Q(item__limit_sales_channels__identifier=channel))
|
||||
else:
|
||||
q_variation &= Q(Q(all_sales_channels=True) | Q(limit_sales_channels=channel))
|
||||
q_variation &= Q(Q(item__all_sales_channels=True) | Q(item__limit_sales_channels=channel))
|
||||
|
||||
if voucher:
|
||||
if voucher.variation_id:
|
||||
q_variation &= Q(pk=voucher.variation_id)
|
||||
@@ -962,7 +970,7 @@ class Event(EventMixin, LoggedModel):
|
||||
):
|
||||
c_items = list(d.condition_limit_products.all())
|
||||
b_items = list(d.benefit_limit_products.all())
|
||||
limit_sales_channels = list(v.limit_sales_channels.all())
|
||||
limit_sales_channels = list(d.limit_sales_channels.all())
|
||||
d.pk = None
|
||||
d.event = self
|
||||
d._prefetched_objects_cache = {}
|
||||
@@ -1536,8 +1544,11 @@ class SubEvent(EventMixin, LoggedModel):
|
||||
return qs_annotated
|
||||
|
||||
@classmethod
|
||||
def annotated(cls, qs, channel='web', voucher=None):
|
||||
def annotated(cls, qs, channel, voucher=None):
|
||||
from .items import SubEventItem, SubEventItemVariation
|
||||
from .organizer import SalesChannel
|
||||
|
||||
assert isinstance(channel, (str, SalesChannel))
|
||||
|
||||
qs = super().annotated(qs, channel, voucher=voucher)
|
||||
qs = qs.annotate(
|
||||
|
||||
@@ -271,16 +271,24 @@ class SubEventItemVariation(models.Model):
|
||||
|
||||
|
||||
def filter_available(qs, channel='web', voucher=None, allow_addons=False):
|
||||
assert isinstance(channel, str)
|
||||
# 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
|
||||
|
||||
assert isinstance(channel, (SalesChannel, str))
|
||||
q = (
|
||||
# IMPORTANT: If this is updated, also update the ItemVariation query
|
||||
# in models/event.py: EventMixin.annotated()
|
||||
Q(active=True)
|
||||
& Q(Q(available_from__isnull=True) | Q(available_from__lte=time_machine_now()) | Q(available_from_mode='info'))
|
||||
& Q(Q(available_until__isnull=True) | Q(available_until__gte=time_machine_now()) | Q(available_until_mode='info'))
|
||||
& Q(Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=channel))
|
||||
& Q(require_bundling=False)
|
||||
)
|
||||
if isinstance(channel, str):
|
||||
q &= Q(Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=channel))
|
||||
else:
|
||||
q &= Q(Q(all_sales_channels=True) | Q(limit_sales_channels=channel))
|
||||
|
||||
if not allow_addons:
|
||||
q &= Q(Q(category__isnull=True) | Q(category__is_addon=False))
|
||||
|
||||
|
||||
@@ -2042,7 +2042,7 @@ class OrderChangeManager:
|
||||
# This also prevents accidental removal through the UI because a hidden product will no longer
|
||||
# be part of the input.
|
||||
(a.variation and a.variation.unavailability_reason(has_voucher=True, subevent=a.subevent))
|
||||
or (a.variation and self.order.sales_channel not in a.variation.sales_channels)
|
||||
or (a.variation and not a.variation.all_sales_channels and not a.variation.limit_sales_channels.contains(self.order.sales_channel))
|
||||
or a.item.unavailability_reason(has_voucher=True, subevent=a.subevent)
|
||||
or (
|
||||
not item.all_sales_channels and
|
||||
|
||||
@@ -105,6 +105,7 @@ def preview(event: int, provider: str):
|
||||
order = event.orders.create(status=Order.STATUS_PENDING, datetime=now(),
|
||||
email='sample@pretix.eu',
|
||||
locale=event.settings.locale,
|
||||
sales_channel=event.organizer.sales_channels.get(identifier="web"),
|
||||
expires=now(), code="PREVIEW1234", total=119)
|
||||
|
||||
scheme = PERSON_NAME_SCHEMES[event.settings.name_scheme]
|
||||
|
||||
@@ -136,9 +136,15 @@
|
||||
{% if i.tax_rule and i.default_price %}
|
||||
<br/>
|
||||
<small class="text-muted">
|
||||
{% blocktrans trimmed with rate=i.tax_rule.rate|floatformat:-2 taxname=i.tax_rule.name|default:s_taxes %}
|
||||
incl. {{ rate }}% {{ taxname }}
|
||||
{% endblocktrans %}
|
||||
{% if not i.tax_rule.price_includes_tax %}
|
||||
{% blocktrans trimmed with rate=i.tax_rule.rate|floatformat:-2 taxname=i.tax_rule.name %}
|
||||
<strong>plus</strong> {{ rate }}% {{ taxname }}
|
||||
{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans trimmed with rate=i.tax_rule.rate|floatformat:-2 taxname=i.tax_rule.name|default:s_taxes %}
|
||||
incl. {{ rate }}% {{ taxname }}
|
||||
{% endblocktrans %}
|
||||
{% endif %}
|
||||
</small>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
{% for se in request.event.subevents.all %}
|
||||
<option value="{{ se.id }}"
|
||||
{% if request.GET.subevent|add:0 == se.id %}selected="selected"{% endif %}>
|
||||
{{ se.name }} – {{ se.get_date_range_display }}
|
||||
{{ se }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
@@ -119,7 +119,7 @@
|
||||
{% for se in request.event.subevents.all %}
|
||||
<option value="{{ se.id }}"
|
||||
{% if request.GET.subevent|add:0 == se.id %}selected="selected"{% endif %}>
|
||||
{{ se.name }} – {{ se.get_date_range_display }}
|
||||
{{ se }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
@@ -195,7 +195,7 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if request.event.has_subevents %}
|
||||
<td>{{ e.subevent.name }} – {{ e.subevent.get_date_range_display }}</td>
|
||||
<td>{{ e.subevent }}</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
{{ e.created|date:"SHORT_DATETIME_FORMAT" }}
|
||||
|
||||
@@ -400,7 +400,7 @@ class EventPlugins(EventSettingsViewMixin, EventPermissionRequiredMixin, Templat
|
||||
if key.startswith("plugin:"):
|
||||
module = key.split(":")[1]
|
||||
if value == "enable" and module in plugins_available:
|
||||
if getattr(plugins_available[module].app, 'restricted', False):
|
||||
if getattr(plugins_available[module], 'restricted', False):
|
||||
if module not in request.event.settings.allowed_restricted_plugins:
|
||||
continue
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class ItemList(ListView):
|
||||
def get_queryset(self):
|
||||
return Item.objects.filter(
|
||||
event=self.request.event
|
||||
).annotate(
|
||||
).select_related("tax_rule").annotate(
|
||||
var_count=Count('variations')
|
||||
).prefetch_related("category", "limit_sales_channels").order_by(
|
||||
F('category__position').asc(nulls_first=True),
|
||||
|
||||
@@ -3161,7 +3161,7 @@ class ChannelUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMix
|
||||
}
|
||||
|
||||
def form_valid(self, form):
|
||||
if form.has_changed() or self.formset.has_changed():
|
||||
if form.has_changed():
|
||||
self.object.log_action('pretix.saleschannel.changed', user=self.request.user, data={
|
||||
k: getattr(self.object, k)
|
||||
for k in form.changed_data
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-06-30 18:55+0000\n"
|
||||
"PO-Revision-Date: 2024-06-30 21:07+0000\n"
|
||||
"PO-Revision-Date: 2024-07-02 19:00+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/de/"
|
||||
">\n"
|
||||
@@ -3536,7 +3536,7 @@ msgstr "Sie können keinen Ticketcode verwenden, der bereits existiert."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:490
|
||||
msgid "Please enter a valid language code."
|
||||
msgstr "Bitte geben Sie einen gültigen Sprachcode ein."
|
||||
msgstr "Bitte einen gültigen Sprachcode eingeben."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:558 pretix/base/modelimport_orders.py:560
|
||||
msgid "Please enter a valid sales channel."
|
||||
@@ -9608,7 +9608,7 @@ msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:1346
|
||||
msgid "Ask search engines not to index the ticket shop"
|
||||
msgstr "Der Ticket-Shop soll von Suchmaschinen nicht indiziert werden"
|
||||
msgstr "Der Ticketshop soll von Suchmaschinen nicht indiziert werden"
|
||||
|
||||
#: pretix/base/settings.py:1355
|
||||
msgid "Show variations of a product expanded by default"
|
||||
@@ -10874,7 +10874,7 @@ msgstr ""
|
||||
"Sie haben sich auf die Warteliste für {event} \n"
|
||||
"für das Produkt {product} eingetragen.\n"
|
||||
"\n"
|
||||
"Wir haben nun ein Ticket für Sie! Sie können es in unserem Ticket-Shop "
|
||||
"Wir haben nun ein Ticket für Sie! Sie können es in unserem Ticketshop "
|
||||
"erwerben,\n"
|
||||
"indem Sie in den nächsten {hours} Stunden den folgenden Gutscheincode "
|
||||
"eingeben:\n"
|
||||
@@ -11971,7 +11971,7 @@ msgid ""
|
||||
"If you just configured this as a domain for your ticket shop, you now need "
|
||||
"to set this up as a \"custom domain\" in your organizer account."
|
||||
msgstr ""
|
||||
"Wenn Sie gerade diese Domain für Ihren Ticket-Shop eingerichtet haben, "
|
||||
"Wenn Sie gerade diese Domain für Ihren Ticketshop eingerichtet haben, "
|
||||
"müssen Sie diese nun in Ihrem Veranstalterkonto als \"eigene Domain\" "
|
||||
"eintragen."
|
||||
|
||||
@@ -18403,7 +18403,7 @@ msgid ""
|
||||
"You can instead take your shop offline. This will hide it from everyone "
|
||||
"except from the organizer teams you configured to have access to the event."
|
||||
msgstr ""
|
||||
"Sie können stattdessen den Ticket-Shop abschalten. Dies wird die "
|
||||
"Sie können stattdessen den Ticketshop abschalten. Dies wird die "
|
||||
"Veranstaltung vor allen außer den zugewiesenen Veranstalter-Teams verstecken."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/delete.html:66
|
||||
@@ -18629,14 +18629,14 @@ msgid ""
|
||||
"Your ticket shop is currently not live. It is thus only visible to you and "
|
||||
"your team, not to any visitors."
|
||||
msgstr ""
|
||||
"Ihr Ticket-Shop ist zur Zeit offline und daher nur für Sie und Ihr Team "
|
||||
"Ihr Ticketshop ist zur Zeit offline und daher nur für Sie und Ihr Team "
|
||||
"verfügbar und nicht für Besucher."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:41
|
||||
msgid ""
|
||||
"To publish your ticket shop, you first need to resolve the following issues:"
|
||||
msgstr ""
|
||||
"Um Ihren Ticket-Shop zu veröffentlichen, müssen Sie zuerst die folgenden "
|
||||
"Um Ihren Ticketshop zu veröffentlichen, müssen Sie zuerst die folgenden "
|
||||
"Probleme beheben:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:51
|
||||
@@ -18646,7 +18646,7 @@ msgstr "Shop veröffentlichen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:59
|
||||
msgid "If you want to, you can publish your ticket shop now."
|
||||
msgstr "Sie können Ihren Ticket-Shop jederzeit veröffentlichen."
|
||||
msgstr "Sie können Ihren Ticketshop jederzeit veröffentlichen."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:83
|
||||
msgid ""
|
||||
@@ -19488,7 +19488,7 @@ msgid ""
|
||||
"website. This way, your visitors can buy their ticket right away without "
|
||||
"leaving your website."
|
||||
msgstr ""
|
||||
"Das pretix-Widget ist ein Weg, den Ticket-Shop in Ihre Event-Website "
|
||||
"Das pretix-Widget ist ein Weg, den Ticketshop in Ihre Event-Website "
|
||||
"einzubetten. Auf diese Weise können Besucher Ihrer Website ein Ticket "
|
||||
"erwerben, ohne die Website verlassen zu müssen."
|
||||
|
||||
@@ -19515,7 +19515,7 @@ msgid ""
|
||||
"JavaScript is disabled in your browser. To access our ticket shop without "
|
||||
"JavaScript, please <a %(a_attr)s>click here</a>."
|
||||
msgstr ""
|
||||
"JavaScript ist in Ihrem Browser deaktiviert. Um unseren Ticket-Shop ohne "
|
||||
"JavaScript ist in Ihrem Browser deaktiviert. Um unseren Ticketshop ohne "
|
||||
"JavaScript aufzurufen, klicken Sie bitte <a %(a_attr)s>hier</a>."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/widget.html:64
|
||||
@@ -19580,7 +19580,7 @@ msgid ""
|
||||
"less than 10 characters that can be easily remembered, but you can also "
|
||||
"choose to use a random value."
|
||||
msgstr ""
|
||||
"Dies ist die Adresse, unter der Ihr Ticket-Shop verfügbar sein wird. Sie "
|
||||
"Dies ist die Adresse, unter der Ihr Ticketshop verfügbar sein wird. Sie "
|
||||
"sollte kurz sein und darf nur Kleinbuchstaben, Zahlen, Punkte und "
|
||||
"Bindestriche enthalten. Sie muss unter Ihren Veranstaltungen einmalig sein. "
|
||||
"Wir empfehlen eine Abkürzung oder ein Datum mit weniger als 10 Zeichen, das "
|
||||
@@ -22464,7 +22464,7 @@ msgstr "Veröffentlichen Sie Ihren Shop"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/index.html:27
|
||||
msgid "Go to the ticket shop"
|
||||
msgstr "Zum Ticket-Shop"
|
||||
msgstr "Zum Ticketshop"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/index.html:35
|
||||
msgid "Search query:"
|
||||
@@ -23102,7 +23102,7 @@ msgid ""
|
||||
"usage, the legal details in your specific jurisdiction, or the agreements "
|
||||
"you have with third parties such as payment or tracking providers."
|
||||
msgstr ""
|
||||
"Trotzdem bleibt es Ihre Verantwortung, dass Ihr Ticket-Shop allen "
|
||||
"Trotzdem bleibt es Ihre Verantwortung, dass Ihr Ticketshop allen "
|
||||
"anwendbaren Gesetzen entspricht. Wir versuchen mit diesen Einstellungen zu "
|
||||
"helfen, aber können keine Haftung übernehmen, da wir unter anderem die "
|
||||
"genaue Konfiguration Ihres Ticketshops, die rechtlichen Details der "
|
||||
@@ -25624,7 +25624,7 @@ msgstr "{quota} übrig"
|
||||
|
||||
#: pretix/control/views/dashboards.py:269
|
||||
msgid "Your ticket shop is"
|
||||
msgstr "Ihr Ticket-Shop ist"
|
||||
msgstr "Ihr Ticketshop ist"
|
||||
|
||||
#: pretix/control/views/dashboards.py:269
|
||||
msgid "Click here to change"
|
||||
@@ -31490,7 +31490,7 @@ msgstr "Warnung"
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:127
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:201
|
||||
msgid "This ticket shop is currently in test mode."
|
||||
msgstr "Dieser Ticket-Shop ist momentan im Testmodus."
|
||||
msgstr "Dieser Ticketshop ist momentan im Testmodus."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:130
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:204
|
||||
@@ -32857,7 +32857,7 @@ msgstr "Shop ausgeschaltet"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/offline.html:9
|
||||
msgid "This ticket shop is currently turned off."
|
||||
msgstr "Dieser Ticket-Shop ist im Moment nicht aktiv."
|
||||
msgstr "Dieser Ticketshop ist im Moment nicht aktiv."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/offline.html:10
|
||||
msgid "It is only accessible to authenticated team members."
|
||||
@@ -33684,7 +33684,7 @@ msgid ""
|
||||
"open source ticket sales software</a>."
|
||||
msgstr ""
|
||||
"Dies ist eine selbst-gehostete Installation von <a %(a_attr)s>pretix, dem "
|
||||
"freundlichen Open Source Ticket-Shop</a>."
|
||||
"freundlichen Open Source Ticketshop</a>."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/index.html:15
|
||||
msgid ""
|
||||
@@ -34215,7 +34215,7 @@ msgstr ""
|
||||
|
||||
#: pretix/presale/views/widget.py:372
|
||||
msgid "This ticket shop is currently disabled."
|
||||
msgstr "Dieser Ticket-Shop ist im Moment nicht verfügbar."
|
||||
msgstr "Dieser Ticketshop ist im Moment nicht verfügbar."
|
||||
|
||||
#: pretix/presale/views/widget.py:386
|
||||
msgid "The selected date does not exist in this event series."
|
||||
@@ -34336,7 +34336,7 @@ msgstr "Kosovo"
|
||||
#~ msgstr "Sie können nicht fortfahren."
|
||||
|
||||
#~ msgid "The selected ticket shop is currently not available."
|
||||
#~ msgstr "Der ausgewählte Ticket-Shop ist im Moment nicht verfügbar."
|
||||
#~ msgstr "Der ausgewählte Ticketshop ist im Moment nicht verfügbar."
|
||||
|
||||
#~ msgid "Needs to be enabled in your Stripe account first."
|
||||
#~ msgstr "Muss erst im Stripe-Account aktiviert werden."
|
||||
|
||||
@@ -871,12 +871,12 @@ msgstr "minimale Bestellmenge: %s"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:39
|
||||
msgctxt "widget"
|
||||
msgid "Close ticket shop"
|
||||
msgstr "Ticket-Shop schließen"
|
||||
msgstr "Ticketshop schließen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:40
|
||||
msgctxt "widget"
|
||||
msgid "The ticket shop could not be loaded."
|
||||
msgstr "Der Ticket-Shop konnte nicht geladen werden."
|
||||
msgstr "Der Ticketshop konnte nicht geladen werden."
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:41
|
||||
msgctxt "widget"
|
||||
@@ -890,7 +890,7 @@ msgstr ""
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:43
|
||||
msgctxt "widget"
|
||||
msgid "Open ticket shop"
|
||||
msgstr "Ticket-Shop öffnen"
|
||||
msgstr "Ticketshop öffnen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:44
|
||||
msgctxt "widget"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-06-30 18:55+0000\n"
|
||||
"PO-Revision-Date: 2024-06-30 21:07+0000\n"
|
||||
"PO-Revision-Date: 2024-07-02 19:00+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix/de_Informal/>\n"
|
||||
@@ -3536,7 +3536,7 @@ msgstr "Sie können keinen Ticketcode verwenden, der bereits existiert."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:490
|
||||
msgid "Please enter a valid language code."
|
||||
msgstr "Bitte gib einen gültigen Sprachcode ein."
|
||||
msgstr "Bitte einen gültigen Sprachcode eingeben."
|
||||
|
||||
#: pretix/base/modelimport_orders.py:558 pretix/base/modelimport_orders.py:560
|
||||
msgid "Please enter a valid sales channel."
|
||||
@@ -9594,7 +9594,7 @@ msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:1346
|
||||
msgid "Ask search engines not to index the ticket shop"
|
||||
msgstr "Der Ticket-Shop soll von Suchmaschinen nicht indiziert werden"
|
||||
msgstr "Der Ticketshop soll von Suchmaschinen nicht indiziert werden"
|
||||
|
||||
#: pretix/base/settings.py:1355
|
||||
msgid "Show variations of a product expanded by default"
|
||||
@@ -10856,7 +10856,7 @@ msgstr ""
|
||||
"du hast dich auf die Warteliste für {event} \n"
|
||||
"für das Produkt {product} eingetragen.\n"
|
||||
"\n"
|
||||
"Wir haben nun ein Ticket für dich! Du kannst es in unserem Ticket-Shop "
|
||||
"Wir haben nun ein Ticket für dich! Du kannst es in unserem Ticketshop "
|
||||
"erwerben,\n"
|
||||
"indem du in den nächsten {hours} Stunden den folgenden Gutscheincode "
|
||||
"eingibst:\n"
|
||||
@@ -11950,7 +11950,7 @@ msgid ""
|
||||
"If you just configured this as a domain for your ticket shop, you now need "
|
||||
"to set this up as a \"custom domain\" in your organizer account."
|
||||
msgstr ""
|
||||
"Wenn du gerade diese Domain für deinen Ticket-Shop eingerichtet hast, musst "
|
||||
"Wenn du gerade diese Domain für deinen Ticketshop eingerichtet hast, musst "
|
||||
"du diese nun in deinem Veranstalterkonto als \"eigene Domain\" eintragen."
|
||||
|
||||
#: pretix/base/templates/403.html:4 pretix/base/templates/403.html:8
|
||||
@@ -18371,7 +18371,7 @@ msgid ""
|
||||
"You can instead take your shop offline. This will hide it from everyone "
|
||||
"except from the organizer teams you configured to have access to the event."
|
||||
msgstr ""
|
||||
"Du kannst stattdessen den Ticket-Shop abschalten. Dies wird die "
|
||||
"Du kannst stattdessen den Ticketshop abschalten. Dies wird die "
|
||||
"Veranstaltung vor allen außer den zugewiesenen Veranstalter-Teams verstecken."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/delete.html:66
|
||||
@@ -18596,14 +18596,14 @@ msgid ""
|
||||
"Your ticket shop is currently not live. It is thus only visible to you and "
|
||||
"your team, not to any visitors."
|
||||
msgstr ""
|
||||
"Dein Ticket-Shop ist zur Zeit offline und daher nur für dich und dein Team "
|
||||
"Dein Ticketshop ist zur Zeit offline und daher nur für dich und dein Team "
|
||||
"verfügbar und nicht für Besucher."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:41
|
||||
msgid ""
|
||||
"To publish your ticket shop, you first need to resolve the following issues:"
|
||||
msgstr ""
|
||||
"Um deinen Ticket-Shop zu veröffentlichen, musst du zuerst die folgenden "
|
||||
"Um deinen Ticketshop zu veröffentlichen, musst du zuerst die folgenden "
|
||||
"Probleme beheben:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:51
|
||||
@@ -18613,7 +18613,7 @@ msgstr "Shop veröffentlichen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:59
|
||||
msgid "If you want to, you can publish your ticket shop now."
|
||||
msgstr "Du kannst deinen Ticket-Shop jederzeit veröffentlichen."
|
||||
msgstr "Du kannst deinen Ticketshop jederzeit veröffentlichen."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/live.html:83
|
||||
msgid ""
|
||||
@@ -19454,7 +19454,7 @@ msgid ""
|
||||
"website. This way, your visitors can buy their ticket right away without "
|
||||
"leaving your website."
|
||||
msgstr ""
|
||||
"Das pretix-Widget ist ein Weg, den Ticket-Shop in deine Event-Website "
|
||||
"Das pretix-Widget ist ein Weg, den Ticketshop in deine Event-Website "
|
||||
"einzubetten. Auf diese Weise können Besucher deiner Website ein Ticket "
|
||||
"erwerben, ohne die Website verlassen zu müssen."
|
||||
|
||||
@@ -19481,7 +19481,7 @@ msgid ""
|
||||
"JavaScript is disabled in your browser. To access our ticket shop without "
|
||||
"JavaScript, please <a %(a_attr)s>click here</a>."
|
||||
msgstr ""
|
||||
"JavaScript ist in deinem Browser deaktiviert. Um unseren Ticket-Shop ohne "
|
||||
"JavaScript ist in deinem Browser deaktiviert. Um unseren Ticketshop ohne "
|
||||
"JavaScript aufzurufen, klicke bitte <a %(a_attr)s>hier</a>."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/widget.html:64
|
||||
@@ -19546,7 +19546,7 @@ msgid ""
|
||||
"less than 10 characters that can be easily remembered, but you can also "
|
||||
"choose to use a random value."
|
||||
msgstr ""
|
||||
"Dies ist die Adresse, unter der dein Ticket-Shop verfügbar sein wird. Sie "
|
||||
"Dies ist die Adresse, unter der dein Ticketshop verfügbar sein wird. Sie "
|
||||
"sollte kurz sein und darf nur Kleinbuchstaben, Zahlen, Punkte und "
|
||||
"Bindestriche enthalten. Sie muss unter deinen Veranstaltungen einmalig sein. "
|
||||
"Wir empfehlen eine Abkürzung oder ein Datum mit unter 10 Zeichen, das man "
|
||||
@@ -22425,7 +22425,7 @@ msgstr "Veröffentliche deinen Shop"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/index.html:27
|
||||
msgid "Go to the ticket shop"
|
||||
msgstr "Zum Ticket-Shop"
|
||||
msgstr "Zum Ticketshop"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/index.html:35
|
||||
msgid "Search query:"
|
||||
@@ -23063,7 +23063,7 @@ msgid ""
|
||||
"usage, the legal details in your specific jurisdiction, or the agreements "
|
||||
"you have with third parties such as payment or tracking providers."
|
||||
msgstr ""
|
||||
"Trotzdem bleibt es deine Verantwortung, dass dein Ticket-Shop allen "
|
||||
"Trotzdem bleibt es deine Verantwortung, dass dein Ticketshop allen "
|
||||
"anwendbaren Gesetzen entspricht. Wir versuchen mit diesen Einstellungen zu "
|
||||
"helfen, aber können keine Haftung übernehmen, da wir unter anderem die "
|
||||
"genaue Konfiguration deines Ticketshops, die rechtlichen Details der "
|
||||
@@ -25579,7 +25579,7 @@ msgstr "{quota} übrig"
|
||||
|
||||
#: pretix/control/views/dashboards.py:269
|
||||
msgid "Your ticket shop is"
|
||||
msgstr "Dein Ticket-Shop ist"
|
||||
msgstr "Dein Ticketshop ist"
|
||||
|
||||
#: pretix/control/views/dashboards.py:269
|
||||
msgid "Click here to change"
|
||||
@@ -31432,7 +31432,7 @@ msgstr "Warnung"
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:127
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:201
|
||||
msgid "This ticket shop is currently in test mode."
|
||||
msgstr "Dieser Ticket-Shop ist momentan im Testmodus."
|
||||
msgstr "Dieser Ticketshop ist momentan im Testmodus."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:130
|
||||
#: pretix/presale/templates/pretixpresale/event/base.html:204
|
||||
@@ -32794,7 +32794,7 @@ msgstr "Shop ausgeschaltet"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/offline.html:9
|
||||
msgid "This ticket shop is currently turned off."
|
||||
msgstr "Dieser Ticket-Shop ist im Moment nicht aktiv."
|
||||
msgstr "Dieser Ticketshop ist im Moment nicht aktiv."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/offline.html:10
|
||||
msgid "It is only accessible to authenticated team members."
|
||||
@@ -33622,7 +33622,7 @@ msgid ""
|
||||
"open source ticket sales software</a>."
|
||||
msgstr ""
|
||||
"Dies ist eine selbst-gehostete Installation von <a %(a_attr)s>pretix, dem "
|
||||
"freundlichen Open Source Ticket-Shop</a>."
|
||||
"freundlichen Open Source Ticketshop</a>."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/index.html:15
|
||||
msgid ""
|
||||
@@ -34150,7 +34150,7 @@ msgstr ""
|
||||
|
||||
#: pretix/presale/views/widget.py:372
|
||||
msgid "This ticket shop is currently disabled."
|
||||
msgstr "Dieser Ticket-Shop ist im Moment nicht verfügbar."
|
||||
msgstr "Dieser Ticketshop ist im Moment nicht verfügbar."
|
||||
|
||||
#: pretix/presale/views/widget.py:386
|
||||
msgid "The selected date does not exist in this event series."
|
||||
@@ -34271,7 +34271,7 @@ msgstr "Kosovo"
|
||||
#~ msgstr "Du kannst daher nicht fortfahren."
|
||||
|
||||
#~ msgid "The selected ticket shop is currently not available."
|
||||
#~ msgstr "Der ausgewählte Ticket-Shop ist im Moment nicht verfügbar."
|
||||
#~ msgstr "Der ausgewählte Ticketshop ist im Moment nicht verfügbar."
|
||||
|
||||
#~ msgid "Needs to be enabled in your Stripe account first."
|
||||
#~ msgstr "Muss erst im Stripe-Account aktiviert werden."
|
||||
|
||||
@@ -870,12 +870,12 @@ msgstr "minimale Bestellmenge: %s"
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:39
|
||||
msgctxt "widget"
|
||||
msgid "Close ticket shop"
|
||||
msgstr "Ticket-Shop schließen"
|
||||
msgstr "Ticketshop schließen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:40
|
||||
msgctxt "widget"
|
||||
msgid "The ticket shop could not be loaded."
|
||||
msgstr "Der Ticket-Shop konnte nicht geladen werden."
|
||||
msgstr "Der Ticketshop konnte nicht geladen werden."
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:41
|
||||
msgctxt "widget"
|
||||
@@ -889,7 +889,7 @@ msgstr ""
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:43
|
||||
msgctxt "widget"
|
||||
msgid "Open ticket shop"
|
||||
msgstr "Ticket-Shop öffnen"
|
||||
msgstr "Ticketshop öffnen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:44
|
||||
msgctxt "widget"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-06-30 18:55+0000\n"
|
||||
"PO-Revision-Date: 2024-06-27 17:00+0000\n"
|
||||
"PO-Revision-Date: 2024-07-01 16:00+0000\n"
|
||||
"Last-Translator: Anarion Dunedain <anarion80@gmail.com>\n"
|
||||
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix/pl/"
|
||||
">\n"
|
||||
@@ -122,7 +122,7 @@ msgstr "Słowacki"
|
||||
|
||||
#: pretix/_base_settings.py:103
|
||||
msgid "Swedish"
|
||||
msgstr ""
|
||||
msgstr "Szwedzki"
|
||||
|
||||
#: pretix/_base_settings.py:104
|
||||
msgid "Spanish"
|
||||
@@ -640,13 +640,15 @@ msgstr "Sklep online"
|
||||
|
||||
#: pretix/base/channels.py:174
|
||||
msgid "API"
|
||||
msgstr ""
|
||||
msgstr "API"
|
||||
|
||||
#: pretix/base/channels.py:175
|
||||
msgid ""
|
||||
"API sales channels come with no built-in functionality, but may be used for "
|
||||
"custom integrations."
|
||||
msgstr ""
|
||||
"Kanały sprzedaży API nie mają wbudowanych funkcji, ale mogą być używane do "
|
||||
"niestandardowych integracji."
|
||||
|
||||
#: pretix/base/context.py:45
|
||||
#, python-brace-format
|
||||
@@ -4041,10 +4043,8 @@ msgid "Position"
|
||||
msgstr "Pozycja"
|
||||
|
||||
#: pretix/base/models/discount.py:68
|
||||
#, fuzzy
|
||||
#| msgid "Sales channels"
|
||||
msgid "All supported sales channels"
|
||||
msgstr "Kanały sprzedaży"
|
||||
msgstr "Wszystkie obsługiwane kanały sprzedaży"
|
||||
|
||||
#: pretix/base/models/discount.py:89
|
||||
msgid "Event series handling"
|
||||
@@ -4257,10 +4257,8 @@ msgid "Seating plan"
|
||||
msgstr "Plan miejsc"
|
||||
|
||||
#: pretix/base/models/event.py:639 pretix/base/models/items.py:618
|
||||
#, fuzzy
|
||||
#| msgid "Sales channels"
|
||||
msgid "Sell on all sales channels"
|
||||
msgstr "Kanały sprzedaży"
|
||||
msgstr "Sprzedawaj we wszystkich kanałach sprzedaży"
|
||||
|
||||
#: pretix/base/models/event.py:644 pretix/base/models/items.py:623
|
||||
#: pretix/base/models/items.py:1170 pretix/base/payment.py:417
|
||||
@@ -4570,9 +4568,6 @@ msgid "{category} (Add-On products)"
|
||||
msgstr "{category} (Produkty dodatkowe)"
|
||||
|
||||
#: pretix/base/models/items.py:128
|
||||
#, fuzzy
|
||||
#| msgctxt "checkoutflow"
|
||||
#| msgid "Add-on products"
|
||||
msgid "Add-On products"
|
||||
msgstr "Produkty dodatkowe"
|
||||
|
||||
@@ -4859,11 +4854,8 @@ msgstr ""
|
||||
"przeceny. Ustawienie kosmetyczne bez wzgędlu na faktyczną cenę sprzedaży."
|
||||
|
||||
#: pretix/base/models/items.py:624
|
||||
#, fuzzy
|
||||
#| msgid "Only sell tickets for this event on the following sales channels."
|
||||
msgid "Only sell tickets for this product on the selected sales channels."
|
||||
msgstr ""
|
||||
"Sprzedaj bilety tylko na to wydarzenie na następujących kanałach sprzedaży."
|
||||
msgstr "Sprzedaj bilety na ten produkt tylko w wybranych kanałach sprzedaży."
|
||||
|
||||
#: pretix/base/models/items.py:629
|
||||
msgid ""
|
||||
@@ -5114,6 +5106,8 @@ msgstr "Ten wariant nie będzie sprzedawany po podanej dacie."
|
||||
#: pretix/base/models/items.py:1165
|
||||
msgid "Sell on all sales channels the product is sold on"
|
||||
msgstr ""
|
||||
"Sprzedaj we wszystkich kanałach sprzedaży, w których sprzedawany jest ten "
|
||||
"produkt."
|
||||
|
||||
#: pretix/base/models/items.py:1171
|
||||
msgid ""
|
||||
@@ -6053,9 +6047,6 @@ msgstr "Zaproszenie do zespołu '{team}' dla '{email}'"
|
||||
|
||||
#: pretix/base/models/organizer.py:538
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channels.html:23
|
||||
#, fuzzy
|
||||
#| msgctxt "reusable_medium"
|
||||
#| msgid "Identifier"
|
||||
msgid "Identifier"
|
||||
msgstr "Identyfikator"
|
||||
|
||||
@@ -12050,6 +12041,8 @@ msgid ""
|
||||
"This sales channel cannot be used properly since the respective plugin is "
|
||||
"not active for this event."
|
||||
msgstr ""
|
||||
"Ten kanał sprzedaży nie może być używany prawidłowo, ponieważ odpowiednia "
|
||||
"wtyczka nie jest aktywna dla tego wydarzenia."
|
||||
|
||||
#: pretix/base/templates/pretixbase/forms/widgets/portrait_image.html:10
|
||||
msgid "Upload photo"
|
||||
@@ -14061,6 +14054,8 @@ msgid ""
|
||||
"You have selected dynamic validity but have not entered a time period. This "
|
||||
"would render the tickets unusable."
|
||||
msgstr ""
|
||||
"Wybrałeś dynamiczną ważność, ale nie wprowadziłeś okresu czasu. Spowoduje "
|
||||
"to, że bilety będą bezużyteczne."
|
||||
|
||||
#: pretix/control/forms/item.py:858
|
||||
#, python-format
|
||||
@@ -14807,10 +14802,8 @@ msgid "The selected organizer has already been invited."
|
||||
msgstr "Wybrany organizator został już zaproszony."
|
||||
|
||||
#: pretix/control/forms/organizer.py:1128
|
||||
#, fuzzy
|
||||
#| msgid "A voucher with this code already exists."
|
||||
msgid "A sales channel with the same identifier already exists."
|
||||
msgstr "Voucher o tym kodzie już istnieje."
|
||||
msgstr "Kanał sprzedaży o tym samym identyfikatorze już istnieje."
|
||||
|
||||
#: pretix/control/forms/renderers.py:56
|
||||
#: pretix/control/templates/pretixcontrol/items/question_edit.html:139
|
||||
@@ -15423,23 +15416,16 @@ msgid "The membership type has been deleted."
|
||||
msgstr "Typ członkostwa został usunięty."
|
||||
|
||||
#: pretix/control/logdisplay.py:360 pretix/control/views/organizer.py:3119
|
||||
#, fuzzy
|
||||
#| msgctxt "subevent"
|
||||
#| msgid "The new date has been created."
|
||||
msgid "The sales channel has been created."
|
||||
msgstr "Nowa data została utworzona."
|
||||
msgstr "Kanał sprzedaży został utworzony."
|
||||
|
||||
#: pretix/control/logdisplay.py:361
|
||||
#, fuzzy
|
||||
#| msgid "The device has been changed."
|
||||
msgid "The sales channel has been changed."
|
||||
msgstr "Urządzenie zostało zmienione."
|
||||
msgstr "Kanał sprzedaży został zmieniony."
|
||||
|
||||
#: pretix/control/logdisplay.py:362
|
||||
#, fuzzy
|
||||
#| msgid "The selected list has been deleted."
|
||||
msgid "The sales channel has been deleted."
|
||||
msgstr "Wybrana lista została usunięta."
|
||||
msgstr "Kanał sprzedaży został usunięty."
|
||||
|
||||
#: pretix/control/logdisplay.py:363
|
||||
msgid "The account has been created."
|
||||
@@ -20190,14 +20176,14 @@ msgstr "Utwórz nową kategorię"
|
||||
#: pretix/control/templates/pretixcontrol/items/index.html:146
|
||||
#: pretix/control/templates/pretixcontrol/organizers/properties.html:54
|
||||
msgid "Move up"
|
||||
msgstr ""
|
||||
msgstr "Przesuń w górę"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/categories.html:45
|
||||
#: pretix/control/templates/pretixcontrol/items/discounts.html:142
|
||||
#: pretix/control/templates/pretixcontrol/items/index.html:147
|
||||
#: pretix/control/templates/pretixcontrol/organizers/properties.html:55
|
||||
msgid "Move down"
|
||||
msgstr ""
|
||||
msgstr "Przesuń w dół"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/categories.html:46
|
||||
#: pretix/control/templates/pretixcontrol/items/discounts.html:145
|
||||
@@ -20207,6 +20193,8 @@ msgid ""
|
||||
"Click and drag this button to reorder. Double click to show buttons for "
|
||||
"reordering."
|
||||
msgstr ""
|
||||
"Kliknij i przeciągnij ten przycisk, aby zmienić kolejność. Kliknij "
|
||||
"dwukrotnie, aby wyświetlić przyciski do zmiany kolejności."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/category.html:27
|
||||
msgid "Category history"
|
||||
@@ -20350,15 +20338,12 @@ msgstr ""
|
||||
"produktu"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/discounts.html:111
|
||||
#, fuzzy
|
||||
#| msgctxt "discount"
|
||||
#| msgid "Condition"
|
||||
msgid "Condition:"
|
||||
msgstr "Stan"
|
||||
msgstr "Stan:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/discounts.html:126
|
||||
msgid "Applies to:"
|
||||
msgstr ""
|
||||
msgstr "Dotyczy:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/fragment_quota_availability.html:3
|
||||
msgid "Closed"
|
||||
@@ -20398,12 +20383,6 @@ msgid "taxes"
|
||||
msgstr "podatki"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/index.html:10
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Below, you find a list of all available products. You can click on a "
|
||||
#| "product name to inspect and change product details. You can also use the "
|
||||
#| "buttons on the right to change the order of products within a give "
|
||||
#| "category."
|
||||
msgid ""
|
||||
"Below, you find a list of all available products. You can click on a product "
|
||||
"name to inspect and change product details. You can also use the buttons on "
|
||||
@@ -20412,8 +20391,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Poniżej znajduje się lista wszystkich dostępnych produktów. Możesz kliknąć "
|
||||
"nazwę produktu, aby sprawdzić i zmienić jego szczegóły. Możesz także użyć "
|
||||
"przycisków po prawej stronie, aby zmienić kolejność produktów w danej "
|
||||
"kategorii."
|
||||
"przycisków po prawej stronie, aby zmienić kolejność produktów lub przenieść "
|
||||
"produkty do innej kategorii."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/index.html:19
|
||||
msgid "You haven't created any products yet."
|
||||
@@ -22479,48 +22458,34 @@ msgstr "Wyszukiwanie zamówień"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_add.html:6
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_add_choice.html:6
|
||||
#, fuzzy
|
||||
#| msgid "Sales channel"
|
||||
msgid "Add sales channel"
|
||||
msgstr "Kanał sprzedaży"
|
||||
msgstr "Dodaj kanał sprzedaży"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_add.html:13
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_edit.html:13
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channels.html:24
|
||||
#, fuzzy
|
||||
#| msgid "Scan type"
|
||||
msgid "Channel type"
|
||||
msgstr "Typ skanowania"
|
||||
msgstr "Typ kanału"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:5
|
||||
#, fuzzy
|
||||
#| msgid "Sales channel"
|
||||
msgid "Delete sales channel:"
|
||||
msgstr "Kanał sprzedaży"
|
||||
msgstr "Usuń kanał sprzedaży:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:10
|
||||
#, fuzzy
|
||||
#| msgid "Are you sure you want to delete the gate?"
|
||||
msgid "Are you sure you want to delete this sales channel?"
|
||||
msgstr "Czy na pewno chcesz usunąć bramkę?"
|
||||
msgstr "Czy na pewno chcesz usunąć ten kanał sprzedaży?"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:15
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "This membership cannot be deleted since it has been used in an order. "
|
||||
#| "Change its end date to the past instead."
|
||||
msgid ""
|
||||
"This sales channel cannot be deleted since it has already been used to sell "
|
||||
"orders or because it is a core element of the system."
|
||||
msgstr ""
|
||||
"Tego członkostwa nie można usunąć, ponieważ zostało użyte w zamówieniu. "
|
||||
"Zamiast tego zmień jego datę końcową na przeszłą."
|
||||
"Tego kanału sprzedaży nie można usunąć, ponieważ został już użyty do "
|
||||
"sprzedaży zamówień lub jest podstawowym elementem systemu."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channel_edit.html:6
|
||||
#, fuzzy
|
||||
#| msgid "Sales channel"
|
||||
msgid "Sales channel:"
|
||||
msgstr "Kanał sprzedaży"
|
||||
msgstr "Kanał sprzedaży:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channels.html:8
|
||||
msgid ""
|
||||
@@ -22528,18 +22493,17 @@ msgid ""
|
||||
"through. This is useful to unlock new revenue streams or to separate revenue "
|
||||
"between different sources for reporting purchases."
|
||||
msgstr ""
|
||||
"Na tej stronie można zarządzać różnymi kanałami sprzedaży biletów. Jest to "
|
||||
"przydatne do odblokowania nowych źródeł przychodów lub rozdzielenia "
|
||||
"przychodów między różne źródła w celu raportowania zakupów."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channels.html:15
|
||||
#, fuzzy
|
||||
#| msgid "Add a new value"
|
||||
msgid "Add a new channel"
|
||||
msgstr "Dodaj nową wartość"
|
||||
msgstr "Dodaj nowy kanał"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/channels.html:22
|
||||
#, fuzzy
|
||||
#| msgid "Change"
|
||||
msgid "Channel"
|
||||
msgstr "Zmień"
|
||||
msgstr "Kanał"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/customer.html:7
|
||||
#: pretix/control/templates/pretixcontrol/organizers/customer.html:13
|
||||
@@ -26776,34 +26740,24 @@ msgid "The customer account has been anonymized."
|
||||
msgstr "Konto klienta zostało zanonimizowane."
|
||||
|
||||
#: pretix/control/views/organizer.py:3201
|
||||
#, fuzzy
|
||||
#| msgid "This organizer can not be deleted."
|
||||
msgid "This channel can not be deleted."
|
||||
msgstr "Tego organizatora nie można usunąć."
|
||||
msgstr "Tego kanału nie można usunąć."
|
||||
|
||||
#: pretix/control/views/organizer.py:3206
|
||||
#, fuzzy
|
||||
#| msgid "The selected list has been deleted."
|
||||
msgid "The selected sales channel has been deleted."
|
||||
msgstr "Wybrana lista została usunięta."
|
||||
msgstr "Wybrany kanał sprzedaży został usunięty."
|
||||
|
||||
#: pretix/control/views/organizer.py:3208
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "The team could not be deleted as some constraints (e.g. data created by "
|
||||
#| "plug-ins) do not allow it."
|
||||
msgid ""
|
||||
"The channel could not be deleted as some constraints (e.g. data created by "
|
||||
"plug-ins) did not allow it."
|
||||
msgstr ""
|
||||
"Zespół nie mógł zostać usunięty, ponieważ niektóre ograniczenia (np. dane "
|
||||
"utworzone przez wtyczki) na to nie pozwalają."
|
||||
"Kanał nie mógł zostać usunięty, ponieważ niektóre ograniczenia (np. dane "
|
||||
"utworzone przez wtyczki) na to nie pozwoliły."
|
||||
|
||||
#: pretix/control/views/organizer.py:3232
|
||||
#, fuzzy
|
||||
#| msgid "The order of discounts has been updated."
|
||||
msgid "The order of sales channels has been updated."
|
||||
msgstr "Kolejność rabatów została zaktualizowana."
|
||||
msgstr "Kolejność kanałów sprzedaży została zaktualizowana."
|
||||
|
||||
#: pretix/control/views/pdf.py:83
|
||||
msgid "The uploaded PDF file is too large."
|
||||
@@ -28613,13 +28567,6 @@ msgid "Your PayPal account has been disconnected."
|
||||
msgstr "Twoje konto PayPal zostało odłączone."
|
||||
|
||||
#: pretix/plugins/paypal2/apps.py:40
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Accept payments with your PayPal account. In addition to regular PayPal "
|
||||
#| "payments, you can now also offer payments in a variety of local payment "
|
||||
#| "methods such as giropay, SOFORT, iDEAL and many more to your customers - "
|
||||
#| "they don't even need a PayPal account. PayPal is one of the most popular "
|
||||
#| "payment methods world-wide."
|
||||
msgid ""
|
||||
"Accept payments with your PayPal account. In addition to regular PayPal "
|
||||
"payments, you can now also offer payments in a variety of local payment "
|
||||
@@ -28629,9 +28576,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Akceptuj płatności za pomocą konta PayPal. Oprócz zwykłych płatności PayPal, "
|
||||
"możesz teraz oferować swoim klientom płatności za pomocą różnych lokalnych "
|
||||
"metod płatności, takich jak giropay, SOFORT, iDEAL i wiele innych - nie "
|
||||
"potrzebują oni nawet konta PayPal. PayPal jest jedną z najpopularniejszych "
|
||||
"metod płatności na całym świecie."
|
||||
"metod płatności, takich jak eps, iDEAL i wiele innych - nie potrzebują oni "
|
||||
"nawet konta PayPal. PayPal jest jedną z najpopularniejszych metod płatności "
|
||||
"na całym świecie."
|
||||
|
||||
#: pretix/plugins/paypal2/payment.py:99
|
||||
msgid "PayPal Merchant ID"
|
||||
@@ -28652,14 +28599,6 @@ msgid "Alternative Payment Methods"
|
||||
msgstr "Alternatywne metody płatności"
|
||||
|
||||
#: pretix/plugins/paypal2/payment.py:151
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "In addition to payments through a PayPal account, you can also offer your "
|
||||
#| "customers the option to pay with credit cards and other, local payment "
|
||||
#| "methods such as SOFORT, giropay, iDEAL, and many more - even when they do "
|
||||
#| "not have a PayPal account. Eligible payment methods will be determined "
|
||||
#| "based on the shoppers location. For German merchants, this is the direct "
|
||||
#| "successor of PayPal Plus."
|
||||
msgid ""
|
||||
"In addition to payments through a PayPal account, you can also offer your "
|
||||
"customers the option to pay with credit cards and other, local payment "
|
||||
@@ -28670,10 +28609,10 @@ msgid ""
|
||||
msgstr ""
|
||||
"Oprócz płatności za pośrednictwem konta PayPal, możesz również zaoferować "
|
||||
"swoim klientom możliwość płacenia kartami kredytowymi i innymi lokalnymi "
|
||||
"metodami płatności, takimi jak SOFORT, giropay, iDEAL i wiele innych - nawet "
|
||||
"jeśli nie mają konta PayPal. Kwalifikujące się metody płatności zostaną "
|
||||
"określone na podstawie lokalizacji kupującego. Dla niemieckich sprzedawców "
|
||||
"jest to bezpośredni następca PayPal Plus."
|
||||
"metodami płatności, takimi jak eps, iDEAL i wiele innych - nawet jeśli nie "
|
||||
"mają konta PayPal. Kwalifikujące się metody płatności zostaną określone na "
|
||||
"podstawie lokalizacji kupującego. Dla niemieckich sprzedawców jest to "
|
||||
"bezpośredni następca PayPal Plus."
|
||||
|
||||
#: pretix/plugins/paypal2/payment.py:166
|
||||
msgid "Disable SEPA Direct Debit"
|
||||
@@ -29880,11 +29819,6 @@ msgid "Stripe"
|
||||
msgstr "Stripe"
|
||||
|
||||
#: pretix/plugins/stripe/apps.py:40
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Accept payments via Stripe, a globally popular payment service provider. "
|
||||
#| "Stripe supports payments via credit cards as well as many local payment "
|
||||
#| "methods such as giropay, iDEAL, Alipay,and many more."
|
||||
msgid ""
|
||||
"Accept payments via Stripe, a globally popular payment service provider. "
|
||||
"Stripe supports payments via credit cards as well as many local payment "
|
||||
@@ -33278,6 +33212,9 @@ msgid ""
|
||||
"been added to the waiting list. We will only contact you once a spot opens "
|
||||
"up."
|
||||
msgstr ""
|
||||
"Po dodaniu do listy oczekujących <strong>nie</strong> otrzymasz wiadomość e-"
|
||||
"mail z potwierdzeniem. Skontaktujemy się z Tobą dopiero, gdy zwolni się "
|
||||
"miejsce."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:44
|
||||
msgid "Add me to the list"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -119,6 +119,7 @@ class CheckInListMixin(BaseExporter):
|
||||
choices=[
|
||||
('name', _('Attendee name')),
|
||||
('code', _('Order code')),
|
||||
('order_datetime', _('Order date')),
|
||||
] + ([
|
||||
('name:{}'.format(k), _('Attendee name: {part}').format(part=label))
|
||||
for k, label, w in name_scheme['fields']
|
||||
@@ -229,6 +230,8 @@ class CheckInListMixin(BaseExporter):
|
||||
)
|
||||
elif sort == 'code':
|
||||
qs = qs.order_by(*o, 'order__code')
|
||||
elif sort == 'order_datetime':
|
||||
qs = qs.order_by(*o, '-order__datetime')
|
||||
elif sort.startswith('name:'):
|
||||
part = sort[5:]
|
||||
qs = qs.annotate(
|
||||
@@ -516,6 +519,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
|
||||
headers.append(_('Order time'))
|
||||
headers.append(_('Requires special attention'))
|
||||
headers.append(_('Comment'))
|
||||
headers.append(_('Check-in text'))
|
||||
headers.append(_('Seat ID'))
|
||||
headers.append(_('Seat name'))
|
||||
headers.append(_('Seat zone'))
|
||||
@@ -623,6 +627,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
|
||||
row.append(op.order.datetime.astimezone(self.event.timezone).strftime('%H:%M:%S'))
|
||||
row.append(_('Yes') if op.require_checkin_attention else _('No'))
|
||||
row.append(op.order.comment or "")
|
||||
row.append("\n".join(text for text in [op.order.checkin_text, op.item.checkin_text] if text))
|
||||
|
||||
if op.seat:
|
||||
row += [
|
||||
|
||||
@@ -949,6 +949,9 @@ class PaypalMethod(BasePaymentProvider):
|
||||
}
|
||||
})
|
||||
response = self.client.execute(req)
|
||||
except KeyError:
|
||||
raise PaymentException(_('Refunding the amount via PayPal failed: The original payment does not contain '
|
||||
'the required information to issue an automated refund.'))
|
||||
except IOError as e:
|
||||
refund.order.log_action('pretix.event.order.refund.failed', {
|
||||
'local_id': refund.local_id,
|
||||
|
||||
@@ -163,7 +163,7 @@ def signal_process_response(sender, request: HttpRequest, response: HttpResponse
|
||||
# 'frame-src': ['https://www.paypal.com', 'https://www.sandbox.paypal.com', "'nonce-{}'".format(_nonce(request))],
|
||||
'frame-src': ['https:', "'nonce-{}'".format(_nonce(request))],
|
||||
'connect-src': ['https://www.paypal.com', 'https://www.sandbox.paypal.com'], # Or not - seems to only affect PayPal logging...
|
||||
'img-src': ['https://t.paypal.com'],
|
||||
'img-src': ['https://t.paypal.com', 'https://www.paypalobjects.com'],
|
||||
'style-src': ["'unsafe-inline'"] # PayPal does not comply with our nonce unfortunately, see Z#23113213
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ seatingframe_html_head = EventPluginSignal()
|
||||
"""
|
||||
Arguments: ``request``
|
||||
|
||||
**Temporary workaround, might be removed again later.**
|
||||
This signal allows you to put code inside the HTML ``<head>`` tag
|
||||
of the seatingframe page in the frontend. You will get the request as the keyword argument
|
||||
``request`` and are expected to return plain HTML.
|
||||
|
||||
@@ -151,7 +151,7 @@ def get_grouped_items(event, *, channel: SalesChannel, subevent=None, voucher=No
|
||||
),
|
||||
).filter(
|
||||
variation_q,
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=channel),
|
||||
active=True,
|
||||
quotas__isnull=False,
|
||||
subevent_disabled=False
|
||||
@@ -685,7 +685,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
add_subevents_for_days(
|
||||
filter_qs_by_attr(
|
||||
self.request.event.subevents_annotated(
|
||||
self.request.sales_channel.identifier,
|
||||
self.request.sales_channel,
|
||||
voucher,
|
||||
).using(settings.DATABASE_REPLICA),
|
||||
self.request
|
||||
@@ -744,7 +744,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
add_subevents_for_days(
|
||||
filter_qs_by_attr(
|
||||
self.request.event.subevents_annotated(
|
||||
self.request.sales_channel.identifier,
|
||||
self.request.sales_channel,
|
||||
voucher=voucher,
|
||||
).using(settings.DATABASE_REPLICA),
|
||||
self.request
|
||||
@@ -793,7 +793,7 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
context['subevent_list'] = self.request.event.subevents_sorted(
|
||||
filter_qs_by_attr(
|
||||
self.request.event.subevents_annotated(
|
||||
self.request.sales_channel.identifier,
|
||||
self.request.sales_channel,
|
||||
voucher=voucher,
|
||||
).using(settings.DATABASE_REPLICA),
|
||||
self.request
|
||||
|
||||
@@ -185,7 +185,7 @@ class EventListMixin:
|
||||
def _get_event_list_queryset(self):
|
||||
query = Q(is_public=True) & Q(live=True)
|
||||
qs = self.request.organizer.events.using(settings.DATABASE_REPLICA).filter(query)
|
||||
qs = qs.filter(Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier))
|
||||
qs = qs.filter(Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel))
|
||||
qs = qs.annotate(
|
||||
min_from=Min('subevents__date_from'),
|
||||
min_to=Min('subevents__date_to'),
|
||||
@@ -213,7 +213,7 @@ class EventListMixin:
|
||||
).order_by('order_from')
|
||||
qs = Event.annotated(filter_qs_by_attr(
|
||||
qs, self.request, match_subevents_with_conditions=Q(active=True) & Q(is_public=True) & date_q
|
||||
))
|
||||
), self.request.sales_channel)
|
||||
return qs
|
||||
|
||||
def _set_month_to_next_subevent(self):
|
||||
@@ -724,10 +724,10 @@ class CalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
|
||||
ctx['has_before'], ctx['has_after'] = has_before_after(
|
||||
self.request.organizer.events.filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
),
|
||||
SubEvent.objects.filter(
|
||||
Q(event__all_sales_channels=True) | Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__all_sales_channels=True) | Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
@@ -746,14 +746,14 @@ class CalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
def _events_by_day(self, before, after):
|
||||
ebd = defaultdict(list)
|
||||
timezones = set()
|
||||
add_events_for_days(self.request, Event.annotated(self.request.organizer.events, 'web').using(
|
||||
add_events_for_days(self.request, Event.annotated(self.request.organizer.events, self.request.sales_channel).using(
|
||||
settings.DATABASE_REPLICA
|
||||
).filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
), before, after, ebd, timezones)
|
||||
add_subevents_for_days(filter_qs_by_attr(SubEvent.annotated(SubEvent.objects.filter(
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
@@ -768,7 +768,7 @@ class CalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
)
|
||||
)
|
||||
)
|
||||
)), self.request).using(settings.DATABASE_REPLICA), before, after, ebd, timezones)
|
||||
), self.request.sales_channel), self.request).using(settings.DATABASE_REPLICA), before, after, ebd, timezones)
|
||||
self._multiple_timezones = len(timezones) > 1
|
||||
return ebd
|
||||
|
||||
@@ -807,11 +807,11 @@ class WeekCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
|
||||
ctx['has_before'], ctx['has_after'] = has_before_after(
|
||||
self.request.organizer.events.filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
),
|
||||
SubEvent.objects.filter(
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
@@ -842,14 +842,14 @@ class WeekCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
def _events_by_day(self, before, after):
|
||||
ebd = defaultdict(list)
|
||||
timezones = set()
|
||||
add_events_for_days(self.request, Event.annotated(self.request.organizer.events, 'web').using(
|
||||
add_events_for_days(self.request, Event.annotated(self.request.organizer.events, self.request.sales_channel).using(
|
||||
settings.DATABASE_REPLICA
|
||||
).filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
), before, after, ebd, timezones)
|
||||
add_subevents_for_days(filter_qs_by_attr(SubEvent.annotated(SubEvent.objects.filter(
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
@@ -864,7 +864,7 @@ class WeekCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
)
|
||||
)
|
||||
)
|
||||
)), self.request).using(settings.DATABASE_REPLICA), before, after, ebd, timezones)
|
||||
), self.request.sales_channel), self.request).using(settings.DATABASE_REPLICA), before, after, ebd, timezones)
|
||||
self._multiple_timezones = len(timezones) > 1
|
||||
return ebd
|
||||
|
||||
@@ -946,11 +946,11 @@ class DayCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
|
||||
ctx['has_before'], ctx['has_after'] = has_before_after(
|
||||
self.request.organizer.events.filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
),
|
||||
SubEvent.objects.filter(
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
@@ -1194,14 +1194,14 @@ class DayCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
def _events_by_day(self, before, after):
|
||||
ebd = defaultdict(list)
|
||||
timezones = set()
|
||||
add_events_for_days(self.request, Event.annotated(self.request.organizer.events, 'web').using(
|
||||
add_events_for_days(self.request, Event.annotated(self.request.organizer.events, self.request.sales_channel).using(
|
||||
settings.DATABASE_REPLICA
|
||||
).filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
), before, after, ebd, timezones)
|
||||
add_subevents_for_days(filter_qs_by_attr(SubEvent.annotated(SubEvent.objects.filter(
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
@@ -1216,7 +1216,7 @@ class DayCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
|
||||
)
|
||||
)
|
||||
)
|
||||
)), self.request).using(settings.DATABASE_REPLICA), before, after, ebd, timezones)
|
||||
), self.request.sales_channel), self.request).using(settings.DATABASE_REPLICA), before, after, ebd, timezones)
|
||||
self._multiple_timezones = len(timezones) > 1
|
||||
return ebd
|
||||
|
||||
@@ -1229,7 +1229,7 @@ class OrganizerIcalDownload(OrganizerViewMixin, View):
|
||||
filter_qs_by_attr(
|
||||
self.request.organizer.events.filter(
|
||||
Q(date_from__gt=cutoff) | Q(date_to__gt=cutoff),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
is_public=True,
|
||||
live=True,
|
||||
has_subevents=False,
|
||||
@@ -1250,7 +1250,7 @@ class OrganizerIcalDownload(OrganizerViewMixin, View):
|
||||
SubEvent.objects.filter(
|
||||
Q(date_from__gt=cutoff) | Q(date_to__gt=cutoff),
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
event__organizer=self.request.organizer,
|
||||
event__is_public=True,
|
||||
event__live=True,
|
||||
|
||||
@@ -545,9 +545,9 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
if hasattr(self.request, 'event'):
|
||||
add_subevents_for_days(
|
||||
filter_qs_by_attr(
|
||||
self.request.event.subevents_annotated('web').filter(
|
||||
self.request.event.subevents_annotated(self.request.sales_channel).filter(
|
||||
Q(event__all_sales_channels=True) |
|
||||
Q(event__limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Q(event__limit_sales_channels=self.request.sales_channel),
|
||||
), self.request
|
||||
),
|
||||
limit_before, after, ebd, set(), self.request.event,
|
||||
@@ -558,8 +558,8 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
add_events_for_days(
|
||||
self.request,
|
||||
filter_qs_by_attr(
|
||||
Event.annotated(self.request.organizer.events, 'web').filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels__identifier=self.request.sales_channel.identifier),
|
||||
Event.annotated(self.request.organizer.events, self.request.sales_channel).filter(
|
||||
Q(all_sales_channels=True) | Q(limit_sales_channels=self.request.sales_channel),
|
||||
), self.request
|
||||
),
|
||||
limit_before, after, ebd, timezones
|
||||
@@ -572,7 +572,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
event__live=True,
|
||||
).prefetch_related(
|
||||
'event___settings_objects', 'event__organizer___settings_objects'
|
||||
)), self.request), limit_before, after, ebd, timezones)
|
||||
), self.request.sales_channel), self.request), limit_before, after, ebd, timezones)
|
||||
|
||||
data['weeks'] = weeks_for_template(ebd, self.year, self.month)
|
||||
for w in data['weeks']:
|
||||
@@ -605,7 +605,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
ebd = defaultdict(list)
|
||||
if hasattr(self.request, 'event'):
|
||||
add_subevents_for_days(
|
||||
filter_qs_by_attr(self.request.event.subevents_annotated('web'), self.request),
|
||||
filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel), self.request),
|
||||
limit_before, after, ebd, set(), self.request.event,
|
||||
kwargs.get('cart_namespace')
|
||||
)
|
||||
@@ -613,7 +613,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
timezones = set()
|
||||
add_events_for_days(
|
||||
self.request,
|
||||
filter_qs_by_attr(Event.annotated(self.request.organizer.events, 'web'), self.request),
|
||||
filter_qs_by_attr(Event.annotated(self.request.organizer.events, self.request.sales_channel), self.request),
|
||||
limit_before, after, ebd, timezones
|
||||
)
|
||||
add_subevents_for_days(filter_qs_by_attr(SubEvent.annotated(SubEvent.objects.filter(
|
||||
@@ -622,7 +622,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
event__live=True,
|
||||
).prefetch_related(
|
||||
'event___settings_objects', 'event__organizer___settings_objects'
|
||||
)), self.request), limit_before, after, ebd, timezones)
|
||||
), self.request.sales_channel), self.request), limit_before, after, ebd, timezones)
|
||||
|
||||
data['days'] = days_for_template(ebd, week)
|
||||
for d in data['days']:
|
||||
@@ -632,7 +632,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
limit = 50
|
||||
if hasattr(self.request, 'event'):
|
||||
evs = filter_qs_by_attr(
|
||||
self.request.event.subevents_annotated(self.request.sales_channel.identifier),
|
||||
self.request.event.subevents_annotated(self.request.sales_channel),
|
||||
self.request,
|
||||
match_subevents_with_conditions=(
|
||||
Q(Q(date_to__isnull=True) & Q(date_from__gte=now() - timedelta(hours=24)))
|
||||
|
||||
@@ -195,7 +195,7 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
.alert-danger::before {
|
||||
background-color: $state-danger-border;
|
||||
background-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2036%2036'%20xmlns='http://www.w3.org/2000/svg'%20xml:space='preserve'%3E%3Cpath%20d='M12.14%204.62h11.64l8.24%208.24V23.4l-8.24%208.24H12.14L3.9%2023.39V12.86l8.24-8.24Z'%20fill='%23fff'/%3E%3Cpath%20d='M24.74%2022.6c0-.28-.11-.56-.31-.76l-3.27-3.27%203.27-3.27a1.08%201.08%200%200%200%200-1.52l-1.51-1.5a1.08%201.08%200%200%200-1.52%200l-3.27%203.26-3.27-3.27a1.08%201.08%200%200%200-1.52%200l-1.5%201.51a1.08%201.08%200%200%200%200%201.52l3.26%203.27-3.27%203.27a1.08%201.08%200%200%200%200%201.52l1.51%201.51a1.08%201.08%200%200%200%201.52%200l3.27-3.27%203.27%203.27a1.08%201.08%200%200%200%201.52%200l1.51-1.51c.2-.2.31-.48.31-.76Z'%20fill='#{url-friendly-colour($state-danger-text)}'/%3E%3C/svg%3E%0A");
|
||||
background-image: url('data:image/svg+xml,<svg viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"><path d="M12.14 4.62h11.64l8.24 8.24V23.4l-8.24 8.24H12.14L3.9 23.39V12.86l8.24-8.24Zm12.6 17.98c0-.28-.11-.56-.31-.76l-3.27-3.27 3.27-3.27a1.085 1.085 0 0 0 0-1.52l-1.51-1.5a1.085 1.085 0 0 0-1.52 0l-3.27 3.26-3.27-3.27a1.085 1.085 0 0 0-1.52 0l-1.5 1.51a1.085 1.085 0 0 0 0 1.52l3.26 3.27-3.27 3.27a1.085 1.085 0 0 0 0 1.52l1.51 1.51a1.085 1.085 0 0 0 1.52 0l3.27-3.27 3.27 3.27a1.085 1.085 0 0 0 1.52 0l1.51-1.51c.2-.2.31-.48.31-.76Z" style="fill:%23fff"/></svg>');
|
||||
}
|
||||
.alert-primary::before {
|
||||
background: $brand-primary !important;
|
||||
|
||||
@@ -1381,3 +1381,18 @@ def test_checkin_pdf_data_requires_permission(token_client, event, team, organiz
|
||||
organizer.slug, event.slug, clist_all.pk
|
||||
))
|
||||
assert not resp.data['results'][0].get('pdf_data')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_expand(token_client, organizer, event, clist, clist_all, item, other_item, order, django_assert_max_num_queries):
|
||||
with scopes_disabled():
|
||||
op = order.positions.first()
|
||||
var1 = item.variations.create(value="XS")
|
||||
op.variation = var1
|
||||
op.save()
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/?search=z3fsn8jyu&expand=variation'.format(
|
||||
organizer.slug, event.slug, clist_all.pk
|
||||
))
|
||||
assert resp.status_code == 200
|
||||
assert 'value' in resp.data['results'][0]['variation']
|
||||
|
||||
@@ -763,6 +763,50 @@ def test_event_update(token_client, organizer, event, item, meta_prop):
|
||||
assert cnt == event.all_logentries().count()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_event_update_plugins_validation(token_client, organizer, event, item, meta_prop):
|
||||
resp = token_client.patch(
|
||||
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
|
||||
{
|
||||
"plugins": ["pretix.plugins.paypal2", "unknown"]
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {"plugins": ["Unknown plugin: 'unknown'."]}
|
||||
|
||||
resp = token_client.patch(
|
||||
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
|
||||
{
|
||||
"plugins": ["pretix.plugins.paypal2", "tests.testdummyhidden"]
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {"plugins": ["Unknown plugin: 'tests.testdummyhidden'."]}
|
||||
|
||||
resp = token_client.patch(
|
||||
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
|
||||
{
|
||||
"plugins": ["pretix.plugins.paypal2", "tests.testdummyrestricted"]
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 400
|
||||
assert resp.data == {"plugins": ["Restricted plugin: 'tests.testdummyrestricted'."]}
|
||||
|
||||
organizer.settings.allowed_restricted_plugins = ["tests.testdummyrestricted"]
|
||||
|
||||
resp = token_client.patch(
|
||||
'/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug),
|
||||
{
|
||||
"plugins": ["pretix.plugins.paypal2", "tests.testdummyrestricted"]
|
||||
},
|
||||
format='json'
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_event_test_mode(token_client, organizer, event):
|
||||
resp = token_client.patch(
|
||||
|
||||
@@ -86,6 +86,18 @@ def test_giftcard_list(token_client, organizer, event, giftcard, other_giftcard)
|
||||
assert resp.status_code == 200
|
||||
assert 2 == len(resp.data['results'])
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/giftcards/?expired=false'.format(organizer.slug))
|
||||
assert 1 == len(resp.data['results'])
|
||||
resp = token_client.get('/api/v1/organizers/{}/giftcards/?expired=true'.format(organizer.slug))
|
||||
assert 0 == len(resp.data['results'])
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/giftcards/?value=23.00'.format(organizer.slug))
|
||||
assert 1 == len(resp.data['results'])
|
||||
resp = token_client.get('/api/v1/organizers/{}/giftcards/?value=23'.format(organizer.slug))
|
||||
assert 1 == len(resp.data['results'])
|
||||
resp = token_client.get('/api/v1/organizers/{}/giftcards/?value=24'.format(organizer.slug))
|
||||
assert 0 == len(resp.data['results'])
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_giftcard_detail(token_client, organizer, event, giftcard):
|
||||
|
||||
@@ -370,6 +370,13 @@ def test_item_list(token_client, organizer, event, team, item):
|
||||
assert resp.status_code == 200
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/items/?search=Budget'.format(organizer.slug, event.slug))
|
||||
assert resp.status_code == 200
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/items/?search=Free'.format(organizer.slug, event.slug))
|
||||
assert resp.status_code == 200
|
||||
assert [] == resp.data['results']
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_item_detail(token_client, organizer, event, team, item):
|
||||
@@ -590,7 +597,28 @@ def test_item_create_with_variation(token_client, organizer, event, item, catego
|
||||
"meta_data": {
|
||||
"day": "Wednesday",
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": {
|
||||
"de": "web",
|
||||
"en": "web"
|
||||
},
|
||||
"active": True,
|
||||
"require_approval": True,
|
||||
"checkin_attention": False,
|
||||
"checkin_text": None,
|
||||
"require_membership": False,
|
||||
"require_membership_hidden": False,
|
||||
"require_membership_types": [],
|
||||
"description": None,
|
||||
"position": 0,
|
||||
"default_price": None,
|
||||
"sales_channels": ["web"],
|
||||
"price": "23.00",
|
||||
"meta_data": {
|
||||
"day": "Wednesday",
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
format='json'
|
||||
@@ -604,6 +632,8 @@ def test_item_create_with_variation(token_client, organizer, event, item, catego
|
||||
assert new_item.variations.first().all_sales_channels is True
|
||||
assert not new_item.variations.first().limit_sales_channels.exists()
|
||||
assert new_item.variations.first().meta_data == {"day": "Wednesday"}
|
||||
assert new_item.variations.last().all_sales_channels is False
|
||||
assert new_item.variations.last().limit_sales_channels.exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -1389,6 +1419,21 @@ def test_variations_list(token_client, organizer, event, item, variation):
|
||||
assert res['position'] == resp.data['results'][0]['position']
|
||||
assert res['price'] == resp.data['results'][0]['price']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/items/{}/variations/?active=true'.format(organizer.slug, event.slug, item.pk))
|
||||
assert resp.status_code == 200
|
||||
assert res['value'] == resp.data['results'][0]['value']
|
||||
resp = token_client.get(
|
||||
'/api/v1/organizers/{}/events/{}/items/{}/variations/?active=false'.format(organizer.slug, event.slug, item.pk))
|
||||
assert resp.status_code == 200
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/items/{}/variations/?search=Child'.format(organizer.slug, event.slug, item.pk))
|
||||
assert resp.status_code == 200
|
||||
assert res['value'] == resp.data['results'][0]['value']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/items/{}/variations/?search=Incorrect'.format(organizer.slug, event.slug, item.pk))
|
||||
assert resp.status_code == 200
|
||||
assert [] == resp.data['results']
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_variations_detail(token_client, organizer, event, item, variation):
|
||||
|
||||
@@ -414,6 +414,16 @@ def test_order_list(token_client, organizer, event, order, item, taxrule, questi
|
||||
'/api/v1/organizers/{}/events/{}/orders/?email=foo@example.org'.format(organizer.slug, event.slug))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?payment_provider=banktransfer'.format(organizer.slug, event.slug))
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?payment_provider=manual'.format(organizer.slug, event.slug))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?sales_channel=web'.format(organizer.slug, event.slug))
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?sales_channel=bar'.format(organizer.slug, event.slug))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?locale=en'.format(organizer.slug, event.slug))
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?locale=de'.format(organizer.slug, event.slug))
|
||||
@@ -434,6 +444,36 @@ def test_order_list(token_client, organizer, event, order, item, taxrule, questi
|
||||
))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?created_since={}'.format(
|
||||
organizer.slug, event.slug,
|
||||
(order.datetime - datetime.timedelta(hours=1)).isoformat().replace('+00:00', 'Z')
|
||||
))
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?created_since={}'.format(
|
||||
organizer.slug, event.slug, order.datetime.isoformat().replace('+00:00', 'Z')
|
||||
))
|
||||
assert [res] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?created_since={}'.format(
|
||||
organizer.slug, event.slug,
|
||||
(order.datetime + datetime.timedelta(hours=1)).isoformat().replace('+00:00', 'Z')
|
||||
))
|
||||
assert [] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?created_before={}'.format(
|
||||
organizer.slug, event.slug,
|
||||
(order.datetime - datetime.timedelta(hours=1)).isoformat().replace('+00:00', 'Z')
|
||||
))
|
||||
assert [] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?created_before={}'.format(
|
||||
organizer.slug, event.slug, order.datetime.isoformat().replace('+00:00', 'Z')
|
||||
))
|
||||
assert [] == resp.data['results']
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?created_before={}'.format(
|
||||
organizer.slug, event.slug,
|
||||
(order.datetime + datetime.timedelta(hours=1)).isoformat().replace('+00:00', 'Z')
|
||||
))
|
||||
assert [res] == resp.data['results']
|
||||
|
||||
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?include_canceled_positions=false'.format(organizer.slug, event.slug))
|
||||
assert resp.status_code == 200
|
||||
assert len(resp.data['results'][0]['positions']) == 1
|
||||
|
||||
@@ -2329,8 +2329,8 @@ class EventTest(TestCase):
|
||||
item2 = Item.objects.create(event=event, name='Early-bird ticket', default_price=0, active=False)
|
||||
q.items.add(item)
|
||||
q.items.add(item2)
|
||||
assert Event.annotated(Event.objects).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, 'foo').first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, self.organizer.sales_channels.get(identifier="bar")).first().active_quotas == []
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_product_inactive(self):
|
||||
@@ -2341,7 +2341,7 @@ class EventTest(TestCase):
|
||||
q = Quota.objects.create(event=event, name='Quota', size=2)
|
||||
item = Item.objects.create(event=event, name='Early-bird ticket', default_price=0, active=False)
|
||||
q.items.add(item)
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_product_hidden_by_voucher(self):
|
||||
@@ -2354,16 +2354,16 @@ class EventTest(TestCase):
|
||||
q.items.add(item)
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='a', item=item, show_hidden_items=True)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == [q]
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='b', item=item, show_hidden_items=False)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == []
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='c', show_hidden_items=True)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == [q]
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='d', quota=q, show_hidden_items=True)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == [q]
|
||||
|
||||
item2 = Item.objects.create(event=event, name='Early-bird ticket', default_price=0)
|
||||
var = item2.variations.create(item=item2, value='Test', hide_without_voucher=True)
|
||||
@@ -2373,13 +2373,13 @@ class EventTest(TestCase):
|
||||
q.variations.add(var)
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='e', item=item2, variation=var, show_hidden_items=True)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == [q]
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='f', item=item2, variation=var2, show_hidden_items=True)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == []
|
||||
|
||||
voucher = Voucher.objects.create(event=event, code='g', quota=q, show_hidden_items=True)
|
||||
assert Event.annotated(Event.objects, voucher=voucher).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, "web", voucher=voucher).first().active_quotas == [q]
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_product_addon(self):
|
||||
@@ -2395,7 +2395,7 @@ class EventTest(TestCase):
|
||||
item.category = cat
|
||||
item.save()
|
||||
q.items.add(item)
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_product_unavailable(self):
|
||||
@@ -2407,7 +2407,7 @@ class EventTest(TestCase):
|
||||
item = Item.objects.create(event=event, name='Early-bird ticket', default_price=0, active=True,
|
||||
available_until=now() - timedelta(days=1))
|
||||
q.items.add(item)
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_variation_not_in_quota(self):
|
||||
@@ -2419,7 +2419,7 @@ class EventTest(TestCase):
|
||||
item = Item.objects.create(event=event, name='Early-bird ticket', default_price=0, active=True)
|
||||
item.variations.create(value="foo")
|
||||
q.items.add(item)
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_variation(self):
|
||||
@@ -2434,29 +2434,29 @@ class EventTest(TestCase):
|
||||
v.limit_sales_channels.add(self.organizer.sales_channels.get(identifier="web"))
|
||||
q.items.add(item)
|
||||
q.variations.add(v)
|
||||
assert Event.annotated(Event.objects).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == [q]
|
||||
item.available_until = now() - timedelta(days=1)
|
||||
item.save()
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
item.available_until = None
|
||||
item.available_from = now() + timedelta(days=1)
|
||||
item.save()
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
item.available_until = None
|
||||
item.available_from = None
|
||||
item.active = False
|
||||
item.save()
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
item.active = True
|
||||
item.save()
|
||||
assert Event.annotated(Event.objects).first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, 'foo').first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == [q]
|
||||
assert Event.annotated(Event.objects, self.organizer.sales_channels.get(identifier="bar")).first().active_quotas == []
|
||||
v.active = False
|
||||
v.save()
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
item.hide_without_voucher = True
|
||||
item.save()
|
||||
assert Event.annotated(Event.objects).first().active_quotas == []
|
||||
assert Event.annotated(Event.objects, 'web').first().active_quotas == []
|
||||
|
||||
|
||||
class SubEventTest(TestCase):
|
||||
@@ -2502,8 +2502,10 @@ class SubEventTest(TestCase):
|
||||
all_sales_channels=False)
|
||||
item.limit_sales_channels.add(self.organizer.sales_channels.get(identifier="web"))
|
||||
q.items.add(item)
|
||||
assert SubEvent.annotated(SubEvent.objects).first().active_quotas == [q]
|
||||
assert SubEvent.annotated(SubEvent.objects, 'foo').first().active_quotas == []
|
||||
assert SubEvent.annotated(SubEvent.objects, 'web').first().active_quotas == [q]
|
||||
assert SubEvent.annotated(SubEvent.objects, 'bar').first().active_quotas == []
|
||||
assert SubEvent.annotated(SubEvent.objects, self.organizer.sales_channels.get(identifier="web")).first().active_quotas == [q]
|
||||
assert SubEvent.annotated(SubEvent.objects, self.organizer.sales_channels.get(identifier="bar")).first().active_quotas == []
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_active_quotas_annotation_no_interference(self):
|
||||
@@ -2514,8 +2516,8 @@ class SubEventTest(TestCase):
|
||||
subevent=se2)
|
||||
item = Item.objects.create(event=self.event, name='Early-bird ticket', default_price=0, active=True)
|
||||
q.items.add(item)
|
||||
assert SubEvent.annotated(SubEvent.objects).filter(pk=self.se.pk).first().active_quotas == []
|
||||
assert SubEvent.annotated(SubEvent.objects).filter(pk=se2.pk).first().active_quotas == [q]
|
||||
assert SubEvent.annotated(SubEvent.objects, 'web').filter(pk=self.se.pk).first().active_quotas == []
|
||||
assert SubEvent.annotated(SubEvent.objects, 'web').filter(pk=se2.pk).first().active_quotas == [q]
|
||||
|
||||
@classscope(attr='organizer')
|
||||
def test_best_availability(self):
|
||||
@@ -2540,7 +2542,7 @@ class SubEventTest(TestCase):
|
||||
q = Quota.objects.create(event=self.event, name='Quota', size=1,
|
||||
subevent=self.se)
|
||||
q.items.add(item)
|
||||
obj = SubEvent.annotated(SubEvent.objects).first()
|
||||
obj = SubEvent.annotated(SubEvent.objects, 'web').first()
|
||||
assert len(obj.active_quotas) == 1
|
||||
assert obj.best_availability == (Quota.AVAILABILITY_GONE, 0, 1)
|
||||
|
||||
@@ -2548,14 +2550,14 @@ class SubEventTest(TestCase):
|
||||
q2 = Quota.objects.create(event=self.event, name='Quota 2', size=2,
|
||||
subevent=self.se)
|
||||
q2.items.add(item)
|
||||
obj = SubEvent.annotated(SubEvent.objects).first()
|
||||
obj = SubEvent.annotated(SubEvent.objects, 'web').first()
|
||||
assert len(obj.active_quotas) == 2
|
||||
assert obj.best_availability == (Quota.AVAILABILITY_GONE, 0, 1)
|
||||
|
||||
# 2 quotas - 2 items. Higher quota wins since second item is only connected to second quota.
|
||||
item2 = Item.objects.create(event=self.event, name='Regular ticket', default_price=10, active=True)
|
||||
q2.items.add(item2)
|
||||
obj = SubEvent.annotated(SubEvent.objects).first()
|
||||
obj = SubEvent.annotated(SubEvent.objects, 'web').first()
|
||||
assert len(obj.active_quotas) == 2
|
||||
assert obj.best_availability == (Quota.AVAILABILITY_OK, 1, 2)
|
||||
assert obj.best_availability_is_low
|
||||
@@ -2564,7 +2566,7 @@ class SubEventTest(TestCase):
|
||||
q.size = 10
|
||||
q.save()
|
||||
q2.delete()
|
||||
obj = SubEvent.annotated(SubEvent.objects).first()
|
||||
obj = SubEvent.annotated(SubEvent.objects, 'web').first()
|
||||
assert len(obj.active_quotas) == 1
|
||||
assert obj.best_availability == (Quota.AVAILABILITY_OK, 9, 10)
|
||||
assert not obj.best_availability_is_low
|
||||
@@ -2572,7 +2574,7 @@ class SubEventTest(TestCase):
|
||||
# Unlimited quota
|
||||
q.size = None
|
||||
q.save()
|
||||
obj = SubEvent.annotated(SubEvent.objects).first()
|
||||
obj = SubEvent.annotated(SubEvent.objects, 'web').first()
|
||||
assert obj.best_availability == (Quota.AVAILABILITY_OK, None, None)
|
||||
assert not obj.best_availability_is_low
|
||||
|
||||
|
||||
@@ -299,6 +299,8 @@ class EventsTest(SoupTest):
|
||||
doc = self.get_doc('/control/event/%s/%s/settings/plugins' % (self.orga1.slug, self.event1.slug))
|
||||
self.assertIn("Stripe", doc.select(".form-plugins")[0].text)
|
||||
self.assertIn("Enable", doc.select("[name=\"plugin:pretix.plugins.stripe\"]")[0].text)
|
||||
assert not doc.select("[name=\"plugin:tests.testdummyrestricted\"]")
|
||||
assert not doc.select("[name=\"plugin:tests.testdummyhidden\"]")
|
||||
|
||||
doc = self.post_doc('/control/event/%s/%s/settings/plugins' % (self.orga1.slug, self.event1.slug),
|
||||
{'plugin:pretix.plugins.stripe': 'enable'})
|
||||
@@ -308,6 +310,23 @@ class EventsTest(SoupTest):
|
||||
{'plugin:pretix.plugins.stripe': 'disable'})
|
||||
self.assertIn("Enable", doc.select("[name=\"plugin:pretix.plugins.stripe\"]")[0].text)
|
||||
|
||||
self.post_doc('/control/event/%s/%s/settings/plugins' % (self.orga1.slug, self.event1.slug),
|
||||
{'plugin:tests.testdummyhidden': 'enable'})
|
||||
self.event1.refresh_from_db()
|
||||
assert "testdummyhidden" not in self.event1.plugins
|
||||
|
||||
self.post_doc('/control/event/%s/%s/settings/plugins' % (self.orga1.slug, self.event1.slug),
|
||||
{'plugin:tests.testdummyrestricted': 'enable'})
|
||||
self.event1.refresh_from_db()
|
||||
assert "testdummyrestricted" not in self.event1.plugins
|
||||
|
||||
self.orga1.settings.allowed_restricted_plugins = ["tests.testdummyrestricted"]
|
||||
|
||||
self.post_doc('/control/event/%s/%s/settings/plugins' % (self.orga1.slug, self.event1.slug),
|
||||
{'plugin:tests.testdummyrestricted': 'enable'})
|
||||
self.event1.refresh_from_db()
|
||||
assert "testdummyrestricted" in self.event1.plugins
|
||||
|
||||
def test_testmode_enable(self):
|
||||
self.event1.testmode = False
|
||||
self.event1.save()
|
||||
|
||||
@@ -91,12 +91,12 @@ def test_csv_simple(event):
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title","Attendee name:
|
||||
First name","Attendee name: Middle name","Attendee name: Family name","Product","Price","Checked in","Checked out","Automatically
|
||||
checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special attention",
|
||||
"Comment","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until","Address","ZIP code",
|
||||
"Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until","Address","ZIP code",
|
||||
"City","Country","State"
|
||||
"FOO","Mr Peter A Jones","Mr","Peter","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
"FOO","Mrs Andrea J Zulu","Mrs","Andrea","J","Zulu","Ticket","13.00","","","No","ggsngqtnmhx74jswjngw3fk8pfwz2a7k",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
""")
|
||||
|
||||
|
||||
@@ -113,12 +113,12 @@ def test_csv_order_by_name_parts(event): # noqa
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title",
|
||||
"Attendee name: First name","Attendee name: Middle name","Attendee name: Family name","Product","Price",
|
||||
"Checked in","Checked out","Automatically checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special
|
||||
attention","Comment","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
attention","Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
"Address","ZIP code","City","Country","State"
|
||||
"FOO","Mrs Andrea J Zulu","Mrs","Andrea","J","Zulu","Ticket","13.00","","","No","ggsngqtnmhx74jswjngw3fk8pfwz2a7k",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
"FOO","Mr Peter A Jones","Mr","Peter","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
""")
|
||||
c = CSVCheckinList(event, organizer=event.organizer)
|
||||
_, _, content = c.render({
|
||||
@@ -131,12 +131,12 @@ def test_csv_order_by_name_parts(event): # noqa
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title",
|
||||
"Attendee name: First name","Attendee name: Middle name","Attendee name: Family name","Product","Price",
|
||||
"Checked in","Checked out","Automatically checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special
|
||||
attention","Comment","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
attention","Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
"Address","ZIP code","City","Country","State"
|
||||
"FOO","Mr Peter A Jones","Mr","Peter","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
"FOO","Mrs Andrea J Zulu","Mrs","Andrea","J","Zulu","Ticket","13.00","","","No","ggsngqtnmhx74jswjngw3fk8pfwz2a7k",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
""")
|
||||
|
||||
|
||||
@@ -184,12 +184,12 @@ def test_csv_order_by_inherited_name_parts(event): # noqa
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title",
|
||||
"Attendee name: First name","Attendee name: Middle name","Attendee name: Family name","Product","Price",
|
||||
"Checked in","Checked out","Automatically checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special
|
||||
attention","Comment","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
attention","Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
"Address","ZIP code","City","Country","State"
|
||||
"BAR","Mr Albert J Zulu","Mr","Albert","J","Zulu","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytyy",
|
||||
"dummy@dummy.test","'+498912345678","BARCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","BARCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
"FOO","Mr Paul A Jones","Mr","Paul","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","FOOCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","FOOCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
""")
|
||||
c = CSVCheckinList(event, organizer=event.organizer)
|
||||
_, _, content = c.render({
|
||||
@@ -202,12 +202,12 @@ def test_csv_order_by_inherited_name_parts(event): # noqa
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title",
|
||||
"Attendee name: First name","Attendee name: Middle name","Attendee name: Family name","Product","Price",
|
||||
"Checked in","Checked out","Automatically checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special
|
||||
attention","Comment","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
attention","Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
"Address","ZIP code","City","Country","State"
|
||||
"BAR","Mr Albert J Zulu","Mr","Albert","J","Zulu","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytyy",
|
||||
"dummy@dummy.test","'+498912345678","BARCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","BARCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
"FOO","Mr Paul A Jones","Mr","Paul","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","FOOCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","FOOCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
""")
|
||||
c = CSVCheckinList(event, organizer=event.organizer)
|
||||
_, _, content = c.render({
|
||||
@@ -220,10 +220,56 @@ def test_csv_order_by_inherited_name_parts(event): # noqa
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title",
|
||||
"Attendee name: First name","Attendee name: Middle name","Attendee name: Family name","Product","Price",
|
||||
"Checked in","Checked out","Automatically checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special
|
||||
attention","Comment","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
attention","Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until",
|
||||
"Address","ZIP code","City","Country","State"
|
||||
"FOO","Mr Paul A Jones","Mr","Paul","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","FOOCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","FOOCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
"BAR","Mr Albert J Zulu","Mr","Albert","J","Zulu","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytyy",
|
||||
"dummy@dummy.test","'+498912345678","BARCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","",""
|
||||
"dummy@dummy.test","'+498912345678","BARCORP","","2019-02-22","14:00:00","No","","","","","","","","","","","","","","",""
|
||||
""")
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_csv_order_by_orderdatetime(event):
|
||||
order1 = event.orders.first()
|
||||
order1.checkin_text = 'meow'
|
||||
order1.save()
|
||||
order2 = Order.objects.create(
|
||||
code='FOO2', event=event, email='dummy@dummy.test', phone="+498912345678",
|
||||
status=Order.STATUS_PAID,
|
||||
datetime=datetime.datetime(2019, 2, 22, 22, 0, 0, tzinfo=datetime.timezone.utc),
|
||||
expires=now() + datetime.timedelta(days=10),
|
||||
total=33, locale='en', checkin_text='beep',
|
||||
sales_channel=event.organizer.sales_channels.get(identifier="web"),
|
||||
)
|
||||
item_ticket = Item.objects.create(event=event, name="Ticket2", default_price=23, admission=True, checkin_text='boop')
|
||||
OrderPosition.objects.create(
|
||||
order=order2,
|
||||
item=item_ticket,
|
||||
variation=None,
|
||||
price=Decimal("23"),
|
||||
attendee_name_parts={"title": "Mx", "given_name": "Alex", "middle_name": "F", "family_name": "Nord"},
|
||||
secret='asdfasdfasdfasdfasdfasdfasfdasdf'
|
||||
)
|
||||
|
||||
c = CSVCheckinList(event, organizer=event.organizer)
|
||||
_, _, content = c.render({
|
||||
'list': event.checkin_lists.first().pk,
|
||||
'secrets': True,
|
||||
'sort': 'order_datetime',
|
||||
'_format': 'default',
|
||||
'questions': []
|
||||
})
|
||||
assert clean(content.decode()) == clean(""""Order code","Attendee name","Attendee name: Title","Attendee name:
|
||||
First name","Attendee name: Middle name","Attendee name: Family name","Product","Price","Checked in","Checked out","Automatically
|
||||
checked in","Secret","E-mail","Phone number","Company","Voucher code","Order date","Order time","Requires special attention",
|
||||
"Comment","Check-in text","Seat ID","Seat name","Seat zone","Seat row","Seat number","Blocked","Valid from","Valid until","Address","ZIP code",
|
||||
"City","Country","State"
|
||||
"FOO2","Mx Alex F Nord","Mx","Alex","F","Nord","Ticket2","23.00","","","No","asdfasdfasdfasdfasdfasdfasfdasdf",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","22:00:00","No","","beep\nboop","","","","","","","","","","","","",""
|
||||
"FOO","Mr Peter A Jones","Mr","Peter","A","Jones","Ticket","23.00","","","No","hutjztuxhkbtwnesv2suqv26k6ttytxx",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","meow","","","","","","","","","","","","",""
|
||||
"FOO","Mrs Andrea J Zulu","Mrs","Andrea","J","Zulu","Ticket","13.00","","","No","ggsngqtnmhx74jswjngw3fk8pfwz2a7k",
|
||||
"dummy@dummy.test","'+498912345678","","","2019-02-22","14:00:00","No","","meow","","","","","","","","","","","","",""
|
||||
""")
|
||||
|
||||
|
||||
@@ -28,6 +28,8 @@ TEST_DIR = os.path.dirname(__file__)
|
||||
TEMPLATES[0]['DIRS'].append(os.path.join(TEST_DIR, 'templates')) # NOQA
|
||||
|
||||
INSTALLED_APPS.append('tests.testdummy') # NOQA
|
||||
INSTALLED_APPS.append('tests.testdummyrestricted') # NOQA
|
||||
INSTALLED_APPS.append('tests.testdummyhidden') # NOQA
|
||||
|
||||
PRETIX_AUTH_BACKENDS = [
|
||||
'pretix.base.auth.NativeAuthBackend',
|
||||
|
||||
21
src/tests/testdummyhidden/__init__.py
Normal file
21
src/tests/testdummyhidden/__init__.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
35
src/tests/testdummyhidden/apps.py
Normal file
35
src/tests/testdummyhidden/apps.py
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class TestDummyHiddenApp(AppConfig):
|
||||
name = 'tests.testdummyhidden'
|
||||
verbose_name = 'testdummyhidden'
|
||||
|
||||
class PretixPluginMeta:
|
||||
name = 'testdummyhidden'
|
||||
version = '1.0.0'
|
||||
restricted = True
|
||||
|
||||
def is_available(self, event):
|
||||
return False
|
||||
21
src/tests/testdummyrestricted/__init__.py
Normal file
21
src/tests/testdummyrestricted/__init__.py
Normal file
@@ -0,0 +1,21 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
32
src/tests/testdummyrestricted/apps.py
Normal file
32
src/tests/testdummyrestricted/apps.py
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class TestDummyRestrictedApp(AppConfig):
|
||||
name = 'tests.testdummyrestricted'
|
||||
verbose_name = 'testdummyrestricted'
|
||||
|
||||
class PretixPluginMeta:
|
||||
name = 'testdummyrestricted'
|
||||
version = '1.0.0'
|
||||
restricted = True
|
||||
Reference in New Issue
Block a user