mirror of
https://github.com/pretix/pretix.git
synced 2025-12-22 16:52:27 +00:00
Compare commits
33 Commits
logentryty
...
validate-u
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3689d4a5a0 | ||
|
|
867ea39a0d | ||
|
|
b060968f62 | ||
|
|
9a47eb6385 | ||
|
|
be67e40f1c | ||
|
|
c99a9ebe9a | ||
|
|
b5cac90475 | ||
|
|
58d36706b2 | ||
|
|
c520f77bbb | ||
|
|
73ceeffc7f | ||
|
|
7b6c82c341 | ||
|
|
35ac277b3d | ||
|
|
eb731f305b | ||
|
|
bf9af08cab | ||
|
|
95639dc6e1 | ||
|
|
966d6bb8e9 | ||
|
|
2c20bf972f | ||
|
|
0deba91e4b | ||
|
|
b9b937ea0d | ||
|
|
410215f575 | ||
|
|
1fa84b772b | ||
|
|
cda950befc | ||
|
|
783d51b75f | ||
|
|
7333f82e45 | ||
|
|
b2a4ba96f8 | ||
|
|
81f5af8414 | ||
|
|
ce1406b158 | ||
|
|
b5ad68f48d | ||
|
|
5512fa8245 | ||
|
|
83f891ce24 | ||
|
|
04e4e33885 | ||
|
|
2a98907e88 | ||
|
|
22e7962a29 |
@@ -33,7 +33,7 @@ dependencies = [
|
||||
"celery==5.5.*",
|
||||
"chardet==5.2.*",
|
||||
"cryptography>=44.0.0",
|
||||
"css-inline==0.18.*",
|
||||
"css-inline==0.17.*",
|
||||
"defusedcsv>=1.1.0",
|
||||
"Django[argon2]==4.2.*,>=4.2.24",
|
||||
"django-bootstrap3==25.2",
|
||||
|
||||
@@ -800,7 +800,7 @@ class SalesChannelViewSet(viewsets.ModelViewSet):
|
||||
identifier=serializer.instance.identifier,
|
||||
)
|
||||
inst.log_action(
|
||||
'pretix.saleschannel.changed',
|
||||
'pretix.sales_channel.changed',
|
||||
user=self.request.user,
|
||||
auth=self.request.auth,
|
||||
data=self.request.data,
|
||||
|
||||
@@ -214,21 +214,38 @@ class PasswordRecoverForm(forms.Form):
|
||||
error_messages = {
|
||||
'pw_mismatch': _("Please enter the same password twice"),
|
||||
}
|
||||
email = forms.EmailField(
|
||||
max_length=255,
|
||||
disabled=True,
|
||||
label=_("Your email address"),
|
||||
widget=forms.EmailInput(
|
||||
attrs={'autocomplete': 'username'},
|
||||
),
|
||||
)
|
||||
password = forms.CharField(
|
||||
label=_('Password'),
|
||||
widget=forms.PasswordInput,
|
||||
widget=forms.PasswordInput(attrs={
|
||||
'autocomplete': 'new-password',
|
||||
}),
|
||||
max_length=4096,
|
||||
required=True
|
||||
)
|
||||
password_repeat = forms.CharField(
|
||||
label=_('Repeat password'),
|
||||
widget=forms.PasswordInput,
|
||||
widget=forms.PasswordInput(attrs={
|
||||
'autocomplete': 'new-password',
|
||||
}),
|
||||
max_length=4096,
|
||||
)
|
||||
|
||||
def __init__(self, user_id=None, *args, **kwargs):
|
||||
self.user_id = user_id
|
||||
super().__init__(*args, **kwargs)
|
||||
initial = kwargs.pop('initial', {})
|
||||
try:
|
||||
self.user = User.objects.get(id=user_id)
|
||||
initial['email'] = self.user.email
|
||||
except User.DoesNotExist:
|
||||
self.user = None
|
||||
super().__init__(*args, initial=initial, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
password1 = self.cleaned_data.get('password', '')
|
||||
@@ -243,11 +260,7 @@ class PasswordRecoverForm(forms.Form):
|
||||
|
||||
def clean_password(self):
|
||||
password1 = self.cleaned_data.get('password', '')
|
||||
try:
|
||||
user = User.objects.get(id=self.user_id)
|
||||
except User.DoesNotExist:
|
||||
user = None
|
||||
if validate_password(password1, user=user) is not None:
|
||||
if validate_password(password1, user=self.user) is not None:
|
||||
raise forms.ValidationError(_(password_validators_help_texts()), code='pw_invalid')
|
||||
return password1
|
||||
|
||||
@@ -307,3 +320,10 @@ class ReauthForm(forms.Form):
|
||||
self.error_messages['inactive'],
|
||||
code='inactive',
|
||||
)
|
||||
|
||||
|
||||
class ConfirmationCodeForm(forms.Form):
|
||||
code = forms.IntegerField(
|
||||
label=_('Confirmation code'),
|
||||
widget=forms.NumberInput(attrs={'class': 'confirmation-code-input', 'inputmode': 'numeric', 'type': 'text'}),
|
||||
)
|
||||
|
||||
@@ -39,37 +39,16 @@ from django.contrib.auth.password_validation import (
|
||||
password_validators_help_texts, validate_password,
|
||||
)
|
||||
from django.db.models import Q
|
||||
from django.urls.base import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from pytz import common_timezones
|
||||
|
||||
from pretix.base.models import User
|
||||
from pretix.control.forms import SingleLanguageWidget
|
||||
from pretix.helpers.format import format_map
|
||||
|
||||
|
||||
class UserSettingsForm(forms.ModelForm):
|
||||
error_messages = {
|
||||
'duplicate_identifier': _("There already is an account associated with this email address. "
|
||||
"Please choose a different one."),
|
||||
'pw_current': _("Please enter your current password if you want to change your email address "
|
||||
"or password."),
|
||||
'pw_current_wrong': _("The current password you entered was not correct."),
|
||||
'pw_mismatch': _("Please enter the same password twice"),
|
||||
'rate_limit': _("For security reasons, please wait 5 minutes before you try again."),
|
||||
'pw_equal': _("Please choose a password different to your current one.")
|
||||
}
|
||||
|
||||
old_pw = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("Your current password"),
|
||||
widget=forms.PasswordInput())
|
||||
new_pw = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("New password"),
|
||||
widget=forms.PasswordInput())
|
||||
new_pw_repeat = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("Repeat new password"),
|
||||
widget=forms.PasswordInput())
|
||||
timezone = forms.ChoiceField(
|
||||
choices=((a, a) for a in common_timezones),
|
||||
label=_("Default timezone"),
|
||||
@@ -93,11 +72,60 @@ class UserSettingsForm(forms.ModelForm):
|
||||
self.user = kwargs.pop('user')
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['email'].required = True
|
||||
if self.user.auth_backend != 'native':
|
||||
del self.fields['old_pw']
|
||||
del self.fields['new_pw']
|
||||
del self.fields['new_pw_repeat']
|
||||
self.fields['email'].disabled = True
|
||||
self.fields['email'].disabled = True
|
||||
self.fields['email'].help_text = format_map('<a href="{link}"><span class="fa fa-edit"></span> {text}</a>', {
|
||||
'text': _("Change email address"),
|
||||
'link': reverse('control:user.settings.email.change')
|
||||
})
|
||||
|
||||
|
||||
class User2FADeviceAddForm(forms.Form):
|
||||
name = forms.CharField(label=_('Device name'), max_length=64)
|
||||
devicetype = forms.ChoiceField(label=_('Device type'), widget=forms.RadioSelect, choices=(
|
||||
('totp', _('Smartphone with the Authenticator application')),
|
||||
('webauthn', _('WebAuthn-compatible hardware token (e.g. Yubikey)')),
|
||||
))
|
||||
|
||||
|
||||
class UserPasswordChangeForm(forms.Form):
|
||||
error_messages = {
|
||||
'pw_current': _("Please enter your current password if you want to change your email address "
|
||||
"or password."),
|
||||
'pw_current_wrong': _("The current password you entered was not correct."),
|
||||
'pw_mismatch': _("Please enter the same password twice"),
|
||||
'rate_limit': _("For security reasons, please wait 5 minutes before you try again."),
|
||||
'pw_equal': _("Please choose a password different to your current one.")
|
||||
}
|
||||
email = forms.EmailField(max_length=255,
|
||||
disabled=True,
|
||||
label=_("Your email address"),
|
||||
widget=forms.EmailInput(
|
||||
attrs={'autocomplete': 'username'},
|
||||
))
|
||||
old_pw = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("Your current password"),
|
||||
widget=forms.PasswordInput(
|
||||
attrs={'autocomplete': 'current-password'},
|
||||
))
|
||||
new_pw = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("New password"),
|
||||
widget=forms.PasswordInput(
|
||||
attrs={'autocomplete': 'new-password'},
|
||||
))
|
||||
new_pw_repeat = forms.CharField(max_length=255,
|
||||
required=False,
|
||||
label=_("Repeat new password"),
|
||||
widget=forms.PasswordInput(
|
||||
attrs={'autocomplete': 'new-password'},
|
||||
))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop('user')
|
||||
initial = kwargs.pop('initial', {})
|
||||
initial['email'] = self.user.email
|
||||
super().__init__(*args, initial=initial, **kwargs)
|
||||
|
||||
def clean_old_pw(self):
|
||||
old_pw = self.cleaned_data.get('old_pw')
|
||||
@@ -121,15 +149,6 @@ class UserSettingsForm(forms.ModelForm):
|
||||
|
||||
return old_pw
|
||||
|
||||
def clean_email(self):
|
||||
email = self.cleaned_data['email']
|
||||
if User.objects.filter(Q(email__iexact=email) & ~Q(pk=self.instance.pk)).exists():
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['duplicate_identifier'],
|
||||
code='duplicate_identifier',
|
||||
)
|
||||
return email
|
||||
|
||||
def clean_new_pw(self):
|
||||
password1 = self.cleaned_data.get('new_pw', '')
|
||||
if password1 and validate_password(password1, user=self.user) is not None:
|
||||
@@ -148,32 +167,24 @@ class UserSettingsForm(forms.ModelForm):
|
||||
code='pw_mismatch'
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
password1 = self.cleaned_data.get('new_pw')
|
||||
email = self.cleaned_data.get('email')
|
||||
old_pw = self.cleaned_data.get('old_pw')
|
||||
|
||||
if (password1 or email != self.user.email) and not old_pw:
|
||||
class UserEmailChangeForm(forms.Form):
|
||||
error_messages = {
|
||||
'duplicate_identifier': _("There already is an account associated with this email address. "
|
||||
"Please choose a different one."),
|
||||
}
|
||||
old_email = forms.EmailField(label=_('Old email address'), disabled=True)
|
||||
new_email = forms.EmailField(label=_('New email address'))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.user = kwargs.pop('user')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def clean_new_email(self):
|
||||
email = self.cleaned_data['new_email']
|
||||
if User.objects.filter(Q(email__iexact=email) & ~Q(pk=self.user.pk)).exists():
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['pw_current'],
|
||||
code='pw_current'
|
||||
self.error_messages['duplicate_identifier'],
|
||||
code='duplicate_identifier',
|
||||
)
|
||||
|
||||
if password1 and password1 == old_pw:
|
||||
raise forms.ValidationError(
|
||||
self.error_messages['pw_equal'],
|
||||
code='pw_equal'
|
||||
)
|
||||
|
||||
if password1:
|
||||
self.instance.set_password(password1)
|
||||
|
||||
return self.cleaned_data
|
||||
|
||||
|
||||
class User2FADeviceAddForm(forms.Form):
|
||||
name = forms.CharField(label=_('Device name'), max_length=64)
|
||||
devicetype = forms.ChoiceField(label=_('Device type'), widget=forms.RadioSelect, choices=(
|
||||
('totp', _('Smartphone with the Authenticator application')),
|
||||
('webauthn', _('WebAuthn-compatible hardware token (e.g. Yubikey)')),
|
||||
))
|
||||
return email
|
||||
|
||||
@@ -19,20 +19,15 @@
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
import json
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
from functools import cached_property
|
||||
from typing import Optional
|
||||
|
||||
import jsonschema
|
||||
from django.urls import reverse
|
||||
from django.utils.html import format_html
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from pretix.base.signals import PluginAwareRegistry
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def make_link(a_map, wrapper, is_active=True, event=None, plugin_name=None):
|
||||
if a_map:
|
||||
@@ -110,38 +105,12 @@ They are annotated with their ``action_type`` and the defining ``plugin``.
|
||||
log_entry_types = LogEntryTypeRegistry()
|
||||
|
||||
|
||||
def prepare_schema(schema):
|
||||
def handle_properties(t):
|
||||
return {"shred_properties": [k for k, v in t["properties"].items() if v["shred"]]}
|
||||
|
||||
def walk_tree(schema):
|
||||
if type(schema) is dict:
|
||||
new_keys = {}
|
||||
for k, v in schema.items():
|
||||
if k == "properties":
|
||||
new_keys = handle_properties(schema)
|
||||
walk_tree(v)
|
||||
if schema.get("type") == "object" and "additionalProperties" not in new_keys:
|
||||
new_keys["additionalProperties"] = False
|
||||
schema.update(new_keys)
|
||||
elif type(schema) is list:
|
||||
for v in schema:
|
||||
walk_tree(v)
|
||||
|
||||
walk_tree(schema)
|
||||
return schema
|
||||
|
||||
|
||||
class LogEntryType:
|
||||
"""
|
||||
Base class for a type of LogEntry, identified by its action_type.
|
||||
"""
|
||||
|
||||
data_schema = None # {"type": "object", "properties": []}
|
||||
|
||||
def __init__(self, action_type=None, plain=None):
|
||||
if self.data_schema:
|
||||
print(self.__class__.__name__, "has schema", self._prepared_schema)
|
||||
if action_type:
|
||||
self.action_type = action_type
|
||||
if plain:
|
||||
@@ -178,37 +147,12 @@ class LogEntryType:
|
||||
|
||||
object_link_wrapper = '{val}'
|
||||
|
||||
def validate_data(self, parsed_data):
|
||||
if not self._prepared_schema:
|
||||
return
|
||||
try:
|
||||
jsonschema.validate(parsed_data, self._prepared_schema)
|
||||
except jsonschema.exceptions.ValidationError as ex:
|
||||
logger.warning("%s schema validation failed: %s %s", type(self).__name__, ex.json_path, ex.message)
|
||||
raise
|
||||
|
||||
@cached_property
|
||||
def _prepared_schema(self):
|
||||
if self.data_schema:
|
||||
return prepare_schema(self.data_schema)
|
||||
|
||||
def shred_pii(self, logentry):
|
||||
"""
|
||||
To be used for shredding personally identified information contained in the data field of a LogEntry of this
|
||||
type.
|
||||
"""
|
||||
if self._prepared_schema:
|
||||
def shred_fun(validator, value, instance, schema):
|
||||
for key in value:
|
||||
instance[key] = "##########"
|
||||
|
||||
v = jsonschema.validators.extend(jsonschema.validators.Draft202012Validator,
|
||||
validators={"shred_properties": shred_fun})
|
||||
data = logentry.parsed_data
|
||||
jsonschema.validate(data, self._prepared_schema, v)
|
||||
logentry.data = json.dumps(data)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class NoOpShredderMixin:
|
||||
|
||||
18
src/pretix/base/migrations/0294_user_is_verified.py
Normal file
18
src/pretix/base/migrations/0294_user_is_verified.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2.23 on 2025-09-04 16:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0293_cartposition_price_includes_rounding_correction_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="is_verified",
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
]
|
||||
@@ -35,6 +35,7 @@
|
||||
import binascii
|
||||
import json
|
||||
import operator
|
||||
import secrets
|
||||
from datetime import timedelta
|
||||
from functools import reduce
|
||||
|
||||
@@ -44,6 +45,7 @@ from django.contrib.auth.models import (
|
||||
)
|
||||
from django.contrib.auth.tokens import default_token_generator
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import BadRequest, PermissionDenied
|
||||
from django.db import IntegrityError, models, transaction
|
||||
from django.db.models import Q
|
||||
from django.utils.crypto import get_random_string, salted_hmac
|
||||
@@ -239,9 +241,11 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
|
||||
|
||||
USERNAME_FIELD = 'email'
|
||||
REQUIRED_FIELDS = []
|
||||
MAX_CONFIRMATION_CODE_ATTEMPTS = 10
|
||||
|
||||
email = models.EmailField(unique=True, db_index=True, null=True, blank=True,
|
||||
verbose_name=_('Email'), max_length=190)
|
||||
is_verified = models.BooleanField(default=False, verbose_name=_('Verified email address'))
|
||||
fullname = models.CharField(max_length=255, blank=True, null=True,
|
||||
verbose_name=_('Full name'))
|
||||
is_active = models.BooleanField(default=True,
|
||||
@@ -353,6 +357,77 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
|
||||
except SendMailException:
|
||||
pass # Already logged
|
||||
|
||||
def send_confirmation_code(self, session, reason, email=None, state=None):
|
||||
"""
|
||||
Sends a confirmation code via email to the user. The code is only valid for the action specified by `reason`.
|
||||
The email is either sent to the email address currently on file for the user, or to the one given in the optional `email` parameter.
|
||||
A `state` value can be provided which is bound to this confirmation code, and returned on successfully checking the code.
|
||||
:param session: the user's request session
|
||||
:param reason: the action which should be confirmed using this confirmation code (currently, only `email_change` is allowed)
|
||||
:param email: optional, the email address to send the confirmation code to
|
||||
:param state: optional
|
||||
"""
|
||||
from pretix.base.services.mail import mail
|
||||
|
||||
with language(self.locale):
|
||||
if reason == 'email_change':
|
||||
msg = str(_('to confirm changing your email address from {old_email}\nto {new_email}, use the following code:').format(
|
||||
old_email=self.email, new_email=email,
|
||||
))
|
||||
elif reason == 'email_verify':
|
||||
msg = str(_('to confirm that your email address {email} belongs to your pretix account, use the following code:').format(
|
||||
email=self.email,
|
||||
))
|
||||
else:
|
||||
raise Exception('Invalid confirmation code reason')
|
||||
|
||||
code = "%07d" % secrets.SystemRandom().randint(0, 9999999)
|
||||
session['user_confirmation_code:' + reason] = {
|
||||
'code': code,
|
||||
'state': state,
|
||||
'attempts': 0,
|
||||
}
|
||||
mail(
|
||||
email or self.email,
|
||||
_('pretix confirmation code'),
|
||||
'pretixcontrol/email/confirmation_code.txt',
|
||||
{
|
||||
'user': self,
|
||||
'reason': msg,
|
||||
'code': code,
|
||||
},
|
||||
event=None,
|
||||
user=self,
|
||||
locale=self.locale
|
||||
)
|
||||
|
||||
def check_confirmation_code(self, session, reason, code):
|
||||
"""
|
||||
Checks a confirmation code entered by the user against the valid code stored in the session.
|
||||
If the code is correct, an optional state bound to the code is returned.
|
||||
If the code is incorrect, PermissionDenied is raised. If the code could not be validated, either because no
|
||||
code for the given reason is stored, or the number of input attempts is exceeded, BadRequest is raised.
|
||||
|
||||
:param session: the user's request session
|
||||
:param reason: the action which should be confirmed using this confirmation code
|
||||
:param code: the code entered by the user
|
||||
:return: optional state bound to this code using the state parameter of send_confirmation_code, None otherwise
|
||||
"""
|
||||
stored = session.get('user_confirmation_code:' + reason)
|
||||
if not stored:
|
||||
raise BadRequest
|
||||
|
||||
if stored['attempts'] > User.MAX_CONFIRMATION_CODE_ATTEMPTS:
|
||||
raise BadRequest
|
||||
|
||||
if int(stored['code']) == int(code):
|
||||
del session['user_confirmation_code:' + reason]
|
||||
return stored['state']
|
||||
else:
|
||||
stored['attempts'] += 1
|
||||
session['user_confirmation_code:' + reason] = stored
|
||||
raise PermissionDenied
|
||||
|
||||
def send_password_reset(self):
|
||||
from pretix.base.services.mail import mail
|
||||
|
||||
|
||||
@@ -80,7 +80,6 @@ class LoggingMixin:
|
||||
from pretix.api.models import OAuthAccessToken, OAuthApplication
|
||||
from pretix.api.webhooks import notify_webhooks
|
||||
|
||||
from ..logentrytype_registry import log_entry_types
|
||||
from ..services.notifications import notify
|
||||
from .devices import Device
|
||||
from .event import Event
|
||||
@@ -125,13 +124,7 @@ class LoggingMixin:
|
||||
if (sensitivekey in k) and v:
|
||||
data[k] = "********"
|
||||
|
||||
type, meta = log_entry_types.get(action_type=action)
|
||||
if not type:
|
||||
raise TypeError("Undefined log entry type '%s'" % action)
|
||||
|
||||
logentry.data = json.dumps(data, cls=CustomJSONEncoder, sort_keys=True)
|
||||
|
||||
type.validate_data(json.loads(logentry.data))
|
||||
elif data:
|
||||
raise TypeError("You should only supply dictionaries as log data.")
|
||||
if save:
|
||||
|
||||
@@ -1377,7 +1377,7 @@ class GiftCardPayment(BasePaymentProvider):
|
||||
execute_payment_needs_user = False
|
||||
verbose_name = _("Gift card")
|
||||
payment_form_class = GiftCardPaymentForm
|
||||
payment_form_template_name = 'pretixpresale/giftcard/checkout.html'
|
||||
payment_form_template_name = 'pretixcontrol/giftcards/checkout.html'
|
||||
|
||||
@cached_property
|
||||
def customer_gift_cards(self):
|
||||
@@ -1504,7 +1504,7 @@ class GiftCardPayment(BasePaymentProvider):
|
||||
return super().order_change_allowed(order) and self.event.organizer.has_gift_cards
|
||||
|
||||
def checkout_confirm_render(self, request, order=None, info_data=None) -> str:
|
||||
return get_template('pretixpresale/giftcard/checkout_confirm.html').render({
|
||||
return get_template('pretixcontrol/giftcards/checkout_confirm.html').render({
|
||||
'info_data': info_data,
|
||||
})
|
||||
|
||||
|
||||
@@ -258,15 +258,9 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
||||
if resp:
|
||||
desc += "<br/>" + resp
|
||||
|
||||
answers_qs = p.answers.filter(
|
||||
question__print_on_invoice=True
|
||||
).select_related(
|
||||
'question'
|
||||
).order_by(
|
||||
'question__position',
|
||||
'question__id'
|
||||
)
|
||||
for answ in answers_qs:
|
||||
for answ in p.answers.all():
|
||||
if not answ.question.print_on_invoice:
|
||||
continue
|
||||
desc += "<br />{}{} {}".format(
|
||||
answ.question.question,
|
||||
"" if str(answ.question.question).endswith("?") else ":",
|
||||
|
||||
@@ -69,6 +69,7 @@ class UserEditForm(forms.ModelForm):
|
||||
'email',
|
||||
'require_2fa',
|
||||
'is_active',
|
||||
'is_verified',
|
||||
'is_staff',
|
||||
'needs_password_change',
|
||||
'last_login'
|
||||
|
||||
@@ -503,6 +503,7 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl
|
||||
'pretix.event.order.valid_if_pending.set': _('The order has been set to be usable before it is paid.'),
|
||||
'pretix.event.order.valid_if_pending.unset': _('The order has been set to require payment before use.'),
|
||||
'pretix.event.order.expired': _('The order has been marked as expired.'),
|
||||
'pretix.event.order.paid': _('The order has been marked as paid.'),
|
||||
'pretix.event.order.cancellationrequest.deleted': _('The cancellation request has been deleted.'),
|
||||
'pretix.event.order.refunded': _('The order has been refunded.'),
|
||||
'pretix.event.order.reactivated': _('The order has been reactivated.'),
|
||||
@@ -534,7 +535,7 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl
|
||||
'pretix.event.order.checkin_attention': _('The order\'s flag to require attention at check-in has been '
|
||||
'toggled.'),
|
||||
'pretix.event.order.checkin_text': _('The order\'s check-in text has been changed.'),
|
||||
'pretix.event.order.valid_if_pending': _('The order\'s flag to be considered valid even if '
|
||||
'pretix.event.order.pretix.event.order.valid_if_pending': _('The order\'s flag to be considered valid even if '
|
||||
'unpaid has been toggled.'),
|
||||
'pretix.event.order.payment.changed': _('A new payment {local_id} has been started instead of the previous one.'),
|
||||
'pretix.event.order.email.sent': _('An unidentified type email has been sent.'),
|
||||
@@ -574,21 +575,6 @@ class CoreOrderLogEntryType(OrderLogEntryType):
|
||||
pass
|
||||
|
||||
|
||||
@log_entry_types.new()
|
||||
class OrderPaidLogEntryType(CoreOrderLogEntryType):
|
||||
action_type = 'pretix.event.order.paid'
|
||||
plain = _('The order has been marked as paid.')
|
||||
data_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"provider": {"type": ["null", "string"], "shred": False, },
|
||||
"info": {"type": ["null", "string", "object"], "shred": True, },
|
||||
"date": {"type": ["null", "string"], "shred": False, },
|
||||
"force": {"type": "boolean", "shred": False, },
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@log_entry_types.new_from_dict({
|
||||
'pretix.voucher.added': _('The voucher has been created.'),
|
||||
'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
|
||||
@@ -599,63 +585,13 @@ class OrderPaidLogEntryType(CoreOrderLogEntryType):
|
||||
'pretix.voucher.added.waitinglist': _('The voucher has been assigned to {email} through the waiting list.'),
|
||||
})
|
||||
class CoreVoucherLogEntryType(VoucherLogEntryType):
|
||||
data_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": {"type": ["null", "number"], "shred": False, },
|
||||
"variation": {"type": ["null", "number"], "shred": False, },
|
||||
"tag": {"type": "string", "shred": False,},
|
||||
"block_quota": {"type": "boolean", "shred": False, },
|
||||
"valid_until": {"type": ["null", "string"], "shred": False, },
|
||||
"min_usages": {"type": "number", "shred": False, },
|
||||
"max_usages": {"type": "number", "shred": False, },
|
||||
"subevent": {"type": ["null", "number", "object"], "shred": False, },
|
||||
"source": {"type": "string", "shred": False,},
|
||||
"allow_ignore_quota": {"type": "boolean", "shred": False, },
|
||||
"code": {"type": "string", "shred": False,},
|
||||
"comment": {"type": "string", "shred": True,},
|
||||
"price_mode": {"type": "string", "shred": False,},
|
||||
"seat": {"type": "string", "shred": False,},
|
||||
"quota": {"type": ["null", "number"], "shred": False,},
|
||||
"value": {"type": ["null", "string"], "shred": False,},
|
||||
"redeemed": {"type": "number", "shred": False,},
|
||||
"all_addons_included": {"type": "boolean", "shred": False, },
|
||||
"all_bundles_included": {"type": "boolean", "shred": False, },
|
||||
"budget": {"type": ["null", "number"], "shred": False, },
|
||||
"itemvar": {"type": "string", "shred": False,},
|
||||
"show_hidden_items": {"type": "boolean", "shred": False, },
|
||||
|
||||
# bulk create:
|
||||
"bulk": {"type": "boolean", "shred": False,},
|
||||
"seats": {"type": "array", "shred": False,},
|
||||
"send": {"type": ["string", "boolean"], "shred": False,},
|
||||
"send_recipients": {"type": "array", "shred": True,},
|
||||
"send_subject": {"type": "string", "shred": False,},
|
||||
"send_message": {"type": "string", "shred": True,},
|
||||
|
||||
# pretix.voucher.sent
|
||||
"recipient": {"type": "string", "shred": True,},
|
||||
"name": {"type": "string", "shred": True,},
|
||||
"subject": {"type": "string", "shred": False,},
|
||||
"message": {"type": "string", "shred": True,},
|
||||
|
||||
# pretix.voucher.added.waitinglist
|
||||
"email": {"type": "string", "shred": True,},
|
||||
"waitinglistentry": {"type": "number", "shred": False, },
|
||||
},
|
||||
}
|
||||
pass
|
||||
|
||||
|
||||
@log_entry_types.new()
|
||||
class VoucherRedeemedLogEntryType(VoucherLogEntryType):
|
||||
action_type = 'pretix.voucher.redeemed'
|
||||
plain = _('The voucher has been redeemed in order {order_code}.')
|
||||
data_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"order_code": {"type": "string", "shred": False, },
|
||||
},
|
||||
}
|
||||
|
||||
def display(self, logentry, data):
|
||||
url = reverse('control:event.order', kwargs={
|
||||
@@ -698,16 +634,9 @@ class TeamMembershipLogEntryType(LogEntryType):
|
||||
'pretix.team.member.removed': _('{user} has been removed from the team.'),
|
||||
'pretix.team.invite.created': _('{user} has been invited to the team.'),
|
||||
'pretix.team.invite.resent': _('Invite for {user} has been resent.'),
|
||||
'pretix.team.invite.deleted': _('Invite for {user} has been deleted.'),
|
||||
})
|
||||
class CoreTeamMembershipLogEntryType(TeamMembershipLogEntryType):
|
||||
data_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {"type": "string", "shred": True, },
|
||||
"user": {"type": "number", "shred": False, },
|
||||
},
|
||||
}
|
||||
pass
|
||||
|
||||
|
||||
@log_entry_types.new()
|
||||
@@ -738,6 +667,14 @@ class UserSettingsChangedLogEntryType(LogEntryType):
|
||||
return text
|
||||
|
||||
|
||||
@log_entry_types.new_from_dict({
|
||||
'pretix.user.email.changed': _('Your email address has been changed from {old_email} to {email}.'),
|
||||
'pretix.user.email.confirmed': _('Your email address {email} has been confirmed.'),
|
||||
})
|
||||
class UserEmailChangedLogEntryType(LogEntryType):
|
||||
pass
|
||||
|
||||
|
||||
class UserImpersonatedLogEntryType(LogEntryType):
|
||||
def display(self, logentry, data):
|
||||
return self.plain.format(data['other_email'])
|
||||
@@ -904,10 +841,6 @@ class OrganizerPluginStateLogEntryType(LogEntryType):
|
||||
'pretix.event.permissions.invited': _('A user has been invited to the event team.'),
|
||||
'pretix.event.permissions.changed': _('A user\'s permissions have been changed.'),
|
||||
'pretix.event.permissions.deleted': _('A user has been removed from the event team.'),
|
||||
'pretix.event.seats.blocks.changed': _('A seat in the seating plan has been blocked or unblocked.'),
|
||||
'pretix.seatingplan.added': _('A seating plan has been added.'),
|
||||
'pretix.seatingplan.changed': _('A seating plan has been changed.'),
|
||||
'pretix.seatingplan.deleted': _('A seating plan has been deleted.'),
|
||||
})
|
||||
class CoreEventLogEntryType(EventLogEntryType):
|
||||
pass
|
||||
|
||||
@@ -72,7 +72,7 @@ class PermissionMiddleware:
|
||||
)
|
||||
|
||||
EXCEPTIONS_FORCED_PW_CHANGE = (
|
||||
"user.settings",
|
||||
"user.settings.password.change",
|
||||
"auth.logout"
|
||||
)
|
||||
|
||||
@@ -139,7 +139,7 @@ class PermissionMiddleware:
|
||||
return redirect_to_url(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
|
||||
except SessionPasswordChangeRequired:
|
||||
if url_name not in self.EXCEPTIONS_FORCED_PW_CHANGE:
|
||||
return redirect_to_url(reverse('control:user.settings') + '?next=' + quote(request.get_full_path()))
|
||||
return redirect_to_url(reverse('control:user.settings.password.change') + '?next=' + quote(request.get_full_path()))
|
||||
except Session2FASetupRequired:
|
||||
if url_name not in self.EXCEPTIONS_2FA:
|
||||
return redirect_to_url(reverse('control:user.settings.2fa'))
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<h3>{% trans "Set new password" %}</h3>
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form type='all' layout='inline' %}
|
||||
{% bootstrap_field form.email %}
|
||||
{% bootstrap_field form.password %}
|
||||
{% bootstrap_field form.password_repeat %}
|
||||
<div class="form-group buttons">
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{% load i18n %}{% blocktrans with url=url|safe messages=messages|safe %}Hello,
|
||||
|
||||
{{ reason }}
|
||||
|
||||
{{ code }}
|
||||
|
||||
Please do never give this code to another person. Our support team will never ask for this code.
|
||||
|
||||
If this code was not requested by you, please contact us immediately.
|
||||
|
||||
Best regards,
|
||||
Your pretix team
|
||||
{% endblocktrans %}
|
||||
@@ -0,0 +1,35 @@
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load money %}
|
||||
{% load rich_text %}
|
||||
|
||||
{{ request.event.settings.payment_giftcard_public_description|rich_text }}
|
||||
{% if customer_gift_cards %}
|
||||
<p><strong>
|
||||
<span class="sr-only">{% trans "Information" %}</span>
|
||||
{% trans "The following gift cards are available in your customer account:" %}
|
||||
</strong></p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<ul class="list-group">
|
||||
{% for c in customer_gift_cards %}
|
||||
<li class="list-group-item row row-no-gutters">
|
||||
<div class="col-sm-8 col-md-9" id="gc-code-{{ forloop.counter }}">
|
||||
{{ c }}
|
||||
</div>
|
||||
<div class="col-sm-2 text-right" id="gc-value-{{ forloop.counter }}">
|
||||
{{ c.value|money:c.currency }}
|
||||
</div>
|
||||
<div class="col-sm-2 col-md-1 text-right">
|
||||
<button name="use_giftcard" class="btn btn-primary btn-xs use_giftcard" data-value="{{ c.secret }}"
|
||||
title="{% trans "Use gift card" %}"
|
||||
aria-describedby="gc-code-{{ forloop.counter }} gc-value-{{ forloop.counter }}">
|
||||
{% trans "Apply" %}
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% bootstrap_form form layout='checkout' %}
|
||||
@@ -769,12 +769,10 @@
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-6 col-md-offset-5 price">
|
||||
<strong>{{ items.total|money:event.currency }}</strong>
|
||||
{% if django_settings.DEBUG %}
|
||||
<br/>
|
||||
<small class="admin-only">
|
||||
tax_rounding_mode = {{ order.tax_rounding_mode }}
|
||||
</small>
|
||||
{% endif %}
|
||||
<br/>
|
||||
<small class="admin-only">
|
||||
tax_rounding_mode = {{ order.tax_rounding_mode }}
|
||||
</small>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
{% extends "pretixcontrol/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Change login email address" %}{% endblock %}
|
||||
{% block content %}
|
||||
<form action="" method="post" class="form centered-form">
|
||||
<h1>
|
||||
{% trans "Change login email address" %}
|
||||
</h1>
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form %}
|
||||
<p class="text-muted">
|
||||
{% trans "This changes the email address used to login to your account, as well as where we send email notifications." %}
|
||||
</p>
|
||||
{% bootstrap_field form.old_email %}
|
||||
{% bootstrap_field form.new_email %}
|
||||
<p>
|
||||
{% trans "We will send a confirmation code to your new email address, which you need to enter in the next step to confirm the email address is correct." %}
|
||||
</p>
|
||||
<div class="form-group submit-group">
|
||||
<a href="{% url "control:user.settings" %}" class="btn btn-default btn-cancel">
|
||||
{% trans "Cancel" %}
|
||||
</a>
|
||||
<button type="submit" class="btn btn-primary btn-save btn-lg">
|
||||
{% trans "Continue" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,24 @@
|
||||
{% extends "pretixcontrol/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Change password" %}{% endblock %}
|
||||
{% block content %}
|
||||
<form action="" method="post" class="form centered-form">
|
||||
<h1>
|
||||
{% trans "Change password" %}
|
||||
</h1>
|
||||
<br>
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form %}
|
||||
{% bootstrap_field form.email %}
|
||||
{% bootstrap_field form.old_pw %}
|
||||
{% bootstrap_field form.new_pw %}
|
||||
{% bootstrap_field form.new_pw_repeat %}
|
||||
<div class="form-group submit-group">
|
||||
<a href="{% url "control:user.settings" %}" class="btn btn-default btn-cancel">{% trans "Cancel" %}</a>
|
||||
<button type="submit" class="btn btn-primary btn-save btn-lg">
|
||||
{% trans "Change password" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% extends "pretixcontrol/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Enter confirmation code" %}{% endblock %}
|
||||
{% block content %}
|
||||
<form action="" method="post" class="form centered-form">
|
||||
<h1>
|
||||
{% trans "Enter confirmation code" %}
|
||||
</h1>
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form type='all' layout='inline' %}
|
||||
<p>{{ message }}</p>
|
||||
{% bootstrap_field form.code %}
|
||||
<div class="form-group submit-group">
|
||||
<a href="{{ cancel_url }}" class="btn btn-default btn-cancel">{% trans "Cancel" %}</a>
|
||||
<button type="submit" class="btn btn-primary btn-save btn-lg">
|
||||
{% trans "Continue" %}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -3,8 +3,26 @@
|
||||
{% load bootstrap3 %}
|
||||
{% block title %}{% trans "Account settings" %}{% endblock %}
|
||||
{% block content %}
|
||||
{% if not user.is_verified %}
|
||||
<div class="alert alert-info">
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Your email address is not confirmed yet. To secure your account, please confirm your email address using
|
||||
a confirmation code we will send to your email address.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
<form action="{% url "control:user.settings.email.send_verification_code" %}" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-primary">
|
||||
{% trans "Send confirmation email" %}
|
||||
</button>
|
||||
</form>
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<h1>{% trans "Account settings" %}</h1>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
<form action="" method="post" class="form-horizontal" data-testid="usersettingsform">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form_errors form %}
|
||||
<fieldset>
|
||||
@@ -13,7 +31,7 @@
|
||||
{% bootstrap_field form.locale layout='horizontal' %}
|
||||
{% bootstrap_field form.timezone layout='horizontal' %}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label" for="id_new_pw_repeat">{% trans "Notifications" %}</label>
|
||||
<label class="col-md-3 control-label">{% trans "Notifications" %}</label>
|
||||
<div class="col-md-9 static-form-row">
|
||||
{% if request.user.notifications_send and request.user.notification_settings.exists %}
|
||||
<span class="label label-success">
|
||||
@@ -41,8 +59,18 @@
|
||||
{% bootstrap_field form.new_pw layout='horizontal' %}
|
||||
{% bootstrap_field form.new_pw_repeat layout='horizontal' %}
|
||||
{% endif %}
|
||||
{% if user.auth_backend == 'native' %}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label">{% trans "Password" %}</label>
|
||||
<div class="col-md-9 static-form-row">
|
||||
<a href="{% url "control:user.settings.password.change" %}">
|
||||
<span class="fa fa-edit"></span> {% trans "Change password" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label" for="id_new_pw_repeat">{% trans "Two-factor authentication" %}</label>
|
||||
<label class="col-md-3 control-label">{% trans "Two-factor authentication" %}</label>
|
||||
<div class="col-md-9 static-form-row">
|
||||
{% if user.require_2fa %}
|
||||
<span class="label label-success">{% trans "Enabled" %}</span>
|
||||
@@ -58,7 +86,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label" for="">{% trans "Authorized applications" %}</label>
|
||||
<label class="col-md-3 control-label">{% trans "Authorized applications" %}</label>
|
||||
<div class="col-md-9 static-form-row">
|
||||
<a href="{% url "control:user.settings.oauth.list" %}">
|
||||
<span class="fa fa-plug"></span>
|
||||
@@ -67,7 +95,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label" for="">{% trans "Account history" %}</label>
|
||||
<label class="col-md-3 control-label">{% trans "Account history" %}</label>
|
||||
<div class="col-md-9 static-form-row">
|
||||
<a href="{% url "control:user.settings.history" %}">
|
||||
<span class="fa fa-history"></span>
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
{% if form.new_pw %}
|
||||
{% bootstrap_field form.new_pw layout='control' %}
|
||||
{% bootstrap_field form.new_pw_repeat layout='control' %}
|
||||
{% bootstrap_field form.is_verified layout='control' %}
|
||||
{% endif %}
|
||||
{% bootstrap_field form.last_login layout='control' %}
|
||||
{% bootstrap_field form.require_2fa layout='control' %}
|
||||
|
||||
@@ -110,6 +110,10 @@ urlpatterns = [
|
||||
name='user.settings.2fa.confirm.webauthn'),
|
||||
re_path(r'^settings/2fa/(?P<devicetype>[^/]+)/(?P<device>[0-9]+)/delete', user.User2FADeviceDeleteView.as_view(),
|
||||
name='user.settings.2fa.delete'),
|
||||
re_path(r'^settings/email/confirm$', user.UserEmailConfirmView.as_view(), name='user.settings.email.confirm'),
|
||||
re_path(r'^settings/email/change$', user.UserEmailChangeView.as_view(), name='user.settings.email.change'),
|
||||
re_path(r'^settings/email/verify', user.UserEmailVerifyView.as_view(), name='user.settings.email.send_verification_code'),
|
||||
re_path(r'^settings/password/change$', user.UserPasswordChangeView.as_view(), name='user.settings.password.change'),
|
||||
re_path(r'^organizers/$', organizer.OrganizerList.as_view(), name='organizers'),
|
||||
re_path(r'^organizers/add$', organizer.OrganizerCreate.as_view(), name='organizers.add'),
|
||||
re_path(r'^organizers/select2$', typeahead.organizer_select2, name='organizers.select2'),
|
||||
|
||||
@@ -44,11 +44,13 @@ from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth import update_session_auth_hash
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import BadRequest, PermissionDenied
|
||||
from django.db import transaction
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import format_html
|
||||
from django.utils.http import url_has_allowed_host_and_scheme
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -60,8 +62,11 @@ from django_scopes import scopes_disabled
|
||||
from webauthn.helpers import generate_challenge, generate_user_handle
|
||||
|
||||
from pretix.base.auth import get_auth_backends
|
||||
from pretix.base.forms.auth import ReauthForm
|
||||
from pretix.base.forms.user import User2FADeviceAddForm, UserSettingsForm
|
||||
from pretix.base.forms.auth import ConfirmationCodeForm, ReauthForm
|
||||
from pretix.base.forms.user import (
|
||||
User2FADeviceAddForm, UserEmailChangeForm, UserPasswordChangeForm,
|
||||
UserSettingsForm,
|
||||
)
|
||||
from pretix.base.models import (
|
||||
Event, LogEntry, NotificationSetting, U2FDevice, User, WebAuthnDevice,
|
||||
)
|
||||
@@ -237,25 +242,7 @@ class UserSettings(UpdateView):
|
||||
|
||||
data = {}
|
||||
for k in form.changed_data:
|
||||
if k not in ('old_pw', 'new_pw_repeat'):
|
||||
if 'new_pw' == k:
|
||||
data['new_pw'] = True
|
||||
else:
|
||||
data[k] = form.cleaned_data[k]
|
||||
|
||||
msgs = []
|
||||
|
||||
if 'new_pw' in form.changed_data:
|
||||
self.request.user.needs_password_change = False
|
||||
msgs.append(_('Your password has been changed.'))
|
||||
|
||||
if 'email' in form.changed_data:
|
||||
msgs.append(_('Your email address has been changed to {email}.').format(email=form.cleaned_data['email']))
|
||||
|
||||
if msgs:
|
||||
self.request.user.send_security_notice(msgs, email=form.cleaned_data['email'])
|
||||
if self._old_email != form.cleaned_data['email']:
|
||||
self.request.user.send_security_notice(msgs, email=self._old_email)
|
||||
data[k] = form.cleaned_data[k]
|
||||
|
||||
sup = super().form_valid(form)
|
||||
self.request.user.log_action('pretix.user.settings.changed', user=self.request.user, data=data)
|
||||
@@ -834,3 +821,159 @@ class EditStaffSession(StaffMemberRequiredMixin, UpdateView):
|
||||
return get_object_or_404(StaffSession, pk=self.kwargs['id'])
|
||||
else:
|
||||
return get_object_or_404(StaffSession, pk=self.kwargs['id'], user=self.request.user)
|
||||
|
||||
|
||||
class UserPasswordChangeView(FormView):
|
||||
max_time = 300
|
||||
|
||||
form_class = UserPasswordChangeForm
|
||||
template_name = 'pretixcontrol/user/change_password.html'
|
||||
|
||||
def get_form_kwargs(self):
|
||||
if self.request.user.auth_backend != 'native':
|
||||
raise PermissionDenied
|
||||
|
||||
return {
|
||||
**super().get_form_kwargs(),
|
||||
"user": self.request.user,
|
||||
}
|
||||
|
||||
def form_valid(self, form):
|
||||
with transaction.atomic():
|
||||
self.request.user.set_password(form.cleaned_data['new_pw'])
|
||||
self.request.user.needs_password_change = False
|
||||
self.request.user.save()
|
||||
msgs = []
|
||||
msgs.append(_('Your password has been changed.'))
|
||||
self.request.user.send_security_notice(msgs)
|
||||
|
||||
self.request.user.log_action('pretix.user.settings.changed', user=self.request.user, data={'new_pw': True})
|
||||
|
||||
update_session_auth_hash(self.request, self.request.user)
|
||||
|
||||
messages.success(self.request, _('Your changes have been saved.'))
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
def form_invalid(self, form):
|
||||
messages.error(self.request, _('We could not save your changes. See below for details.'))
|
||||
return super().form_invalid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
if "next" in self.request.GET and url_has_allowed_host_and_scheme(self.request.GET.get("next"), allowed_hosts=None):
|
||||
return self.request.GET.get("next")
|
||||
return reverse('control:user.settings')
|
||||
|
||||
|
||||
class UserEmailChangeView(RecentAuthenticationRequiredMixin, FormView):
|
||||
max_time = 300
|
||||
|
||||
form_class = UserEmailChangeForm
|
||||
template_name = 'pretixcontrol/user/change_email.html'
|
||||
|
||||
def get_form_kwargs(self):
|
||||
if self.request.user.auth_backend != 'native':
|
||||
raise PermissionDenied
|
||||
|
||||
return {
|
||||
**super().get_form_kwargs(),
|
||||
"user": self.request.user,
|
||||
}
|
||||
|
||||
def get_initial(self):
|
||||
return {
|
||||
"old_email": self.request.user.email
|
||||
}
|
||||
|
||||
def form_valid(self, form):
|
||||
self.request.user.send_confirmation_code(
|
||||
session=self.request.session,
|
||||
reason='email_change',
|
||||
email=form.cleaned_data['new_email'],
|
||||
state=form.cleaned_data['new_email'],
|
||||
)
|
||||
self.request.session['email_confirmation_destination'] = form.cleaned_data['new_email']
|
||||
return redirect(reverse('control:user.settings.email.confirm', kwargs={}) + '?reason=email_change')
|
||||
|
||||
def form_invalid(self, form):
|
||||
messages.error(self.request, _('We could not save your changes. See below for details.'))
|
||||
return super().form_invalid(form)
|
||||
|
||||
|
||||
class UserEmailVerifyView(View):
|
||||
def post(self, request, *args, **kwargs):
|
||||
if self.request.user.is_verified:
|
||||
messages.success(self.request, _('Your email address was already verified.'))
|
||||
return redirect(reverse('control:user.settings', kwargs={}))
|
||||
|
||||
self.request.user.send_confirmation_code(
|
||||
session=self.request.session,
|
||||
reason='email_verify',
|
||||
email=self.request.user.email,
|
||||
state=self.request.user.email,
|
||||
)
|
||||
self.request.session['email_confirmation_destination'] = self.request.user.email
|
||||
return redirect(reverse('control:user.settings.email.confirm', kwargs={}) + '?reason=email_verify')
|
||||
|
||||
|
||||
class UserEmailConfirmView(FormView):
|
||||
form_class = ConfirmationCodeForm
|
||||
template_name = 'pretixcontrol/user/confirmation_code_dialog.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
return {
|
||||
**super().get_context_data(**kwargs),
|
||||
"cancel_url": reverse('control:user.settings', kwargs={}),
|
||||
"message": format_html(
|
||||
_("Please enter the confirmation code we sent to your email address <strong>{email}</strong>."),
|
||||
email=self.request.session.get('email_confirmation_destination', ''),
|
||||
),
|
||||
}
|
||||
|
||||
@transaction.atomic()
|
||||
def form_valid(self, form):
|
||||
reason = self.request.GET['reason']
|
||||
if reason not in ('email_change', 'email_verify'):
|
||||
raise PermissionDenied
|
||||
try:
|
||||
new_email = self.request.user.check_confirmation_code(
|
||||
session=self.request.session,
|
||||
reason=reason,
|
||||
code=form.cleaned_data['code'],
|
||||
)
|
||||
except PermissionDenied:
|
||||
return self.form_invalid(form)
|
||||
except BadRequest:
|
||||
messages.error(self.request, _(
|
||||
'We were unable to verify your confirmation code. Please try again.'
|
||||
))
|
||||
return redirect(reverse('control:user.settings', kwargs={}))
|
||||
|
||||
log_data = {
|
||||
'email': new_email,
|
||||
'email_verified': True,
|
||||
}
|
||||
if reason == 'email_change':
|
||||
msgs = []
|
||||
msgs.append(_('Your email address has been changed to {email}.').format(email=new_email))
|
||||
log_data['old_email'] = old_email = self.request.user.email
|
||||
self.request.user.send_security_notice(msgs, email=old_email)
|
||||
self.request.user.send_security_notice(msgs, email=new_email)
|
||||
log_action = 'pretix.user.email.changed'
|
||||
else:
|
||||
log_action = 'pretix.user.email.confirmed'
|
||||
|
||||
self.request.user.email = new_email
|
||||
self.request.user.is_verified = True
|
||||
self.request.user.save()
|
||||
self.request.user.log_action(log_action, user=self.request.user, data=log_data)
|
||||
update_session_auth_hash(self.request, self.request.user)
|
||||
|
||||
if reason == 'email_change':
|
||||
messages.success(self.request, _('Your email address has been changed successfully.'))
|
||||
else:
|
||||
messages.success(self.request, _('Your email address has been confirmed successfully.'))
|
||||
return redirect(reverse('control:user.settings', kwargs={}))
|
||||
|
||||
def form_invalid(self, form):
|
||||
messages.error(self.request, _('The entered confirmation code is not correct. Please try again.'))
|
||||
return super().form_invalid(form)
|
||||
|
||||
@@ -8,10 +8,10 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-29 07:55+0000\n"
|
||||
"PO-Revision-Date: 2025-10-31 17:00+0000\n"
|
||||
"PO-Revision-Date: 2025-10-28 17:00+0000\n"
|
||||
"Last-Translator: Núria Masclans <nuriamasclansserrat@gmail.com>\n"
|
||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/"
|
||||
"pretix-js/ca/>\n"
|
||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
"js/ca/>\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -651,8 +651,6 @@ msgid ""
|
||||
"Your color has insufficient contrast to white. Accessibility of your site "
|
||||
"will be impacted."
|
||||
msgstr ""
|
||||
"El color no té prou contrast amb el blanc i pot afectar a l'accessibilitat "
|
||||
"del lloc web."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:418
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:438
|
||||
@@ -714,226 +712,229 @@ msgstr[0] "(una data més)"
|
||||
msgstr[1] "({num} dates més)"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:47
|
||||
#, fuzzy
|
||||
#| msgid "The items in your cart are no longer reserved for you."
|
||||
msgid ""
|
||||
"The items in your cart are no longer reserved for you. You can still "
|
||||
"complete your order as long as they’re available."
|
||||
msgstr ""
|
||||
"Ja no tens reservat el contingut de la cistella. Encara pots completar la "
|
||||
"comanda si els articles seleccionats continuen disponibles."
|
||||
msgstr "El contingut de la cistella ja no el teniu reservat."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:49
|
||||
msgid "Cart expired"
|
||||
msgstr "Cistella caducada"
|
||||
msgstr "Cistella expirada"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:58
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:84
|
||||
msgid "Your cart is about to expire."
|
||||
msgstr "La teva cistella està a punt de caducar."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:62
|
||||
#, fuzzy
|
||||
#| msgid "The items in your cart are no longer reserved for you."
|
||||
msgid "The items in your cart are reserved for you for one minute."
|
||||
msgid_plural "The items in your cart are reserved for you for {num} minutes."
|
||||
msgstr[0] "El contingut de la teva cistella està reservat durant un minut."
|
||||
msgstr[1] "El contingut de la teva cistella està reservat durant {num} minuts."
|
||||
msgstr[0] "El contingut de la cistella ja no el teniu reservat."
|
||||
msgstr[1] "El contingut de la cistella ja no el teniu reservat."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:83
|
||||
#, fuzzy
|
||||
#| msgid "Cart expired"
|
||||
msgid "Your cart has expired."
|
||||
msgstr "La teva cistella ha caducat."
|
||||
msgstr "Cistella expirada"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:86
|
||||
#, fuzzy
|
||||
#| msgid "The items in your cart are no longer reserved for you."
|
||||
msgid ""
|
||||
"The items in your cart are no longer reserved for you. You can still "
|
||||
"complete your order as long as they're available."
|
||||
msgstr ""
|
||||
"Ja no teniu reservat el contingut de la cistella. Encara podeu completar la "
|
||||
"comanda si els articles continuen disponibles."
|
||||
msgstr "El contingut de la cistella ja no el teniu reservat."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:87
|
||||
msgid "Do you want to renew the reservation period?"
|
||||
msgstr "Vols ampliar el temps de reserva?"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:90
|
||||
msgid "Renew reservation"
|
||||
msgstr "Renovar reserva"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:194
|
||||
msgid "The organizer keeps %(currency)s %(amount)s"
|
||||
msgstr "L'entitat organitzadora es queda %(currency)s %(amount)s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:202
|
||||
msgid "You get %(currency)s %(amount)s back"
|
||||
msgstr "Rebràs %(currency)s %(amount)s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:218
|
||||
msgid "Please enter the amount the organizer can keep."
|
||||
msgstr "Introdueix l’import que es queda l’organitzador."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:570
|
||||
msgid "Your local time:"
|
||||
msgstr "La teva hora local:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/walletdetection.js:39
|
||||
#, fuzzy
|
||||
msgid "Google Pay"
|
||||
msgstr "Google Pay"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:16
|
||||
msgctxt "widget"
|
||||
msgid "Quantity"
|
||||
msgstr "Quantitat"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:17
|
||||
msgctxt "widget"
|
||||
msgid "Decrease quantity"
|
||||
msgstr "Disminueix quantitat"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:18
|
||||
msgctxt "widget"
|
||||
msgid "Increase quantity"
|
||||
msgstr "Augmenta quantitat"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:19
|
||||
msgctxt "widget"
|
||||
msgid "Filter events by"
|
||||
msgstr "Filtra els esdeveniments per"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:20
|
||||
msgctxt "widget"
|
||||
msgid "Filter"
|
||||
msgstr "Filtra"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:21
|
||||
msgctxt "widget"
|
||||
msgid "Price"
|
||||
msgstr "Preu"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:22
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "Original price: %s"
|
||||
msgstr "Preu original: %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:23
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "New price: %s"
|
||||
msgstr "Nou preu: %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:24
|
||||
msgctxt "widget"
|
||||
msgid "Select"
|
||||
msgstr "Selecciona"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:25
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "Select %s"
|
||||
msgstr "Selecciona %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:26
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "Select variant %s"
|
||||
msgstr "Selecciona la variant %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:27
|
||||
msgctxt "widget"
|
||||
msgid "Sold out"
|
||||
msgstr "Esgotat"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:28
|
||||
msgctxt "widget"
|
||||
msgid "Buy"
|
||||
msgstr "Compra"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:29
|
||||
msgctxt "widget"
|
||||
msgid "Register"
|
||||
msgstr "Registrar-vos"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:30
|
||||
msgctxt "widget"
|
||||
msgid "Reserved"
|
||||
msgstr "Reservat"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:31
|
||||
msgctxt "widget"
|
||||
msgid "FREE"
|
||||
msgstr "GRATUÏT"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:32
|
||||
msgctxt "widget"
|
||||
msgid "from %(currency)s %(price)s"
|
||||
msgstr "des de %(price)s %(currency)s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:33
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "Image of %s"
|
||||
msgstr "Imatge de %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:34
|
||||
msgctxt "widget"
|
||||
msgid "incl. %(rate)s% %(taxname)s"
|
||||
msgstr "Inclòs %(rate)s% %(taxname)s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:35
|
||||
msgctxt "widget"
|
||||
msgid "plus %(rate)s% %(taxname)s"
|
||||
msgstr "més %(rate)s% %(taxname)s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:36
|
||||
msgctxt "widget"
|
||||
msgid "incl. taxes"
|
||||
msgstr "incl. impostos"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:37
|
||||
msgctxt "widget"
|
||||
msgid "plus taxes"
|
||||
msgstr "més impostos"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:38
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "currently available: %s"
|
||||
msgstr "disponibles: %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:39
|
||||
msgctxt "widget"
|
||||
msgid "Only available with a voucher"
|
||||
msgstr "Només disponible amb un cupó"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:40
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:43
|
||||
msgctxt "widget"
|
||||
msgid "Not yet available"
|
||||
msgstr "Encara no disponible"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:41
|
||||
msgctxt "widget"
|
||||
msgid "Not available anymore"
|
||||
msgstr "Ja no està disponible"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:42
|
||||
msgctxt "widget"
|
||||
msgid "Currently not available"
|
||||
msgstr "No disponible"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:44
|
||||
#, javascript-format
|
||||
msgctxt "widget"
|
||||
msgid "minimum amount to order: %s"
|
||||
msgstr "Comanda mínima: %s"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:45
|
||||
msgctxt "widget"
|
||||
msgid "Close ticket shop"
|
||||
msgstr "Tanca la botiga d'entrades"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:46
|
||||
msgctxt "widget"
|
||||
msgid "The ticket shop could not be loaded."
|
||||
msgstr "No s'ha pogut carregar la botiga d'entrades."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:47
|
||||
msgctxt "widget"
|
||||
|
||||
@@ -5,7 +5,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-30 10:55+0000\n"
|
||||
"PO-Revision-Date: 2025-10-30 20:00+0000\n"
|
||||
"PO-Revision-Date: 2025-10-29 09:24+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/de/"
|
||||
">\n"
|
||||
@@ -9664,15 +9664,15 @@ msgstr "Der Gutschein wurde an {recipient} verschickt."
|
||||
|
||||
#: pretix/base/settings.py:81
|
||||
msgid "Compute taxes for every line individually"
|
||||
msgstr "Berechne Steuern für jede Position einzeln"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:82
|
||||
msgid "Compute taxes based on net total"
|
||||
msgstr "Berechne Steuern auf Basis der Nettosumme"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:83
|
||||
msgid "Compute taxes based on net total with stable gross prices"
|
||||
msgstr "Berechne Steuern auf Basis der Nettosumme mit konstanten Bruttopreisen"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:133
|
||||
msgid "Allow usage of restricted plugins"
|
||||
@@ -9762,8 +9762,13 @@ msgid "Add-on products will not be counted."
|
||||
msgstr "Zusatzprodukte werden nicht mitgezählt."
|
||||
|
||||
#: pretix/base/settings.py:334
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Show net prices instead of gross prices in the product list (not "
|
||||
#| "recommended!)"
|
||||
msgid "Show net prices instead of gross prices in the product list"
|
||||
msgstr "Zeigen Nettopreise statt Bruttopreisen in der Produktliste"
|
||||
msgstr ""
|
||||
"Zeige Netto- statt Bruttopreisen in den Produktlisten (nicht empfohlen)"
|
||||
|
||||
#: pretix/base/settings.py:335
|
||||
msgid ""
|
||||
@@ -9880,8 +9885,10 @@ msgid "Require a phone number per order"
|
||||
msgstr "Telefonnummer pro Bestellung erfordern"
|
||||
|
||||
#: pretix/base/settings.py:481
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Rounding of taxes"
|
||||
msgstr "Rundung der Steuern"
|
||||
msgstr "inklusive aller Steuern"
|
||||
|
||||
#: pretix/base/settings.py:485
|
||||
msgid ""
|
||||
@@ -9889,10 +9896,6 @@ msgid ""
|
||||
"for tax reporting, you need to make sure to account for possible rounding "
|
||||
"differences if your external system rounds differently than pretix."
|
||||
msgstr ""
|
||||
"Bitte beachten Sie, dass bei der Übertragung der Verkaufsdaten in ein "
|
||||
"externes Buchhaltungssystem darauf geachtet werden muss, dass potentielle "
|
||||
"Rundungsabweichungen behandelt werden, wenn das externe System anders rundet "
|
||||
"als pretix."
|
||||
|
||||
#: pretix/base/settings.py:500
|
||||
msgid "Ask for invoice address"
|
||||
@@ -14034,24 +14037,31 @@ msgstr ""
|
||||
"Ausstellung ablaufen."
|
||||
|
||||
#: pretix/control/forms/event.py:806
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Prices including tax"
|
||||
msgstr "Preis inklusive Steuern"
|
||||
msgstr "inklusive aller Steuern"
|
||||
|
||||
#: pretix/control/forms/event.py:807
|
||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||
msgstr "Empfohlen, wenn mindestens teilweise an Verbraucher verkauft wird."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:811
|
||||
#, fuzzy
|
||||
#| msgctxt "reporting_timeframe"
|
||||
#| msgid "All future (excluding today)"
|
||||
msgid "Prices excluding tax"
|
||||
msgstr "Preise exklusive Steuern"
|
||||
msgstr "Zukunft (ab morgen)"
|
||||
|
||||
#: pretix/control/forms/event.py:812
|
||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||
msgstr "Empfohlen, wenn primär an Geschäftskunden verkauft wird."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:848
|
||||
#, fuzzy
|
||||
#| msgid "Date chosen by customer"
|
||||
msgid "Prices shown to customer"
|
||||
msgstr "Preisanzeige für Kunden"
|
||||
msgstr "Wunschdatum des Kunden"
|
||||
|
||||
#: pretix/control/forms/event.py:852
|
||||
msgid ""
|
||||
@@ -14060,10 +14070,6 @@ msgid ""
|
||||
"product, the total tax amount can differ from when it would be computed from "
|
||||
"the order total."
|
||||
msgstr ""
|
||||
"Empfohlen, wenn keine E-Rechnungen benötigt werden. Jedes Produkt wird zum "
|
||||
"beworbenen Netto- und Bruttopreis verkauft. Im Fall von Bestellungen mit "
|
||||
"mehreren Produkten kann die Gesamt-Steuersumme höher oder niedriger sein als "
|
||||
"die, die sich aus der Bestellsumme berechnen würde."
|
||||
|
||||
#: pretix/control/forms/event.py:857
|
||||
msgid ""
|
||||
@@ -14072,11 +14078,6 @@ msgid ""
|
||||
"may be changed to ensure correct rounding, while the net prices will be kept "
|
||||
"as configured. This may cause the actual payment amount to differ."
|
||||
msgstr ""
|
||||
"Empfohlen für E-Rechnungen, wenn primär an Geschäftskunden verkauft wird und "
|
||||
"Kunden Nettopreise angezeigt werden. Der Bruttopreis einzelner Produkte kann "
|
||||
"sich automatisch ändern, um ein korrektes Rundungsverhalten sicherzustellen, "
|
||||
"während die Nettopreise immer den eingestellten Preisen entsprechen. Der "
|
||||
"resultierende Zahlungsbetrag kann durch die Rundung abweichen."
|
||||
|
||||
#: pretix/control/forms/event.py:863
|
||||
msgid ""
|
||||
@@ -14086,13 +14087,6 @@ msgid ""
|
||||
"configured whenever possible. Gross prices may still change if they are "
|
||||
"impossible to derive from a rounded net price."
|
||||
msgstr ""
|
||||
"Empfohlen für E-Rechnungen, wenn primär an Verbraucher verkauft wird und "
|
||||
"Kunden Bruttopreise angezeigt werden. Der Netto- oder Bruttopreis einzelner "
|
||||
"Produkte kann sich automatisch ändern, um ein korrektes Rundungsverhalten "
|
||||
"sicherzustellen. Dabei versucht das System, die Bruttopreise möglichst bei "
|
||||
"den eingestellten Preisen zu belassen. Die Bruttopreise können sich dennoch "
|
||||
"ändern, wenn sie durch Errechnung von einem gerundeten Nettopreis nicht "
|
||||
"erreichbar sind."
|
||||
|
||||
#: pretix/control/forms/event.py:961
|
||||
msgid "Generate invoices for Sales channels"
|
||||
@@ -21284,10 +21278,6 @@ msgid ""
|
||||
"optionally contain additional rules that depend on the customer's country "
|
||||
"and type."
|
||||
msgstr ""
|
||||
"Steuer-Regeln definieren unterschiedliche Besteuerungsszenarien, die dann "
|
||||
"den verschiedenen Produkten zugewiesen werden können. Jede Steuer-Regel "
|
||||
"enthält einen Standard-Steuersatz und kann optional zusätzliche Regeln "
|
||||
"enthalten, die auf die Art und Herkunft des Kunden Bezug nehmen."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:21
|
||||
msgid "You haven't created any tax rules yet."
|
||||
@@ -21314,11 +21304,13 @@ msgid "Make default"
|
||||
msgstr "Zum Standard machen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:67
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(count)s event"
|
||||
#| msgid_plural "%(count)s events"
|
||||
msgid "%(count)s product"
|
||||
msgid_plural "%(count)s products"
|
||||
msgstr[0] "%(count)s Produkt"
|
||||
msgstr[1] "%(count)s Produkte"
|
||||
msgstr[0] "%(count)s Veranstaltung"
|
||||
msgstr[1] "%(count)s Veranstaltungen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:75
|
||||
#, python-format
|
||||
@@ -21331,12 +21323,16 @@ msgid "excl. %(rate)s %%"
|
||||
msgstr "zzgl. %(rate)s %%"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Custom rules"
|
||||
msgid "with custom rules"
|
||||
msgstr "mit eigenen Regeln"
|
||||
msgstr "Eigene Regeln"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
||||
#, fuzzy
|
||||
#| msgid "Base settings"
|
||||
msgid "Tax settings"
|
||||
msgstr "Steuer-Einstellungen"
|
||||
msgstr "Grundeinstellungen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
||||
@@ -24153,7 +24149,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/order/transactions.html:73
|
||||
#, python-format
|
||||
msgid "incl. %(amount)s rounding correction"
|
||||
msgstr "inkl. %(amount)s Rundungskorrektur"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:7
|
||||
|
||||
@@ -362,9 +362,6 @@ Reverse-Proxy
|
||||
Revisionssicherheit
|
||||
Revolut
|
||||
Revolut-App
|
||||
Rundungsabweichungen
|
||||
Rundungskorrektur
|
||||
Rundungsverhalten
|
||||
rückabgewickelt
|
||||
Sa
|
||||
Sammlungsstücken
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-30 10:55+0000\n"
|
||||
"PO-Revision-Date: 2025-10-30 20:00+0000\n"
|
||||
"PO-Revision-Date: 2025-10-29 09:24+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix/de_Informal/>\n"
|
||||
@@ -9651,15 +9651,15 @@ msgstr "Der Gutschein wurde an {recipient} verschickt."
|
||||
|
||||
#: pretix/base/settings.py:81
|
||||
msgid "Compute taxes for every line individually"
|
||||
msgstr "Berechne Steuern für jede Position einzeln"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:82
|
||||
msgid "Compute taxes based on net total"
|
||||
msgstr "Berechne Steuern auf Basis der Nettosumme"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:83
|
||||
msgid "Compute taxes based on net total with stable gross prices"
|
||||
msgstr "Berechne Steuern auf Basis der Nettosumme mit konstanten Bruttopreisen"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:133
|
||||
msgid "Allow usage of restricted plugins"
|
||||
@@ -9749,8 +9749,13 @@ msgid "Add-on products will not be counted."
|
||||
msgstr "Zusatzprodukte werden nicht mitgezählt."
|
||||
|
||||
#: pretix/base/settings.py:334
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Show net prices instead of gross prices in the product list (not "
|
||||
#| "recommended!)"
|
||||
msgid "Show net prices instead of gross prices in the product list"
|
||||
msgstr "Zeigen Nettopreise statt Bruttopreisen in der Produktliste"
|
||||
msgstr ""
|
||||
"Zeige Netto- statt Bruttopreisen in den Produktlisten (nicht empfohlen)"
|
||||
|
||||
#: pretix/base/settings.py:335
|
||||
msgid ""
|
||||
@@ -9867,8 +9872,10 @@ msgid "Require a phone number per order"
|
||||
msgstr "Telefonnummer pro Bestellung erfordern"
|
||||
|
||||
#: pretix/base/settings.py:481
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Rounding of taxes"
|
||||
msgstr "Rundung der Steuern"
|
||||
msgstr "inklusive aller Steuern"
|
||||
|
||||
#: pretix/base/settings.py:485
|
||||
msgid ""
|
||||
@@ -9876,10 +9883,6 @@ msgid ""
|
||||
"for tax reporting, you need to make sure to account for possible rounding "
|
||||
"differences if your external system rounds differently than pretix."
|
||||
msgstr ""
|
||||
"Bitte beachte, dass bei der Übertragung der Verkaufsdaten in ein externes "
|
||||
"Buchhaltungssystem darauf geachtet werden muss, dass potentielle "
|
||||
"Rundungsabweichungen behandelt werden, wenn das externe System anders rundet "
|
||||
"als pretix."
|
||||
|
||||
#: pretix/base/settings.py:500
|
||||
msgid "Ask for invoice address"
|
||||
@@ -14010,24 +14013,31 @@ msgstr ""
|
||||
"Ausstellung ablaufen."
|
||||
|
||||
#: pretix/control/forms/event.py:806
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Prices including tax"
|
||||
msgstr "Preis inklusive Steuern"
|
||||
msgstr "inklusive aller Steuern"
|
||||
|
||||
#: pretix/control/forms/event.py:807
|
||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||
msgstr "Empfohlen, wenn mindestens teilweise an Verbraucher verkauft wird."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:811
|
||||
#, fuzzy
|
||||
#| msgctxt "reporting_timeframe"
|
||||
#| msgid "All future (excluding today)"
|
||||
msgid "Prices excluding tax"
|
||||
msgstr "Preise exklusive Steuern"
|
||||
msgstr "Zukunft (ab morgen)"
|
||||
|
||||
#: pretix/control/forms/event.py:812
|
||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||
msgstr "Empfohlen, wenn primär an Geschäftskunden verkauft wird."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:848
|
||||
#, fuzzy
|
||||
#| msgid "Date chosen by customer"
|
||||
msgid "Prices shown to customer"
|
||||
msgstr "Preisanzeige für Kunden"
|
||||
msgstr "Wunschdatum des Kunden"
|
||||
|
||||
#: pretix/control/forms/event.py:852
|
||||
msgid ""
|
||||
@@ -14036,10 +14046,6 @@ msgid ""
|
||||
"product, the total tax amount can differ from when it would be computed from "
|
||||
"the order total."
|
||||
msgstr ""
|
||||
"Empfohlen, wenn keine E-Rechnungen benötigt werden. Jedes Produkt wird zum "
|
||||
"beworbenen Netto- und Bruttopreis verkauft. Im Fall von Bestellungen mit "
|
||||
"mehreren Produkten kann die Gesamt-Steuersumme höher oder niedriger sein als "
|
||||
"die, die sich aus der Bestellsumme berechnen würde."
|
||||
|
||||
#: pretix/control/forms/event.py:857
|
||||
msgid ""
|
||||
@@ -14048,11 +14054,6 @@ msgid ""
|
||||
"may be changed to ensure correct rounding, while the net prices will be kept "
|
||||
"as configured. This may cause the actual payment amount to differ."
|
||||
msgstr ""
|
||||
"Empfohlen für E-Rechnungen, wenn primär an Geschäftskunden verkauft wird und "
|
||||
"Kunden Nettopreise angezeigt werden. Der Bruttopreis einzelner Produkte kann "
|
||||
"sich automatisch ändern, um ein korrektes Rundungsverhalten sicherzustellen, "
|
||||
"während die Nettopreise immer den eingestellten Preisen entsprechen. Der "
|
||||
"resultierende Zahlungsbetrag kann durch die Rundung abweichen."
|
||||
|
||||
#: pretix/control/forms/event.py:863
|
||||
msgid ""
|
||||
@@ -14062,13 +14063,6 @@ msgid ""
|
||||
"configured whenever possible. Gross prices may still change if they are "
|
||||
"impossible to derive from a rounded net price."
|
||||
msgstr ""
|
||||
"Empfohlen für E-Rechnungen, wenn primär an Verbraucher verkauft wird und "
|
||||
"Kunden Bruttopreise angezeigt werden. Der Netto- oder Bruttopreis einzelner "
|
||||
"Produkte kann sich automatisch ändern, um ein korrektes Rundungsverhalten "
|
||||
"sicherzustellen. Dabei versucht das System, die Bruttopreise möglichst bei "
|
||||
"den eingestellten Preisen zu belassen. Die Bruttopreise können sich dennoch "
|
||||
"ändern, wenn sie durch Errechnung von einem gerundeten Nettopreis nicht "
|
||||
"erreichbar sind."
|
||||
|
||||
#: pretix/control/forms/event.py:961
|
||||
msgid "Generate invoices for Sales channels"
|
||||
@@ -21254,10 +21248,6 @@ msgid ""
|
||||
"optionally contain additional rules that depend on the customer's country "
|
||||
"and type."
|
||||
msgstr ""
|
||||
"Steuer-Regeln definieren unterschiedliche Besteuerungsszenarien, die dann "
|
||||
"den verschiedenen Produkten zugewiesen werden können. Jede Steuer-Regel "
|
||||
"enthält einen Standard-Steuersatz und kann optional zusätzliche Regeln "
|
||||
"enthalten, die auf die Art und Herkunft des Kunden Bezug nehmen."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:21
|
||||
msgid "You haven't created any tax rules yet."
|
||||
@@ -21284,11 +21274,13 @@ msgid "Make default"
|
||||
msgstr "Zum Standard machen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:67
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(count)s event"
|
||||
#| msgid_plural "%(count)s events"
|
||||
msgid "%(count)s product"
|
||||
msgid_plural "%(count)s products"
|
||||
msgstr[0] "%(count)s Produkt"
|
||||
msgstr[1] "%(count)s Produkte"
|
||||
msgstr[0] "%(count)s Veranstaltung"
|
||||
msgstr[1] "%(count)s Veranstaltungen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:75
|
||||
#, python-format
|
||||
@@ -21301,12 +21293,16 @@ msgid "excl. %(rate)s %%"
|
||||
msgstr "zzgl. %(rate)s %%"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Custom rules"
|
||||
msgid "with custom rules"
|
||||
msgstr "mit eigenen Regeln"
|
||||
msgstr "Eigene Regeln"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
||||
#, fuzzy
|
||||
#| msgid "Base settings"
|
||||
msgid "Tax settings"
|
||||
msgstr "Steuer-Einstellungen"
|
||||
msgstr "Grundeinstellungen"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
||||
@@ -24120,7 +24116,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/order/transactions.html:73
|
||||
#, python-format
|
||||
msgid "incl. %(amount)s rounding correction"
|
||||
msgstr "inkl. %(amount)s Rundungskorrektur"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:7
|
||||
|
||||
@@ -362,9 +362,6 @@ Reverse-Proxy
|
||||
Revisionssicherheit
|
||||
Revolut
|
||||
Revolut-App
|
||||
Rundungsabweichungen
|
||||
Rundungskorrektur
|
||||
Rundungsverhalten
|
||||
rückabgewickelt
|
||||
Sa
|
||||
Sammlungsstücken
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-30 10:55+0000\n"
|
||||
"PO-Revision-Date: 2025-11-04 10:25+0000\n"
|
||||
"PO-Revision-Date: 2025-10-22 16:00+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"es/>\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.14\n"
|
||||
"X-Generator: Weblate 5.13.3\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -8346,8 +8346,10 @@ msgid "Event canceled"
|
||||
msgstr "Evento cancelado"
|
||||
|
||||
#: pretix/base/services/cancelevent.py:392
|
||||
#, fuzzy
|
||||
#| msgid "Create configuration"
|
||||
msgid "Bulk-refund confirmation"
|
||||
msgstr "Confirmación de reembolso masivo"
|
||||
msgstr "Crear configuración"
|
||||
|
||||
#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:247
|
||||
#: pretix/base/services/orders.py:155
|
||||
@@ -9653,16 +9655,15 @@ msgstr "El vale de compra ha sido enviado a {recipient}."
|
||||
|
||||
#: pretix/base/settings.py:81
|
||||
msgid "Compute taxes for every line individually"
|
||||
msgstr "Calcular los impuestos para cada línea individualmente"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:82
|
||||
msgid "Compute taxes based on net total"
|
||||
msgstr "Calcular los impuestos basándose en el total neto"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:83
|
||||
msgid "Compute taxes based on net total with stable gross prices"
|
||||
msgstr ""
|
||||
"Calcular los impuestos basándose en el total neto con precios brutos estables"
|
||||
|
||||
#: pretix/base/settings.py:133
|
||||
msgid "Allow usage of restricted plugins"
|
||||
@@ -9754,9 +9755,14 @@ msgid "Add-on products will not be counted."
|
||||
msgstr "Los productos adicionales no se contarán."
|
||||
|
||||
#: pretix/base/settings.py:334
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Show net prices instead of gross prices in the product list (not "
|
||||
#| "recommended!)"
|
||||
msgid "Show net prices instead of gross prices in the product list"
|
||||
msgstr ""
|
||||
"Mostrar precios netos en lugar de precios brutos en la lista de productos"
|
||||
"Mostrar precios netos en lugar de precios brutos en la lista de productos "
|
||||
"(¡no recomendado!)"
|
||||
|
||||
#: pretix/base/settings.py:335
|
||||
msgid ""
|
||||
@@ -9877,8 +9883,10 @@ msgid "Require a phone number per order"
|
||||
msgstr "Requerir un número de teléfono por pedido"
|
||||
|
||||
#: pretix/base/settings.py:481
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Rounding of taxes"
|
||||
msgstr "Redondeo de impuestos"
|
||||
msgstr "impuestos incluidos"
|
||||
|
||||
#: pretix/base/settings.py:485
|
||||
msgid ""
|
||||
@@ -9886,10 +9894,6 @@ msgid ""
|
||||
"for tax reporting, you need to make sure to account for possible rounding "
|
||||
"differences if your external system rounds differently than pretix."
|
||||
msgstr ""
|
||||
"Tenga en cuenta que si transfiere sus datos de ventas desde pretix a un "
|
||||
"sistema externo para la declaración de impuestos, debe asegurarse de tener "
|
||||
"en cuenta las posibles diferencias de redondeo si su sistema externo "
|
||||
"redondea de forma diferente a pretix."
|
||||
|
||||
#: pretix/base/settings.py:500
|
||||
msgid "Ask for invoice address"
|
||||
@@ -13160,20 +13164,18 @@ msgstr ""
|
||||
msgid ""
|
||||
"You have requested us to cancel an event which includes a larger bulk-refund:"
|
||||
msgstr ""
|
||||
"Nos ha solicitado cancelar un evento que incluye un reembolso masivo de "
|
||||
"mayor importe:"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:6
|
||||
#, fuzzy
|
||||
#| msgid "Initiate a refund of %(amount)s"
|
||||
msgid "Estimated refund amount"
|
||||
msgstr "Importe estimado del reembolso"
|
||||
msgstr "Iniciar un reembolso de %(amount)s"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:8
|
||||
msgid ""
|
||||
"Please confirm that you want to proceed by coping the following confirmation "
|
||||
"code into the cancellation form:"
|
||||
msgstr ""
|
||||
"Confirme que desea continuar copiando el siguiente código de confirmación en "
|
||||
"el formulario de cancelación:"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/email_footer.html:3
|
||||
#, python-format
|
||||
@@ -14015,25 +14017,31 @@ msgstr ""
|
||||
"año en el que se emite la tarjeta de regalo."
|
||||
|
||||
#: pretix/control/forms/event.py:806
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Prices including tax"
|
||||
msgstr "Precios con impuestos incluidos"
|
||||
msgstr "impuestos incluidos"
|
||||
|
||||
#: pretix/control/forms/event.py:807
|
||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||
msgstr "Recomendado si se venden entradas, al menos en parte, a consumidores."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:811
|
||||
#, fuzzy
|
||||
#| msgctxt "reporting_timeframe"
|
||||
#| msgid "All future (excluding today)"
|
||||
msgid "Prices excluding tax"
|
||||
msgstr "Precios sin impuestos"
|
||||
msgstr "Todo el futuro (excepto hoy)"
|
||||
|
||||
#: pretix/control/forms/event.py:812
|
||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||
msgstr ""
|
||||
"Recomendado solo si vende entradas principalmente a clientes empresariales."
|
||||
|
||||
#: pretix/control/forms/event.py:848
|
||||
#, fuzzy
|
||||
#| msgid "Date chosen by customer"
|
||||
msgid "Prices shown to customer"
|
||||
msgstr "Precios mostrados a los clientes"
|
||||
msgstr "Fecha elegida por el cliente"
|
||||
|
||||
#: pretix/control/forms/event.py:852
|
||||
msgid ""
|
||||
@@ -14042,10 +14050,6 @@ msgid ""
|
||||
"product, the total tax amount can differ from when it would be computed from "
|
||||
"the order total."
|
||||
msgstr ""
|
||||
"Recomendado cuando no se requiere facturación electrónica. Cada producto se "
|
||||
"venderá con el precio neto y bruto anunciado. Sin embargo, en pedidos de más "
|
||||
"de un producto, el importe total de los impuestos puede diferir del que se "
|
||||
"calcularía a partir del total del pedido."
|
||||
|
||||
#: pretix/control/forms/event.py:857
|
||||
msgid ""
|
||||
@@ -14054,12 +14058,6 @@ msgid ""
|
||||
"may be changed to ensure correct rounding, while the net prices will be kept "
|
||||
"as configured. This may cause the actual payment amount to differ."
|
||||
msgstr ""
|
||||
"Recomendado para la facturación electrónica cuando se vende principalmente a "
|
||||
"clientes empresariales y se muestran los precios a los clientes sin "
|
||||
"impuestos. El precio bruto de algunos productos puede modificarse para "
|
||||
"garantizar un redondeo correcto, mientras que los precios netos se "
|
||||
"mantendrán tal y como están configurados. Esto puede provocar que el importe "
|
||||
"real del pago sea diferente."
|
||||
|
||||
#: pretix/control/forms/event.py:863
|
||||
msgid ""
|
||||
@@ -14069,12 +14067,6 @@ msgid ""
|
||||
"configured whenever possible. Gross prices may still change if they are "
|
||||
"impossible to derive from a rounded net price."
|
||||
msgstr ""
|
||||
"Recomendado para la facturación electrónica cuando se vende principalmente a "
|
||||
"consumidores. El precio bruto o neto de algunos productos puede modificarse "
|
||||
"automáticamente para garantizar el redondeo correcto del total del pedido. "
|
||||
"El sistema intenta mantener los precios brutos tal y como se han configurado "
|
||||
"siempre que sea posible. Los precios brutos pueden seguir cambiando si no es "
|
||||
"posible obtenerlos a partir de un precio neto redondeado."
|
||||
|
||||
#: pretix/control/forms/event.py:961
|
||||
msgid "Generate invoices for Sales channels"
|
||||
@@ -16193,7 +16185,7 @@ msgstr "Confirme que desea cancelar TODAS las fechas de esta serie de eventos."
|
||||
|
||||
#: pretix/control/forms/orders.py:1037
|
||||
msgid "I understand that this is not reversible and want to continue"
|
||||
msgstr "Entiendo que esto no es reversible y deseo continuar"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/orders.py:1041
|
||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
||||
@@ -16204,12 +16196,12 @@ msgstr "Código de confirmación"
|
||||
msgid ""
|
||||
"We have just emailed you a confirmation code to enter to confirm this action"
|
||||
msgstr ""
|
||||
"Acabamos de enviarle por correo electrónico un código de confirmación que "
|
||||
"deberá introducir para confirmar esta acción"
|
||||
|
||||
#: pretix/control/forms/orders.py:1055
|
||||
#, fuzzy
|
||||
#| msgid "The confirm code you entered was incorrect."
|
||||
msgid "The confirmation code is incorrect."
|
||||
msgstr "El código de confirmación es incorrecto."
|
||||
msgstr "El código de confirmación que introdujo era incorrecto."
|
||||
|
||||
#: pretix/control/forms/organizer.py:93
|
||||
msgid "This slug is already in use. Please choose a different one."
|
||||
@@ -21276,10 +21268,6 @@ msgid ""
|
||||
"optionally contain additional rules that depend on the customer's country "
|
||||
"and type."
|
||||
msgstr ""
|
||||
"Las normas fiscales definen diferentes escenarios fiscales que luego se "
|
||||
"pueden asignar a los productos individuales. Cada norma fiscal contiene un "
|
||||
"tipo impositivo predeterminado y, opcionalmente, puede contener normas "
|
||||
"adicionales que dependen del país y el tipo de cliente."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:21
|
||||
msgid "You haven't created any tax rules yet."
|
||||
@@ -21306,11 +21294,13 @@ msgid "Make default"
|
||||
msgstr "Establecer por defecto"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:67
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(count)s event"
|
||||
#| msgid_plural "%(count)s events"
|
||||
msgid "%(count)s product"
|
||||
msgid_plural "%(count)s products"
|
||||
msgstr[0] "%(count)s producto"
|
||||
msgstr[1] "%(count)s productos"
|
||||
msgstr[0] "%(count)s elemento"
|
||||
msgstr[1] "%(count)s elementos"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:75
|
||||
#, python-format
|
||||
@@ -21323,12 +21313,16 @@ msgid "excl. %(rate)s %%"
|
||||
msgstr "excluido %(rate)s %%"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Custom rules"
|
||||
msgid "with custom rules"
|
||||
msgstr "con reglas personalizadas"
|
||||
msgstr "Reglas personalizadas"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
||||
#, fuzzy
|
||||
#| msgid "Base settings"
|
||||
msgid "Tax settings"
|
||||
msgstr "Configuración de impuestos"
|
||||
msgstr "Ajustes básicos"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
||||
@@ -24147,7 +24141,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/order/transactions.html:73
|
||||
#, python-format
|
||||
msgid "incl. %(amount)s rounding correction"
|
||||
msgstr "incl. %(amount)s corrección por redondeo"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:7
|
||||
@@ -24253,77 +24247,84 @@ msgstr ""
|
||||
"los que estén en la lista de espera recibirán varios correos electrónicos."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel.html:84
|
||||
#, fuzzy
|
||||
#| msgid "Refund amount"
|
||||
msgid "Preview refund amount"
|
||||
msgstr "Previsualizar el importe del reembolso"
|
||||
msgstr "Importe del reembolso"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel.html:88
|
||||
msgid "Cancel all orders"
|
||||
msgstr "Cancelar todos los pedidos"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:13
|
||||
#, fuzzy
|
||||
#| msgid "If you contact us, please send us the following code:"
|
||||
msgid "If you proceed, the system will do the following:"
|
||||
msgstr "Si continúa, el sistema hará lo siguiente:"
|
||||
msgstr ""
|
||||
"Si se pone en contacto con nosotros, por favor envíenos el siguiente código:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:19
|
||||
#, python-format
|
||||
msgid "%(count)s order will be canceled fully"
|
||||
msgid_plural "%(count)s orders will be canceled fully"
|
||||
msgstr[0] "%(count)s pedido se cancelará por completo"
|
||||
msgstr[1] "%(count)s pedidos se cancelarán por completo"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:26
|
||||
#, python-format
|
||||
msgid "%(count)s order will be canceled partially"
|
||||
msgid_plural "%(count)s orders will be canceled partially"
|
||||
msgstr[0] "%(count)s pedido se cancelará parcialmente"
|
||||
msgstr[1] "%(count)s pedidos se cancelarán parcialmente"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:36
|
||||
#, python-format
|
||||
msgid "%(amount)s are eligible for refunds."
|
||||
msgstr "%(amount)s son reembolsables."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:40
|
||||
msgid ""
|
||||
"The system will attempt to refund the money automatically if supported by "
|
||||
"the payment method."
|
||||
msgstr ""
|
||||
"El sistema intentará reembolsar el dinero automáticamente si el método de "
|
||||
"pago lo permite."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:42
|
||||
msgid "The system will create manual refunds that you need to execute."
|
||||
msgstr "El sistema creará reembolsos manuales que deberá ejecutar."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:44
|
||||
#, fuzzy
|
||||
#| msgid "Text (if order will not expire automatically)"
|
||||
msgid "Refunds will not happen automatically."
|
||||
msgstr "Los reembolsos no se realizarán automáticamente."
|
||||
msgstr "Texto (si el pedido no caducará automáticamente)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:52
|
||||
#, fuzzy
|
||||
#| msgid "Send information via email"
|
||||
msgid "Inform all customers via email."
|
||||
msgstr "Informar a todos los clientes por correo electrónico."
|
||||
msgstr "Enviar información por correo electrónico"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:57
|
||||
msgid "Inform all waiting list contacts via email."
|
||||
msgstr ""
|
||||
"Informar a todos los contactos de la lista de espera por correo electrónico."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:62
|
||||
msgid ""
|
||||
"These numbers are estimates and may change if the data in your event "
|
||||
"recently changed."
|
||||
msgstr ""
|
||||
"Estas cifras son estimaciones y pueden variar si los datos del evento han "
|
||||
"cambiado recientemente."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:76
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "Initiate a refund of %(amount)s"
|
||||
msgid "Proceed and refund approx. %(amount)s"
|
||||
msgstr "Proseguir y reembolsar aprox. %(amount)s"
|
||||
msgstr "Iniciar un reembolso de %(amount)s"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Yes, cancel order"
|
||||
msgid "Proceed and cancel orders"
|
||||
msgstr "Proceder y cancelar pedidos"
|
||||
msgstr "Sí, cancelar pedido"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:8
|
||||
|
||||
@@ -4,7 +4,7 @@ msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-30 10:55+0000\n"
|
||||
"PO-Revision-Date: 2025-11-04 10:25+0000\n"
|
||||
"PO-Revision-Date: 2025-10-22 16:00+0000\n"
|
||||
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
|
||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix/fr/"
|
||||
">\n"
|
||||
@@ -13,7 +13,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.14\n"
|
||||
"X-Generator: Weblate 5.13.3\n"
|
||||
|
||||
#: pretix/_base_settings.py:87
|
||||
msgid "English"
|
||||
@@ -8397,8 +8397,10 @@ msgid "Event canceled"
|
||||
msgstr "Événement annulé"
|
||||
|
||||
#: pretix/base/services/cancelevent.py:392
|
||||
#, fuzzy
|
||||
#| msgid "Create configuration"
|
||||
msgid "Bulk-refund confirmation"
|
||||
msgstr "Confirmation de remboursement en bloc"
|
||||
msgstr "Créer une configuration"
|
||||
|
||||
#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:247
|
||||
#: pretix/base/services/orders.py:155
|
||||
@@ -9718,15 +9720,15 @@ msgstr "Le bon a été envoyé à {recipient}."
|
||||
|
||||
#: pretix/base/settings.py:81
|
||||
msgid "Compute taxes for every line individually"
|
||||
msgstr "Calculer les taxes individuellement pour chaque ligne"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:82
|
||||
msgid "Compute taxes based on net total"
|
||||
msgstr "Calculer les taxes sur la base du total net"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:83
|
||||
msgid "Compute taxes based on net total with stable gross prices"
|
||||
msgstr "Calculer les taxes sur la base du total net avec des prix bruts stables"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:133
|
||||
msgid "Allow usage of restricted plugins"
|
||||
@@ -9819,9 +9821,14 @@ msgid "Add-on products will not be counted."
|
||||
msgstr "Les Add-Ons e sont pas comptabilisés."
|
||||
|
||||
#: pretix/base/settings.py:334
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Show net prices instead of gross prices in the product list (not "
|
||||
#| "recommended!)"
|
||||
msgid "Show net prices instead of gross prices in the product list"
|
||||
msgstr ""
|
||||
"Afficher les prix nets au lieu des prix bruts dans la liste des produits"
|
||||
"Afficher les prix nets au lieu des prix bruts dans la liste de produits (pas "
|
||||
"recommandé !)"
|
||||
|
||||
#: pretix/base/settings.py:335
|
||||
msgid ""
|
||||
@@ -9940,8 +9947,10 @@ msgid "Require a phone number per order"
|
||||
msgstr "Exiger un numéro de téléphone par commande"
|
||||
|
||||
#: pretix/base/settings.py:481
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Rounding of taxes"
|
||||
msgstr "Arrondi des taxes"
|
||||
msgstr "toutes taxes comprises"
|
||||
|
||||
#: pretix/base/settings.py:485
|
||||
msgid ""
|
||||
@@ -9949,10 +9958,6 @@ msgid ""
|
||||
"for tax reporting, you need to make sure to account for possible rounding "
|
||||
"differences if your external system rounds differently than pretix."
|
||||
msgstr ""
|
||||
"Veuillez noter que si vous transférez vos données de vente depuis pretix "
|
||||
"vers un système externe à des fins de déclaration fiscale, vous devez tenir "
|
||||
"compte des éventuelles différences d'arrondi si votre système externe "
|
||||
"arrondit différemment de pretix."
|
||||
|
||||
#: pretix/base/settings.py:500
|
||||
msgid "Ask for invoice address"
|
||||
@@ -13285,20 +13290,18 @@ msgstr ""
|
||||
msgid ""
|
||||
"You have requested us to cancel an event which includes a larger bulk-refund:"
|
||||
msgstr ""
|
||||
"Vous nous avez demandé d'annuler un événement qui implique un remboursement "
|
||||
"groupé important :"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:6
|
||||
#, fuzzy
|
||||
#| msgid "Initiate a refund of %(amount)s"
|
||||
msgid "Estimated refund amount"
|
||||
msgstr "Montant estimé du remboursement"
|
||||
msgstr "Initier un remboursement de %(amount)s"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:8
|
||||
msgid ""
|
||||
"Please confirm that you want to proceed by coping the following confirmation "
|
||||
"code into the cancellation form:"
|
||||
msgstr ""
|
||||
"Veuillez confirmer que vous souhaitez poursuivre en copiant le code de "
|
||||
"confirmation suivant dans le formulaire d'annulation :"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/email_footer.html:3
|
||||
#, python-format
|
||||
@@ -14148,27 +14151,31 @@ msgstr ""
|
||||
"plus l’année d’émission de la carte-cadeau."
|
||||
|
||||
#: pretix/control/forms/event.py:806
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Prices including tax"
|
||||
msgstr "Prix TTC"
|
||||
msgstr "toutes taxes comprises"
|
||||
|
||||
#: pretix/control/forms/event.py:807
|
||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||
msgstr ""
|
||||
"Recommandé si vous vendez des billets au moins en partie à des consommateurs."
|
||||
|
||||
#: pretix/control/forms/event.py:811
|
||||
#, fuzzy
|
||||
#| msgctxt "reporting_timeframe"
|
||||
#| msgid "All future (excluding today)"
|
||||
msgid "Prices excluding tax"
|
||||
msgstr "Prix hors taxes"
|
||||
msgstr "Tout futur (sauf aujourd’hui)"
|
||||
|
||||
#: pretix/control/forms/event.py:812
|
||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||
msgstr ""
|
||||
"Recommandé uniquement si vous vendez principalement des billets à des "
|
||||
"clients professionnels."
|
||||
|
||||
#: pretix/control/forms/event.py:848
|
||||
#, fuzzy
|
||||
#| msgid "Date chosen by customer"
|
||||
msgid "Prices shown to customer"
|
||||
msgstr "Prix indiqués aux clients"
|
||||
msgstr "Date choisie par le client"
|
||||
|
||||
#: pretix/control/forms/event.py:852
|
||||
msgid ""
|
||||
@@ -14177,11 +14184,6 @@ msgid ""
|
||||
"product, the total tax amount can differ from when it would be computed from "
|
||||
"the order total."
|
||||
msgstr ""
|
||||
"Recommandé lorsque la facturation électronique n'est pas requise. Chaque "
|
||||
"produit sera vendu au prix net et brut annoncé. Cependant, dans le cas de "
|
||||
"commandes comprenant plusieurs produits, le montant total des taxes peut "
|
||||
"différer de celui qui serait calculé à partir du montant total de la "
|
||||
"commande."
|
||||
|
||||
#: pretix/control/forms/event.py:857
|
||||
msgid ""
|
||||
@@ -14190,12 +14192,6 @@ msgid ""
|
||||
"may be changed to ensure correct rounding, while the net prices will be kept "
|
||||
"as configured. This may cause the actual payment amount to differ."
|
||||
msgstr ""
|
||||
"Recommandé pour la facturation électronique lorsque vous vendez "
|
||||
"principalement à des clients professionnels et affichez les prix hors taxes "
|
||||
"à vos clients. Le prix brut de certains produits peut être modifié afin "
|
||||
"d'assurer un arrondi correct, tandis que les prix nets resteront tels qu'ils "
|
||||
"ont été configurés. Cela peut entraîner une différence entre le montant réel "
|
||||
"du paiement et le montant indiqué."
|
||||
|
||||
#: pretix/control/forms/event.py:863
|
||||
msgid ""
|
||||
@@ -14205,13 +14201,6 @@ msgid ""
|
||||
"configured whenever possible. Gross prices may still change if they are "
|
||||
"impossible to derive from a rounded net price."
|
||||
msgstr ""
|
||||
"Recommandé pour la facturation électronique lorsque vous vendez "
|
||||
"principalement à des consommateurs. Le prix brut ou net de certains produits "
|
||||
"peut être modifié automatiquement afin d'assurer un arrondi correct du total "
|
||||
"de la commande. Le système tente de conserver les prix bruts tels qu'ils ont "
|
||||
"été configurés dans la mesure du possible. Les prix bruts peuvent toutefois "
|
||||
"être modifiés s'il est impossible de les calculer à partir d'un prix net "
|
||||
"arrondi."
|
||||
|
||||
#: pretix/control/forms/event.py:961
|
||||
msgid "Generate invoices for Sales channels"
|
||||
@@ -16343,7 +16332,6 @@ msgstr ""
|
||||
#: pretix/control/forms/orders.py:1037
|
||||
msgid "I understand that this is not reversible and want to continue"
|
||||
msgstr ""
|
||||
"Je comprends que cette opération est irréversible et je souhaite continuer"
|
||||
|
||||
#: pretix/control/forms/orders.py:1041
|
||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
||||
@@ -16354,12 +16342,12 @@ msgstr "Code de confirmation"
|
||||
msgid ""
|
||||
"We have just emailed you a confirmation code to enter to confirm this action"
|
||||
msgstr ""
|
||||
"Nous venons de vous envoyer par e-mail un code de confirmation à saisir pour "
|
||||
"confirmer cette action"
|
||||
|
||||
#: pretix/control/forms/orders.py:1055
|
||||
#, fuzzy
|
||||
#| msgid "The confirm code you entered was incorrect."
|
||||
msgid "The confirmation code is incorrect."
|
||||
msgstr "Le code de confirmation est incorrect."
|
||||
msgstr "Le code de confirmation que vous avez entré était incorrect."
|
||||
|
||||
#: pretix/control/forms/organizer.py:93
|
||||
msgid "This slug is already in use. Please choose a different one."
|
||||
@@ -21431,10 +21419,6 @@ msgid ""
|
||||
"optionally contain additional rules that depend on the customer's country "
|
||||
"and type."
|
||||
msgstr ""
|
||||
"Les règles fiscales définissent différents scénarios d'imposition qui "
|
||||
"peuvent ensuite être attribués à chaque produit. Chaque règle fiscale "
|
||||
"contient un taux d'imposition par défaut et peut éventuellement contenir des "
|
||||
"règles supplémentaires qui dépendent du pays et du type de client."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:21
|
||||
msgid "You haven't created any tax rules yet."
|
||||
@@ -21461,11 +21445,13 @@ msgid "Make default"
|
||||
msgstr "Définir par défaut"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:67
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(count)s event"
|
||||
#| msgid_plural "%(count)s events"
|
||||
msgid "%(count)s product"
|
||||
msgid_plural "%(count)s products"
|
||||
msgstr[0] "%(count)s produit"
|
||||
msgstr[1] "%(count)s produits"
|
||||
msgstr[0] "%(count)s élement"
|
||||
msgstr[1] "%(count)s élements"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:75
|
||||
#, python-format
|
||||
@@ -21478,12 +21464,16 @@ msgid "excl. %(rate)s %%"
|
||||
msgstr "hors %(rate)s %%"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Custom rules"
|
||||
msgid "with custom rules"
|
||||
msgstr "avec des règles personnalisées"
|
||||
msgstr "Règles personnalisées"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
||||
#, fuzzy
|
||||
#| msgid "Base settings"
|
||||
msgid "Tax settings"
|
||||
msgstr "Paramètres relatifs aux taxes"
|
||||
msgstr "Réglages de base"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
||||
@@ -24324,7 +24314,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/order/transactions.html:73
|
||||
#, python-format
|
||||
msgid "incl. %(amount)s rounding correction"
|
||||
msgstr "y compris %(amount)s de correction d'arrondi"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:7
|
||||
@@ -24435,77 +24425,83 @@ msgstr ""
|
||||
"plusieurs courriels."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel.html:84
|
||||
#, fuzzy
|
||||
#| msgid "Refund amount"
|
||||
msgid "Preview refund amount"
|
||||
msgstr "Prévisualiser le montant du remboursement"
|
||||
msgstr "Montant du remboursement"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel.html:88
|
||||
msgid "Cancel all orders"
|
||||
msgstr "Annuler toutes les commandes"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:13
|
||||
#, fuzzy
|
||||
#| msgid "If you contact us, please send us the following code:"
|
||||
msgid "If you proceed, the system will do the following:"
|
||||
msgstr "Si vous continuez, le système effectuera les opérations suivantes :"
|
||||
msgstr "Si vous nous contactez, veuillez nous envoyer le code suivant :"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:19
|
||||
#, python-format
|
||||
msgid "%(count)s order will be canceled fully"
|
||||
msgid_plural "%(count)s orders will be canceled fully"
|
||||
msgstr[0] "%(count)s commande sera totalement annulée"
|
||||
msgstr[1] "%(count)s commandes seront totalement annulées"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:26
|
||||
#, python-format
|
||||
msgid "%(count)s order will be canceled partially"
|
||||
msgid_plural "%(count)s orders will be canceled partially"
|
||||
msgstr[0] "%(count)s commande sera partiellement annulé"
|
||||
msgstr[1] "%(count)s commandes seront partiellement annulées"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:36
|
||||
#, python-format
|
||||
msgid "%(amount)s are eligible for refunds."
|
||||
msgstr "%(amount)s sont susceptibles d'être remboursés."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:40
|
||||
msgid ""
|
||||
"The system will attempt to refund the money automatically if supported by "
|
||||
"the payment method."
|
||||
msgstr ""
|
||||
"Le système tentera de rembourser automatiquement l'argent si le mode de "
|
||||
"paiement le permet."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:42
|
||||
msgid "The system will create manual refunds that you need to execute."
|
||||
msgstr "Le système créera des remboursements manuels que vous devrez exécuter."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:44
|
||||
#, fuzzy
|
||||
#| msgid "Text (if order will not expire automatically)"
|
||||
msgid "Refunds will not happen automatically."
|
||||
msgstr "Les remboursements ne se feront pas automatiquement."
|
||||
msgstr "Texte (si la commande n’expire pas automatiquement)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:52
|
||||
#, fuzzy
|
||||
#| msgid "Send information via email"
|
||||
msgid "Inform all customers via email."
|
||||
msgstr "Informez tous les clients par e-mail."
|
||||
msgstr "Envoyer des informations par e-mail"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:57
|
||||
msgid "Inform all waiting list contacts via email."
|
||||
msgstr ""
|
||||
"Informez toutes les personnes inscrites sur la liste d'attente par e-mail."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:62
|
||||
msgid ""
|
||||
"These numbers are estimates and may change if the data in your event "
|
||||
"recently changed."
|
||||
msgstr ""
|
||||
"Ces chiffres sont des estimations et peuvent changer si les données "
|
||||
"relatives à votre événement ont récemment été modifiées."
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:76
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "Initiate a refund of %(amount)s"
|
||||
msgid "Proceed and refund approx. %(amount)s"
|
||||
msgstr "Poursuivre et rembourser environ %(amount)s"
|
||||
msgstr "Initier un remboursement de %(amount)s"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Yes, cancel order"
|
||||
msgid "Proceed and cancel orders"
|
||||
msgstr "Poursuivre et annuler les commandes"
|
||||
msgstr "Oui, annuler la commande"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:8
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-10-30 10:55+0000\n"
|
||||
"PO-Revision-Date: 2025-11-04 10:25+0000\n"
|
||||
"PO-Revision-Date: 2025-10-27 12:00+0000\n"
|
||||
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
|
||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"ja/>\n"
|
||||
@@ -8190,8 +8190,10 @@ msgid "Event canceled"
|
||||
msgstr "イベントがキャンセルされました"
|
||||
|
||||
#: pretix/base/services/cancelevent.py:392
|
||||
#, fuzzy
|
||||
#| msgid "Add confirmation text"
|
||||
msgid "Bulk-refund confirmation"
|
||||
msgstr "一括払い戻しの確認"
|
||||
msgstr "確認テキストを追加"
|
||||
|
||||
#: pretix/base/services/cart.py:102 pretix/base/services/modelimport.py:247
|
||||
#: pretix/base/services/orders.py:155
|
||||
@@ -9429,15 +9431,15 @@ msgstr "バウチャーは、{recipient}あてに送信されました。"
|
||||
|
||||
#: pretix/base/settings.py:81
|
||||
msgid "Compute taxes for every line individually"
|
||||
msgstr "各行ごとに税額を計算する"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:82
|
||||
msgid "Compute taxes based on net total"
|
||||
msgstr "税抜合計に基づいて税額を計算する"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:83
|
||||
msgid "Compute taxes based on net total with stable gross prices"
|
||||
msgstr "税込価格を固定して税抜合計に基づいて税額を計算する"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/settings.py:133
|
||||
msgid "Allow usage of restricted plugins"
|
||||
@@ -9525,8 +9527,12 @@ msgid "Add-on products will not be counted."
|
||||
msgstr "アドオン製品はカウントされません。"
|
||||
|
||||
#: pretix/base/settings.py:334
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Show net prices instead of gross prices in the product list (not "
|
||||
#| "recommended!)"
|
||||
msgid "Show net prices instead of gross prices in the product list"
|
||||
msgstr "製品リストに税込価格ではなく税抜価格を表示する"
|
||||
msgstr "製品リストには、総額ではなく純額を表示してください(お勧めしません!)"
|
||||
|
||||
#: pretix/base/settings.py:335
|
||||
msgid ""
|
||||
@@ -9640,8 +9646,10 @@ msgid "Require a phone number per order"
|
||||
msgstr "1注文につき1つの電話番号が必要"
|
||||
|
||||
#: pretix/base/settings.py:481
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Rounding of taxes"
|
||||
msgstr "税額の端数処理"
|
||||
msgstr "すべての税金を含めて"
|
||||
|
||||
#: pretix/base/settings.py:485
|
||||
msgid ""
|
||||
@@ -9649,9 +9657,6 @@ msgid ""
|
||||
"for tax reporting, you need to make sure to account for possible rounding "
|
||||
"differences if your external system rounds differently than pretix."
|
||||
msgstr ""
|
||||
"pretixから外部システムに販売データを転送して税務申告を行う場合、外部システム"
|
||||
"の端数処理がpretixと異なる場合は、端数処理の差異を考慮する必要があることに注"
|
||||
"意してください。"
|
||||
|
||||
#: pretix/base/settings.py:500
|
||||
msgid "Ask for invoice address"
|
||||
@@ -12786,18 +12791,19 @@ msgstr "数分以上かかる場合は、このページを更新するか、お
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:2
|
||||
msgid ""
|
||||
"You have requested us to cancel an event which includes a larger bulk-refund:"
|
||||
msgstr "大量の払い戻しを伴うイベントのキャンセルをリクエストされました:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:6
|
||||
#, fuzzy
|
||||
#| msgid "Initiate a refund of %(amount)s"
|
||||
msgid "Estimated refund amount"
|
||||
msgstr "推定払い戻し金額"
|
||||
msgstr "%(amount)sの払い戻しを開始する"
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/cancel_confirm.txt:8
|
||||
msgid ""
|
||||
"Please confirm that you want to proceed by coping the following confirmation "
|
||||
"code into the cancellation form:"
|
||||
msgstr "以下の確認コードをキャンセルフォームにコピーして、続行することを確認してくだ"
|
||||
"さい:"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/base/templates/pretixbase/email/email_footer.html:3
|
||||
#, python-format
|
||||
@@ -13618,24 +13624,31 @@ msgid ""
|
||||
msgstr "ギフトカードの有効期限を発行年を含めた{}年に設定しました。"
|
||||
|
||||
#: pretix/control/forms/event.py:806
|
||||
#, fuzzy
|
||||
#| msgid "including all taxes"
|
||||
msgid "Prices including tax"
|
||||
msgstr "税込価格"
|
||||
msgstr "すべての税金を含めて"
|
||||
|
||||
#: pretix/control/forms/event.py:807
|
||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||
msgstr "少なくとも一部を消費者に販売する場合に推奨されます。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:811
|
||||
#, fuzzy
|
||||
#| msgctxt "reporting_timeframe"
|
||||
#| msgid "All future (excluding today)"
|
||||
msgid "Prices excluding tax"
|
||||
msgstr "税込価格"
|
||||
msgstr "すべての未来(今日を除く)"
|
||||
|
||||
#: pretix/control/forms/event.py:812
|
||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||
msgstr "主に法人顧客にチケットを販売する場合のみ推奨されます。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/event.py:848
|
||||
#, fuzzy
|
||||
#| msgid "Date chosen by customer"
|
||||
msgid "Prices shown to customer"
|
||||
msgstr "顧客に表示される価格"
|
||||
msgstr "お客様が選んだ日付"
|
||||
|
||||
#: pretix/control/forms/event.py:852
|
||||
msgid ""
|
||||
@@ -13644,9 +13657,6 @@ msgid ""
|
||||
"product, the total tax amount can differ from when it would be computed from "
|
||||
"the order total."
|
||||
msgstr ""
|
||||
"電子インボイスが不要な場合に推奨されます。各製品は表示された税抜価格と税込価"
|
||||
"格で販売されます。ただし、複数の製品を含む注文では、合計税額が注文合計から計"
|
||||
"算した場合と異なる可能性があります。"
|
||||
|
||||
#: pretix/control/forms/event.py:857
|
||||
msgid ""
|
||||
@@ -13655,10 +13665,6 @@ msgid ""
|
||||
"may be changed to ensure correct rounding, while the net prices will be kept "
|
||||
"as configured. This may cause the actual payment amount to differ."
|
||||
msgstr ""
|
||||
"主に法人顧客に販売し、顧客に税抜価格を表示する場合の電子インボイスに推奨され"
|
||||
"ます。正確な端数処理を確保するために、一部の製品の税込価格が変更される場合が"
|
||||
"ありますが、税抜価格は設定どおりに保たれます。これにより実際の支払い金額が異"
|
||||
"なる場合があります。"
|
||||
|
||||
#: pretix/control/forms/event.py:863
|
||||
msgid ""
|
||||
@@ -13668,11 +13674,6 @@ msgid ""
|
||||
"configured whenever possible. Gross prices may still change if they are "
|
||||
"impossible to derive from a rounded net price."
|
||||
msgstr ""
|
||||
"主に消費者に販売する場合の電子インボイスに推奨されます。注文合計の正確な端数"
|
||||
"処理を確保するために、一部の製品の税込価格または税抜価格が自動的に変更される"
|
||||
"場合があります。システムは可能な限り設定どおりの税込価格を維持しようとします"
|
||||
"。ただし、端数処理された税抜価格から算出できない場合は、税込価格が変更される"
|
||||
"ことがあります。"
|
||||
|
||||
#: pretix/control/forms/event.py:961
|
||||
msgid "Generate invoices for Sales channels"
|
||||
@@ -14126,7 +14127,7 @@ msgstr "有効な注文"
|
||||
|
||||
#: pretix/control/forms/filter.py:220
|
||||
msgid "Paid (or canceled with paid fee)"
|
||||
msgstr "支払い済み (または支払い済み手数料でキャンセルされた)"
|
||||
msgstr "支払われた(または支払われた手数料でキャンセルされた)"
|
||||
|
||||
#: pretix/control/forms/filter.py:221
|
||||
#: pretix/control/templates/pretixcontrol/items/question.html:27
|
||||
@@ -14153,7 +14154,7 @@ msgstr "キャンセル"
|
||||
|
||||
#: pretix/control/forms/filter.py:226
|
||||
msgid "Canceled (fully)"
|
||||
msgstr "キャンセル済み (全額)"
|
||||
msgstr "キャンセルされました(完全に)"
|
||||
|
||||
#: pretix/control/forms/filter.py:227
|
||||
msgid "Canceled (fully or with paid fee)"
|
||||
@@ -14165,11 +14166,11 @@ msgstr "キャンセル済み(少なくとも1つのポジション)"
|
||||
|
||||
#: pretix/control/forms/filter.py:229
|
||||
msgid "Cancellation requested"
|
||||
msgstr "キャンセル申請済み"
|
||||
msgstr "キャンセルがリクエストされました"
|
||||
|
||||
#: pretix/control/forms/filter.py:230
|
||||
msgid "Fully canceled but invoice not canceled"
|
||||
msgstr "キャンセル済み(請求書は未キャンセル)"
|
||||
msgstr "完全にキャンセルされましたが、請求書はキャンセルされていません"
|
||||
|
||||
#: pretix/control/forms/filter.py:232
|
||||
msgid "Payment process"
|
||||
@@ -14187,11 +14188,11 @@ msgstr "保留中(期限切れ)"
|
||||
|
||||
#: pretix/control/forms/filter.py:236
|
||||
msgid "Overpaid"
|
||||
msgstr "過払い済み"
|
||||
msgstr "過剰な給料"
|
||||
|
||||
#: pretix/control/forms/filter.py:237
|
||||
msgid "Partially paid"
|
||||
msgstr "一部支払い済み"
|
||||
msgstr "部分的に支払われました"
|
||||
|
||||
#: pretix/control/forms/filter.py:238
|
||||
msgid "Underpaid (but confirmed)"
|
||||
@@ -15747,7 +15748,7 @@ msgstr ""
|
||||
|
||||
#: pretix/control/forms/orders.py:1037
|
||||
msgid "I understand that this is not reversible and want to continue"
|
||||
msgstr "これは元に戻せないことを理解し、続行します"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/orders.py:1041
|
||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
||||
@@ -15757,11 +15758,13 @@ msgstr "確認コード"
|
||||
#: pretix/control/forms/orders.py:1042
|
||||
msgid ""
|
||||
"We have just emailed you a confirmation code to enter to confirm this action"
|
||||
msgstr "この操作を確認するための確認コードをメールで送信しました"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/forms/orders.py:1055
|
||||
#, fuzzy
|
||||
#| msgid "The confirm code you entered was incorrect."
|
||||
msgid "The confirmation code is incorrect."
|
||||
msgstr "確認コードが正しくありません。"
|
||||
msgstr "入力した確認コードが間違っています。"
|
||||
|
||||
#: pretix/control/forms/organizer.py:93
|
||||
msgid "This slug is already in use. Please choose a different one."
|
||||
@@ -20690,9 +20693,6 @@ msgid ""
|
||||
"optionally contain additional rules that depend on the customer's country "
|
||||
"and type."
|
||||
msgstr ""
|
||||
"税ルールは、個々の製品に割り当てることができるさまざまな課税シナリオを定義し"
|
||||
"ます。各税ルールには既定の税率が含まれ、オプションで顧客の国や種別に応じた追"
|
||||
"加ルールを含めることができます。"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:21
|
||||
msgid "You haven't created any tax rules yet."
|
||||
@@ -20719,10 +20719,12 @@ msgid "Make default"
|
||||
msgstr "デフォルトに設定"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:67
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(count)s event"
|
||||
#| msgid_plural "%(count)s events"
|
||||
msgid "%(count)s product"
|
||||
msgid_plural "%(count)s products"
|
||||
msgstr[0] "%(count)s個の製品"
|
||||
msgstr[0] "%(count)s 件のイベント"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:75
|
||||
#, python-format
|
||||
@@ -20735,12 +20737,16 @@ msgid "excl. %(rate)s %%"
|
||||
msgstr "%(rate)s %%を除く"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Custom rules"
|
||||
msgid "with custom rules"
|
||||
msgstr "カスタムルールあり"
|
||||
msgstr "国"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
||||
#, fuzzy
|
||||
#| msgid "Base settings"
|
||||
msgid "Tax settings"
|
||||
msgstr "税の設定"
|
||||
msgstr "ベースの設定"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
||||
@@ -23481,7 +23487,7 @@ msgstr ""
|
||||
#: pretix/control/templates/pretixcontrol/order/transactions.html:73
|
||||
#, python-format
|
||||
msgid "incl. %(amount)s rounding correction"
|
||||
msgstr "%(amount)sの端数処理調整を含む"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/bulk_action.html:7
|
||||
@@ -23584,71 +23590,81 @@ msgstr ""
|
||||
"空席待ちリストのすべての人が複数のメールを受け取ることになります。"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel.html:84
|
||||
#, fuzzy
|
||||
#| msgid "Refund amount"
|
||||
msgid "Preview refund amount"
|
||||
msgstr "払い戻し金額のプレビュー"
|
||||
msgstr "払い戻し金額"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel.html:88
|
||||
msgid "Cancel all orders"
|
||||
msgstr "すべての注文をキャンセルします"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:13
|
||||
#, fuzzy
|
||||
#| msgid "If you contact us, please send us the following code:"
|
||||
msgid "If you proceed, the system will do the following:"
|
||||
msgstr "続行すると、システムは以下を実行します:"
|
||||
msgstr "お問い合わせの際は、以下のコードをお送りください:"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:19
|
||||
#, python-format
|
||||
msgid "%(count)s order will be canceled fully"
|
||||
msgid_plural "%(count)s orders will be canceled fully"
|
||||
msgstr[0] "%(count)s件の注文が全額キャンセルされます"
|
||||
msgstr[0] ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:26
|
||||
#, python-format
|
||||
msgid "%(count)s order will be canceled partially"
|
||||
msgid_plural "%(count)s orders will be canceled partially"
|
||||
msgstr[0] "%(count)s件の注文が一部キャンセルされます"
|
||||
msgstr[0] ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:36
|
||||
#, python-format
|
||||
msgid "%(amount)s are eligible for refunds."
|
||||
msgstr "%(amount)sが払い戻し対象です。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:40
|
||||
msgid ""
|
||||
"The system will attempt to refund the money automatically if supported by "
|
||||
"the payment method."
|
||||
msgstr "当該の決済方法に対応している場合、システムは自動的に払い戻しを試みます。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:42
|
||||
msgid "The system will create manual refunds that you need to execute."
|
||||
msgstr "システムは手動払い戻しを作成しますので、ご自身で実行する必要があります。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:44
|
||||
#, fuzzy
|
||||
#| msgid "Text (if order will not expire automatically)"
|
||||
msgid "Refunds will not happen automatically."
|
||||
msgstr "払い戻しは自動的には実行されません。"
|
||||
msgstr "テキスト(注文が自動的に期限切れにならない場合)"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:52
|
||||
#, fuzzy
|
||||
#| msgid "Send information via email"
|
||||
msgid "Inform all customers via email."
|
||||
msgstr "メールで情報を送信する。"
|
||||
msgstr "メールで情報を送信する"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:57
|
||||
msgid "Inform all waiting list contacts via email."
|
||||
msgstr "すべての空席待ちリストの連絡先にメールで通知する。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:62
|
||||
msgid ""
|
||||
"These numbers are estimates and may change if the data in your event "
|
||||
"recently changed."
|
||||
msgstr "これらの数値は推定値であり、イベントのデータが最近変更された場合は変わる可能"
|
||||
"性があります。"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:76
|
||||
#, python-format
|
||||
#, fuzzy, python-format
|
||||
#| msgid "Initiate a refund of %(amount)s"
|
||||
msgid "Proceed and refund approx. %(amount)s"
|
||||
msgstr "続行して約%(amount)sを払い戻す"
|
||||
msgstr "%(amount)sの払い戻しを開始する"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/cancel_confirm.html:80
|
||||
#, fuzzy
|
||||
#| msgid "Yes, cancel order"
|
||||
msgid "Proceed and cancel orders"
|
||||
msgstr "続行して注文をキャンセルする"
|
||||
msgstr "はい、注文をキャンセルします"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:5
|
||||
#: pretix/control/templates/pretixcontrol/orders/export.html:8
|
||||
@@ -24043,7 +24059,7 @@ msgstr "請求書はキャンセルされていません"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/index.html:251
|
||||
msgid "Sum over all pages"
|
||||
msgstr "全ページの合計"
|
||||
msgstr "すべてのページに渡り合計する"
|
||||
|
||||
#: pretix/control/templates/pretixcontrol/orders/index.html:254
|
||||
#, python-format
|
||||
@@ -30197,7 +30213,7 @@ msgstr "手動処理用の完全にカスタマイズ可能な支払い方法。
|
||||
#: pretix/plugins/paypal2/payment.py:1097
|
||||
#: pretix/plugins/paypal2/payment.py:1098 pretix/plugins/stripe/payment.py:1816
|
||||
msgid "PayPal"
|
||||
msgstr "PayPal"
|
||||
msgstr "ペイパル"
|
||||
|
||||
#: pretix/plugins/paypal/apps.py:53
|
||||
msgid ""
|
||||
@@ -30217,7 +30233,7 @@ msgstr ""
|
||||
|
||||
#: pretix/plugins/paypal/payment.py:104
|
||||
msgid "PayPal account"
|
||||
msgstr "PayPalアカウント"
|
||||
msgstr "ペイパルアカウント"
|
||||
|
||||
#: pretix/plugins/paypal/payment.py:117 pretix/plugins/paypal2/payment.py:114
|
||||
#, python-brace-format
|
||||
@@ -30314,7 +30330,7 @@ msgstr "PayPalの支払いID"
|
||||
|
||||
#: pretix/plugins/paypal/payment.py:711 pretix/plugins/paypal2/payment.py:1080
|
||||
msgid "PayPal sale ID"
|
||||
msgstr "PayPalの売上ID"
|
||||
msgstr "ペイパルの売上ID"
|
||||
|
||||
#: pretix/plugins/paypal/templates/pretixplugins/paypal/checkout_payment_confirm.html:3
|
||||
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/checkout_payment_confirm.html:19
|
||||
|
||||
@@ -26,7 +26,6 @@ from django.dispatch import receiver
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from pretix.base.logentrytype_registry import LogEntryType, log_entry_types
|
||||
from pretix.base.models import Checkin, OrderPayment
|
||||
from pretix.base.signals import (
|
||||
checkin_created, event_copy_data, item_copy_data, logentry_display,
|
||||
@@ -65,13 +64,19 @@ def nav_event_receiver(sender, request, **kwargs):
|
||||
]
|
||||
|
||||
|
||||
@log_entry_types.new_from_dict({
|
||||
"pretix.plugins.autocheckin.rule.added": _("An auto check-in rule was created"),
|
||||
"pretix.plugins.autocheckin.rule.changed": _("An auto check-in rule was updated"),
|
||||
"pretix.plugins.autocheckin.rule.deleted": _("An auto check-in rule was deleted"),
|
||||
})
|
||||
class AutocheckinLogEntryType(LogEntryType):
|
||||
pass
|
||||
@receiver(signal=logentry_display)
|
||||
def logentry_display_receiver(sender, logentry, **kwargs):
|
||||
plains = {
|
||||
"pretix.plugins.autocheckin.rule.added": _("An auto check-in rule was created"),
|
||||
"pretix.plugins.autocheckin.rule.changed": _(
|
||||
"An auto check-in rule was updated"
|
||||
),
|
||||
"pretix.plugins.autocheckin.rule.deleted": _(
|
||||
"An auto check-in rule was deleted"
|
||||
),
|
||||
}
|
||||
if logentry.action_type in plains:
|
||||
return plains[logentry.action_type]
|
||||
|
||||
|
||||
@receiver(item_copy_data, dispatch_uid="autocheckin_item_copy")
|
||||
|
||||
@@ -31,7 +31,6 @@ from django.utils.translation import gettext_lazy as _
|
||||
from paypalhttp import HttpResponse
|
||||
|
||||
from pretix.base.forms import SecretKeySettingsField
|
||||
from pretix.base.logentrytype_registry import LogEntryType, log_entry_types
|
||||
from pretix.base.middleware import _merge_csp, _parse_csp, _render_csp
|
||||
from pretix.base.settings import settings_hierarkey
|
||||
from pretix.base.signals import (
|
||||
@@ -81,36 +80,37 @@ def html_head_presale(sender, request=None, **kwargs):
|
||||
return ""
|
||||
|
||||
|
||||
@log_entry_types.new()
|
||||
class StripeEvent(LogEntryType):
|
||||
action_type = 'pretix.plugins.stripe.event'
|
||||
@receiver(signal=logentry_display, dispatch_uid="stripe_logentry_display")
|
||||
def pretixcontrol_logentry_display(sender, logentry, **kwargs):
|
||||
if logentry.action_type != 'pretix.plugins.stripe.event':
|
||||
return
|
||||
|
||||
def display(self, logentry, data):
|
||||
event_type = data.get('type')
|
||||
text = None
|
||||
plains = {
|
||||
'charge.succeeded': _('Charge succeeded.'),
|
||||
'charge.refunded': _('Charge refunded.'),
|
||||
'charge.updated': _('Charge updated.'),
|
||||
'charge.pending': _('Charge pending'),
|
||||
'source.chargeable': _('Payment authorized.'),
|
||||
'source.canceled': _('Payment authorization canceled.'),
|
||||
'source.failed': _('Payment authorization failed.')
|
||||
}
|
||||
data = json.loads(logentry.data)
|
||||
event_type = data.get('type')
|
||||
text = None
|
||||
plains = {
|
||||
'charge.succeeded': _('Charge succeeded.'),
|
||||
'charge.refunded': _('Charge refunded.'),
|
||||
'charge.updated': _('Charge updated.'),
|
||||
'charge.pending': _('Charge pending'),
|
||||
'source.chargeable': _('Payment authorized.'),
|
||||
'source.canceled': _('Payment authorization canceled.'),
|
||||
'source.failed': _('Payment authorization failed.')
|
||||
}
|
||||
|
||||
if event_type in plains:
|
||||
text = plains[event_type]
|
||||
elif event_type == 'charge.failed':
|
||||
text = _('Charge failed. Reason: {}').format(data['data']['object']['failure_message'])
|
||||
elif event_type == 'charge.dispute.created':
|
||||
text = _('Dispute created. Reason: {}').format(data['data']['object']['reason'])
|
||||
elif event_type == 'charge.dispute.updated':
|
||||
text = _('Dispute updated. Reason: {}').format(data['data']['object']['reason'])
|
||||
elif event_type == 'charge.dispute.closed':
|
||||
text = _('Dispute closed. Status: {}').format(data['data']['object']['status'])
|
||||
if event_type in plains:
|
||||
text = plains[event_type]
|
||||
elif event_type == 'charge.failed':
|
||||
text = _('Charge failed. Reason: {}').format(data['data']['object']['failure_message'])
|
||||
elif event_type == 'charge.dispute.created':
|
||||
text = _('Dispute created. Reason: {}').format(data['data']['object']['reason'])
|
||||
elif event_type == 'charge.dispute.updated':
|
||||
text = _('Dispute updated. Reason: {}').format(data['data']['object']['reason'])
|
||||
elif event_type == 'charge.dispute.closed':
|
||||
text = _('Dispute closed. Status: {}').format(data['data']['object']['status'])
|
||||
|
||||
if text:
|
||||
return _('Stripe reported an event: {}').format(text)
|
||||
if text:
|
||||
return _('Stripe reported an event: {}').format(text)
|
||||
|
||||
|
||||
settings_hierarkey.add_default('payment_stripe_method_card', True, bool)
|
||||
|
||||
@@ -9,6 +9,34 @@
|
||||
{% endblock %}
|
||||
{% block inner %}
|
||||
<h3 class="sr-only">{% trans "Payment" %}</h3>
|
||||
{% if customer_gift_cards %}
|
||||
<p><strong>
|
||||
<span class="sr-only">{% trans "Information" %}</span>
|
||||
{% trans "The following gift cards are available in your customer account:" %}
|
||||
</strong></p>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<ul class="list-group">
|
||||
{% for c in customer_gift_cards %}
|
||||
<li class="list-group-item row">
|
||||
<div class="col-xs-9" id="gc-code-{{ forloop.counter }}">
|
||||
{{ c }}
|
||||
</div>
|
||||
<div class="col-xs-2 text-right" id="gc-value-{{ forloop.counter }}">
|
||||
{{ c.value|money:c.currency }}
|
||||
</div>
|
||||
<div class="col-xs-1 text-right">
|
||||
<button name="use_giftcard" value="{{ c.secret }}" title="{% trans "Use gift card" %}"
|
||||
aria-describedby="gc-code-{{ forloop.counter }} gc-value-{{ forloop.counter }}"
|
||||
class="btn btn-primary btn-xs">
|
||||
{% trans "Apply" %}
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if current_payments %}
|
||||
<p>{% trans "You already selected the following payment methods:" %}</p>
|
||||
<form method="post">
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
{% load i18n %}
|
||||
{% load bootstrap3 %}
|
||||
{% load money %}
|
||||
{% load rich_text %}
|
||||
|
||||
{{ request.event.settings.payment_giftcard_public_description|rich_text }}
|
||||
{% if customer_gift_cards %}
|
||||
<p><strong>
|
||||
<span class="sr-only">{% trans "Information" %}</span>
|
||||
{% trans "The following gift cards are available in your customer account:" %}
|
||||
</strong></p>
|
||||
{% csrf_token %}
|
||||
<ul class="list-group">
|
||||
{% for c in customer_gift_cards %}
|
||||
<li class="list-group-item row row-no-gutters">
|
||||
<div class="col-sm-8 col-md-9" id="gc-code-{{ forloop.counter }}">
|
||||
{{ c }}
|
||||
</div>
|
||||
<div class="col-sm-2 text-right" id="gc-value-{{ forloop.counter }}">
|
||||
{{ c.value|money:c.currency }}
|
||||
</div>
|
||||
<div class="col-sm-2 col-md-1 text-right">
|
||||
<button name="use_giftcard" class="btn btn-primary btn-xs use_giftcard" data-value="{{ c.secret }}"
|
||||
title="{% trans "Use gift card" %}"
|
||||
aria-describedby="gc-code-{{ forloop.counter }} gc-value-{{ forloop.counter }}">
|
||||
{% trans "Apply" %}
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% bootstrap_form form layout='checkout' %}
|
||||
371
src/pretix/static/npm_dir/package-lock.json
generated
371
src/pretix/static/npm_dir/package-lock.json
generated
@@ -8,10 +8,10 @@
|
||||
"name": "pretix",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/preset-env": "^7.28.5",
|
||||
"@rollup/plugin-babel": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@babel/core": "^7.28.4",
|
||||
"@babel/preset-env": "^7.28.3",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-vue": "^5.0.1",
|
||||
"vue": "^2.7.16",
|
||||
@@ -33,27 +33,27 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
|
||||
"integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
|
||||
"integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz",
|
||||
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/generator": "^7.28.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-module-transforms": "^7.28.3",
|
||||
"@babel/helpers": "^7.28.4",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/parser": "^7.28.4",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/traverse": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.4",
|
||||
"@babel/types": "^7.28.4",
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"debug": "^4.1.0",
|
||||
@@ -89,12 +89,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
|
||||
"integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
|
||||
"integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/parser": "^7.28.3",
|
||||
"@babel/types": "^7.28.2",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
@@ -348,9 +348,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -391,11 +392,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
|
||||
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
|
||||
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.5"
|
||||
"@babel/types": "^7.28.4"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@@ -405,12 +406,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz",
|
||||
"integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz",
|
||||
"integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.5"
|
||||
"@babel/traverse": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -601,9 +603,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz",
|
||||
"integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz",
|
||||
"integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -646,16 +648,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-classes": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
|
||||
"integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.3.tgz",
|
||||
"integrity": "sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
"@babel/traverse": "^7.28.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -681,12 +683,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-destructuring": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
|
||||
"integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz",
|
||||
"integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.5"
|
||||
"@babel/traverse": "^7.28.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -773,9 +775,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-exponentiation-operator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz",
|
||||
"integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz",
|
||||
"integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -865,9 +868,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz",
|
||||
"integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz",
|
||||
"integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -926,14 +930,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-modules-systemjs": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz",
|
||||
"integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz",
|
||||
"integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-transforms": "^7.28.3",
|
||||
"@babel/helper-module-transforms": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.5"
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1020,15 +1025,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-object-rest-spread": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz",
|
||||
"integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz",
|
||||
"integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==",
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.0",
|
||||
"@babel/plugin-transform-parameters": "^7.27.7",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
"@babel/traverse": "^7.28.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1069,9 +1074,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-optional-chaining": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz",
|
||||
"integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
|
||||
"integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
|
||||
@@ -1146,9 +1152,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-regenerator": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
|
||||
"integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.3.tgz",
|
||||
"integrity": "sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
@@ -1330,15 +1336,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/preset-env": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz",
|
||||
"integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz",
|
||||
"integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.28.5",
|
||||
"@babel/compat-data": "^7.28.0",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-validator-option": "^7.27.1",
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5",
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1",
|
||||
"@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1",
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1",
|
||||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1",
|
||||
@@ -1351,42 +1357,42 @@
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.28.0",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.27.1",
|
||||
"@babel/plugin-transform-block-scoped-functions": "^7.27.1",
|
||||
"@babel/plugin-transform-block-scoping": "^7.28.5",
|
||||
"@babel/plugin-transform-block-scoping": "^7.28.0",
|
||||
"@babel/plugin-transform-class-properties": "^7.27.1",
|
||||
"@babel/plugin-transform-class-static-block": "^7.28.3",
|
||||
"@babel/plugin-transform-classes": "^7.28.4",
|
||||
"@babel/plugin-transform-classes": "^7.28.3",
|
||||
"@babel/plugin-transform-computed-properties": "^7.27.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.5",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.0",
|
||||
"@babel/plugin-transform-dotall-regex": "^7.27.1",
|
||||
"@babel/plugin-transform-duplicate-keys": "^7.27.1",
|
||||
"@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1",
|
||||
"@babel/plugin-transform-dynamic-import": "^7.27.1",
|
||||
"@babel/plugin-transform-explicit-resource-management": "^7.28.0",
|
||||
"@babel/plugin-transform-exponentiation-operator": "^7.28.5",
|
||||
"@babel/plugin-transform-exponentiation-operator": "^7.27.1",
|
||||
"@babel/plugin-transform-export-namespace-from": "^7.27.1",
|
||||
"@babel/plugin-transform-for-of": "^7.27.1",
|
||||
"@babel/plugin-transform-function-name": "^7.27.1",
|
||||
"@babel/plugin-transform-json-strings": "^7.27.1",
|
||||
"@babel/plugin-transform-literals": "^7.27.1",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.28.5",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.27.1",
|
||||
"@babel/plugin-transform-member-expression-literals": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-amd": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.28.5",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-umd": "^7.27.1",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1",
|
||||
"@babel/plugin-transform-new-target": "^7.27.1",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.27.1",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.28.4",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.28.0",
|
||||
"@babel/plugin-transform-object-super": "^7.27.1",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.27.1",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.28.5",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.27.1",
|
||||
"@babel/plugin-transform-parameters": "^7.27.7",
|
||||
"@babel/plugin-transform-private-methods": "^7.27.1",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.27.1",
|
||||
"@babel/plugin-transform-property-literals": "^7.27.1",
|
||||
"@babel/plugin-transform-regenerator": "^7.28.4",
|
||||
"@babel/plugin-transform-regenerator": "^7.28.3",
|
||||
"@babel/plugin-transform-regexp-modifiers": "^7.27.1",
|
||||
"@babel/plugin-transform-reserved-words": "^7.27.1",
|
||||
"@babel/plugin-transform-shorthand-properties": "^7.27.1",
|
||||
@@ -1448,16 +1454,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
|
||||
"integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz",
|
||||
"integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/generator": "^7.28.3",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/parser": "^7.28.4",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/types": "^7.28.4",
|
||||
"debug": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1465,12 +1471,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
|
||||
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
|
||||
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
"@babel/helper-validator-identifier": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@@ -1517,9 +1523,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-babel": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.1.0.tgz",
|
||||
"integrity": "sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==",
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz",
|
||||
"integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.18.6",
|
||||
"@rollup/pluginutils": "^5.0.1"
|
||||
@@ -1542,9 +1548,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "16.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz",
|
||||
"integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==",
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz",
|
||||
"integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
@@ -3783,24 +3790,24 @@
|
||||
}
|
||||
},
|
||||
"@babel/compat-data": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz",
|
||||
"integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
|
||||
"integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="
|
||||
},
|
||||
"@babel/core": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz",
|
||||
"integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/generator": "^7.28.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-module-transforms": "^7.28.3",
|
||||
"@babel/helpers": "^7.28.4",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/parser": "^7.28.4",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/traverse": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.4",
|
||||
"@babel/types": "^7.28.4",
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"debug": "^4.1.0",
|
||||
@@ -3822,12 +3829,12 @@
|
||||
}
|
||||
},
|
||||
"@babel/generator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
|
||||
"integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
|
||||
"integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
|
||||
"requires": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/parser": "^7.28.3",
|
||||
"@babel/types": "^7.28.2",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
@@ -4004,9 +4011,9 @@
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="
|
||||
},
|
||||
"@babel/helper-validator-option": {
|
||||
"version": "7.27.1",
|
||||
@@ -4033,20 +4040,20 @@
|
||||
}
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
|
||||
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz",
|
||||
"integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.28.5"
|
||||
"@babel/types": "^7.28.4"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz",
|
||||
"integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz",
|
||||
"integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.5"
|
||||
"@babel/traverse": "^7.27.1"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-bugfix-safari-class-field-initializer-scope": {
|
||||
@@ -4152,9 +4159,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz",
|
||||
"integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz",
|
||||
"integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
}
|
||||
@@ -4178,16 +4185,16 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-classes": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz",
|
||||
"integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.3.tgz",
|
||||
"integrity": "sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==",
|
||||
"requires": {
|
||||
"@babel/helper-annotate-as-pure": "^7.27.3",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-replace-supers": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
"@babel/traverse": "^7.28.3"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-computed-properties": {
|
||||
@@ -4200,12 +4207,12 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-destructuring": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz",
|
||||
"integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz",
|
||||
"integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.5"
|
||||
"@babel/traverse": "^7.28.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-dotall-regex": {
|
||||
@@ -4252,9 +4259,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-exponentiation-operator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz",
|
||||
"integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz",
|
||||
"integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
}
|
||||
@@ -4303,9 +4310,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-logical-assignment-operators": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz",
|
||||
"integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz",
|
||||
"integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
}
|
||||
@@ -4337,14 +4344,14 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-systemjs": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz",
|
||||
"integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz",
|
||||
"integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==",
|
||||
"requires": {
|
||||
"@babel/helper-module-transforms": "^7.28.3",
|
||||
"@babel/helper-module-transforms": "^7.27.1",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5",
|
||||
"@babel/traverse": "^7.28.5"
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-modules-umd": {
|
||||
@@ -4390,15 +4397,15 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-object-rest-spread": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz",
|
||||
"integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==",
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz",
|
||||
"integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==",
|
||||
"requires": {
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.0",
|
||||
"@babel/plugin-transform-parameters": "^7.27.7",
|
||||
"@babel/traverse": "^7.28.4"
|
||||
"@babel/traverse": "^7.28.0"
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-object-super": {
|
||||
@@ -4419,9 +4426,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-optional-chaining": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz",
|
||||
"integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz",
|
||||
"integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.27.1"
|
||||
@@ -4463,9 +4470,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-transform-regenerator": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz",
|
||||
"integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.3.tgz",
|
||||
"integrity": "sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==",
|
||||
"requires": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
}
|
||||
@@ -4564,15 +4571,15 @@
|
||||
}
|
||||
},
|
||||
"@babel/preset-env": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz",
|
||||
"integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==",
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz",
|
||||
"integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==",
|
||||
"requires": {
|
||||
"@babel/compat-data": "^7.28.5",
|
||||
"@babel/compat-data": "^7.28.0",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-plugin-utils": "^7.27.1",
|
||||
"@babel/helper-validator-option": "^7.27.1",
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5",
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1",
|
||||
"@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1",
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1",
|
||||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1",
|
||||
@@ -4585,42 +4592,42 @@
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.28.0",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.27.1",
|
||||
"@babel/plugin-transform-block-scoped-functions": "^7.27.1",
|
||||
"@babel/plugin-transform-block-scoping": "^7.28.5",
|
||||
"@babel/plugin-transform-block-scoping": "^7.28.0",
|
||||
"@babel/plugin-transform-class-properties": "^7.27.1",
|
||||
"@babel/plugin-transform-class-static-block": "^7.28.3",
|
||||
"@babel/plugin-transform-classes": "^7.28.4",
|
||||
"@babel/plugin-transform-classes": "^7.28.3",
|
||||
"@babel/plugin-transform-computed-properties": "^7.27.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.5",
|
||||
"@babel/plugin-transform-destructuring": "^7.28.0",
|
||||
"@babel/plugin-transform-dotall-regex": "^7.27.1",
|
||||
"@babel/plugin-transform-duplicate-keys": "^7.27.1",
|
||||
"@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1",
|
||||
"@babel/plugin-transform-dynamic-import": "^7.27.1",
|
||||
"@babel/plugin-transform-explicit-resource-management": "^7.28.0",
|
||||
"@babel/plugin-transform-exponentiation-operator": "^7.28.5",
|
||||
"@babel/plugin-transform-exponentiation-operator": "^7.27.1",
|
||||
"@babel/plugin-transform-export-namespace-from": "^7.27.1",
|
||||
"@babel/plugin-transform-for-of": "^7.27.1",
|
||||
"@babel/plugin-transform-function-name": "^7.27.1",
|
||||
"@babel/plugin-transform-json-strings": "^7.27.1",
|
||||
"@babel/plugin-transform-literals": "^7.27.1",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.28.5",
|
||||
"@babel/plugin-transform-logical-assignment-operators": "^7.27.1",
|
||||
"@babel/plugin-transform-member-expression-literals": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-amd": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.28.5",
|
||||
"@babel/plugin-transform-modules-systemjs": "^7.27.1",
|
||||
"@babel/plugin-transform-modules-umd": "^7.27.1",
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1",
|
||||
"@babel/plugin-transform-new-target": "^7.27.1",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.27.1",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.28.4",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.28.0",
|
||||
"@babel/plugin-transform-object-super": "^7.27.1",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.27.1",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.28.5",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.27.1",
|
||||
"@babel/plugin-transform-parameters": "^7.27.7",
|
||||
"@babel/plugin-transform-private-methods": "^7.27.1",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.27.1",
|
||||
"@babel/plugin-transform-property-literals": "^7.27.1",
|
||||
"@babel/plugin-transform-regenerator": "^7.28.4",
|
||||
"@babel/plugin-transform-regenerator": "^7.28.3",
|
||||
"@babel/plugin-transform-regexp-modifiers": "^7.27.1",
|
||||
"@babel/plugin-transform-reserved-words": "^7.27.1",
|
||||
"@babel/plugin-transform-shorthand-properties": "^7.27.1",
|
||||
@@ -4668,26 +4675,26 @@
|
||||
}
|
||||
},
|
||||
"@babel/traverse": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
|
||||
"integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz",
|
||||
"integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==",
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/generator": "^7.28.3",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/parser": "^7.28.4",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@babel/types": "^7.28.4",
|
||||
"debug": "^4.3.1"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
|
||||
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz",
|
||||
"integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==",
|
||||
"requires": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
"@babel/helper-validator-identifier": "^7.27.1"
|
||||
}
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
@@ -4728,18 +4735,18 @@
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-babel": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.1.0.tgz",
|
||||
"integrity": "sha512-dFZNuFD2YRcoomP4oYf+DvQNSUA9ih+A3vUqopQx5EdtPGo3WBnQcI/S8pwpz91UsGfL0HsMSOlaMld8HrbubA==",
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz",
|
||||
"integrity": "sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==",
|
||||
"requires": {
|
||||
"@babel/helper-module-imports": "^7.18.6",
|
||||
"@rollup/pluginutils": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-node-resolve": {
|
||||
"version": "16.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz",
|
||||
"integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==",
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz",
|
||||
"integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==",
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
"private": true,
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.28.5",
|
||||
"@babel/preset-env": "^7.28.5",
|
||||
"@rollup/plugin-babel": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@babel/core": "^7.28.4",
|
||||
"@babel/preset-env": "^7.28.3",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"vue": "^2.7.16",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-vue": "^5.0.1",
|
||||
|
||||
@@ -263,3 +263,11 @@ svg.svg-icon {
|
||||
@include table-row-variant('warning', var(--pretix-brand-warning-lighten-40), var(--pretix-brand-warning-lighten-35));
|
||||
@include table-row-variant('danger', var(--pretix-brand-danger-lighten-30), var(--pretix-brand-danger-lighten-25));
|
||||
|
||||
.confirmation-code-input {
|
||||
font-size: 200%;
|
||||
font-family: monospace;
|
||||
font-stretch: expanded;
|
||||
text-align: center;
|
||||
height: 50px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
@@ -938,3 +938,25 @@ details {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: $screen-lg-min) {
|
||||
.centered-form {
|
||||
margin: 80px auto;
|
||||
max-width: 800px;
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px 40px 0;
|
||||
border-radius: 4px;
|
||||
box-shadow: 2px 2px 2px #eee;
|
||||
}
|
||||
|
||||
.form.centered-form .submit-group {
|
||||
margin: 25px -40px 0 !important;
|
||||
padding-right: 40px;
|
||||
padding-left: 40px;
|
||||
}
|
||||
|
||||
.centered-form p {
|
||||
margin: 20px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1134,7 +1134,7 @@ class PasswordChangeRequiredTest(TestCase):
|
||||
super().setUp()
|
||||
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
|
||||
|
||||
def test_redirect_to_settings(self):
|
||||
def test_redirect_to_password_change(self):
|
||||
self.user.needs_password_change = True
|
||||
self.user.save()
|
||||
self.client.login(email='dummy@dummy.dummy', password='dummy')
|
||||
@@ -1143,9 +1143,9 @@ class PasswordChangeRequiredTest(TestCase):
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
assert self.user.needs_password_change is True
|
||||
self.assertIn('/control/settings?next=/control/events/', response['Location'])
|
||||
self.assertIn('/control/settings/password/change?next=/control/events/', response['Location'])
|
||||
|
||||
def test_redirect_to_2fa_to_settings(self):
|
||||
def test_redirect_to_2fa_to_password_change(self):
|
||||
self.user.require_2fa = True
|
||||
self.user.needs_password_change = True
|
||||
self.user.save()
|
||||
@@ -1168,4 +1168,4 @@ class PasswordChangeRequiredTest(TestCase):
|
||||
response = self.client.get('/control/events/')
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertIn('/control/settings?next=/control/events/', response['Location'])
|
||||
self.assertIn('/control/settings/password/change?next=/control/events/', response['Location'])
|
||||
|
||||
@@ -19,22 +19,11 @@
|
||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||||
# <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of
|
||||
# the Apache License 2.0 can be obtained at <http://www.apache.org/licenses/LICENSE-2.0>.
|
||||
#
|
||||
# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A
|
||||
# full history of changes and contributors is available at <https://github.com/pretix/pretix>.
|
||||
#
|
||||
# This file contains Apache-licensed contributions copyrighted by: Jason Estibeiro
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
|
||||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
import re
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from django.core import mail as djmail
|
||||
from django.utils.timezone import now
|
||||
from django_otp.oath import TOTP
|
||||
from django_otp.plugins.otp_static.models import StaticDevice
|
||||
@@ -56,7 +45,7 @@ class UserSettingsTest(SoupTest):
|
||||
self.user = User.objects.create_user('dummy@dummy.dummy', 'barfoofoo')
|
||||
self.client.login(email='dummy@dummy.dummy', password='barfoofoo')
|
||||
doc = self.get_doc('/control/settings')
|
||||
self.form_data = extract_form_fields(doc.select('.container-fluid form')[0])
|
||||
self.form_data = extract_form_fields(doc.select('form[data-testid="usersettingsform"]')[0])
|
||||
|
||||
def save(self, data):
|
||||
form_data = self.form_data.copy()
|
||||
@@ -71,33 +60,107 @@ class UserSettingsTest(SoupTest):
|
||||
self.user = User.objects.get(pk=self.user.pk)
|
||||
assert self.user.fullname == 'Peter Miller'
|
||||
|
||||
def test_change_email_require_password(self):
|
||||
def test_set_locale_and_timezone(self):
|
||||
doc = self.save({
|
||||
'email': 'foo@example.com',
|
||||
'locale': 'fr',
|
||||
'timezone': 'Europe/Paris',
|
||||
})
|
||||
assert doc.select(".alert-danger")
|
||||
assert doc.select(".alert-success")
|
||||
self.user = User.objects.get(pk=self.user.pk)
|
||||
assert self.user.email == 'dummy@dummy.dummy'
|
||||
assert self.user.locale == 'fr'
|
||||
assert self.user.timezone == 'Europe/Paris'
|
||||
|
||||
|
||||
class UserEmailChangeTest(SoupTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = User.objects.create_user('dummy@dummy.dummy', 'barfoofoo')
|
||||
self.client.login(email='dummy@dummy.dummy', password='barfoofoo')
|
||||
session = self.client.session
|
||||
session['pretix_auth_login_time'] = int(time.time())
|
||||
session.save()
|
||||
doc = self.get_doc('/control/settings/email/change')
|
||||
self.form_data = extract_form_fields(doc.select('.container-fluid form')[0])
|
||||
|
||||
def test_require_reauth(self):
|
||||
session = self.client.session
|
||||
session['pretix_auth_login_time'] = int(time.time()) - 3600 * 2
|
||||
session.save()
|
||||
|
||||
response = self.client.get('/control/settings/email/change')
|
||||
self.assertIn('/control/reauth', response['Location'])
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
response = self.client.post('/control/reauth/?next=/control/settings/email/change', {
|
||||
'password': 'barfoofoo'
|
||||
})
|
||||
self.assertIn('/control/settings/email/change', response['Location'])
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def submit_step_1(self, data):
|
||||
form_data = self.form_data.copy()
|
||||
form_data.update(data)
|
||||
return self.post_doc('/control/settings/email/change', form_data)
|
||||
|
||||
def submit_step_2(self, data):
|
||||
form_data = self.form_data.copy()
|
||||
form_data.update(data)
|
||||
return self.post_doc('/control/settings/email/confirm?reason=email_change', form_data)
|
||||
|
||||
def test_change_email_success(self):
|
||||
doc = self.save({
|
||||
'email': 'foo@example.com',
|
||||
'old_pw': 'barfoofoo'
|
||||
djmail.outbox = []
|
||||
doc = self.submit_step_1({
|
||||
'new_email': 'foo@example.com',
|
||||
})
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == ['foo@example.com']
|
||||
code = re.search("[0-9]{7}", djmail.outbox[0].body).group(0)
|
||||
doc = self.submit_step_2({
|
||||
'code': code,
|
||||
})
|
||||
assert doc.select(".alert-success")
|
||||
self.user = User.objects.get(pk=self.user.pk)
|
||||
assert self.user.email == 'foo@example.com'
|
||||
|
||||
def test_change_email_no_duplicates(self):
|
||||
User.objects.create_user('foo@example.com', 'foo')
|
||||
doc = self.save({
|
||||
'email': 'foo@example.com',
|
||||
'old_pw': 'barfoofoo'
|
||||
def test_change_email_wrong_code(self):
|
||||
djmail.outbox = []
|
||||
doc = self.submit_step_1({
|
||||
'new_email': 'foo@example.com',
|
||||
})
|
||||
assert len(djmail.outbox) == 1
|
||||
assert djmail.outbox[0].to == ['foo@example.com']
|
||||
code = re.search("[0-9]{7}", djmail.outbox[0].body).group(0)
|
||||
wrong_code = '0000000' if code == '1234567' else '1234567'
|
||||
doc = self.submit_step_2({
|
||||
'code': wrong_code,
|
||||
})
|
||||
assert doc.select(".alert-danger")
|
||||
self.user = User.objects.get(pk=self.user.pk)
|
||||
assert self.user.email == 'dummy@dummy.dummy'
|
||||
|
||||
def test_change_email_no_duplicates(self):
|
||||
User.objects.create_user('foo@example.com', 'foo')
|
||||
doc = self.submit_step_1({
|
||||
'new_email': 'foo@example.com',
|
||||
})
|
||||
assert doc.select(".alert-danger")
|
||||
self.user = User.objects.get(pk=self.user.pk)
|
||||
assert self.user.email == 'dummy@dummy.dummy'
|
||||
|
||||
|
||||
class UserPasswordChangeTest(SoupTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.user = User.objects.create_user('dummy@dummy.dummy', 'barfoofoo')
|
||||
self.client.login(email='dummy@dummy.dummy', password='barfoofoo')
|
||||
doc = self.get_doc('/control/settings/password/change')
|
||||
self.form_data = extract_form_fields(doc.select('.container-fluid form')[0])
|
||||
|
||||
def save(self, data):
|
||||
form_data = self.form_data.copy()
|
||||
form_data.update(data)
|
||||
return self.post_doc('/control/settings/password/change', form_data)
|
||||
|
||||
def test_change_password_require_password(self):
|
||||
doc = self.save({
|
||||
'new_pw': 'foo',
|
||||
@@ -193,18 +256,6 @@ class UserSettingsTest(SoupTest):
|
||||
})
|
||||
assert doc.select(".alert-danger")
|
||||
|
||||
def test_needs_password_change(self):
|
||||
self.user.needs_password_change = True
|
||||
self.user.save()
|
||||
doc = self.save({
|
||||
'email': 'foo@example.com',
|
||||
'old_pw': 'barfoofoo'
|
||||
})
|
||||
assert doc.select(".alert-success")
|
||||
assert doc.select(".alert-warning")
|
||||
self.user.refresh_from_db()
|
||||
assert self.user.needs_password_change is True
|
||||
|
||||
def test_needs_password_change_changed(self):
|
||||
self.user.needs_password_change = True
|
||||
self.user.save()
|
||||
|
||||
Reference in New Issue
Block a user