Compare commits

..

15 Commits

Author SHA1 Message Date
Mira Weller
2ecf81bdfe Experimental organizer-level plugin implementation 2024-09-23 18:45:33 +02:00
Mira Weller
e395834811 Fix circular imports 2024-09-23 18:45:20 +02:00
Mira Weller
86a32d7856 Add inline "json_script" as supported data source for select2 2024-09-23 18:44:16 +02:00
Mira Weller
47e8549f19 Add full_code property to OrderPosition 2024-09-23 18:43:18 +02:00
Mira Weller
47b84c06b0 code style 2024-09-03 12:06:18 +02:00
Mira Weller
204bc84e85 move logentrytypes to own module 2024-09-02 17:44:01 +02:00
Mira Weller
0487d5803b move CORE_MODULES to base settings so it's already available when registering types 2024-09-02 17:43:31 +02:00
Mira Weller
a94c89ba4f add shredder mixins 2024-09-02 17:43:31 +02:00
Mira Weller
2045009e2e refactor signal receiver active check 2024-09-02 17:43:31 +02:00
Mira Weller
9269a485a6 store plugin name for registered types 2024-09-02 17:43:31 +02:00
Mira Weller
166f50fcb0 refactor: simplify is_active / core_module logic 2024-09-02 17:43:31 +02:00
Mira Weller
a3358bae6b migrate from logentry_display signal to LogEntryTypes 2024-09-02 17:43:27 +02:00
Mira Weller
a3164a94b7 refactor: use logentry.parsed_data 2024-09-02 17:38:52 +02:00
Mira Weller
f56df892e3 remove dead code 2024-09-02 17:38:52 +02:00
Mira Weller
093a0db182 implement registration facility for log entry types 2024-09-02 17:38:52 +02:00
62 changed files with 2841 additions and 33261 deletions

View File

@@ -20,9 +20,8 @@ internal_name string An optional nam
rate decimal (string) Tax rate in percent
price_includes_tax boolean If ``true`` (default), tax is assumed to be included in
the specified product price
eu_reverse_charge boolean **DEPRECATED**. If ``true``, EU reverse charge rules
are applied. Will be ignored if custom rules are set.
Use custom rules instead.
eu_reverse_charge boolean If ``true``, EU reverse charge rules are applied. Will
be ignored if custom rules are set.
home_country string Merchant country (required for reverse charge), can be
``null`` or empty string
keep_gross_if_rate_changes boolean If ``true``, changes of the tax rate based on custom

View File

@@ -175,7 +175,7 @@ without any special behavior.
Connecting SSO providers (pretix as the SSO client)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To connect an external application as a SSO provider, go to "Customer accounts" → "SSO providers" → "Create a new SSO provider"
To connect an external application as a SSO client, go to "Customer accounts" → "SSO providers" → "Create a new SSO provider"
in your organizer account.
.. thumbnail:: ../../screens/organizer/customer_ssoprovider_add.png

View File

