mirror of
https://github.com/pretix/pretix.git
synced 2026-04-01 19:42:27 +00:00
Compare commits
4 Commits
master
...
less-cart-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1ba5c298d | ||
|
|
c6c48537dd | ||
|
|
ab08dea9f7 | ||
|
|
4d15731528 |
@@ -90,10 +90,10 @@ dependencies = [
|
||||
"pytz-deprecation-shim==0.1.*",
|
||||
"pyuca",
|
||||
"qrcode==8.2",
|
||||
"redis==7.4.*",
|
||||
"redis==7.1.*",
|
||||
"reportlab==4.4.*",
|
||||
"requests==2.32.*",
|
||||
"sentry-sdk==2.57.*",
|
||||
"sentry-sdk==2.56.*",
|
||||
"sepaxml==2.7.*",
|
||||
"stripe==7.9.*",
|
||||
"text-unidecode==1.*",
|
||||
|
||||
@@ -67,9 +67,9 @@ from pretix.base.email import get_email_context
|
||||
from pretix.base.i18n import get_language_without_region, language
|
||||
from pretix.base.media import MEDIA_TYPES
|
||||
from pretix.base.models import (
|
||||
CartPosition, Device, Event, GiftCard, Item, ItemVariation, LogEntry,
|
||||
Membership, Order, OrderPayment, OrderPosition, Quota, Seat,
|
||||
SeatCategoryMapping, User, Voucher,
|
||||
CartPosition, Device, Event, GiftCard, Item, ItemVariation, Membership,
|
||||
Order, OrderPayment, OrderPosition, Quota, Seat, SeatCategoryMapping, User,
|
||||
Voucher,
|
||||
)
|
||||
from pretix.base.models.event import SubEvent
|
||||
from pretix.base.models.orders import (
|
||||
@@ -1618,7 +1618,7 @@ class OrderChangeManager:
|
||||
MembershipOperation = namedtuple('MembershipOperation', ('position', 'membership'))
|
||||
CancelOperation = namedtuple('CancelOperation', ('position', 'price_diff'))
|
||||
AddOperation = namedtuple('AddOperation', ('item', 'variation', 'price', 'addon_to', 'subevent', 'seat', 'membership',
|
||||
'valid_from', 'valid_until', 'is_bundled', 'result', 'count'))
|
||||
'valid_from', 'valid_until', 'is_bundled', 'result'))
|
||||
SplitOperation = namedtuple('SplitOperation', ('position',))
|
||||
FeeValueOperation = namedtuple('FeeValueOperation', ('fee', 'value', 'price_diff'))
|
||||
AddFeeOperation = namedtuple('AddFeeOperation', ('fee', 'price_diff'))
|
||||
@@ -1632,24 +1632,16 @@ class OrderChangeManager:
|
||||
ForceRecomputeOperation = namedtuple('ForceRecomputeOperation', tuple())
|
||||
|
||||
class AddPositionResult:
|
||||
_positions: Optional[List[OrderPosition]]
|
||||
_position: Optional[OrderPosition]
|
||||
|
||||
def __init__(self):
|
||||
self._positions = None
|
||||
self._position = None
|
||||
|
||||
@property
|
||||
def position(self) -> OrderPosition:
|
||||
if self._positions is None:
|
||||
if self._position is None:
|
||||
raise RuntimeError("Order position has not been created yet. Call commit() first on OrderChangeManager.")
|
||||
if len(self._positions) != 1:
|
||||
raise RuntimeError("More than one position created.")
|
||||
return self._positions[0]
|
||||
|
||||
@property
|
||||
def positions(self) -> List[OrderPosition]:
|
||||
if self._positions is None:
|
||||
raise RuntimeError("Order position has not been created yet. Call commit() first on OrderChangeManager.")
|
||||
return self._positions
|
||||
return self._position
|
||||
|
||||
def __init__(self, order: Order, user=None, auth=None, notify=True, reissue_invoice=True, allow_blocked_seats=False):
|
||||
self.order = order
|
||||
@@ -1856,12 +1848,8 @@ class OrderChangeManager:
|
||||
|
||||
def add_position(self, item: Item, variation: ItemVariation, price: Decimal, addon_to: OrderPosition = None,
|
||||
subevent: SubEvent = None, seat: Seat = None, membership: Membership = None,
|
||||
valid_from: datetime = None, valid_until: datetime = None, count: int = 1) -> 'OrderChangeManager.AddPositionResult':
|
||||
if count < 1:
|
||||
raise ValueError("Count must be positive")
|
||||
valid_from: datetime = None, valid_until: datetime = None) -> 'OrderChangeManager.AddPositionResult':
|
||||
if isinstance(seat, str):
|
||||
if count > 1:
|
||||
raise ValueError("Cannot combine count > 1 with seat")
|
||||
if not seat:
|
||||
seat = None
|
||||
else:
|
||||
@@ -1915,14 +1903,14 @@ class OrderChangeManager:
|
||||
if self.order.event.settings.invoice_include_free or price.gross != Decimal('0.00'):
|
||||
self._invoice_dirty = True
|
||||
|
||||
self._totaldiff_guesstimate += price.gross * count
|
||||
self._quotadiff.update({q: count for q in new_quotas})
|
||||
self._totaldiff_guesstimate += price.gross
|
||||
self._quotadiff.update(new_quotas)
|
||||
if seat:
|
||||
self._seatdiff.update([seat])
|
||||
|
||||
result = self.AddPositionResult()
|
||||
self._operations.append(self.AddOperation(item, variation, price, addon_to, subevent, seat, membership,
|
||||
valid_from, valid_until, is_bundled, result, count))
|
||||
valid_from, valid_until, is_bundled, result))
|
||||
return result
|
||||
|
||||
def split(self, position: OrderPosition):
|
||||
@@ -2542,35 +2530,29 @@ class OrderChangeManager:
|
||||
secret_dirty.remove(position)
|
||||
position.save(update_fields=['canceled', 'secret'])
|
||||
elif isinstance(op, self.AddOperation):
|
||||
new_pos = []
|
||||
new_logs = []
|
||||
for i in range(op.count):
|
||||
pos = OrderPosition.objects.create(
|
||||
item=op.item, variation=op.variation, addon_to=op.addon_to,
|
||||
price=op.price.gross, order=self.order, tax_rate=op.price.rate, tax_code=op.price.code,
|
||||
tax_value=op.price.tax, tax_rule=op.item.tax_rule,
|
||||
positionid=nextposid, subevent=op.subevent, seat=op.seat,
|
||||
used_membership=op.membership, valid_from=op.valid_from, valid_until=op.valid_until,
|
||||
is_bundled=op.is_bundled,
|
||||
)
|
||||
nextposid += 1
|
||||
new_pos.append(pos)
|
||||
new_logs.append(self.order.log_action('pretix.event.order.changed.add', user=self.user, auth=self.auth, data={
|
||||
'position': pos.pk,
|
||||
'item': op.item.pk,
|
||||
'variation': op.variation.pk if op.variation else None,
|
||||
'addon_to': op.addon_to.pk if op.addon_to else None,
|
||||
'price': op.price.gross,
|
||||
'positionid': pos.positionid,
|
||||
'membership': pos.used_membership_id,
|
||||
'subevent': op.subevent.pk if op.subevent else None,
|
||||
'seat': op.seat.pk if op.seat else None,
|
||||
'valid_from': op.valid_from.isoformat() if op.valid_from else None,
|
||||
'valid_until': op.valid_until.isoformat() if op.valid_until else None,
|
||||
}, save=False))
|
||||
|
||||
op.result._positions = new_pos
|
||||
LogEntry.bulk_create_and_postprocess(new_logs)
|
||||
pos = OrderPosition.objects.create(
|
||||
item=op.item, variation=op.variation, addon_to=op.addon_to,
|
||||
price=op.price.gross, order=self.order, tax_rate=op.price.rate, tax_code=op.price.code,
|
||||
tax_value=op.price.tax, tax_rule=op.item.tax_rule,
|
||||
positionid=nextposid, subevent=op.subevent, seat=op.seat,
|
||||
used_membership=op.membership, valid_from=op.valid_from, valid_until=op.valid_until,
|
||||
is_bundled=op.is_bundled,
|
||||
)
|
||||
nextposid += 1
|
||||
self.order.log_action('pretix.event.order.changed.add', user=self.user, auth=self.auth, data={
|
||||
'position': pos.pk,
|
||||
'item': op.item.pk,
|
||||
'variation': op.variation.pk if op.variation else None,
|
||||
'addon_to': op.addon_to.pk if op.addon_to else None,
|
||||
'price': op.price.gross,
|
||||
'positionid': pos.positionid,
|
||||
'membership': pos.used_membership_id,
|
||||
'subevent': op.subevent.pk if op.subevent else None,
|
||||
'seat': op.seat.pk if op.seat else None,
|
||||
'valid_from': op.valid_from.isoformat() if op.valid_from else None,
|
||||
'valid_until': op.valid_until.isoformat() if op.valid_until else None,
|
||||
})
|
||||
op.result._position = pos
|
||||
elif isinstance(op, self.SplitOperation):
|
||||
position = position_cache.setdefault(op.position.pk, op.position)
|
||||
split_positions.append(position)
|
||||
@@ -2895,7 +2877,7 @@ class OrderChangeManager:
|
||||
return total
|
||||
|
||||
def _check_order_size(self):
|
||||
if (len(self.order.positions.all()) + sum([op.count for op in self._operations if isinstance(op, self.AddOperation)])) > settings.PRETIX_MAX_ORDER_SIZE:
|
||||
if (len(self.order.positions.all()) + len([op for op in self._operations if isinstance(op, self.AddOperation)])) > settings.PRETIX_MAX_ORDER_SIZE:
|
||||
raise OrderError(
|
||||
self.error_messages['max_order_size'] % {
|
||||
'max': settings.PRETIX_MAX_ORDER_SIZE,
|
||||
@@ -2956,7 +2938,7 @@ class OrderChangeManager:
|
||||
]) + len([
|
||||
o for o in self._operations if isinstance(o, self.SplitOperation)
|
||||
])
|
||||
adds = sum([o.count for o in self._operations if isinstance(o, self.AddOperation)])
|
||||
adds = len([o for o in self._operations if isinstance(o, self.AddOperation)])
|
||||
if current > 0 and current - cancels + adds < 1:
|
||||
raise OrderError(self.error_messages['complete_cancel'])
|
||||
|
||||
@@ -3003,18 +2985,17 @@ class OrderChangeManager:
|
||||
elif isinstance(op, self.CancelOperation) and op.position in positions_to_fake_cart:
|
||||
fake_cart.remove(positions_to_fake_cart[op.position])
|
||||
elif isinstance(op, self.AddOperation):
|
||||
for i in range(op.count):
|
||||
cp = CartPosition(
|
||||
event=self.event,
|
||||
item=op.item,
|
||||
variation=op.variation,
|
||||
used_membership=op.membership,
|
||||
subevent=op.subevent,
|
||||
seat=op.seat,
|
||||
)
|
||||
cp.override_valid_from = op.valid_from
|
||||
cp.override_valid_until = op.valid_until
|
||||
fake_cart.append(cp)
|
||||
cp = CartPosition(
|
||||
event=self.event,
|
||||
item=op.item,
|
||||
variation=op.variation,
|
||||
used_membership=op.membership,
|
||||
subevent=op.subevent,
|
||||
seat=op.seat,
|
||||
)
|
||||
cp.override_valid_from = op.valid_from
|
||||
cp.override_valid_until = op.valid_until
|
||||
fake_cart.append(cp)
|
||||
try:
|
||||
validate_memberships_in_order(self.order.customer, fake_cart, self.event, lock=True, ignored_order=self.order, testmode=self.order.testmode)
|
||||
except ValidationError as e:
|
||||
|
||||
@@ -331,10 +331,6 @@ class OtherOperationsForm(forms.Form):
|
||||
|
||||
|
||||
class OrderPositionAddForm(forms.Form):
|
||||
count = forms.IntegerField(
|
||||
label=_('Number of products to add'),
|
||||
initial=1,
|
||||
)
|
||||
itemvar = forms.ChoiceField(
|
||||
label=_('Product')
|
||||
)
|
||||
@@ -436,10 +432,6 @@ class OrderPositionAddForm(forms.Form):
|
||||
d['used_membership'] = [m for m in self.memberships if str(m.pk) == d['used_membership']][0]
|
||||
else:
|
||||
d['used_membership'] = None
|
||||
if d.get("count", 1) and d.get("seat"):
|
||||
raise ValidationError({
|
||||
"seat": _("You can not choose a seat when adding multiple products at once.")
|
||||
})
|
||||
return d
|
||||
|
||||
|
||||
|
||||
@@ -329,7 +329,6 @@
|
||||
{{ add_form.custom_error }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% bootstrap_field add_form.count layout="control" %}
|
||||
{% bootstrap_field add_form.itemvar layout="control" %}
|
||||
{% bootstrap_field add_form.price addon_after=request.event.currency layout="control" %}
|
||||
{% if add_form.addon_to %}
|
||||
@@ -365,7 +364,6 @@
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-horizontal">
|
||||
{% bootstrap_field add_position_formset.empty_form.count layout="control" %}
|
||||
{% bootstrap_field add_position_formset.empty_form.itemvar layout="control" %}
|
||||
{% bootstrap_field add_position_formset.empty_form.price addon_after=request.event.currency layout="control" %}
|
||||
{% if add_position_formset.empty_form.addon_to %}
|
||||
|
||||
@@ -2059,13 +2059,12 @@ class OrderChange(OrderView):
|
||||
else:
|
||||
variation = None
|
||||
try:
|
||||
for i in range(f.cleaned_data.get("count", 1)):
|
||||
ocm.add_position(item, variation,
|
||||
f.cleaned_data['price'],
|
||||
f.cleaned_data.get('addon_to'),
|
||||
f.cleaned_data.get('subevent'),
|
||||
f.cleaned_data.get('seat'),
|
||||
f.cleaned_data.get('used_membership'))
|
||||
ocm.add_position(item, variation,
|
||||
f.cleaned_data['price'],
|
||||
f.cleaned_data.get('addon_to'),
|
||||
f.cleaned_data.get('subevent'),
|
||||
f.cleaned_data.get('seat'),
|
||||
f.cleaned_data.get('used_membership'))
|
||||
except OrderError as e:
|
||||
f.custom_error = str(e)
|
||||
return False
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-30 11:22+0000\n"
|
||||
"PO-Revision-Date: 2026-03-31 17:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-18 12:23+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"es/>\n"
|
||||
@@ -13331,7 +13331,7 @@ msgstr ""
|
||||
#: pretix/base/settings.py:4157
|
||||
#, python-brace-format
|
||||
msgid "VAT-ID is not supported for \"{}\"."
|
||||
msgstr "El NIF no es compatible con «{}»."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:4164
|
||||
msgid "The last payment date cannot be before the end of presale."
|
||||
@@ -27567,30 +27567,28 @@ msgid "Add a two-factor authentication device"
|
||||
msgstr "Añadir un dispositivo de autenticación de dos factores"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Smartphone with the Authenticator application"
|
||||
msgid "Smartphone with Authenticator app"
|
||||
msgstr "Smartphone con la aplicación Authenticator"
|
||||
msgstr "Celular con aplicación de autenticación"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:21
|
||||
msgid ""
|
||||
"Use your smartphone with any Time-based One-Time-Password app like freeOTP, "
|
||||
"Google Authenticator or Proton Authenticator."
|
||||
msgstr ""
|
||||
"Use su smartphone con cualquier aplicación de contraseñas de un solo uso "
|
||||
"basadas en el tiempo, como freeOTP, Google Authenticator o Proton "
|
||||
"Authenticator."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:30
|
||||
#, fuzzy
|
||||
#| msgid "WebAuthn-compatible hardware token (e.g. Yubikey)"
|
||||
msgid "WebAuthn-compatible hardware token"
|
||||
msgstr "Token físico compatible con WebAuthn"
|
||||
msgstr "Hardware compatible con token WebAuthn (p. ej. Yubikey)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:32
|
||||
msgid ""
|
||||
"Use a hardware token like the Yubikey, or other biometric authentication "
|
||||
"like fingerprint or face recognition."
|
||||
msgstr ""
|
||||
"Utiliza un dispositivo de seguridad físico, como el Yubikey, u otro método "
|
||||
"de autenticación biométrica, como el reconocimiento de huellas dactilares o "
|
||||
"facial."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
|
||||
msgid "To set up this device, please follow the following steps:"
|
||||
|
||||
@@ -4,10 +4,10 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-30 11:22+0000\n"
|
||||
"PO-Revision-Date: 2026-03-31 17:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-18 12:23+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"fr/>\n"
|
||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix/fr/"
|
||||
">\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -13454,7 +13454,7 @@ msgstr ""
|
||||
#: pretix/base/settings.py:4157
|
||||
#, python-brace-format
|
||||
msgid "VAT-ID is not supported for \"{}\"."
|
||||
msgstr "Le numéro de TVA n'est pas pris en charge pour « {} »."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:4164
|
||||
msgid "The last payment date cannot be before the end of presale."
|
||||
@@ -27774,30 +27774,28 @@ msgid "Add a two-factor authentication device"
|
||||
msgstr "Ajouter un dispositif d'authentification à deux facteurs"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Smartphone with the Authenticator application"
|
||||
msgid "Smartphone with Authenticator app"
|
||||
msgstr "Smartphone équipé de l'application Authenticator"
|
||||
msgstr "Smartphone avec l'application Authenticator"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:21
|
||||
msgid ""
|
||||
"Use your smartphone with any Time-based One-Time-Password app like freeOTP, "
|
||||
"Google Authenticator or Proton Authenticator."
|
||||
msgstr ""
|
||||
"Utilisez votre smartphone avec n'importe quelle application de mots de passe "
|
||||
"à usage unique générés en temps réel, comme freeOTP, Google Authenticator ou "
|
||||
"Proton Authenticator."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:30
|
||||
#, fuzzy
|
||||
#| msgid "WebAuthn-compatible hardware token (e.g. Yubikey)"
|
||||
msgid "WebAuthn-compatible hardware token"
|
||||
msgstr "Token matériel compatible WebAuthn"
|
||||
msgstr "Token matériel compatible WebAuthn (par ex. Yubikey)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:32
|
||||
msgid ""
|
||||
"Use a hardware token like the Yubikey, or other biometric authentication "
|
||||
"like fingerprint or face recognition."
|
||||
msgstr ""
|
||||
"Utilisez une clé matérielle telle que la Yubikey, ou un autre moyen "
|
||||
"d'authentification biométrique, comme la reconnaissance d'empreintes "
|
||||
"digitales ou faciale."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
|
||||
msgid "To set up this device, please follow the following steps:"
|
||||
|
||||
@@ -7,10 +7,10 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-30 11:22+0000\n"
|
||||
"PO-Revision-Date: 2026-03-31 17:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-18 12:23+0000\n"
|
||||
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
|
||||
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
|
||||
"\n"
|
||||
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/"
|
||||
">\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -13283,7 +13283,7 @@ msgstr ""
|
||||
#: pretix/base/settings.py:4157
|
||||
#, python-brace-format
|
||||
msgid "VAT-ID is not supported for \"{}\"."
|
||||
msgstr "Btw-nummer wordt niet ondersteund voor \"{}\"."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:4164
|
||||
msgid "The last payment date cannot be before the end of presale."
|
||||
@@ -27461,28 +27461,28 @@ msgid "Add a two-factor authentication device"
|
||||
msgstr "Twee-factor-authenticatieapparaat toevoegen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Smartphone with the Authenticator application"
|
||||
msgid "Smartphone with Authenticator app"
|
||||
msgstr "Smartphone met Authenticator-app"
|
||||
msgstr "Smartphone met de Authenticator-applicatie"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:21
|
||||
msgid ""
|
||||
"Use your smartphone with any Time-based One-Time-Password app like freeOTP, "
|
||||
"Google Authenticator or Proton Authenticator."
|
||||
msgstr ""
|
||||
"Gebruik uw smartphone met een willekeurige app voor tijdgebonden eenmalige "
|
||||
"wachtwoorden, zoals freeOTP, Google Authenticator of Proton Authenticator."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:30
|
||||
#, fuzzy
|
||||
#| msgid "WebAuthn-compatible hardware token (e.g. Yubikey)"
|
||||
msgid "WebAuthn-compatible hardware token"
|
||||
msgstr "WebAuthn-compatibel hardwaretoken"
|
||||
msgstr "WebAuthn-compatibel hardware-token (bijvoorbeeld Yubikey)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:32
|
||||
msgid ""
|
||||
"Use a hardware token like the Yubikey, or other biometric authentication "
|
||||
"like fingerprint or face recognition."
|
||||
msgstr ""
|
||||
"Gebruik een hardwaretoken zoals de Yubikey, of een andere vorm van "
|
||||
"biometrische authenticatie, zoals vingerafdruk- of gezichtsherkenning."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
|
||||
msgid "To set up this device, please follow the following steps:"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-30 11:22+0000\n"
|
||||
"PO-Revision-Date: 2026-03-31 17:00+0000\n"
|
||||
"PO-Revision-Date: 2026-03-18 14:50+0000\n"
|
||||
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
|
||||
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
|
||||
"pretix/nl_Informal/>\n"
|
||||
@@ -13314,7 +13314,7 @@ msgstr ""
|
||||
#: pretix/base/settings.py:4157
|
||||
#, python-brace-format
|
||||
msgid "VAT-ID is not supported for \"{}\"."
|
||||
msgstr "Btw-nummer wordt niet ondersteund voor \"{}\"."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:4164
|
||||
msgid "The last payment date cannot be before the end of presale."
|
||||
@@ -27518,28 +27518,28 @@ msgid "Add a two-factor authentication device"
|
||||
msgstr "Twee-factor-authenticatieapparaat toevoegen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Smartphone with the Authenticator application"
|
||||
msgid "Smartphone with Authenticator app"
|
||||
msgstr "Smartphone met Authenticator-app"
|
||||
msgstr "Smartphone met de Authenticator-applicatie"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:21
|
||||
msgid ""
|
||||
"Use your smartphone with any Time-based One-Time-Password app like freeOTP, "
|
||||
"Google Authenticator or Proton Authenticator."
|
||||
msgstr ""
|
||||
"Gebruik je smartphone met een willekeurige app voor tijdgebonden eenmalige "
|
||||
"wachtwoorden, zoals freeOTP, Google Authenticator of Proton Authenticator."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:30
|
||||
#, fuzzy
|
||||
#| msgid "WebAuthn-compatible hardware token (e.g. Yubikey)"
|
||||
msgid "WebAuthn-compatible hardware token"
|
||||
msgstr "WebAuthn-compatibel hardwaretoken"
|
||||
msgstr "WebAuthn-compatibel hardware-token (bijvoorbeeld Yubikey)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_add.html:32
|
||||
msgid ""
|
||||
"Use a hardware token like the Yubikey, or other biometric authentication "
|
||||
"like fingerprint or face recognition."
|
||||
msgstr ""
|
||||
"Gebruik een hardwaretoken zoals de Yubikey, of een andere vorm van "
|
||||
"biometrische authenticatie, zoals vingerafdruk- of gezichtsherkenning."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
|
||||
msgid "To set up this device, please follow the following steps:"
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-03-30 11:22+0000\n"
|
||||
"PO-Revision-Date: 2026-03-30 21: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/pt_BR/>\n"
|
||||
@@ -19613,7 +19613,7 @@ msgstr "Excluir"
|
||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_form.html:91
|
||||
#: pretix/presale/templates/pretixpresale/fragment_event_list_filter.html:22
|
||||
msgid "Filter"
|
||||
msgstr "Filtrar"
|
||||
msgstr "Filtro"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:50
|
||||
msgid "Your search did not match any check-ins."
|
||||
@@ -28003,9 +28003,6 @@ msgid ""
|
||||
"According to your event settings, sold out products are hidden from "
|
||||
"customers. This way, customers will not be able to discover the waiting list."
|
||||
msgstr ""
|
||||
"De acordo com as configurações do seu evento, os produtos esgotados ficam "
|
||||
"ocultos para os clientes. Dessa forma, os clientes não poderão descobrir a "
|
||||
"lista de espera."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/waitinglist/index.html:38
|
||||
msgid "Send vouchers"
|
||||
@@ -28052,9 +28049,6 @@ msgid ""
|
||||
"waiting list in, you could sell tickets worth an additional "
|
||||
"<strong>%(amount)s</strong>."
|
||||
msgstr ""
|
||||
"Se você conseguir criar espaço suficiente em seu evento para acomodar todas "
|
||||
"as pessoas na lista de espera, poderá vender ingressos no valor de um "
|
||||
"adicional de <strong>%(amount)s</strong>."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/waitinglist/index.html:115
|
||||
msgid "Successfully redeemed"
|
||||
|
||||
@@ -296,8 +296,7 @@ class SetPasswordForm(forms.Form):
|
||||
}
|
||||
email = forms.EmailField(
|
||||
label=_('Email'),
|
||||
widget=forms.EmailInput(attrs={'autocomplete': 'username', 'readonly': 'readonly'}),
|
||||
required=False,
|
||||
disabled=True
|
||||
)
|
||||
password = forms.CharField(
|
||||
label=_('Password'),
|
||||
|
||||
@@ -157,7 +157,7 @@ DATABASES = {
|
||||
'HOST': config.get('database', 'host', fallback=''),
|
||||
'PORT': config.get('database', 'port', fallback=''),
|
||||
'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120,
|
||||
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3',
|
||||
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3', # Will only be used from Django 4.1 onwards
|
||||
'DISABLE_SERVER_SIDE_CURSORS': db_disable_server_side_cursors,
|
||||
'OPTIONS': db_options,
|
||||
'TEST': {}
|
||||
@@ -179,21 +179,6 @@ if config.has_section('replica'):
|
||||
}
|
||||
DATABASE_ROUTERS = ['pretix.helpers.database.ReplicaRouter']
|
||||
|
||||
if config.has_section('dbreadonly'):
|
||||
DATABASES['readonly'] = {
|
||||
'ENGINE': 'django.db.backends.' + db_backend,
|
||||
'NAME': config.get('dbreadonly', 'name', fallback=DATABASES['default']['NAME']),
|
||||
'USER': config.get('dbreadonly', 'user', fallback=DATABASES['default']['USER']),
|
||||
'PASSWORD': config.get('dbreadonly', 'password', fallback=DATABASES['default']['PASSWORD']),
|
||||
'HOST': config.get('dbreadonly', 'host', fallback=DATABASES['default']['HOST']),
|
||||
'PORT': config.get('dbreadonly', 'port', fallback=DATABASES['default']['PORT']),
|
||||
'CONN_MAX_AGE': 0, # do not spam primary with open connections as long as readonly is only used occasionally
|
||||
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3',
|
||||
'DISABLE_SERVER_SIDE_CURSORS': db_disable_server_side_cursors,
|
||||
'OPTIONS': db_options,
|
||||
'TEST': {}
|
||||
}
|
||||
|
||||
STATIC_URL = config.get('urls', 'static', fallback='/static/')
|
||||
|
||||
MEDIA_URL = config.get('urls', 'media', fallback='/media/')
|
||||
|
||||
@@ -2406,15 +2406,6 @@ class OrderChangeManagerTests(TestCase):
|
||||
self.ocm.commit()
|
||||
assert self.order.positions.count() == 2
|
||||
|
||||
@classscope(attr='o')
|
||||
def test_add_item_quota_partial(self):
|
||||
q1 = self.event.quotas.create(name='Test', size=1)
|
||||
q1.items.add(self.shirt)
|
||||
self.ocm.add_position(self.shirt, None, None, None, count=2)
|
||||
with self.assertRaises(OrderError):
|
||||
self.ocm.commit()
|
||||
assert self.order.positions.count() == 2
|
||||
|
||||
@classscope(attr='o')
|
||||
def test_add_item_addon(self):
|
||||
self.shirt.category = self.event.categories.create(name='Add-ons', is_addon=True)
|
||||
|
||||
@@ -1584,11 +1584,10 @@ class OrderChangeTests(SoupTest):
|
||||
'add_position-MAX_NUM_FORMS': '100',
|
||||
'add_position-0-itemvar': str(self.shirt.pk),
|
||||
'add_position-0-do': 'on',
|
||||
'add_position-0-count': '2',
|
||||
'add_position-0-price': '14.00',
|
||||
})
|
||||
with scopes_disabled():
|
||||
assert self.order.positions.count() == 4
|
||||
assert self.order.positions.count() == 3
|
||||
assert self.order.positions.last().item == self.shirt
|
||||
assert self.order.positions.last().price == 14
|
||||
|
||||
|
||||
Reference in New Issue
Block a user