Compare commits

...
Author SHA1 Message Date
Raphael Michel ac9f67ee15 Improve backend UI if not qualified for invoice 2026-01-26 09:30:10 +01:00
Raphael Michel 15c2c39ac4 Invoices: Allow issuing invoices only to businesses
In situations where every invoice has a significant accounting cost and
consumers usually do not need invoices, this can save a lot of money or
effort.
2026-01-26 09:30:10 +01:00
Raphael Michel 5c8e785a6f Fix typo from merge conflict resolving 2026-01-26 09:29:22 +01:00
8e61ac6071 Invoice address: Add convenient autofill for Pepppol in Belgium (Z#23220397) (#5809)
* Invoice address: Add convenient autofill for Pepppol in Belgium (Z#23220397)

* Update src/pretix/static/pretixbase/js/addressform.js

Co-authored-by: Richard Schreiber <schreiber@pretix.eu>

---------

Co-authored-by: Richard Schreiber <schreiber@pretix.eu>
2026-01-26 09:12:07 +01:00
Raphael MichelandGitHub c3fd3a0838 Scheduled exports: Add copy button (Z#23221224) (#5823)
* Scheduled exports: Add copy button (Z#23221224)

* Update button label
2026-01-26 08:46:25 +01:00
Phin WolkwitzandGitHub 0d6e1e2271 Prefetch program times, add test for query count (#5822) 2026-01-26 08:38:44 +01:00
0af011eed4 Web check-in: Show addons of ticket (Z#23220213) (#5827)
* Web check-in: Show addons of ticket (Z#23220213)

* Update src/pretix/plugins/webcheckin/static/pretixplugins/webcheckin/components/app.vue

Co-authored-by: luelista <weller@rami.io>

---------

Co-authored-by: luelista <weller@rami.io>
2026-01-26 08:37:54 +01:00
Kian CrossandGitHub a0dae48cec Prevent double-clicks on SSO login providers (#5842) 2026-01-26 08:31:30 +01:00
Ruud HendrickxandRaphael Michel a53795ea88 Translations: Update Dutch
Currently translated at 100.0% (6193 of 6193 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Ruud HendrickxandRaphael Michel f1c0f24e25 Translations: Update Dutch
Currently translated at 100.0% (6193 of 6193 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Ruud HendrickxandRaphael Michel 980f4712a7 Translations: Update Dutch
Currently translated at 100.0% (6193 of 6193 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Ruud HendrickxandRaphael Michel bc8a8d8851 Translations: Update Dutch
Currently translated at 100.0% (254 of 254 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Ruud HendrickxandRaphael Michel 10ec4d6c29 Translations: Update Dutch
Currently translated at 100.0% (6193 of 6193 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Vajda TamásandRaphael Michel 584345cb99 Translations: Update Hungarian
Currently translated at 40.1% (102 of 254 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/hu/

powered by weblate
2026-01-26 08:26:17 +01:00
Vajda TamásandRaphael Michel 88545bcd05 Translations: Update Hungarian
Currently translated at 10.6% (657 of 6193 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/hu/

powered by weblate
2026-01-26 08:26:17 +01:00
Ruud HendrickxandRaphael Michel f034f4cde4 Translations: Update Dutch
Currently translated at 100.0% (254 of 254 strings)

Translation: pretix/pretix (JavaScript parts)
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix-js/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Ruud HendrickxandRaphael Michel fc6475b0bc Translations: Update Dutch
Currently translated at 100.0% (6193 of 6193 strings)

Translation: pretix/pretix
Translate-URL: https://translate.pretix.eu/projects/pretix/pretix/nl/

powered by weblate
2026-01-26 08:26:17 +01:00
Lukas BockstallerandGitHub aecc87ccdb handle open ended datetime ranges (#5838) 2026-01-23 12:25:28 +01:00
29 changed files with 929 additions and 763 deletions
+1
View File
@@ -806,6 +806,7 @@ class EventSettingsSerializer(SettingsSerializer):
'invoice_reissue_after_modify',
'invoice_include_free',
'invoice_generate',
'invoice_generate_only_business',
'invoice_period',
'invoice_numbers_consecutive',
'invoice_numbers_prefix',
+10
View File
@@ -704,6 +704,16 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
if 'answers.question' in self.context['expand']:
self.fields['answers'].child.fields['question'] = QuestionSerializer(read_only=True)
if 'addons' in self.context['expand']:
# Experimental feature, undocumented on purpose for now in case we need to remove it again
# for performance reasons
subl = CheckinListOrderPositionSerializer(read_only=True, many=True, context={
**self.context,
'expand': [v for v in self.context['expand'] if v != 'addons'],
'pdf_data': False,
})
self.fields['addons'] = subl
class OrderPaymentTypeField(serializers.Field):
# TODO: Remove after pretix 2.2
+37 -24
View File
@@ -381,15 +381,21 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
qs = qs.filter(reduce(operator.or_, lists_qs))
prefetch_related = [
Prefetch(
lookup='checkins',
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists]).select_related('device')
),
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
'answers', 'answers__options', 'answers__question',
]
select_related = [
'item', 'variation', 'order', 'addon_to', 'order__invoice_address', 'order', 'seat'
]
if pdf_data:
qs = qs.prefetch_related(
Prefetch(
lookup='checkins',
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists]).select_related('device')
),
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
'answers', 'answers__options', 'answers__question',
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation')),
# Don't add to list, we don't want to propagate to addons
Prefetch('order', Order.objects.select_related('invoice_address').prefetch_related(
Prefetch(
'event',
@@ -404,32 +410,39 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
)
)
))
).select_related(
'item', 'variation', 'item__category', 'addon_to', 'order', 'order__invoice_address', 'seat'
)
else:
qs = qs.prefetch_related(
Prefetch(
lookup='checkins',
queryset=Checkin.objects.filter(list_id__in=[cl.pk for cl in checkinlists]).select_related('device')
),
Prefetch('print_logs', queryset=PrintLog.objects.select_related('device')),
'answers', 'answers__options', 'answers__question',
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation'))
).select_related('item', 'variation', 'order', 'addon_to', 'order__invoice_address', 'order', 'seat')
if expand and 'subevent' in expand:
qs = qs.prefetch_related(
prefetch_related += [
'subevent', 'subevent__event', 'subevent__subeventitem_set', 'subevent__subeventitemvariation_set',
'subevent__seat_category_mappings', 'subevent__meta_values'
)
]
if expand and 'item' in expand:
qs = qs.prefetch_related('item', 'item__addons', 'item__bundles', 'item__meta_values',
'item__variations').select_related('item__tax_rule')
prefetch_related += [
'item', 'item__addons', 'item__bundles', 'item__meta_values',
'item__variations',
]
select_related.append('item__tax_rule')
if expand and 'variation' in expand:
qs = qs.prefetch_related('variation', 'variation__meta_values')
prefetch_related += [
'variation', 'variation__meta_values',
]
if expand and 'addons' in expand:
prefetch_related += [
Prefetch('addons', OrderPosition.objects.prefetch_related(*prefetch_related).select_related(*select_related)),
]
else:
prefetch_related += [
Prefetch('addons', OrderPosition.objects.select_related('item', 'variation'))
]
if pdf_data:
select_related.remove("order") # Don't need it twice on this queryset
qs = qs.prefetch_related(*prefetch_related).select_related(*select_related)
return qs
+1 -1
View File
@@ -106,7 +106,7 @@ class ItemViewSet(ConditionalListView, viewsets.ModelViewSet):
'variations', 'addons', 'bundles', 'meta_values', 'meta_values__property',
'variations__meta_values', 'variations__meta_values__property',
'require_membership_types', 'variations__require_membership_types',
'limit_sales_channels', 'variations__limit_sales_channels',
'limit_sales_channels', 'variations__limit_sales_channels', 'program_times'
).all()
def perform_create(self, serializer):
+1 -1
View File
@@ -2031,7 +2031,7 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
else:
order = Order.objects.select_for_update(of=OF_SELF).get(pk=inv.order_id)
c = generate_cancellation(inv)
if inv.order.status != Order.STATUS_CANCELED:
if invoice_qualified(order):
inv = generate_invoice(order)
else:
inv = c
+13 -2
View File
@@ -521,9 +521,20 @@ def invoice_pdf_task(invoice: int):
def invoice_qualified(order: Order):
if order.total == Decimal('0.00') or order.require_approval or \
order.sales_channel.identifier not in order.event.settings.get('invoice_generate_sales_channels'):
if order.total == Decimal('0.00'):
return False
if order.require_approval:
return False
if order.sales_channel.identifier not in order.event.settings.invoice_generate_sales_channels:
return False
if order.status in (Order.STATUS_CANCELED, Order.STATUS_EXPIRED):
return False
if order.event.settings.invoice_generate_only_business:
try:
ia = order.invoice_address
return ia.is_business
except InvoiceAddress.DoesNotExist:
return False
return True
+9
View File
@@ -1225,6 +1225,15 @@ DEFAULTS = {
'default': json.dumps(['web']),
'type': list
},
'invoice_generate_only_business': {
'default': 'False',
'type': bool,
'form_class': forms.BooleanField,
'serializer_class': serializers.BooleanField,
'form_kwargs': dict(
label=_("Only issue invoices to business customers"),
)
},
'invoice_address_from': {
'default': '',
'type': str,
+1
View File
@@ -939,6 +939,7 @@ class InvoiceSettingsForm(EventSettingsValidationMixin, SettingsForm):
'invoice_show_payments',
'invoice_reissue_after_modify',
'invoice_generate',
'invoice_generate_only_business',
'invoice_period',
'invoice_attendee_name',
'invoice_event_location',
+4 -4
View File
@@ -1315,10 +1315,10 @@ class QuestionAnswerFilterForm(forms.Form):
if date_range is not None:
d_start, d_end = resolve_timeframe_to_datetime_start_inclusive_end_exclusive(now(), date_range, self.event.timezone)
opqs = opqs.filter(
subevent__date_from__gte=d_start,
subevent__date_from__lt=d_end
)
if d_start:
opqs = opqs.filter(subevent__date_from__gte=d_start)
if d_end:
opqs = opqs.filter(subevent__date_from__lt=d_end)
s = fdata.get("status", Order.STATUS_PENDING + Order.STATUS_PAID)
if s != "":
@@ -12,6 +12,7 @@
<legend>{% trans "Invoice generation" %}</legend>
{% bootstrap_field form.invoice_generate layout="control" %}
{% bootstrap_field form.invoice_generate_sales_channels layout="control" %}
{% bootstrap_field form.invoice_generate_only_business layout="control" %}
{% bootstrap_field form.invoice_email_attachment layout="control" %}
{% bootstrap_field form.invoice_email_organizer layout="control" %}
{% bootstrap_field form.invoice_language layout="control" %}
@@ -353,7 +353,7 @@
data-toggle="tooltip"
title="{% trans 'Generate a cancellation document for this invoice and create a new invoice with a new invoice number.' %}"
{% endif %}>
{% if order.status == "c" %}
{% if order.status == "c" or not invoice_qualified %}
{% trans "Generate cancellation" %}
{% else %}
{% trans "Cancel and reissue" %}
@@ -22,7 +22,7 @@
{{ s.owner.fullname|default:s.owner.email }}
</span>
</div>
<div class="col-lg-5 col-md-6 col-xs-12">
<div class="col-lg-4 col-md-5 col-xs-12">
{% if s.schedule_next_run %}
<span class="fa fa-clock-o fa-fw"></span>
{% trans "Next run:" %}
@@ -53,7 +53,7 @@
{{ s.mail_subject }}
</span>
</div>
<div class="col-lg-2 col-md-2 col-xs-12 text-right">
<div class="col-lg-3 col-md-3 col-xs-12 text-right">
<form action="{% url "control:event.orders.export.do" event=request.event.slug organizer=request.organizer.slug %}"
method="post" class="form-horizontal" data-asynctask data-asynctask-download
data-asynctask-long>
@@ -73,6 +73,9 @@
<a href="?identifier={{ s.export_identifier }}&scheduled={{ s.pk }}" class="btn btn-default" title="{% trans "Edit" %}" data-toggle="tooltip">
<span class="fa fa-edit"></span>
</a>
<a href="?identifier={{ s.export_identifier }}&scheduled_copy_from={{ s.pk }}" class="btn btn-default" title="{% trans "Copy" %}" data-toggle="tooltip">
<span class="fa fa-copy"></span>
</a>
{% endif %}
<a href="{% url "control:event.orders.export.scheduled.delete" event=request.event.slug organizer=request.event.organizer.slug pk=s.pk %}" class="btn btn-danger" title="{% trans "Delete" %}" data-toggle="tooltip">
<span class="fa fa-trash"></span>
@@ -42,7 +42,11 @@
<div class="form-group submit-group">
<button formaction="{{ request.get_full_path }}" name="schedule" value="save" type="submit"
class="btn btn-primary btn-save" data-no-asynctask>
{% trans "Save" %}
{% if scheduled_copy_from %}
{% trans "Save copy" %}
{% else %}
{% trans "Save" %}
{% endif %}
</button>
</div>
{% else %}
@@ -22,7 +22,7 @@
{{ s.owner.fullname|default:s.owner.email }}
</span>
</div>
<div class="col-lg-5 col-md-6 col-xs-12">
<div class="col-lg-4 col-md-5 col-xs-12">
{% if s.schedule_next_run %}
<span class="fa fa-clock-o fa-fw"></span>
{% trans "Next run:" %}
@@ -53,7 +53,7 @@
{{ s.mail_subject }}
</span>
</div>
<div class="col-lg-2 col-md-2 col-xs-12 text-right">
<div class="col-lg-3 col-md-3 col-xs-12 text-right">
<form action="{% url "control:organizer.export.do" organizer=request.organizer.slug %}"
method="post" class="form-horizontal" data-asynctask data-asynctask-download
data-asynctask-long>
@@ -73,6 +73,9 @@
<a href="?identifier={{ s.export_identifier }}&scheduled={{ s.pk }}" class="btn btn-default" title="{% trans "Edit" %}" data-toggle="tooltip">
<span class="fa fa-edit"></span>
</a>
<a href="?identifier={{ s.export_identifier }}&scheduled_copy_from={{ s.pk }}" class="btn btn-default" title="{% trans "Copy" %}" data-toggle="tooltip">
<span class="fa fa-copy"></span>
</a>
{% endif %}
<a href="{% url "control:organizer.export.scheduled.delete" organizer=request.organizer.slug pk=s.pk %}" class="btn btn-danger" title="{% trans "Delete" %}" data-toggle="tooltip">
<span class="fa fa-trash"></span>
@@ -43,7 +43,11 @@
<div class="form-group submit-group">
<button formaction="{{ request.get_full_path }}" name="schedule" value="save" type="submit"
class="btn btn-primary btn-save" data-no-asynctask>
{% trans "Save" %}
{% if scheduled_copy_from %}
{% trans "Save copy" %}
{% else %}
{% trans "Save" %}
{% endif %}
</button>
</div>
{% else %}
+28 -12
View File
@@ -33,6 +33,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
import copy
import json
import logging
import mimetypes
@@ -508,9 +509,10 @@ class OrderView(EventPermissionRequiredMixin, DetailView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['can_generate_invoice'] = invoice_qualified(self.order) and (
ctx['invoice_qualified'] = invoice_qualified(self.order)
ctx['can_generate_invoice'] = ctx['invoice_qualified'] and (
self.request.event.settings.invoice_generate in ('admin', 'user', 'paid', 'user_paid', 'True')
) and self.order.status in (Order.STATUS_PAID, Order.STATUS_PENDING) and (
) and (
not self.order.invoices.exists()
or self.order.invoices.filter(is_cancellation=True).count() >= self.order.invoices.filter(is_cancellation=False).count()
)
@@ -1741,14 +1743,15 @@ class OrderInvoiceReissue(OrderView):
messages.error(self.request, _('The invoice has been cleaned of personal data.'))
else:
c = generate_cancellation(inv)
if order.status not in (Order.STATUS_CANCELED, Order.STATUS_EXPIRED):
if invoice_qualified(order):
inv = generate_invoice(order)
messages.success(self.request, _('The invoice has been reissued.'))
else:
inv = c
messages.success(self.request, _('The invoice has been canceled.'))
order.log_action('pretix.event.order.invoice.reissued', user=self.request.user, data={
'invoice': inv.pk
})
messages.success(self.request, _('The invoice has been reissued.'))
return redirect(self.get_order_url())
def get(self, *args, **kwargs): # NOQA
@@ -2677,8 +2680,8 @@ class ExportMixin:
if id != ex.identifier:
continue
if self.scheduled:
initial = dict(self.scheduled.export_form_data)
if self.scheduled or self.scheduled_copy_from:
initial = dict((self.scheduled or self.scheduled_copy_from).export_form_data)
test_form = ExporterForm(data=self.request.GET, prefix=ex.identifier)
test_form.fields = ex.export_form_fields
@@ -2721,6 +2724,11 @@ class ExportMixin:
elif "scheduled" in self.request.GET:
return get_object_or_404(self.get_scheduled_queryset(), pk=self.request.GET.get("scheduled"))
@cached_property
def scheduled_copy_from(self):
if "scheduled_copy_from" in self.request.GET:
return get_object_or_404(self.get_scheduled_queryset(), pk=self.request.GET.get("scheduled_copy_from"))
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['exporters'] = self.exporters
@@ -2838,6 +2846,8 @@ class ExportView(EventPermissionRequiredMixin, ExportMixin, ListView):
def rrule_form(self):
if self.scheduled:
initial = RRuleForm.initial_from_rrule(self.scheduled.schedule_rrule)
elif self.scheduled_copy_from:
initial = RRuleForm.initial_from_rrule(self.scheduled_copy_from.schedule_rrule)
else:
initial = {}
return RRuleForm(
@@ -2848,11 +2858,15 @@ class ExportView(EventPermissionRequiredMixin, ExportMixin, ListView):
@cached_property
def schedule_form(self):
instance = self.scheduled or ScheduledEventExport(
event=self.request.event,
owner=self.request.user,
)
if not self.scheduled:
if self.scheduled_copy_from:
instance = copy.copy(self.scheduled_copy_from)
instance.pk = None
else:
instance = self.scheduled or ScheduledEventExport(
event=self.request.event,
owner=self.request.user,
)
if not self.scheduled and not self.scheduled_copy_from:
initial = {
"mail_subject": gettext("Export: {title}").format(title=self.exporter.verbose_name),
"mail_template": gettext("Hello,\n\nattached to this email, you can find a new scheduled report for {name}.").format(
@@ -2877,9 +2891,11 @@ class ExportView(EventPermissionRequiredMixin, ExportMixin, ListView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
if "schedule" in self.request.POST or self.scheduled:
if "schedule" in self.request.POST or self.scheduled or self.scheduled_copy_from:
ctx['schedule_form'] = self.schedule_form
ctx['rrule_form'] = self.rrule_form
ctx['scheduled_copy_from'] = self.scheduled_copy_from
elif not self.exporter:
for s in ctx['scheduled']:
try:
+21 -8
View File
@@ -32,6 +32,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
import copy
import json
import logging
import re
@@ -1943,8 +1944,8 @@ class ExportMixin:
for ex in self.exporters:
if id != ex.identifier:
continue
if self.scheduled:
initial = dict(self.scheduled.export_form_data)
if self.scheduled or self.scheduled_copy_from:
initial = dict((self.scheduled or self.scheduled_copy_from).export_form_data)
test_form = ExporterForm(data=self.request.GET, prefix=ex.identifier)
test_form.fields = ex.export_form_fields
@@ -2047,6 +2048,11 @@ class ExportMixin:
elif "scheduled" in self.request.GET:
return get_object_or_404(self.get_scheduled_queryset(), pk=self.request.GET.get("scheduled"))
@cached_property
def scheduled_copy_from(self):
if "scheduled_copy_from" in self.request.GET:
return get_object_or_404(self.get_scheduled_queryset(), pk=self.request.GET.get("scheduled_copy_from"))
class ExportDoView(OrganizerPermissionRequiredMixin, ExportMixin, AsyncAction, TemplateView):
known_errortypes = ['ExportError', 'ExportEmptyError']
@@ -2160,6 +2166,8 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
def rrule_form(self):
if self.scheduled:
initial = RRuleForm.initial_from_rrule(self.scheduled.schedule_rrule)
elif self.scheduled_copy_from:
initial = RRuleForm.initial_from_rrule(self.scheduled_copy_from.schedule_rrule)
else:
initial = {}
return RRuleForm(
@@ -2171,11 +2179,15 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
@cached_property
def schedule_form(self):
instance = self.scheduled or ScheduledOrganizerExport(
organizer=self.request.organizer,
owner=self.request.user,
timezone=str(get_current_timezone()),
)
if self.scheduled_copy_from:
instance = copy.copy(self.scheduled_copy_from)
instance.pk = None
else:
instance = self.scheduled or ScheduledOrganizerExport(
organizer=self.request.organizer,
owner=self.request.user,
timezone=str(get_current_timezone()),
)
if not self.scheduled:
initial = {
"mail_subject": gettext("Export: {title}").format(title=self.exporter.verbose_name),
@@ -2208,9 +2220,10 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
if "schedule" in self.request.POST or self.scheduled:
if "schedule" in self.request.POST or self.scheduled or self.scheduled_copy_from:
ctx['schedule_form'] = self.schedule_form
ctx['rrule_form'] = self.rrule_form
ctx['scheduled_copy_from'] = self.scheduled_copy_from
elif not self.exporter:
for s in ctx['scheduled']:
try:
+35 -39
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-05 12:12+0000\n"
"PO-Revision-Date: 2025-05-17 18:00+0000\n"
"Last-Translator: Patrick Chilton <chpatrick@gmail.com>\n"
"PO-Revision-Date: 2026-01-23 15:00+0000\n"
"Last-Translator: Vajda Tamás <vajda.tamas@szwg.hu>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix/"
"hu/>\n"
"Language: hu\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.11.4\n"
"X-Generator: Weblate 5.15.2\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -37,11 +37,11 @@ msgstr "arab"
#: pretix/_base_settings.py:91
msgid "Basque"
msgstr ""
msgstr "Baszk"
#: pretix/_base_settings.py:92
msgid "Catalan"
msgstr ""
msgstr "Katalán"
#: pretix/_base_settings.py:93
msgid "Chinese (simplified)"
@@ -57,7 +57,7 @@ msgstr "cseh"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr ""
msgstr "Horvát"
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -89,7 +89,7 @@ msgstr "görög"
#: pretix/_base_settings.py:104
msgid "Hebrew"
msgstr ""
msgstr "Héber"
#: pretix/_base_settings.py:105
msgid "Indonesian"
@@ -101,7 +101,7 @@ msgstr "olasz"
#: pretix/_base_settings.py:107
msgid "Japanese"
msgstr ""
msgstr "Japán"
#: pretix/_base_settings.py:108
msgid "Latvian"
@@ -133,11 +133,11 @@ msgstr "orosz"
#: pretix/_base_settings.py:115
msgid "Slovak"
msgstr ""
msgstr "Szlovák"
#: pretix/_base_settings.py:116
msgid "Swedish"
msgstr ""
msgstr "Svéd"
#: pretix/_base_settings.py:117
msgid "Spanish"
@@ -145,7 +145,7 @@ msgstr "spanyol"
#: pretix/_base_settings.py:118
msgid "Spanish (Latin America)"
msgstr ""
msgstr "Spanyol (Latin-Amerikai változat)"
#: pretix/_base_settings.py:119
msgid "Turkish"
@@ -305,7 +305,7 @@ msgstr "A fizetés túl későn történt meg az elfogadáshoz."
#: pretix/api/serializers/item.py:242 pretix/base/models/items.py:2321
msgid "The program end must not be before the program start."
msgstr ""
msgstr "A program vége időpont nem lehet a kezdő időpont előtt."
#: pretix/api/serializers/item.py:247 pretix/base/models/items.py:2315
#, fuzzy
@@ -369,12 +369,12 @@ msgstr "Ezt a fajta kérdést nem lehet megmutatni becsekkolás közben."
msgid ""
"A medium with the same identifier and type already exists in your organizer "
"account."
msgstr ""
msgstr "Már létező médium (azonos azonosító és típus)."
#: pretix/api/serializers/order.py:85
#, python-brace-format
msgid "\"{input}\" is not a valid choice."
msgstr ""
msgstr "\"{input}\" nem választható."
#: pretix/api/serializers/order.py:1453 pretix/api/views/cart.py:224
#: pretix/base/services/orders.py:1605
@@ -397,38 +397,38 @@ msgstr "Nem áll elegendő \"{}\" kvóta rendelkezésre a művelet végrehajtás
#: pretix/api/serializers/organizer.py:145
#: pretix/control/forms/organizer.py:925 pretix/presale/forms/customer.py:458
msgid "An account with this email address is already registered."
msgstr ""
msgstr "Ezzel az email címmel már létezik regisztráció."
#: pretix/api/serializers/organizer.py:278
#: pretix/control/forms/organizer.py:761
msgid ""
"A gift card with the same secret already exists in your or an affiliated "
"organizer account."
msgstr ""
msgstr "Ezzel a titkos kulccsal már létezik ajándékkártya."
#: pretix/api/serializers/organizer.py:369
#: pretix/control/views/organizer.py:1042
msgid "pretix account invitation"
msgstr ""
msgstr "pretix ügyfél meghívó"
#: pretix/api/serializers/organizer.py:391
#: pretix/control/views/organizer.py:1141
msgid "This user already has been invited for this team."
msgstr ""
msgstr "Ez a felhasználó már meghívásra került ebbe a csoportba."
#: pretix/api/serializers/organizer.py:407
#: pretix/control/views/organizer.py:1158
msgid "This user already has permissions for this team."
msgstr ""
msgstr "A felhasználó már rendelkezik hozzáféréssel."
#: pretix/api/views/cart.py:209
msgid ""
"The specified voucher has already been used the maximum number of times."
msgstr ""
msgstr "A kupon elérte a felhasználhatóságának felső határát."
#: pretix/api/views/checkin.py:627 pretix/api/views/checkin.py:634
msgid "Medium connected to other event"
msgstr ""
msgstr "A médium rendezvényhez csatlakoztatása megtörtént"
#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:764
#, python-brace-format
@@ -436,21 +436,23 @@ msgid ""
"The application \"{application_name}\" has been authorized to access your "
"account."
msgstr ""
"A(z) \"{application_name}\" applikáció mostantól eléréssel rendelkezik a "
"fiókodhoz."
#: pretix/api/views/order.py:609 pretix/control/views/orders.py:1608
#: pretix/presale/views/order.py:736 pretix/presale/views/order.py:816
msgid "You cannot generate an invoice for this order."
msgstr ""
msgstr "Ehhez a megrendeléshez nem készíthető számla."
#: pretix/api/views/order.py:614 pretix/control/views/orders.py:1610
#: pretix/presale/views/order.py:738 pretix/presale/views/order.py:818
msgid "An invoice for this order already exists."
msgstr ""
msgstr "Ehhez a megrendeléshez már készült számla."
#: pretix/api/views/order.py:640 pretix/control/views/orders.py:1788
#: pretix/control/views/users.py:145
msgid "There was an error sending the mail. Please try again later."
msgstr ""
msgstr "Az email küldése sikertelen. Kérjük, próbálja meg később."
#: pretix/api/views/order.py:720 pretix/base/services/cart.py:223
#: pretix/base/services/orders.py:190 pretix/presale/views/order.py:800
@@ -461,22 +463,22 @@ msgstr "\"{}\" termékhez nincs kvóta rendelve."
#: pretix/api/webhooks.py:263 pretix/base/notifications.py:233
msgid "New order placed"
msgstr ""
msgstr "Új megrendelés került rögzítésre"
#: pretix/api/webhooks.py:267 pretix/base/notifications.py:239
msgid "New order requires approval"
msgstr ""
msgstr "Az új megrendelés jóváhagyásra vár"
#: pretix/api/webhooks.py:271 pretix/base/notifications.py:245
msgid "Order marked as paid"
msgstr ""
msgstr "A megrendelés fizetett státuszba került"
#: pretix/api/webhooks.py:275 pretix/base/models/checkin.py:355
#: pretix/base/notifications.py:251
#: pretix/control/templates/pretixcontrol/event/mail.html:114
#: pretix/control/views/orders.py:1569
msgid "Order canceled"
msgstr ""
msgstr "A megrendelés lemondásra került"
#: pretix/api/webhooks.py:279 pretix/base/notifications.py:257
msgid "Order reactivated"
@@ -614,29 +616,23 @@ msgstr ""
#: pretix/api/webhooks.py:401
msgid "Waiting list entry changed"
msgstr ""
msgstr "A várólista eleme megváltozott."
#: pretix/api/webhooks.py:405
#, fuzzy
#| msgid "The selected seat \"{seat}\" is not available."
msgid "Waiting list entry deleted"
msgstr "A kiválasztott \"{seat}\" ülés nem elérhető."
msgstr "A várólista eleme törlésre került."
#: pretix/api/webhooks.py:409
msgid "Waiting list entry received voucher"
msgstr ""
msgstr "A várólista eleme kupont kapott"
#: pretix/api/webhooks.py:413
#, fuzzy
#| msgid "Voucher code"
msgid "Voucher added"
msgstr "Kuponkód"
msgstr "Kuponkód hozzáadásra került"
#: pretix/api/webhooks.py:417
#, fuzzy
#| msgid "Voucher code"
msgid "Voucher changed"
msgstr "Kuponkód"
msgstr "Kuponkód megváltozott"
#: pretix/api/webhooks.py:418
msgid ""
+4 -4
View File
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-05 12:13+0000\n"
"PO-Revision-Date: 2024-11-28 06:00+0000\n"
"Last-Translator: Patrick Chilton <chpatrick@gmail.com>\n"
"PO-Revision-Date: 2026-01-23 15:00+0000\n"
"Last-Translator: Vajda Tamás <vajda.tamas@szwg.hu>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
"js/hu/>\n"
"Language: hu\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.3\n"
"X-Generator: Weblate 5.15.2\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -317,7 +317,7 @@ msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
msgid "Order canceled"
msgstr ""
msgstr "A megrendelés lemondásra került"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
msgid "Ticket code is ambiguous on list"
File diff suppressed because it is too large Load Diff
+35 -38
View File
@@ -7,7 +7,7 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-01-05 12:13+0000\n"
"PO-Revision-Date: 2026-01-22 19:00+0000\n"
"PO-Revision-Date: 2026-01-24 01:00+0000\n"
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
"nl/>\n"
@@ -249,7 +249,7 @@ msgstr "Ingewisseld"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:49
msgid "Cancel"
msgstr "Annuleer"
msgstr "Annuleren"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:51
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:60
@@ -310,7 +310,7 @@ msgstr "Bestelling geannuleerd"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
msgid "Ticket code is ambiguous on list"
msgstr "Ticket-code op de lijst is niet eenduidig"
msgstr "Ticketcode op de lijst is niet eenduidig"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
msgid "Order not approved"
@@ -389,14 +389,14 @@ msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:162
#: pretix/static/pretixcontrol/js/ui/mail.js:21
msgid "The request took too long. Please try again."
msgstr "De aanvraag duurde te lang, probeer het alstublieft opnieuw."
msgstr "De aanvraag duurde te lang. Probeer het opnieuw."
#: pretix/static/pretixbase/js/asynctask.js:188
#: pretix/static/pretixcontrol/js/ui/mail.js:26
msgid ""
"We currently cannot reach the server. Please try again. Error code: {code}"
msgstr ""
"De server is op dit moment niet bereikbaar, probeer het alstublieft opnieuw. "
"De server is op dit moment niet bereikbaar. Probeer het alstublieft opnieuw. "
"Foutcode: {code}"
#: pretix/static/pretixbase/js/asynctask.js:216
@@ -466,11 +466,11 @@ msgstr "Huidige datum en tijd"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
msgstr "Huidige dag van de week (1 = Maandag, 7 = Zondag)"
msgstr "Huidige dag van de week (1 = maandag, 7 = zondag)"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
msgid "Current entry status"
msgstr "Huidige toegangstatus"
msgstr "Huidige toegangsstatus"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
msgid "Number of previous entries"
@@ -530,7 +530,7 @@ msgstr "Toegangstijd evenement"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:187
msgid "custom date and time"
msgstr "Aangepaste datum en tijd"
msgstr "aangepaste datum en tijd"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:188
msgid "custom time"
@@ -550,7 +550,7 @@ msgstr "minuten"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
msgid "Duplicate"
msgstr "duplicaat"
msgstr "Duplicaat"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
msgctxt "entry_status"
@@ -588,7 +588,7 @@ msgstr "Tekstobject (verouderd)"
#: pretix/static/pretixcontrol/js/ui/editor.js:911
msgid "Text box"
msgstr "Tekstkader"
msgstr "Tekstvak"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
msgid "Barcode area"
@@ -617,7 +617,7 @@ msgstr "Opslaan mislukt."
#: pretix/static/pretixcontrol/js/ui/editor.js:1361
#: pretix/static/pretixcontrol/js/ui/editor.js:1412
msgid "Error while uploading your PDF file, please try again."
msgstr "Probleem bij het uploaden van het PDF-bestand, probeer het opnieuw."
msgstr "Probleem bij het uploaden van het PDF-bestand. Probeer het opnieuw."
#: pretix/static/pretixcontrol/js/ui/editor.js:1395
msgid "Do you really want to leave the editor without saving your changes?"
@@ -638,7 +638,7 @@ msgstr "Onbekende fout."
#: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility."
msgstr ""
"Uw kleur heeft een goed contrast, en zal zorgen voor een uitstekende "
"Uw kleur heeft een goed contrast en zal zorgen voor een uitstekende "
"toegankelijkheid."
#: pretix/static/pretixcontrol/js/ui/main.js:313
@@ -646,16 +646,16 @@ msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility "
"requirements."
msgstr ""
"Uw kleur heeft een redelijk contrast, en is voldoende voor de minimale "
"toegankelijkheids eisen."
"Uw kleur heeft een redelijk contrast en is voldoende voor de minimale "
"toegankelijkheidseisen."
#: pretix/static/pretixcontrol/js/ui/main.js:317
msgid ""
"Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted."
msgstr ""
"Uw kleur heeft een te weinig contrast met wit. De toegankelijkheid van jouw "
"site wordt beïnvloed."
"Uw kleur heeft te weinig contrast met wit. De toegankelijkheid van uw site "
"wordt negatief beïnvloed."
#: pretix/static/pretixcontrol/js/ui/main.js:443
#: pretix/static/pretixcontrol/js/ui/main.js:463
@@ -676,11 +676,11 @@ msgstr "Alleen geselecteerde"
#: pretix/static/pretixcontrol/js/ui/main.js:839
msgid "Enter page number between 1 and %(max)s."
msgstr "voer een pagina nummer tussen 1 en %(max)s in."
msgstr "Voer een paginanummer tussen 1 en %(max)s in."
#: pretix/static/pretixcontrol/js/ui/main.js:842
msgid "Invalid page number."
msgstr "Ongeldig pagina nummer."
msgstr "Ongeldig paginanummer."
#: pretix/static/pretixcontrol/js/ui/main.js:1000
msgid "Use a different name internally"
@@ -692,7 +692,7 @@ msgstr "Klik om te sluiten"
#: pretix/static/pretixcontrol/js/ui/main.js:1121
msgid "You have unsaved changes!"
msgstr "U heeft nog niet opgeslagen wijzigingen!"
msgstr "Sommige wijzigingen zijn nog niet opgeslagen!"
#: pretix/static/pretixcontrol/js/ui/orderchange.js:25
msgid "Calculating default price…"
@@ -731,7 +731,7 @@ msgstr "Winkelwagen is verlopen"
#: pretix/static/pretixpresale/js/ui/cart.js:58
#: pretix/static/pretixpresale/js/ui/cart.js:84
msgid "Your cart is about to expire."
msgstr "Uw winkelwagen staat op het punt om te verlopen."
msgstr "Uw winkelwagen verloopt bijna."
#: pretix/static/pretixpresale/js/ui/cart.js:62
msgid "The items in your cart are reserved for you for one minute."
@@ -754,7 +754,7 @@ msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:87
msgid "Do you want to renew the reservation period?"
msgstr "Wilt u de reservererings periode vernieuwen?"
msgstr "Wilt u de reserveringsperiode vernieuwen?"
#: pretix/static/pretixpresale/js/ui/cart.js:90
msgid "Renew reservation"
@@ -893,7 +893,7 @@ msgstr "incl. belasting"
#: pretix/static/pretixpresale/js/widget/widget.js:37
msgctxt "widget"
msgid "plus taxes"
msgstr "excl. belasting"
msgstr "plus belasting"
#: pretix/static/pretixpresale/js/widget/widget.js:38
#, javascript-format
@@ -960,9 +960,7 @@ msgstr "Afrekenen"
#: pretix/static/pretixpresale/js/widget/widget.js:51
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr ""
"De winkelwagen kon niet gemaakt worden. Probeer het alstublieft later "
"opnieuw."
msgstr "De winkelwagen kon niet aangemaakt worden. Probeer het later opnieuw."
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
@@ -971,8 +969,8 @@ msgid ""
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
"Uw winkelwagen kon niet worden aangemaakt omdat er op dit moment te veel "
"gebruikers actief zijn in deze ticketwinkel. Klik op \"Doorgaan\" om dit "
"opnieuw te proberen in een nieuw tabblad."
"gebruikers actief zijn in deze ticketwinkel. Klik op \"Doorgaan\" om opnieuw "
"te proberen in een nieuw tabblad."
#: pretix/static/pretixpresale/js/widget/widget.js:54
msgctxt "widget"
@@ -985,8 +983,8 @@ msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
"U heeft momenteel een actieve winkelwagen voor dit evenement. Als u meer "
"producten selecteert worden deze toegevoegd aan uw bestaande winkelwagen."
"U hebt momenteel een actieve winkelwagen voor dit evenement. Als u meer "
"producten selecteert, worden deze toegevoegd aan uw bestaande winkelwagen."
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
@@ -996,12 +994,12 @@ msgstr "Doorgaan met afrekenen"
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Verzilver een voucher"
msgstr "Voucher inwisselen"
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Redeem"
msgstr "Verzilveren"
msgstr "Inwisselen"
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
@@ -1016,18 +1014,17 @@ msgstr "Sluiten"
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Close checkout"
msgstr "Stoppen met afrekenen"
msgstr "Afrekenen sluiten"
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr ""
"U kan niet deze actie annuleren. Alstublieft wacht tot het laden is voltooid."
msgstr "U kunt deze actie niet annuleren. Wacht tot het laden is voltooid."
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Continue"
msgstr "Ga verder"
msgstr "Doorgaan"
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
@@ -1086,9 +1083,9 @@ msgid ""
"add yourself to the waiting list. We will then notify if seats are available "
"again."
msgstr ""
"Sommige of alle tiketcategorieën zijn op heden uitverkocht. Als je wilt, kun "
"je jezelf toevoegen aan de wachtlijst. We zullen je informeren wanneer er "
"weer plaatsen beschikbaar zijn."
"Sommige of alle ticketcategorieën zijn uitverkocht. Als u wilt, kunt u zich "
"op de wachtlijst zetten. We zullen u informeren wanneer er weer plaatsen "
"beschikbaar zijn."
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgctxt "widget"
@@ -38,6 +38,7 @@
<div class="details">
<code>{{ checkResult.position.order }}-{{ checkResult.position.positionid }}</code>
<h4>{{ checkResult.position.attendee_name }}</h4>
<div v-if="checkResultAddons" class="addons">{{ checkResultAddons }}</div>
<span v-if="checkResultSubevent">{{ checkResultSubevent }}<br></span>
<span class="secret">{{ checkResult.position.secret }}</span>
<span v-if="checkResult.position.seat"><br>{{ checkResult.position.seat.name }}</span>
@@ -265,6 +266,16 @@ export default {
const date = moment.utc(this.checkinlist.subevent.date_from).tz(this.$root.timezone).format(this.$root.datetime_format)
return `${name} · ${date}`
},
checkResultAddons() {
if (!this.checkResult) return ''
if (!this.checkResult.position.addons) return ''
return this.checkResult.position.addons.map((addon) => {
if (addon.variation) {
return `+ ${addon.item.internal_name || i18nstring_localize(addon.item.name)} ${i18nstring_localize(addon.variation.value)}`
}
return "+ " + (addon.item.internal_name || i18nstring_localize(addon.item.name));
}).join("\n")
},
checkResultSubevent() {
if (!this.checkResult) return ''
if (!this.checkResult.position.subevent) return ''
@@ -369,7 +380,7 @@ export default {
this.$refs.input.blur()
})
let url = this.$root.api.lists + this.checkinlist.id + '/positions/' + encodeURIComponent(id) + '/redeem/?expand=item&expand=subevent&expand=variation&expand=answers.question'
let url = this.$root.api.lists + this.checkinlist.id + '/positions/' + encodeURIComponent(id) + '/redeem/?expand=item&expand=subevent&expand=variation&expand=answers.question&expand=addons'
if (untrusted) {
url += '&untrusted_input=true'
}
@@ -92,6 +92,9 @@ a.searchresult, .check-result {
word-break: break-word;
color: $text-muted;
}
.addons {
white-space: pre-line;
}
}
.check-result-status {
@@ -60,7 +60,7 @@
{% endif %}
{% if providers %}
<ul class="list-inline text-center blank-after">
<ul id="customer-account-login-providers" class="list-inline text-center blank-after">
{% for provider in providers %}
<li>
<a href="{% eventurl request.organizer "presale:organizer.customer.login" provider=provider.pk %}?{{ request.META.QUERY_STRING }}"
@@ -166,6 +166,23 @@ $(function () {
};
update();
dependencies.on("change", update);
if (dependents.vat_id && dependents.transmission_type && dependents.transmission_peppol_participant_id) {
// In Belgium, the VAT ID is built from "BE" + the company ID. The Peppol ID also needs to be built
// from the company ID with ID scheme 0208. We can save users some knowing and typing by filling this in!
if (!dependents.transmission_peppol_participant_id.val()) {
const fill_peppol_id = function () {
const vatId = dependents.vat_id.val();
if (vatId && vatId.startsWith("BE") && dependents.transmission_type.val() === "peppol" && autofill_peppol_id) {
dependents.transmission_peppol_participant_id.val("0201:" + vatId.substring(2))
}
}
dependents.vat_id.add(dependents.transmission_type).on("change", fill_peppol_id);
dependents.transmission_peppol_participant_id.one("change", () => {
dependents.vat_id.add(dependents.transmission_type).unbind("change", fill_peppol_id)
});
}
}
});
});
@@ -731,6 +731,11 @@ $(function () {
$(countInput).trigger("change");
});
});
$("#customer-account-login-providers a").click(function () {
// Prevent double-submit, see also https://github.com/pretix/pretix/issues/5836
$(this).addClass("disabled");
});
});
function copy_answers(elements, answers) {
+13
View File
@@ -737,6 +737,19 @@ def test_question_expand(token_client, organizer, clist, event, order, question)
assert resp.data["position"]["answers"][0]["question"]["question"]["en"] == "Size"
@pytest.mark.django_db
def test_addons_expand(token_client, organizer, clist, event, order, question, other_item):
with scopes_disabled():
p = order.positions.first()
question[0].save()
p.answers.create(question=question[0], answer="3")
resp = _redeem(token_client, organizer, clist, p.secret, {"answers": {question[0].pk: ""}}, query="?expand=addons&expand=item")
assert resp.status_code == 201
assert resp.data["status"] == "ok"
assert resp.data["position"]["addons"][0]["item"]["id"] == other_item.pk
@pytest.mark.django_db
def test_store_failed(token_client, organizer, clist, event, order):
with scopes_disabled():
+8
View File
@@ -50,6 +50,7 @@ from pretix.base.models import (
QuestionOption, Quota,
)
from pretix.base.models.orders import OrderFee
from pretix.testutils.queries import assert_num_queries
@pytest.fixture
@@ -422,6 +423,13 @@ def test_item_list(token_client, organizer, event, team, item):
assert [] == resp.data['results']
@pytest.mark.django_db
def test_item_list_queries(token_client, organizer, event, team, item, item3):
with assert_num_queries(18):
resp = token_client.get('/api/v1/organizers/{}/events/{}/items/'.format(organizer.slug, event.slug))
assert resp.status_code == 200
@pytest.mark.django_db
def test_item_detail(token_client, organizer, event, team, item):
res = dict(TEST_ITEM_RES)
+19
View File
@@ -612,6 +612,25 @@ def test_sales_channels_qualify(env):
assert invoice_qualified(order) is False
@pytest.mark.django_db
def test_business_only(env):
event, order = env
event.settings.set('invoice_generate', 'admin')
event.settings.set('invoice_generate_only_business', True)
order.total = Decimal('42.00')
ia = InvoiceAddress.objects.create(company='Acme Company', street='221B Baker Street', is_business=True,
zipcode='12345', city='London', country_old='England', country='', order=order)
assert invoice_qualified(order) is True
ia.is_business = False
ia.save()
# Order with default Sales Channel (web)
assert invoice_qualified(order) is False
def test_addon_aware_groupby():
def is_addon(item):
is_addon, id, price = item