@@ -36,7 +36,7 @@ dependencies = [
"css-inline==0.14.*",
"defusedcsv>=1.1.0",
"Django[argon2]==4.2.*,>=4.2.15",
"django-bootstrap3==24.3",
"django-bootstrap3==24.2",
"django-compressor==4.5.1",
"django-countries==7.6.*",
"django-filter==24.3",
@@ -81,7 +81,7 @@ dependencies = [
"pycountry",
"pycparser==2.22",
"pycryptodome==3.20.*",
"pypdf==5.0.*",
"pypdf==4.3.*",
"python-bidi==0.6.*", # Support for Arabic in reportlab
"python-dateutil==2.9.*",
"pytz",
@@ -91,7 +91,7 @@ dependencies = [
"redis==5.0.*",
"reportlab==4.2.*",
"requests==2.31.*",
"sentry-sdk==2.14.*",
"sentry-sdk==2.13.*",
"sepaxml==2.6.*",
"slimit",
"stripe==7.9.*",

View File

@@ -75,6 +75,14 @@ FORMAT_MODULE_PATH = [
'pretix.helpers.formats',
]
CORE_MODULES = {
"pretix.base",
"pretix.presale",
"pretix.control",
"pretix.plugins.checkinlists",
"pretix.plugins.reports",
}
ALL_LANGUAGES = [
('en', _('English')),
('de', _('German')),

View File

@@ -32,16 +32,13 @@
# 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 string
from collections import OrderedDict
from importlib import import_module
from django import forms
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.hashers import check_password, make_password
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _, ngettext
from django.utils.translation import gettext_lazy as _
def get_auth_backends():
@@ -163,62 +160,3 @@ class NativeAuthBackend(BaseAuthBackend):
u = authenticate(request=request, email=form_data['email'].lower(), password=form_data['password'])
if u and u.auth_backend == self.identifier:
return u
class NumericAndAlphabeticPasswordValidator:
def validate(self, password, user=None):
has_numeric = any(c in string.digits for c in password)
has_alpha = any(c in string.ascii_letters for c in password)
if not has_numeric or not has_alpha:
raise ValidationError(
_(
"Your password must contain both numeric and alphabetic characters.",
),
code="password_numeric_and_alphabetic",
)
def get_help_text(self):
return _(
"Your password must contain both numeric and alphabetic characters.",
)
class HistoryPasswordValidator:
def __init__(self, history_length=4):
self.history_length = history_length
def validate(self, password, user=None):
from pretix.base.models import User
if not user or not user.pk or not isinstance(user, User):
return
for hp in user.historic_passwords.order_by("-created")[:self.history_length]:
if check_password(password, hp.password):
raise ValidationError(
ngettext(
"Your password may not be the same as your previous password.",
"Your password may not be the same as one of your %(history_length)s previous passwords.",
self.history_length,
),
code="password_history",
params={"history_length": self.history_length},
)
def get_help_text(self):
return ngettext(
"Your password may not be the same as your previous password.",
"Your password may not be the same as one of your %(history_length)s previous passwords.",
self.history_length,
) % {"history_length": self.history_length}
def password_changed(self, password, user=None):
if not user:
pass
user.historic_passwords.create(password=make_password(password))
user.historic_passwords.filter(
pk__in=user.historic_passwords.order_by("-created")[self.history_length:].values_list("pk", flat=True),
).delete()

View File

@@ -46,8 +46,6 @@ This module contains utilities for implementing OpenID Connect for customer auth
as well as an OpenID Provider (OP).
"""
pretix_token_endpoint_auth_methods = ['client_secret_basic', 'client_secret_post']
def _urljoin(base, path):
if not base.endswith("/"):
@@ -129,16 +127,6 @@ def oidc_validate_and_complete_config(config):
fields=", ".join(provider_config.get("claims_supported", []))
))
if "token_endpoint_auth_methods_supported" in provider_config:
token_endpoint_auth_methods_supported = provider_config.get("token_endpoint_auth_methods_supported",
["client_secret_basic"])
if not any(x in pretix_token_endpoint_auth_methods for x in token_endpoint_auth_methods_supported):
raise ValidationError(
_(f'No supported Token Endpoint Auth Methods supported: {token_endpoint_auth_methods_supported}').format(
token_endpoint_auth_methods_supported=", ".join(token_endpoint_auth_methods_supported)
)
)
config['provider_config'] = provider_config
return config
@@ -159,18 +147,6 @@ def oidc_authorize_url(provider, state, redirect_uri):
def oidc_validate_authorization(provider, code, redirect_uri):
endpoint = provider.configuration['provider_config']['token_endpoint']
# Wall of shame and RFC ignorant IDPs
if endpoint == 'https://www.linkedin.com/oauth/v2/accessToken':
token_endpoint_auth_method = 'client_secret_post'
else:
token_endpoint_auth_methods = provider.configuration['provider_config'].get(
'token_endpoint_auth_methods_supported', ['client_secret_basic']
)
token_endpoint_auth_method = [
x for x in pretix_token_endpoint_auth_methods if x in token_endpoint_auth_methods
][0]
params = {
# https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
# https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint
@@ -178,11 +154,6 @@ def oidc_validate_authorization(provider, code, redirect_uri):
'code': code,
'redirect_uri': redirect_uri,
}
if token_endpoint_auth_method == 'client_secret_post':
params['client_id'] = provider.configuration['client_id']
params['client_secret'] = provider.configuration['client_secret']
try:
resp = requests.post(
endpoint,
@@ -190,10 +161,7 @@ def oidc_validate_authorization(provider, code, redirect_uri):
headers={
'Accept': 'application/json',
},
auth=(
provider.configuration['client_id'],
provider.configuration['client_secret']
) if token_endpoint_auth_method == 'client_secret_basic' else None,
auth=(provider.configuration['client_id'], provider.configuration['client_secret']),
)
resp.raise_for_status()
data = resp.json()

View File

@@ -0,0 +1,164 @@
from collections import defaultdict
from django.urls import reverse
from django.utils.html import escape
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from pretix.base.signals import PluginRegistry
def make_link(a_map, wrapper, is_active=True, event=None, plugin_name=None):
if a_map:
if is_active:
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
elif event and plugin_name:
a_map['val'] = (
'<i>{val}</i> <a href="{plugin_href}">'
'<span data-toggle="tooltip" title="{errmes}" class="fa fa-warning fa-fw"></span></a>'
).format_map({
**a_map,
"errmes": _("The relevant plugin is currently not active. To activate it, click here to go to the plugin settings."),
"plugin_href": reverse('control:event.settings.plugins', kwargs={
'organizer': event.organizer.slug,
'event': event.slug,
}) + '#plugin_' + plugin_name,
})
else:
a_map['val'] = '<i>{val}</i> <span data-toggle="tooltip" title="{errmes}" class="fa fa-warning fa-fw"></span>'.format_map({
**a_map,
"errmes": _("The relevant plugin is currently not active."),
})
return wrapper.format_map(a_map)
class LogEntryTypeRegistry(PluginRegistry):
def new_from_dict(self, data):
def reg(clz):
for action_type, plain in data.items():
self.register(clz(action_type=action_type, plain=plain))
return reg
log_entry_types = LogEntryTypeRegistry({'action_type': lambda o: getattr(o, 'action_type')})
class LogEntryType:
def __init__(self, action_type=None, plain=None):
assert self.__module__ != LogEntryType.__module__ # must not instantiate base classes, only derived ones
if action_type:
self.action_type = action_type
if plain:
self.plain = plain
def display(self, logentry):
if hasattr(self, 'plain'):
plain = str(self.plain)
if '{' in plain:
data = defaultdict(lambda: '?', logentry.parsed_data)
return plain.format_map(data)
else:
return plain
def get_object_link_info(self, logentry) -> dict:
pass
def get_object_link(self, logentry):
a_map = self.get_object_link_info(logentry)
return make_link(a_map, self.object_link_wrapper)
object_link_wrapper = '{val}'
def shred_pii(self, logentry):
raise NotImplementedError
class EventLogEntryType(LogEntryType):
def get_object_link_info(self, logentry) -> dict:
if hasattr(self, 'object_link_viewname') and hasattr(self, 'object_link_argname') and logentry.content_object:
return {
'href': reverse(self.object_link_viewname, kwargs={
'event': logentry.event.slug,
'organizer': logentry.event.organizer.slug,
self.object_link_argname: self.object_link_argvalue(logentry.content_object),
}),
'val': escape(self.object_link_display_name(logentry.content_object)),
}
def object_link_argvalue(self, content_object):
return content_object.id
def object_link_display_name(self, content_object):
return str(content_object)
class OrderLogEntryType(EventLogEntryType):
object_link_wrapper = _('Order {val}')
object_link_viewname = 'control:event.order'
object_link_argname = 'code'
def object_link_argvalue(self, order):
return order.code
def object_link_display_name(self, order):
return order.code
class VoucherLogEntryType(EventLogEntryType):
object_link_wrapper = _('Voucher {val}')
object_link_viewname = 'control:event.voucher'
object_link_argname = 'voucher'
def object_link_display_name(self, order):
return order.code[:6]
class ItemLogEntryType(EventLogEntryType):
object_link_wrapper = _('Product {val}')
object_link_viewname = 'control:event.item'
object_link_argname = 'item'
class SubEventLogEntryType(EventLogEntryType):
object_link_wrapper = pgettext_lazy('subevent', 'Date {val}')
object_link_viewname = 'control:event.subevent'
object_link_argname = 'subevent'
class QuotaLogEntryType(EventLogEntryType):
object_link_wrapper = _('Quota {val}')
object_link_viewname = 'control:event.items.quotas.show'
object_link_argname = 'quota'
class DiscountLogEntryType(EventLogEntryType):
object_link_wrapper = _('Discount {val}')
object_link_viewname = 'control:event.items.discounts.edit'
object_link_argname = 'discount'
class ItemCategoryLogEntryType(EventLogEntryType):
object_link_wrapper = _('Category {val}')
object_link_viewname = 'control:event.items.categories.edit'
object_link_argname = 'category'
class QuestionLogEntryType(EventLogEntryType):
object_link_wrapper = _('Question {val}')
object_link_viewname = 'control:event.items.questions.show'
object_link_argname = 'question'
class TaxRuleLogEntryType(EventLogEntryType):
object_link_wrapper = _('Tax rule {val}')
object_link_viewname = 'control:event.settings.tax.edit'
object_link_argname = 'rule'
class NoOpShredderMixin:
def shred_pii(self, logentry):
pass
class ClearDataShredderMixin:
def shred_pii(self, logentry):
logentry.data = None

View File

@@ -1,36 +0,0 @@
# Generated by Django 4.2.15 on 2024-09-16 15:10
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0269_order_api_meta"),
]
operations = [
migrations.CreateModel(
name="HistoricPassword",
fields=[
(
"id",
models.BigAutoField(
auto_created=True, primary_key=True, serialize=False
),
),
("created", models.DateTimeField(auto_now_add=True)),
("password", models.CharField(max_length=128)),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="historic_passwords",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@@ -213,13 +213,7 @@ class DatetimeColumnMixin:
except (ValueError, TypeError):
pass
else:
try:
d = datetime.datetime.fromisoformat(value)
if not d.tzinfo:
d = d.replace(tzinfo=self.timezone)
return d
except (ValueError, TypeError):
raise ValidationError(_("Could not parse {value} as a date and time.").format(value=value))
raise ValidationError(_("Could not parse {value} as a date and time.").format(value=value))
class DecimalColumnMixin:

View File

@@ -40,8 +40,8 @@ from phonenumbers import SUPPORTED_REGIONS
from pretix.base.forms.questions import guess_country
from pretix.base.modelimport import (
BooleanColumnMixin, DatetimeColumnMixin, DecimalColumnMixin, ImportColumn,
SubeventColumnMixin, i18n_flat,
DatetimeColumnMixin, DecimalColumnMixin, ImportColumn, SubeventColumnMixin,
i18n_flat,
)
from pretix.base.models import (
Customer, ItemVariation, OrderPosition, Question, QuestionAnswer,
@@ -604,22 +604,6 @@ class Comment(ImportColumn):
order.comment = value or ''
class CheckinAttentionColumn(BooleanColumnMixin, ImportColumn):
identifier = 'checkin_attention'
verbose_name = gettext_lazy('Requires special attention')
def assign(self, value, order, position, invoice_address, **kwargs):
order.checkin_attention = value
class CheckinTextColumn(ImportColumn):
identifier = 'checkin_text'
verbose_name = gettext_lazy('Check-in text')
def assign(self, value, order, position, invoice_address, **kwargs):
order.checkin_text = value
class QuestionColumn(ImportColumn):
def __init__(self, event, q):
self.q = q
@@ -758,8 +742,6 @@ def get_order_import_columns(event):
ValidUntil(event),
Locale(event),
Saleschannel(event),
CheckinAttentionColumn(event),
CheckinTextColumn(event),
Expires(event),
Comment(event),
]

View File

@@ -654,9 +654,3 @@ class WebAuthnDevice(Device):
@property
def webauthnpubkey(self):
return websafe_decode(self.pub_key)
class HistoricPassword(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="historic_passwords")
created = models.DateTimeField(auto_now_add=True)
password = models.CharField(verbose_name=_("Password"), max_length=128)

View File

@@ -742,8 +742,8 @@ class Event(EventMixin, LoggedModel):
Returns the names of the plugins activated for this event as a list.
"""
if self.plugins is None:
return []
return self.plugins.split(",")
return self.organizer.get_plugins()
return self.plugins.split(",") + self.organizer.get_plugins()
def get_cache(self):
"""

View File

@@ -33,16 +33,17 @@
# License for the specific language governing permissions and limitations under the License.
import json
import logging
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.html import escape
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from django.utils.translation import gettext_lazy as _
from pretix.base.signals import logentry_object_link
from pretix.base.logentrytypes import log_entry_types, make_link
from pretix.base.signals import is_app_active, logentry_object_link
class VisibleOnlyManager(models.Manager):
@@ -92,6 +93,10 @@ class LogEntry(models.Model):
indexes = [models.Index(fields=["datetime", "id"])]
def display(self):
log_entry_type, meta = log_entry_types.find(action_type=self.action_type)
if log_entry_type:
return log_entry_type.display(self)
from ..signals import logentry_display
for receiver, response in logentry_display.send(self.event, logentry=self):
@@ -126,10 +131,18 @@ class LogEntry(models.Model):
@cached_property
def display_object(self):
from . import (
Discount, Event, Item, ItemCategory, Order, Question, Quota,
SubEvent, TaxRule, Voucher,
Discount, Event, Item, Order, Question, Quota, SubEvent, Voucher,
)
log_entry_type, meta = log_entry_types.find(action_type=self.action_type)
if log_entry_type:
link_info = log_entry_type.get_object_link_info(self)
if is_app_active(self.event, meta['plugin']):
return make_link(link_info, log_entry_type.object_link_wrapper)
else:
return make_link(link_info, log_entry_type.object_link_wrapper, is_active=False,
event=self.event, plugin_name=meta['plugin'] and getattr(meta['plugin'], 'name'))
try:
if self.content_type.model_class() is Event:
return ''
@@ -137,110 +150,15 @@ class LogEntry(models.Model):
co = self.content_object
except:
return ''
a_map = None
a_text = None
if isinstance(co, Order):
a_text = _('Order {val}')
a_map = {
'href': reverse('control:event.order', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'code': co.code
}),
'val': escape(co.code),
}
elif isinstance(co, Voucher):
a_text = _('Voucher {val}')
a_map = {
'href': reverse('control:event.voucher', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'voucher': co.id
}),
'val': escape(co.code[:6]),
}
elif isinstance(co, Item):
a_text = _('Product {val}')
a_map = {
'href': reverse('control:event.item', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'item': co.id
}),
'val': escape(co.name),
}
elif isinstance(co, SubEvent):
a_text = pgettext_lazy('subevent', 'Date {val}')
a_map = {
'href': reverse('control:event.subevent', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'subevent': co.id
}),
'val': escape(str(co))
}
elif isinstance(co, Quota):
a_text = _('Quota {val}')
a_map = {
'href': reverse('control:event.items.quotas.show', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'quota': co.id
}),
'val': escape(co.name),
}
elif isinstance(co, Discount):
a_text = _('Discount {val}')
a_map = {
'href': reverse('control:event.items.discounts.edit', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'discount': co.id
}),
'val': escape(co.internal_name),
}
elif isinstance(co, ItemCategory):
a_text = _('Category {val}')
a_map = {
'href': reverse('control:event.items.categories.edit', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'category': co.id
}),
'val': escape(co.name),
}
elif isinstance(co, Question):
a_text = _('Question {val}')
a_map = {
'href': reverse('control:event.items.questions.show', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'question': co.id
}),
'val': escape(co.question),
}
elif isinstance(co, TaxRule):
a_text = _('Tax rule {val}')
a_map = {
'href': reverse('control:event.settings.tax.edit', kwargs={
'event': self.event.slug,
'organizer': self.event.organizer.slug,
'rule': co.id
}),
'val': escape(co.name),
}
for receiver, response in logentry_object_link.send(self.event, logentry=self):
if response:
return response
if a_text and a_map:
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
return a_text.format_map(a_map)
elif a_text:
return a_text
else:
for receiver, response in logentry_object_link.send(self.event, logentry=self):
if response:
return response
return ''
if isinstance(co, (Order, Voucher, Item, SubEvent, Quota, Discount, Question)):
logging.warning("LogEntryType missing or ill-defined: %s", self.action_type)
return ''
@cached_property
def parsed_data(self):

View File

@@ -2836,12 +2836,12 @@ class OrderPosition(AbstractPosition):
)
@property
def code(self):
def full_code(self):
"""
A ticket code which is unique among all events of a single organizer,
built by the order code and the position number.
built by concatenating the event slug and the order code.
"""
return '{order_code}-{position}'.format(order_code=self.order.code, position=self.positionid)
return '{order}-{position}'.format(order=self.order.full_code, position=self.positionid)
class Transaction(models.Model):

View File

@@ -91,6 +91,10 @@ class Organizer(LoggedModel):
verbose_name=_("Short form"),
unique=True
)
plugins = models.TextField(
null=True, blank=True,
verbose_name=_("Plugins"),
)
class Meta:
verbose_name = _("Organizer")
@@ -119,6 +123,14 @@ class Organizer(LoggedModel):
"""
self.settings.cookie_consent = True
def get_plugins(self):
"""
Returns the names of the plugins activated for this organizer as a list.
"""
if self.plugins is None:
return []
return self.plugins.split(",")
def get_cache(self):
"""
Returns an :py:class:`ObjectRelatedCache` object. This behaves equivalent to

View File

@@ -29,8 +29,6 @@ from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.deconstruct import deconstructible
from django.utils.formats import localize
from django.utils.functional import lazy
from django.utils.html import format_html
from django.utils.translation import gettext_lazy as _, pgettext
from i18nfield.fields import I18nCharField
from i18nfield.strings import LazyI18nString
@@ -122,8 +120,6 @@ EU_CURRENCIES = {
}
VAT_ID_COUNTRIES = EU_COUNTRIES | {'CH', 'NO'}
format_html_lazy = lazy(format_html, str)
def is_eu_country(cc):
cc = str(cc)
@@ -197,17 +193,11 @@ class TaxRule(LoggedModel):
eu_reverse_charge = models.BooleanField(
verbose_name=_("Use EU reverse charge taxation rules"),
default=False,
help_text=format_html_lazy(
'<span class="label label-warning" data-toggle="tooltip" title="{}">{}</span> {}',
_('This feature will be removed in the future as it does not handle VAT for non-business customers in '
'other EU countries in a way that works for all organizers. Use custom rules instead.'),
_('DEPRECATED'),
_("Not recommended. Most events will NOT be qualified for reverse charge since the place of "
"taxation is the location of the event. This option disables charging VAT for all customers "
"outside the EU and for business customers in different EU countries who entered a valid EU VAT "
"ID. Only enable this option after consulting a tax counsel. No warranty given for correct tax "
"calculation. USE AT YOUR OWN RISK.")
),
help_text=_("Not recommended. Most events will NOT be qualified for reverse charge since the place of "
"taxation is the location of the event. This option disables charging VAT for all customers "
"outside the EU and for business customers in different EU countries who entered a valid EU VAT "
"ID. Only enable this option after consulting a tax counsel. No warranty given for correct tax "
"calculation. USE AT YOUR OWN RISK.")
)
home_country = FastCountryField(
verbose_name=_('Merchant country'),

View File

@@ -52,49 +52,71 @@ def _populate_app_cache():
app_cache[ac.name] = ac
class EventPluginSignal(django.dispatch.Signal):
def get_defining_app(o):
# If sentry packed this in a wrapper, unpack that
if "sentry" in o.__module__:
o = o.__wrapped__
# Find the Django application this belongs to
searchpath = o.__module__
# Core modules are always active
if any(searchpath.startswith(cm) for cm in settings.CORE_MODULES):
return 'CORE'
if not app_cache:
_populate_app_cache()
while True:
app = app_cache.get(searchpath)
if "." not in searchpath or app:
break
searchpath, _ = searchpath.rsplit(".", 1)
return app
def is_app_active(sender, app):
if app == 'CORE':
return True
excluded = settings.PRETIX_PLUGINS_EXCLUDE
if sender and app and app.name in sender.get_plugins() and app.name not in excluded:
if not hasattr(app, 'compatibility_errors') or not app.compatibility_errors:
return True
return False
def is_receiver_active(sender, receiver):
if sender is None:
# Send to all events!
return True
app = get_defining_app(receiver)
return is_app_active(sender, app)
def is_plugin_host(sender):
return hasattr(sender, 'get_plugins')
class PluginSignal(django.dispatch.Signal):
"""
This is an extension to Django's built-in signals which differs in a way that it sends
out it's events only to receivers which belong to plugins that are enabled for the given
Event.
"""
def _is_active(self, sender, receiver):
if sender is None:
# Send to all events!
return True
# If sentry packed this in a wrapper, unpack that
if "sentry" in receiver.__module__:
receiver = receiver.__wrapped__
# Find the Django application this belongs to
searchpath = receiver.__module__
core_module = any([searchpath.startswith(cm) for cm in settings.CORE_MODULES])
app = None
if not core_module:
while True:
app = app_cache.get(searchpath)
if "." not in searchpath or app:
break
searchpath, _ = searchpath.rsplit(".", 1)
# Only fire receivers from active plugins and core modules
excluded = settings.PRETIX_PLUGINS_EXCLUDE
if core_module or (sender and app and app.name in sender.get_plugins() and app.name not in excluded):
if not hasattr(app, 'compatibility_errors') or not app.compatibility_errors:
return True
return False
def send(self, sender: Event, **named) -> List[Tuple[Callable, Any]]:
def send(self, sender, **named) -> List[Tuple[Callable, Any]]:
"""
Send signal from sender to all connected receivers that belong to
plugins enabled for the given Event.
sender is required to be an instance of ``pretix.base.models.Event``.
sender is required to be a plugin host (an object with a `get_plugins` method),
for example a ``pretix.base.models.Event``.
"""
if sender and not isinstance(sender, Event):
raise ValueError("Sender needs to be an event.")
if sender and not is_plugin_host(sender):
raise ValueError("Sender needs to be a plugin host.")
responses = []
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
@@ -104,21 +126,22 @@ class EventPluginSignal(django.dispatch.Signal):
_populate_app_cache()
for receiver in self._sorted_receivers(sender):
if self._is_active(sender, receiver):
if is_receiver_active(sender, receiver):
response = receiver(signal=self, sender=sender, **named)
responses.append((receiver, response))
return responses
def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
def send_chained(self, sender, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
"""
Send signal from sender to all connected receivers. The return value of the first receiver
will be used as the keyword argument specified by ``chain_kwarg_name`` in the input to the
second receiver and so on. The return value of the last receiver is returned by this method.
sender is required to be an instance of ``pretix.base.models.Event``.
sender is required to be a plugin host (an object with a `get_plugins` method),
for example a ``pretix.base.models.Event``.
"""
if sender and not isinstance(sender, Event):
raise ValueError("Sender needs to be an event.")
if sender and not is_plugin_host(sender):
raise ValueError("Sender needs to be a plugin host.")
response = named.get(chain_kwarg_name)
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
@@ -128,21 +151,22 @@ class EventPluginSignal(django.dispatch.Signal):
_populate_app_cache()
for receiver in self._sorted_receivers(sender):
if self._is_active(sender, receiver):
if is_receiver_active(sender, receiver):
named[chain_kwarg_name] = response
response = receiver(signal=self, sender=sender, **named)
return response
def send_robust(self, sender: Event, **named) -> List[Tuple[Callable, Any]]:
def send_robust(self, sender, **named) -> List[Tuple[Callable, Any]]:
"""
Send signal from sender to all connected receivers. If a receiver raises an exception
instead of returning a value, the exception is included as the result instead of
stopping the response chain at the offending receiver.
sender is required to be an instance of ``pretix.base.models.Event``.
sender is required to be a plugin host (an object with a `get_plugins` method),
for example a ``pretix.base.models.Event``.
"""
if sender and not isinstance(sender, Event):
raise ValueError("Sender needs to be an event.")
if sender and not is_plugin_host(sender):
raise ValueError("Sender needs to be a plugin host.")
responses = []
if (
@@ -155,7 +179,7 @@ class EventPluginSignal(django.dispatch.Signal):
_populate_app_cache()
for receiver in self._sorted_receivers(sender):
if self._is_active(sender, receiver):
if is_receiver_active(sender, receiver):
try:
response = receiver(signal=self, sender=sender, **named)
except Exception as err:
@@ -177,6 +201,14 @@ class EventPluginSignal(django.dispatch.Signal):
return sorted_list
class OrganizerPluginSignal(PluginSignal):
pass
class EventPluginSignal(PluginSignal):
pass
class GlobalSignal(django.dispatch.Signal):
def send_chained(self, sender: Event, chain_kwarg_name, **named) -> List[Tuple[Callable, Any]]:
"""
@@ -202,6 +234,37 @@ class DeprecatedSignal(django.dispatch.Signal):
super().connect(receiver, sender=None, weak=True, dispatch_uid=None)
class Registry:
def __init__(self, keys):
self.registered_items = list()
self.keys = keys
self.by_key = {key: {} for key in self.keys.keys()}
def register(self, *objs):
for obj in objs:
meta = {k: accessor(obj) for k, accessor in self.keys.items()}
tup = (obj, meta)
for key, accessor in self.keys.items():
self.by_key[key][accessor(obj)] = tup
self.registered_items.append(tup)
def new(self, *args, **kwargs):
def reg(clz):
obj = clz(*args, **kwargs)
self.register(obj)
return clz
return reg
def find(self, **kwargs):
(key, value), = kwargs.items()
return self.by_key.get(key).get(value, (None, None))
class PluginRegistry(Registry):
def __init__(self, keys):
super().__init__({"plugin": lambda o: get_defining_app(o), **keys})
event_live_issues = EventPluginSignal()
"""
This signal is sent out to determine whether an event can be taken live. If you want to

View File

@@ -30,9 +30,7 @@ from celery import states
from celery.result import AsyncResult
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import (
BadRequest, PermissionDenied, ValidationError,
)
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.files.uploadedfile import UploadedFile
from django.db import transaction
from django.http import HttpResponse, JsonResponse, QueryDict
@@ -133,8 +131,6 @@ class AsyncMixin:
return data
def get_result(self, request):
if not request.GET.get('async_id'):
raise BadRequest("No async_id given")
res = AsyncResult(request.GET.get('async_id'))
if 'ajax' in self.request.GET:
return JsonResponse(self._return_ajax_result(res, timeout=0.25))
@@ -144,12 +140,7 @@ class AsyncMixin:
return self.success(res.info)
else:
return self.error(res.info)
state, info = res.state, res.info
return render(request, 'pretixpresale/waiting.html', {
'started': state in ('PROGRESS', 'STARTED'),
'percentage': info.get('value', 0) if isinstance(info, dict) else 0,
'steps': info.get('steps', []) if isinstance(info, dict) else None,
})
return render(request, 'pretixpresale/waiting.html')
def success(self, value):
smes = self.get_success_message(value)
@@ -217,8 +208,6 @@ class AsyncAction(AsyncMixin):
def get(self, request, *args, **kwargs):
if 'async_id' in request.GET and settings.HAS_CELERY:
if not request.GET.get('async_id'):
raise BadRequest("No async_id given")
return self.get_result(request)
return self.http_method_not_allowed(request)

View File

@@ -1143,12 +1143,12 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm):
widget=I18nTextInput,
)
mail_subject_order_incomplete_payment = I18nFormField(
label=_("Subject (if an incomplete payment was received)"),
label=_("Subject"),
required=False,
widget=I18nTextInput,
)
mail_text_order_incomplete_payment = I18nFormField(
label=_("Text (if an incomplete payment was received)"),
label=_("Text"),
required=False,
widget=I18nMarkdownTextarea,
help_text=_("This email only applies to payment methods that can receive incomplete payments, "

View File

@@ -47,11 +47,19 @@ from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from i18nfield.strings import LazyI18nString
from pretix.base.logentrytypes import (
DiscountLogEntryType, EventLogEntryType, ItemCategoryLogEntryType,
ItemLogEntryType, LogEntryType, OrderLogEntryType, QuestionLogEntryType,
QuotaLogEntryType, TaxRuleLogEntryType, VoucherLogEntryType,
log_entry_types,
)
from pretix.base.models import (
Checkin, CheckinList, Event, ItemVariation, LogEntry, OrderPosition,
TaxRule,
)
from pretix.base.signals import logentry_display, orderposition_blocked_display
from pretix.base.signals import (
app_cache, logentry_display, orderposition_blocked_display,
)
from pretix.base.templatetags.money import money_filter
OVERVIEW_BANLIST = [
@@ -328,278 +336,6 @@ def _display_checkin(event, logentry):
@receiver(signal=logentry_display, dispatch_uid="pretixcontrol_logentry_display")
def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
plains = {
'pretix.object.cloned': _('This object has been created by cloning.'),
'pretix.organizer.changed': _('The organizer has been changed.'),
'pretix.organizer.settings': _('The organizer settings have been changed.'),
'pretix.organizer.footerlinks.changed': _('The footer links have been changed.'),
'pretix.organizer.export.schedule.added': _('A scheduled export has been added.'),
'pretix.organizer.export.schedule.changed': _('A scheduled export has been changed.'),
'pretix.organizer.export.schedule.deleted': _('A scheduled export has been deleted.'),
'pretix.organizer.export.schedule.executed': _('A scheduled export has been executed.'),
'pretix.organizer.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
'pretix.giftcards.acceptance.added': _('Gift card acceptance for another organizer has been added.'),
'pretix.giftcards.acceptance.removed': _('Gift card acceptance for another organizer has been removed.'),
'pretix.giftcards.acceptance.acceptor.invited': _('A new gift card acceptor has been invited.'),
'pretix.giftcards.acceptance.acceptor.removed': _('A gift card acceptor has been removed.'),
'pretix.giftcards.acceptance.issuer.removed': _('A gift card issuer has been removed or declined.'),
'pretix.giftcards.acceptance.issuer.accepted': _('A new gift card issuer has been accepted.'),
'pretix.webhook.created': _('The webhook has been created.'),
'pretix.webhook.changed': _('The webhook has been changed.'),
'pretix.webhook.retries.expedited': _('The webhook call retry jobs have been manually expedited.'),
'pretix.webhook.retries.dropped': _('The webhook call retry jobs have been dropped.'),
'pretix.ssoprovider.created': _('The SSO provider has been created.'),
'pretix.ssoprovider.changed': _('The SSO provider has been changed.'),
'pretix.ssoprovider.deleted': _('The SSO provider has been deleted.'),
'pretix.ssoclient.created': _('The SSO client has been created.'),
'pretix.ssoclient.changed': _('The SSO client has been changed.'),
'pretix.ssoclient.deleted': _('The SSO client has been deleted.'),
'pretix.membershiptype.created': _('The membership type has been created.'),
'pretix.membershiptype.changed': _('The membership type has been changed.'),
'pretix.membershiptype.deleted': _('The membership type has been deleted.'),
'pretix.saleschannel.created': _('The sales channel has been created.'),
'pretix.saleschannel.changed': _('The sales channel has been changed.'),
'pretix.saleschannel.deleted': _('The sales channel has been deleted.'),
'pretix.customer.created': _('The account has been created.'),
'pretix.customer.changed': _('The account has been changed.'),
'pretix.customer.membership.created': _('A membership for this account has been added.'),
'pretix.customer.membership.changed': _('A membership of this account has been changed.'),
'pretix.customer.membership.deleted': _('A membership of this account has been deleted.'),
'pretix.customer.anonymized': _('The account has been disabled and anonymized.'),
'pretix.customer.password.resetrequested': _('A new password has been requested.'),
'pretix.customer.password.set': _('A new password has been set.'),
'pretix.reusable_medium.created': _('The reusable medium has been created.'),
'pretix.reusable_medium.created.auto': _('The reusable medium has been created automatically.'),
'pretix.reusable_medium.changed': _('The reusable medium has been changed.'),
'pretix.reusable_medium.linked_orderposition.changed': _('The medium has been connected to a new ticket.'),
'pretix.reusable_medium.linked_giftcard.changed': _('The medium has been connected to a new gift card.'),
'pretix.email.error': _('Sending of an email has failed.'),
'pretix.event.comment': _('The event\'s internal comment has been updated.'),
'pretix.event.canceled': _('The event has been canceled.'),
'pretix.event.deleted': _('An event has been deleted.'),
'pretix.event.shredder.started': _('A removal process for personal data has been started.'),
'pretix.event.shredder.completed': _('A removal process for personal data has been completed.'),
'pretix.event.order.modified': _('The order details have been changed.'),
'pretix.event.order.unpaid': _('The order has been marked as unpaid.'),
'pretix.event.order.secret.changed': _('The order\'s secret has been changed.'),
'pretix.event.order.expirychanged': _('The order\'s expiry date has been changed.'),
'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.'),
'pretix.event.order.deleted': _('The test mode order {code} has been deleted.'),
'pretix.event.order.placed': _('The order has been created.'),
'pretix.event.order.placed.require_approval': _('The order requires approval before it can continue to be processed.'),
'pretix.event.order.approved': _('The order has been approved.'),
'pretix.event.order.denied': _('The order has been denied (comment: "{comment}").'),
'pretix.event.order.contact.changed': _('The email address has been changed from "{old_email}" '
'to "{new_email}".'),
'pretix.event.order.contact.confirmed': _('The email address has been confirmed to be working (the user clicked on a link '
'in the email for the first time).'),
'pretix.event.order.phone.changed': _('The phone number has been changed from "{old_phone}" '
'to "{new_phone}".'),
'pretix.event.order.customer.changed': _('The customer account has been changed.'),
'pretix.event.order.locale.changed': _('The order locale has been changed.'),
'pretix.event.order.invoice.generated': _('The invoice has been generated.'),
'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
'pretix.event.order.comment': _('The order\'s internal comment has been updated.'),
'pretix.event.order.custom_followup_at': _('The order\'s follow-up date has been updated.'),
'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.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.'),
'pretix.event.order.email.error': _('Sending of an email has failed.'),
'pretix.event.order.email.attachments.skipped': _('The email has been sent without attached tickets since they '
'would have been too large to be likely to arrive.'),
'pretix.event.order.email.custom_sent': _('A custom email has been sent.'),
'pretix.event.order.position.email.custom_sent': _('A custom email has been sent to an attendee.'),
'pretix.event.order.email.download_reminder_sent': _('An email has been sent with a reminder that the ticket '
'is available for download.'),
'pretix.event.order.email.expire_warning_sent': _('An email has been sent with a warning that the order is about '
'to expire.'),
'pretix.event.order.email.order_canceled': _('An email has been sent to notify the user that the order has been canceled.'),
'pretix.event.order.email.event_canceled': _('An email has been sent to notify the user that the event has '
'been canceled.'),
'pretix.event.order.email.order_changed': _('An email has been sent to notify the user that the order has been changed.'),
'pretix.event.order.email.order_free': _('An email has been sent to notify the user that the order has been received.'),
'pretix.event.order.email.order_paid': _('An email has been sent to notify the user that payment has been received.'),
'pretix.event.order.email.order_denied': _('An email has been sent to notify the user that the order has been denied.'),
'pretix.event.order.email.order_approved': _('An email has been sent to notify the user that the order has '
'been approved.'),
'pretix.event.order.email.order_placed': _('An email has been sent to notify the user that the order has been received and requires payment.'),
'pretix.event.order.email.order_placed_require_approval': _('An email has been sent to notify the user that '
'the order has been received and requires '
'approval.'),
'pretix.event.order.email.resend': _('An email with a link to the order detail page has been resent to the user.'),
'pretix.event.order.email.payment_failed': _('An email has been sent to notify the user that the payment failed.'),
'pretix.event.order.payment.confirmed': _('Payment {local_id} has been confirmed.'),
'pretix.event.order.payment.canceled': _('Payment {local_id} has been canceled.'),
'pretix.event.order.payment.canceled.failed': _('Canceling payment {local_id} has failed.'),
'pretix.event.order.payment.started': _('Payment {local_id} has been started.'),
'pretix.event.order.payment.failed': _('Payment {local_id} has failed.'),
'pretix.event.order.quotaexceeded': _('The order could not be marked as paid: {message}'),
'pretix.event.order.overpaid': _('The order has been overpaid.'),
'pretix.event.order.refund.created': _('Refund {local_id} has been created.'),
'pretix.event.order.refund.created.externally': _('Refund {local_id} has been created by an external entity.'),
'pretix.event.order.refund.requested': _('The customer requested you to issue a refund.'),
'pretix.event.order.refund.done': _('Refund {local_id} has been completed.'),
'pretix.event.order.refund.canceled': _('Refund {local_id} has been canceled.'),
'pretix.event.order.refund.failed': _('Refund {local_id} has failed.'),
'pretix.event.export.schedule.added': _('A scheduled export has been added.'),
'pretix.event.export.schedule.changed': _('A scheduled export has been changed.'),
'pretix.event.export.schedule.deleted': _('A scheduled export has been deleted.'),
'pretix.event.export.schedule.executed': _('A scheduled export has been executed.'),
'pretix.event.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
'pretix.control.auth.user.created': _('The user has been created.'),
'pretix.control.auth.user.new_source': _('A first login using {agent_type} on {os_type} from {country} has '
'been detected.'),
'pretix.user.settings.2fa.enabled': _('Two-factor authentication has been enabled.'),
'pretix.user.settings.2fa.disabled': _('Two-factor authentication has been disabled.'),
'pretix.user.settings.2fa.regenemergency': _('Your two-factor emergency codes have been regenerated.'),
'pretix.user.settings.2fa.emergency': _('A two-factor emergency code has been generated.'),
'pretix.user.settings.2fa.device.added': _('A new two-factor authentication device "{name}" has been added to '
'your account.'),
'pretix.user.settings.2fa.device.deleted': _('The two-factor authentication device "{name}" has been removed '
'from your account.'),
'pretix.user.settings.notifications.enabled': _('Notifications have been enabled.'),
'pretix.user.settings.notifications.disabled': _('Notifications have been disabled.'),
'pretix.user.settings.notifications.changed': _('Your notification settings have been changed.'),
'pretix.user.anonymized': _('This user has been anonymized.'),
'pretix.user.oauth.authorized': _('The application "{application_name}" has been authorized to access your '
'account.'),
'pretix.control.auth.user.forgot_password.mail_sent': _('Password reset mail sent.'),
'pretix.control.auth.user.forgot_password.recovered': _('The password has been reset.'),
'pretix.control.auth.user.forgot_password.denied.repeated': _('A repeated password reset has been denied, as '
'the last request was less than 24 hours ago.'),
'pretix.organizer.deleted': _('The organizer "{name}" has been deleted.'),
'pretix.voucher.added': _('The voucher has been created.'),
'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
'pretix.voucher.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'),
'pretix.voucher.expired.waitinglist': _('The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
'pretix.voucher.changed': _('The voucher has been changed.'),
'pretix.voucher.deleted': _('The voucher has been deleted.'),
'pretix.voucher.redeemed': _('The voucher has been redeemed in order {order_code}.'),
'pretix.event.item.added': _('The product has been created.'),
'pretix.event.item.changed': _('The product has been changed.'),
'pretix.event.item.reordered': _('The product has been reordered.'),
'pretix.event.item.deleted': _('The product has been deleted.'),
'pretix.event.item.variation.added': _('The variation "{value}" has been created.'),
'pretix.event.item.variation.deleted': _('The variation "{value}" has been deleted.'),
'pretix.event.item.variation.changed': _('The variation "{value}" has been changed.'),
'pretix.event.item.addons.added': _('An add-on has been added to this product.'),
'pretix.event.item.addons.removed': _('An add-on has been removed from this product.'),
'pretix.event.item.addons.changed': _('An add-on has been changed on this product.'),
'pretix.event.item.bundles.added': _('A bundled item has been added to this product.'),
'pretix.event.item.bundles.removed': _('A bundled item has been removed from this product.'),
'pretix.event.item.bundles.changed': _('A bundled item has been changed on this product.'),
'pretix.event.item_meta_property.added': _('A meta property has been added to this event.'),
'pretix.event.item_meta_property.deleted': _('A meta property has been removed from this event.'),
'pretix.event.item_meta_property.changed': _('A meta property has been changed on this event.'),
'pretix.event.quota.added': _('The quota has been added.'),
'pretix.event.quota.deleted': _('The quota has been deleted.'),
'pretix.event.quota.changed': _('The quota has been changed.'),
'pretix.event.quota.closed': _('The quota has closed.'),
'pretix.event.quota.opened': _('The quota has been re-opened.'),
'pretix.event.category.added': _('The category has been added.'),
'pretix.event.category.deleted': _('The category has been deleted.'),
'pretix.event.category.changed': _('The category has been changed.'),
'pretix.event.category.reordered': _('The category has been reordered.'),
'pretix.event.question.added': _('The question has been added.'),
'pretix.event.question.deleted': _('The question has been deleted.'),
'pretix.event.question.changed': _('The question has been changed.'),
'pretix.event.question.reordered': _('The question has been reordered.'),
'pretix.event.discount.added': _('The discount has been added.'),
'pretix.event.discount.deleted': _('The discount has been deleted.'),
'pretix.event.discount.changed': _('The discount has been changed.'),
'pretix.event.taxrule.added': _('The tax rule has been added.'),
'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
'pretix.event.checkinlist.added': _('The check-in list has been added.'),
'pretix.event.checkinlist.deleted': _('The check-in list has been deleted.'),
'pretix.event.checkinlists.deleted': _('The check-in list has been deleted.'), # backwards compatibility
'pretix.event.checkinlist.changed': _('The check-in list has been changed.'),
'pretix.event.settings': _('The event settings have been changed.'),
'pretix.event.tickets.settings': _('The ticket download settings have been changed.'),
'pretix.event.plugins.enabled': _('A plugin has been enabled.'),
'pretix.event.plugins.disabled': _('A plugin has been disabled.'),
'pretix.event.live.activated': _('The shop has been taken live.'),
'pretix.event.live.deactivated': _('The shop has been taken offline.'),
'pretix.event.testmode.activated': _('The shop has been taken into test mode.'),
'pretix.event.testmode.deactivated': _('The test mode has been disabled.'),
'pretix.event.added': _('The event has been created.'),
'pretix.event.changed': _('The event details have been changed.'),
'pretix.event.footerlinks.changed': _('The footer links have been changed.'),
'pretix.event.question.option.added': _('An answer option has been added to the question.'),
'pretix.event.question.option.deleted': _('An answer option has been removed from the question.'),
'pretix.event.question.option.changed': _('An answer option has been changed.'),
'pretix.event.permissions.added': _('A user has been added to the event team.'),
'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.waitinglist.voucher': _('A voucher has been sent to a person on the waiting list.'), # legacy
'pretix.event.orders.waitinglist.voucher_assigned': _('A voucher has been sent to a person on the waiting list.'),
'pretix.event.orders.waitinglist.deleted': _('An entry has been removed from the waiting list.'),
'pretix.event.order.waitinglist.transferred': _('An entry has been transferred to another waiting list.'), # legacy
'pretix.event.orders.waitinglist.changed': _('An entry has been changed on the waiting list.'),
'pretix.event.orders.waitinglist.added': _('An entry has been added to the waiting list.'),
'pretix.team.created': _('The team has been created.'),
'pretix.team.changed': _('The team settings have been changed.'),
'pretix.team.deleted': _('The team has been deleted.'),
'pretix.gate.created': _('The gate has been created.'),
'pretix.gate.changed': _('The gate has been changed.'),
'pretix.gate.deleted': _('The gate has been deleted.'),
'pretix.subevent.deleted': pgettext_lazy('subevent', 'The event date has been deleted.'),
'pretix.subevent.canceled': pgettext_lazy('subevent', 'The event date has been canceled.'),
'pretix.subevent.changed': pgettext_lazy('subevent', 'The event date has been changed.'),
'pretix.subevent.added': pgettext_lazy('subevent', 'The event date has been created.'),
'pretix.subevent.quota.added': pgettext_lazy('subevent', 'A quota has been added to the event date.'),
'pretix.subevent.quota.changed': pgettext_lazy('subevent', 'A quota has been changed on the event date.'),
'pretix.subevent.quota.deleted': pgettext_lazy('subevent', 'A quota has been removed from the event date.'),
'pretix.device.created': _('The device has been created.'),
'pretix.device.changed': _('The device has been changed.'),
'pretix.device.revoked': _('Access of the device has been revoked.'),
'pretix.device.initialized': _('The device has been initialized.'),
'pretix.device.keyroll': _('The access token of the device has been regenerated.'),
'pretix.device.updated': _('The device has notified the server of an hardware or software update.'),
'pretix.giftcards.created': _('The gift card has been created.'),
'pretix.giftcards.modified': _('The gift card has been changed.'),
'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
}
data = json.loads(logentry.data)
if logentry.action_type.startswith('pretix.event.item.variation'):
if 'value' not in data:
# Backwards compatibility
var = ItemVariation.objects.filter(id=data['id']).first()
if var:
data['value'] = str(var.value)
else:
data['value'] = '?'
else:
data['value'] = LazyI18nString(data['value'])
if logentry.action_type == "pretix.voucher.redeemed":
data = defaultdict(lambda: '?', data)
url = reverse('control:event.order', kwargs={
'event': logentry.event.slug,
'organizer': logentry.event.organizer.slug,
'code': data['order_code']
})
return mark_safe(plains[logentry.action_type].format(
order_code='<a href="{}">{}</a>'.format(url, data['order_code']),
))
if logentry.action_type in plains:
data = defaultdict(lambda: '?', data)
return plains[logentry.action_type].format_map(data)
if logentry.action_type.startswith('pretix.event.order.changed'):
return _display_order_changed(sender, logentry)
@@ -623,91 +359,22 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
return _('The order has been canceled.')
if logentry.action_type in ('pretix.control.views.checkin.reverted', 'pretix.event.checkin.reverted'):
if 'list' in data:
if 'list' in logentry.parsed_data:
try:
checkin_list = sender.checkin_lists.get(pk=data.get('list')).name
checkin_list = sender.checkin_lists.get(pk=logentry.parsed_data.get('list')).name
except CheckinList.DoesNotExist:
checkin_list = _("(unknown)")
else:
checkin_list = _("(unknown)")
return _('The check-in of position #{posid} on list "{list}" has been reverted.').format(
posid=data.get('positionid'),
posid=logentry.parsed_data.get('positionid'),
list=checkin_list,
)
if sender and logentry.action_type.startswith('pretix.event.checkin'):
return _display_checkin(sender, logentry)
if logentry.action_type == 'pretix.control.views.checkin':
# deprecated
dt = dateutil.parser.parse(data.get('datetime'))
tz = sender.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in data:
try:
checkin_list = sender.checkin_lists.get(pk=data.get('list')).name
except CheckinList.DoesNotExist:
checkin_list = _("(unknown)")
else:
checkin_list = _("(unknown)")
if data.get('first'):
return _('Position #{posid} has been checked in manually at {datetime} on list "{list}".').format(
posid=data.get('positionid'),
datetime=dt_formatted,
list=checkin_list,
)
return _('Position #{posid} has been checked in again at {datetime} on list "{list}".').format(
posid=data.get('positionid'),
datetime=dt_formatted,
list=checkin_list
)
if logentry.action_type == 'pretix.team.member.added':
return _('{user} has been added to the team.').format(user=data.get('email'))
if logentry.action_type == 'pretix.team.member.removed':
return _('{user} has been removed from the team.').format(user=data.get('email'))
if logentry.action_type == 'pretix.team.member.joined':
return _('{user} has joined the team using the invite sent to {email}.').format(
user=data.get('email'), email=data.get('invite_email')
)
if logentry.action_type == 'pretix.team.invite.created':
return _('{user} has been invited to the team.').format(user=data.get('email'))
if logentry.action_type == 'pretix.team.invite.resent':
return _('Invite for {user} has been resent.').format(user=data.get('email'))
if logentry.action_type == 'pretix.team.invite.deleted':
return _('The invite for {user} has been revoked.').format(user=data.get('email'))
if logentry.action_type == 'pretix.team.token.created':
return _('The token "{name}" has been created.').format(name=data.get('name'))
if logentry.action_type == 'pretix.team.token.deleted':
return _('The token "{name}" has been revoked.').format(name=data.get('name'))
if logentry.action_type == 'pretix.user.settings.changed':
text = str(_('Your account settings have been changed.'))
if 'email' in data:
text = text + ' ' + str(_('Your email address has been changed to {email}.').format(email=data['email']))
if 'new_pw' in data:
text = text + ' ' + str(_('Your password has been changed.'))
if data.get('is_active') is True:
text = text + ' ' + str(_('Your account has been enabled.'))
elif data.get('is_active') is False:
text = text + ' ' + str(_('Your account has been disabled.'))
return text
if logentry.action_type == 'pretix.control.auth.user.impersonated':
return str(_('You impersonated {}.')).format(data['other_email'])
if logentry.action_type == 'pretix.control.auth.user.impersonate_stopped':
return str(_('You stopped impersonating {}.')).format(data['other_email'])
@receiver(signal=orderposition_blocked_display, dispatch_uid="pretixcontrol_orderposition_blocked_display")
def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, block_name, **kwargs):
@@ -715,3 +382,459 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl
return _('Blocked manually')
elif block_name.startswith('api:'):
return _('Blocked because of an API integration')
@log_entry_types.new_from_dict({
'pretix.event.order.modified': _('The order details have been changed.'),
'pretix.event.order.unpaid': _('The order has been marked as unpaid.'),
'pretix.event.order.secret.changed': _('The order\'s secret has been changed.'),
'pretix.event.order.expirychanged': _('The order\'s expiry date has been changed.'),
'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.'),
'pretix.event.order.deleted': _('The test mode order {code} has been deleted.'),
'pretix.event.order.placed': _('The order has been created.'),
'pretix.event.order.placed.require_approval': _(
'The order requires approval before it can continue to be processed.'),
'pretix.event.order.approved': _('The order has been approved.'),
'pretix.event.order.denied': _('The order has been denied (comment: "{comment}").'),
'pretix.event.order.contact.changed': _('The email address has been changed from "{old_email}" '
'to "{new_email}".'),
'pretix.event.order.contact.confirmed': _(
'The email address has been confirmed to be working (the user clicked on a link '
'in the email for the first time).'),
'pretix.event.order.phone.changed': _('The phone number has been changed from "{old_phone}" '
'to "{new_phone}".'),
'pretix.event.order.customer.changed': _('The customer account has been changed.'),
'pretix.event.order.locale.changed': _('The order locale has been changed.'),
'pretix.event.order.invoice.generated': _('The invoice has been generated.'),
'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
'pretix.event.order.comment': _('The order\'s internal comment has been updated.'),
'pretix.event.order.custom_followup_at': _('The order\'s follow-up date has been updated.'),
'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.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.'),
'pretix.event.order.email.error': _('Sending of an email has failed.'),
'pretix.event.order.email.attachments.skipped': _('The email has been sent without attached tickets since they '
'would have been too large to be likely to arrive.'),
'pretix.event.order.email.custom_sent': _('A custom email has been sent.'),
'pretix.event.order.position.email.custom_sent': _('A custom email has been sent to an attendee.'),
'pretix.event.order.email.download_reminder_sent': _('An email has been sent with a reminder that the ticket '
'is available for download.'),
'pretix.event.order.email.expire_warning_sent': _('An email has been sent with a warning that the order is about '
'to expire.'),
'pretix.event.order.email.order_canceled': _(
'An email has been sent to notify the user that the order has been canceled.'),
'pretix.event.order.email.event_canceled': _('An email has been sent to notify the user that the event has '
'been canceled.'),
'pretix.event.order.email.order_changed': _(
'An email has been sent to notify the user that the order has been changed.'),
'pretix.event.order.email.order_free': _(
'An email has been sent to notify the user that the order has been received.'),
'pretix.event.order.email.order_paid': _(
'An email has been sent to notify the user that payment has been received.'),
'pretix.event.order.email.order_denied': _(
'An email has been sent to notify the user that the order has been denied.'),
'pretix.event.order.email.order_approved': _('An email has been sent to notify the user that the order has '
'been approved.'),
'pretix.event.order.email.order_placed': _(
'An email has been sent to notify the user that the order has been received and requires payment.'),
'pretix.event.order.email.order_placed_require_approval': _('An email has been sent to notify the user that '
'the order has been received and requires '
'approval.'),
'pretix.event.order.email.resend': _('An email with a link to the order detail page has been resent to the user.'),
'pretix.event.order.email.payment_failed': _('An email has been sent to notify the user that the payment failed.'),
})
class CoreOrderLogEntryType(OrderLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.voucher.added': _('The voucher has been created.'),
'pretix.voucher.sent': _('The voucher has been sent to {recipient}.'),
'pretix.voucher.added.waitinglist': _('The voucher has been created and sent to a person on the waiting list.'),
'pretix.voucher.expired.waitinglist': _(
'The voucher has been set to expire because the recipient removed themselves from the waiting list.'),
'pretix.voucher.changed': _('The voucher has been changed.'),
'pretix.voucher.deleted': _('The voucher has been deleted.'),
})
class CoreVoucherLogEntryType(VoucherLogEntryType):
pass
@log_entry_types.new()
class VoucherRedeemedLogEntryType(VoucherLogEntryType):
action_type = 'pretix.voucher.redeemed'
plain = _('The voucher has been redeemed in order {order_code}.')
def display(self, logentry):
data = json.loads(logentry.data)
data = defaultdict(lambda: '?', data)
url = reverse('control:event.order', kwargs={
'event': logentry.event.slug,
'organizer': logentry.event.organizer.slug,
'code': data['order_code']
})
return mark_safe(self.plain.format(
order_code='<a href="{}">{}</a>'.format(url, data['order_code']),
))
@log_entry_types.new_from_dict({
'pretix.event.category.added': _('The category has been added.'),
'pretix.event.category.deleted': _('The category has been deleted.'),
'pretix.event.category.changed': _('The category has been changed.'),
'pretix.event.category.reordered': _('The category has been reordered.'),
})
class CoreItemCategoryLogEntryType(ItemCategoryLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.taxrule.added': _('The tax rule has been added.'),
'pretix.event.taxrule.deleted': _('The tax rule has been deleted.'),
'pretix.event.taxrule.changed': _('The tax rule has been changed.'),
})
class CoreTaxRuleLogEntryType(TaxRuleLogEntryType):
pass
class TeamMembershipLogEntryType(LogEntryType):
def display(self, logentry):
return self.plain.format(user=logentry.parsed_data.get('email'))
@log_entry_types.new_from_dict({
'pretix.team.member.added': _('{user} has been added to the team.'),
'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.'),
})
class CoreTeamMembershipLogEntryType(TeamMembershipLogEntryType):
pass
@log_entry_types.new()
class TeamMemberJoinedLogEntryType(LogEntryType):
action_type = 'pretix.team.member.joined'
def display(self, logentry):
return _('{user} has joined the team using the invite sent to {email}.').format(
user=logentry.parsed_data.get('email'), email=logentry.parsed_data.get('invite_email')
)
@log_entry_types.new()
class UserSettingsChangedLogEntryType(LogEntryType):
action_type = 'pretix.user.settings.changed'
def display(self, logentry):
text = str(_('Your account settings have been changed.'))
if 'email' in logentry.parsed_data:
text = text + ' ' + str(
_('Your email address has been changed to {email}.').format(email=logentry.parsed_data['email']))
if 'new_pw' in logentry.parsed_data:
text = text + ' ' + str(_('Your password has been changed.'))
if logentry.parsed_data.get('is_active') is True:
text = text + ' ' + str(_('Your account has been enabled.'))
elif logentry.parsed_data.get('is_active') is False:
text = text + ' ' + str(_('Your account has been disabled.'))
return text
class UserImpersonatedLogEntryType(LogEntryType):
def display(self, logentry):
return self.plain.format(logentry.parsed_data['other_email'])
@log_entry_types.new_from_dict({
'pretix.control.auth.user.impersonated': _('You impersonated {}.'),
'pretix.control.auth.user.impersonate_stopped': _('You stopped impersonating {}.'),
})
class CoreUserImpersonatedLogEntryType(UserImpersonatedLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.object.cloned': _('This object has been created by cloning.'),
'pretix.organizer.changed': _('The organizer has been changed.'),
'pretix.organizer.settings': _('The organizer settings have been changed.'),
'pretix.organizer.footerlinks.changed': _('The footer links have been changed.'),
'pretix.organizer.export.schedule.added': _('A scheduled export has been added.'),
'pretix.organizer.export.schedule.changed': _('A scheduled export has been changed.'),
'pretix.organizer.export.schedule.deleted': _('A scheduled export has been deleted.'),
'pretix.organizer.export.schedule.executed': _('A scheduled export has been executed.'),
'pretix.organizer.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
'pretix.giftcards.acceptance.added': _('Gift card acceptance for another organizer has been added.'),
'pretix.giftcards.acceptance.removed': _('Gift card acceptance for another organizer has been removed.'),
'pretix.giftcards.acceptance.acceptor.invited': _('A new gift card acceptor has been invited.'),
'pretix.giftcards.acceptance.acceptor.removed': _('A gift card acceptor has been removed.'),
'pretix.giftcards.acceptance.issuer.removed': _('A gift card issuer has been removed or declined.'),
'pretix.giftcards.acceptance.issuer.accepted': _('A new gift card issuer has been accepted.'),
'pretix.webhook.created': _('The webhook has been created.'),
'pretix.webhook.changed': _('The webhook has been changed.'),
'pretix.webhook.retries.expedited': _('The webhook call retry jobs have been manually expedited.'),
'pretix.webhook.retries.dropped': _('The webhook call retry jobs have been dropped.'),
'pretix.ssoprovider.created': _('The SSO provider has been created.'),
'pretix.ssoprovider.changed': _('The SSO provider has been changed.'),
'pretix.ssoprovider.deleted': _('The SSO provider has been deleted.'),
'pretix.ssoclient.created': _('The SSO client has been created.'),
'pretix.ssoclient.changed': _('The SSO client has been changed.'),
'pretix.ssoclient.deleted': _('The SSO client has been deleted.'),
'pretix.membershiptype.created': _('The membership type has been created.'),
'pretix.membershiptype.changed': _('The membership type has been changed.'),
'pretix.membershiptype.deleted': _('The membership type has been deleted.'),
'pretix.saleschannel.created': _('The sales channel has been created.'),
'pretix.saleschannel.changed': _('The sales channel has been changed.'),
'pretix.saleschannel.deleted': _('The sales channel has been deleted.'),
'pretix.customer.created': _('The account has been created.'),
'pretix.customer.changed': _('The account has been changed.'),
'pretix.customer.membership.created': _('A membership for this account has been added.'),
'pretix.customer.membership.changed': _('A membership of this account has been changed.'),
'pretix.customer.membership.deleted': _('A membership of this account has been deleted.'),
'pretix.customer.anonymized': _('The account has been disabled and anonymized.'),
'pretix.customer.password.resetrequested': _('A new password has been requested.'),
'pretix.customer.password.set': _('A new password has been set.'),
'pretix.reusable_medium.created': _('The reusable medium has been created.'),
'pretix.reusable_medium.created.auto': _('The reusable medium has been created automatically.'),
'pretix.reusable_medium.changed': _('The reusable medium has been changed.'),
'pretix.reusable_medium.linked_orderposition.changed': _('The medium has been connected to a new ticket.'),
'pretix.reusable_medium.linked_giftcard.changed': _('The medium has been connected to a new gift card.'),
'pretix.email.error': _('Sending of an email has failed.'),
'pretix.event.comment': _('The event\'s internal comment has been updated.'),
'pretix.event.canceled': _('The event has been canceled.'),
'pretix.event.deleted': _('An event has been deleted.'),
'pretix.event.shredder.started': _('A removal process for personal data has been started.'),
'pretix.event.shredder.completed': _('A removal process for personal data has been completed.'),
'pretix.event.export.schedule.added': _('A scheduled export has been added.'),
'pretix.event.export.schedule.changed': _('A scheduled export has been changed.'),
'pretix.event.export.schedule.deleted': _('A scheduled export has been deleted.'),
'pretix.event.export.schedule.executed': _('A scheduled export has been executed.'),
'pretix.event.export.schedule.failed': _('A scheduled export has failed: {reason}.'),
'pretix.control.auth.user.created': _('The user has been created.'),
'pretix.control.auth.user.new_source': _('A first login using {agent_type} on {os_type} from {country} has '
'been detected.'),
'pretix.user.settings.2fa.enabled': _('Two-factor authentication has been enabled.'),
'pretix.user.settings.2fa.disabled': _('Two-factor authentication has been disabled.'),
'pretix.user.settings.2fa.regenemergency': _('Your two-factor emergency codes have been regenerated.'),
'pretix.user.settings.2fa.emergency': _('A two-factor emergency code has been generated.'),
'pretix.user.settings.2fa.device.added': _('A new two-factor authentication device "{name}" has been added to '
'your account.'),
'pretix.user.settings.2fa.device.deleted': _('The two-factor authentication device "{name}" has been removed '
'from your account.'),
'pretix.user.settings.notifications.enabled': _('Notifications have been enabled.'),
'pretix.user.settings.notifications.disabled': _('Notifications have been disabled.'),
'pretix.user.settings.notifications.changed': _('Your notification settings have been changed.'),
'pretix.user.anonymized': _('This user has been anonymized.'),
'pretix.user.oauth.authorized': _('The application "{application_name}" has been authorized to access your '
'account.'),
'pretix.control.auth.user.forgot_password.mail_sent': _('Password reset mail sent.'),
'pretix.control.auth.user.forgot_password.recovered': _('The password has been reset.'),
'pretix.control.auth.user.forgot_password.denied.repeated': _('A repeated password reset has been denied, as '
'the last request was less than 24 hours ago.'),
'pretix.organizer.deleted': _('The organizer "{name}" has been deleted.'),
'pretix.waitinglist.voucher': _('A voucher has been sent to a person on the waiting list.'), # legacy
'pretix.event.orders.waitinglist.voucher_assigned': _('A voucher has been sent to a person on the waiting list.'),
'pretix.event.orders.waitinglist.deleted': _('An entry has been removed from the waiting list.'),
'pretix.event.order.waitinglist.transferred': _('An entry has been transferred to another waiting list.'), # legacy
'pretix.event.orders.waitinglist.changed': _('An entry has been changed on the waiting list.'),
'pretix.event.orders.waitinglist.added': _('An entry has been added to the waiting list.'),
'pretix.team.created': _('The team has been created.'),
'pretix.team.changed': _('The team settings have been changed.'),
'pretix.team.deleted': _('The team has been deleted.'),
'pretix.gate.created': _('The gate has been created.'),
'pretix.gate.changed': _('The gate has been changed.'),
'pretix.gate.deleted': _('The gate has been deleted.'),
'pretix.subevent.deleted': pgettext_lazy('subevent', 'The event date has been deleted.'),
'pretix.subevent.canceled': pgettext_lazy('subevent', 'The event date has been canceled.'),
'pretix.subevent.changed': pgettext_lazy('subevent', 'The event date has been changed.'),
'pretix.subevent.added': pgettext_lazy('subevent', 'The event date has been created.'),
'pretix.subevent.quota.added': pgettext_lazy('subevent', 'A quota has been added to the event date.'),
'pretix.subevent.quota.changed': pgettext_lazy('subevent', 'A quota has been changed on the event date.'),
'pretix.subevent.quota.deleted': pgettext_lazy('subevent', 'A quota has been removed from the event date.'),
'pretix.device.created': _('The device has been created.'),
'pretix.device.changed': _('The device has been changed.'),
'pretix.device.revoked': _('Access of the device has been revoked.'),
'pretix.device.initialized': _('The device has been initialized.'),
'pretix.device.keyroll': _('The access token of the device has been regenerated.'),
'pretix.device.updated': _('The device has notified the server of an hardware or software update.'),
'pretix.giftcards.created': _('The gift card has been created.'),
'pretix.giftcards.modified': _('The gift card has been changed.'),
'pretix.giftcards.transaction.manual': _('A manual transaction has been performed.'),
'pretix.team.token.created': _('The token "{name}" has been created.'),
'pretix.team.token.deleted': _('The token "{name}" has been revoked.'),
})
class CoreLogEntryType(LogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.item_meta_property.added': _('A meta property has been added to this event.'),
'pretix.event.item_meta_property.deleted': _('A meta property has been removed from this event.'),
'pretix.event.item_meta_property.changed': _('A meta property has been changed on this event.'),
'pretix.event.checkinlist.added': _('The check-in list has been added.'),
'pretix.event.checkinlist.deleted': _('The check-in list has been deleted.'),
'pretix.event.checkinlists.deleted': _('The check-in list has been deleted.'), # backwards compatibility
'pretix.event.checkinlist.changed': _('The check-in list has been changed.'),
'pretix.event.settings': _('The event settings have been changed.'),
'pretix.event.tickets.settings': _('The ticket download settings have been changed.'),
'pretix.event.live.activated': _('The shop has been taken live.'),
'pretix.event.live.deactivated': _('The shop has been taken offline.'),
'pretix.event.testmode.activated': _('The shop has been taken into test mode.'),
'pretix.event.testmode.deactivated': _('The test mode has been disabled.'),
'pretix.event.added': _('The event has been created.'),
'pretix.event.changed': _('The event details have been changed.'),
'pretix.event.footerlinks.changed': _('The footer links have been changed.'),
'pretix.event.question.option.added': _('An answer option has been added to the question.'),
'pretix.event.question.option.deleted': _('An answer option has been removed from the question.'),
'pretix.event.question.option.changed': _('An answer option has been changed.'),
'pretix.event.permissions.added': _('A user has been added to the event team.'),
'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.'),
})
class CoreEventLogEntryType(EventLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.plugins.enabled': _('The plugin has been enabled.'),
'pretix.event.plugins.disabled': _('The plugin has been disabled.'),
})
class EventPluginStateLogEntryType(EventLogEntryType):
object_link_wrapper = _('Plugin {val}')
def get_object_link_info(self, logentry) -> dict:
if 'plugin' in logentry.parsed_data:
app = app_cache.get(logentry.parsed_data['plugin'])
if app and hasattr(app, 'PretixPluginMeta'):
return {
'href': reverse('control:event.settings.plugins', kwargs={
'organizer': logentry.event.organizer.slug,
'event': logentry.event.slug,
}) + '#plugin_' + logentry.parsed_data['plugin'],
'val': app.PretixPluginMeta.name
}
@log_entry_types.new_from_dict({
'pretix.event.item.added': _('The product has been created.'),
'pretix.event.item.changed': _('The product has been changed.'),
'pretix.event.item.reordered': _('The product has been reordered.'),
'pretix.event.item.deleted': _('The product has been deleted.'),
'pretix.event.item.addons.added': _('An add-on has been added to this product.'),
'pretix.event.item.addons.removed': _('An add-on has been removed from this product.'),
'pretix.event.item.addons.changed': _('An add-on has been changed on this product.'),
'pretix.event.item.bundles.added': _('A bundled item has been added to this product.'),
'pretix.event.item.bundles.removed': _('A bundled item has been removed from this product.'),
'pretix.event.item.bundles.changed': _('A bundled item has been changed on this product.'),
})
class CoreItemLogEntryType(ItemLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.item.variation.added': _('The variation "{value}" has been created.'),
'pretix.event.item.variation.deleted': _('The variation "{value}" has been deleted.'),
'pretix.event.item.variation.changed': _('The variation "{value}" has been changed.'),
})
class VariationLogEntryType(ItemLogEntryType):
def display(self, logentry):
if 'value' not in logentry.parsed_data:
# Backwards compatibility
var = ItemVariation.objects.filter(id=logentry.parsed_data['id']).first()
if var:
logentry.parsed_data['value'] = str(var.value)
else:
logentry.parsed_data['value'] = '?'
else:
logentry.parsed_data['value'] = LazyI18nString(logentry.parsed_data['value'])
return super().display(logentry)
@log_entry_types.new_from_dict({
'pretix.event.order.payment.confirmed': _('Payment {local_id} has been confirmed.'),
'pretix.event.order.payment.canceled': _('Payment {local_id} has been canceled.'),
'pretix.event.order.payment.canceled.failed': _('Canceling payment {local_id} has failed.'),
'pretix.event.order.payment.started': _('Payment {local_id} has been started.'),
'pretix.event.order.payment.failed': _('Payment {local_id} has failed.'),
'pretix.event.order.quotaexceeded': _('The order could not be marked as paid: {message}'),
'pretix.event.order.overpaid': _('The order has been overpaid.'),
'pretix.event.order.refund.created': _('Refund {local_id} has been created.'),
'pretix.event.order.refund.created.externally': _('Refund {local_id} has been created by an external entity.'),
'pretix.event.order.refund.requested': _('The customer requested you to issue a refund.'),
'pretix.event.order.refund.done': _('Refund {local_id} has been completed.'),
'pretix.event.order.refund.canceled': _('Refund {local_id} has been canceled.'),
'pretix.event.order.refund.failed': _('Refund {local_id} has failed.'),
})
class CoreOrderPaymentLogEntryType(OrderLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.quota.added': _('The quota has been added.'),
'pretix.event.quota.deleted': _('The quota has been deleted.'),
'pretix.event.quota.changed': _('The quota has been changed.'),
'pretix.event.quota.closed': _('The quota has closed.'),
'pretix.event.quota.opened': _('The quota has been re-opened.'),
})
class CoreQuotaLogEntryType(QuotaLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.question.added': _('The question has been added.'),
'pretix.event.question.deleted': _('The question has been deleted.'),
'pretix.event.question.changed': _('The question has been changed.'),
'pretix.event.question.reordered': _('The question has been reordered.'),
})
class CoreQuestionLogEntryType(QuestionLogEntryType):
pass
@log_entry_types.new_from_dict({
'pretix.event.discount.added': _('The discount has been added.'),
'pretix.event.discount.deleted': _('The discount has been deleted.'),
'pretix.event.discount.changed': _('The discount has been changed.'),
})
class CoreDiscountLogEntryType(DiscountLogEntryType):
pass
@log_entry_types.new()
class LegacyCheckinLogEntryType(OrderLogEntryType):
action_type = 'pretix.control.views.checkin'
def display(self, logentry):
# deprecated
dt = dateutil.parser.parse(logentry.parsed_data.get('datetime'))
tz = logentry.event.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in logentry.parsed_data:
try:
checkin_list = logentry.event.checkin_lists.get(pk=logentry.parsed_data.get('list')).name
except CheckinList.DoesNotExist:
checkin_list = _("(unknown)")
else:
checkin_list = _("(unknown)")
if logentry.parsed_data.get('first'):
return _('Position #{posid} has been checked in manually at {datetime} on list "{list}".').format(
posid=logentry.parsed_data.get('positionid'),
datetime=dt_formatted,
list=checkin_list,
)
return _('Position #{posid} has been checked in again at {datetime} on list "{list}".').format(
posid=logentry.parsed_data.get('positionid'),
datetime=dt_formatted,
list=checkin_list
)

View File

@@ -34,7 +34,7 @@
from django.dispatch import Signal
from pretix.base.signals import DeprecatedSignal, EventPluginSignal
from pretix.base.signals import DeprecatedSignal, EventPluginSignal, OrganizerPluginSignal
html_page_start = Signal()
"""
@@ -221,7 +221,7 @@ Deprecated signal, no longer works. We just keep the definition so old plugins d
break the installation.
"""
nav_organizer = Signal()
nav_organizer = OrganizerPluginSignal()
"""
Arguments: 'organizer', 'request'

View File

@@ -23,7 +23,7 @@
<legend>{{ catlabel }}</legend>
<div class="plugin-list">
{% for plugin in plist %}
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}">
<div class="plugin-container {% if plugin.featured %}featured-plugin{% endif %}" id="plugin_{{ plugin.module }}">
{% if plugin.featured %}
<div class="panel panel-default">
<div class="panel-body">

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-09 06:00+0000\n"
"Last-Translator: Ahmad AlHarthi <to.ahmad@pm.me>\n"
"PO-Revision-Date: 2024-05-08 07:07+0000\n"
"Last-Translator: AbdelatifAitBara <aitbaraabdelatif@outlook.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix/ar/"
">\n"
"Language: ar\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 5.7\n"
"X-Generator: Weblate 5.4.3\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -38,7 +38,7 @@ msgstr "العربية"
#: pretix/_base_settings.py:83
msgid "Catalan"
msgstr "الكتالانية"
msgstr ""
#: pretix/_base_settings.py:84
msgid "Chinese (simplified)"
@@ -46,7 +46,7 @@ msgstr "الصينية (المبسطة)"
#: pretix/_base_settings.py:85
msgid "Chinese (traditional)"
msgstr "الصينية (التقليدية)"
msgstr ""
#: pretix/_base_settings.py:86
msgid "Czech"
@@ -74,7 +74,7 @@ msgstr "الفنلندية"
#: pretix/_base_settings.py:92
msgid "Galician"
msgstr "الجاليكية"
msgstr ""
#: pretix/_base_settings.py:93
msgid "Greek"
@@ -94,7 +94,7 @@ msgstr "لاتفيفية"
#: pretix/_base_settings.py:97
msgid "Norwegian Bokmål"
msgstr "النرويجية"
msgstr ""
#: pretix/_base_settings.py:98
msgid "Polish"
@@ -110,7 +110,7 @@ msgstr "البرتغالية (البرازيل)"
#: pretix/_base_settings.py:101
msgid "Romanian"
msgstr "الرومانية"
msgstr ""
#: pretix/_base_settings.py:102
msgid "Russian"
@@ -118,11 +118,11 @@ msgstr "الروسية"
#: pretix/_base_settings.py:103
msgid "Slovak"
msgstr "السلوفاكية"
msgstr ""
#: pretix/_base_settings.py:104
msgid "Swedish"
msgstr "السويدية"
msgstr ""
#: pretix/_base_settings.py:105
msgid "Spanish"
@@ -134,7 +134,7 @@ msgstr "التركية"
#: pretix/_base_settings.py:107
msgid "Ukrainian"
msgstr "الأوكرانية"
msgstr ""
#: pretix/api/auth/devicesecurity.py:31
msgid ""
@@ -149,12 +149,16 @@ msgid "pretixSCAN"
msgstr "بريتكس pretixSCAN"
#: pretix/api/auth/devicesecurity.py:90
#, fuzzy
#| msgid "pretixSCAN (kiosk mode, online only)"
msgid "pretixSCAN (kiosk mode, no order sync, no search)"
msgstr "pretixSCAN (وضع kiosk، لا مزامنة للطلبات ولا بحث)"
msgstr "pretixSCAN (وضع kiosk، عبر الانترنت فقط)"
#: pretix/api/auth/devicesecurity.py:124
#, fuzzy
#| msgid "pretixSCAN (kiosk mode, online only)"
msgid "pretixSCAN (online only, no order sync)"
msgstr "pretixSCAN (وضع kiosk، لا مزامنة للطلبات)"
msgstr "pretixSCAN (وضع kiosk، عبر الانترنت فقط)"
#: pretix/api/auth/devicesecurity.py:159
msgid "pretixPOS"
@@ -173,8 +177,10 @@ msgid "Allowed URIs list, space separated"
msgstr "قائمة العناوين المسموح بها, مفصولة بمسافة"
#: pretix/api/models.py:47
#, fuzzy
#| msgid "Allowed URIs list, space separated"
msgid "Allowed Post Logout URIs list, space separated"
msgstr "قائمة العناوين المسموح بها بعد تسجيل الخروج، مفصولة بمسافة"
msgstr "قائمة العناوين المسموح بها، مفصولة بمسافة"
#: pretix/api/models.py:51 pretix/base/models/customers.py:395
#: pretix/plugins/paypal/payment.py:113 pretix/plugins/paypal2/payment.py:110
@@ -257,9 +263,10 @@ msgid "Unknown plugin: '{name}'."
msgstr "إضافة غير معروفة: '{name}'."
#: pretix/api/serializers/event.py:295
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Unknown plugin: '{name}'."
msgid "Restricted plugin: '{name}'."
msgstr "إضافة مقيدة: '{name}'."
msgstr "إضافة غير معروفة: '{name}'."
#: pretix/api/serializers/item.py:86 pretix/api/serializers/item.py:148
#: pretix/api/serializers/item.py:359
@@ -285,7 +292,7 @@ msgstr ""
#: pretix/api/serializers/item.py:306
msgid "Only admission products can currently be personalized."
msgstr "يمكن حاليًا تخصيص منتجات القبول فقط."
msgstr ""
#: pretix/api/serializers/item.py:317
msgid ""
@@ -320,19 +327,26 @@ msgid "This type of question cannot be asked during check-in."
msgstr "لا يمكن طرح هذا النوع من الأسئلة أثناء تسجيل الدخول."
#: pretix/api/serializers/item.py:531 pretix/control/forms/item.py:142
#, fuzzy
#| msgid "This type of question cannot be asked during check-in."
msgid "This type of question cannot be shown during check-in."
msgstr "لا يمكن عرض هذا النوع من الأسئلة أثناء تسجيل الدخول."
msgstr "لا يمكن طرح هذا النوع من الأسئلة أثناء تسجيل الدخول."
#: pretix/api/serializers/media.py:108
#, fuzzy
#| msgid ""
#| "A gift card with the same secret already exists in your or an affiliated "
#| "organizer account."
msgid ""
"A medium with the same identifier and type already exists in your organizer "
"account."
msgstr "توجد وسيلة بنفس المعرف والنوع في حساب المنظم الخاص بك."
msgstr "توجد مسبقا بطاقة هدايا بنفس السر في حسابك أو حساب منظم تابع."
#: pretix/api/serializers/order.py:78
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Your input was invalid, please try again."
msgid "\"{input}\" is not a valid choice."
msgstr "\"{input}\" ادخال غير صالحة، يرجى المحاولة مرة أخرى."
msgstr "كان الإدخال غير صالحة، يرجى المحاولة مرة أخرى."
#: pretix/api/serializers/order.py:1316 pretix/api/views/cart.py:224
#: pretix/base/services/orders.py:1530
@@ -387,7 +401,7 @@ msgstr "تم استخدام رمز كود الخصم هذا سابقا لأقص
#: pretix/api/views/checkin.py:604 pretix/api/views/checkin.py:611
msgid "Medium connected to other event"
msgstr "الوسيط متصل بحدث آخر"
msgstr ""
#: pretix/api/views/oauth.py:107 pretix/control/logdisplay.py:475
#, python-brace-format
@@ -399,17 +413,17 @@ msgstr "تم تفويض التطبيق \"{application_name}\" للوصول إل
#: pretix/api/views/order.py:603 pretix/control/views/orders.py:1587
#: pretix/presale/views/order.py:743 pretix/presale/views/order.py:816
msgid "You cannot generate an invoice for this order."
msgstr "لا يمكن انشاء فاتورة لهذا الطلب."
msgstr "لا يمكنك توليد فاتورة لهذا الطلب."
#: pretix/api/views/order.py:608 pretix/control/views/orders.py:1589
#: pretix/presale/views/order.py:745 pretix/presale/views/order.py:818
msgid "An invoice for this order already exists."
msgstr "توجد فاتورة مصدرة لهذا الطلب مسبقاً."
msgstr "توجد فاتورة مصدرة لهذا الطلب مسبقا."
#: pretix/api/views/order.py:634 pretix/control/views/orders.py:1715
#: pretix/control/views/users.py:143
msgid "There was an error sending the mail. Please try again later."
msgstr "حدث خطأ اثناء ارسال البريد الاكتروني. الرجاء المحاولة مرة أخرى لاحقاً."
msgstr "حدث خطأ أثناء إرسال البريد. الرجاء المحاولة مرة أخرى في وقت لاحق."
#: pretix/api/views/order.py:712 pretix/base/services/cart.py:215
#: pretix/base/services/orders.py:186 pretix/presale/views/order.py:800
@@ -418,11 +432,11 @@ msgstr "أحد المنتجات المختارة غير متوفر في البل
#: pretix/api/webhooks.py:237 pretix/base/notifications.py:233
msgid "New order placed"
msgstr "تم وضع طلب جديد"
msgstr "تم تقديم طلب جديد"
#: pretix/api/webhooks.py:241 pretix/base/notifications.py:239
msgid "New order requires approval"
msgstr "الطلب الجديد بحاجة إلى موافقة"
msgstr "طلب جديد يتطلب الموافقة."
#: pretix/api/webhooks.py:245 pretix/base/notifications.py:245
msgid "Order marked as paid"

View File

@@ -5,8 +5,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-13 21:00+0000\n"
"Last-Translator: Wikinaut <mail@tgries.de>\n"
"PO-Revision-Date: 2024-08-27 16:02+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/de/"
">\n"
"Language: de\n"
@@ -5997,9 +5997,8 @@ msgid ""
"your organizer accounts and your events."
msgstr ""
"Sollte kurz sein und darf nur Kleinbuchstaben, Zahlen, Bindestriche und "
"Punkte enthalten. Jede Kurzform kann nur einmal vergeben werden. Sie wird in "
"URLs verwendet, um auf Ihr Veranstalterkonto und Ihre Veranstaltungen zu "
"verweisen."
"Punkte enthalten. Jede Kurzform kann nur einmal benutzt werden und wird in "
"URLs zu Ihrem Veranstalterkonto und Ihren Veranstaltern."
#: pretix/base/models/organizer.py:97 pretix/control/navigation.py:348
#: pretix/control/templates/pretixcontrol/oauth/authorized.html:19
@@ -6881,9 +6880,9 @@ msgid ""
"Create an invoice for orders using bank transfer immediately if the event is "
"otherwise configured to create invoices after payment is completed."
msgstr ""
"Generiere Rechnungen für Bestellungen sofort, wenn Banküberweisung als "
"Zahlungsmethode genutzt wird, und zwar auch dann, wenn die Veranstaltung so "
"konfiguriert ist, Rechnungen erst nach Zahlungseingang zu generieren."
"Generiere Rechnungen für Bestellungen die Banküberweisung als "
"Zahlungsmethode nutzen sofort, auch wenn die Veranstaltung konfiguriert ist "
"Rechnungen erst nach Zahlungseingang zu generieren."
#: pretix/base/payment.py:1259
msgid "Offsetting"
@@ -24188,7 +24187,7 @@ msgid ""
"generated by plugins. If you want to embed a logo or other images, use a "
"custom background instead."
msgstr ""
"Sie können diese Funktion nutzen, um dynamische Bilder z.B. aus Fragefeldern "
"Sie können diese Funktion nutzen um dynamische Bilder z.B. aus Fragefeldern "
"oder aus Erweiterungen einzubinden. Wenn Sie ein Logo oder andere statische "
"Bilder einbinden wollen, nutzen Sie stattdessen einen eigenen Hintergrund."

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
"PO-Revision-Date: 2024-08-27 16:02+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
"de/>\n"
@@ -572,8 +572,10 @@ msgid "Group of objects"
msgstr "Gruppe von Objekten"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "Text-Objekt (veraltet)"
msgstr "Text-Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
msgid "Text box"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
"Last-Translator: Richard Schreiber <schreiber@rami.io>\n"
"PO-Revision-Date: 2024-08-27 16:00+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix/de_Informal/>\n"
"Language: de_Informal\n"
@@ -5993,9 +5993,8 @@ msgid ""
"your organizer accounts and your events."
msgstr ""
"Sollte kurz sein und darf nur Kleinbuchstaben, Zahlen, Bindestriche und "
"Punkte enthalten. Jede Kurzform kann nur einmal vergeben werden. Sie wird in "
"URLs verwendet, um auf dein Veranstalterkonto und deine Veranstaltungen zu "
"verweisen."
"Punkte enthalten. Jede Kurzform darf nur einmal vergeben werden und wird in "
"URLs zu deinem Veranstalter und deinen Veranstalterkonten verwendet."
#: pretix/base/models/organizer.py:97 pretix/control/navigation.py:348
#: pretix/control/templates/pretixcontrol/oauth/authorized.html:19

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-10 07:17+0000\n"
"PO-Revision-Date: 2024-08-27 16:00+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
"pretix/pretix-js/de_Informal/>\n"
@@ -571,8 +571,10 @@ msgid "Group of objects"
msgstr "Gruppe von Objekten"
#: pretix/static/pretixcontrol/js/ui/editor.js:899
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "Text-Objekt (veraltet)"
msgstr "Text-Objekt"
#: pretix/static/pretixcontrol/js/ui/editor.js:901
msgid "Text box"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-03 00:00+0000\n"
"PO-Revision-Date: 2024-07-23 10:22+0000\n"
"Last-Translator: Alberto Ortega <ortega16.cieza@gmail.com>\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.7\n"
"X-Generator: Weblate 5.6.2\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -3984,9 +3984,8 @@ msgstr ""
#: pretix/base/models/customers.py:299 pretix/base/models/orders.py:1513
#: pretix/base/models/orders.py:3175 pretix/base/settings.py:1096
#, fuzzy
msgid "Company name"
msgstr "Razón Social / Organización"
msgstr "Nombre de la Compañía"
#: pretix/base/models/customers.py:303 pretix/base/models/orders.py:1517
#: pretix/base/models/orders.py:3182 pretix/base/settings.py:81

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-18 14:02+0000\n"
"PO-Revision-Date: 2024-08-29 21:00+0000\n"
"Last-Translator: Albizuri <oier@puntu.eus>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix/eu/"
">\n"
@@ -17,11 +17,11 @@ 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.7.2\n"
"X-Generator: Weblate 5.7\n"
#: pretix/_base_settings.py:79
msgid "English"
msgstr "Euskara"
msgstr "Ingelesa"
#: pretix/_base_settings.py:80
msgid "German"
@@ -1414,7 +1414,7 @@ msgstr "Helbidea"
#: pretix/plugins/reports/exporters.py:841 pretix/control/forms/filter.py:630
#: pretix/control/forms/filter.py:661
msgid "ZIP code"
msgstr "Posta-kodea"
msgstr "ZIP kodea"
#: pretix/base/exporters/invoices.py:209 pretix/base/exporters/invoices.py:217
#: pretix/base/exporters/invoices.py:335 pretix/base/exporters/invoices.py:343
@@ -2372,7 +2372,7 @@ msgstr "Fakturaren helbidea kalea"
#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:345
msgid "Invoice address ZIP code"
msgstr "Fakturaren helbidea posta-kodea"
msgstr "Fakturaren helbidea posta kodea"
#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:350
msgid "Invoice address city"
@@ -3015,7 +3015,7 @@ msgstr "Lehentasuna"
#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:19
#: pretix/control/views/vouchers.py:118
msgid "Voucher code"
msgstr "Kupoia"
msgstr "Kupoiaren kodea"
#: pretix/base/forms/__init__.py:95 pretix/base/forms/__init__.py:106
#: pretix/base/forms/__init__.py:118
@@ -3270,11 +3270,11 @@ msgstr "Ordua"
#: pretix/base/forms/widgets.py:234 pretix/base/forms/widgets.py:239
#: pretix/base/forms/widgets.py:233 pretix/base/forms/widgets.py:238
msgid "Business or institutional customer"
msgstr "Enpresa edo erakundea"
msgstr "Enpresa- edo erakunde-bezeroa"
#: pretix/base/forms/widgets.py:238 pretix/base/forms/widgets.py:237
msgid "Individual customer"
msgstr "Norbanakoa"
msgstr "Norbanako bezeroa"
#: pretix/base/invoice.py:86
#, python-format
@@ -7729,7 +7729,8 @@ msgstr[1] ""
#: pretix/base/services/cart.py:168
msgid ""
"This voucher code has already been used the maximum number of times allowed."
msgstr "Kupoi hori baimendutako gehienezko aldi-kopurua erabili da dagoeneko."
msgstr ""
"Kupoi-kode hori baimendutako gehienezko aldi-kopurua erabili da dagoeneko."
#: pretix/base/services/cart.py:170
#, python-format
@@ -10479,7 +10480,7 @@ msgid "Your event registration: {code}"
msgstr "Zure ekitaldiaren erregistroa: {code}"
#: pretix/base/settings.py:2159
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10501,7 +10502,7 @@ msgstr ""
"{url}\n"
"\n"
"Adeitasunez,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2172
#, python-brace-format
@@ -10509,7 +10510,7 @@ msgid "Your orders for {event}"
msgstr "Zure eskaerak {event}-rako"
#: pretix/base/settings.py:2176
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10529,10 +10530,10 @@ msgstr ""
"{orders}\n"
"\n"
"Adeitasunez,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2192
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {attendee_name},\n"
"\n"
@@ -10552,7 +10553,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2212
#, python-brace-format
@@ -10570,17 +10571,17 @@ msgid ""
msgstr ""
"Kaixo,\n"
"\n"
"{event}-rako sarrerak eskuratu dituzu. Doakoak direnez,\n"
"{event}-erako izena eman duzu. Doako produktuak eskatu dituzunez,\n"
"ez duzu ezer ordaindu behar.\n"
"\n"
"Eskaeraren xehetasunak aldatu eta eskaeraren egoera ikus dezakezu hemen\n"
"{url}\n"
"\n"
"Agur bat,\n"
"{event}eko lantaldea"
"{event} taldea"
#: pretix/base/settings.py:2229
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10605,10 +10606,10 @@ msgstr ""
"{url}\n"
"\n"
"Agur bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2247
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10635,7 +10636,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2265
msgid "Attachment for new orders"
@@ -10662,7 +10663,7 @@ msgstr ""
"dadin, MB {size} arteko PDF fitxategiak baino ezin dituzu kargatu."
#: pretix/base/settings.py:2297
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {attendee_name},\n"
"\n"
@@ -10682,7 +10683,7 @@ msgstr ""
"{url}\n"
"\n"
"Adeitasunez,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2309
#, python-brace-format
@@ -10690,7 +10691,7 @@ msgid "Your order has been changed: {code}"
msgstr "Zure eskera aldatu egin da: {code}"
#: pretix/base/settings.py:2313
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10710,7 +10711,7 @@ msgstr ""
"{url}\n"
"\n"
"Adeitasunez,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2325
#, python-brace-format
@@ -10718,7 +10719,7 @@ msgid "Payment received for your order: {code}"
msgstr "Zure eskaeraren ordainketa jaso dugu: {code}"
#: pretix/base/settings.py:2329
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10742,7 +10743,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2347
#, python-brace-format
@@ -10750,7 +10751,7 @@ msgid "Event registration confirmed: {code}"
msgstr "Ekitaldiko izen-ematea konfirmatuta: {code}"
#: pretix/base/settings.py:2351
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {attendee_name},\n"
"\n"
@@ -10770,7 +10771,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bat,\n"
"PUNTUEUS"
"{event} zure ekipoa"
#: pretix/base/settings.py:2368 pretix/control/forms/event.py:1119
#: pretix/control/forms/event.py:1219 pretix/plugins/sendmail/models.py:259
@@ -10791,7 +10792,7 @@ msgid "Your order is about to expire: {code}"
msgstr "Zure eskaera iraungitzear dago: {code}"
#: pretix/base/settings.py:2382
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10816,7 +10817,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2396
#, python-brace-format
@@ -10824,7 +10825,7 @@ msgid "Your order is pending payment: {code}"
msgstr "Zure eskaera ordaintzeke dago: {code}"
#: pretix/base/settings.py:2400
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10846,7 +10847,7 @@ msgstr ""
"{url}\n"
"\n"
"Adeitasunez,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2413
#, python-brace-format
@@ -10854,7 +10855,7 @@ msgid "Incomplete payment received: {code}"
msgstr "Ordainketaren zati bat jaso da: {code}"
#: pretix/base/settings.py:2417
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10882,7 +10883,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2433
#, python-brace-format
@@ -10890,7 +10891,7 @@ msgid "Payment failed for your order: {code}"
msgstr "Zure eskeraren ordainketak huts egin du: {code}"
#: pretix/base/settings.py:2437
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10907,8 +10908,8 @@ msgid ""
"Your {event} team"
msgstr ""
"Kaixo,\n"
"{event} ekitaldirako egin duzun eskaeraren ordainketa-saiakerak huts egin du."
"\n"
"{event} ekitaldirako egin duzun eskaeraren ordainketa-saiakerak huts egin "
"du.\n"
"\n"
"Zure eskaera oraindik baliozkoa da, eta ordainketa berdinarekin edo beste "
"ordainketa-metodo batekin berriro saiatu zaitezke. Mesedez, osatu ordainketa "
@@ -10918,7 +10919,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2451
#, python-brace-format
@@ -10926,7 +10927,7 @@ msgid "You have been selected from the waitinglist for {event}"
msgstr "{event} ekitaldirako itxaron-zerrendatik hautatu zaituzte"
#: pretix/base/settings.py:2455
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -10970,8 +10971,8 @@ msgstr ""
"\n"
"{url}\n"
"\n"
"Kontuan izan esteka hau hurrengo {hours} orduetan baino ez dela baliogarria!"
"\n"
"Kontuan izan esteka hau hurrengo {hours} orduetan baino ez dela "
"baliogarria!\n"
"Denbora tarte horretan bonua trukatzen ez baduzu, sarrera itxaron-zerrendan "
"dagoen\n"
"hurrengo pertsonari esleituko diogu.\n"
@@ -10984,7 +10985,7 @@ msgstr ""
"{url_remove}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2484
#, python-brace-format
@@ -10992,7 +10993,7 @@ msgid "Order canceled: {code}"
msgstr "Eskaera ezeztatua: {code}"
#: pretix/base/settings.py:2488
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11016,7 +11017,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2502
#, python-brace-format
@@ -11024,7 +11025,7 @@ msgid "Order approved and awaiting payment: {code}"
msgstr "Eskaera onartuta eta ordainketaren zain: {code}"
#: pretix/base/settings.py:2506
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11052,10 +11053,10 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2530 pretix/base/settings.py:2567
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11075,7 +11076,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2542
#, python-brace-format
@@ -11083,7 +11084,7 @@ msgid "Order approved and confirmed: {code}"
msgstr "Eskaera onartuta eta konfirmatuta: {code}"
#: pretix/base/settings.py:2546
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11106,7 +11107,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2579
#, python-brace-format
@@ -11114,7 +11115,7 @@ msgid "Order denied: {code}"
msgstr "Eskaera ukatua: {code}"
#: pretix/base/settings.py:2583
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11139,10 +11140,10 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat, \n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2598
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11158,7 +11159,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat, \n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2616 pretix/base/settings.py:2632
#, python-brace-format
@@ -11166,7 +11167,7 @@ msgid "Your ticket is ready for download: {code}"
msgstr "Zure sarrera deskargatzeko prest dago: {code}"
#: pretix/base/settings.py:2620
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {attendee_name},\n"
"\n"
@@ -11186,10 +11187,10 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat, \n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2636
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -11209,7 +11210,7 @@ msgstr ""
"{url}\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{event} taldea"
#: pretix/base/settings.py:2648
#, python-brace-format
@@ -11217,7 +11218,7 @@ msgid "Activate your account at {organizer}"
msgstr "Zure kontua aktibatu {organizer}-en"
#: pretix/base/settings.py:2652
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {name},\n"
"\n"
@@ -11248,7 +11249,7 @@ msgstr ""
"Zure izen-ematea zuk egin ez baduzu, mesedez, baztertu mezu hau.\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{organizer} taldea"
#: pretix/base/settings.py:2670
#, python-brace-format
@@ -11256,7 +11257,7 @@ msgid "Confirm email address for your account at {organizer}"
msgstr "Zure kontuaren e-posta helbidea berretsi {organizer}-en"
#: pretix/base/settings.py:2674
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {name},\n"
"\n"
@@ -11287,7 +11288,7 @@ msgstr ""
"Aldaketa hori zuk eskatu ez baduzu, mesedez, baztertu mezu hau.\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{organizer} taldea"
#: pretix/base/settings.py:2692
#, python-brace-format
@@ -11295,7 +11296,7 @@ msgid "Set a new password for your account at {organizer}"
msgstr "Ezarri pasahitz berria zure {organizer} konturako"
#: pretix/base/settings.py:2696
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello {name},\n"
"\n"
@@ -11326,7 +11327,7 @@ msgstr ""
"Pasahitz berri bat eskatu ez baduzu, mesedez, baztertu mezu hau.\n"
"\n"
"Agur bero bat,\n"
"PUNTUEUS"
"{organizer} taldea"
#: pretix/base/settings.py:2748 pretix/base/settings.py:2755
#: pretix/base/settings.py:2769 pretix/base/settings.py:2777
@@ -11558,8 +11559,9 @@ msgid ""
"Make sure to enter a valid email address. We will send you an order "
"confirmation including a link that you need to access your order later."
msgstr ""
"Ziurtatu baliozko e-posta helbidea sartzen duzula. Eskaeraren konfirmazio "
"bat bidaliko dizugu eskaerara sartzeko beharrezkoa den estekarekin."
"Ziurtatu baliozko e-posta helbidea sartzen duzula. Eskaera konfirmazio bat "
"bidaliko dizugu, eta eskaerara gero sartzeko beharrezkoa den esteka bat "
"izango du."
#: pretix/base/settings.py:3107
msgid "Help text of the email field"
@@ -12485,12 +12487,12 @@ msgstr "Iragan guztia (gaurko eguna barne)"
#: pretix/base/timeframes.py:284
msgctxt "timeframe"
msgid "Start"
msgstr "Hasiera-ordua:"
msgstr "Hasiera"
#: pretix/base/timeframes.py:285
msgctxt "timeframe"
msgid "End"
msgstr "Amaiera-ordua"
msgstr "Amaiera"
#: pretix/base/timeframes.py:318
msgid "The end date must be after the start date."
@@ -14968,10 +14970,10 @@ msgstr ""
#: pretix/control/forms/vouchers.py:273 pretix/control/forms/vouchers.py:272
#, python-brace-format
msgid "Your voucher for {event}"
msgstr "{event}erako zure kupoia"
msgstr ""
#: pretix/control/forms/vouchers.py:279 pretix/control/forms/vouchers.py:278
#, fuzzy, python-brace-format
#, python-brace-format
msgid ""
"Hello,\n"
"\n"
@@ -14986,18 +14988,6 @@ msgid ""
"Best regards, \n"
"Your {event} team"
msgstr ""
"Kaixo,\n"
"\n"
"Mezu honetan, {event}erako kupoi bat edo gehiago bidaltzen dizkizugu:\n"
"\n"
"{voucher_list}\n"
"\n"
"Kupoiak orrialde honetan erabil ditzakezu:\n"
"\n"
"{url}\n"
"\n"
"Agur bat, \n"
"PUNTUEUS"
#: pretix/control/forms/vouchers.py:285
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_create.html:28
@@ -16250,7 +16240,7 @@ msgstr ""
#: pretix/presale/views/order.py:1054 pretix/control/views/orders.py:1548
#: pretix/presale/views/order.py:1052
msgid "The order has been canceled."
msgstr "Sarrerak bertan behera utzi dira."
msgstr ""
#: pretix/control/logdisplay.py:634
#, python-brace-format
@@ -18233,9 +18223,6 @@ msgid ""
"vouchers and might perform actual payments. The only difference is that you "
"can delete test orders. Use at your own risk!"
msgstr ""
"Kontuan izan proba-eskaerek kuotetan kontatzen jarraitzen dutela, kupoiak "
"erabiltzen dituztela eta ordainketak egin ditzaketela. Ezberdintasun bakarra "
"da probako aginduak ezaba ditzakezula. Erabil itzazu zeure ardurapean!"
#: pretix/control/templates/pretixcontrol/event/live.html:108
msgid ""
@@ -20344,7 +20331,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/refund_cancel.html:27
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:212
msgid "No, take me back"
msgstr "Ez, itzuli"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/approve.html:25
msgid "Yes, approve order"
@@ -20357,7 +20344,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order.html:478
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:7
msgid "Cancel order"
msgstr "Sarrerak ezeztatu"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/cancel.html:12
#: pretix/control/templates/pretixcontrol/order/deny.html:11
@@ -20381,7 +20368,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/cancel.html:51
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:220
msgid "Yes, cancel order"
msgstr "Bai, sarrerak bertan behera utzi"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/cancellation_request_delete.html:4
#: pretix/control/templates/pretixcontrol/order/cancellation_request_delete.html:8
@@ -20620,13 +20607,13 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order_modify.html:29
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:78
msgid "Invoice information"
msgstr "Fakturazio datuak"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/change_questions.html:26
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:40
#: pretix/presale/templates/pretixpresale/event/order_modify.html:30
msgid "(optional)"
msgstr "(hautazkoa)"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/delete.html:4
#: pretix/control/templates/pretixcontrol/order/delete.html:8
@@ -20831,7 +20818,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:369
#: pretix/presale/templates/pretixpresale/event/order.html:196
msgid "Ordered items"
msgstr "Sarrerak"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:388
#, python-format
@@ -20851,7 +20838,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:422
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:54
msgid "Voucher code used:"
msgstr "Erabilitako kupoia:"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:424
#, python-format
@@ -20994,7 +20981,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order.html:317
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:94
msgid "ZIP code and city"
msgstr "Posta-kodea eta herria"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:970
msgid "Valid EU VAT ID"
@@ -22185,7 +22172,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/edit.html:161
msgid "Privacy"
msgstr "Pribatutasuna"
msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/edit.html:165
msgid ""
@@ -24086,9 +24073,6 @@ msgid ""
"Vouchers allow you to assign tickets to specific persons for a lower price. "
"They also enable you to reserve some quota for your very special guests."
msgstr ""
"Kupoiek aukera ematen diote pertsona jakin batzuei sarrerak prezio baxuagoan "
"esleitzeko. Gonbidatu oso berezientzat kuotaren bat erreserbatzeko aukera "
"ere ematen diote."
#: pretix/control/templates/pretixcontrol/vouchers/index.html:67
msgid "Your search did not match any vouchers."
@@ -30688,7 +30672,7 @@ msgstr "Eskaera loteslea egin"
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:209
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:213
msgid "Submit registration"
msgstr "Erosketarekin amaitu"
msgstr "Izen-ematea bidali"
#: pretix/presale/templates/pretixpresale/event/checkout_customer.html:20
msgid "Log in with a customer account"
@@ -31099,7 +31083,7 @@ msgstr "Ez dago produktu honetarako osagarririk."
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:6
msgid "Enter a voucher code below to buy this product."
msgstr "Sarrera hau eskuratzeko sartu kupoia beheko laukian."
msgstr "Sartu kupoiaren kodea behean produktu hau erosteko."
#: pretix/presale/templates/pretixpresale/event/fragment_availability.html:10
msgid "Not available yet."
@@ -31183,7 +31167,7 @@ msgstr[1] "Sarrera hau %(count)s aldiz erabili da."
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:170
msgid "No attendee name provided"
msgstr "Ez da bertaratuko den pertsonaren izena adierazi"
msgstr "Ez dago bertaratuko den pertsonaren izena ahalbidetuta"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:223
msgid "The image you previously uploaded"
@@ -31282,7 +31266,7 @@ msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as theyre available."
msgstr ""
"Zure saskiko produktuak ez daude zuretzat erreserbatuta. Oraindik ere zure "
"Zure saskiko artikuluak ez daude zuretzat erreserbatuta. Oraindik ere zure "
"eskaera bete dezakezu, baldin eta eskuragarri badaude."
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:490
@@ -31301,13 +31285,13 @@ msgstr "Erosketari ekin"
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:40
msgid "Empty cart"
msgstr "Saskia hustu"
msgstr "Saski hutsa"
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:45
#: pretix/presale/templates/pretixpresale/event/index.html:236
#: pretix/presale/templates/pretixpresale/event/voucher_form.html:16
msgid "Redeem a voucher"
msgstr "Kupoia erabili"
msgstr "Kupoi bat trukatu"
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:48
msgid "We're applying this voucher to your cart..."
@@ -31316,7 +31300,7 @@ msgstr "Kupoi hau zure saskiari aplikatzen ari gara..."
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:56
#: pretix/presale/templates/pretixpresale/event/fragment_voucher_form.html:26
msgid "Redeem voucher"
msgstr "Kupoia erabili"
msgstr "Kupoia trukatu"
#: pretix/presale/templates/pretixpresale/event/fragment_change_confirm.html:10
msgid "Change summary"
@@ -31474,7 +31458,7 @@ msgstr "Une honetan:"
#: pretix/presale/templates/pretixpresale/event/fragment_checkoutflow.html:26
msgctxt "checkoutflow"
msgid "Order confirmed"
msgstr "Eskaera konfirmatu"
msgstr "Eskaera konfirmatuta"
#: pretix/presale/templates/pretixpresale/event/fragment_downloads.html:14
msgid "Please check your email account, we've sent you your tickets."
@@ -31815,7 +31799,7 @@ msgstr ""
"Zure eskaeraren egoera eta xehetasunak ikusi edo aldatu nahi badituzu, egin "
"klik eskaera-prozesuan bidaltzen dizkizugun mezu elektronikoetako baten "
"estekan. Esteka aurkitu ezin baduzu, egin klik hurrengo botoian, berriro "
"bidal diezazugun."
"bidaltzeko zure eskaerarako esteka eskatzeko."
#: pretix/presale/templates/pretixpresale/event/index.html:256
msgid "Resend order link"
@@ -31851,7 +31835,7 @@ msgstr "Zure eskaera ongi gauzatu da. Ikus beherago xehetasun gehiagorako."
#: pretix/presale/templates/pretixpresale/event/order.html:16
#: pretix/presale/templates/pretixpresale/event/order.html:48
msgid "Your order has been processed successfully! See below for details."
msgstr "Zure eskaera ongi gauzatu da! Behean dituzu xehetasun gehiago."
msgstr "Zure eskaera ongi prozesatu da! Ikus beherago xehetasun gehiagorako."
#: pretix/presale/templates/pretixpresale/event/order.html:18
#: pretix/presale/templates/pretixpresale/event/order.html:50
@@ -31885,8 +31869,9 @@ msgid ""
"your order later. We also sent you an email containing the link to the "
"address you specified."
msgstr ""
"Mesedez, gorde orri honetarako esteka zure eskaera geroago ikusi nahi "
"baduzu. E-mail bat ere bidali dizugu, zehaztutako helbidera lotura duena."
"Mesedez, markatu edo gorde orri zehatz honetarako esteka zure eskaera "
"aurrerago ikusi nahi baduzu. E-mail bat ere bidali dizugu, zehaztutako "
"helbidera lotura duena."
#: pretix/presale/templates/pretixpresale/event/order.html:58
msgid ""
@@ -31964,13 +31949,13 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order.html:198
#: pretix/presale/templates/pretixpresale/event/position.html:33
msgid "Change ordered items"
msgstr "Eskatutako produktuak aldatu"
msgstr "Eskatutako artikuluak aldatu"
#: pretix/presale/templates/pretixpresale/event/order.html:199
#: pretix/presale/templates/pretixpresale/event/order.html:290
#: pretix/presale/templates/pretixpresale/event/position.html:34
msgid "Change details"
msgstr "Editatu"
msgstr "Xehetasunak aldatu"
#: pretix/presale/templates/pretixpresale/event/order.html:262
msgid ""
@@ -32008,7 +31993,7 @@ msgstr "Zure eskaera aldatu"
#: pretix/presale/templates/pretixpresale/event/order.html:353
msgctxt "action"
msgid "Cancel your order"
msgstr "Zure sarrerak ezeztatu"
msgstr "Zure eskaera ezeztatu"
#: pretix/presale/templates/pretixpresale/event/order.html:361
msgid ""
@@ -32119,7 +32104,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order.html:467
msgid "You can cancel this order using the following button."
msgstr "Sarrera hauek bertan behera utz ditzakezu hurrengo botoian klik eginez."
msgstr "Eskaera hori bertan behera utz dezakezu hurrengo botoiarekin."
#: pretix/presale/templates/pretixpresale/event/order_cancel.html:11
#, python-format
@@ -32340,9 +32325,9 @@ msgid ""
"you used for your order. We will send you an email with links to all orders "
"you placed using this email address."
msgstr ""
"Zure eskaerarako edo eskaeretarako esteka galdu baduzu, idatzi eskaera "
"egiteko erabili zenuen helbide elektronikoa. E-mail bat bidaliko dizugu, "
"helbide elektroniko hau erabiliz egin dituzun eskaera guztietarako estekekin."
"Zure eskaerarako edo eskaeretarako esteka galdu baduzu, sartu eskaerarako "
"erabili zenuen helbide elektronikoa. E-mail bat bidaliko dizugu, e-mail hau "
"erabiliz egin dituzun eskaera guztietarako estekekin."
#: pretix/presale/templates/pretixpresale/event/resend_link.html:30
msgid "Send links"
@@ -32391,7 +32376,9 @@ msgstr "Une honetan ez dago kupoi honekin eros daitekeen produkturik."
msgid ""
"You entered a voucher code that allows you to buy one of the following "
"products at the specified price:"
msgstr "Kupoi bat sartu duzu, produktu hauetako bat eskuratzeko:"
msgstr ""
"Deskontu-kode bat sartu duzu, produktu hauetako bat zehaztutako prezioan "
"erosteko:"
#: pretix/presale/templates/pretixpresale/event/voucher.html:113
#, python-format

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
"PO-Revision-Date: 2024-08-29 10:36+0000\n"
"Last-Translator: Albizuri <oier@puntu.eus>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
"eu/>\n"
@@ -720,7 +720,7 @@ msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as theyre available."
msgstr ""
"Zure saskiko produktuak ez daude zuretzat erreserbatuta. Oraindik ere zure "
"Zure saskiko artikuluak ez daude zuretzat erreserbatuta. Oraindik ere zure "
"eskaera bete dezakezu, baldin eta eskuragarri badaude."
#: pretix/static/pretixpresale/js/ui/cart.js:45
@@ -730,8 +730,8 @@ msgstr "Saskia iraungita"
#: pretix/static/pretixpresale/js/ui/cart.js:50
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] "Zure saskiko produktuak minutu -ez erreserbatuta daude zuretzat."
msgstr[1] "Zure saskiko produktuak {num} minutuz erreserbatuta daude zuretzat."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:203
msgid "The organizer keeps %(currency)s %(amount)s"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-16 13:00+0000\n"
"Last-Translator: Svyatoslav <slava@digitalarthouse.eu>\n"
"PO-Revision-Date: 2023-11-03 22:00+0000\n"
"Last-Translator: Jāzeps Benjamins Baško <jazeps.basko@gmail.com>\n"
"Language-Team: Latvian <https://translate.pretix.eu/projects/pretix/pretix/"
"lv/>\n"
"Language: lv\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n % 10 == 0 || n % 100 >= 11 && n % 100 <= "
"19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n"
"X-Generator: Weblate 5.7\n"
"X-Generator: Weblate 5.1.1\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -31361,7 +31361,7 @@ msgstr "Lūdzu, izvēlieties pasākumu, lai izmantotu kuponu/promokodu."
#: pretix/presale/templates/pretixpresale/event/index.html:82
msgid "View other date"
msgstr "Skatīt citus datumus vai notikumus"
msgstr "Skatīt citu datumu"
#: pretix/presale/templates/pretixpresale/event/index.html:87
msgid "Choose date to book a ticket"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-13 06:00+0000\n"
"Last-Translator: Arthur Nunes <coletivosuburbano@gmail.com>\n"
"PO-Revision-Date: 2024-06-18 20:00+0000\n"
"Last-Translator: \"L. Pereira\" <l@tia.mat.br>\n"
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_BR/>\n"
"Language: pt_BR\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.7\n"
"X-Generator: Weblate 5.5.5\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -37,7 +37,7 @@ msgstr "Árabe"
#: pretix/_base_settings.py:83
msgid "Catalan"
msgstr "Catalão"
msgstr ""
#: pretix/_base_settings.py:84
msgid "Chinese (simplified)"
@@ -117,11 +117,11 @@ msgstr "Russo"
#: pretix/_base_settings.py:103
msgid "Slovak"
msgstr "Eslovaco"
msgstr ""
#: pretix/_base_settings.py:104
msgid "Swedish"
msgstr "Sueco"
msgstr ""
#: pretix/_base_settings.py:105
msgid "Spanish"
@@ -256,9 +256,10 @@ msgid "Unknown plugin: '{name}'."
msgstr "Plugin desconhecido: '{name}'."
#: pretix/api/serializers/event.py:295
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Unknown plugin: '{name}'."
msgid "Restricted plugin: '{name}'."
msgstr "Plugin restrito: '{name}'."
msgstr "Plugin desconhecido: '{name}'."
#: pretix/api/serializers/item.py:86 pretix/api/serializers/item.py:148
#: pretix/api/serializers/item.py:359
@@ -497,8 +498,10 @@ msgid "Order denied"
msgstr "Pedido negado"
#: pretix/api/webhooks.py:313
#, fuzzy
#| msgid "Order denied"
msgid "Order deleted"
msgstr "Pedido deletado"
msgstr "Pedido negado"
#: pretix/api/webhooks.py:317
msgid "Ticket checked in"
@@ -642,15 +645,13 @@ msgstr "Compra online"
#: pretix/base/channels.py:174
msgid "API"
msgstr "API"
msgstr ""
#: pretix/base/channels.py:175
msgid ""
"API sales channels come with no built-in functionality, but may be used for "
"custom integrations."
msgstr ""
"Os canais de vendas da API não vêm com nenhuma funcionalidade incorporada, "
"mas podem ser usados para integrações personalizadas."
#: pretix/base/context.py:45
#, python-brace-format
@@ -1050,6 +1051,8 @@ msgid "No"
msgstr "Não"
#: pretix/base/exporters/dekodi.py:42 pretix/base/exporters/invoices.py:66
#, fuzzy
#| msgid "Invoices"
msgctxt "export_category"
msgid "Invoices"
msgstr "Faturas"
@@ -1081,12 +1084,16 @@ msgid "Date range"
msgstr "Intervalo de datas"
#: pretix/base/exporters/dekodi.py:237 pretix/base/exporters/invoices.py:77
#, fuzzy
#| msgid ""
#| "Only include invoices issued on or after this date. Note that the invoice "
#| "date does not always correspond to the order or payment date."
msgid ""
"Only include invoices issued in this time frame. Note that the invoice date "
"does not always correspond to the order or payment date."
msgstr ""
"Inclua apenas as faturas emitidas nesse período. Observe que a data da "
"fatura nem sempre corresponde à data do pedido ou do pagamento."
"Incluir apenas as faturas emitidas a partir desta data. Observe que a data "
"da fatura não corresponde sempre à ordem ou à data de pagamento."
#: pretix/base/exporters/events.py:47
msgid "Event data"
@@ -1515,6 +1522,9 @@ msgid "Payment providers"
msgstr "Provedores de pagamento"
#: pretix/base/exporters/invoices.py:285 pretix/base/exporters/invoices.py:388
#, fuzzy
#| msgctxt "invoice"
#| msgid "Cancellation"
msgid "Cancellation"
msgstr "Cancelamento"
@@ -1820,10 +1830,6 @@ msgid ""
"sheets, one with a line for every order, one with a line for every order "
"position, and one with a line for every additional fee charged in an order."
msgstr ""
"Faça o download de uma planilha de todos os pedidos. A planilha incluirá "
"três planilhas, uma com uma linha para cada pedido, uma com uma linha para "
"cada posição do pedido e uma com uma linha para cada taxa adicional cobrada "
"em um pedido."
#: pretix/base/exporters/orderlist.py:100 pretix/base/models/orders.py:330
#: pretix/control/navigation.py:253 pretix/control/navigation.py:360
@@ -1860,8 +1866,10 @@ msgstr "Mostrar opções de múltipla escolha agrupadas em uma coluna"
#: pretix/base/exporters/orderlist.py:131
#: pretix/plugins/reports/exporters.py:701
#, fuzzy
#| msgid "Only include orders created on or after this date."
msgid "Only include orders created within this date range."
msgstr "Incluir somente os pedidos criados dentro desse intervalo de datas."
msgstr "Incluir apenas pedidos criados a partir desta data."
#: pretix/base/exporters/orderlist.py:135 pretix/base/notifications.py:194
#: pretix/base/pdf.py:234 pretix/plugins/badges/exporters.py:484
@@ -1872,12 +1880,16 @@ msgid "Event date"
msgstr "Data do evento"
#: pretix/base/exporters/orderlist.py:138
#, fuzzy
#| msgid ""
#| "Only include orders including at least one ticket for a date on or after "
#| "this date. Will also include other dates in case of mixed orders!"
msgid ""
"Only include orders including at least one ticket for a date in this range. "
"Will also include other dates in case of mixed orders!"
msgstr ""
"Incluir apenas pedidos que incluam pelo menos um ingresso para uma data "
"nesse intervalo. Também incluiremos outras datas no caso de pedidos mistos!"
"Incluir apenas pedidos que possuam pelo menos um ingresso para esta data ou "
"após a mesma. Também incluirá outras datas em caso de pedidos mistos!"
#: pretix/base/exporters/orderlist.py:261
#: pretix/base/exporters/orderlist.py:440
@@ -2034,7 +2046,7 @@ msgstr "Canal de vendas"
#: pretix/base/exporters/orderlist.py:621 pretix/base/models/orders.py:275
#: pretix/control/forms/filter.py:240
msgid "Follow-up date"
msgstr "Data de acompanhamento"
msgstr ""
#: pretix/base/exporters/orderlist.py:286
#: pretix/control/templates/pretixcontrol/orders/index.html:151
@@ -2052,8 +2064,11 @@ msgstr "Endereço de e-mail verificado"
#: pretix/base/exporters/orderlist.py:288
#: pretix/base/exporters/orderlist.py:465
#: pretix/base/exporters/orderlist.py:659
#, fuzzy
#| msgctxt "refund_source"
#| msgid "Customer"
msgid "External customer ID"
msgstr "ID do cliente externo"
msgstr "Cliente"
#: pretix/base/exporters/orderlist.py:293
#, python-brace-format
@@ -2213,8 +2228,10 @@ msgstr "ID Proteção de Dados"
#: pretix/base/exporters/orderlist.py:611 pretix/control/forms/filter.py:677
#: pretix/control/templates/pretixcontrol/order/change.html:274
#, fuzzy
#| msgid "Device name"
msgid "Ticket secret"
msgstr "Segredo do bilhete"
msgstr "Nome do dispositivo"
#: pretix/base/exporters/orderlist.py:612 pretix/base/modelimport_orders.py:569
#: pretix/base/modelimport_vouchers.py:272
@@ -2249,7 +2266,7 @@ msgstr "Número do assento"
#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:108
#: pretix/plugins/statistics/templates/pretixplugins/statistics/index.html:110
msgid "Blocked"
msgstr "Bloqueado"
msgstr ""
#: pretix/base/exporters/orderlist.py:618 pretix/base/modelimport_orders.py:499
#: pretix/base/models/orders.py:2466
@@ -2258,8 +2275,10 @@ msgstr "Bloqueado"
#: pretix/plugins/checkinlists/exporters.py:702
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:22
#: pretix/presale/templates/pretixpresale/organizers/customer_profile.html:131
#, fuzzy
#| msgid "Paid orders"
msgid "Valid from"
msgstr "Válido a partir de"
msgstr "Ordens pagas"
#: pretix/base/exporters/orderlist.py:619 pretix/base/modelimport_orders.py:507
#: pretix/base/modelimport_vouchers.py:111 pretix/base/models/orders.py:2471
@@ -2278,29 +2297,45 @@ msgid "Order comment"
msgstr "Comentário do pedido"
#: pretix/base/exporters/orderlist.py:622
#, fuzzy
#| msgid "Position ID"
msgid "Add-on to position ID"
msgstr "Complemento da ID de posição"
msgstr "ID Posição"
#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:340
#, fuzzy
#| msgctxt "invoice"
#| msgid "Invoice date"
msgid "Invoice address street"
msgstr "Rua do endereço da fatura"
msgstr "Data da fatura"
#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:345
#, fuzzy
#| msgctxt "invoice"
#| msgid "Invoice date"
msgid "Invoice address ZIP code"
msgstr "CEP do Endereço da fatura"
msgstr "Data da fatura"
#: pretix/base/exporters/orderlist.py:650 pretix/base/pdf.py:350
#, fuzzy
#| msgctxt "invoice"
#| msgid "Invoice date"
msgid "Invoice address city"
msgstr "Cidade do Endereço da fatura"
msgstr "Data da fatura"
#: pretix/base/exporters/orderlist.py:651 pretix/base/pdf.py:360
#, fuzzy
#| msgctxt "invoice"
#| msgid "Invoice date"
msgid "Invoice address country"
msgstr "Estado do Endereço da fatura"
msgstr "Data da fatura"
#: pretix/base/exporters/orderlist.py:652
#, fuzzy
#| msgid "Invoice address name"
msgctxt "address"
msgid "Invoice address state"
msgstr "Estado do endereço da fatura"
msgstr "Endereço da fatura"
#: pretix/base/exporters/orderlist.py:660 pretix/control/navigation.py:303
#: pretix/control/templates/pretixcontrol/checkin/lists.html:6
@@ -2310,11 +2345,13 @@ msgstr "Estado do endereço da fatura"
#: pretix/control/templates/pretixcontrol/subevents/detail.html:162
#: pretix/plugins/checkinlists/apps.py:44
msgid "Check-in lists"
msgstr "Listas de check-in"
msgstr ""
#: pretix/base/exporters/orderlist.py:822
#, fuzzy
#| msgid "Creation date"
msgid "Order transaction data"
msgstr "Dados de transações de pedidos"
msgstr "Data de criação"
#: pretix/base/exporters/orderlist.py:824
msgid ""
@@ -2322,14 +2359,12 @@ msgid ""
"changes to products, prices or tax rates. The information is only accurate "
"for changes made with pretix versions released after October 2021."
msgstr ""
"Faça o download de uma planilha de todas as alterações substanciais em "
"pedidos, ou seja, todas as alterações em produtos, preços ou taxas de "
"impostos. As informações são precisas apenas para alterações feitas com "
"versões pretix lançadas após outubro de 2021."
#: pretix/base/exporters/orderlist.py:840
#, fuzzy
#| msgid "Only include orders created on or after this date."
msgid "Only include transactions created within this date range."
msgstr "Inclua apenas as transações criadas dentro desse intervalo de datas."
msgstr "Incluir apenas pedidos criados a partir desta data."
#: pretix/base/exporters/orderlist.py:875 pretix/base/models/event.py:659
#: pretix/base/models/items.py:424 pretix/base/models/items.py:1979
@@ -2358,19 +2393,25 @@ msgstr "Evento"
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/control_legacy.html:15
#: pretix/plugins/stripe/templates/pretixplugins/stripe/control.html:75
msgid "Currency"
msgstr "Moeda"
msgstr ""
#: pretix/base/exporters/orderlist.py:883
#, fuzzy
#| msgid "Creation date"
msgid "Transaction date"
msgstr "Data da transação"
msgstr "Data de criação"
#: pretix/base/exporters/orderlist.py:884
#, fuzzy
#| msgid "Creation date"
msgid "Transaction time"
msgstr "Hora da transação"
msgstr "Data de criação"
#: pretix/base/exporters/orderlist.py:885
#, fuzzy
#| msgid "Order data"
msgid "Old data"
msgstr "Dados antigos"
msgstr "Informação do pedido"
#: pretix/base/exporters/orderlist.py:888 pretix/base/models/items.py:1502
#: pretix/control/templates/pretixcontrol/order/transactions.html:22

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-08 10:55+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2024-06-08 18:00+0000\n"
"Last-Translator: David Vaz <davidmgvaz@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_PT/>\n"
"Language: pt_PT\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.7\n"
"X-Generator: Weblate 5.5.5\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -7940,24 +7940,28 @@ msgid "number of entries today"
msgstr "número de entradas hoje"
#: pretix/base/services/checkin.py:318
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "number of entries today"
msgid "number of entries since {datetime}"
msgstr "número de entradas hoje {datetime}"
msgstr "número de entradas hoje"
#: pretix/base/services/checkin.py:319
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "number of entries today"
msgid "number of entries before {datetime}"
msgstr "número de entradas hoje {datetime}"
msgstr "número de entradas hoje"
#: pretix/base/services/checkin.py:320
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "number of entries today"
msgid "number of days with an entry since {datetime}"
msgstr "número de entradas hoje {datetime}"
msgstr "número de entradas hoje"
#: pretix/base/services/checkin.py:321
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "number of entries today"
msgid "number of days with an entry before {datetime}"
msgstr "número de entradas hoje {datetime}"
msgstr "número de entradas hoje"
#: pretix/base/services/checkin.py:322
msgid "week day"
@@ -8025,14 +8029,16 @@ msgid "This order is not yet approved."
msgstr "Esta encomenda não está pendente de aprovação."
#: pretix/base/services/checkin.py:999 pretix/base/services/checkin.py:1003
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Only allowed after {datetime}"
msgid "This ticket is only valid after {datetime}."
msgstr "Permitido após {datetime}."
msgstr "Permitido após {datetime}"
#: pretix/base/services/checkin.py:1013 pretix/base/services/checkin.py:1017
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "This ticket has already been redeemed."
msgid "This ticket was only valid before {datetime}."
msgstr "Este bilhete já foi resgatado {datetime}."
msgstr "Este bilhete já foi resgatado."
#: pretix/base/services/checkin.py:1048
msgid "This order position has an invalid product for this check-in list."
@@ -8092,8 +8098,10 @@ msgid "Export failed"
msgstr "Ficheiros exportados"
#: pretix/base/services/export.py:206
#, fuzzy
#| msgid "Permission denied"
msgid "Permission denied."
msgstr "Permissão negada."
msgstr "Permissão negada"
#: pretix/base/services/export.py:221
msgid "Your exported data exceeded the size limit for scheduled exports."
@@ -8164,7 +8172,14 @@ msgid "New invoice: {number}"
msgstr "Nova fatura: {number}"
#: pretix/base/services/invoices.py:528
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Hello,\n"
#| "\n"
#| "a new invoice for {event} has been created, see attached.\n"
#| "\n"
#| "We are sending this email because you configured us to do so in your "
#| "event settings."
msgid ""
"Hello,\n"
"\n"
@@ -8175,7 +8190,7 @@ msgid ""
msgstr ""
"Olá,\n"
"\n"
"Uma nova fatura a ordem {order} em {event} foi criada, consulte anexo.\n"
"Uma nova fatura para {event} foi criada, consulte anexo.\n"
"\n"
"Estamos a enviar este e -mail porque configurou para fazê -lo nas suas "
"configurações de evento."
@@ -8299,17 +8314,20 @@ msgstr ""
"vezes, que é o valor máximo."
#: pretix/base/services/memberships.py:227
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "You are trying to use a membership of type \"{type}\" for an event taking "
#| "place at {date}, however you already used the same membership for a "
#| "different ticket at the same time."
msgid ""
"You are trying to use a membership of type \"{type}\" for a ticket valid "
"from {valid_from} until {valid_until}, however you already used the same "
"membership for a different ticket that overlaps with this time frame "
"({conflict_from} {conflict_until})."
msgstr ""
"Está a tentar utilizar uma adesão do tipo \"{type}\" para um bilhete válido "
"de {valid_from} até {valid_until}, no entanto já usou a mesma adesão para um "
"bilhete diferente que se sobrepõe a este prazo ({conflict_from} "
"{conflict_until})."
"Está a tentar usar uma associação do tipo \"{type}\" para um evento que "
"ocorre em {date}, no entanto, já usou a mesma associação para um ticket "
"diferente ao mesmo tempo."
#: pretix/base/services/memberships.py:231
#: pretix/base/services/memberships.py:233
@@ -8718,8 +8736,10 @@ msgstr ""
"Algo aconteceu no seu evento após a exportação, por favor tente novamente."
#: pretix/base/services/shredder.py:177
#, fuzzy
#| msgid "Payment completed."
msgid "Data shredding completed"
msgstr "Pagamento completo"
msgstr "Pagamento completo."
#: pretix/base/services/stats.py:215
msgid "Uncategorized"
@@ -9228,9 +9248,10 @@ msgstr ""
"%y (sem século) para inserir o ano da factura, ou %m e %d para o dia do mês."
#: pretix/base/settings.py:684 pretix/base/settings.py:706
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Please do not use special characters in names."
msgid "Please only use the characters {allowed} in this field."
msgstr "Por favor, utilize apenas os caracteres {allowed} neste campo."
msgstr "Por favor não use caracteres especiais em nomes."
#: pretix/base/settings.py:697
msgid "Invoice number prefix for cancellations"
@@ -10064,16 +10085,21 @@ msgid "No modifications after order was submitted"
msgstr ""
#: pretix/base/settings.py:1669 pretix/base/settings.py:1678
#, fuzzy
#| msgid "Only pending or paid orders can be changed."
msgid "Only the person who ordered can make changes"
msgstr "Apenas encomendas pendentes ou pagas podem ser alteradas"
msgstr "Apenas encomendas pendentes ou pagas podem ser alteradas."
#: pretix/base/settings.py:1670 pretix/base/settings.py:1679
msgid "Both the attendee and the person who ordered can make changes"
msgstr ""
#: pretix/base/settings.py:1674
#, fuzzy
#| msgid "Allow customers to modify their information after they checked in."
msgid "Allow customers to modify their information"
msgstr "Permitir que os clientes modifique as suas informações"
msgstr ""
"Permitir que os clientes modifiquem as suas informações após o check -in."
#: pretix/base/settings.py:1689
msgid "Allow customers to modify their information after they checked in."
@@ -11063,7 +11089,17 @@ msgstr ""
"A sua equipa {event}"
#: pretix/base/settings.py:2530 pretix/base/settings.py:2567
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Hello {attendee_name},\n"
#| "\n"
#| "a ticket for {event} has been ordered for you.\n"
#| "\n"
#| "You can view the details and status of your ticket here:\n"
#| "{url}\n"
#| "\n"
#| "Best regards, \n"
#| "Your {event} team"
msgid ""
"Hello,\n"
"\n"
@@ -11075,7 +11111,7 @@ msgid ""
"Best regards, \n"
"Your {event} team"
msgstr ""
"Olá,\n"
"Olá {attendee_name},\n"
"\n"
"um bilhete para {event} foi pedido para si.\n"
"\n"
@@ -11892,9 +11928,10 @@ msgid "The last payment date cannot be before the end of presale."
msgstr "A última data de pagamento não pode ser antes do final da pré-venda."
#: pretix/base/settings.py:3811
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Please enter a valid sales channel."
msgid "The value \"{identifier}\" is not a valid sales channel."
msgstr "O valor \"{identifier}\" não é um canal de vendas válido."
msgstr "Por favor, indique um canal de vendas válido."
#: pretix/base/settings.py:3826
msgid "This needs to be disabled if other NFC-based types are active."
@@ -15443,20 +15480,18 @@ msgid "A new secret has been generated for position #{posid}."
msgstr "Um novo segredo foi gerado para a posição #{posid}."
#: pretix/control/logdisplay.py:165
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "This order position has been canceled."
msgid ""
"The validity start date for position #{posid} has been changed to {value}."
msgstr ""
"A data de início de validade para a posição #{posid} foi alterada para "
"{value}."
msgstr "Esta posição encomenda foi cancelada."
#: pretix/control/logdisplay.py:171
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "This order position has been canceled."
msgid ""
"The validity end date for position #{posid} has been changed to {value}."
msgstr ""
"A data de final de validade para a posição #{posid} foi alterada para "
"{value}."
msgstr "Esta posição encomenda foi cancelada."
#: pretix/control/logdisplay.py:176
#, fuzzy, python-brace-format
@@ -17501,7 +17536,10 @@ msgid "Delete check-ins"
msgstr "Excluir lista de check-in"
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:15
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "Are you sure you want to delete the check-in list <strong>%(name)s</"
#| "strong>?"
msgid ""
"Are you sure you want to permanently delete the check-ins of <strong>one "
"ticket</strong>."
@@ -17509,11 +17547,11 @@ msgid_plural ""
"Are you sure you want to permanently delete the check-ins of "
"<strong>%(count)s tickets</strong>?"
msgstr[0] ""
"Tem certeza de que deseja apagar a lista de check-in "
"<strong>%(count)s</strong>?"
"Tem certeza de que deseja apagar a lista de check-in <strong>%(name)s</"
"strong>?"
msgstr[1] ""
"Tem certeza de que deseja apagar a lista de check-in "
"<strong>%(count)s</strong>?"
"Tem certeza de que deseja apagar a lista de check-in <strong>%(name)s</"
"strong>?"
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:24
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html:18
@@ -20723,8 +20761,11 @@ msgstr ""
"produto foi definido"
#: pretix/control/templates/pretixcontrol/items/discounts.html:111
#, fuzzy
#| msgctxt "discount"
#| msgid "Condition"
msgid "Condition:"
msgstr "Doença:"
msgstr "Doença"
#: pretix/control/templates/pretixcontrol/items/discounts.html:126
msgid "Applies to:"
@@ -22895,8 +22936,10 @@ msgid "Channel type"
msgstr "Tipo de digitalização"
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:5
#, fuzzy
#| msgid "Sales channel"
msgid "Delete sales channel:"
msgstr "Canal de vendas:"
msgstr "Canal de vendas"
#: pretix/control/templates/pretixcontrol/organizers/channel_delete.html:10
#, fuzzy
@@ -22917,8 +22960,10 @@ msgstr ""
"sua data de término para o passado."
#: pretix/control/templates/pretixcontrol/organizers/channel_edit.html:6
#, fuzzy
#| msgid "Sales channel"
msgid "Sales channel:"
msgstr "Canal de vendas:"
msgstr "Canal de vendas"
#: pretix/control/templates/pretixcontrol/organizers/channels.html:8
msgid ""
@@ -26912,9 +26957,10 @@ msgid "Your export schedule has been saved, but no next export is planned."
msgstr ""
#: pretix/control/views/orders.py:2704 pretix/control/views/organizer.py:1859
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Export date"
msgid "Export: {title}"
msgstr "Exportação: {title}"
msgstr "Data de Exportação"
#: pretix/control/views/orders.py:2705 pretix/control/views/organizer.py:1861
#, python-brace-format
@@ -28290,9 +28336,10 @@ msgid "The invoice was sent to the designated email address."
msgstr "Digite o mesmo endereço de e-mail duas vezes."
#: pretix/plugins/banktransfer/signals.py:132
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Invoice number"
msgid "Invoice {invoice_number}"
msgstr "Factura {invoice_number}"
msgstr "Número da factura"
#: pretix/plugins/banktransfer/signals.py:137
#, python-brace-format
@@ -29714,9 +29761,10 @@ msgstr ""
#: pretix/plugins/reports/accountingreport.py:644
#: pretix/plugins/reports/accountingreport.py:694
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Extend payment term"
msgid "Pending payments at {datetime}"
msgstr "Pagamentos pendentes em {datetime}"
msgstr "Estender prazo de pagamento"
#: pretix/plugins/reports/accountingreport.py:751
#: pretix/plugins/reports/accountingreport.py:789
@@ -30393,13 +30441,16 @@ msgid "There are no matching recipients for your selection."
msgstr "Não há encomendas correspondentes a esta selecção."
#: pretix/plugins/sendmail/views.py:223
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "Your message has been queued and will be sent to the contact addresses of "
#| "%d orders in the next few minutes."
msgid ""
"Your message has been queued and will be sent to the contact addresses of %s "
"in the next few minutes."
msgstr ""
"A sua mensagem foi colocada na fila e será enviada para os endereços de "
"contato de %s pedidos nos próximos minutos."
"contato de %d pedidos nos próximos minutos."
#: pretix/plugins/sendmail/views.py:253
#, fuzzy
@@ -30427,11 +30478,12 @@ msgid ""
msgstr ""
#: pretix/plugins/sendmail/views.py:516
#, python-format
#, fuzzy, python-format
#| msgid "Waiting list entry"
msgid "%(number)s waiting list entry"
msgid_plural "%(number)s waiting list entries"
msgstr[0] "%(number)s entrada em fila de espera"
msgstr[1] "%(number)s entrada em fila de espera"
msgstr[0] "Entrada em fila de espera"
msgstr[1] "Entrada em fila de espera"
#: pretix/plugins/statistics/apps.py:30 pretix/plugins/statistics/apps.py:33
#: pretix/plugins/statistics/signals.py:37
@@ -31386,12 +31438,16 @@ msgid "Enter the entity number, reference number, and amount."
msgstr ""
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:25
#, fuzzy
#| msgid "Invoice number"
msgid "Entity number:"
msgstr "Número da factura:"
msgstr "Número da factura"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:26
#, fuzzy
#| msgid "Reference code"
msgid "Reference number:"
msgstr "Código de referência:"
msgstr "Código de referência"
#: pretix/plugins/stripe/templates/pretixplugins/stripe/pending.html:35
msgid ""
@@ -33323,7 +33379,7 @@ msgstr "Participe da lista de espera"
#: pretix/presale/templates/pretixpresale/event/voucher.html:437
msgctxt "free_tickets"
msgid "Register"
msgstr "Registro"
msgstr "Registo"
#: pretix/presale/templates/pretixpresale/event/index.html:222
#: pretix/presale/templates/pretixpresale/event/voucher.html:442
@@ -33802,11 +33858,11 @@ msgstr "Total: %(total)s"
#: pretix/presale/templates/pretixpresale/event/position.html:7
msgid "Registration details"
msgstr "Detalhes do registro"
msgstr "Detalhes do registo"
#: pretix/presale/templates/pretixpresale/event/position.html:10
msgid "Your registration"
msgstr "O seu registro"
msgstr "O seu registo"
#: pretix/presale/templates/pretixpresale/event/position.html:31
msgid "Your items"
@@ -34685,13 +34741,16 @@ msgstr ""
"disponível atualmente."
#: pretix/presale/views/waiting.py:141
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "We've added you to the waiting list. You will receive an email as soon as "
#| "this product gets available again."
msgid ""
"We've added you to the waiting list. We will send an email to {email} as "
"soon as this product gets available again."
msgstr ""
"Adicionámos à lista de espera. Enviaremos um e-mail para {email} assim que "
"este produto estiver novamente disponível."
"Adicionamos você à lista de espera. Você receberá um email assim que este "
"produto estiver disponível novamente."
#: pretix/presale/views/waiting.py:169
msgid "We could not find you on our waiting list."

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-08 11:04+0000\n"
"Last-Translator: Martin Gross <gross@rami.io>\n"
"PO-Revision-Date: 2024-06-08 18:00+0000\n"
"Last-Translator: David Vaz <davidmgvaz@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
"pretix/pretix-js/pt_PT/>\n"
"Language: pt_PT\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.7\n"
"X-Generator: Weblate 5.5.5\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -292,8 +292,10 @@ msgid "Information required"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:58
#, fuzzy
#| msgid "Unknown error."
msgid "Unknown ticket"
msgstr "Bilhete desconhecido"
msgstr "Erro desconhecido."
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:59
msgid "Ticket type not allowed here"
@@ -803,19 +805,21 @@ msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:20
msgctxt "widget"
msgid "Select"
msgstr "Selecionar"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:21
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "Selecionados %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:22
#, javascript-format
#, fuzzy, javascript-format
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Select variant %s"
msgstr "Selecione variantes %s"
msgstr "Ver alternativas"
#: pretix/static/pretixpresale/js/widget/widget.js:23
msgctxt "widget"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-16 13:00+0000\n"
"Last-Translator: Svyatoslav <slava@digitalarthouse.eu>\n"
"PO-Revision-Date: 2024-05-13 21:00+0000\n"
"Last-Translator: Serhii Horichenko <m@sgg.im>\n"
"Language-Team: Russian <https://translate.pretix.eu/projects/pretix/pretix/"
"ru/>\n"
"Language: ru\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 5.7\n"
"X-Generator: Weblate 5.4.3\n"
#: pretix/_base_settings.py:79
msgid "English"
@@ -32313,7 +32313,7 @@ msgstr "Пожалуйста, выберите конкретный вариан
#: pretix/presale/templates/pretixpresale/event/index.html:82
msgid "View other date"
msgstr "Посмотреть другие даты или мероприятия"
msgstr "Посмотреть другую дату"
#: pretix/presale/templates/pretixpresale/event/index.html:87
msgid "Choose date to book a ticket"

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-15 18:00+0000\n"
"PO-Revision-Date: 2024-06-26 22:00+0000\n"
"Last-Translator: Kristian Feldsam <feldsam@gmail.com>\n"
"Language-Team: Slovak <https://translate.pretix.eu/projects/pretix/pretix-js/"
"sk/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 5.7\n"
"X-Generator: Weblate 5.6.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -156,7 +156,7 @@ msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
msgid "Paid orders"
msgstr "Zaplatené objednávky"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
msgid "Total revenue"
@@ -176,15 +176,15 @@ msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
msgid "Select a check-in list"
msgstr "Vyberte zoznam na odbavenie"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
msgid "No active check-in lists found."
msgstr "Nenašli sa žiadne aktívne zoznamy na odbavenie."
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:32
msgid "Switch check-in list"
msgstr "Prepnúť zoznam odbavení"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:33
msgid "Search results"
@@ -274,7 +274,7 @@ msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:56
msgid "Ticket already used"
msgstr "Už použitá vstupenka"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:57
msgid "Information required"
@@ -282,7 +282,7 @@ msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:58
msgid "Unknown ticket"
msgstr "Neznáma vstupenka"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:59
msgid "Ticket type not allowed here"
@@ -318,7 +318,7 @@ msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:68
msgid "Checked-in Tickets"
msgstr "Odbavené vstupenky"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:69
msgid "Valid Tickets"
@@ -398,9 +398,6 @@ msgid ""
"than one minute, please check your internet connection and then reload this "
"page and try again."
msgstr ""
"Momentálne odosielame vašu požiadavku na server. Ak to trvá dlhšie ako jednu "
"minútu, skontrolujte svoje internetové pripojenie a potom znovu načítajte "
"túto stránku a skúste to znova."
#: pretix/static/pretixbase/js/asynctask.js:301
#: pretix/static/pretixcontrol/js/ui/main.js:71
@@ -549,7 +546,7 @@ msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:171
msgid "Check-in QR"
msgstr "QR na odbavenie"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:543
msgid "The PDF background file could not be loaded for the following reason:"
@@ -686,8 +683,6 @@ msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as theyre available."
msgstr ""
"Vstupenky v košíku už nie sú pre Vás rezervované. Objednávku môžete "
"dokončiť, ak sú stále k dispozícii."
#: pretix/static/pretixpresale/js/ui/cart.js:45
msgid "Cart expired"
@@ -696,9 +691,8 @@ msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:50
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] "Vstupenky v košíku sú pre Vás rezervované jednu minútu."
msgstr[1] "Vstupenky v košíku sú pre Vás rezervované {num} minúty."
msgstr[2] "Vstupenky v košíku sú pre Vás rezervované {num} minút."
msgstr[0] ""
msgstr[1] ""
#: pretix/static/pretixpresale/js/ui/main.js:203
msgid "The organizer keeps %(currency)s %(amount)s"
@@ -710,11 +704,11 @@ msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:227
msgid "Please enter the amount the organizer can keep."
msgstr "Zadajte sumu, ktorú si organizátor môže ponechať."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:449
msgid "Please enter a quantity for one of the ticket types."
msgstr "Vyberte si prosím aspoň jednu vstupenku."
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:485
msgid "required"
@@ -736,131 +730,131 @@ msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:16
msgctxt "widget"
msgid "Quantity"
msgstr "Počet"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:17
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Znížiť počet"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:18
msgctxt "widget"
msgid "Increase quantity"
msgstr "Zvýšiť počet"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:19
msgctxt "widget"
msgid "Price"
msgstr "Cena"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:20
msgctxt "widget"
msgid "Select"
msgstr "Vybrať"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:21
#, javascript-format
msgctxt "widget"
msgid "Select %s"
msgstr "Vybrať %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:22
#, javascript-format
msgctxt "widget"
msgid "Select variant %s"
msgstr "Vybrať variantu %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:23
msgctxt "widget"
msgid "Sold out"
msgstr "Vypredané"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:24
msgctxt "widget"
msgid "Buy"
msgstr "Kúpiť"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:25
msgctxt "widget"
msgid "Register"
msgstr "Registrovať sa"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:26
msgctxt "widget"
msgid "Reserved"
msgstr "Rezervované"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:27
msgctxt "widget"
msgid "FREE"
msgstr "ZADARMO"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:28
msgctxt "widget"
msgid "from %(currency)s %(price)s"
msgstr "z %(currency)s %(price)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:29
msgctxt "widget"
msgid "incl. %(rate)s% %(taxname)s"
msgstr "vrátane %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:30
msgctxt "widget"
msgid "plus %(rate)s% %(taxname)s"
msgstr "plus %(rate)s% %(taxname)s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:31
msgctxt "widget"
msgid "incl. taxes"
msgstr "vrátane dane"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:32
msgctxt "widget"
msgid "plus taxes"
msgstr "plus daň"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:33
#, javascript-format
msgctxt "widget"
msgid "currently available: %s"
msgstr "aktuálne k dispozícii: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:34
msgctxt "widget"
msgid "Only available with a voucher"
msgstr "K dispozícii len s poukážkou"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:35
msgctxt "widget"
msgid "Not yet available"
msgstr "Zatiaľ nedostupné"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:36
msgctxt "widget"
msgid "Not available anymore"
msgstr "Už nie je k dispozícii"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:37
msgctxt "widget"
msgid "Currently not available"
msgstr "Momentálne nie je k dispozícii"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:38
#, javascript-format
msgctxt "widget"
msgid "minimum amount to order: %s"
msgstr "minimálna suma na objednávku: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:39
msgctxt "widget"
msgid "Close ticket shop"
msgstr "Zatvoriť obchod so vstupenkami"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:40
msgctxt "widget"
msgid "The ticket shop could not be loaded."
msgstr "Obchod so vstupenkami sa nepodarilo načítať."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:41
msgctxt "widget"
@@ -868,18 +862,16 @@ msgid ""
"There are currently a lot of users in this ticket shop. Please open the shop "
"in a new tab to continue."
msgstr ""
"V súčasnosti je v tomto obchode so vstupenkami veľa používateľov. Ak chcete "
"pokračovať, otvorte obchod v novej karte."
#: pretix/static/pretixpresale/js/widget/widget.js:43
msgctxt "widget"
msgid "Open ticket shop"
msgstr "Otvoriť obchod so vstupenkami"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:44
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Nákupný košík sa nepodarilo vytvoriť. Skúste to prosím neskôr"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:45
msgctxt "widget"
@@ -887,14 +879,11 @@ msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
"Nepodarilo sa nám vytvoriť Váš nákupný košík, pretože v tomto obchode je "
"momentálne príliš veľa používateľov. Kliknutím na tlačidlo „Pokračovať“ to "
"skúste znova v novej karte."
#: pretix/static/pretixpresale/js/widget/widget.js:47
msgctxt "widget"
msgid "Waiting list"
msgstr "Čakací zoznam"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:48
msgctxt "widget"
@@ -902,88 +891,86 @@ msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
"V súčasnosti máte aktívny nákupný košík pre toto podujatie. Ak si vyberiete "
"ďalšie vstupenky, pridajú sa do vášho existujúceho košíka."
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid "Resume checkout"
msgstr "Pokračovať v objednávke"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:51
msgctxt "widget"
msgid "Redeem a voucher"
msgstr "Uplatnenie poukážky"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:52
msgctxt "widget"
msgid "Redeem"
msgstr "Uplatniť"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:53
msgctxt "widget"
msgid "Voucher code"
msgstr "Kód poukážky"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:54
msgctxt "widget"
msgid "Close"
msgstr "Zatvoriť"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:55
msgctxt "widget"
msgid "Continue"
msgstr "Pokračovať"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:56
msgctxt "widget"
msgid "Show variants"
msgstr "Zobraziť varianty"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:57
msgctxt "widget"
msgid "Hide variants"
msgstr "Skryť varianty"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:58
msgctxt "widget"
msgid "Choose a different event"
msgstr "Vybrať iné podujatie"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:59
msgctxt "widget"
msgid "Choose a different date"
msgstr "Vybrať iný dátum"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:60
msgctxt "widget"
msgid "Back"
msgstr "Späť"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:61
msgctxt "widget"
msgid "Next month"
msgstr "Nasledujúci mesiac"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:62
msgctxt "widget"
msgid "Previous month"
msgstr "Predchádzajúci mesiac"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "Next week"
msgstr "Nasledujúci týždeň"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
msgid "Previous week"
msgstr "Predchádzajúci týždeň"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:65
msgctxt "widget"
msgid "Open seat selection"
msgstr "Zobraziť výber sedadiel"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:66
msgctxt "widget"
@@ -992,14 +979,11 @@ msgid ""
"add yourself to the waiting list. We will then notify if seats are available "
"again."
msgstr ""
"Niektoré alebo všetky kategórie vstupeniek sú v súčasnosti vypredané. Ak "
"chcete, môžete sa pridať na zoznam čakateľov. Budeme vás informovať, ak sa "
"miesta uvoľnia."
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
msgid "Load more"
msgstr "Načítať viac"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:69
msgid "Mo"

File diff suppressed because it is too large Load Diff

View File

@@ -8,16 +8,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
"PO-Revision-Date: 2024-09-12 03:00+0000\n"
"Last-Translator: Tinna Sandström <tinna@coeo.events>\n"
"Language-Team: Swedish <https://translate.pretix.eu/projects/pretix/"
"pretix-js/sv/>\n"
"PO-Revision-Date: 2024-06-27 17:00+0000\n"
"Last-Translator: Erik Löfman <erik@disruptiveventures.se>\n"
"Language-Team: Swedish <https://translate.pretix.eu/projects/pretix/pretix-"
"js/sv/>\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"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.7\n"
"X-Generator: Weblate 5.6.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -727,8 +727,8 @@ msgstr "Varukorgen har gått ut"
#: pretix/static/pretixpresale/js/ui/cart.js:50
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] "Produkterna i din bokning är reserverade för dig i en minut."
msgstr[1] "Produkterna i din bokning är reserverade för dig i {num} minuter."
msgstr[0] "Artiklarna i din varukorg är reserverade för dig i en minut."
msgstr[1] "Artiklarna i din varukorg är reserverade för dig i {num} minuter."
#: pretix/static/pretixpresale/js/ui/main.js:203
msgid "The organizer keeps %(currency)s %(amount)s"
@@ -819,7 +819,7 @@ msgstr "Köp"
#: pretix/static/pretixpresale/js/widget/widget.js:25
msgctxt "widget"
msgid "Register"
msgstr "BOKA"
msgstr "Registrera"
#: pretix/static/pretixpresale/js/widget/widget.js:26
msgctxt "widget"
@@ -829,7 +829,7 @@ msgstr "Reserverad"
#: pretix/static/pretixpresale/js/widget/widget.js:27
msgctxt "widget"
msgid "FREE"
msgstr "ANTAL"
msgstr "GRATIS"
#: pretix/static/pretixpresale/js/widget/widget.js:28
msgctxt "widget"
@@ -921,7 +921,7 @@ msgstr "Öppna biljettbutik"
#: pretix/static/pretixpresale/js/widget/widget.js:44
msgctxt "widget"
msgid "The cart could not be created. Please try again later"
msgstr "Bokningen kunde inte skapas. Vänligen försök senare."
msgstr "Varukorgen kunde inte skapas. Vänligen försök senare"
#: pretix/static/pretixpresale/js/widget/widget.js:45
msgctxt "widget"
@@ -929,8 +929,9 @@ msgid ""
"We could not create your cart, since there are currently too many users in "
"this ticket shop. Please click \"Continue\" to retry in a new tab."
msgstr ""
"Vi kunde inte skapa din bokning, då det just nu är många användare i den här "
"biljettbutiken. Klicka på \"Fortsätt\" för att försöka på nytt i en ny flik."
"Vi kunde inte skapa din varukorg, då det just nu är många användare i den "
"här biljettbutiken. Klicka på \"Fortsätt\" för att försöka på nytt i en ny "
"flik."
#: pretix/static/pretixpresale/js/widget/widget.js:47
msgctxt "widget"
@@ -943,13 +944,13 @@ msgid ""
"You currently have an active cart for this event. If you select more "
"products, they will be added to your existing cart."
msgstr ""
"Du har för tillfället en pågående bokning för den här eventet. Om du väljer "
"fler produkter, kommer de att läggas till din befintliga bokning."
"Du har för tillfället en aktiv varukorg för den här eventet. Om du väljer "
"fler artiklar, kommer de att läggas till din befintliga varukorg."
#: pretix/static/pretixpresale/js/widget/widget.js:50
msgctxt "widget"
msgid "Resume checkout"
msgstr "Fortsätt med ditt bokningen"
msgstr "Fortsätt med ditt köp"
#: pretix/static/pretixpresale/js/widget/widget.js:51
msgctxt "widget"

