mirror of
https://github.com/pretix/pretix.git
synced 2026-05-16 17:03:58 +00:00
Compare commits
23 Commits
ssrf-prote
...
bulk-vouch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20da00d4fb | ||
|
|
178a5525d5 | ||
|
|
1da1393a86 | ||
|
|
adf167e611 | ||
|
|
4867afc503 | ||
|
|
9ba5497287 | ||
|
|
4c0c775baa | ||
|
|
394652a5ff | ||
|
|
3f50d065ec | ||
|
|
4121061267 | ||
|
|
aed2220139 | ||
|
|
4b2c54d38e | ||
|
|
0113a3dc1f | ||
|
|
c12a8935f1 | ||
|
|
a86a6cc2c7 | ||
|
|
fec2b9a2fc | ||
|
|
d847a7e8f8 | ||
|
|
c58a968196 | ||
|
|
81cbaca162 | ||
|
|
218df7a49f | ||
|
|
f64343d977 | ||
|
|
b36c7cbef3 | ||
|
|
18b39ba7cd |
@@ -33,15 +33,18 @@
|
||||
# License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
import csv
|
||||
from collections import namedtuple
|
||||
from collections import Counter, namedtuple
|
||||
from io import StringIO
|
||||
|
||||
from django import forms
|
||||
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
||||
from django.core.validators import EmailValidator
|
||||
from django.db.models import Count, F, Max
|
||||
from django.db.models.functions import Upper
|
||||
from django.forms.utils import ErrorDict
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _, pgettext_lazy
|
||||
from django_scopes.forms import SafeModelChoiceField
|
||||
|
||||
from pretix.base.email import get_available_placeholders
|
||||
@@ -50,7 +53,9 @@ from pretix.base.forms import (
|
||||
)
|
||||
from pretix.base.forms.widgets import format_placeholders_help_text
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.models import Item, Voucher
|
||||
from pretix.base.models import Item, ItemVariation, Quota, SubEvent, Voucher
|
||||
from pretix.base.services.locking import lock_objects
|
||||
from pretix.base.services.quotas import QuotaAvailability
|
||||
from pretix.control.forms import SplitDateTimeField, SplitDateTimePickerWidget
|
||||
from pretix.control.forms.widgets import Select2, Select2ItemVarQuota
|
||||
from pretix.control.signals import voucher_form_validation
|
||||
@@ -105,15 +110,17 @@ class VoucherForm(I18nModelForm):
|
||||
except Item.DoesNotExist:
|
||||
pass
|
||||
super().__init__(*args, **kwargs)
|
||||
if not self.event and self.instance:
|
||||
self.event = self.instance.event
|
||||
|
||||
if instance.event.has_subevents:
|
||||
self.fields['subevent'].queryset = instance.event.subevents.all()
|
||||
if self.event.has_subevents:
|
||||
self.fields['subevent'].queryset = self.event.subevents.all()
|
||||
self.fields['subevent'].widget = Select2(
|
||||
attrs={
|
||||
'data-model-select2': 'event',
|
||||
'data-select2-url': reverse('control:event.subevents.select2', kwargs={
|
||||
'event': instance.event.slug,
|
||||
'organizer': instance.event.organizer.slug,
|
||||
'event': self.event.slug,
|
||||
'organizer': self.event.organizer.slug,
|
||||
}),
|
||||
}
|
||||
)
|
||||
@@ -123,18 +130,19 @@ class VoucherForm(I18nModelForm):
|
||||
del self.fields['subevent']
|
||||
|
||||
choices = []
|
||||
if 'itemvar' in initial or (self.data and 'itemvar' in self.data):
|
||||
iv = self.data.get('itemvar') or initial.get('itemvar', '')
|
||||
prefix = (self.prefix + '-') if self.prefix else ''
|
||||
if 'itemvar' in initial or (self.data and prefix + 'itemvar' in self.data):
|
||||
iv = self.data.get(prefix + 'itemvar', '') or initial.get('itemvar', '') or ''
|
||||
if iv.startswith('q-'):
|
||||
q = self.instance.event.quotas.get(pk=iv[2:])
|
||||
q = self.event.quotas.get(pk=iv[2:])
|
||||
choices.append(('q-%d' % q.pk, _('Any product in quota "{quota}"').format(quota=q)))
|
||||
elif '-' in iv:
|
||||
itemid, varid = iv.split('-')
|
||||
i = self.instance.event.items.get(pk=itemid)
|
||||
i = self.event.items.get(pk=itemid)
|
||||
v = i.variations.get(pk=varid)
|
||||
choices.append(('%d-%d' % (i.pk, v.pk), '%s – %s' % (str(i), v.value)))
|
||||
elif iv:
|
||||
i = self.instance.event.items.get(pk=iv)
|
||||
i = self.event.items.get(pk=iv)
|
||||
if i.variations.exists():
|
||||
choices.append((str(i.pk), _('{product} – Any variation').format(product=i)))
|
||||
else:
|
||||
@@ -145,8 +153,8 @@ class VoucherForm(I18nModelForm):
|
||||
attrs={
|
||||
'data-model-select2': 'generic',
|
||||
'data-select2-url': reverse('control:event.vouchers.itemselect2', kwargs={
|
||||
'event': instance.event.slug,
|
||||
'organizer': instance.event.organizer.slug,
|
||||
'event': self.event.slug,
|
||||
'organizer': self.event.organizer.slug,
|
||||
}),
|
||||
'data-placeholder': _('All products')
|
||||
}
|
||||
@@ -154,7 +162,7 @@ class VoucherForm(I18nModelForm):
|
||||
self.fields['itemvar'].required = False
|
||||
self.fields['itemvar'].widget.choices = self.fields['itemvar'].choices
|
||||
|
||||
if self.instance.event.seating_plan or self.instance.event.subevents.filter(seating_plan__isnull=False).exists():
|
||||
if self.event.seating_plan or self.event.subevents.filter(seating_plan__isnull=False).exists():
|
||||
self.fields['seat'] = forms.CharField(
|
||||
label=_("Specific seat ID"),
|
||||
max_length=255,
|
||||
@@ -181,14 +189,14 @@ class VoucherForm(I18nModelForm):
|
||||
itemid, varid = None, None
|
||||
|
||||
if itemid:
|
||||
self.instance.item = self.instance.event.items.get(pk=itemid)
|
||||
self.instance.item = self.event.items.get(pk=itemid)
|
||||
if varid:
|
||||
self.instance.variation = self.instance.item.variations.get(pk=varid)
|
||||
else:
|
||||
self.instance.variation = None
|
||||
self.instance.quota = None
|
||||
elif quotaid:
|
||||
self.instance.quota = self.instance.event.quotas.get(pk=quotaid)
|
||||
self.instance.quota = self.event.quotas.get(pk=quotaid)
|
||||
self.instance.item = None
|
||||
self.instance.variation = None
|
||||
else:
|
||||
@@ -209,7 +217,7 @@ class VoucherForm(I18nModelForm):
|
||||
|
||||
try:
|
||||
Voucher.clean_item_properties(
|
||||
data, self.instance.event,
|
||||
data, self.event,
|
||||
self.instance.quota, self.instance.item, self.instance.variation,
|
||||
seats_given=data.get('seat') or data.get('seats'),
|
||||
block_quota=data.get('block_quota')
|
||||
@@ -229,7 +237,7 @@ class VoucherForm(I18nModelForm):
|
||||
|
||||
try:
|
||||
Voucher.clean_subevent(
|
||||
data, self.instance.event
|
||||
data, self.event
|
||||
)
|
||||
except ValidationError as e:
|
||||
raise ValidationError({"subevent": e.message})
|
||||
@@ -245,19 +253,19 @@ class VoucherForm(I18nModelForm):
|
||||
if check_quota:
|
||||
Voucher.clean_quota_check(
|
||||
data, cnt, self.initial_instance_data,
|
||||
self.instance.event, self.instance.quota, self.instance.item, self.instance.variation
|
||||
self.event, self.instance.quota, self.instance.item, self.instance.variation
|
||||
)
|
||||
Voucher.clean_voucher_code(data, self.instance.event, self.instance.pk)
|
||||
Voucher.clean_voucher_code(data, self.event, self.instance.pk)
|
||||
if 'seat' in self.fields:
|
||||
if data.get('seat'):
|
||||
self.instance.seat = Voucher.clean_seat_id(
|
||||
data, self.instance.item, self.instance.quota, self.instance.event, self.instance.pk
|
||||
data, self.instance.item, self.instance.quota, self.event, self.instance.pk
|
||||
)
|
||||
self.instance.item = self.instance.seat.product
|
||||
else:
|
||||
self.instance.seat = None
|
||||
|
||||
voucher_form_validation.send(sender=self.instance.event, form=self, data=data)
|
||||
voucher_form_validation.send(sender=self.event, form=self, data=data)
|
||||
|
||||
return data
|
||||
|
||||
@@ -265,6 +273,273 @@ class VoucherForm(I18nModelForm):
|
||||
return super().save(commit)
|
||||
|
||||
|
||||
class VoucherBulkEditForm(VoucherForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.mixed_values = kwargs.pop('mixed_values')
|
||||
self.queryset = kwargs.pop('queryset')
|
||||
super().__init__(**kwargs)
|
||||
del self.fields["code"]
|
||||
self.fields.pop("seat", None)
|
||||
|
||||
def clean(self):
|
||||
# We skip the parent class because it's not suited for bulk editing and implement custom validation here.
|
||||
# This does not validate *everything* we validate in VoucherForm. For example, we skip validation that one does
|
||||
# not create a voucher for an add-on product or that the seat matches the product to save on complexity.
|
||||
# This is a UX validation only anyway, since one could first create the voucher and then make the product an
|
||||
# add-on product. However, we need to validate everything that we don't want violated in the database.
|
||||
data = super(VoucherForm, self).clean()
|
||||
|
||||
if self.prefix + "itemvar" in self.data.getlist('_bulk'):
|
||||
try:
|
||||
itemid = quotaid = None
|
||||
iv = data.get('itemvar', '')
|
||||
if iv.startswith('q-'):
|
||||
quotaid = iv[2:]
|
||||
elif '-' in iv:
|
||||
itemid, varid = iv.split('-')
|
||||
elif iv:
|
||||
itemid, varid = iv, None
|
||||
else:
|
||||
itemid, varid = None, None
|
||||
|
||||
if itemid:
|
||||
data["item"] = self.event.items.get(pk=itemid)
|
||||
if varid:
|
||||
data["variation"] = data["item"].variations.get(pk=varid)
|
||||
else:
|
||||
data["variation"] = None
|
||||
data["quota"] = None
|
||||
elif quotaid:
|
||||
data["quota"] = self.event.quotas.get(pk=quotaid)
|
||||
data["item"] = None
|
||||
data["variation"] = None
|
||||
else:
|
||||
data["quota"] = None
|
||||
data["item"] = None
|
||||
data["variation"] = None
|
||||
|
||||
except ObjectDoesNotExist:
|
||||
raise ValidationError(_("Invalid product selected."))
|
||||
|
||||
if self.prefix + "max_usages" in self.data.getlist('_bulk') and "max_usages" in data:
|
||||
max_redeemed = self.queryset.aggregate(m=Max("redeemed"))["m"]
|
||||
if data["max_usages"] < max_redeemed:
|
||||
raise ValidationError(_(
|
||||
"You cannot reduce the maximum number of redemptions to %(max_usages)s, because at least one "
|
||||
"of the selected vouchers has already been redeemed %(max_redeemed)s times."
|
||||
) % {"max_usages": data["max_usages"], "max_redeemed": max_redeemed})
|
||||
|
||||
# Check diff on product and quota usage based on old groups of vouchers
|
||||
if any(self.prefix + k in self.data.getlist('_bulk') for k in ("max_usages", "itemvar", "block_quota", "valid_until", "subevent")):
|
||||
quota_diff = Counter()
|
||||
|
||||
current_vouchers = self.queryset.order_by().values(
|
||||
"item", "variation", "quota", "block_quota", "valid_until", "subevent", "redeemed", "max_usages",
|
||||
"allow_ignore_quota",
|
||||
).annotate(c=Count("*"))
|
||||
item_cache = {i.pk: i for i in Item.objects.filter(pk__in=[c["item"] for c in current_vouchers])}
|
||||
var_cache = {v.pk: v for v in ItemVariation.objects.filter(pk__in=[c["variation"] for c in current_vouchers])}
|
||||
quota_cache = {q.pk: q for q in Quota.objects.filter(pk__in=[c["quota"] for c in current_vouchers])}
|
||||
subevent_cache = {s.pk: s for s in SubEvent.objects.filter(pk__in=[c["subevent"] for c in current_vouchers])}
|
||||
|
||||
for current in current_vouchers:
|
||||
was_valid = current["valid_until"] is None or current["valid_until"] >= now()
|
||||
|
||||
# Get quotas that are currently used
|
||||
if current["item"]:
|
||||
current["item"] = item_cache[current["item"]]
|
||||
if current["variation"]:
|
||||
current["variation"] = var_cache[current["variation"]]
|
||||
if current["quota"]:
|
||||
current["quota"] = quota_cache[current["quota"]]
|
||||
if current["subevent"]:
|
||||
current["subevent"] = subevent_cache[current["subevent"]]
|
||||
|
||||
old_quotas = set()
|
||||
if was_valid and current["block_quota"] and current["max_usages"] > current["redeemed"]:
|
||||
if current["quota"]:
|
||||
old_quotas.add(current["quota"])
|
||||
elif current["variation"]:
|
||||
old_quotas |= set(current["variation"].quotas.filter(subevent=current["subevent"]))
|
||||
elif current["item"]:
|
||||
if current["item"].has_variations:
|
||||
old_quotas |= set(
|
||||
Quota.objects.filter(pk__in=Quota.variations.through.objects.filter(
|
||||
itemvariation__item=current["item"],
|
||||
quota__subevent=current["subevent"],
|
||||
).values('quota_id'))
|
||||
)
|
||||
else:
|
||||
old_quotas |= set(current["item"].quotas.filter(subevent=current["subevent"]))
|
||||
old_amount = max(current["max_usages"] - current["redeemed"], 0) * current["c"]
|
||||
|
||||
# Predict state after change
|
||||
after_change = dict(current)
|
||||
if self.prefix + "itemvar" in self.data.getlist('_bulk') and "itemvar" in data:
|
||||
after_change["item"] = data["item"]
|
||||
after_change["variation"] = data["variation"]
|
||||
after_change["quota"] = data["quota"]
|
||||
if self.prefix + "subevent" in self.data.getlist('_bulk') and "subevent" in data:
|
||||
after_change["subevent"] = data["subevent"]
|
||||
if self.prefix + "max_usages" in self.data.getlist('_bulk') and "max_usages" in data:
|
||||
after_change["max_usages"] = data["max_usages"]
|
||||
if self.prefix + "block_quota" in self.data.getlist('_bulk') and "block_quota" in data:
|
||||
after_change["block_quota"] = data["block_quota"]
|
||||
if self.prefix + "valid_until" in self.data.getlist('_bulk') and "valid_until" in data:
|
||||
after_change["valid_until"] = data["valid_until"]
|
||||
if self.prefix + "allow_ignore_quota" in self.data.getlist('_bulk') and "allow_ignore_quota" in data:
|
||||
after_change["allow_ignore_quota"] = data["allow_ignore_quota"]
|
||||
|
||||
if after_change["quota"] and self.event.has_subevents and not after_change["subevent"]:
|
||||
raise ValidationError(_("You cannot create a voucher that allows selection of a quota but has no date selected."))
|
||||
|
||||
if after_change["quota"] and after_change["subevent"] and after_change["quota"].subevent_id != after_change["subevent"].pk:
|
||||
raise ValidationError(_("The selected quota does not match the selected subevent."))
|
||||
|
||||
if after_change["block_quota"] and self.event.has_subevents and not after_change["subevent"]:
|
||||
raise ValidationError(
|
||||
_('If you want this voucher to block quota, you need to select a specific date.'))
|
||||
|
||||
if after_change["block_quota"] and not after_change["item"] and not after_change["quota"]:
|
||||
raise ValidationError(
|
||||
_('You need to select a specific product or quota if this voucher should reserve '
|
||||
'tickets.')
|
||||
)
|
||||
|
||||
if after_change["allow_ignore_quota"]:
|
||||
# todo: is this the most useful way to do this?
|
||||
continue
|
||||
|
||||
will_be_valid = after_change["valid_until"] is None or after_change["valid_until"] >= now()
|
||||
new_quotas = set()
|
||||
if will_be_valid and after_change["block_quota"] and after_change["max_usages"] > current["redeemed"]:
|
||||
if after_change["quota"]:
|
||||
new_quotas.add(after_change["quota"])
|
||||
elif after_change["variation"]:
|
||||
new_quotas |= set(after_change["variation"].quotas.filter(subevent=after_change["subevent"]))
|
||||
elif after_change["item"]:
|
||||
if after_change["item"].has_variations:
|
||||
new_quotas |= set(
|
||||
Quota.objects.filter(pk__in=Quota.variations.through.objects.filter(
|
||||
itemvariation__item=after_change["item"],
|
||||
quota__subevent=after_change["subevent"],
|
||||
).values('quota_id'))
|
||||
)
|
||||
else:
|
||||
new_quotas |= set(after_change["item"].quotas.filter(subevent=after_change["subevent"]))
|
||||
|
||||
new_amount = max(after_change["max_usages"] - after_change["redeemed"], 0) * current["c"]
|
||||
if new_quotas != old_quotas or new_amount != old_amount:
|
||||
for q in old_quotas:
|
||||
quota_diff[q] -= old_amount
|
||||
for q in new_quotas:
|
||||
quota_diff[q] += new_amount
|
||||
|
||||
if any(v > 0 for q, v in quota_diff.items()):
|
||||
lock_objects([q for q, v in quota_diff.items() if q.size is not None and v > 0], shared_lock_objects=[self.event])
|
||||
qa = QuotaAvailability(count_waitinglist=False)
|
||||
qa.queue(*(q for q, v in quota_diff.items() if v > 0))
|
||||
qa.compute()
|
||||
|
||||
if any(qa.results[q][0] != Quota.AVAILABILITY_OK or (qa.results[q][1] is not None and qa.results[q][1] < required)
|
||||
for q, required in quota_diff.items() if required > 0):
|
||||
raise ValidationError(_(
|
||||
'There is no sufficient quota available to perform this change.'
|
||||
))
|
||||
|
||||
has_seat = self.queryset.filter(seat__isnull=False).exists()
|
||||
if has_seat:
|
||||
if self.prefix + "max_usages" in self.data.getlist('_bulk'):
|
||||
raise ValidationError(_(
|
||||
'Changing the maximum number of usages in bulk is not supported if any of the selected vouchers '
|
||||
'is assigned a seat.'
|
||||
))
|
||||
if self.prefix + "subevent" in self.data.getlist('_bulk'):
|
||||
raise ValidationError(pgettext_lazy(
|
||||
'subevent',
|
||||
'Changing the date in bulk is not supported if any of the selected vouchers '
|
||||
'is assigned a seat.'
|
||||
))
|
||||
if self.prefix + "itemvar" in self.data.getlist('_bulk') and data["quota"]:
|
||||
raise ValidationError(_(
|
||||
'Changing the product to a quota is not supported if any of the selected vouchers '
|
||||
'is assigned a seat.'
|
||||
))
|
||||
|
||||
if self.prefix + "valid_until" in self.data.getlist('_bulk'):
|
||||
if data["valid_until"] is None or data["valid_until"] >= now():
|
||||
currently_not_blocked_seats = self.queryset.filter(
|
||||
seat__isnull=False,
|
||||
max_usages__gt=F("redeemed"),
|
||||
valid_until__lt=now(),
|
||||
)
|
||||
if self.event.has_subevents:
|
||||
subevents = self.event.subevents.filter(pk__in=currently_not_blocked_seats.values_list("subevent"))
|
||||
for se in subevents:
|
||||
conflicts = currently_not_blocked_seats.filter(
|
||||
subevent=se
|
||||
).exclude(
|
||||
seat_id__in=se.free_seats().values("pk")
|
||||
)
|
||||
if conflicts:
|
||||
raise ValidationError(_(
|
||||
'This change cannot be completed because not all assigned seats of the vouchers are '
|
||||
'still available'
|
||||
))
|
||||
else:
|
||||
conflicts = currently_not_blocked_seats.exclude(
|
||||
seat_id__in=self.event.free_seats().values("pk")
|
||||
)
|
||||
if conflicts:
|
||||
raise ValidationError(_(
|
||||
'This change cannot be completed because not all assigned seats of the vouchers are '
|
||||
'still available'
|
||||
))
|
||||
|
||||
return data
|
||||
|
||||
def save(self, commit=True):
|
||||
objs = list(self.queryset)
|
||||
fields = set()
|
||||
|
||||
check_map = {
|
||||
'price_mode': '__price',
|
||||
'value': '__price',
|
||||
}
|
||||
for k in self.fields:
|
||||
cb_val = self.prefix + check_map.get(k, k)
|
||||
if cb_val not in self.data.getlist('_bulk'):
|
||||
continue
|
||||
|
||||
if k == 'itemvar':
|
||||
fields.add("item")
|
||||
fields.add("variation")
|
||||
fields.add("quota")
|
||||
else:
|
||||
fields.add(k)
|
||||
for obj in objs:
|
||||
if k == 'itemvar':
|
||||
obj.item = self.cleaned_data["item"]
|
||||
obj.variation = self.cleaned_data["variation"]
|
||||
obj.quota = self.cleaned_data["quota"]
|
||||
else:
|
||||
setattr(obj, k, self.cleaned_data[k])
|
||||
|
||||
fields = [f for f in fields if f != 'itemvars']
|
||||
if fields:
|
||||
Voucher.objects.bulk_update(objs, fields, 200)
|
||||
|
||||
def full_clean(self):
|
||||
if len(self.data) == 0:
|
||||
# form wasn't submitted
|
||||
self._errors = ErrorDict()
|
||||
return
|
||||
super().full_clean()
|
||||
|
||||
def _post_clean(self):
|
||||
pass # skip model-level clean
|
||||
|
||||
|
||||
class VoucherBulkForm(VoucherForm):
|
||||
codes = forms.CharField(
|
||||
widget=forms.Textarea,
|
||||
|
||||
@@ -8,7 +8,45 @@
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form %}
|
||||
{% bootstrap_field form.name layout='horizontal' %}
|
||||
{% bootstrap_field form.devicetype layout='horizontal' %}
|
||||
|
||||
<div class="form-group{% if form.devicetype.errors %} has-error{% endif %}">
|
||||
<label class="col-md-3 control-label">{% trans "Device type" %}</label>
|
||||
<div class="col-md-9">
|
||||
<div>
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" required value="totp" name="{{ form.devicetype.html_name }}" {% if form.devicetype.value == "totp" %}checked{% endif %}>
|
||||
<strong>{% trans "Smartphone with Authenticator app" %}</strong><br>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
Use your smartphone with any Time-based One-Time-Password app like freeOTP, Google Authenticator or Proton Authenticator.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" required value="webauthn" name="{{ form.devicetype.html_name }}" {% if form.devicetype.value == "webauthn" %}checked{% endif %}>
|
||||
<strong>{% trans "WebAuthn-compatible hardware token" %}</strong><br>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
Use a hardware token like the Yubikey, or other biometric authentication like fingerprint or face recognition.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if form.devicetype.errors %}
|
||||
<div class="help-block">
|
||||
{% for error in form.devicetype.errors %}
|
||||
<p>{{ error|escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Continue" %}
|
||||
|
||||
@@ -28,11 +28,6 @@
|
||||
{% trans "iOS (iTunes)" %}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://m.google.com/authenticator">
|
||||
{% trans "Blackberry (Link via Google)" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
{% extends "pretixcontrol/items/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load eventsignal %}
|
||||
{% load eventurl %}
|
||||
{% block title %}{% trans "Change multiple vouchers" %}{% endblock %}
|
||||
{% block inside %}
|
||||
<h1>
|
||||
{% trans "Change multiple vouchers" %}
|
||||
<small>
|
||||
{% blocktrans trimmed with number=vouchers.count %}
|
||||
{{ number }} selected
|
||||
{% endblocktrans %}
|
||||
</small>
|
||||
</h1>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Voucher details" %}</legend>
|
||||
{% bootstrap_field form.max_usages layout="bulkedit" %}
|
||||
{% bootstrap_field form.valid_until layout="bulkedit" %}
|
||||
{% bootstrap_field form.itemvar layout="bulkedit" %}
|
||||
|
||||
<div class="bulk-edit-field-group">
|
||||
<label class="field-toggle">
|
||||
<input type="checkbox" name="_bulk" value="{{ form.prefix }}__price" {% if form.prefix|add:"__price" in bulk_selected %}checked{% endif %}>
|
||||
{% trans "change" context "form_bulk" %}
|
||||
</label>
|
||||
<div class="field-content">
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label" for="id_tag">{% trans "Price effect" %}</label>
|
||||
<div class="col-md-5">
|
||||
{% bootstrap_field form.price_mode show_label=False form_group_class="" %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% bootstrap_field form.value show_label=False form_group_class="" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-9 col-md-offset-3">
|
||||
<div class="controls">
|
||||
<div class="alert alert-info">
|
||||
{% blocktrans trimmed %}
|
||||
If you choose "any product" for a specific quota and choose to reserve quota for this
|
||||
voucher above, the product can still be unavailable to the voucher holder if another quota
|
||||
associated with the product is sold out!
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if form.subevent %}
|
||||
{% bootstrap_field form.subevent layout="bulkedit" %}
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>{% trans "Advanced settings" %}</legend>
|
||||
{% bootstrap_field form.block_quota layout="bulkedit" %}
|
||||
{% bootstrap_field form.allow_ignore_quota layout="bulkedit" %}
|
||||
{% bootstrap_field form.min_usages layout="bulkedit" %}
|
||||
{% bootstrap_field form.budget addon_after=request.event.currency layout="bulkedit" %}
|
||||
{% bootstrap_field form.tag layout="bulkedit" %}
|
||||
{% bootstrap_field form.comment layout="bulkedit" %}
|
||||
{% bootstrap_field form.show_hidden_items layout="bulkedit" %}
|
||||
{% bootstrap_field form.all_addons_included layout="bulkedit" %}
|
||||
{% bootstrap_field form.all_bundles_included layout="bulkedit" %}
|
||||
</fieldset>
|
||||
<div class="form-group submit-group">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Save" %}
|
||||
</button>
|
||||
{% if voucher.pk %}
|
||||
<div class="pull-left">
|
||||
<a href="{% url "control:event.voucher.delete" organizer=request.organizer.slug event=request.event.slug voucher=voucher.pk %}"
|
||||
class="btn btn-danger btn-lg">
|
||||
<span class="fa fa-trash"></span>
|
||||
{% trans "Delete voucher" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -144,6 +144,18 @@
|
||||
{% endif %}
|
||||
<th></th>
|
||||
</tr>
|
||||
{% if "event.vouchers:write" in request.eventpermset and page_obj.paginator.num_pages > 1 %}
|
||||
<tr class="table-select-all warning hidden">
|
||||
<td>
|
||||
<input type="checkbox" name="__ALL" id="__all" data-results-total="{{ page_obj.paginator.count }}">
|
||||
</td>
|
||||
<td colspan="5">
|
||||
<label for="__all">
|
||||
{% trans "Select all results on other pages as well" %}
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for v in vouchers %}
|
||||
@@ -211,6 +223,10 @@
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
{% trans "Delete selected" %}
|
||||
</button>
|
||||
<button type="submit" class="btn btn-primary btn-save" name="action" value="edit"
|
||||
formaction="{% url "control:event.vouchers.bulkedit" organizer=request.event.organizer.slug event=request.event.slug %}">
|
||||
<i class="fa fa-edit"></i>{% trans "Edit selected" %}
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
@@ -379,6 +379,7 @@ urlpatterns = [
|
||||
re_path(r'^vouchers/bulk_add$', vouchers.VoucherBulkCreate.as_view(), name='event.vouchers.bulk'),
|
||||
re_path(r'^vouchers/bulk_add/mail_preview$', vouchers.VoucherBulkMailPreview.as_view(), name='event.vouchers.bulk.mail_preview'),
|
||||
re_path(r'^vouchers/bulk_action$', vouchers.VoucherBulkAction.as_view(), name='event.vouchers.bulkaction'),
|
||||
re_path(r'^vouchers/bulk_edit$', vouchers.VoucherBulkUpdateView.as_view(), name='event.vouchers.bulkedit'),
|
||||
re_path(r'^vouchers/import/$', modelimport.VoucherImportView.as_view(), name='event.vouchers.import'),
|
||||
re_path(r'^vouchers/import/(?P<file>[^/]+)/$', modelimport.VoucherProcessView.as_view(), name='event.vouchers.import.process'),
|
||||
re_path(r'^orders/(?P<code>[0-9A-Z]+)/transition$', orders.OrderTransition.as_view(),
|
||||
|
||||
@@ -42,7 +42,7 @@ from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import PermissionDenied, ValidationError
|
||||
from django.db import connection, transaction
|
||||
from django.db.models import Exists, OuterRef, Sum
|
||||
from django.db.models import Count, Exists, OuterRef, Sum
|
||||
from django.http import (
|
||||
Http404, HttpResponse, HttpResponseBadRequest, HttpResponseRedirect,
|
||||
JsonResponse,
|
||||
@@ -55,7 +55,7 @@ from django.utils.safestring import mark_safe
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import (
|
||||
CreateView, ListView, TemplateView, UpdateView, View,
|
||||
CreateView, FormView, ListView, TemplateView, UpdateView, View,
|
||||
)
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
@@ -70,7 +70,9 @@ from pretix.base.services.vouchers import vouchers_send
|
||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||
from pretix.base.views.tasks import AsyncFormView
|
||||
from pretix.control.forms.filter import VoucherFilterForm, VoucherTagFilterForm
|
||||
from pretix.control.forms.vouchers import VoucherBulkForm, VoucherForm
|
||||
from pretix.control.forms.vouchers import (
|
||||
VoucherBulkEditForm, VoucherBulkForm, VoucherForm,
|
||||
)
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.control.signals import voucher_form_class
|
||||
from pretix.control.views import PaginationMixin
|
||||
@@ -80,7 +82,35 @@ from pretix.helpers.models import modelcopy
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
|
||||
|
||||
class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView):
|
||||
class VoucherQueryMixin:
|
||||
|
||||
@cached_property
|
||||
def request_data(self):
|
||||
if self.request.method == "POST":
|
||||
return self.request.POST
|
||||
return self.request.GET
|
||||
|
||||
@scopes_disabled() # we have an event check here, and we can save some performance on subqueries
|
||||
def get_queryset(self):
|
||||
qs = self.request.event.vouchers.exclude(
|
||||
Exists(WaitingListEntry.objects.filter(voucher_id=OuterRef('pk')))
|
||||
)
|
||||
if self.filter_form.is_valid():
|
||||
qs = self.filter_form.filter_qs(qs)
|
||||
|
||||
if 'voucher' in self.request_data and '__ALL' not in self.request_data:
|
||||
qs = qs.filter(
|
||||
id__in=self.request_data.getlist('voucher')
|
||||
)
|
||||
|
||||
return qs
|
||||
|
||||
@cached_property
|
||||
def filter_form(self):
|
||||
return VoucherFilterForm(data=self.request_data, prefix='filter', event=self.request.event)
|
||||
|
||||
|
||||
class VoucherList(VoucherQueryMixin, PaginationMixin, EventPermissionRequiredMixin, ListView):
|
||||
model = Voucher
|
||||
context_object_name = 'vouchers'
|
||||
template_name = 'pretixcontrol/vouchers/index.html'
|
||||
@@ -88,25 +118,15 @@ class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView):
|
||||
|
||||
@scopes_disabled() # we have an event check here, and we can save some performance on subqueries
|
||||
def get_queryset(self):
|
||||
qs = Voucher.annotate_budget_used(self.request.event.vouchers.exclude(
|
||||
Exists(WaitingListEntry.objects.filter(voucher_id=OuterRef('pk')))
|
||||
).select_related(
|
||||
return Voucher.annotate_budget_used(super().get_queryset().select_related(
|
||||
'item', 'variation', 'seat'
|
||||
))
|
||||
if self.filter_form.is_valid():
|
||||
qs = self.filter_form.filter_qs(qs)
|
||||
|
||||
return qs
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['filter_form'] = self.filter_form
|
||||
return ctx
|
||||
|
||||
@cached_property
|
||||
def filter_form(self):
|
||||
return VoucherFilterForm(data=self.request.GET, event=self.request.event)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
if request.GET.get("download", "") == "yes":
|
||||
return self._download_csv()
|
||||
@@ -293,6 +313,12 @@ class VoucherUpdate(EventPermissionRequiredMixin, UpdateView):
|
||||
f.disabled = True
|
||||
return form
|
||||
|
||||
def get_form_kwargs(self):
|
||||
return {
|
||||
**super().get_form_kwargs(),
|
||||
"event": self.request.event,
|
||||
}
|
||||
|
||||
def get_object(self, queryset=None) -> VoucherForm:
|
||||
url = resolve(self.request.path_info)
|
||||
try:
|
||||
@@ -603,26 +629,21 @@ class VoucherRNG(EventPermissionRequiredMixin, View):
|
||||
})
|
||||
|
||||
|
||||
class VoucherBulkAction(EventPermissionRequiredMixin, View):
|
||||
class VoucherBulkAction(VoucherQueryMixin, EventPermissionRequiredMixin, View):
|
||||
permission = 'event.vouchers:write'
|
||||
|
||||
@cached_property
|
||||
def objects(self):
|
||||
return self.request.event.vouchers.filter(
|
||||
id__in=self.request.POST.getlist('voucher')
|
||||
)
|
||||
|
||||
@transaction.atomic
|
||||
def post(self, request, *args, **kwargs):
|
||||
if request.POST.get('action') == 'delete':
|
||||
return render(request, 'pretixcontrol/vouchers/delete_bulk.html', {
|
||||
'allowed': self.objects.filter(redeemed=0),
|
||||
'forbidden': self.objects.exclude(redeemed=0),
|
||||
'allowed': self.get_queryset().filter(redeemed=0),
|
||||
'forbidden': self.get_queryset().exclude(redeemed=0),
|
||||
})
|
||||
elif request.POST.get('action') == 'delete_confirm':
|
||||
log_entries = []
|
||||
to_delete = []
|
||||
for obj in self.objects:
|
||||
to_update = []
|
||||
for obj in self.get_queryset():
|
||||
if obj.allow_delete():
|
||||
log_entries.append(obj.log_action('pretix.voucher.deleted', user=self.request.user, save=False))
|
||||
to_delete.append(obj.pk)
|
||||
@@ -632,12 +653,14 @@ class VoucherBulkAction(EventPermissionRequiredMixin, View):
|
||||
'bulk': True
|
||||
}, save=False))
|
||||
obj.max_usages = min(obj.redeemed, obj.max_usages)
|
||||
obj.save(update_fields=['max_usages'])
|
||||
to_update.append(obj)
|
||||
|
||||
if to_delete:
|
||||
CartPosition.objects.filter(addon_to__voucher_id__in=to_delete).delete()
|
||||
CartPosition.objects.filter(voucher_id__in=to_delete).delete()
|
||||
Voucher.objects.filter(pk__in=to_delete).delete()
|
||||
if to_update:
|
||||
Voucher.objects.bulk_update(to_update, ['max_usages'])
|
||||
|
||||
LogEntry.bulk_create_and_postprocess(log_entries)
|
||||
messages.success(request, _('The selected vouchers have been deleted or disabled.'))
|
||||
@@ -648,3 +671,117 @@ class VoucherBulkAction(EventPermissionRequiredMixin, View):
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug,
|
||||
})
|
||||
|
||||
|
||||
class VoucherBulkUpdateView(VoucherQueryMixin, EventPermissionRequiredMixin, FormView):
|
||||
template_name = 'pretixcontrol/vouchers/bulk_edit.html'
|
||||
permission = 'event.vouchers:write'
|
||||
context_object_name = 'vouchers'
|
||||
form_class = VoucherBulkEditForm
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().prefetch_related(None).order_by()
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return HttpResponse(status=405)
|
||||
|
||||
@cached_property
|
||||
def is_submitted(self):
|
||||
# Usually, django considers a form "bound" / "submitted" on every POST request. However, this view is always
|
||||
# called with POST method, even if just to pass the selection of objects to work on, so we want to modify
|
||||
# that behavior
|
||||
return '_bulk' in self.request.POST
|
||||
|
||||
def get_form_kwargs(self):
|
||||
initial = {}
|
||||
mixed_values = set()
|
||||
qs = self.get_queryset().annotate()
|
||||
|
||||
fields = (
|
||||
'valid_until', 'block_quota', 'allow_ignore_quota', 'value', 'tag', 'comment', 'max_usages',
|
||||
'min_usages', 'price_mode', 'subevent', 'show_hidden_items', 'all_addons_included', 'all_bundles_included',
|
||||
'budget',
|
||||
)
|
||||
for f in fields:
|
||||
existing_values = list(qs.order_by(f).values(f).annotate(c=Count('*')))
|
||||
if len(existing_values) == 1:
|
||||
initial[f] = existing_values[0][f]
|
||||
elif len(existing_values) > 1:
|
||||
mixed_values.add(f)
|
||||
if f == "max_usages":
|
||||
initial[f] = 1
|
||||
else:
|
||||
initial[f] = None
|
||||
|
||||
existing_values = list(qs.order_by("item", "variation", "quota").values("item", "variation", "quota").annotate(c=Count('*')))
|
||||
if len(existing_values) == 1:
|
||||
i = existing_values[0]
|
||||
if i["quota"]:
|
||||
initial["itemvar"] = f'q-{i["quota"]}'
|
||||
elif i["variation"]:
|
||||
initial["itemvar"] = f'{i["item"]}-{i["variation"]}'
|
||||
elif i["item"]:
|
||||
initial["itemvar"] = f'{i["item"]}'
|
||||
else:
|
||||
initial["itemvar"] = None
|
||||
elif len(existing_values) > 1:
|
||||
mixed_values.add("itemvar")
|
||||
initial["itemvar"] = None
|
||||
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['event'] = self.request.event
|
||||
kwargs['prefix'] = 'bulkedit'
|
||||
kwargs['initial'] = initial
|
||||
kwargs['queryset'] = self.get_queryset()
|
||||
kwargs['mixed_values'] = mixed_values
|
||||
if not self.is_submitted:
|
||||
kwargs['data'] = None
|
||||
kwargs['files'] = None
|
||||
return kwargs
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('control:event.vouchers', kwargs={
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'event': self.request.event.slug,
|
||||
})
|
||||
|
||||
def form_valid(self, form):
|
||||
log_entries = []
|
||||
|
||||
# Main form
|
||||
form.save()
|
||||
data = {
|
||||
k: v
|
||||
for k, v in form.cleaned_data.items()
|
||||
if k in form.changed_data
|
||||
}
|
||||
data['_raw_bulk_data'] = self.request.POST.dict()
|
||||
for obj in self.get_queryset():
|
||||
log_entries.append(
|
||||
obj.log_action('pretix.voucher.changed', data=data, user=self.request.user, save=False)
|
||||
)
|
||||
|
||||
LogEntry.bulk_create_and_postprocess(log_entries)
|
||||
|
||||
messages.success(self.request, _('Your changes have been saved.'))
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['vouchers'] = self.get_queryset()
|
||||
ctx['bulk_selected'] = self.request.POST.getlist("_bulk")
|
||||
return ctx
|
||||
|
||||
@transaction.atomic
|
||||
def post(self, request, *args, **kwargs):
|
||||
form = self.get_form()
|
||||
is_valid = (
|
||||
self.is_submitted and
|
||||
form.is_valid()
|
||||
)
|
||||
if is_valid:
|
||||
return self.form_valid(form)
|
||||
else:
|
||||
if self.is_submitted:
|
||||
messages.error(self.request, _('We could not save your changes. See below for details.'))
|
||||
return self.form_invalid(form)
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:05+0000\n"
|
||||
"PO-Revision-Date: 2026-02-10 16:49+0000\n"
|
||||
"Last-Translator: Michele Pagnozzi <michele.pagnozzi@gmail.com>\n"
|
||||
"PO-Revision-Date: 2026-03-27 09:03+0000\n"
|
||||
"Last-Translator: Ivano Voghera <ivano.voghera@gmail.com>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"it/>\n"
|
||||
"Language: it\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.15.2\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -412,9 +412,8 @@ msgstr ""
|
||||
|
||||
#: pretix/api/serializers/organizer.py:482
|
||||
#: pretix/control/views/organizer.py:1039
|
||||
#, fuzzy
|
||||
msgid "Account invitation"
|
||||
msgstr "Informazioni account modificate"
|
||||
msgstr "Invito account"
|
||||
|
||||
#: pretix/api/serializers/organizer.py:503
|
||||
#: pretix/control/views/organizer.py:1138
|
||||
@@ -656,22 +655,16 @@ msgid "Customer account anonymized"
|
||||
msgstr "Account del cliente anonimizzato"
|
||||
|
||||
#: pretix/api/webhooks.py:470
|
||||
#, fuzzy
|
||||
#| msgid "Gift card code"
|
||||
msgid "Gift card added"
|
||||
msgstr "Codice carta regalo"
|
||||
msgstr "Carta regalo aggiunta"
|
||||
|
||||
#: pretix/api/webhooks.py:474
|
||||
#, fuzzy
|
||||
#| msgid "Gift card code"
|
||||
msgid "Gift card modified"
|
||||
msgstr "Codice carta regalo"
|
||||
msgstr "Carta regalo modificata"
|
||||
|
||||
#: pretix/api/webhooks.py:478
|
||||
#, fuzzy
|
||||
#| msgid "Gift card transactions"
|
||||
msgid "Gift card used in transaction"
|
||||
msgstr "Transazioni con carta regalo"
|
||||
msgstr "Carta regalo usata nella transazione"
|
||||
|
||||
#: pretix/base/addressvalidation.py:100 pretix/base/addressvalidation.py:103
|
||||
#: pretix/base/addressvalidation.py:108 pretix/base/forms/questions.py:1054
|
||||
@@ -1237,7 +1230,7 @@ msgstr "Caricamento dei file di risposta alle domande"
|
||||
#: pretix/plugins/reports/exporters.py:666
|
||||
msgctxt "export_category"
|
||||
msgid "Order data"
|
||||
msgstr "Dati dell'ordine"
|
||||
msgstr "Data dell'ordine"
|
||||
|
||||
#: pretix/base/exporters/answers.py:56
|
||||
msgid ""
|
||||
@@ -2324,6 +2317,10 @@ msgid ""
|
||||
"contain at least one position of this product. The order totals etc. still "
|
||||
"include all products contained in the order."
|
||||
msgstr ""
|
||||
"Se non ne viene selezionato nessuno, saranno inclusi tutti i prodotti. Gli "
|
||||
"ordini vengono inclusi se contengono almeno un articolo di questo prodotto. "
|
||||
"I totali dell'ordine ecc. includeranno comunque tutti i prodotti contenuti "
|
||||
"nell'ordine."
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:283
|
||||
#: pretix/base/exporters/orderlist.py:479
|
||||
@@ -2590,16 +2587,12 @@ msgid "Voucher"
|
||||
msgstr "Voucher"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:655
|
||||
#, fuzzy
|
||||
#| msgid "Voucher deleted"
|
||||
msgid "Voucher budget usage"
|
||||
msgstr "Buono eliminato"
|
||||
msgstr "Utilizzo budget del buono"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:656
|
||||
#, fuzzy
|
||||
#| msgid "Voucher"
|
||||
msgid "Voucher tag"
|
||||
msgstr "Voucher"
|
||||
msgstr "Voucher tag"
|
||||
|
||||
#: pretix/base/exporters/orderlist.py:657
|
||||
msgid "Pseudonymization ID"
|
||||
@@ -3418,39 +3411,34 @@ msgid "Street and Number"
|
||||
msgstr "Indirizzo e numero civico"
|
||||
|
||||
#: pretix/base/forms/questions.py:893
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Please enter a shorter name."
|
||||
#, python-brace-format
|
||||
msgid "Please enter a date between {min} and {max}."
|
||||
msgstr "Per favore inserisci un nome più breve."
|
||||
msgstr "Per favore inserisci una data inclusa tra {min} e {max}."
|
||||
|
||||
#: pretix/base/forms/questions.py:899
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Please enter a valid sales channel."
|
||||
#, python-brace-format
|
||||
msgid "Please enter a date no earlier than {min}."
|
||||
msgstr "Inserire un canale di vendita valido."
|
||||
msgstr "Per favore inserisci una data successiva a {min}."
|
||||
|
||||
#: pretix/base/forms/questions.py:904
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Please enter a shorter name."
|
||||
#, python-brace-format
|
||||
msgid "Please enter a date no later than {max}."
|
||||
msgstr "Per favore inserisci un nome più breve."
|
||||
msgstr "Per favore inserisci una data precedente a {max}."
|
||||
|
||||
#: pretix/base/forms/questions.py:942
|
||||
#, python-brace-format
|
||||
msgid "Please enter a date and time between {min} and {max}."
|
||||
msgstr ""
|
||||
msgstr "Per favore inserisci data e orario compresi tra {min} e {max}."
|
||||
|
||||
#: pretix/base/forms/questions.py:948
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Please enter a valid sales channel."
|
||||
#, python-brace-format
|
||||
msgid "Please enter a date and time no earlier than {min}."
|
||||
msgstr "Inserire un canale di vendita valido."
|
||||
msgstr "Per favore inserisci data e orario successivi a {min}."
|
||||
|
||||
#: pretix/base/forms/questions.py:953
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Please enter the correct result."
|
||||
#, python-brace-format
|
||||
msgid "Please enter a date and time no later than {max}."
|
||||
msgstr "Per favore inserisci il risultato corretto."
|
||||
msgstr "Per favore inserisci data e orario precedenti a {max}."
|
||||
|
||||
#: pretix/base/forms/questions.py:1172
|
||||
msgid ""
|
||||
@@ -3957,7 +3945,7 @@ msgstr ""
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:166
|
||||
msgid "The Peppol participant ID is not registered on the Peppol network."
|
||||
msgstr ""
|
||||
msgstr "L'ID partecipante Peppol non è registrato nella rete Peppol."
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:192
|
||||
msgid "Peppol participant ID"
|
||||
@@ -3965,7 +3953,7 @@ msgstr "ID partecipante Peppol"
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:211
|
||||
msgid "The Peppol participant ID does not match your VAT ID."
|
||||
msgstr ""
|
||||
msgstr "L'ID partecipante Peppol non corrisponde alla tua Partita IVA."
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:214
|
||||
msgctxt "peppol_invoice"
|
||||
@@ -4336,7 +4324,7 @@ msgstr "Permetti di superare la quota"
|
||||
#: pretix/control/templates/pretixcontrol/vouchers/detail.html:70
|
||||
#: pretix/control/views/vouchers.py:121
|
||||
msgid "Price effect"
|
||||
msgstr ""
|
||||
msgstr "Variazione di prezzo"
|
||||
|
||||
#: pretix/base/modelimport_vouchers.py:150
|
||||
#, fuzzy, python-brace-format
|
||||
@@ -5339,7 +5327,6 @@ msgstr "trasmesso"
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:44
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:145
|
||||
#: pretix/plugins/sendmail/models.py:51
|
||||
#, fuzzy
|
||||
msgid "failed"
|
||||
msgstr "fallito"
|
||||
|
||||
@@ -5401,7 +5388,7 @@ msgstr "Categoria normale"
|
||||
|
||||
#: pretix/base/models/items.py:115 pretix/control/forms/item.py:111
|
||||
msgid "Normal + cross-selling category"
|
||||
msgstr "Categoria normale + cross-selling"
|
||||
msgstr "Normale + Categoria cross-selling"
|
||||
|
||||
#: pretix/base/models/items.py:116 pretix/control/forms/item.py:106
|
||||
msgid "Cross-selling category"
|
||||
@@ -6449,13 +6436,13 @@ msgstr "Fine"
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:38
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:139
|
||||
msgid "queued"
|
||||
msgstr ""
|
||||
msgstr "in coda"
|
||||
|
||||
#: pretix/base/models/mail.py:53
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:40
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:141
|
||||
msgid "being sent"
|
||||
msgstr ""
|
||||
msgstr "invio in corso"
|
||||
|
||||
#: pretix/base/models/mail.py:54
|
||||
#, fuzzy
|
||||
@@ -6467,25 +6454,25 @@ msgstr "Voce in lista d'attesa"
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:48
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:149
|
||||
msgid "withheld"
|
||||
msgstr ""
|
||||
msgstr "trattenuto"
|
||||
|
||||
#: pretix/base/models/mail.py:57
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:50
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:151
|
||||
msgid "aborted"
|
||||
msgstr ""
|
||||
msgstr "annullato"
|
||||
|
||||
#: pretix/base/models/mail.py:58
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:52
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:153
|
||||
msgid "sent"
|
||||
msgstr ""
|
||||
msgstr "inviato"
|
||||
|
||||
#: pretix/base/models/mail.py:59
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mail.html:46
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:147
|
||||
msgid "bounced"
|
||||
msgstr ""
|
||||
msgstr "rimbalzato"
|
||||
|
||||
#: pretix/base/models/memberships.py:44
|
||||
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:28
|
||||
@@ -6689,7 +6676,7 @@ msgstr "confermato"
|
||||
#: pretix/base/models/orders.py:1734
|
||||
msgctxt "payment_state"
|
||||
msgid "canceled"
|
||||
msgstr "annullato"
|
||||
msgstr "cancellato"
|
||||
|
||||
#: pretix/base/models/orders.py:1735
|
||||
msgctxt "payment_state"
|
||||
@@ -6920,7 +6907,7 @@ msgstr "Ammissione all'evento"
|
||||
#: pretix/base/models/organizer.py:379
|
||||
#: pretix/control/templates/pretixcontrol/organizers/team_edit.html:34
|
||||
msgid "Event permissions"
|
||||
msgstr ""
|
||||
msgstr "Permessi dell'evento"
|
||||
|
||||
#: pretix/base/models/organizer.py:380
|
||||
#, fuzzy
|
||||
@@ -6930,7 +6917,7 @@ msgstr "Impostazioni account"
|
||||
#: pretix/base/models/organizer.py:381
|
||||
#: pretix/control/templates/pretixcontrol/organizers/team_edit.html:25
|
||||
msgid "Organizer permissions"
|
||||
msgstr ""
|
||||
msgstr "Permessi dell'organizzatore"
|
||||
|
||||
#: pretix/base/models/organizer.py:401
|
||||
#, python-format
|
||||
@@ -8435,7 +8422,7 @@ msgstr "Il tuo file di layout non è un layout valido. Messaggio di errore: {}"
|
||||
#: pretix/base/permissions.py:314 pretix/base/permissions.py:331
|
||||
msgctxt "permission_level"
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
msgstr "Vista"
|
||||
|
||||
#: pretix/base/permissions.py:164 pretix/base/permissions.py:169
|
||||
#: pretix/base/permissions.py:174 pretix/base/permissions.py:179
|
||||
@@ -8447,12 +8434,14 @@ msgstr "Salva modifiche"
|
||||
|
||||
#: pretix/base/permissions.py:168
|
||||
msgid "API only"
|
||||
msgstr ""
|
||||
msgstr "Solo API"
|
||||
|
||||
#: pretix/base/permissions.py:173
|
||||
msgid ""
|
||||
"Menu item will only show up if the user has permission for general settings."
|
||||
msgstr ""
|
||||
"La voce di menu apparirà solo se l'utente ha il permesso per le impostazioni "
|
||||
"generali."
|
||||
|
||||
#: pretix/base/permissions.py:177 pretix/base/permissions.py:231
|
||||
#: pretix/base/permissions.py:285 pretix/base/permissions.py:313
|
||||
@@ -8474,12 +8463,14 @@ msgid ""
|
||||
"This includes access to all settings not listed explicitly below, including "
|
||||
"plugin settings."
|
||||
msgstr ""
|
||||
"Include l'accesso a tutte le impostazioni non elencate esplicitamente di "
|
||||
"seguito, comprese le impostazioni dei plugin."
|
||||
|
||||
#: pretix/base/permissions.py:197
|
||||
#: pretix/control/templates/pretixcontrol/event/payment.html:6
|
||||
#: pretix/control/templates/pretixcontrol/event/payment_provider.html:5
|
||||
msgid "Payment settings"
|
||||
msgstr ""
|
||||
msgstr "Impostazioni di pagamento"
|
||||
|
||||
#: pretix/base/permissions.py:203
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:120
|
||||
@@ -8488,10 +8479,8 @@ msgid "Tax settings"
|
||||
msgstr "Impostazioni account"
|
||||
|
||||
#: pretix/base/permissions.py:209
|
||||
#, fuzzy
|
||||
#| msgid "Login settings"
|
||||
msgid "Invoicing settings"
|
||||
msgstr "Impostazioni login"
|
||||
msgstr "Impostazioni Fattura"
|
||||
|
||||
#: pretix/base/permissions.py:215
|
||||
#, fuzzy
|
||||
@@ -8508,7 +8497,7 @@ msgstr "Nome prodotto e variante"
|
||||
|
||||
#: pretix/base/permissions.py:224
|
||||
msgid "Also includes related objects like categories or discounts."
|
||||
msgstr ""
|
||||
msgstr "Include anche gli oggetti correlati come categorie o sconti."
|
||||
|
||||
#: pretix/base/permissions.py:232
|
||||
#, fuzzy
|
||||
@@ -8519,7 +8508,7 @@ msgstr "Filtra per stato"
|
||||
#: pretix/base/permissions.py:233
|
||||
msgctxt "permission_level"
|
||||
msgid "View all"
|
||||
msgstr ""
|
||||
msgstr "Vedi tutto"
|
||||
|
||||
#: pretix/base/permissions.py:234
|
||||
#, fuzzy
|
||||
@@ -8530,15 +8519,15 @@ msgstr "Filtra per stato"
|
||||
#: pretix/base/permissions.py:235
|
||||
msgctxt "permission_level"
|
||||
msgid "View all and change"
|
||||
msgstr ""
|
||||
msgstr "Vedi e modifica tutto"
|
||||
|
||||
#: pretix/base/permissions.py:236
|
||||
msgid "Includes the ability to cancel and refund individual orders."
|
||||
msgstr ""
|
||||
msgstr "Include il permesso di cancellare e rimborsare ordini individuali."
|
||||
|
||||
#: pretix/base/permissions.py:238
|
||||
msgid "Also includes related objects like the waiting list."
|
||||
msgstr ""
|
||||
msgstr "Include anche gli oggetti correlati come la lista d'attesa."
|
||||
|
||||
#: pretix/base/permissions.py:248
|
||||
#, fuzzy
|
||||
@@ -8562,17 +8551,19 @@ msgstr "Tasse"
|
||||
#: pretix/base/permissions.py:268
|
||||
msgctxt "permission_level"
|
||||
msgid "Access existing events"
|
||||
msgstr ""
|
||||
msgstr "Accedere agli eventi esistenti"
|
||||
|
||||
#: pretix/base/permissions.py:269
|
||||
msgctxt "permission_level"
|
||||
msgid "Access existing and create new events"
|
||||
msgstr ""
|
||||
msgstr "Accedere agli eventi esistenti e crearne di nuovi"
|
||||
|
||||
#: pretix/base/permissions.py:271
|
||||
msgid ""
|
||||
"The level of access to events is determined in detail by the settings below."
|
||||
msgstr ""
|
||||
"Il livello di accesso agli eventi è determinato nel dettaglio dalle "
|
||||
"impostazioni sottostanti."
|
||||
|
||||
#: pretix/base/permissions.py:275 pretix/control/navigation.py:143
|
||||
#: pretix/control/navigation.py:462 pretix/control/navigation.py:512
|
||||
@@ -8591,6 +8582,8 @@ msgid ""
|
||||
"This includes access to all organizer-level functionality not listed "
|
||||
"explicitly below, including plugin settings."
|
||||
msgstr ""
|
||||
"Include l'accesso a tutte le funzionalità a livello di organizzatore non "
|
||||
"elencate esplicitamente di seguito, comprese le impostazioni dei plugin."
|
||||
|
||||
#: pretix/base/permissions.py:287
|
||||
msgid ""
|
||||
@@ -8625,7 +8618,7 @@ msgstr "Piano dei posti a sedere"
|
||||
#: pretix/base/permissions.py:327 pretix/control/navigation.py:712
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:8
|
||||
msgid "Outgoing emails"
|
||||
msgstr ""
|
||||
msgstr "Email in uscita"
|
||||
|
||||
#: pretix/base/plugins.py:138
|
||||
#: pretix/control/templates/pretixcontrol/event/quick_setup.html:132
|
||||
@@ -10097,6 +10090,11 @@ msgid ""
|
||||
"placing an order, the restriction only becomes active after the customer "
|
||||
"account is activated."
|
||||
msgstr ""
|
||||
"Se abilitato, gli utenti che erano autenticati al momento dell'acquisto "
|
||||
"dovranno effettuare l'accesso anche per consultare le informazioni sul "
|
||||
"proprio ordine. Se un account cliente viene creato durante l'effettuazione "
|
||||
"di un ordine, la restrizione diventerà attiva solo dopo l'attivazione "
|
||||
"dell'account stesso."
|
||||
|
||||
#: pretix/base/settings.py:203
|
||||
msgid "Match orders based on email address"
|
||||
@@ -13190,6 +13188,9 @@ msgid ""
|
||||
"logged email contents. This will also remove the association to customer "
|
||||
"accounts."
|
||||
msgstr ""
|
||||
"Questo rimuoverà tutti gli indirizzi email dagli ordini e dai partecipanti, "
|
||||
"così come il contenuto delle email registrate. Rimuoverà inoltre "
|
||||
"l'associazione agli account cliente."
|
||||
|
||||
#: pretix/base/shredder.py:373
|
||||
msgid ""
|
||||
@@ -16579,19 +16580,19 @@ msgstr "Salva modifiche"
|
||||
|
||||
#: pretix/control/forms/rrule.py:35
|
||||
msgid "year(s)"
|
||||
msgstr ""
|
||||
msgstr "anno/i"
|
||||
|
||||
#: pretix/control/forms/rrule.py:36
|
||||
msgid "month(s)"
|
||||
msgstr "mese(i)"
|
||||
msgstr "mese/i"
|
||||
|
||||
#: pretix/control/forms/rrule.py:37
|
||||
msgid "week(s)"
|
||||
msgstr "settimana (e)"
|
||||
msgstr "settimana/e"
|
||||
|
||||
#: pretix/control/forms/rrule.py:38
|
||||
msgid "day(s)"
|
||||
msgstr ""
|
||||
msgstr "giorno/i"
|
||||
|
||||
#: pretix/control/forms/rrule.py:43
|
||||
msgid "Interval"
|
||||
@@ -16628,7 +16629,7 @@ msgstr ""
|
||||
#: pretix/control/forms/rrule.py:111 pretix/control/forms/rrule.py:150
|
||||
#: pretix/presale/templates/pretixpresale/fragment_calendar_nav.html:20
|
||||
msgid "Day"
|
||||
msgstr ""
|
||||
msgstr "Giorno"
|
||||
|
||||
#: pretix/control/forms/rrule.py:113 pretix/control/forms/rrule.py:152
|
||||
msgid "Weekend day"
|
||||
@@ -17230,9 +17231,8 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/logdisplay.py:529
|
||||
#, fuzzy
|
||||
msgid "The customer account has been changed."
|
||||
msgstr "La data dell'evento è stata modificata."
|
||||
msgstr "L'account cliente è stato modificato."
|
||||
|
||||
#: pretix/control/logdisplay.py:530
|
||||
msgid "The order locale has been changed."
|
||||
@@ -18914,7 +18914,7 @@ msgstr ""
|
||||
#: pretix/presale/templates/pretixpresale/postmessage.html:27
|
||||
#: pretix/presale/templates/pretixpresale/waiting.html:42
|
||||
msgid "If this takes longer than a few minutes, please contact us."
|
||||
msgstr ""
|
||||
msgstr "Se questa operazione richiede alcuni minuti, si prega di contattarci."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:4
|
||||
#: pretix/control/templates/pretixcontrol/organizers/devices.html:75
|
||||
@@ -20687,8 +20687,6 @@ msgid "Payment reminder"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/mail.html:108
|
||||
#, fuzzy
|
||||
#| msgid "Payment confirmed"
|
||||
msgid "Payment failed"
|
||||
msgstr "Pagamento rifiutato"
|
||||
|
||||
@@ -20739,7 +20737,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/event/payment.html:78
|
||||
msgctxt "unit"
|
||||
msgid "days"
|
||||
msgstr ""
|
||||
msgstr "giorni"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/payment_provider.html:13
|
||||
#: pretix/control/templates/pretixcontrol/events/create_base.html:24
|
||||
@@ -21616,7 +21614,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/fragment_quota_box_paid.html:3
|
||||
#, python-format
|
||||
msgid "Currently available: %(num)s"
|
||||
msgstr ""
|
||||
msgstr "Attualmente disponibili: %(num)s"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/global_license.html:8
|
||||
msgid ""
|
||||
@@ -21862,6 +21860,8 @@ msgid ""
|
||||
"This product is currently not being sold since you configured below that it "
|
||||
"should only be available in a certain timeframe."
|
||||
msgstr ""
|
||||
"Questo prodotto non è attualmente in vendita, poiché è stato configurato per "
|
||||
"essere disponibile solo in un determinato intervallo di tempo."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/item/base.html:41
|
||||
msgid ""
|
||||
@@ -22367,6 +22367,8 @@ msgstr "Crea un nuovo organizzatore"
|
||||
msgid ""
|
||||
"Currently unavailable since a limited timeframe for this product has been set"
|
||||
msgstr ""
|
||||
"Attualmente non disponibile poiché è stato impostato un intervallo di tempo "
|
||||
"limitato per questo prodotto"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/discounts.html:119
|
||||
msgid "Condition:"
|
||||
@@ -22863,12 +22865,13 @@ msgstr ""
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:483
|
||||
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:7
|
||||
msgid "Cancel order"
|
||||
msgstr ""
|
||||
msgstr "Elimina ordine"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/cancel.html:12
|
||||
#: pretix/control/templates/pretixcontrol/order/deny.html:11
|
||||
msgid "Do you really want to cancel this order? You cannot revert this action."
|
||||
msgstr ""
|
||||
"Vuoi davvero eliminare questo ordine? Questa azione non può essere annullata."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/cancel.html:16
|
||||
msgid ""
|
||||
@@ -22887,12 +22890,12 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/order/cancel.html:51
|
||||
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:220
|
||||
msgid "Yes, cancel order"
|
||||
msgstr ""
|
||||
msgstr "Si, elimina ordine"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/cancellation_request_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/order/cancellation_request_delete.html:8
|
||||
msgid "Ignore cancellation request"
|
||||
msgstr ""
|
||||
msgstr "Ignora la richiesta di cancellazione"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/cancellation_request_delete.html:10
|
||||
msgid ""
|
||||
@@ -23002,9 +23005,8 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/change.html:220
|
||||
#, fuzzy
|
||||
msgid "Ticket block"
|
||||
msgstr "Codice biglietto"
|
||||
msgstr "Biglietto bloccato"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/change.html:226
|
||||
msgid "Blocked due to external constraints"
|
||||
@@ -25151,9 +25153,8 @@ msgid "Organizer logs"
|
||||
msgstr "Organizzatore"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/mail.html:60
|
||||
#, fuzzy
|
||||
msgid "Customer account registration"
|
||||
msgstr "Invia ordine"
|
||||
msgstr "Registrazione account cliente"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/organizers/mail.html:63
|
||||
#, fuzzy
|
||||
@@ -26182,7 +26183,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:10
|
||||
msgctxt "subevent"
|
||||
msgid "Create multiple dates"
|
||||
msgstr ""
|
||||
msgstr "Crea date multiple"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:35
|
||||
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:146
|
||||
@@ -26275,10 +26276,9 @@ msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:9
|
||||
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:12
|
||||
#, fuzzy
|
||||
msgctxt "subevent"
|
||||
msgid "Change multiple dates"
|
||||
msgstr "Solo ordini pagati"
|
||||
msgstr "Cambia date multiple"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/subevents/bulk_edit.html:154
|
||||
msgid "Item prices"
|
||||
@@ -27208,6 +27208,12 @@ msgid ""
|
||||
"quota is available) or you can press the big button below this text to send "
|
||||
"out as many vouchers as currently possible to the persons who waited longest."
|
||||
msgstr ""
|
||||
"Hai configurato il sistema affinché i voucher <strong>non</strong> vengano "
|
||||
"inviati automaticamente. Puoi inviarli singolarmente nell'ordine che "
|
||||
"preferisci cliccando sui pulsanti accanto a ogni riga di questa tabella (se "
|
||||
"la quota è sufficiente), oppure puoi premere il pulsante grande sotto questo "
|
||||
"testo per inviare quanti più voucher possibile alle persone in attesa da più "
|
||||
"tempo."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/waitinglist/index.html:79
|
||||
msgid "Send as many vouchers as possible"
|
||||
@@ -33293,10 +33299,9 @@ msgstr ""
|
||||
|
||||
#: pretix/presale/forms/renderers.py:66
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:14
|
||||
#, fuzzy
|
||||
msgctxt "form"
|
||||
msgid "required"
|
||||
msgstr "Carrello scaduto"
|
||||
msgstr "obbligatorio"
|
||||
|
||||
#: pretix/presale/ical.py:87 pretix/presale/ical.py:146
|
||||
#: pretix/presale/ical.py:182
|
||||
@@ -33629,7 +33634,7 @@ msgstr "Invia ordine"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:19
|
||||
msgid "Log in with a customer account"
|
||||
msgstr ""
|
||||
msgstr "Accedi con un account cliente"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:26
|
||||
msgid "You are currently logged in with the following credentials."
|
||||
@@ -34002,7 +34007,7 @@ msgstr ""
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:25
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:91
|
||||
msgid "FULLY BOOKED"
|
||||
msgstr ""
|
||||
msgstr "TUTTO PRENOTATO"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:37
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:101
|
||||
@@ -34514,7 +34519,7 @@ msgstr ""
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_quota_left.html:4
|
||||
#, python-format
|
||||
msgid "%(num)s currently available"
|
||||
msgstr ""
|
||||
msgstr "%(num)s attualmente disponibili"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_calendar.html:5
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_subevent_calendar_week.html:5
|
||||
@@ -34751,18 +34756,14 @@ msgstr ""
|
||||
"completo."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:56
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Please bookmark or save the link to this exact page if you want to access "
|
||||
#| "your order later. We also sent you an email containing the link to the "
|
||||
#| "address you specified."
|
||||
msgid ""
|
||||
"Please bookmark or save the link to this exact page if you want to access "
|
||||
"your order later. We also sent you an email to the address you specified "
|
||||
"containing the link to this page."
|
||||
msgstr ""
|
||||
"Salva questa pagina nei preferiti se vuoi accedervi in seguito. Ti abbiamo "
|
||||
"anche inviato una email contenente il link a questa pagina."
|
||||
"Salva questa pagina nei preferiti se vuoi accedere al tuo ordine in seguito. "
|
||||
"Ti abbiamo anche inviato una email all'indirizzo che hai indicato contenente "
|
||||
"il link a questa pagina."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:60
|
||||
#, fuzzy
|
||||
@@ -34877,7 +34878,7 @@ msgstr "Riferimento Interno"
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:354
|
||||
msgctxt "action"
|
||||
msgid "Change or cancel your order"
|
||||
msgstr ""
|
||||
msgstr "Modifica o cancella il tuo ordine"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:356
|
||||
#, fuzzy
|
||||
@@ -34887,10 +34888,9 @@ msgid "Change your order"
|
||||
msgstr "Cambia ordine"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:358
|
||||
#, fuzzy
|
||||
msgctxt "action"
|
||||
msgid "Cancel your order"
|
||||
msgstr "Solo ordini pagati"
|
||||
msgstr "Cancella il tuo ordine"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:366
|
||||
msgid ""
|
||||
@@ -34984,7 +34984,7 @@ msgstr ""
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order.html:472
|
||||
msgid "You can cancel this order using the following button."
|
||||
msgstr ""
|
||||
msgstr "Puoi cancellare questo ordine usando il bottone di seguito."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:11
|
||||
#, python-format
|
||||
@@ -35271,7 +35271,7 @@ msgstr "Devi selezionare almeno %(number)s prodotti."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:5
|
||||
msgid "Add me to the waiting list"
|
||||
msgstr ""
|
||||
msgstr "Aggiungimi alla lista d'attesa"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:22
|
||||
#, python-format
|
||||
@@ -35280,6 +35280,10 @@ msgid ""
|
||||
"waiting list. If we notify you, you'll have %(hours)s hours time to buy a "
|
||||
"ticket until we assign it to the next person on the list."
|
||||
msgstr ""
|
||||
"Se i biglietti dovessero tornare disponibili, informeremo le prime persone "
|
||||
"in lista d'attesa. Se ti avvisiamo, avrai %(hours)s ore di tempo per "
|
||||
"acquistare un biglietto prima che venga assegnato alla persona successiva in "
|
||||
"lista."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:28
|
||||
msgid ""
|
||||
@@ -35287,6 +35291,9 @@ msgid ""
|
||||
"you need to add yourself to the waiting list multiple times. There is no "
|
||||
"guarantee that you will receive a certain number of tickets."
|
||||
msgstr ""
|
||||
"Tieni presente che riceverai un solo biglietto. Se hai bisogno di più "
|
||||
"biglietti, dovrai iscriverti alla lista d'attesa più volte. Non è garantito "
|
||||
"che riceverai un numero esatto di biglietti."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:32
|
||||
msgid ""
|
||||
@@ -35295,6 +35302,10 @@ msgid ""
|
||||
"email addresses. There is no guarantee that you will receive a certain "
|
||||
"number of tickets."
|
||||
msgstr ""
|
||||
"Tieni presente che riceverai un solo biglietto. Se hai bisogno di più "
|
||||
"biglietti, dovrai iscriverti alla lista d'attesa più volte utilizzando "
|
||||
"indirizzi email diversi. Non è garantito che riceverai un numero esatto di "
|
||||
"biglietti."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:38
|
||||
msgid ""
|
||||
@@ -35302,15 +35313,17 @@ msgid ""
|
||||
"been added to the waiting list. We will only contact you once a spot opens "
|
||||
"up."
|
||||
msgstr ""
|
||||
"<strong>Non</strong> riceverai un'email di conferma dopo essere stato "
|
||||
"aggiunto alla lista d'attesa. Ti contatteremo solo quando si libererà un "
|
||||
"posto."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist.html:44
|
||||
msgid "Add me to the list"
|
||||
msgstr ""
|
||||
msgstr "Aggiungimi alla lista"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist_remove.html:5
|
||||
#, fuzzy
|
||||
msgid "Remove me from the waiting list"
|
||||
msgstr "Informazioni dell'ordine modificate"
|
||||
msgstr "Cancellami dalla lista d'attesa"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist_remove.html:9
|
||||
msgid ""
|
||||
@@ -35320,10 +35333,9 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/waitinglist_remove.html:16
|
||||
#, fuzzy
|
||||
msgctxt "waitinglist"
|
||||
msgid "Yes, remove my ticket"
|
||||
msgstr "Aggiungi o rimuovi biglietti"
|
||||
msgstr "Si, cancella i miei biglietti"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_calendar.html:7
|
||||
msgid "Calendar"
|
||||
@@ -35347,9 +35359,8 @@ msgstr "(continua)"
|
||||
#: pretix/presale/templates/pretixpresale/fragment_event_list_status.html:14
|
||||
#: pretix/presale/templates/pretixpresale/fragment_week_calendar.html:58
|
||||
#: pretix/presale/views/widget.py:440
|
||||
#, fuzzy
|
||||
msgid "Few tickets left"
|
||||
msgstr "Abilita formato biglietti"
|
||||
msgstr "Pochi biglietti rimasti"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_calendar.html:92
|
||||
#: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:97
|
||||
@@ -35397,10 +35408,9 @@ msgid "iCal"
|
||||
msgstr "iCal"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:25
|
||||
#, fuzzy
|
||||
msgctxt "day calendar"
|
||||
msgid "Single events"
|
||||
msgstr "Prezzo netto"
|
||||
msgstr "Singoli eventi"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_day_calendar.html:79
|
||||
msgctxt "timerange"
|
||||
@@ -35426,13 +35436,12 @@ msgstr ""
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_login_status.html:5
|
||||
msgid "customer account"
|
||||
msgstr ""
|
||||
msgstr "account cliente"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_login_status.html:8
|
||||
#: pretix/presale/templates/pretixpresale/fragment_login_status.html:9
|
||||
#, fuzzy
|
||||
msgid "View customer account"
|
||||
msgstr "Vedi un'altra data"
|
||||
msgstr "Vedi account cliente"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/fragment_modals.html:18
|
||||
#, fuzzy
|
||||
@@ -35630,9 +35639,8 @@ msgid "Change account information"
|
||||
msgstr "Le tue informazioni"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/organizers/customer_base.html:41
|
||||
#, fuzzy
|
||||
msgid "customer account information"
|
||||
msgstr "Invia ordine"
|
||||
msgstr "Informazioni account cliente"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:28
|
||||
#, fuzzy, python-format
|
||||
@@ -35790,7 +35798,7 @@ msgstr "Ripeti la nuova password"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/organizers/index.html:11
|
||||
msgid "Event list"
|
||||
msgstr ""
|
||||
msgstr "Lista eventi"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/organizers/index.html:35
|
||||
msgid "Past events"
|
||||
@@ -35801,10 +35809,9 @@ msgid "Upcoming events"
|
||||
msgstr "Prossimi eventi"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/organizers/index.html:56
|
||||
#, fuzzy
|
||||
msgctxt "subevent"
|
||||
msgid "Multiple dates"
|
||||
msgstr "Solo ordini pagati"
|
||||
msgstr "Date multiple"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/organizers/index.html:105
|
||||
msgid "No archived events found."
|
||||
@@ -36147,6 +36154,8 @@ msgid ""
|
||||
"You cannot add yourself to the waiting list as this product is currently "
|
||||
"available."
|
||||
msgstr ""
|
||||
"Non puoi aggiungerti alla lista d'attesa in quanto questo prodotto è "
|
||||
"attualmente disponibile."
|
||||
|
||||
#: pretix/presale/views/waiting.py:180
|
||||
#, python-brace-format
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:06+0000\n"
|
||||
"PO-Revision-Date: 2026-02-10 16:49+0000\n"
|
||||
"Last-Translator: Raffaele Doretto <ced@comune.portogruaro.ve.it>\n"
|
||||
"PO-Revision-Date: 2026-03-25 14:14+0000\n"
|
||||
"Last-Translator: Pietro Isotti <isottipietro@gmail.com>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/it/>\n"
|
||||
"Language: it\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.15.2\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -310,9 +310,8 @@ msgid "Ticket code revoked/changed"
|
||||
msgstr "Codice biglietto annullato/modificato"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
|
||||
#, fuzzy
|
||||
msgid "Ticket blocked"
|
||||
msgstr "Biglietto non pagato"
|
||||
msgstr "Biglietto bloccato"
|
||||
|
||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
|
||||
msgid "Ticket not valid at this time"
|
||||
@@ -429,7 +428,7 @@ msgstr ""
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:276
|
||||
msgid "If this takes longer than a few minutes, please contact us."
|
||||
msgstr ""
|
||||
msgstr "Se questa operazione richiede alcuni minuti, si prega di contattarci."
|
||||
|
||||
#: pretix/static/pretixbase/js/asynctask.js:331
|
||||
msgid "Close message"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:05+0000\n"
|
||||
"PO-Revision-Date: 2026-03-09 12:52+0000\n"
|
||||
"PO-Revision-Date: 2026-03-23 21:00+0000\n"
|
||||
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
|
||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"ja/>\n"
|
||||
@@ -399,10 +399,8 @@ msgstr ""
|
||||
|
||||
#: pretix/api/serializers/organizer.py:482
|
||||
#: pretix/control/views/organizer.py:1039
|
||||
#, fuzzy
|
||||
#| msgid "Account information"
|
||||
msgid "Account invitation"
|
||||
msgstr "アカウント情報"
|
||||
msgstr "アカウントに招待"
|
||||
|
||||
#: pretix/api/serializers/organizer.py:503
|
||||
#: pretix/control/views/organizer.py:1138
|
||||
@@ -3926,10 +3924,8 @@ msgid "Peppol participant ID"
|
||||
msgstr "Peppol参加者ID"
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:211
|
||||
#, fuzzy
|
||||
#| msgid "The Peppol participant ID is not registered on the Peppol network."
|
||||
msgid "The Peppol participant ID does not match your VAT ID."
|
||||
msgstr "Peppol参加者IDはPeppolネットワークに登録されていません。"
|
||||
msgstr "Peppolの参加者IDがVAT IDと一致しません。"
|
||||
|
||||
#: pretix/base/invoicing/peppol.py:214
|
||||
msgctxt "peppol_invoice"
|
||||
@@ -6766,10 +6762,8 @@ msgstr ""
|
||||
"かかる場合があります。"
|
||||
|
||||
#: pretix/base/models/organizer.py:378
|
||||
#, fuzzy
|
||||
#| msgid "Event permissions"
|
||||
msgid "All event permissions"
|
||||
msgstr "イベントの権限"
|
||||
msgstr "すべてのイベントの権限"
|
||||
|
||||
#: pretix/base/models/organizer.py:379
|
||||
#: pretix/control/templates/pretixcontrol/organizers/team_edit.html:34
|
||||
@@ -6777,10 +6771,8 @@ msgid "Event permissions"
|
||||
msgstr "イベントの権限"
|
||||
|
||||
#: pretix/base/models/organizer.py:380
|
||||
#, fuzzy
|
||||
#| msgid "Organizer permissions"
|
||||
msgid "All organizer permissions"
|
||||
msgstr "主催者の権限"
|
||||
msgstr "全ての主催者の権限"
|
||||
|
||||
#: pretix/base/models/organizer.py:381
|
||||
#: pretix/control/templates/pretixcontrol/organizers/team_edit.html:25
|
||||
@@ -8244,36 +8236,30 @@ msgstr ""
|
||||
#: pretix/base/permissions.py:314 pretix/base/permissions.py:331
|
||||
msgctxt "permission_level"
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
msgstr "見る"
|
||||
|
||||
#: pretix/base/permissions.py:164 pretix/base/permissions.py:169
|
||||
#: pretix/base/permissions.py:174 pretix/base/permissions.py:179
|
||||
#: pretix/base/permissions.py:286 pretix/base/permissions.py:315
|
||||
#, fuzzy
|
||||
#| msgid "Save and check"
|
||||
msgctxt "permission_level"
|
||||
msgid "View and change"
|
||||
msgstr "保存してチェックします"
|
||||
msgstr "確認と変更"
|
||||
|
||||
#: pretix/base/permissions.py:168
|
||||
#, fuzzy
|
||||
#| msgid "API tokens"
|
||||
msgid "API only"
|
||||
msgstr "APIトークン"
|
||||
msgstr "APIのみ"
|
||||
|
||||
#: pretix/base/permissions.py:173
|
||||
msgid ""
|
||||
"Menu item will only show up if the user has permission for general settings."
|
||||
msgstr ""
|
||||
msgstr "メニュー項目は、ユーザーが一般設定の権限を持っている場合にのみ表示されます。"
|
||||
|
||||
#: pretix/base/permissions.py:177 pretix/base/permissions.py:231
|
||||
#: pretix/base/permissions.py:285 pretix/base/permissions.py:313
|
||||
#: pretix/base/permissions.py:330
|
||||
#, fuzzy
|
||||
#| msgid "Revoke access"
|
||||
msgctxt "permission_level"
|
||||
msgid "No access"
|
||||
msgstr "アクセスを取り消す"
|
||||
msgstr "アクセスなし"
|
||||
|
||||
#: pretix/base/permissions.py:188
|
||||
#: pretix/control/templates/pretixcontrol/event/settings.html:7
|
||||
@@ -8287,6 +8273,8 @@ msgid ""
|
||||
"This includes access to all settings not listed explicitly below, including "
|
||||
"plugin settings."
|
||||
msgstr ""
|
||||
"これには、以下に明示的に記載されていないすべての設定(プラグイン設定を含む)"
|
||||
"へのアクセスが含まれます。"
|
||||
|
||||
#: pretix/base/permissions.py:197
|
||||
#: pretix/control/templates/pretixcontrol/event/payment.html:6
|
||||
@@ -8300,100 +8288,77 @@ msgid "Tax settings"
|
||||
msgstr "税の設定"
|
||||
|
||||
#: pretix/base/permissions.py:209
|
||||
#, fuzzy
|
||||
#| msgid "Invoice settings"
|
||||
msgid "Invoicing settings"
|
||||
msgstr "請求書の設定"
|
||||
msgstr "請求の設定"
|
||||
|
||||
#: pretix/base/permissions.py:215
|
||||
#, fuzzy
|
||||
#| msgctxt "subevent"
|
||||
#| msgid "Event series date added"
|
||||
msgid "Event series dates"
|
||||
msgstr "イベントシリーズに日程が追加されました"
|
||||
msgstr "イベントシリーズの日程"
|
||||
|
||||
#: pretix/base/permissions.py:221
|
||||
#, fuzzy
|
||||
#| msgid "Product name and variation"
|
||||
msgid "Products, quotas and questions"
|
||||
msgstr "製品名とバリエーション"
|
||||
msgstr "製品、クオータおよび質問"
|
||||
|
||||
#: pretix/base/permissions.py:224
|
||||
msgid "Also includes related objects like categories or discounts."
|
||||
msgstr ""
|
||||
msgstr "カテゴリや割引などの関連オブジェクトも含まれます。"
|
||||
|
||||
#: pretix/base/permissions.py:232
|
||||
#, fuzzy
|
||||
#| msgid "All check-ins"
|
||||
msgctxt "permission_level"
|
||||
msgid "Only check-in"
|
||||
msgstr "すべてのチェックイン"
|
||||
msgstr "チェックインのみ"
|
||||
|
||||
#: pretix/base/permissions.py:233
|
||||
#, fuzzy
|
||||
#| msgid "View full log"
|
||||
msgctxt "permission_level"
|
||||
msgid "View all"
|
||||
msgstr "フルログを表示します"
|
||||
msgstr "すべてを表示"
|
||||
|
||||
#: pretix/base/permissions.py:234
|
||||
#, fuzzy
|
||||
#| msgid "Valid check-in"
|
||||
msgctxt "permission_level"
|
||||
msgid "View all and check-in"
|
||||
msgstr "有効なチェックイン"
|
||||
msgstr "すべてを表示してチェックイン"
|
||||
|
||||
#: pretix/base/permissions.py:235
|
||||
#, fuzzy
|
||||
#| msgid "View all upcoming events"
|
||||
msgctxt "permission_level"
|
||||
msgid "View all and change"
|
||||
msgstr "すべての予定されているイベントを表示します"
|
||||
msgstr "すべてを表示して変更する"
|
||||
|
||||
#: pretix/base/permissions.py:236
|
||||
msgid "Includes the ability to cancel and refund individual orders."
|
||||
msgstr ""
|
||||
msgstr "個別の注文をキャンセルおよび返金する機能が含まれています。"
|
||||
|
||||
#: pretix/base/permissions.py:238
|
||||
#, fuzzy
|
||||
#| msgid "An entry has been added to the waiting list."
|
||||
msgid "Also includes related objects like the waiting list."
|
||||
msgstr "空席待ちリストに登録が追加されました。"
|
||||
msgstr "待機リストなどの関連オブジェクトも含まれます。"
|
||||
|
||||
#: pretix/base/permissions.py:248
|
||||
#, fuzzy
|
||||
#| msgid "Generate cancellation"
|
||||
msgid "Full event or date cancellation"
|
||||
msgstr "キャンセルを生成します"
|
||||
msgstr "イベント全体または日程のキャンセル"
|
||||
|
||||
#: pretix/base/permissions.py:252
|
||||
#, fuzzy
|
||||
#| msgid "Sale not allowed"
|
||||
msgctxt "permission_level"
|
||||
msgid "Not allowed"
|
||||
msgstr "販売は許可されていません"
|
||||
msgstr "許可されていません"
|
||||
|
||||
#: pretix/base/permissions.py:253
|
||||
#, fuzzy
|
||||
#| msgid "Allowed titles"
|
||||
msgctxt "permission_level"
|
||||
msgid "Allowed"
|
||||
msgstr "選択可能な敬称"
|
||||
msgstr "許可されている"
|
||||
|
||||
#: pretix/base/permissions.py:268
|
||||
msgctxt "permission_level"
|
||||
msgid "Access existing events"
|
||||
msgstr ""
|
||||
msgstr "既存のイベントにアクセス"
|
||||
|
||||
#: pretix/base/permissions.py:269
|
||||
msgctxt "permission_level"
|
||||
msgid "Access existing and create new events"
|
||||
msgstr ""
|
||||
msgstr "既存のイベントにアクセスし、新しいイベントを作成する"
|
||||
|
||||
#: pretix/base/permissions.py:271
|
||||
msgid ""
|
||||
"The level of access to events is determined in detail by the settings below."
|
||||
msgstr ""
|
||||
msgstr "イベントへのアクセスレベルは、以下の設定によって詳細に決定されます。"
|
||||
|
||||
#: pretix/base/permissions.py:275 pretix/control/navigation.py:143
|
||||
#: pretix/control/navigation.py:462 pretix/control/navigation.py:512
|
||||
@@ -8412,12 +8377,14 @@ msgid ""
|
||||
"This includes access to all organizer-level functionality not listed "
|
||||
"explicitly below, including plugin settings."
|
||||
msgstr ""
|
||||
"これには、以下に明示的に記載されていないすべてのオーガナイザーレベル機能への"
|
||||
"アクセスが含まれ、プラグイン設定も含まれます。"
|
||||
|
||||
#: pretix/base/permissions.py:287
|
||||
msgid ""
|
||||
"Includes the ability to give someone (including oneself) additional "
|
||||
"permissions."
|
||||
msgstr ""
|
||||
msgstr "自分自身を含む誰かに追加の権限を付与する機能が含まれています。"
|
||||
|
||||
#: pretix/base/permissions.py:298 pretix/control/navigation.py:608
|
||||
#: pretix/control/templates/pretixcontrol/organizers/customers.html:6
|
||||
@@ -8435,12 +8402,12 @@ msgid ""
|
||||
"Includes the ability to give access to events and data oneself does not have "
|
||||
"access to."
|
||||
msgstr ""
|
||||
"自らがアクセスできないイベントやデータへのアクセス権を付与する機能が含まれま"
|
||||
"す。"
|
||||
|
||||
#: pretix/base/permissions.py:321
|
||||
#, fuzzy
|
||||
#| msgid "Seating plan"
|
||||
msgid "Seating plans"
|
||||
msgstr "座席表"
|
||||
msgstr "座席プラン"
|
||||
|
||||
#: pretix/base/permissions.py:327 pretix/control/navigation.py:712
|
||||
#: pretix/control/templates/pretixcontrol/organizers/outgoing_mails.html:8
|
||||
@@ -9043,12 +9010,12 @@ msgid "Czech National Bank"
|
||||
msgstr "チェコ国立銀行"
|
||||
|
||||
#: pretix/base/services/export.py:94 pretix/base/services/export.py:154
|
||||
#, fuzzy
|
||||
#| msgid "You do not have sufficient permission to perform this export."
|
||||
msgid ""
|
||||
"Export not found or you do not have sufficient permission to perform this "
|
||||
"export."
|
||||
msgstr "このエクスポートを実行するための十分な権限がありません。"
|
||||
msgstr ""
|
||||
"エクスポートが見つからないか、エクスポートを実行するための十分な権限がありま"
|
||||
"せん。"
|
||||
|
||||
#: pretix/base/services/export.py:107 pretix/base/services/export.py:179
|
||||
#: pretix/base/services/export.py:357
|
||||
@@ -13334,25 +13301,7 @@ msgid "Contact"
|
||||
msgstr "連絡先"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/shred_completed.txt:2
|
||||
#, fuzzy, python-format
|
||||
#| msgid ""
|
||||
#| "Hello,\n"
|
||||
#| "\n"
|
||||
#| "we hereby confirm that the following data shredding job has been "
|
||||
#| "completed:\n"
|
||||
#| "\n"
|
||||
#| "Organizer: %(organizer)s\n"
|
||||
#| "\n"
|
||||
#| "Event: %(event)s\n"
|
||||
#| "\n"
|
||||
#| "Data selection: %(shredders)s\n"
|
||||
#| "\n"
|
||||
#| "Start time: %(start_time)s (new data added after this time might not have "
|
||||
#| "been deleted)\n"
|
||||
#| "\n"
|
||||
#| "Best regards,\n"
|
||||
#| "\n"
|
||||
#| "Your pretix team\n"
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Hello,\n"
|
||||
"\n"
|
||||
@@ -13386,7 +13335,7 @@ msgstr ""
|
||||
"\n"
|
||||
"敬具\n"
|
||||
"\n"
|
||||
"担当 pretix チーム\n"
|
||||
"担当 %(instance)sチーム\n"
|
||||
|
||||
#: pretix/base/templates/pretixbase/forms/widgets/checkbox_sales_channel_option.html:16
|
||||
msgid ""
|
||||
@@ -13940,16 +13889,12 @@ msgid "This is an event series"
|
||||
msgstr "これはイベントシリーズです"
|
||||
|
||||
#: pretix/control/forms/event.py:135 pretix/control/forms/event.py:363
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "You do not have sufficient permission to enable plugins that need to be "
|
||||
#| "enabled for the entire organizer account."
|
||||
msgid ""
|
||||
"You do not have a sufficient level of access on the event you selected to "
|
||||
"copy it to the desired organizer."
|
||||
msgstr ""
|
||||
"主催者アカウント全体で有効化する必要があるプラグインを有効にするのに十分な権"
|
||||
"限がありません。"
|
||||
"選択したイベントに対して、目的の主催者にコピーするための十分なアクセス権があ"
|
||||
"りません。"
|
||||
|
||||
#: pretix/control/forms/event.py:143
|
||||
msgid ""
|
||||
@@ -14028,6 +13973,8 @@ msgid ""
|
||||
"You cannot choose a team that would give you more access than you have on "
|
||||
"the event you are copying."
|
||||
msgstr ""
|
||||
"コピーしているイベントに対して、より多くのアクセス権が付与されるチームを選択"
|
||||
"することはできません。"
|
||||
|
||||
#: pretix/control/forms/event.py:344
|
||||
msgid "Copy configuration from"
|
||||
@@ -14043,6 +13990,8 @@ msgid ""
|
||||
"You cannot choose an event on which you have less access than the team you "
|
||||
"selected in the previous step."
|
||||
msgstr ""
|
||||
"前のステップで選択したチームよりもアクセス権が少ないイベントを選択することは"
|
||||
"できません。"
|
||||
|
||||
#: pretix/control/forms/event.py:387 pretix/control/forms/item.py:1304
|
||||
#: pretix/control/forms/subevents.py:411
|
||||
@@ -14992,7 +14941,7 @@ msgstr "すべての参加者"
|
||||
#: pretix/plugins/checkinlists/exporters.py:109
|
||||
#: pretix/plugins/checkinlists/exporters.py:501
|
||||
msgid "Checked in"
|
||||
msgstr "チェックインしました"
|
||||
msgstr "チェックイン済み"
|
||||
|
||||
#: pretix/control/forms/filter.py:2043
|
||||
#: pretix/plugins/checkinlists/exporters.py:110
|
||||
@@ -15010,7 +14959,7 @@ msgstr "チェックインしたが退出済み"
|
||||
#: pretix/control/templates/pretixcontrol/checkin/index.html:178
|
||||
#: pretix/plugins/checkinlists/exporters.py:112
|
||||
msgid "Not checked in"
|
||||
msgstr "未チェックイン"
|
||||
msgstr "チェックイン未了"
|
||||
|
||||
#: pretix/control/forms/filter.py:2064
|
||||
msgctxt "subevent"
|
||||
@@ -16347,7 +16296,7 @@ msgstr "1つの組織ドメインのみを設定できます。"
|
||||
|
||||
#: pretix/control/forms/organizer.py:322
|
||||
msgid "Provided by a plugin"
|
||||
msgstr ""
|
||||
msgstr "プラグインによって提供"
|
||||
|
||||
#: pretix/control/forms/organizer.py:438
|
||||
msgid ""
|
||||
@@ -17216,10 +17165,8 @@ msgid "The order has been denied (comment: \"{comment}\")."
|
||||
msgstr "注文は拒否されました(コメント:\"{comment}\")。"
|
||||
|
||||
#: pretix/control/logdisplay.py:521
|
||||
#, fuzzy
|
||||
#| msgid "The order has been overpaid."
|
||||
msgid "The customer VAT ID has been verified."
|
||||
msgstr "注文が過払いされました。"
|
||||
msgstr "顧客のVAT IDが確認されました。"
|
||||
|
||||
#: pretix/control/logdisplay.py:522
|
||||
#, python-brace-format
|
||||
@@ -17498,10 +17445,9 @@ msgid "{user} has been invited to the team."
|
||||
msgstr "{user} がチームに招待されました。"
|
||||
|
||||
#: pretix/control/logdisplay.py:644
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "Invite for {user} has been resent."
|
||||
#, python-brace-format
|
||||
msgid "Invite for {user} has been deleted."
|
||||
msgstr "{user}への招待状が再送されました。"
|
||||
msgstr "{user}への招待が削除されました。"
|
||||
|
||||
#: pretix/control/logdisplay.py:645
|
||||
#, python-brace-format
|
||||
@@ -19779,21 +19725,7 @@ msgid "Add property"
|
||||
msgstr "プロパティを追加"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email/confirmation_code.txt:1
|
||||
#, fuzzy, python-format
|
||||
#| msgid ""
|
||||
#| "Hello,\n"
|
||||
#| "\n"
|
||||
#| "%(reason)s\n"
|
||||
#| "\n"
|
||||
#| " %(code)s\n"
|
||||
#| "\n"
|
||||
#| "Please do never give this code to another person. Our support team will "
|
||||
#| "never ask for this code.\n"
|
||||
#| "\n"
|
||||
#| "If this code was not requested by you, please contact us immediately.\n"
|
||||
#| "\n"
|
||||
#| "Best regards,\n"
|
||||
#| "Your pretix team\n"
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Hello,\n"
|
||||
"\n"
|
||||
@@ -19821,7 +19753,7 @@ msgstr ""
|
||||
"このコードにお心当たりがない場合は、直ちにご連絡ください。\n"
|
||||
"\n"
|
||||
"よろしくお願いいたします。\n"
|
||||
"pretixチーム\n"
|
||||
"%(instance)sチーム\n"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email/email_setup.txt:1
|
||||
#, python-format
|
||||
@@ -19859,17 +19791,7 @@ msgstr ""
|
||||
"%(instance)s チーム\n"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email/forgot.txt:1
|
||||
#, fuzzy, python-format
|
||||
#| msgid ""
|
||||
#| "Hello,\n"
|
||||
#| "\n"
|
||||
#| "you requested a new password. Please go to the following page to reset "
|
||||
#| "your password:\n"
|
||||
#| "\n"
|
||||
#| "%(url)s\n"
|
||||
#| "\n"
|
||||
#| "Best regards, \n"
|
||||
#| "Your pretix team\n"
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Hello,\n"
|
||||
"\n"
|
||||
@@ -19889,27 +19811,10 @@ msgstr ""
|
||||
"%(url)s\n"
|
||||
"\n"
|
||||
"よろしくお願いします、 \n"
|
||||
"あなたのpretixチーム\n"
|
||||
"あなたの%(instance)sチーム\n"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email/invitation.txt:1
|
||||
#, fuzzy, python-format
|
||||
#| msgid ""
|
||||
#| "Hello,\n"
|
||||
#| "\n"
|
||||
#| "you have been invited to a team on pretix, a platform to perform event\n"
|
||||
#| "ticket sales.\n"
|
||||
#| "\n"
|
||||
#| "Organizer: %(organizer)s\n"
|
||||
#| "Team: %(team)s\n"
|
||||
#| "\n"
|
||||
#| "If you want to join that team, just click on the following link:\n"
|
||||
#| "%(url)s\n"
|
||||
#| "\n"
|
||||
#| "If you do not want to join, you can safely ignore or delete this email.\n"
|
||||
#| "\n"
|
||||
#| "Best regards, \n"
|
||||
#| "\n"
|
||||
#| "Your pretix team\n"
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Hello,\n"
|
||||
"\n"
|
||||
@@ -19931,7 +19836,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"こんにちは、\n"
|
||||
"\n"
|
||||
"あなたは、pretixというイベントチケット販売プラットフォームの\n"
|
||||
"あなたは、%(instance)sというイベントチケット販売プラットフォームの\n"
|
||||
"チームに招待されました。\n"
|
||||
"\n"
|
||||
"主催者: %(organizer)s\n"
|
||||
@@ -19944,7 +19849,7 @@ msgstr ""
|
||||
"\n"
|
||||
"よろしくお願いします。\n"
|
||||
"\n"
|
||||
"pretixチーム\n"
|
||||
"%(instance)sチーム\n"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email/login_notice.txt:1
|
||||
#, python-format
|
||||
@@ -19981,24 +19886,7 @@ msgstr ""
|
||||
"%(instance)sチーム\n"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email/security_notice.txt:1
|
||||
#, fuzzy, python-format
|
||||
#| msgid ""
|
||||
#| "Hello,\n"
|
||||
#| "\n"
|
||||
#| "this is to inform you that the account information of your pretix account "
|
||||
#| "has been\n"
|
||||
#| "changed. In particular, the following changes have been performed:\n"
|
||||
#| "\n"
|
||||
#| "%(messages)s\n"
|
||||
#| "\n"
|
||||
#| "If this change was not performed by you, please contact us immediately.\n"
|
||||
#| "\n"
|
||||
#| "You can review and change your account settings here:\n"
|
||||
#| "\n"
|
||||
#| "%(url)s\n"
|
||||
#| "\n"
|
||||
#| "Best regards, \n"
|
||||
#| "Your pretix team\n"
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Hello,\n"
|
||||
"\n"
|
||||
@@ -20019,20 +19907,21 @@ msgid ""
|
||||
msgstr ""
|
||||
"こんにちは\n"
|
||||
"\n"
|
||||
"お客様のpretixアカウントの情報が変更されましたので、お知らせいたします。\n"
|
||||
"あなたの%(instance)sのアカウント情報が変更されましたので、お知らせいたします"
|
||||
"。\n"
|
||||
"具体的には、以下の変更が行われました:\n"
|
||||
"\n"
|
||||
"%(messages)s\n"
|
||||
"\n"
|
||||
"もしもこの変更がお客様自身によるものでない場合は、直ちにお問い合わせくださ"
|
||||
"い。\n"
|
||||
"もしもこの変更がお客様自身によるものでない場合は、直ちにお問い合わせください"
|
||||
"。\n"
|
||||
"\n"
|
||||
"アカウント設定の確認や変更はこちらから行えます:\n"
|
||||
"\n"
|
||||
"%(url)s\n"
|
||||
"\n"
|
||||
"以上、よろしくお願いいたします。 \n"
|
||||
"pretixチームより\n"
|
||||
"%(instance)sチームより\n"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/email_setup.html:8
|
||||
#: pretix/control/templates/pretixcontrol/email_setup_simple.html:8
|
||||
@@ -20287,10 +20176,8 @@ msgstr ""
|
||||
"ルと払い戻しを行うことができます。"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/dangerzone.html:51
|
||||
#, fuzzy
|
||||
#| msgid "Permissions"
|
||||
msgid "No permission"
|
||||
msgstr "権限"
|
||||
msgstr "権限なし"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/dangerzone.html:59
|
||||
#: pretix/control/templates/pretixcontrol/event/dangerzone.html:72
|
||||
@@ -22768,10 +22655,8 @@ msgid "Edit question"
|
||||
msgstr "質問を編集"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/question.html:55
|
||||
#, fuzzy
|
||||
#| msgid "You do not have permission to view this content."
|
||||
msgid "No permission to view answers."
|
||||
msgstr "このコンテンツを表示する権限がありません。"
|
||||
msgstr "回答を閲覧する権限がありません。"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/items/question.html:63
|
||||
msgid "No matching answers found."
|
||||
@@ -24382,10 +24267,8 @@ msgstr "次の実行は予定されていない"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:37
|
||||
#: pretix/control/templates/pretixcontrol/organizers/export.html:37
|
||||
#, fuzzy
|
||||
#| msgid "Exporter not found"
|
||||
msgid "Exporter not found or no permission"
|
||||
msgstr "エクスポーターが見つかりません"
|
||||
msgstr "エクスポーターが見つからない、または権限がありません"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:42
|
||||
#: pretix/control/templates/pretixcontrol/organizers/export.html:42
|
||||
@@ -24428,10 +24311,8 @@ msgstr "新規ユーザー向けのおすすめです"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:120
|
||||
#: pretix/control/templates/pretixcontrol/organizers/export.html:120
|
||||
#, fuzzy
|
||||
#| msgid "There are no add-ons available for this product."
|
||||
msgid "There are no exporters available for you."
|
||||
msgstr "この製品に利用可能なアドオンはありません。"
|
||||
msgstr "ご利用いただけるエクスポーターがありません。"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/orders/export_delete.html:6
|
||||
@@ -26329,7 +26210,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/pdf/index.html:274
|
||||
#, python-format
|
||||
msgid "max. %(size)s, smaller is better"
|
||||
msgstr ""
|
||||
msgstr "最大%(size)sで、より少ない数値が望ましい"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/pdf/index.html:282
|
||||
msgid "Download current background"
|
||||
@@ -29023,16 +28904,12 @@ msgstr ""
|
||||
"い。"
|
||||
|
||||
#: pretix/control/views/orders.py:2798 pretix/control/views/organizer.py:2131
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Your user account does not have sufficient permission to run this report, "
|
||||
#| "therefore you cannot schedule it."
|
||||
msgid ""
|
||||
"Your user account does not have sufficient permission to run this report, "
|
||||
"therefore you cannot change it."
|
||||
msgstr ""
|
||||
"ユーザーアカウントにはこのレポートを実行するのに十分な権限がないため、スケ"
|
||||
"ジュールを設定できません。"
|
||||
"あなたのユーザーアカウントにはこのレポートを実行する十分な権限がありませんの"
|
||||
"で、変更することはできません。"
|
||||
|
||||
#: pretix/control/views/orders.py:2807 pretix/control/views/organizer.py:2140
|
||||
msgid ""
|
||||
@@ -32995,7 +32872,7 @@ msgstr "Stripe経由でiDEAL"
|
||||
|
||||
#: pretix/plugins/stripe/payment.py:1572
|
||||
msgid "iDEAL | Wero"
|
||||
msgstr ""
|
||||
msgstr "iDEAL | Wero"
|
||||
|
||||
#: pretix/plugins/stripe/payment.py:1575
|
||||
msgid ""
|
||||
@@ -35905,6 +35782,8 @@ msgid ""
|
||||
"the shop that affect quotas, such as the validity period of carts and "
|
||||
"vouchers."
|
||||
msgstr ""
|
||||
"変更された時間は、カートやバウチャーの有効期間など、クォータに影響を与える"
|
||||
"ショップの項目については考慮されませんので、ご了承ください。"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/timemachine.html:31
|
||||
msgid "Enable time machine"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:06+0000\n"
|
||||
"PO-Revision-Date: 2026-02-23 10:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-23 21:00+0000\n"
|
||||
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
|
||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/ja/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 5.16\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -60,7 +60,7 @@ msgstr "PayPal後払い"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
|
||||
msgid "iDEAL | Wero"
|
||||
msgstr ""
|
||||
msgstr "iDEAL | Wero"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
||||
msgid "SEPA Direct Debit"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:05+0000\n"
|
||||
"PO-Revision-Date: 2026-03-18 23:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-25 12:41+0000\n"
|
||||
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
|
||||
"Language-Team: Dutch (Belgium) <https://translate.pretix.eu/projects/pretix/"
|
||||
"pretix/nl_BE/>\n"
|
||||
@@ -29442,163 +29442,177 @@ msgid ""
|
||||
"The order has been canceled. You can now select how you want to transfer the "
|
||||
"money back to the user."
|
||||
msgstr ""
|
||||
"De bestelling is geannuleerd. U kunt nu kiezen hoe u het geld wilt overmaken "
|
||||
"naar de gebruiker."
|
||||
|
||||
#: pretix/control/views/orders.py:1627 pretix/control/views/orders.py:1631
|
||||
msgid "No VAT ID specified."
|
||||
msgstr ""
|
||||
msgstr "Geen btw-nummer opgegeven."
|
||||
|
||||
#: pretix/control/views/orders.py:1635
|
||||
msgid "No country specified."
|
||||
msgstr ""
|
||||
msgstr "Geen land opgegeven."
|
||||
|
||||
#: pretix/control/views/orders.py:1639
|
||||
msgid "VAT ID could not be checked since this country is not supported."
|
||||
msgstr ""
|
||||
"Btw-nummer kon niet gecontroleerd worden, omdat dit land niet ondersteund "
|
||||
"wordt."
|
||||
|
||||
#: pretix/control/views/orders.py:1658
|
||||
msgid ""
|
||||
"The VAT ID could not be checked, as the VAT checking service of the country "
|
||||
"is currently not available."
|
||||
msgstr ""
|
||||
"Uw btw-nummer kon niet gecontroleerd worden, omdat de btw-controledienst van "
|
||||
"uw land momenteel niet beschikbaar is."
|
||||
|
||||
#: pretix/control/views/orders.py:1661
|
||||
msgid "This VAT ID is valid."
|
||||
msgstr ""
|
||||
msgstr "Dit btw-nummer is geldig."
|
||||
|
||||
#: pretix/control/views/orders.py:1675 pretix/control/views/orders.py:1709
|
||||
#: pretix/control/views/orders.py:1741
|
||||
msgid "Unknown invoice."
|
||||
msgstr ""
|
||||
msgstr "Onbekende factuur."
|
||||
|
||||
#: pretix/control/views/orders.py:1678
|
||||
msgid "Invoices may not be changed after they are created."
|
||||
msgstr ""
|
||||
msgstr "Facturen kunnen niet gewijzigd worden nadat ze zijn aangemaakt."
|
||||
|
||||
#: pretix/control/views/orders.py:1680
|
||||
msgid "Invoices may not be changed after they are transmitted."
|
||||
msgstr ""
|
||||
msgstr "Facturen kunnen niet gewijzigd worden nadat ze verstuurd zijn."
|
||||
|
||||
#: pretix/control/views/orders.py:1682 pretix/control/views/orders.py:1744
|
||||
msgid "The invoice has already been canceled."
|
||||
msgstr ""
|
||||
msgstr "De factuur is al geannuleerd."
|
||||
|
||||
#: pretix/control/views/orders.py:1684
|
||||
msgid "The invoice file has already been exported."
|
||||
msgstr ""
|
||||
msgstr "Het factuurbestand is al geëxporteerd."
|
||||
|
||||
#: pretix/control/views/orders.py:1686
|
||||
msgid "The invoice file is too old to be regenerated."
|
||||
msgstr ""
|
||||
msgstr "Het factuurbestand is te oud om opnieuw te worden gegenereerd."
|
||||
|
||||
#: pretix/control/views/orders.py:1688 pretix/control/views/orders.py:1746
|
||||
msgid "The invoice has been cleaned of personal data."
|
||||
msgstr ""
|
||||
msgstr "Persoonlijke gegevens zijn uit de factuur verwijderd."
|
||||
|
||||
#: pretix/control/views/orders.py:1713
|
||||
msgid ""
|
||||
"The invoice is currently being transmitted. You can start a new attempt "
|
||||
"after the current one has been completed."
|
||||
msgstr ""
|
||||
"De factuur wordt momenteel verzonden. U kunt een nieuwe poging doen nadat de "
|
||||
"huidige voltooid is."
|
||||
|
||||
#: pretix/control/views/orders.py:1720
|
||||
msgid "The invoice has been scheduled for retransmission."
|
||||
msgstr ""
|
||||
msgstr "De factuur is ingepland voor herverzending."
|
||||
|
||||
#: pretix/control/views/orders.py:1754
|
||||
msgid "The invoice has been canceled."
|
||||
msgstr ""
|
||||
msgstr "De factuur is geannuleerd."
|
||||
|
||||
#: pretix/control/views/orders.py:1793
|
||||
msgid "The email has been queued to be sent."
|
||||
msgstr ""
|
||||
msgstr "De e-mail is opgeslagen om te worden verzonden."
|
||||
|
||||
#: pretix/control/views/orders.py:1817 pretix/presale/views/order.py:1369
|
||||
msgid "This invoice has not been found"
|
||||
msgstr ""
|
||||
msgstr "Deze factuur is niet gevonden"
|
||||
|
||||
#: pretix/control/views/orders.py:1824 pretix/presale/views/order.py:1376
|
||||
msgid "The invoice file is no longer stored on the server."
|
||||
msgstr ""
|
||||
msgstr "Het factuurbestand is niet meer opgeslagen op de server."
|
||||
|
||||
#: pretix/control/views/orders.py:1829 pretix/presale/views/order.py:1381
|
||||
msgid ""
|
||||
"The invoice file has not yet been generated, we will generate it for you "
|
||||
"now. Please try again in a few seconds."
|
||||
msgstr ""
|
||||
"Het factuurbestand is nog niet gegenereerd, we zullen het nu voor u "
|
||||
"genereren. Probeer het over een paar seconden opnieuw."
|
||||
|
||||
#: pretix/control/views/orders.py:1857
|
||||
msgid "The payment term has been changed."
|
||||
msgstr ""
|
||||
msgstr "De betalingstermijn is gewijzigd."
|
||||
|
||||
#: pretix/control/views/orders.py:1862 pretix/control/views/orders.py:1919
|
||||
msgid ""
|
||||
"We were not able to process the request completely as the server was too "
|
||||
"busy."
|
||||
msgstr ""
|
||||
msgstr "We konden uw verzoek niet verwerken, omdat de server het te druk heeft."
|
||||
|
||||
#: pretix/control/views/orders.py:1870
|
||||
msgid "This action is only allowed for pending orders."
|
||||
msgstr ""
|
||||
msgstr "Deze actie is alleen toegestaan voor openstaande bestellingen."
|
||||
|
||||
#: pretix/control/views/orders.py:1925
|
||||
msgid "This action is only allowed for canceled orders."
|
||||
msgstr ""
|
||||
msgstr "Deze actie is alleen toegestaan voor geannuleerde bestellingen."
|
||||
|
||||
#: pretix/control/views/orders.py:2183 pretix/presale/views/order.py:1664
|
||||
msgid "An error occurred. Please see the details below."
|
||||
msgstr ""
|
||||
msgstr "Er is een fout opgetreden. Zie de details hieronder."
|
||||
|
||||
#: pretix/control/views/orders.py:2191
|
||||
msgid "The order has been changed and the user has been notified."
|
||||
msgstr ""
|
||||
msgstr "De bestelling is gewijzigd en de gebruiker is op de hoogte gesteld."
|
||||
|
||||
#: pretix/control/views/orders.py:2193 pretix/control/views/orders.py:2329
|
||||
#: pretix/control/views/orders.py:2366 pretix/presale/views/order.py:1700
|
||||
msgid "The order has been changed."
|
||||
msgstr ""
|
||||
msgstr "De bestelling is gewijzigd."
|
||||
|
||||
#: pretix/control/views/orders.py:2220 pretix/presale/checkoutflow.py:943
|
||||
#: pretix/presale/views/order.py:845 pretix/presale/views/order.py:981
|
||||
msgid ""
|
||||
"We had difficulties processing your input. Please review the errors below."
|
||||
msgstr ""
|
||||
"We hadden problemen met het verwerken van uw invoer. Zie de fouten hieronder."
|
||||
|
||||
#: pretix/control/views/orders.py:2331
|
||||
msgid "Nothing about the order had to be changed."
|
||||
msgstr ""
|
||||
msgstr "Er is geen wijziging aangebracht aan de bestelling."
|
||||
|
||||
#: pretix/control/views/orders.py:2412 pretix/plugins/sendmail/views.py:176
|
||||
msgid "We could not send the email. See below for details."
|
||||
msgstr ""
|
||||
msgstr "We konden de e-mail niet versturen. Zie onder voor details."
|
||||
|
||||
#: pretix/control/views/orders.py:2428 pretix/control/views/orders.py:2492
|
||||
#: pretix/plugins/sendmail/views.py:204 pretix/plugins/sendmail/views.py:671
|
||||
#, python-brace-format
|
||||
msgid "Subject: {subject}"
|
||||
msgstr ""
|
||||
msgstr "Onderwerp: {subject}"
|
||||
|
||||
#: pretix/control/views/orders.py:2446 pretix/control/views/orders.py:2511
|
||||
#, python-brace-format
|
||||
msgid "Your message has been queued and will be sent to {}."
|
||||
msgstr ""
|
||||
msgstr "Uw bericht is in de wachtrij gezet en zal verstuurd worden naar {}."
|
||||
|
||||
#: pretix/control/views/orders.py:2564 pretix/presale/views/order.py:1151
|
||||
msgid ""
|
||||
"This link is no longer valid. Please go back, refresh the page, and try "
|
||||
"again."
|
||||
msgstr ""
|
||||
"Deze link is niet meer geldig. Ga terug, ververs de pagina, en probeer het "
|
||||
"opnieuw."
|
||||
|
||||
#: pretix/control/views/orders.py:2645
|
||||
msgid "There is no order with the given order code."
|
||||
msgstr ""
|
||||
msgstr "Er is geen bestelling met de gegeven bestelcode."
|
||||
|
||||
#: pretix/control/views/orders.py:2751 pretix/control/views/organizer.py:2085
|
||||
msgid "The selected exporter was not found."
|
||||
msgstr ""
|
||||
msgstr "Het geselecteerde exportformaat is niet gevonden."
|
||||
|
||||
#: pretix/control/views/orders.py:2761 pretix/control/views/organizer.py:2095
|
||||
msgid "There was a problem processing your input. See below for error details."
|
||||
msgstr ""
|
||||
"Er was een probleem met het verwerken van uw invoer. Zie onder voor details."
|
||||
|
||||
#: pretix/control/views/orders.py:2798 pretix/control/views/organizer.py:2131
|
||||
msgid ""
|
||||
@@ -29613,6 +29627,8 @@ msgid ""
|
||||
"Your user account does not have sufficient permission to run this report, "
|
||||
"therefore you cannot schedule it."
|
||||
msgstr ""
|
||||
"Uw gebruikersaccount heeft onvoldoende rechten om dit rapport uit te voeren. "
|
||||
"Daarom kunt u het niet plannen."
|
||||
|
||||
#: pretix/control/views/orders.py:2823 pretix/control/views/organizer.py:2156
|
||||
#, python-brace-format
|
||||
@@ -29620,15 +29636,17 @@ msgid ""
|
||||
"Your export schedule has been saved. The next export will start around "
|
||||
"{datetime}."
|
||||
msgstr ""
|
||||
"De geplande export is opgeslagen. De volgende export begint omstreeks "
|
||||
"{datetime}."
|
||||
|
||||
#: pretix/control/views/orders.py:2828 pretix/control/views/organizer.py:2161
|
||||
msgid "Your export schedule has been saved, but no next export is planned."
|
||||
msgstr ""
|
||||
msgstr "De geplande export is opgeslagen, maar er is geen volgende run gepland."
|
||||
|
||||
#: pretix/control/views/orders.py:2873 pretix/control/views/organizer.py:2207
|
||||
#, python-brace-format
|
||||
msgid "Export: {title}"
|
||||
msgstr ""
|
||||
msgstr "Export: {title}"
|
||||
|
||||
#: pretix/control/views/orders.py:2874 pretix/control/views/organizer.py:2209
|
||||
#, python-brace-format
|
||||
@@ -29637,6 +29655,9 @@ msgid ""
|
||||
"\n"
|
||||
"attached to this email, you can find a new scheduled report for {name}."
|
||||
msgstr ""
|
||||
"Hallo,\n"
|
||||
"\n"
|
||||
"Als bijlage bij deze e-mail vindt u een nieuw gepland rapport voor {name}."
|
||||
|
||||
#: pretix/control/views/orders.py:2980 pretix/control/views/organizer.py:2343
|
||||
msgid ""
|
||||
@@ -29644,10 +29665,13 @@ msgid ""
|
||||
"Depending on system load and type and size of export, this may take a few "
|
||||
"minutes."
|
||||
msgstr ""
|
||||
"We hebben de export gepland. Het resultaat wordt per e-mail verzonden. "
|
||||
"Afhankelijk van de systeembelasting, het type en de grootte van de export "
|
||||
"kan dit enkele minuten duren."
|
||||
|
||||
#: pretix/control/views/orders.py:3067 pretix/control/views/orders.py:3148
|
||||
msgid "All orders have been canceled."
|
||||
msgstr ""
|
||||
msgstr "Alle bestellingen zijn geannuleerd."
|
||||
|
||||
#: pretix/control/views/orders.py:3069 pretix/control/views/orders.py:3150
|
||||
#, python-brace-format
|
||||
@@ -29655,28 +29679,32 @@ msgid ""
|
||||
"The orders have been canceled. An error occurred with {count} orders, please "
|
||||
"check all uncanceled orders."
|
||||
msgstr ""
|
||||
"De bestellingen zijn geannuleerd. Bij {count} bestellingen is er een fout "
|
||||
"opgetreden, controleer alstublieft alle nog niet geannuleerde bestellingen."
|
||||
|
||||
#: pretix/control/views/orders.py:3097 pretix/control/views/orders.py:3171
|
||||
msgid "Your input was not valid."
|
||||
msgstr ""
|
||||
msgstr "Uw invoer was ongeldig."
|
||||
|
||||
#: pretix/control/views/organizer.py:178
|
||||
msgid "Token name"
|
||||
msgstr ""
|
||||
msgstr "Tokennaam"
|
||||
|
||||
#: pretix/control/views/organizer.py:408
|
||||
msgid "This organizer can not be deleted."
|
||||
msgstr ""
|
||||
msgstr "Deze organisator kan niet verwijderd worden."
|
||||
|
||||
#: pretix/control/views/organizer.py:431
|
||||
msgid "The organizer has been deleted."
|
||||
msgstr ""
|
||||
msgstr "De organisator is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:435
|
||||
msgid ""
|
||||
"The organizer could not be deleted as some constraints (e.g. data created by "
|
||||
"plug-ins) do not allow it."
|
||||
msgstr ""
|
||||
"De organisator kon niet verwijderd worden, omdat sommige beperkingen (bijv. "
|
||||
"data aangemaakt door plug-ins) het niet toestaan."
|
||||
|
||||
#: pretix/control/views/organizer.py:445
|
||||
#, python-brace-format
|
||||
@@ -29684,30 +29712,33 @@ msgid ""
|
||||
"The following database models still contain data that cannot be deleted "
|
||||
"automatically: {affected_models}"
|
||||
msgstr ""
|
||||
"De volgende databasemodellen bevatten nog steeds gegevens die niet "
|
||||
"automatisch verwijderd kunnen worden: {affected_models}"
|
||||
|
||||
#: pretix/control/views/organizer.py:585
|
||||
msgid "The new organizer has been created."
|
||||
msgstr ""
|
||||
msgstr "De nieuwe organisator is aangemaakt."
|
||||
|
||||
#: pretix/control/views/organizer.py:588
|
||||
msgid "Administrators"
|
||||
msgstr ""
|
||||
msgstr "Beheerders"
|
||||
|
||||
#: pretix/control/views/organizer.py:806
|
||||
msgid "Unknown plugin."
|
||||
msgstr ""
|
||||
msgstr "Onbekende plug-in."
|
||||
|
||||
#: pretix/control/views/organizer.py:812
|
||||
msgid "This plugin is currently not active on the organizer account."
|
||||
msgstr ""
|
||||
"Deze plug-in is momenteel niet actief op het account van de organisator."
|
||||
|
||||
#: pretix/control/views/organizer.py:816
|
||||
msgid "This plugin is currently not allowed for this organizer account."
|
||||
msgstr ""
|
||||
msgstr "Deze plug-in is momenteel niet toegestaan voor dit organisatoraccount."
|
||||
|
||||
#: pretix/control/views/organizer.py:905
|
||||
msgid "The team has been created. You can now add members to the team."
|
||||
msgstr ""
|
||||
msgstr "Het team is aangemaakt. U kunt nu leden aan het team toevoegen."
|
||||
|
||||
#: pretix/control/views/organizer.py:913 pretix/control/views/organizer.py:946
|
||||
#: pretix/control/views/organizer.py:1182
|
||||
@@ -29728,70 +29759,78 @@ msgstr ""
|
||||
#: pretix/control/views/organizer.py:3568
|
||||
#: pretix/control/views/organizer.py:3612
|
||||
msgid "Your changes could not be saved."
|
||||
msgstr ""
|
||||
msgstr "Uw wijzigingen konden niet worden opgeslagen."
|
||||
|
||||
#: pretix/control/views/organizer.py:980
|
||||
msgid "The selected team cannot be deleted."
|
||||
msgstr ""
|
||||
msgstr "Het gekozen team kan niet verwijderd worden."
|
||||
|
||||
#: pretix/control/views/organizer.py:992
|
||||
msgid ""
|
||||
"The team could not be deleted because the team or one of its API tokens is "
|
||||
"part of historical audit logs."
|
||||
msgstr ""
|
||||
"Dit team kan niet verwijderd worden, omdat een van de bijbehorende API-"
|
||||
"tokens deel uitmaakt van de systeemlogboeken."
|
||||
|
||||
#: pretix/control/views/organizer.py:1000
|
||||
msgid ""
|
||||
"The team could not be deleted as some constraints (e.g. data created by plug-"
|
||||
"ins) do not allow it."
|
||||
msgstr ""
|
||||
"Het team kon niet verwijderd worden, omdat sommige beperkingen (bijv. data "
|
||||
"aangemaakt door plug-ins) het niet toestaan."
|
||||
|
||||
#: pretix/control/views/organizer.py:1006
|
||||
msgid "The selected team has been deleted."
|
||||
msgstr ""
|
||||
msgstr "Het geselecteerde team is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1069
|
||||
msgid ""
|
||||
"You cannot remove the last member from this team as no one would be left "
|
||||
"with the permission to change teams."
|
||||
msgstr ""
|
||||
"U kunt het laatste lid niet uit dit team verwijderen, omdat er niemand meer "
|
||||
"zou zijn met de machtiging om teams te beheren."
|
||||
|
||||
#: pretix/control/views/organizer.py:1080
|
||||
msgid "The member has been removed from the team."
|
||||
msgstr ""
|
||||
msgstr "Het lid is verwijderd uit het team."
|
||||
|
||||
#: pretix/control/views/organizer.py:1087
|
||||
#: pretix/control/views/organizer.py:1103
|
||||
msgid "Invalid invite selected."
|
||||
msgstr ""
|
||||
msgstr "Ongeldige uitnodiging geselecteerd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1096
|
||||
msgid "The invite has been revoked."
|
||||
msgstr ""
|
||||
msgstr "De uitnodiging is ingetrokken."
|
||||
|
||||
#: pretix/control/views/organizer.py:1112
|
||||
msgid "The invite has been resent."
|
||||
msgstr ""
|
||||
msgstr "De uitnodiging is opnieuw verstuurd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1119
|
||||
msgid "Invalid token selected."
|
||||
msgstr ""
|
||||
msgstr "Ongeldig token geselecteerd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1129
|
||||
msgid "The token has been revoked."
|
||||
msgstr ""
|
||||
msgstr "Het token is ingetrokken."
|
||||
|
||||
#: pretix/control/views/organizer.py:1141
|
||||
msgid "Users need to have a pretix account before they can be invited."
|
||||
msgstr ""
|
||||
"Gebruikers moeten een pretix-account hebben voordat ze uitgenodigd kunnen "
|
||||
"worden."
|
||||
|
||||
#: pretix/control/views/organizer.py:1151
|
||||
msgid "The new member has been invited to the team."
|
||||
msgstr ""
|
||||
msgstr "Het nieuwe lid is uitgenodigd voor het team."
|
||||
|
||||
#: pretix/control/views/organizer.py:1166
|
||||
msgid "The new member has been added to the team."
|
||||
msgstr ""
|
||||
msgstr "Het nieuwe lid is toegevoegd aan het team."
|
||||
|
||||
#: pretix/control/views/organizer.py:1177
|
||||
#, python-brace-format
|
||||
@@ -29800,101 +29839,108 @@ msgid ""
|
||||
"Please copy this secret to a safe place. You will not be able to view it "
|
||||
"again here."
|
||||
msgstr ""
|
||||
"Er is een nieuw API-token aangemaakt met de volgende sleutel: {}\n"
|
||||
"Bewaar deze sleutel op een veilige plek. U kunt hem hier later niet meer "
|
||||
"opvragen."
|
||||
|
||||
#: pretix/control/views/organizer.py:1474
|
||||
msgid "This device has been set up successfully."
|
||||
msgstr ""
|
||||
msgstr "Het apparaat is succesvol geïnstalleerd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1502
|
||||
msgid "This device currently does not have access."
|
||||
msgstr ""
|
||||
msgstr "Dit apparaat heeft momenteel geen toegang."
|
||||
|
||||
#: pretix/control/views/organizer.py:1514
|
||||
msgid "Access for this device has been revoked."
|
||||
msgstr ""
|
||||
msgstr "De toegang voor dit apparaat is ingetrokken."
|
||||
|
||||
#: pretix/control/views/organizer.py:1635
|
||||
msgid ""
|
||||
"All requests will now be scheduled for an immediate attempt. Please allow "
|
||||
"for a few minutes before they are processed."
|
||||
msgstr ""
|
||||
"Alle wachtende webhooks worden nu ingepland voor een nieuwe poging "
|
||||
"binnenkort. Even geduld a.u.b. totdat de verwerking voltooid is."
|
||||
|
||||
#: pretix/control/views/organizer.py:1642
|
||||
msgid "All unprocessed webhooks have been stopped from retrying."
|
||||
msgstr ""
|
||||
msgstr "Alle onverwerkte webhooks worden niet meer uitgevoerd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1677
|
||||
msgid "The selected organizer has been invited."
|
||||
msgstr ""
|
||||
msgstr "De geselecteerde organisator is uitgenodigd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1717
|
||||
#: pretix/control/views/organizer.py:1731
|
||||
msgid "The selected connection has been removed."
|
||||
msgstr ""
|
||||
msgstr "De geselecteerde verbinding is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1745
|
||||
msgid "The selected connection has been accepted."
|
||||
msgstr ""
|
||||
msgstr "De geselecteerde verbinding is geaccepteerd."
|
||||
|
||||
#: pretix/control/views/organizer.py:1805
|
||||
#: pretix/control/views/organizer.py:1842
|
||||
msgid "Gift cards are not allowed to have negative values."
|
||||
msgstr ""
|
||||
msgstr "Cadeaubonnen kunnen geen negatieve waarde hebben."
|
||||
|
||||
#: pretix/control/views/organizer.py:1832
|
||||
msgid "The transaction could not be reversed."
|
||||
msgstr ""
|
||||
msgstr "De transactie kon niet teruggedraaid worden."
|
||||
|
||||
#: pretix/control/views/organizer.py:1834
|
||||
msgid "The transaction has been reversed."
|
||||
msgstr ""
|
||||
msgstr "De transactie is teruggedraaid."
|
||||
|
||||
#: pretix/control/views/organizer.py:1839
|
||||
msgid "Your input was invalid, please try again."
|
||||
msgstr ""
|
||||
msgstr "Uw invoer was ongeldig, probeer het opnieuw."
|
||||
|
||||
#: pretix/control/views/organizer.py:1859
|
||||
msgid "The manual transaction has been saved."
|
||||
msgstr ""
|
||||
msgstr "De handmatige transactie is opgeslagen."
|
||||
|
||||
#: pretix/control/views/organizer.py:1901
|
||||
msgid "The gift card has been created and can now be used."
|
||||
msgstr ""
|
||||
msgstr "De cadeaubon is aangemaakt en kan nu gebruikt worden."
|
||||
|
||||
#: pretix/control/views/organizer.py:2008
|
||||
msgid "All events (that I have access to)"
|
||||
msgstr ""
|
||||
msgstr "Alle evenementen (waar ik toegang toe heb)"
|
||||
|
||||
#: pretix/control/views/organizer.py:2450
|
||||
msgid "The selected gate has been deleted."
|
||||
msgstr ""
|
||||
msgstr "De geselecteerde ingang is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:2493
|
||||
msgid "You cannot set a default value that is not a valid value."
|
||||
msgstr ""
|
||||
"U kunt geen standaardwaarde instellen die niet in de lijst met toegestane "
|
||||
"waarden staat."
|
||||
|
||||
#: pretix/control/views/organizer.py:2520
|
||||
msgid "The property has been created."
|
||||
msgstr ""
|
||||
msgstr "De eigenschap is aangemaakt."
|
||||
|
||||
#: pretix/control/views/organizer.py:2587
|
||||
msgid "The selected property has been deleted."
|
||||
msgstr ""
|
||||
msgstr "De geselecteerde eigenschap is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:2611
|
||||
msgid "The order of properties has been updated."
|
||||
msgstr ""
|
||||
msgstr "De volgorde van eigenschappen is bijgewerkt."
|
||||
|
||||
#: pretix/control/views/organizer.py:2790
|
||||
#: pretix/control/views/organizer.py:2906
|
||||
#: pretix/control/views/organizer.py:3036
|
||||
#: pretix/control/views/organizer.py:3305
|
||||
msgid "The selected object has been deleted."
|
||||
msgstr ""
|
||||
msgstr "Het geselecteerde object is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:2825
|
||||
msgid "The provider has been created."
|
||||
msgstr ""
|
||||
msgstr "De provider is aangemaakt."
|
||||
|
||||
#: pretix/control/views/organizer.py:2945
|
||||
#, python-brace-format
|
||||
@@ -29902,6 +29948,8 @@ msgid ""
|
||||
"The SSO client has been created. Please note down the following client "
|
||||
"secret, it will never be shown again: {secret}"
|
||||
msgstr ""
|
||||
"De SSO-client is aangemaakt. Noteer de volgende geheime sleutel. Hij wordt "
|
||||
"nooit meer weergegeven: {secret}"
|
||||
|
||||
#: pretix/control/views/organizer.py:2995
|
||||
#, python-brace-format
|
||||
@@ -29909,30 +29957,36 @@ msgid ""
|
||||
"Your changes have been saved. Please note down the following client secret, "
|
||||
"it will never be shown again: {secret}"
|
||||
msgstr ""
|
||||
"Uw wijzigingen zijn opgeslagen. Sla de geheime sleutel veilig op, want hij "
|
||||
"zal hierna nooit meer getoond worden: {secret}"
|
||||
|
||||
#: pretix/control/views/organizer.py:3105
|
||||
msgid ""
|
||||
"We've sent the customer an email with further instructions on resetting your "
|
||||
"password."
|
||||
msgstr ""
|
||||
"We hebben de klant een e-mail gestuurd met verdere instructies om het "
|
||||
"wachtwoord te resetten."
|
||||
|
||||
#: pretix/control/views/organizer.py:3370
|
||||
msgid "The customer account has been anonymized."
|
||||
msgstr ""
|
||||
msgstr "Het klantenaccount is geanonimiseerd."
|
||||
|
||||
#: pretix/control/views/organizer.py:3640
|
||||
msgid "This channel can not be deleted."
|
||||
msgstr ""
|
||||
msgstr "Dit kanaal kan niet verwijderd worden."
|
||||
|
||||
#: pretix/control/views/organizer.py:3645
|
||||
msgid "The selected sales channel has been deleted."
|
||||
msgstr ""
|
||||
msgstr "Het geselecteerde verkoopskanaal is verwijderd."
|
||||
|
||||
#: pretix/control/views/organizer.py:3647
|
||||
msgid ""
|
||||
"The channel could not be deleted as some constraints (e.g. data created by "
|
||||
"plug-ins) did not allow it."
|
||||
msgstr ""
|
||||
"Het kanaal kon niet verwijderd worden, omdat sommige beperkingen (bijv. data "
|
||||
"aangemaakt door plug-ins) het niet toestaan."
|
||||
|
||||
#: pretix/control/views/organizer.py:3672
|
||||
msgid "The order of sales channels has been updated."
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:05+0000\n"
|
||||
"PO-Revision-Date: 2026-03-11 07:08+0000\n"
|
||||
"Last-Translator: Pedro Orlando <scramblerdoodle@gmail.com>\n"
|
||||
"PO-Revision-Date: 2026-03-25 08:00+0000\n"
|
||||
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
|
||||
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix/pt_BR/>\n"
|
||||
"Language: pt_BR\n"
|
||||
@@ -405,10 +405,8 @@ msgstr ""
|
||||
|
||||
#: pretix/api/serializers/organizer.py:482
|
||||
#: pretix/control/views/organizer.py:1039
|
||||
#, fuzzy
|
||||
#| msgid "Account information"
|
||||
msgid "Account invitation"
|
||||
msgstr "Informações da conta"
|
||||
msgstr "Convite de conta"
|
||||
|
||||
#: pretix/api/serializers/organizer.py:503
|
||||
#: pretix/control/views/organizer.py:1138
|
||||
@@ -6840,10 +6838,8 @@ msgstr ""
|
||||
"alguns minutos para entrar em vigor para todos os usuários."
|
||||
|
||||
#: pretix/base/models/organizer.py:378
|
||||
#, fuzzy
|
||||
#| msgid "Event permissions"
|
||||
msgid "All event permissions"
|
||||
msgstr "Permissões de Evento"
|
||||
msgstr "Todas as permissões de evento"
|
||||
|
||||
#: pretix/base/models/organizer.py:379
|
||||
#: pretix/control/templates/pretixcontrol/organizers/team_edit.html:34
|
||||
@@ -6851,10 +6847,8 @@ msgid "Event permissions"
|
||||
msgstr "Permissões de Evento"
|
||||
|
||||
#: pretix/base/models/organizer.py:380
|
||||
#, fuzzy
|
||||
#| msgid "Organizer permissions"
|
||||
msgid "All organizer permissions"
|
||||
msgstr "Permissões de Organizador"
|
||||
msgstr "Todas as permissões de organizador"
|
||||
|
||||
#: pretix/base/models/organizer.py:381
|
||||
#: pretix/control/templates/pretixcontrol/organizers/team_edit.html:25
|
||||
@@ -8352,22 +8346,18 @@ msgstr "Seu arquivo de layout não é um layout válido. Mensagem de erro: {}"
|
||||
#: pretix/base/permissions.py:314 pretix/base/permissions.py:331
|
||||
msgctxt "permission_level"
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
msgstr "Visualizar"
|
||||
|
||||
#: pretix/base/permissions.py:164 pretix/base/permissions.py:169
|
||||
#: pretix/base/permissions.py:174 pretix/base/permissions.py:179
|
||||
#: pretix/base/permissions.py:286 pretix/base/permissions.py:315
|
||||
#, fuzzy
|
||||
#| msgid "Save and check"
|
||||
msgctxt "permission_level"
|
||||
msgid "View and change"
|
||||
msgstr "Salvar e checar"
|
||||
msgstr "Visualizar e alterar"
|
||||
|
||||
#: pretix/base/permissions.py:168
|
||||
#, fuzzy
|
||||
#| msgid "API tokens"
|
||||
msgid "API only"
|
||||
msgstr "Tokens de API"
|
||||
msgstr "Apenas API"
|
||||
|
||||
#: pretix/base/permissions.py:173
|
||||
msgid ""
|
||||
@@ -8377,11 +8367,9 @@ msgstr ""
|
||||
#: pretix/base/permissions.py:177 pretix/base/permissions.py:231
|
||||
#: pretix/base/permissions.py:285 pretix/base/permissions.py:313
|
||||
#: pretix/base/permissions.py:330
|
||||
#, fuzzy
|
||||
#| msgid "Revoke access"
|
||||
msgctxt "permission_level"
|
||||
msgid "No access"
|
||||
msgstr "Revogar acesso"
|
||||
msgstr "Sem acesso"
|
||||
|
||||
#: pretix/base/permissions.py:188
|
||||
#: pretix/control/templates/pretixcontrol/event/settings.html:7
|
||||
@@ -8408,10 +8396,8 @@ msgid "Tax settings"
|
||||
msgstr "Configurações de impostos"
|
||||
|
||||
#: pretix/base/permissions.py:209
|
||||
#, fuzzy
|
||||
#| msgid "Invoice settings"
|
||||
msgid "Invoicing settings"
|
||||
msgstr "Configurações de fatura"
|
||||
msgstr "Configurações de faturamento"
|
||||
|
||||
#: pretix/base/permissions.py:215
|
||||
#, fuzzy
|
||||
@@ -8421,52 +8407,40 @@ msgid "Event series dates"
|
||||
msgstr "Data da série de eventos adicionada"
|
||||
|
||||
#: pretix/base/permissions.py:221
|
||||
#, fuzzy
|
||||
#| msgid "Product name and variation"
|
||||
msgid "Products, quotas and questions"
|
||||
msgstr "Nome do produto e variação"
|
||||
msgstr "Produtos, cotas e perguntas"
|
||||
|
||||
#: pretix/base/permissions.py:224
|
||||
msgid "Also includes related objects like categories or discounts."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/permissions.py:232
|
||||
#, fuzzy
|
||||
#| msgid "All check-ins"
|
||||
msgctxt "permission_level"
|
||||
msgid "Only check-in"
|
||||
msgstr "Todos os check-ins"
|
||||
msgstr "Apenas check-in"
|
||||
|
||||
#: pretix/base/permissions.py:233
|
||||
#, fuzzy
|
||||
#| msgid "View full log"
|
||||
msgctxt "permission_level"
|
||||
msgid "View all"
|
||||
msgstr "Ver log completo"
|
||||
msgstr "Visualizar tudo"
|
||||
|
||||
#: pretix/base/permissions.py:234
|
||||
#, fuzzy
|
||||
#| msgid "Valid check-in"
|
||||
msgctxt "permission_level"
|
||||
msgid "View all and check-in"
|
||||
msgstr "Check-in válido"
|
||||
msgstr "Visualizar tudo e check-in"
|
||||
|
||||
#: pretix/base/permissions.py:235
|
||||
#, fuzzy
|
||||
#| msgid "View all upcoming events"
|
||||
msgctxt "permission_level"
|
||||
msgid "View all and change"
|
||||
msgstr "Ver todos eventos futuros"
|
||||
msgstr "Visualizar tudo e alterar"
|
||||
|
||||
#: pretix/base/permissions.py:236
|
||||
msgid "Includes the ability to cancel and refund individual orders."
|
||||
msgstr ""
|
||||
msgstr "Incluir a habilidade de cancelar e reembolsar pedidos individuais."
|
||||
|
||||
#: pretix/base/permissions.py:238
|
||||
#, fuzzy
|
||||
#| msgid "An entry has been added to the waiting list."
|
||||
msgid "Also includes related objects like the waiting list."
|
||||
msgstr "Uma entrada foi adicionada à lista de espera."
|
||||
msgstr "Também inclui objetos relacionados como a lista de espera."
|
||||
|
||||
#: pretix/base/permissions.py:248
|
||||
#, fuzzy
|
||||
@@ -8475,18 +8449,14 @@ msgid "Full event or date cancellation"
|
||||
msgstr "Gerar cancelamento"
|
||||
|
||||
#: pretix/base/permissions.py:252
|
||||
#, fuzzy
|
||||
#| msgid "Sale not allowed"
|
||||
msgctxt "permission_level"
|
||||
msgid "Not allowed"
|
||||
msgstr "Venda não permitida"
|
||||
msgstr "Não permitida"
|
||||
|
||||
#: pretix/base/permissions.py:253
|
||||
#, fuzzy
|
||||
#| msgid "Allowed titles"
|
||||
msgctxt "permission_level"
|
||||
msgid "Allowed"
|
||||
msgstr "Títulos permitidos"
|
||||
msgstr "Permitida"
|
||||
|
||||
#: pretix/base/permissions.py:268
|
||||
msgctxt "permission_level"
|
||||
@@ -23995,7 +23965,7 @@ msgstr "Reembolso por pagamento em excesso"
|
||||
#: pretix/control/templates/pretixcontrol/order/index.html:118
|
||||
#, python-format
|
||||
msgid "This order is currently overpaid by %(amount)s."
|
||||
msgstr "O pedidos está pago em excesso por %(amount)s."
|
||||
msgstr "Este pedido está pago em excesso por %(amount)s."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/order/index.html:122
|
||||
#, python-format
|
||||
@@ -33294,7 +33264,7 @@ msgstr "iDEAL via Stripe"
|
||||
|
||||
#: pretix/plugins/stripe/payment.py:1572
|
||||
msgid "iDEAL | Wero"
|
||||
msgstr ""
|
||||
msgstr "iDEAL | Wero"
|
||||
|
||||
#: pretix/plugins/stripe/payment.py:1575
|
||||
msgid ""
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:06+0000\n"
|
||||
"PO-Revision-Date: 2026-01-26 22:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-25 08:00+0000\n"
|
||||
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
|
||||
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix-js/pt_BR/>\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.15.2\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -60,7 +60,7 @@ msgstr "PayPal Pay Later"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
|
||||
msgid "iDEAL | Wero"
|
||||
msgstr ""
|
||||
msgstr "iDEAL | Wero"
|
||||
|
||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
||||
msgid "SEPA Direct Debit"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:05+0000\n"
|
||||
"PO-Revision-Date: 2026-01-16 22:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-27 09:03+0000\n"
|
||||
"Last-Translator: Linnea Thelander <linnea@coeo.events>\n"
|
||||
"Language-Team: Swedish <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"sv/>\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.15.2\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -35279,10 +35279,8 @@ msgid "We're now trying to book these add-ons for you!"
|
||||
msgstr "Vi försöker nu reservera dessa tillval till dig!"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/checkout_addons.html:28
|
||||
#, fuzzy
|
||||
#| msgid "Additional settings"
|
||||
msgid "Additional options for"
|
||||
msgstr "Ytterligare inställningar"
|
||||
msgstr "Ytterligare val för"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/checkout_addons.html:60
|
||||
#, fuzzy
|
||||
@@ -35628,13 +35626,10 @@ msgstr[0] "Du måste välja exakt ett alternativ från denna kategori."
|
||||
msgstr[1] "Du måste välja %(min_count)s alternativ från denna kategori."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:26
|
||||
#, fuzzy, python-format
|
||||
#| msgid "You can choose %(max_count)s option from this category."
|
||||
#| msgid_plural ""
|
||||
#| "You can choose up to %(max_count)s options from this category."
|
||||
#, python-format
|
||||
msgid "You can choose one option from this category."
|
||||
msgid_plural "You can choose up to %(max_count)s options from this category."
|
||||
msgstr[0] "Du kan välja %(max_count)s alternativ från denna kategori."
|
||||
msgstr[0] "Du kan välja ett alternativ från denna kategori."
|
||||
msgstr[1] "Du kan välja upp till %(max_count)s alternativ från denna kategori."
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:34
|
||||
@@ -36329,12 +36324,11 @@ msgstr "Visa fullstor bild av %(item)s"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:131
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:288
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(count)s elements"
|
||||
#, python-format
|
||||
msgid "%(amount)s× in your cart"
|
||||
msgid_plural "%(amount)s× in your cart"
|
||||
msgstr[0] "%(count)s element"
|
||||
msgstr[1] "%(count)s element"
|
||||
msgstr[0] "%(amount)sx i din kundvagn"
|
||||
msgstr[1] "%(amount)sx i din kundvagn"
|
||||
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:209
|
||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:374
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-17 14:06+0000\n"
|
||||
"PO-Revision-Date: 2025-10-10 17:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-26 14:29+0000\n"
|
||||
"Last-Translator: Linnea Thelander <linnea@coeo.events>\n"
|
||||
"Language-Team: Swedish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/sv/>\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.13.3\n"
|
||||
"X-Generator: Weblate 5.16.2\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -1023,7 +1023,6 @@ msgid "Waiting list"
|
||||
msgstr "Väntelista"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:55
|
||||
#, fuzzy
|
||||
msgctxt "widget"
|
||||
msgid ""
|
||||
"You currently have an active cart for this event. If you select more "
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
import datetime
|
||||
import decimal
|
||||
import json
|
||||
from decimal import Decimal
|
||||
|
||||
from django.core import mail as djmail
|
||||
from django.test import TransactionTestCase
|
||||
@@ -43,8 +44,8 @@ from django_scopes import scopes_disabled
|
||||
from tests.base import SoupTestMixin, extract_form_fields
|
||||
|
||||
from pretix.base.models import (
|
||||
Event, Item, ItemVariation, Order, OrderPosition, Organizer, Quota, Team,
|
||||
User, Voucher,
|
||||
Event, Item, ItemVariation, Order, OrderPosition, Organizer, Quota,
|
||||
SeatingPlan, Team, User, Voucher,
|
||||
)
|
||||
|
||||
|
||||
@@ -134,49 +135,49 @@ class VoucherFormTest(SoupTestMixin, TransactionTestCase):
|
||||
def test_filter_status_valid(self):
|
||||
with scopes_disabled():
|
||||
v = self.event.vouchers.create(item=self.ticket)
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?status=v' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-status=v' % (self.orga.slug, self.event.slug))
|
||||
assert v.code in doc.content.decode()
|
||||
v.redeemed = 1
|
||||
v.save()
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?status=v' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-status=v' % (self.orga.slug, self.event.slug))
|
||||
assert v.code not in doc.content.decode()
|
||||
|
||||
def test_filter_status_redeemed(self):
|
||||
with scopes_disabled():
|
||||
v = self.event.vouchers.create(item=self.ticket, redeemed=1)
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?status=r' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-status=r' % (self.orga.slug, self.event.slug))
|
||||
assert v.code in doc.content.decode()
|
||||
v.redeemed = 0
|
||||
v.save()
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?status=r' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-status=r' % (self.orga.slug, self.event.slug))
|
||||
assert v.code not in doc.content.decode()
|
||||
|
||||
def test_filter_status_expired(self):
|
||||
with scopes_disabled():
|
||||
v = self.event.vouchers.create(item=self.ticket, valid_until=now() + datetime.timedelta(days=1))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?status=e' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-status=e' % (self.orga.slug, self.event.slug))
|
||||
assert v.code not in doc.content.decode()
|
||||
v.valid_until = now() - datetime.timedelta(days=1)
|
||||
v.save()
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?status=e' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-status=e' % (self.orga.slug, self.event.slug))
|
||||
assert v.code in doc.content.decode()
|
||||
|
||||
def test_filter_tag(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, code='ABCDEFG', comment='Foo', tag='bar')
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?tag=bar' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-tag=bar' % (self.orga.slug, self.event.slug))
|
||||
assert 'ABCDEFG' in doc.content.decode()
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?tag=baz' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-tag=baz' % (self.orga.slug, self.event.slug))
|
||||
assert 'ABCDEFG' not in doc.content.decode()
|
||||
|
||||
def test_search_code(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, code='ABCDEFG', comment='Foo')
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?search=ABCDEFG' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-search=ABCDEFG' % (self.orga.slug, self.event.slug))
|
||||
assert 'ABCDEFG' in doc.content.decode()
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?search=Foo' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-search=Foo' % (self.orga.slug, self.event.slug))
|
||||
assert 'ABCDEFG' in doc.content.decode()
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?search=12345' % (self.orga.slug, self.event.slug))
|
||||
doc = self.client.get('/control/event/%s/%s/vouchers/?filter-search=12345' % (self.orga.slug, self.event.slug))
|
||||
assert 'ABCDEFG' not in doc.content.decode()
|
||||
|
||||
def test_bulk_rng(self):
|
||||
@@ -771,3 +772,425 @@ class VoucherFormTest(SoupTestMixin, TransactionTestCase):
|
||||
|
||||
assert len(doc.select('.alert-warning ul li')) == 1 # Check that there's exactly 1 item in the warning list
|
||||
assert doc.text.count('Order DEDUP') == 1 # Check that the order is listed exactly once
|
||||
|
||||
|
||||
class VoucherBulkEditFormTest(SoupTestMixin, TransactionTestCase):
|
||||
@scopes_disabled()
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
|
||||
self.event = Event.objects.create(
|
||||
organizer=self.orga, name='30C3', slug='30c3',
|
||||
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
|
||||
)
|
||||
t = Team.objects.create(organizer=self.orga, all_event_permissions=True)
|
||||
t.members.add(self.user)
|
||||
t.limit_events.add(self.event)
|
||||
self.client.login(email='dummy@dummy.dummy', password='dummy')
|
||||
|
||||
self.quota_shirts = Quota.objects.create(event=self.event, name='Shirts', size=2)
|
||||
self.shirt = Item.objects.create(event=self.event, name='T-Shirt', default_price=12)
|
||||
self.quota_shirts.items.add(self.shirt)
|
||||
self.shirt_red = ItemVariation.objects.create(item=self.shirt, default_price=14, value='Red')
|
||||
self.shirt_blue = ItemVariation.objects.create(item=self.shirt, value='Blue')
|
||||
self.quota_shirts.variations.add(self.shirt_red)
|
||||
self.quota_shirts.variations.add(self.shirt_blue)
|
||||
self.quota_tickets = Quota.objects.create(event=self.event, name='Tickets', size=2)
|
||||
self.ticket = Item.objects.create(event=self.event, name='Early-bird ticket',
|
||||
default_price=23)
|
||||
self.quota_tickets.items.add(self.ticket)
|
||||
self.url = f'/control/event/{self.orga.slug}/{self.event.slug}/vouchers/bulk_edit'
|
||||
|
||||
def test_simple_edit(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(
|
||||
quota=self.quota_tickets,
|
||||
max_usages=10,
|
||||
price_mode="set",
|
||||
value=13,
|
||||
)
|
||||
self.event.vouchers.create(
|
||||
item=self.ticket,
|
||||
max_usages=10,
|
||||
price_mode="set",
|
||||
value=12,
|
||||
)
|
||||
|
||||
doc = self.post_doc(self.url, {
|
||||
'__ALL': 'on',
|
||||
}, follow=True)
|
||||
fields = extract_form_fields(doc)
|
||||
assert fields.get('bulkedit-max_usages') == '10'
|
||||
assert fields.get('bulkedit-price_mode') == 'set'
|
||||
assert not fields.get('bulkedit-value')
|
||||
fields.update({
|
||||
'_bulk': ['bulkedit__price', 'bulkeditmin_usages', 'bulkedittag', 'bulkeditshow_hidden_items'],
|
||||
'bulkedit-price_mode': 'percent',
|
||||
'bulkedit-value': '15',
|
||||
'bulkedit-min_usages': '3',
|
||||
'bulkedit-tag': 'tagged',
|
||||
'bulkedit-comment': 'This is a comment', # will be ignored, as not included in _bulk
|
||||
'bulkedit-show_hidden_items': '',
|
||||
})
|
||||
doc = self.post_doc(self.url, fields, follow=True)
|
||||
assert doc.select(".alert-success")
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.price_mode == "percent"
|
||||
assert v.value == Decimal("15.00")
|
||||
assert v.min_usages == 3
|
||||
assert v.tag == "tagged"
|
||||
assert v.comment == ""
|
||||
assert v.show_hidden_items is False
|
||||
|
||||
def _update_all(self, data: dict, expect_error: str=None):
|
||||
doc = self.post_doc(self.url, {
|
||||
'__ALL': 'on',
|
||||
}, follow=True)
|
||||
fields = extract_form_fields(doc)
|
||||
fields.update(data)
|
||||
doc = self.post_doc(self.url, fields, follow=True)
|
||||
error_texts = [el.text for el in doc.select(".alert-danger, .has-error")]
|
||||
if expect_error:
|
||||
assert doc.select(".alert-danger")
|
||||
assert any(expect_error in t for t in error_texts), error_texts
|
||||
else:
|
||||
assert doc.select(".alert-success"), error_texts
|
||||
|
||||
def test_change_itemvar_to_product(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(quota=self.quota_tickets)
|
||||
self.event.vouchers.create(item=self.ticket)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'{self.ticket.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.item == self.ticket
|
||||
assert not v.variation
|
||||
assert not v.quota
|
||||
|
||||
def test_change_itemvar_to_variation(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(quota=self.quota_tickets)
|
||||
self.event.vouchers.create(item=self.ticket)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'{self.shirt.pk}-{self.shirt_red.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.item == self.shirt
|
||||
assert v.variation == self.shirt_red
|
||||
assert not v.quota
|
||||
|
||||
def test_change_itemvar_to_quota(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(quota=self.quota_tickets)
|
||||
self.event.vouchers.create(item=self.ticket)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'q-{self.quota_tickets.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert not v.item
|
||||
assert not v.variation
|
||||
assert v.quota == self.quota_tickets
|
||||
|
||||
def test_change_itemvar_to_all(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(quota=self.quota_tickets)
|
||||
self.event.vouchers.create(item=self.ticket)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': '',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert not v.item
|
||||
assert not v.variation
|
||||
assert not v.quota
|
||||
|
||||
def test_change_max_usages(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(quota=self.quota_tickets, max_usages=15, redeemed=4)
|
||||
self.event.vouchers.create(item=self.ticket, max_usages=15, redeemed=2)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditmax_usages'],
|
||||
'bulkedit-max_usages': '3',
|
||||
}, expect_error="already been redeemed 4 times")
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditmax_usages'],
|
||||
'bulkedit-max_usages': '4',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.max_usages == 4
|
||||
|
||||
def _requires_one_more_quota(self, data: dict, quota=None, expect_error: str=None):
|
||||
self._update_all(data, expect_error="no sufficient quota")
|
||||
quota = quota or self.quota_tickets
|
||||
quota.size += 1
|
||||
quota.save()
|
||||
self._update_all(data)
|
||||
|
||||
def test_quota_check_change_item(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.shirt, block_quota=True, max_usages=2, redeemed=1)
|
||||
self.event.vouchers.create(item=self.shirt, block_quota=True, max_usages=3, redeemed=1)
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'{self.ticket.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.item == self.ticket
|
||||
|
||||
def test_quota_check_change_variation(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=2, redeemed=1)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=3, redeemed=1)
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'{self.shirt.pk}-{self.shirt_red.pk}',
|
||||
}, quota=self.quota_shirts)
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.item == self.shirt
|
||||
assert v.variation == self.shirt_red
|
||||
|
||||
def test_quota_check_change_item_with_variations(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=2, redeemed=1)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=3, redeemed=1)
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'{self.shirt.pk}',
|
||||
}, quota=self.quota_shirts)
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.item == self.shirt
|
||||
assert not v.variation
|
||||
|
||||
def test_quota_check_change_expired_to_valid(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=2)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=1, valid_until=now() - datetime.timedelta(days=1))
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkeditvalid_until'],
|
||||
'bulkedit-valid_until_0': '',
|
||||
'bulkedit-valid_until_1': '',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert not v.valid_until
|
||||
|
||||
def test_quota_check_change_max_usages(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=2)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, max_usages=1, redeemed=1)
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkeditmax_usages'],
|
||||
'bulkedit-max_usages': '2',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.max_usages == 2
|
||||
|
||||
def test_quota_check_no_change(self):
|
||||
with scopes_disabled():
|
||||
# Technically overbooked, but we don't have a diff in quota
|
||||
self.event.vouchers.create(item=self.shirt, variation=self.shirt_red, block_quota=True)
|
||||
self.event.vouchers.create(item=self.shirt, variation=self.shirt_red, block_quota=True)
|
||||
self.event.vouchers.create(item=self.shirt, variation=self.shirt_red, block_quota=True)
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'{self.shirt.pk}-{self.shirt_blue.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.variation == self.shirt_blue
|
||||
|
||||
def test_quota_check_change_subevent(self):
|
||||
with scopes_disabled():
|
||||
self.event.has_subevents = True
|
||||
self.event.save()
|
||||
se1 = self.event.subevents.create(name="Foo", date_from=now())
|
||||
se2 = self.event.subevents.create(name="Bar", date_from=now())
|
||||
self.quota_tickets.subevent = se1
|
||||
self.quota_tickets.save()
|
||||
Quota.objects.create(event=self.event, subevent=se2, name='Tickets', size=3)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, subevent=se2)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, subevent=se2)
|
||||
self.event.vouchers.create(item=self.ticket, block_quota=True, subevent=se2)
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkeditsubevent'],
|
||||
'bulkedit-subevent': f'{se1.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.subevent == se1
|
||||
|
||||
def test_change_subevent_quota_invalid(self):
|
||||
with scopes_disabled():
|
||||
self.event.has_subevents = True
|
||||
self.event.save()
|
||||
se1 = self.event.subevents.create(name="Foo", date_from=now())
|
||||
se2 = self.event.subevents.create(name="Bar", date_from=now())
|
||||
self.quota_tickets.subevent = se1
|
||||
self.quota_tickets.save()
|
||||
v1 = self.event.vouchers.create(quota=self.quota_tickets, block_quota=True, subevent=se1)
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditsubevent'],
|
||||
'bulkedit-subevent': f'{se2.pk}',
|
||||
}, expect_error="selected quota does not match the selected subevent")
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditsubevent'],
|
||||
'bulkedit-subevent': '',
|
||||
}, expect_error="has no date selected")
|
||||
v1.quota = None
|
||||
v1.item = self.ticket
|
||||
v1.save()
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditsubevent'],
|
||||
'bulkedit-subevent': '',
|
||||
}, expect_error="If you want this voucher to block quota, you need to select a specific date")
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.subevent == se1
|
||||
|
||||
def test_change_missing_itemvar_with_block_quota(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(quota=self.quota_tickets, block_quota=True)
|
||||
self.event.vouchers.create(quota=self.quota_tickets, block_quota=True)
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': '',
|
||||
}, expect_error="You need to select a specific product or quota if this voucher should reserve")
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar', 'bulkeditblock_quota'],
|
||||
'bulkedit-itemvar': '',
|
||||
'bulkedit-block_quota': '',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert not v.subevent
|
||||
assert not v.block_quota
|
||||
|
||||
def test_change_subevent_and_quota(self):
|
||||
with scopes_disabled():
|
||||
self.event.has_subevents = True
|
||||
self.event.save()
|
||||
se1 = self.event.subevents.create(name="Foo", date_from=now())
|
||||
se2 = self.event.subevents.create(name="Bar", date_from=now())
|
||||
self.quota_tickets.subevent = se1
|
||||
self.quota_tickets.save()
|
||||
q2 = Quota.objects.create(event=self.event, subevent=se2, name='Tickets', size=3)
|
||||
self.event.vouchers.create(quota=self.quota_tickets, block_quota=True, subevent=se1)
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar', 'bulkeditsubevent'],
|
||||
'bulkedit-subevent': f'{se2.pk}',
|
||||
'bulkedit-itemvar': f'q-{q2.pk}',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.subevent == se2
|
||||
assert v.quota == q2
|
||||
|
||||
def test_quota_check_change_block_quota(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, max_usages=3)
|
||||
self._requires_one_more_quota({
|
||||
'_bulk': ['bulkeditblock_quota'],
|
||||
'bulkedit-block_quota': 'on',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.block_quota
|
||||
|
||||
def test_ignore_quota(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, max_usages=3)
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditblock_quota', 'bulkeditallow_ignore_quota'],
|
||||
'bulkedit-block_quota': 'on',
|
||||
'bulkedit-allow_ignore_quota': 'on',
|
||||
})
|
||||
with scopes_disabled():
|
||||
for v in self.event.vouchers.all():
|
||||
assert v.block_quota
|
||||
assert v.allow_ignore_quota
|
||||
|
||||
@scopes_disabled()
|
||||
def _create_seat(self, **kwargs):
|
||||
plan = SeatingPlan.objects.create(
|
||||
name="Plan", organizer=self.orga, layout="{}"
|
||||
)
|
||||
self.event.seating_plan = plan
|
||||
self.event.save()
|
||||
return self.event.seats.create(seat_number="A1", product=self.ticket, seat_guid="A1", **kwargs)
|
||||
|
||||
def test_seated_unsupported(self):
|
||||
with scopes_disabled():
|
||||
self.event.vouchers.create(item=self.ticket, max_usages=1, seat=self._create_seat())
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditmax_usages'],
|
||||
'bulkedit-max_usages': '2',
|
||||
}, expect_error="Changing the maximum number of usages in bulk is not supported")
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditsubevent'],
|
||||
'bulkedit-subevent': '',
|
||||
}, expect_error="Changing the date in bulk is not supported")
|
||||
self._update_all({
|
||||
'_bulk': ['bulkedititemvar'],
|
||||
'bulkedit-itemvar': f'q-{self.quota_tickets.pk}',
|
||||
}, expect_error="Changing the product to a quota is not supported")
|
||||
|
||||
def test_seat_changed_to_valid_needs_to_be_available(self):
|
||||
with scopes_disabled():
|
||||
seat = self._create_seat(blocked=True)
|
||||
self.event.vouchers.create(item=self.ticket, max_usages=1, valid_until=now() - datetime.timedelta(days=1), seat=seat)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditvalid_until'],
|
||||
'bulkedit-valid_until_0': '',
|
||||
'bulkedit-valid_until_1': '',
|
||||
}, expect_error="not all assigned seats of the vouchers are still available")
|
||||
|
||||
seat.blocked = False
|
||||
seat.save()
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditvalid_until'],
|
||||
'bulkedit-valid_until_0': '',
|
||||
'bulkedit-valid_until_1': '',
|
||||
})
|
||||
|
||||
def test_seat_changed_to_valid_needs_to_be_available_subevents(self):
|
||||
with scopes_disabled():
|
||||
self.event.has_subevents = True
|
||||
self.event.save()
|
||||
se1 = self.event.subevents.create(name="Foo", date_from=now())
|
||||
seat = self._create_seat(subevent=se1, blocked=True)
|
||||
self.event.vouchers.create(item=self.ticket, max_usages=1, valid_until=now() - datetime.timedelta(days=1), seat=seat, subevent=se1)
|
||||
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditvalid_until'],
|
||||
'bulkedit-valid_until_0': '',
|
||||
'bulkedit-valid_until_1': '',
|
||||
}, expect_error="not all assigned seats of the vouchers are still available")
|
||||
|
||||
seat.blocked = False
|
||||
seat.save()
|
||||
self._update_all({
|
||||
'_bulk': ['bulkeditvalid_until'],
|
||||
'bulkedit-valid_until_0': '',
|
||||
'bulkedit-valid_until_1': '',
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user