View File

@@ -26,13 +26,12 @@ from collections import defaultdict
from django.dispatch import receiver
from django.template.loader import get_template
from django.urls import resolve, reverse
from django.utils.html import escape
from django.utils.translation import gettext_lazy as _
from pretix.base.logentrytypes import EventLogEntryType, log_entry_types
from pretix.base.models import Event, Order
from pretix.base.signals import (
event_copy_data, item_copy_data, logentry_display, logentry_object_link,
register_data_exporters,
event_copy_data, item_copy_data, register_data_exporters,
)
from pretix.control.signals import (
item_forms, nav_event, order_info, order_position_buttons,
@@ -173,35 +172,13 @@ def control_order_info(sender: Event, request, order: Order, **kwargs):
return template.render(ctx, request=request)
@receiver(signal=logentry_display, dispatch_uid="badges_logentry_display")
def badges_logentry_display(sender, logentry, **kwargs):
if not logentry.action_type.startswith('pretix.plugins.badges'):
return
plains = {
'pretix.plugins.badges.layout.added': _('Badge layout created.'),
'pretix.plugins.badges.layout.deleted': _('Badge layout deleted.'),
'pretix.plugins.badges.layout.changed': _('Badge layout changed.'),
}
if logentry.action_type in plains:
return plains[logentry.action_type]
@receiver(signal=logentry_object_link, dispatch_uid="badges_logentry_object_link")
def badges_logentry_object_link(sender, logentry, **kwargs):
if not logentry.action_type.startswith('pretix.plugins.badges.layout') or not isinstance(logentry.content_object,
BadgeLayout):
return
a_text = _('Badge layout {val}')
a_map = {
'href': reverse('plugins:badges:edit', kwargs={
'event': sender.slug,
'organizer': sender.organizer.slug,
'layout': logentry.content_object.id
}),
'val': escape(logentry.content_object.name),
}
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
return a_text.format_map(a_map)
@log_entry_types.new_from_dict({
'pretix.plugins.badges.layout.added': _('Badge layout created.'),
'pretix.plugins.badges.layout.deleted': _('Badge layout deleted.'),
'pretix.plugins.badges.layout.changed': _('Badge layout changed.'),
})
class BadgeLogEntryType(EventLogEntryType):
object_type = BadgeLayout
object_link_wrapper = _('Badge layout {val}')
object_link_viewname = 'plugins:badges:edit'
object_link_argname = 'layout'

View File

@@ -25,9 +25,12 @@ from django.urls import resolve, reverse
from django.utils.translation import gettext_lazy as _, gettext_noop
from i18nfield.strings import LazyI18nString
from pretix.base.signals import logentry_display, register_payment_providers
from pretix.base.signals import register_payment_providers
from pretix.control.signals import html_head, nav_event, nav_organizer
from ...base.logentrytypes import (
ClearDataShredderMixin, OrderLogEntryType, log_entry_types,
)
from ...base.settings import settings_hierarkey
from .payment import BankTransfer
@@ -117,13 +120,10 @@ def html_head_presale(sender, request=None, **kwargs):
return ""
@receiver(signal=logentry_display)
def pretixcontrol_logentry_display(sender, logentry, **kwargs):
plains = {
'pretix.plugins.banktransfer.order.email.invoice': _('The invoice was sent to the designated email address.'),
}
if logentry.action_type in plains:
return plains[logentry.action_type]
@log_entry_types.new()
class BanktransferOrderEmailInvoiceLogEntryType(OrderLogEntryType, ClearDataShredderMixin):
action_type = 'pretix.plugins.banktransfer.order.email.invoice'
plain = _('The invoice was sent to the designated email address.')
settings_hierarkey.add_default(

View File

@@ -669,7 +669,7 @@ class OrganizerActionView(OrganizerBanktransferView, OrganizerPermissionRequired
def _row_key_func(row):
return row['iban'], row.get('bic') or ''
return row['iban'], row['bic']
def _unite_transaction_rows(transaction_rows):

View File

@@ -22,17 +22,10 @@
from django.dispatch import receiver
from pretix.base.signals import logentry_display, register_payment_providers
from pretix.base.signals import register_payment_providers
@receiver(register_payment_providers, dispatch_uid="payment_paypal")
def register_payment_provider(sender, **kwargs):
from .payment import Paypal
return Paypal
@receiver(signal=logentry_display, dispatch_uid="paypal_logentry_display")
def pretixcontrol_logentry_display(sender, logentry, **kwargs):
from pretix.plugins.paypal2.signals import pretixcontrol_logentry_display
return pretixcontrol_logentry_display(sender, logentry, **kwargs)

View File

@@ -19,7 +19,6 @@
# 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
from collections import OrderedDict
from django import forms
@@ -32,10 +31,11 @@ from django.utils.crypto import get_random_string
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from pretix.base.forms import SecretKeySettingsField
from pretix.base.logentrytypes import EventLogEntryType, 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 (
logentry_display, register_global_settings, register_payment_providers,
register_global_settings, register_payment_providers,
)
from pretix.plugins.paypal2.payment import PaypalMethod
from pretix.presale.signals import html_head, process_response
@@ -47,33 +47,32 @@ def register_payment_provider(sender, **kwargs):
return [PaypalSettingsHolder, PaypalWallet, PaypalAPM]
@receiver(signal=logentry_display, dispatch_uid="paypal2_logentry_display")
def pretixcontrol_logentry_display(sender, logentry, **kwargs):
if logentry.action_type != 'pretix.plugins.paypal.event':
return
@log_entry_types.new()
class PaypalEventLogEntryType(EventLogEntryType):
action_type = 'pretix.plugins.paypal.event'
data = json.loads(logentry.data)
event_type = data.get('event_type')
text = None
plains = {
'PAYMENT.SALE.COMPLETED': _('Payment completed.'),
'PAYMENT.SALE.DENIED': _('Payment denied.'),
'PAYMENT.SALE.REFUNDED': _('Payment refunded.'),
'PAYMENT.SALE.REVERSED': _('Payment reversed.'),
'PAYMENT.SALE.PENDING': _('Payment pending.'),
'CHECKOUT.ORDER.APPROVED': pgettext_lazy('paypal', 'Order approved.'),
'CHECKOUT.ORDER.COMPLETED': pgettext_lazy('paypal', 'Order completed.'),
'PAYMENT.CAPTURE.COMPLETED': pgettext_lazy('paypal', 'Capture completed.'),
'PAYMENT.CAPTURE.PENDING': pgettext_lazy('paypal', 'Capture pending.'),
}
def display(self, logentry):
event_type = logentry.parsed_data.get('event_type')
text = None
plains = {
'PAYMENT.SALE.COMPLETED': _('Payment completed.'),
'PAYMENT.SALE.DENIED': _('Payment denied.'),
'PAYMENT.SALE.REFUNDED': _('Payment refunded.'),
'PAYMENT.SALE.REVERSED': _('Payment reversed.'),
'PAYMENT.SALE.PENDING': _('Payment pending.'),
'CHECKOUT.ORDER.APPROVED': pgettext_lazy('paypal', 'Order approved.'),
'CHECKOUT.ORDER.COMPLETED': pgettext_lazy('paypal', 'Order completed.'),
'PAYMENT.CAPTURE.COMPLETED': pgettext_lazy('paypal', 'Capture completed.'),
'PAYMENT.CAPTURE.PENDING': pgettext_lazy('paypal', 'Capture pending.'),
}
if event_type in plains:
text = plains[event_type]
else:
text = event_type
if event_type in plains:
text = plains[event_type]
else:
text = event_type
if text:
return _('PayPal reported an event: {}').format(text)
if text:
return _('PayPal reported an event: {}').format(text)
@receiver(register_global_settings, dispatch_uid='paypal2_global_settings')

View File

@@ -46,13 +46,16 @@ from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_scopes import scope, scopes_disabled
from pretix.base.logentrytypes import (
EventLogEntryType, OrderLogEntryType, log_entry_types,
)
from pretix.base.models import SubEvent
from pretix.base.signals import (
EventPluginSignal, event_copy_data, logentry_display, periodic_task,
EventPluginSignal, event_copy_data, periodic_task,
)
from pretix.control.signals import nav_event
from pretix.helpers import OF_SELF
from pretix.plugins.sendmail.models import ScheduledMail
from pretix.plugins.sendmail.models import Rule, ScheduledMail
from pretix.plugins.sendmail.views import OrderSendView, WaitinglistSendView
logger = logging.getLogger(__name__)
@@ -116,21 +119,28 @@ def control_nav_import(sender, request=None, **kwargs):
]
@receiver(signal=logentry_display)
def pretixcontrol_logentry_display(sender, logentry, **kwargs):
plains = {
'pretix.plugins.sendmail.sent': _('Mass email was sent to customers or attendees.'),
'pretix.plugins.sendmail.sent.waitinglist': _('Mass email was sent to waiting list entries.'),
'pretix.plugins.sendmail.order.email.sent': _('The order received a mass email.'),
'pretix.plugins.sendmail.order.email.sent.attendee': _('A ticket holder of this order received a mass email.'),
'pretix.plugins.sendmail.rule.added': _('An email rule was created'),
'pretix.plugins.sendmail.rule.changed': _('An email rule was updated'),
'pretix.plugins.sendmail.rule.order.email.sent': _('A scheduled email was sent to the order'),
'pretix.plugins.sendmail.rule.order.position.email.sent': _('A scheduled email was sent to a ticket holder'),
'pretix.plugins.sendmail.rule.deleted': _('An email rule was deleted'),
}
if logentry.action_type in plains:
return plains[logentry.action_type]
@log_entry_types.new('pretix.plugins.sendmail.sent', _('Mass email was sent to customers or attendees.'))
@log_entry_types.new('pretix.plugins.sendmail.sent.waitinglist', _('Mass email was sent to waiting list entries.'))
class SendmailPluginLogEntryType(EventLogEntryType):
pass
@log_entry_types.new('pretix.plugins.sendmail.order.email.sent', _('The order received a mass email.'))
@log_entry_types.new('pretix.plugins.sendmail.order.email.sent.attendee', _('A ticket holder of this order received a mass email.'))
class SendmailPluginOrderLogEntryType(OrderLogEntryType):
pass
@log_entry_types.new('pretix.plugins.sendmail.rule.added', _('An email rule was created'))
@log_entry_types.new('pretix.plugins.sendmail.rule.changed', _('An email rule was updated'))
@log_entry_types.new('pretix.plugins.sendmail.rule.order.email.sent', _('A scheduled email was sent to the order'))
@log_entry_types.new('pretix.plugins.sendmail.rule.order.position.email.sent', _('A scheduled email was sent to a ticket holder'))
@log_entry_types.new('pretix.plugins.sendmail.rule.deleted', _('An email rule was deleted'))
class SendmailPluginRuleLogEntryType(EventLogEntryType):
object_type = Rule
object_link_wrapper = _('Mail rule {val}')
object_link_viewname = 'plugins:sendmail:rule.update'
object_link_argname = 'rule'
@receiver(periodic_task)

View File

@@ -10,7 +10,7 @@
<script type="text/plain" id="stripe_payment_intent_client_secret">{{ payment_intent_client_secret }}</script>
{% if payment_intent_next_action_redirect_url %}
<script type="text/plain" id="stripe_payment_intent_next_action_redirect_url">{{ payment_intent_next_action_redirect_url }}</script>
{% endif %}
{% endif %}}
{% if payment_intent_redirect_action_handling %}
<script type="text/plain" id="stripe_payment_intent_redirect_action_handling">{{ payment_intent_redirect_action_handling }}</script>
{% endif %}

View File

@@ -24,11 +24,11 @@ import json
from django.dispatch import receiver
from django.template.loader import get_template
from django.urls import reverse
from django.utils.html import escape
from django.utils.translation import gettext_lazy as _
from pretix.base.logentrytypes import EventLogEntryType
from pretix.base.models import Event, SalesChannel
from pretix.base.models.log import log_entry_types
from pretix.base.signals import ( # NOQA: legacy import
EventPluginSignal, event_copy_data, item_copy_data, layout_text_variables,
logentry_display, logentry_object_link, register_data_exporters,
@@ -134,38 +134,16 @@ def pdf_event_copy_data_receiver(sender, other, item_map, question_map, **kwargs
return layout_map
@receiver(signal=logentry_display, dispatch_uid="pretix_ticketoutputpdf_logentry_display")
def pdf_logentry_display(sender, logentry, **kwargs):
if not logentry.action_type.startswith('pretix.plugins.ticketoutputpdf'):
return
plains = {
'pretix.plugins.ticketoutputpdf.layout.added': _('Ticket layout created.'),
'pretix.plugins.ticketoutputpdf.layout.deleted': _('Ticket layout deleted.'),
'pretix.plugins.ticketoutputpdf.layout.changed': _('Ticket layout changed.'),
}
if logentry.action_type in plains:
return plains[logentry.action_type]
@receiver(signal=logentry_object_link, dispatch_uid="pretix_ticketoutputpdf_logentry_object_link")
def pdf_logentry_object_link(sender, logentry, **kwargs):
if not logentry.action_type.startswith('pretix.plugins.ticketoutputpdf.layout') or not isinstance(
logentry.content_object, TicketLayout):
return
a_text = _('Ticket layout {val}')
a_map = {
'href': reverse('plugins:ticketoutputpdf:edit', kwargs={
'event': sender.slug,
'organizer': sender.organizer.slug,
'layout': logentry.content_object.id
}),
'val': escape(logentry.content_object.name),
}
a_map['val'] = '<a href="{href}">{val}</a>'.format_map(a_map)
return a_text.format_map(a_map)
@log_entry_types.new_from_dict({
'pretix.plugins.ticketoutputpdf.layout.added': _('Ticket layout created.'),
'pretix.plugins.ticketoutputpdf.layout.deleted': _('Ticket layout deleted.'),
'pretix.plugins.ticketoutputpdf.layout.changed': _('Ticket layout changed.'),
})
class PdfTicketLayoutLogEntryType(EventLogEntryType):
object_type = TicketLayout
object_link_wrapper = _('Ticket layout {val}')
object_link_viewname = 'plugins:ticketoutputpdf:edit'
object_link_argname = 'layout'
def _ticket_layouts_for_item(request, item):

View File

@@ -19,7 +19,6 @@
# 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 functools
import hashlib
import ipaddress
import random
@@ -28,7 +27,7 @@ from django import forms
from django.conf import settings
from django.contrib.auth.hashers import check_password
from django.contrib.auth.password_validation import (
get_password_validators, password_validators_help_texts, validate_password,
password_validators_help_texts, validate_password,
)
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.core import signing
@@ -272,11 +271,6 @@ class RegistrationForm(forms.Form):
return customer
@functools.lru_cache(maxsize=None)
def get_customer_password_validators():
return get_password_validators(settings.CUSTOMER_AUTH_PASSWORD_VALIDATORS)
class SetPasswordForm(forms.Form):
required_css_class = 'required'
error_messages = {
@@ -317,7 +311,7 @@ class SetPasswordForm(forms.Form):
def clean_password(self):
password1 = self.cleaned_data.get('password', '')
if validate_password(password1, user=self.customer, password_validators=get_customer_password_validators()) is not None:
if validate_password(password1, user=self.customer) is not None:
raise forms.ValidationError(_(password_validators_help_texts()), code='pw_invalid')
return password1
@@ -411,7 +405,7 @@ class ChangePasswordForm(forms.Form):
def clean_password(self):
password1 = self.cleaned_data.get('password', '')
if validate_password(password1, user=self.customer, password_validators=get_customer_password_validators()) is not None:
if validate_password(password1, user=self.customer) is not None:
raise forms.ValidationError(_(password_validators_help_texts()), code='pw_invalid')
return password1

View File

@@ -31,7 +31,7 @@
<span class="label label-success">{% trans "Book now" %}</span>
{% endif %}
{% endif %}
{% elif subev.waiting_list_active and subev.best_availability_state >= 0 %}
{% elif event.waiting_list_active and subev.best_availability_state >= 0 %}
<span class="label label-warning">{% trans "Waiting list" %}</span>
{% elif subev.best_availability_state == 20 %}
<span class="label label-danger">{% trans "Reserved" %}</span>

View File

@@ -38,7 +38,7 @@
<script src="{% statici18n request.LANGUAGE_CODE %}" async></script>
{% endif %}
{% if request.session.iframe_session %}
{% compress js file iframeresizer %}
{% compress js %}
<script type="text/javascript" src="{% static "iframeresizer/iframeResizer.contentWindow.js" %}"></script>
{% endcompress %}
{% endif %}

View File

@@ -21,23 +21,6 @@
<h1>{% trans "We are processing your request …" %}</h1>
{% if percentage %}
<div class="progress">
<div class="progress-bar progress-bar-success progress-bar-{{ percentage|floatformat:0 }}">
</div>
</div>
{% if steps %}
<ol class="steps">
{% for step in steps %}
<li>
<span class="fa fa-fw {% if step.done %}fa-check text-success{% else %}fa-cog fa-spin text-muted{% endif %}"></span>
{{ step.label }}
</li>
{% endfor %}
</ol>
{% endif %}
{% endif %}
<p>
{% trans "If this takes longer than a few minutes, please contact us." %}
</p>

View File

@@ -982,11 +982,6 @@ class OrderCancelDo(EventViewMixin, OrderDetailMixin, AsyncAction, View):
def get_error_url(self):
return self.get_order_url()
def get(self, request, *args, **kwargs):
if not self.order:
raise Http404(_('Unknown order code or not authorized to access this order.'))
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
if not self.order:
raise Http404(_('Unknown order code or not authorized to access this order.'))

View File

@@ -417,7 +417,7 @@ class WidgetAPIProductList(EventListMixin, View):
else:
availability['text'] = gettext('Book now')
availability['reason'] = 'ok'
elif ev.waiting_list_active and (ev.best_availability_state is not None and ev.best_availability_state >= 0):
elif event.waiting_list_active and (ev.best_availability_state is not None and ev.best_availability_state >= 0):
availability['color'] = 'orange'
availability['text'] = gettext('Waiting list')
availability['reason'] = 'waitinglist'
@@ -719,7 +719,7 @@ class WidgetAPIProductList(EventListMixin, View):
'display_net_prices': request.event.settings.display_net_prices,
'use_native_spinners': request.event.settings.widget_use_native_spinners,
'show_variations_expanded': request.event.settings.show_variations_expanded,
'waiting_list_enabled': (self.subevent or request.event).waiting_list_active,
'waiting_list_enabled': request.event.waiting_list_active,
'voucher_explanation_text': str(rich_text(request.event.settings.voucher_explanation_text, safelinks=False)),
'error': None,
'cart_exists': False

View File

@@ -340,7 +340,6 @@ if HAS_CELERY:
CELERY_BROKER_TRANSPORT_OPTIONS = loads(config.get('celery', 'broker_transport_options'))
if HAS_CELERY_BACKEND_TRANSPORT_OPTS:
CELERY_RESULT_BACKEND_TRANSPORT_OPTIONS = loads(config.get('celery', 'backend_transport_options'))
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
else:
CELERY_TASK_ALWAYS_EAGER = True
@@ -428,14 +427,6 @@ REST_FRAMEWORK = {
}
CORE_MODULES = {
"pretix.base",
"pretix.presale",
"pretix.control",
"pretix.plugins.checkinlists",
"pretix.plugins.reports",
}
MIDDLEWARE = [
'pretix.helpers.logs.RequestIdMiddleware',
'pretix.api.middleware.IdempotencyMiddleware',
@@ -715,10 +706,6 @@ BOOTSTRAP3 = {
}
PASSWORD_HASHERS = [
# Note that when updating this, all user passwords will be re-hashed on next login, however,
# the HistoricPassword model will not be changed automatically. In case a serious issue with a hasher
# comes to light, dropping the contents of the HistoricPassword table might be the more risk-adequate
# decision.
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
@@ -730,44 +717,7 @@ AUTH_PASSWORD_VALIDATORS = [
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
"OPTIONS": {
# To fulfill per PCI DSS requirement 8.3.6
"min_length": 12,
},
},
{
# To fulfill per PCI DSS requirement 8.3.6
'NAME': 'pretix.base.auth.NumericAndAlphabeticPasswordValidator',
},
{
"NAME": "pretix.base.auth.HistoryPasswordValidator",
"OPTIONS": {
# To fulfill per PCI DSS requirement 8.3.7
"history_length": 4,
},
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
CUSTOMER_AUTH_PASSWORD_VALIDATORS = [
# For customer accounts, we apply a little less strict requirements to provide a risk-adequate
# user experience.
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
"OPTIONS": {
"min_length": 8,
},
},
{
'NAME': 'pretix.base.auth.NumericAndAlphabeticPasswordValidator',
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',

View File

@@ -9,7 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.4",
"@babel/preset-env": "^7.25.3",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"rollup": "^2.79.1",
@@ -43,9 +43,9 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
"integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
"version": "7.25.2",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz",
"integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==",
"engines": {
"node": ">=6.9.0"
}
@@ -99,11 +99,11 @@
}
},
"node_modules/@babel/generator": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
"integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz",
"integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
"dependencies": {
"@babel/types": "^7.25.6",
"@babel/types": "^7.25.0",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
@@ -185,16 +185,18 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"node_modules/@babel/helper-create-class-features-plugin": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
"integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz",
"integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.24.7",
"@babel/helper-member-expression-to-functions": "^7.24.8",
"@babel/helper-environment-visitor": "^7.24.7",
"@babel/helper-function-name": "^7.24.7",
"@babel/helper-member-expression-to-functions": "^7.24.7",
"@babel/helper-optimise-call-expression": "^7.24.7",
"@babel/helper-replace-supers": "^7.25.0",
"@babel/helper-replace-supers": "^7.24.7",
"@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
"@babel/traverse": "^7.25.4",
"@babel/helper-split-export-declaration": "^7.24.7",
"semver": "^6.3.1"
},
"engines": {
@@ -237,9 +239,9 @@
}
},
"node_modules/@babel/helper-define-polyfill-provider": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
"integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz",
"integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==",
"dependencies": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
@@ -251,6 +253,29 @@
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
}
},
"node_modules/@babel/helper-environment-visitor": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
"integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
"dependencies": {
"@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-function-name": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
"integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
"dependencies": {
"@babel/template": "^7.24.7",
"@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-member-expression-to-functions": {
"version": "7.24.8",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
@@ -367,6 +392,17 @@
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
"integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
"dependencies": {
"@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.24.8",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
@@ -431,11 +467,11 @@
}
},
"node_modules/@babel/parser": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
"integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz",
"integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==",
"dependencies": {
"@babel/types": "^7.25.6"
"@babel/types": "^7.25.2"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -761,14 +797,14 @@
}
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz",
"integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==",
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz",
"integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.24.8",
"@babel/helper-remap-async-to-generator": "^7.25.0",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/traverse": "^7.25.4"
"@babel/traverse": "^7.25.0"
},
"engines": {
"node": ">=6.9.0"
@@ -822,12 +858,12 @@
}
},
"node_modules/@babel/plugin-transform-class-properties": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz",
"integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz",
"integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.25.4",
"@babel/helper-plugin-utils": "^7.24.8"
"@babel/helper-create-class-features-plugin": "^7.24.7",
"@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -853,15 +889,15 @@
}
},
"node_modules/@babel/plugin-transform-classes": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
"integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz",
"integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.24.7",
"@babel/helper-compilation-targets": "^7.25.2",
"@babel/helper-compilation-targets": "^7.24.8",
"@babel/helper-plugin-utils": "^7.24.8",
"@babel/helper-replace-supers": "^7.25.0",
"@babel/traverse": "^7.25.4",
"@babel/traverse": "^7.25.0",
"globals": "^11.1.0"
},
"engines": {
@@ -1278,12 +1314,12 @@
}
},
"node_modules/@babel/plugin-transform-private-methods": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz",
"integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz",
"integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.25.4",
"@babel/helper-plugin-utils": "^7.24.8"
"@babel/helper-create-class-features-plugin": "^7.24.7",
"@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1468,12 +1504,12 @@
}
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz",
"integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz",
"integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.25.2",
"@babel/helper-plugin-utils": "^7.24.8"
"@babel/helper-create-regexp-features-plugin": "^7.24.7",
"@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1483,11 +1519,11 @@
}
},
"node_modules/@babel/preset-env": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz",
"integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==",
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz",
"integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==",
"dependencies": {
"@babel/compat-data": "^7.25.4",
"@babel/compat-data": "^7.25.2",
"@babel/helper-compilation-targets": "^7.25.2",
"@babel/helper-plugin-utils": "^7.24.8",
"@babel/helper-validator-option": "^7.24.8",
@@ -1516,13 +1552,13 @@
"@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
"@babel/plugin-transform-arrow-functions": "^7.24.7",
"@babel/plugin-transform-async-generator-functions": "^7.25.4",
"@babel/plugin-transform-async-generator-functions": "^7.25.0",
"@babel/plugin-transform-async-to-generator": "^7.24.7",
"@babel/plugin-transform-block-scoped-functions": "^7.24.7",
"@babel/plugin-transform-block-scoping": "^7.25.0",
"@babel/plugin-transform-class-properties": "^7.25.4",
"@babel/plugin-transform-class-properties": "^7.24.7",
"@babel/plugin-transform-class-static-block": "^7.24.7",
"@babel/plugin-transform-classes": "^7.25.4",
"@babel/plugin-transform-classes": "^7.25.0",
"@babel/plugin-transform-computed-properties": "^7.24.7",
"@babel/plugin-transform-destructuring": "^7.24.8",
"@babel/plugin-transform-dotall-regex": "^7.24.7",
@@ -1550,7 +1586,7 @@
"@babel/plugin-transform-optional-catch-binding": "^7.24.7",
"@babel/plugin-transform-optional-chaining": "^7.24.8",
"@babel/plugin-transform-parameters": "^7.24.7",
"@babel/plugin-transform-private-methods": "^7.25.4",
"@babel/plugin-transform-private-methods": "^7.24.7",
"@babel/plugin-transform-private-property-in-object": "^7.24.7",
"@babel/plugin-transform-property-literals": "^7.24.7",
"@babel/plugin-transform-regenerator": "^7.24.7",
@@ -1563,10 +1599,10 @@
"@babel/plugin-transform-unicode-escapes": "^7.24.7",
"@babel/plugin-transform-unicode-property-regex": "^7.24.7",
"@babel/plugin-transform-unicode-regex": "^7.24.7",
"@babel/plugin-transform-unicode-sets-regex": "^7.25.4",
"@babel/plugin-transform-unicode-sets-regex": "^7.24.7",
"@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.10",
"babel-plugin-polyfill-corejs3": "^0.10.6",
"babel-plugin-polyfill-corejs3": "^0.10.4",
"babel-plugin-polyfill-regenerator": "^0.6.1",
"core-js-compat": "^3.37.1",
"semver": "^6.3.1"
@@ -1629,15 +1665,15 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
"integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz",
"integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==",
"dependencies": {
"@babel/code-frame": "^7.24.7",
"@babel/generator": "^7.25.6",
"@babel/parser": "^7.25.6",
"@babel/generator": "^7.25.0",
"@babel/parser": "^7.25.3",
"@babel/template": "^7.25.0",
"@babel/types": "^7.25.6",
"@babel/types": "^7.25.2",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1646,9 +1682,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
"integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
"version": "7.25.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz",
"integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
"dependencies": {
"@babel/helper-string-parser": "^7.24.8",
"@babel/helper-validator-identifier": "^7.24.7",
@@ -1987,12 +2023,12 @@
}
},
"node_modules/babel-plugin-polyfill-corejs3": {
"version": "0.10.6",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
"integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz",
"integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==",
"dependencies": {
"@babel/helper-define-polyfill-provider": "^0.6.2",
"core-js-compat": "^3.38.0"
"@babel/helper-define-polyfill-provider": "^0.6.1",
"core-js-compat": "^3.36.1"
},
"peerDependencies": {
"@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -2072,9 +2108,9 @@
}
},
"node_modules/browserslist": {
"version": "4.23.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
"integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
"version": "4.23.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
"integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
"funding": [
{
"type": "opencollective",
@@ -2090,9 +2126,9 @@
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001646",
"electron-to-chromium": "^1.5.4",
"node-releases": "^2.0.18",
"caniuse-lite": "^1.0.30001640",
"electron-to-chromium": "^1.4.820",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.1.0"
},
"bin": {
@@ -2279,11 +2315,11 @@
}
},
"node_modules/core-js-compat": {
"version": "3.38.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
"integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
"version": "3.37.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
"integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==",
"dependencies": {
"browserslist": "^4.23.3"
"browserslist": "^4.23.0"
},
"funding": {
"type": "opencollective",
@@ -3084,9 +3120,9 @@
"optional": true
},
"node_modules/node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -4028,9 +4064,9 @@
}
},
"@babel/compat-data": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
"integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ=="
"version": "7.25.2",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz",
"integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ=="
},
"@babel/core": {
"version": "7.25.2",
@@ -4067,11 +4103,11 @@
}
},
"@babel/generator": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
"integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz",
"integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
"requires": {
"@babel/types": "^7.25.6",
"@babel/types": "^7.25.0",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
@@ -4139,16 +4175,18 @@
}
},
"@babel/helper-create-class-features-plugin": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
"integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz",
"integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.24.7",
"@babel/helper-member-expression-to-functions": "^7.24.8",
"@babel/helper-environment-visitor": "^7.24.7",
"@babel/helper-function-name": "^7.24.7",
"@babel/helper-member-expression-to-functions": "^7.24.7",
"@babel/helper-optimise-call-expression": "^7.24.7",
"@babel/helper-replace-supers": "^7.25.0",
"@babel/helper-replace-supers": "^7.24.7",
"@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
"@babel/traverse": "^7.25.4",
"@babel/helper-split-export-declaration": "^7.24.7",
"semver": "^6.3.1"
},
"dependencies": {
@@ -4177,9 +4215,9 @@
}
},
"@babel/helper-define-polyfill-provider": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz",
"integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==",
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz",
"integrity": "sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==",
"requires": {
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-plugin-utils": "^7.22.5",
@@ -4188,6 +4226,23 @@
"resolve": "^1.14.2"
}
},
"@babel/helper-environment-visitor": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz",
"integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==",
"requires": {
"@babel/types": "^7.24.7"
}
},
"@babel/helper-function-name": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz",
"integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==",
"requires": {
"@babel/template": "^7.24.7",
"@babel/types": "^7.24.7"
}
},
"@babel/helper-member-expression-to-functions": {
"version": "7.24.8",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
@@ -4268,6 +4323,14 @@
"@babel/types": "^7.24.7"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz",
"integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==",
"requires": {
"@babel/types": "^7.24.7"
}
},
"@babel/helper-string-parser": {
"version": "7.24.8",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
@@ -4314,11 +4377,11 @@
}
},
"@babel/parser": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
"integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz",
"integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==",
"requires": {
"@babel/types": "^7.25.6"
"@babel/types": "^7.25.2"
}
},
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
@@ -4525,14 +4588,14 @@
}
},
"@babel/plugin-transform-async-generator-functions": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz",
"integrity": "sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg==",
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz",
"integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==",
"requires": {
"@babel/helper-plugin-utils": "^7.24.8",
"@babel/helper-remap-async-to-generator": "^7.25.0",
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/traverse": "^7.25.4"
"@babel/traverse": "^7.25.0"
}
},
"@babel/plugin-transform-async-to-generator": {
@@ -4562,12 +4625,12 @@
}
},
"@babel/plugin-transform-class-properties": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz",
"integrity": "sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.7.tgz",
"integrity": "sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==",
"requires": {
"@babel/helper-create-class-features-plugin": "^7.25.4",
"@babel/helper-plugin-utils": "^7.24.8"
"@babel/helper-create-class-features-plugin": "^7.24.7",
"@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-class-static-block": {
@@ -4581,15 +4644,15 @@
}
},
"@babel/plugin-transform-classes": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
"integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
"version": "7.25.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.0.tgz",
"integrity": "sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.24.7",
"@babel/helper-compilation-targets": "^7.25.2",
"@babel/helper-compilation-targets": "^7.24.8",
"@babel/helper-plugin-utils": "^7.24.8",
"@babel/helper-replace-supers": "^7.25.0",
"@babel/traverse": "^7.25.4",
"@babel/traverse": "^7.25.0",
"globals": "^11.1.0"
}
},
@@ -4838,12 +4901,12 @@
}
},
"@babel/plugin-transform-private-methods": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz",
"integrity": "sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.7.tgz",
"integrity": "sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==",
"requires": {
"@babel/helper-create-class-features-plugin": "^7.25.4",
"@babel/helper-plugin-utils": "^7.24.8"
"@babel/helper-create-class-features-plugin": "^7.24.7",
"@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-private-property-in-object": {
@@ -4950,20 +5013,20 @@
}
},
"@babel/plugin-transform-unicode-sets-regex": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz",
"integrity": "sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA==",
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.7.tgz",
"integrity": "sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==",
"requires": {
"@babel/helper-create-regexp-features-plugin": "^7.25.2",
"@babel/helper-plugin-utils": "^7.24.8"
"@babel/helper-create-regexp-features-plugin": "^7.24.7",
"@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/preset-env": {
"version": "7.25.4",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.4.tgz",
"integrity": "sha512-W9Gyo+KmcxjGahtt3t9fb14vFRWvPpu5pT6GBlovAK6BTBcxgjfVMSQCfJl4oi35ODrxP6xx2Wr8LNST57Mraw==",
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz",
"integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==",
"requires": {
"@babel/compat-data": "^7.25.4",
"@babel/compat-data": "^7.25.2",
"@babel/helper-compilation-targets": "^7.25.2",
"@babel/helper-plugin-utils": "^7.24.8",
"@babel/helper-validator-option": "^7.24.8",
@@ -4992,13 +5055,13 @@
"@babel/plugin-syntax-top-level-await": "^7.14.5",
"@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
"@babel/plugin-transform-arrow-functions": "^7.24.7",
"@babel/plugin-transform-async-generator-functions": "^7.25.4",
"@babel/plugin-transform-async-generator-functions": "^7.25.0",
"@babel/plugin-transform-async-to-generator": "^7.24.7",
"@babel/plugin-transform-block-scoped-functions": "^7.24.7",
"@babel/plugin-transform-block-scoping": "^7.25.0",
"@babel/plugin-transform-class-properties": "^7.25.4",
"@babel/plugin-transform-class-properties": "^7.24.7",
"@babel/plugin-transform-class-static-block": "^7.24.7",
"@babel/plugin-transform-classes": "^7.25.4",
"@babel/plugin-transform-classes": "^7.25.0",
"@babel/plugin-transform-computed-properties": "^7.24.7",
"@babel/plugin-transform-destructuring": "^7.24.8",
"@babel/plugin-transform-dotall-regex": "^7.24.7",
@@ -5026,7 +5089,7 @@
"@babel/plugin-transform-optional-catch-binding": "^7.24.7",
"@babel/plugin-transform-optional-chaining": "^7.24.8",
"@babel/plugin-transform-parameters": "^7.24.7",
"@babel/plugin-transform-private-methods": "^7.25.4",
"@babel/plugin-transform-private-methods": "^7.24.7",
"@babel/plugin-transform-private-property-in-object": "^7.24.7",
"@babel/plugin-transform-property-literals": "^7.24.7",
"@babel/plugin-transform-regenerator": "^7.24.7",
@@ -5039,10 +5102,10 @@
"@babel/plugin-transform-unicode-escapes": "^7.24.7",
"@babel/plugin-transform-unicode-property-regex": "^7.24.7",
"@babel/plugin-transform-unicode-regex": "^7.24.7",
"@babel/plugin-transform-unicode-sets-regex": "^7.25.4",
"@babel/plugin-transform-unicode-sets-regex": "^7.24.7",
"@babel/preset-modules": "0.1.6-no-external-plugins",
"babel-plugin-polyfill-corejs2": "^0.4.10",
"babel-plugin-polyfill-corejs3": "^0.10.6",
"babel-plugin-polyfill-corejs3": "^0.10.4",
"babel-plugin-polyfill-regenerator": "^0.6.1",
"core-js-compat": "^3.37.1",
"semver": "^6.3.1"
@@ -5089,23 +5152,23 @@
}
},
"@babel/traverse": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
"integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
"version": "7.25.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz",
"integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==",
"requires": {
"@babel/code-frame": "^7.24.7",
"@babel/generator": "^7.25.6",
"@babel/parser": "^7.25.6",
"@babel/generator": "^7.25.0",
"@babel/parser": "^7.25.3",
"@babel/template": "^7.25.0",
"@babel/types": "^7.25.6",
"@babel/types": "^7.25.2",
"debug": "^4.3.1",
"globals": "^11.1.0"
}
},
"@babel/types": {
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
"integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
"version": "7.25.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz",
"integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==",
"requires": {
"@babel/helper-string-parser": "^7.24.8",
"@babel/helper-validator-identifier": "^7.24.7",
@@ -5340,12 +5403,12 @@
}
},
"babel-plugin-polyfill-corejs3": {
"version": "0.10.6",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
"integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz",
"integrity": "sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==",
"requires": {
"@babel/helper-define-polyfill-provider": "^0.6.2",
"core-js-compat": "^3.38.0"
"@babel/helper-define-polyfill-provider": "^0.6.1",
"core-js-compat": "^3.36.1"
}
},
"babel-plugin-polyfill-regenerator": {
@@ -5407,13 +5470,13 @@
}
},
"browserslist": {
"version": "4.23.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
"integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
"version": "4.23.2",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz",
"integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==",
"requires": {
"caniuse-lite": "^1.0.30001646",
"electron-to-chromium": "^1.5.4",
"node-releases": "^2.0.18",
"caniuse-lite": "^1.0.30001640",
"electron-to-chromium": "^1.4.820",
"node-releases": "^2.0.14",
"update-browserslist-db": "^1.1.0"
}
},
@@ -5552,11 +5615,11 @@
}
},
"core-js-compat": {
"version": "3.38.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
"integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
"version": "3.37.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
"integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==",
"requires": {
"browserslist": "^4.23.3"
"browserslist": "^4.23.0"
}
},
"css": {
@@ -6152,9 +6215,9 @@
"optional": true
},
"node-releases": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
"integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
},
"normalize-path": {
"version": "3.0.0",

View File

@@ -5,7 +5,7 @@
"scripts": {},
"dependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.4",
"@babel/preset-env": "^7.25.3",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"vue": "^2.7.16",

View File

@@ -18,18 +18,3 @@ body {
font-size: 200px;
color: $brand-primary;
}
.progress {
max-width: 450px;
margin: 0 auto 20px;
}
.steps {
max-width: 450px;
text-align: left;
margin: 0 auto 20px;
list-style-type: none;
padding: 0;
}
@for $i from 0 through 100 {
.progress-bar-#{$i} { width: 1% * $i; }
}

View File

@@ -66,7 +66,7 @@ def inputfile_factory(multiplier=1):
'A': 'GHIJK432',
'B': 'Ticket',
'C': 'False',
'D': '2021-05-28T11:00:00+00:00',
'D': '2021-05-28 11:00:00',
'E': '2',
'F': '1',
},

View File

@@ -337,7 +337,7 @@ class RegistrationFormTest(TestCase):
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'f00barbarbar',
'password': 'foobarbar',
'password_repeat': ''
})
self.assertEqual(response.status_code, 200)
@@ -347,8 +347,8 @@ class RegistrationFormTest(TestCase):
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
})
self.assertEqual(response.status_code, 200)
@@ -356,8 +356,8 @@ class RegistrationFormTest(TestCase):
def test_success(self):
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
})
self.assertEqual(response.status_code, 302)
assert time.time() - self.client.session['pretix_auth_login_time'] < 60
@@ -367,8 +367,8 @@ class RegistrationFormTest(TestCase):
def test_disabled(self):
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
})
self.assertEqual(response.status_code, 403)
@@ -376,8 +376,8 @@ class RegistrationFormTest(TestCase):
def test_no_native_auth(self):
response = self.client.post('/control/register', {
'email': 'dummy@dummy.dummy',
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
})
self.assertEqual(response.status_code, 403)
@@ -593,8 +593,8 @@ class PasswordRecoveryFormTest(TestCase):
response = self.client.post(
'/control/forgot/recover?id=%d&token=foo' % self.user.id,
{
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
}
)
self.assertEqual(response.status_code, 302)
@@ -615,8 +615,8 @@ class PasswordRecoveryFormTest(TestCase):
response = self.client.post(
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
}
)
self.assertEqual(response.status_code, 302)
@@ -630,13 +630,13 @@ class PasswordRecoveryFormTest(TestCase):
response = self.client.post(
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': 'f00barbarbar',
'password_repeat': 'f00barbarbar'
'password': 'foobarbar',
'password_repeat': 'foobarbar'
}
)
self.assertEqual(response.status_code, 302)
self.user = User.objects.get(id=self.user.id)
self.assertTrue(self.user.check_password('f00barbarbar'))
self.assertTrue(self.user.check_password('foobarbar'))
def test_recovery_valid_token_empty_passwords(self):
token = default_token_generator.make_token(self.user)
@@ -645,7 +645,7 @@ class PasswordRecoveryFormTest(TestCase):
response = self.client.post(
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': 'f00barbarbar',
'password': 'foobarbar',
'password_repeat': ''
}
)
@@ -660,7 +660,7 @@ class PasswordRecoveryFormTest(TestCase):
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': '',
'password_repeat': 'f00barbarbar'
'password_repeat': 'foobarbar'
}
)
self.assertEqual(response.status_code, 200)
@@ -697,48 +697,6 @@ class PasswordRecoveryFormTest(TestCase):
self.user = User.objects.get(id=self.user.id)
self.assertTrue(self.user.check_password('demo'))
def test_recovery_valid_token_password_reuse(self):
self.user.set_password("GsvdU4gGZDb4J9WgIhLNcZT9PO7CZ3")
self.user.save()
self.user.set_password("hLPqPpuZIjouGBk9xTLu1aXYqjpRYS")
self.user.save()
self.user.set_password("Jn2nQSa25ZJAc5GUI1HblrneWCXotD")
self.user.save()
self.user.set_password("cboaBj3yIfgnQeKClDgvKNvWC69cV1")
self.user.save()
self.user.set_password("Kkj8f3kGXbXmbgcwHBgf3WKmzkUOhM")
self.user.save()
assert self.user.historic_passwords.count() == 4
token = default_token_generator.make_token(self.user)
response = self.client.get('/control/forgot/recover?id=%d&token=%s' % (self.user.id, token))
self.assertEqual(response.status_code, 200)
response = self.client.post(
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': 'cboaBj3yIfgnQeKClDgvKNvWC69cV1',
'password_repeat': 'cboaBj3yIfgnQeKClDgvKNvWC69cV1'
}
)
self.assertEqual(response.status_code, 200)
self.user = User.objects.get(id=self.user.id)
self.assertTrue(self.user.check_password('Kkj8f3kGXbXmbgcwHBgf3WKmzkUOhM'))
token = default_token_generator.make_token(self.user)
response = self.client.get('/control/forgot/recover?id=%d&token=%s' % (self.user.id, token))
self.assertEqual(response.status_code, 200)
response = self.client.post(
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': 'GsvdU4gGZDb4J9WgIhLNcZT9PO7CZ3',
'password_repeat': 'GsvdU4gGZDb4J9WgIhLNcZT9PO7CZ3'
}
)
self.assertEqual(response.status_code, 302)
self.user = User.objects.get(id=self.user.id)
self.assertTrue(self.user.check_password('GsvdU4gGZDb4J9WgIhLNcZT9PO7CZ3'))
def test_recovery_valid_token_short_passwords(self):
token = default_token_generator.make_token(self.user)
response = self.client.get('/control/forgot/recover?id=%d&token=%s' % (self.user.id, token))
@@ -746,8 +704,8 @@ class PasswordRecoveryFormTest(TestCase):
response = self.client.post(
'/control/forgot/recover?id=%d&token=%s' % (self.user.id, token),
{
'password': 'foobarfooba',
'password_repeat': 'foobarfooba'
'password': 'foobar',
'password_repeat': 'foobar'
}
)
self.assertEqual(response.status_code, 200)

View File

@@ -349,8 +349,8 @@ def test_invite_new_user(event, admin_team, client):
assert b'<form' in resp.content
resp = client.post('/control/invite/{}'.format(i.token), {
'email': 'dummy@example.org',
'password': 'asdsdgfgjh1234567',
'password_repeat': 'asdsdgfgjh1234567'
'password': 'asdsdgfgjh',
'password_repeat': 'asdsdgfgjh'
}, follow=True)
assert b'alert-success' in resp.content

View File

@@ -112,8 +112,8 @@ class UserSettingsTest(SoupTest):
self.user.auth_backend = 'test_request'
self.user.save()
self.save({
'new_pw': 'f00barbarbar',
'new_pw_repeat': 'f00barbarbar',
'new_pw': 'foobarbar',
'new_pw_repeat': 'foobarbar',
'old_pw': 'barfoofoo',
})
pw = self.user.password
@@ -122,13 +122,13 @@ class UserSettingsTest(SoupTest):
def test_change_password_success(self):
doc = self.save({
'new_pw': 'f00barbarbar',
'new_pw_repeat': 'f00barbarbar',
'new_pw': 'foobarbar',
'new_pw_repeat': 'foobarbar',
'old_pw': 'barfoofoo',
})
assert doc.select(".alert-success")
self.user = User.objects.get(pk=self.user.pk)
assert self.user.check_password("f00barbarbar")
assert self.user.check_password("foobarbar")
def test_change_password_short(self):
doc = self.save({
@@ -171,28 +171,6 @@ class UserSettingsTest(SoupTest):
})
assert doc.select(".alert-danger")
def test_change_password_history(self):
doc = self.save({
'new_pw': 'qvuSpukdKWUV7m7PoRrWwpCd2Taij9',
'new_pw_repeat': 'qvuSpukdKWUV7m7PoRrWwpCd2Taij9',
'old_pw': 'barfoofoo',
})
assert doc.select(".alert-success")
doc = self.save({
'new_pw': '9UQl4lSwHLMVUIMgw0L1X8XEFmyvdn',
'new_pw_repeat': '9UQl4lSwHLMVUIMgw0L1X8XEFmyvdn',
'old_pw': 'qvuSpukdKWUV7m7PoRrWwpCd2Taij9',
})
assert doc.select(".alert-success")
doc = self.save({
'new_pw': 'qvuSpukdKWUV7m7PoRrWwpCd2Taij9',
'new_pw_repeat': 'qvuSpukdKWUV7m7PoRrWwpCd2Taij9',
'old_pw': '9UQl4lSwHLMVUIMgw0L1X8XEFmyvdn',
})
assert doc.select(".alert-danger")
def test_needs_password_change(self):
self.user.needs_password_change = True
self.user.save()
@@ -209,8 +187,8 @@ class UserSettingsTest(SoupTest):
self.user.needs_password_change = True
self.user.save()
self.save({
'new_pw': 'f00barbarbar',
'new_pw_repeat': 'f00barbarbar',
'new_pw': 'foobarbar',
'new_pw_repeat': 'foobarbar',
'old_pw': 'barfoofoo'
})
self.user.refresh_from_db()