Compare commits

..

1 Commits

Author SHA1 Message Date
Raphael Michel
423a9febad Sendmail: Chunk query to prevent high memory load (Z#23217167) 2025-12-04 16:57:00 +01:00
75 changed files with 1674 additions and 4033 deletions

View File

@@ -211,7 +211,7 @@ The line-based computation has a few significant advantages:
The main disadvantage is that the tax looks "wrong" when computed from the sum. Taking the sum of net prices (420.15)
and multiplying it with the tax rate (19%) yields a tax amount of 79.83 (instead of 79.85) and a gross sum of 499.98
(instead of 500.00). This becomes a problem when juristictions, data formats, or external systems expect this calculation
(instead of 499.98). This becomes a problem when juristictions, data formats, or external systems expect this calculation
to work on the level of the entire order. A prominent example is the EN 16931 standard for e-invoicing that
does not allow the computation as created by pretix.

View File

@@ -30,7 +30,7 @@ dependencies = [
"babel",
"BeautifulSoup4==4.14.*",
"bleach==6.2.*",
"celery==5.6.*",
"celery==5.5.*",
"chardet==5.2.*",
"cryptography>=44.0.0",
"css-inline==0.18.*",
@@ -62,7 +62,7 @@ dependencies = [
"importlib_metadata==8.*", # Polyfill, we can probably drop this once we require Python 3.10+
"isoweek",
"jsonschema",
"kombu==5.6.*",
"kombu==5.5.*",
"libsass==0.23.*",
"lxml",
"markdown==3.9", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
@@ -92,13 +92,14 @@ dependencies = [
"redis==6.4.*",
"reportlab==4.4.*",
"requests==2.32.*",
"sentry-sdk==2.47.*",
"sentry-sdk==2.46.*",
"sepaxml==2.7.*",
"stripe==7.9.*",
"text-unidecode==1.*",
"tlds>=2020041600",
"tqdm==4.*",
"ua-parser==1.0.*",
"vat_moss_forked==2020.3.20.0.11.0",
"vobject==0.9.*",
"webauthn==2.7.*",
"zeep==4.3.*"

View File

@@ -795,7 +795,6 @@ class EventSettingsSerializer(SettingsSerializer):
'invoice_address_asked',
'invoice_address_required',
'invoice_address_vatid',
'invoice_address_vatid_required_countries',
'invoice_address_company_required',
'invoice_address_beneficiary',
'invoice_address_custom_field',
@@ -944,7 +943,6 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer):
'invoice_address_asked',
'invoice_address_required',
'invoice_address_vatid',
'invoice_address_vatid_required_countries',
'invoice_address_company_required',
'invoice_address_beneficiary',
'invoice_address_custom_field',

View File

@@ -567,7 +567,7 @@ class QuotaViewSet(ConditionalListView, viewsets.ModelViewSet):
write_permission = 'can_change_items'
def get_queryset(self):
return self.request.event.quotas.select_related('subevent').prefetch_related('items', 'variations').all()
return self.request.event.quotas.all()
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset()).distinct()

View File

@@ -721,7 +721,7 @@ class MembershipViewSet(viewsets.ModelViewSet):
def get_queryset(self):
return Membership.objects.filter(
customer__organizer=self.request.organizer
).select_related('customer')
)
def get_serializer_context(self):
ctx = super().get_serializer_context()

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/>.
#
from django.db import transaction
from django.db.models import F, Q
from django.utils.timezone import now
@@ -65,13 +64,8 @@ class VoucherViewSet(viewsets.ModelViewSet):
permission = 'can_view_vouchers'
write_permission = 'can_change_vouchers'
@scopes_disabled() # we have an event check here, and we can save some performance on subqueries
def get_queryset(self):
return Voucher.annotate_budget_used(
self.request.event.vouchers
).select_related(
'item', 'quota', 'seat', 'variation'
)
return self.request.event.vouchers.select_related('seat').all()
@transaction.atomic()
def create(self, request, *args, **kwargs):

View File

@@ -90,7 +90,6 @@ StaticMapping = namedtuple('StaticMapping', ('id', 'pretix_model', 'external_obj
class OutboundSyncProvider:
max_attempts = 5
list_field_joiner = "," # set to None to keep native lists in properties
def __init__(self, event):
self.event = event
@@ -282,8 +281,7 @@ class OutboundSyncProvider:
'Please update value mapping for field "{field_name}" - option "{val}" not assigned'
).format(field_name=key, val=val)])
if self.list_field_joiner:
val = self.list_field_joiner.join(val)
val = ",".join(val)
return val
def get_properties(self, inputs: dict, property_mappings: List[dict]):

View File

@@ -71,20 +71,15 @@ def assign_properties(
return out
def _add_to_list(out, field_name, current_value, new_item_input, list_sep):
def _add_to_list(out, field_name, current_value, new_item, list_sep):
new_item = str(new_item)
if list_sep is not None:
new_items = str(new_item_input).split(list_sep)
new_item = new_item.replace(list_sep, "")
current_value = current_value.split(list_sep) if current_value else []
else:
new_items = [str(new_item_input)]
if not isinstance(current_value, (list, tuple)):
current_value = [str(current_value)]
new_list = list(current_value)
for new_item in new_items:
if new_item not in current_value:
new_list.append(new_item)
if new_list != current_value:
elif not isinstance(current_value, (list, tuple)):
current_value = [str(current_value)]
if new_item not in current_value:
new_list = current_value + [new_item]
if list_sep is not None:
new_list = list_sep.join(new_list)
out[field_name] = new_list

View File

@@ -83,7 +83,7 @@ from pretix.base.invoicing.transmission import (
from pretix.base.models import InvoiceAddress, Item, Question, QuestionOption
from pretix.base.models.tax import ask_for_vat_id
from pretix.base.services.tax import (
VATIDFinalError, VATIDTemporaryError, normalize_vat_id, validate_vat_id,
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
)
from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
@@ -1165,11 +1165,13 @@ class BaseInvoiceAddressForm(forms.ModelForm):
self.fields['vat_id'].help_text = '<br/>'.join([
str(_('Optional, but depending on the country you reside in we might need to charge you '
'additional taxes if you do not enter it.')),
str(_('If you are registered in Switzerland, you can enter your UID instead.')),
])
else:
self.fields['vat_id'].help_text = '<br/>'.join([
str(_('Optional, but it might be required for you to claim tax benefits on your invoice '
'depending on your and the sellers country of residence.')),
str(_('If you are registered in Switzerland, you can enter your UID instead.')),
])
transmission_type_choices = [
@@ -1356,24 +1358,13 @@ class BaseInvoiceAddressForm(forms.ModelForm):
"transmission method.")}
)
vat_id_applicable = (
'vat_id' in self.fields and
data.get('is_business') and
ask_for_vat_id(data.get('country'))
)
vat_id_required = vat_id_applicable and str(data.get('country')) in self.event.settings.invoice_address_vatid_required_countries
if vat_id_required and not data.get('vat_id'):
raise ValidationError({
"vat_id": _("This field is required.")
})
if self.validate_vat_id and self.instance.vat_id_validated and 'vat_id' not in self.changed_data:
pass # Skip re-validation if it is validated
elif self.validate_vat_id and vat_id_applicable:
pass
elif self.validate_vat_id and data.get('is_business') and ask_for_vat_id(data.get('country')) and data.get('vat_id'):
try:
normalized_id = validate_vat_id(data.get('vat_id'), str(data.get('country')))
self.instance.vat_id_validated = True
self.instance.vat_id = data['vat_id'] = normalized_id
self.instance.vat_id = normalized_id
except VATIDFinalError as e:
if self.all_optional:
self.instance.vat_id_validated = False
@@ -1381,9 +1372,6 @@ class BaseInvoiceAddressForm(forms.ModelForm):
else:
raise ValidationError({"vat_id": e.message})
except VATIDTemporaryError as e:
# We couldn't check it online, but we can still normalize it
normalized_id = normalize_vat_id(data.get('vat_id'), str(data.get('country')))
self.instance.vat_id = data['vat_id'] = normalized_id
self.instance.vat_id_validated = False
if self.request and self.vat_warning:
messages.warning(self.request, e.message)

View File

@@ -32,6 +32,7 @@ from itertools import groupby
from typing import Tuple
import bleach
import vat_moss.exchange_rates
from bidi import get_display
from django.contrib.staticfiles import finders
from django.db.models import Sum
@@ -1058,7 +1059,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
def fmt(val):
try:
return money_filter(val, self.invoice.foreign_currency_display)
return vat_moss.exchange_rates.format(val, self.invoice.foreign_currency_display)
except ValueError:
return localize(val) + ' ' + self.invoice.foreign_currency_display

View File

@@ -47,19 +47,6 @@ class DataImportError(LazyLocaleException):
super().__init__(msg)
def rename_duplicates(values):
used = set()
had_duplicates = False
for i, value in enumerate(values):
c = 0
while values[i] in used:
c += 1
values[i] = f'{value}__{c}'
had_duplicates = True
used.add(values[i])
return had_duplicates
def parse_csv(file, length=None, mode="strict", charset=None):
file.seek(0)
data = file.read(length)
@@ -83,7 +70,6 @@ def parse_csv(file, length=None, mode="strict", charset=None):
return None
reader = csv.DictReader(io.StringIO(data), dialect=dialect)
reader._had_duplicates = rename_duplicates(reader.fieldnames)
return reader

View File

@@ -53,6 +53,7 @@ from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_otp.models import Device
from django_scopes import scopes_disabled
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
from pretix.base.i18n import language
from pretix.helpers.urls import build_absolute_uri
@@ -707,8 +708,6 @@ class U2FDevice(Device):
@property
def webauthndevice(self):
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
d = json.loads(self.json_data)
return PublicKeyCredentialDescriptor(websafe_decode(d['keyHandle']))
@@ -738,8 +737,6 @@ class WebAuthnDevice(Device):
@property
def webauthndevice(self):
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
return PublicKeyCredentialDescriptor(websafe_decode(self.credential_id))
@property

View File

@@ -22,6 +22,7 @@
import json
from collections import namedtuple
import jsonschema
from django.contrib.staticfiles import finders
from django.core.exceptions import ValidationError
from django.db import models
@@ -37,8 +38,6 @@ from pretix.base.models import Event, Item, LoggedModel, Organizer, SubEvent
@deconstructible
class SeatingPlanLayoutValidator:
def __call__(self, value):
import jsonschema
if not isinstance(value, dict):
try:
val = json.loads(value)

View File

@@ -23,6 +23,7 @@ import json
from decimal import Decimal
from typing import Optional
import jsonschema
from django.contrib.staticfiles import finders
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
@@ -297,8 +298,6 @@ def cc_to_vat_prefix(country_code):
@deconstructible
class CustomRulesValidator:
def __call__(self, value):
import jsonschema
if not isinstance(value, dict):
try:
val = json.loads(value)

View File

@@ -623,7 +623,7 @@ class Voucher(LoggedModel):
return max(1, self.min_usages - self.redeemed)
@classmethod
def annotate_budget_used(cls, qs):
def annotate_budget_used_orders(cls, qs):
opq = OrderPosition.objects.filter(
voucher_id=OuterRef('pk'),
voucher_budget_use__isnull=False,
@@ -632,7 +632,7 @@ class Voucher(LoggedModel):
Order.STATUS_PENDING
]
).order_by().values('voucher_id').annotate(s=Sum('voucher_budget_use')).values('s')
return qs.annotate(budget_used=Coalesce(Subquery(opq, output_field=models.DecimalField(max_digits=13, decimal_places=2)), Decimal('0.00')))
return qs.annotate(budget_used_orders=Coalesce(Subquery(opq, output_field=models.DecimalField(max_digits=13, decimal_places=2)), Decimal('0.00')))
def budget_used(self):
ops = OrderPosition.objects.filter(

View File

@@ -47,6 +47,7 @@ from collections import OrderedDict, defaultdict
from functools import partial
from io import BytesIO
import jsonschema
import pypdf
import pypdf.generic
import reportlab.rl_config
@@ -1310,8 +1311,6 @@ def _correct_page_media_box(page: pypdf.PageObject):
@deconstructible
class PdfLayoutValidator:
def __call__(self, value):
import jsonschema
if not isinstance(value, dict):
try:
val = json.loads(value)

View File

@@ -1361,11 +1361,6 @@ class CartManager:
deleted_positions.add(op.position.pk)
addons.delete()
op.position.delete()
if op.position.is_bundled:
deleted_positions |= {a.pk for a in op.position.addon_to.addons.all()}
deleted_positions.add(op.position.addon_to.pk)
op.position.addon_to.addons.all().delete()
op.position.addon_to.delete()
else:
raise AssertionError("ExtendOperation cannot affect more than one item")
elif isinstance(op, self.VoucherOperation):

View File

@@ -47,6 +47,7 @@ from urllib.parse import urljoin, urlparse
from zoneinfo import ZoneInfo
import requests
from bs4 import BeautifulSoup
from celery import chain
from celery.exceptions import MaxRetriesExceededError
from django.conf import settings
@@ -763,8 +764,6 @@ def render_mail(template, context, placeholder_mode=SafeFormatter.MODE_RICH_TO_P
def replace_images_with_cid_paths(body_html):
from bs4 import BeautifulSoup
if body_html:
email = BeautifulSoup(body_html, "lxml")
cid_images = []

View File

@@ -27,6 +27,7 @@ from decimal import Decimal
from xml.etree import ElementTree
import requests
import vat_moss.id
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from zeep import Client, Transport
@@ -41,142 +42,14 @@ logger = logging.getLogger(__name__)
error_messages = {
'unavailable': _(
'Your VAT ID could not be checked, as the VAT checking service of '
'your country is currently not available. We will therefore need to '
'charge you the same tax rate as if you did not enter a VAT ID.'
'your country is currently not available. We will therefore '
'need to charge VAT on your invoice. You can get the tax amount '
'back via the VAT reimbursement process.'
),
'invalid': _('This VAT ID is not valid. Please re-check your input.'),
'country_mismatch': _('Your VAT ID does not match the selected country.'),
}
VAT_ID_PATTERNS = {
# Patterns generated by consulting the following URLs:
#
# - http://en.wikipedia.org/wiki/VAT_identification_number
# - http://ec.europa.eu/taxation_customs/vies/faq.html
# - https://euipo.europa.eu/tunnel-web/secure/webdav/guest/document_library/Documents/COSME/VAT%20numbers%20EU.pdf
# - http://www.skatteetaten.no/en/International-pages/Felles-innhold-benyttes-i-flere-malgrupper/Brochure/Guide-to-value-added-tax-in-Norway/?chapter=7159
'AT': { # Austria
'regex': '^U\\d{8}$',
'country_code': 'AT'
},
'BE': { # Belgium
'regex': '^(1|0?)\\d{9}$',
'country_code': 'BE'
},
'BG': { # Bulgaria
'regex': '^\\d{9,10}$',
'country_code': 'BG'
},
'CH': { # Switzerland
'regex': '^\\dE{9}$',
'country_code': 'CH'
},
'CY': { # Cyprus
'regex': '^\\d{8}[A-Z]$',
'country_code': 'CY'
},
'CZ': { # Czech Republic
'regex': '^\\d{8,10}$',
'country_code': 'CZ'
},
'DE': { # Germany
'regex': '^\\d{9}$',
'country_code': 'DE'
},
'DK': { # Denmark
'regex': '^\\d{8}$',
'country_code': 'DK'
},
'EE': { # Estonia
'regex': '^\\d{9}$',
'country_code': 'EE'
},
'EL': { # Greece
'regex': '^\\d{9}$',
'country_code': 'GR'
},
'ES': { # Spain
'regex': '^[A-Z0-9]\\d{7}[A-Z0-9]$',
'country_code': 'ES'
},
'FI': { # Finland
'regex': '^\\d{8}$',
'country_code': 'FI'
},
'FR': { # France
'regex': '^[A-Z0-9]{2}\\d{9}$',
'country_code': 'FR'
},
'GB': { # United Kingdom
'regex': '^(GD\\d{3}|HA\\d{3}|\\d{9}|\\d{12})$',
'country_code': 'GB'
},
'HR': { # Croatia
'regex': '^\\d{11}$',
'country_code': 'HR'
},
'HU': { # Hungary
'regex': '^\\d{8}$',
'country_code': 'HU'
},
'IE': { # Ireland
'regex': '^(\\d{7}[A-Z]{1,2}|\\d[A-Z+*]\\d{5}[A-Z])$',
'country_code': 'IE'
},
'IT': { # Italy
'regex': '^\\d{11}$',
'country_code': 'IT'
},
'LT': { # Lithuania
'regex': '^(\\d{9}|\\d{12})$',
'country_code': 'LT'
},
'LU': { # Luxembourg
'regex': '^\\d{8}$',
'country_code': 'LU'
},
'LV': { # Latvia
'regex': '^\\d{11}$',
'country_code': 'LV'
},
'MT': { # Malta
'regex': '^\\d{8}$',
'country_code': 'MT'
},
'NL': { # Netherlands
'regex': '^\\d{9}B\\d{2}$',
'country_code': 'NL'
},
'NO': { # Norway
'regex': '^\\d{9}MVA$',
'country_code': 'NO'
},
'PL': { # Poland
'regex': '^\\d{10}$',
'country_code': 'PL'
},
'PT': { # Portugal
'regex': '^\\d{9}$',
'country_code': 'PT'
},
'RO': { # Romania
'regex': '^\\d{2,10}$',
'country_code': 'RO'
},
'SE': { # Sweden
'regex': '^\\d{12}$',
'country_code': 'SE'
},
'SI': { # Slovenia
'regex': '^\\d{8}$',
'country_code': 'SI'
},
'SK': { # Slovakia
'regex': '^\\d{10}$',
'country_code': 'SK'
},
}
class VATIDError(Exception):
def __init__(self, message):
@@ -191,57 +64,13 @@ class VATIDTemporaryError(VATIDError):
pass
def normalize_vat_id(vat_id, country_code):
"""
Accepts a VAT ID and normaizes it, getting rid of spaces, periods, dashes
etc and converting it to upper case.
Original function from https://github.com/wbond/vat_moss-python
Copyright (c) 2015 Will Bond <will@wbond.net>
MIT License
"""
if not vat_id:
return None
if not isinstance(vat_id, str):
raise TypeError('VAT ID is not a string')
if len(vat_id) < 3:
raise ValueError('VAT ID must be at least three character long')
# Normalize the ID for simpler regexes
vat_id = re.sub('\\s+', '', vat_id)
vat_id = vat_id.replace('-', '')
vat_id = vat_id.replace('.', '')
vat_id = vat_id.upper()
# Clean the different shapes a number can take in Switzerland depending on purpse
if country_code == "CH":
vat_id = re.sub('[^A-Z0-9]', '', vat_id.replace('HR', '').replace('MWST', ''))
# Fix people using GR prefix for Greece
if vat_id[0:2] == "GR" and country_code == "GR":
vat_id = "EL" + vat_id[2:]
# Check if we already have a valid country prefix. If not, we try to figure out if we can
# add one, since in some countries (e.g. Italy) it's very custom to enter it without the prefix
if vat_id[:2] in VAT_ID_PATTERNS and re.match(VAT_ID_PATTERNS[vat_id[0:2]]['regex'], vat_id[2:]):
# Prefix set and prefix matches pattern, nothing to do
pass
elif re.match(VAT_ID_PATTERNS[cc_to_vat_prefix(country_code)]['regex'], vat_id):
# Prefix not set but adding it fixes pattern
vat_id = cc_to_vat_prefix(country_code) + vat_id
else:
# We have no idea what this is
pass
return vat_id
def _validate_vat_id_NO(vat_id, country_code):
# Inspired by vat_moss library
if not vat_id.startswith("NO"):
# prefix is not usually used in Norway, but expected by vat_moss library
vat_id = "NO" + vat_id
try:
vat_id = normalize_vat_id(vat_id, country_code)
vat_id = vat_moss.id.normalize(vat_id)
except ValueError:
raise VATIDFinalError(error_messages['invalid'])
@@ -275,7 +104,7 @@ def _validate_vat_id_NO(vat_id, country_code):
def _validate_vat_id_EU(vat_id, country_code):
# Inspired by vat_moss library
try:
vat_id = normalize_vat_id(vat_id, country_code)
vat_id = vat_moss.id.normalize(vat_id)
except ValueError:
raise VATIDFinalError(error_messages['invalid'])
@@ -283,10 +112,11 @@ def _validate_vat_id_EU(vat_id, country_code):
raise VATIDFinalError(error_messages['invalid'])
number = vat_id[2:]
if vat_id[:2] != cc_to_vat_prefix(country_code):
raise VATIDFinalError(error_messages['country_mismatch'])
if not re.match(VAT_ID_PATTERNS[cc_to_vat_prefix(country_code)]['regex'], number):
if not re.match(vat_moss.id.ID_PATTERNS[cc_to_vat_prefix(country_code)]['regex'], number):
raise VATIDFinalError(error_messages['invalid'])
# We are relying on the country code of the normalized VAT-ID and not the user/InvoiceAddress-provided
@@ -345,12 +175,9 @@ def _validate_vat_id_EU(vat_id, country_code):
def _validate_vat_id_CH(vat_id, country_code):
if vat_id[:3] != 'CHE':
raise VATIDFinalError(error_messages['country_mismatch'])
raise VATIDFinalError(_('Your VAT ID does not match the selected country.'))
try:
vat_id = normalize_vat_id(vat_id, country_code)
except ValueError:
raise VATIDFinalError(error_messages['invalid'])
vat_id = re.sub('[^A-Z0-9]', '', vat_id.replace('HR', '').replace('MWST', ''))
try:
transport = Transport(
cache=SqliteCache(os.path.join(settings.CACHE_DIR, "validate_vat_id_ch_zeep_cache.db")),

View File

@@ -113,11 +113,6 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
lock_objects(quotas, shared_lock_objects=[event])
for wle in qs:
# add this event to wle.item as it is not yet cached and is needed in check_quotas
wle.item.event = event
if wle.variation:
wle.variation.item = wle.item
if (wle.item_id, wle.variation_id, wle.subevent_id) in gone:
continue
ev = (wle.subevent or event)

View File

@@ -629,40 +629,13 @@ DEFAULTS = {
'form_kwargs': dict(
label=_("Ask for VAT ID"),
help_text=format_lazy(
_("Only works if an invoice address is asked for. VAT ID is only requested from business customers "
"in the following countries: {countries}."),
_("Only works if an invoice address is asked for. VAT ID is never required and only requested from "
"business customers in the following countries: {countries}"),
countries=lazy(lambda *args: ', '.join(sorted(gettext(Country(cc).name) for cc in VAT_ID_COUNTRIES)), str)()
),
widget=forms.CheckboxInput(attrs={'data-checkbox-dependency': '#id_invoice_address_asked'}),
)
},
'invoice_address_vatid_required_countries': {
'default': ['IT', 'GR'],
'type': list,
'form_class': forms.MultipleChoiceField,
'serializer_class': serializers.MultipleChoiceField,
'serializer_kwargs': dict(
choices=lazy(
lambda *args: sorted([(cc, gettext(Country(cc).name)) for cc in VAT_ID_COUNTRIES], key=lambda c: c[1]),
list
)(),
),
'form_kwargs': dict(
label=_("Require VAT ID in"),
choices=lazy(
lambda *args: sorted([(cc, gettext(Country(cc).name)) for cc in VAT_ID_COUNTRIES], key=lambda c: c[1]),
list
)(),
help_text=format_lazy(
_("VAT ID is optional by default, because not all businesses are assigned a VAT ID in all countries. "
"VAT ID will be required for all business addresses in the selected countries."),
),
widget=forms.CheckboxSelectMultiple(attrs={
"class": "scrolling-multiple-choice",
'data-display-dependency': '#id_invoice_address_vatid'
}),
)
},
'invoice_address_explanation_text': {
'default': '',
'type': LazyI18nString,

View File

@@ -93,9 +93,7 @@ def timeline_for_event(event, subevent=None):
description=format_lazy(
'{} ({})',
pgettext_lazy('timeline', 'End of ticket sales'),
pgettext_lazy('timeline', 'automatically because the event is over and no end of presale has been configured')
) if not ev.presale_end else (
pgettext_lazy('timeline', 'End of ticket sales')
pgettext_lazy('timeline', 'automatically because the event is over and no end of presale has been configured') if not ev.presale_end else ""
),
edit_url=ev_edit_url + '#id_presale_end_0'
))

View File

@@ -22,7 +22,7 @@
import pycountry
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext, pgettext, pgettext_lazy
from django.utils.translation import pgettext
from django_countries.fields import Country
from django_scopes import scope
@@ -36,22 +36,6 @@ from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
)
VAT_ID_LABELS = {
# VAT ID is a EU concept and Switzerland has a distinct, but differently-named concept
"CH": pgettext_lazy("tax_id_swiss", "UID"), # Translators: Only translate to French (IDE) and Italien (IDI), otherwise keep the same
# Awareness around VAT IDs differes by EU country. For example, in Germany the VAT ID is assigned
# separately to each company and only used in cross-country transactions. Therefore, it makes sense
# to call it just "VAT ID" on the form, and people will either know their VAT ID or they don't.
# In contrast, in Italy the EU-compatible VAT ID is not separately assigned, but is just "IT" + the national tax
# number (Partita IVA) and also used on domestic transactions. So someone who never purchased something international
# for their company, might still know the value, if we call it the right way and not just "VAT ID".
"IT": pgettext_lazy("tax_id_italy", "VAT ID / P.IVA"), # Translators: Translate to only "P.IVA" in Italian, keep second part as-is in other languages
"GR": pgettext_lazy("tax_id_greece", "VAT ID / TIN"), # Translators: Translate to only "ΑΦΜ" in Greek
"ES": pgettext_lazy("tax_id_spain", "VAT ID / NIF"), # Translators: Translate to only "NIF" in Spanish
"PT": pgettext_lazy("tax_id_portugal", "VAT ID / NIF"), # Translators: Translate to only "NIF" in Portuguese
}
def _info(cc):
info = {
@@ -63,12 +47,7 @@ def _info(cc):
'required': 'if_any' if cc in COUNTRIES_WITH_STATE_IN_ADDRESS else False,
'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')),
},
'vat_id': {
'visible': cc in VAT_ID_COUNTRIES,
'required': False,
'label': VAT_ID_LABELS.get(cc, gettext("VAT ID")),
'helptext_visible': True,
},
'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False},
}
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
return {'data': [], **info}
@@ -145,10 +124,4 @@ def address_form(request):
"required": transmission_type.identifier == selected_transmission_type and k in required
}
if is_business and country in event.settings.invoice_address_vatid_required_countries and info["vat_id"]["visible"]:
info["vat_id"]["required"] = True
if info["vat_id"]["required"]:
# The help text explains that it is optional, so we want to hide that if it is required
info["vat_id"]["helptext_visible"] = False
return JsonResponse(info)

View File

@@ -207,7 +207,6 @@ class EventWizardBasicsForm(I18nModelForm):
'Sample Conference Center\nHeidelberg, Germany'
)
self.fields['slug'].widget.prefix = build_absolute_uri(self.organizer, 'presale:organizer.index')
self.fields['tax_rate']._required = True # Do not render as optional because it is conditionally required
if self.has_subevents:
del self.fields['presale_start']
del self.fields['presale_end']
@@ -928,7 +927,6 @@ class InvoiceSettingsForm(EventSettingsValidationMixin, SettingsForm):
'invoice_address_asked',
'invoice_address_required',
'invoice_address_vatid',
'invoice_address_vatid_required_countries',
'invoice_address_company_required',
'invoice_address_beneficiary',
'invoice_address_custom_field',
@@ -1959,13 +1957,6 @@ class EventFooterLinkForm(I18nModelForm):
class Meta:
model = EventFooterLink
fields = ('label', 'url')
widgets = {
"url": forms.URLInput(
attrs={
"placeholder": "https://..."
}
)
}
class BaseEventFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):

View File

@@ -974,7 +974,7 @@ class EventCancelForm(FormPlaceholderMixin, forms.Form):
self._set_field_placeholders('send_subject', ['event_or_subevent', 'refund_amount', 'position_or_address',
'order', 'event'])
self._set_field_placeholders('send_message', ['event_or_subevent', 'refund_amount', 'position_or_address',
'order', 'event'], rich=True)
'order', 'event'])
self.fields['send_waitinglist_subject'] = I18nFormField(
label=_("Subject"),
required=True,
@@ -998,7 +998,7 @@ class EventCancelForm(FormPlaceholderMixin, forms.Form):
))
)
self._set_field_placeholders('send_waitinglist_subject', ['event_or_subevent', 'event'])
self._set_field_placeholders('send_waitinglist_message', ['event_or_subevent', 'event'], rich=True)
self._set_field_placeholders('send_waitinglist_message', ['event_or_subevent', 'event'])
if self.event.has_subevents:
self.fields['subevent'].queryset = self.event.subevents.all()

View File

@@ -1024,13 +1024,6 @@ class OrganizerFooterLinkForm(I18nModelForm):
class Meta:
model = OrganizerFooterLink
fields = ('label', 'url')
widgets = {
"url": forms.URLInput(
attrs={
"placeholder": "https://..."
}
)
}
class BaseOrganizerFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):

View File

@@ -43,7 +43,6 @@
{% bootstrap_field form.invoice_name_required layout="control" %}
{% bootstrap_field form.invoice_address_company_required layout="control" %}
{% bootstrap_field form.invoice_address_vatid layout="control" %}
{% bootstrap_field form.invoice_address_vatid_required_countries layout="control" %}
{% bootstrap_field form.invoice_address_beneficiary layout="control" %}
{% bootstrap_field form.invoice_address_not_asked_free layout="control" %}
{% bootstrap_field form.invoice_address_custom_field layout="control" %}

View File

@@ -165,7 +165,7 @@
{% if v.budget|default_if_none:"NONE" != "NONE" %}
<br>
<small class="text-muted">
{{ v.budget_used|money:request.event.currency }} / {{ v.budget|money:request.event.currency }}
{{ v.budget_used_orders|money:request.event.currency }} / {{ v.budget|money:request.event.currency }}
</small>
{% endif %}
</td>

View File

@@ -60,6 +60,7 @@ from pretix.base.models import (
)
from pretix.base.services.quotas import QuotaAvailability
from pretix.base.timeline import timeline_for_event
from pretix.control.forms.event import CommentForm
from pretix.control.signals import (
event_dashboard_widgets, user_dashboard_widgets,
)
@@ -340,8 +341,6 @@ def welcome_wizard_widget(sender, **kwargs):
def event_index(request, organizer, event):
from pretix.control.forms.event import CommentForm
subevent = None
if request.GET.get("subevent", "") != "" and request.event.has_subevents:
i = request.GET.get("subevent", "")

View File

@@ -98,6 +98,7 @@ from pretix.control.views.mailsetup import MailSettingsSetupView
from pretix.control.views.user import RecentAuthenticationRequiredMixin
from pretix.helpers.database import rolledback_transaction
from pretix.multidomain.urlreverse import build_absolute_uri, get_event_domain
from pretix.plugins.stripe.payment import StripeSettingsHolder
from pretix.presale.views.widget import (
version_default as widget_version_default,
)
@@ -1665,8 +1666,6 @@ class QuickSetupView(FormView):
'or take your event live to start selling!'))
if form.cleaned_data.get('payment_stripe__enabled', False):
from pretix.plugins.stripe.payment import StripeSettingsHolder
self.request.session['payment_stripe_oauth_enable'] = True
return redirect(StripeSettingsHolder(self.request.event).get_connect_url(self.request))

View File

@@ -146,7 +146,7 @@ class BaseProcessView(AsyncAction, FormView):
else:
charset = None
try:
reader = parse_csv(self.file.file, 1024 * 1024, charset=charset)
return parse_csv(self.file.file, 1024 * 1024, charset=charset)
except UnicodeDecodeError:
messages.warning(
self.request,
@@ -155,16 +155,7 @@ class BaseProcessView(AsyncAction, FormView):
"Some characters were replaced with a placeholder."
)
)
reader = parse_csv(self.file.file, 1024 * 1024, "replace", charset=charset)
if reader and reader._had_duplicates:
messages.warning(
self.request,
_(
"Multiple columns of the CSV file have the same name and were renamed automatically. We "
"recommend that you rename these in your source file to avoid problems during import."
)
)
return reader
return parse_csv(self.file.file, 1024 * 1024, "replace", charset=charset)
@cached_property
def parsed_list(self):

View File

@@ -87,7 +87,7 @@ class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView):
@scopes_disabled() # we have an event check here, and we can save some performance on subqueries
def get_queryset(self):
qs = Voucher.annotate_budget_used(self.request.event.vouchers.exclude(
qs = Voucher.annotate_budget_used_orders(self.request.event.vouchers.exclude(
Exists(WaitingListEntry.objects.filter(voucher_id=OuterRef('pk')))
).select_related(
'item', 'variation', 'seat'

View File

@@ -1,210 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# 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/>.
#
from urllib.parse import quote, urlencode
import text_unidecode
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
def dotdecimal(value):
return str(value).replace(",", ".")
def commadecimal(value):
return str(value).replace(".", ",")
def generate_payment_qr_codes(
event,
code,
amount,
bank_details_sepa_bic,
bank_details_sepa_name,
bank_details_sepa_iban,
):
out = []
for method in [
swiss_qrbill,
czech_spayd,
euro_epc_qr,
euro_bezahlcode,
]:
data = method(
event,
code,
amount,
bank_details_sepa_bic,
bank_details_sepa_name,
bank_details_sepa_iban,
)
if data:
out.append(data)
return out
def euro_epc_qr(
event,
code,
amount,
bank_details_sepa_bic,
bank_details_sepa_name,
bank_details_sepa_iban,
):
if event.currency != 'EUR' or not bank_details_sepa_iban:
return
return {
"id": "girocode",
"label": "EPC-QR",
"qr_data": "\n".join(text_unidecode.unidecode(str(d or '')) for d in [
"BCD", # Service Tag: BCD
"002", # Version: V2
"2", # Character set: ISO 8859-1
"SCT", # Identification code: SCT
bank_details_sepa_bic, # AT-23 BIC of the Beneficiary Bank
bank_details_sepa_name, # AT-21 Name of the Beneficiary
bank_details_sepa_iban, # AT-20 Account number of the Beneficiary
f"{event.currency}{dotdecimal(amount)}", # AT-04 Amount of the Credit Transfer in Euro
"", # AT-44 Purpose of the Credit Transfer
"", # AT-05 Remittance Information (Structured)
code, # AT-05 Remittance Information (Unstructured)
"", # Beneficiary to originator information
"",
]),
}
def euro_bezahlcode(
event,
code,
amount,
bank_details_sepa_bic,
bank_details_sepa_name,
bank_details_sepa_iban,
):
if not bank_details_sepa_iban or bank_details_sepa_iban[:2] != 'DE':
return
if event.currency != 'EUR':
return
qr_data = "bank://singlepaymentsepa?" + urlencode({
"name": str(bank_details_sepa_name),
"iban": str(bank_details_sepa_iban),
"bic": str(bank_details_sepa_bic),
"amount": commadecimal(amount),
"reason": str(code),
"currency": str(event.currency),
}, quote_via=quote)
return {
"id": "bezahlcode",
"label": "BezahlCode",
"qr_data": mark_safe(qr_data),
"link": qr_data,
"link_aria_label": _("Open BezahlCode in your banking app to start the payment process."),
}
def swiss_qrbill(
event,
code,
amount,
bank_details_sepa_bic,
bank_details_sepa_name,
bank_details_sepa_iban,
):
if not bank_details_sepa_iban or not bank_details_sepa_iban[:2] in ('CH', 'LI'):
return
if event.currency not in ('EUR', 'CHF'):
return
if not event.settings.invoice_address_from or not event.settings.invoice_address_from_country:
return
data_fields = [
'SPC',
'0200',
'1',
bank_details_sepa_iban,
'K',
bank_details_sepa_name[:70],
event.settings.invoice_address_from.replace('\n', ', ')[:70],
(event.settings.invoice_address_from_zipcode + ' ' + event.settings.invoice_address_from_city)[:70],
'',
'',
str(event.settings.invoice_address_from_country),
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
str(amount),
event.currency,
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'NON',
'', # structured reference
code,
'EPD',
]
data_fields = [text_unidecode.unidecode(d or '') for d in data_fields]
qr_data = '\r\n'.join(data_fields)
return {
"id": "qrbill",
"label": "QR-bill",
"html_prefix": mark_safe(
'<svg class="banktransfer-swiss-cross" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.8 19.8">'
'<path stroke="#fff" stroke-width="1.436" d="M.7.7h18.4v18.4H.7z"/><path fill="#fff" d="M8.3 4h3.3v11H8.3z"/>'
'<path fill="#fff" d="M4.4 7.9h11v3.3h-11z"/></svg>'
),
"qr_data": qr_data,
"css_class": "banktransfer-swiss-cross-overlay",
}
def czech_spayd(
event,
code,
amount,
bank_details_sepa_bic,
bank_details_sepa_name,
bank_details_sepa_iban,
):
if not bank_details_sepa_iban or not bank_details_sepa_iban[:2] in ('CZ', 'SK'):
return
if event.currency not in ('EUR', 'CZK'):
return
qr_data = f"SPD*1.0*ACC:{bank_details_sepa_iban}*AM:{dotdecimal(amount)}*CC:{event.currency}*MSG:{code}"
return {
"id": "spayd",
"label": "SPAYD",
"qr_data": qr_data,
}

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: 2025-11-20 10:37+0000\n"
"PO-Revision-Date: 2025-12-03 23:00+0000\n"
"Last-Translator: sandra r <sandrarial@gestiontickets.online>\n"
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/"
"pretix-js/gl/>\n"
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
"js/gl/>\n"
"Language: gl\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.14.3\n"
"X-Generator: Weblate 4.8\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -31,104 +31,106 @@ msgstr "Comentario:"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
msgid "PayPal"
msgstr "PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
msgid "Venmo"
msgstr "Venmo"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
#: pretix/static/pretixpresale/js/walletdetection.js:38
msgid "Apple Pay"
msgstr "Apple Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
msgid "Itaú"
msgstr "Itaú"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
msgid "PayPal Credit"
msgstr "Crédito PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
msgid "Credit Card"
msgstr "Tarxeta de crédito"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
msgid "PayPal Pay Later"
msgstr "PayPal Pagar Máis Tarde"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
msgid "iDEAL"
msgstr "iDEAL"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
msgid "SEPA Direct Debit"
msgstr "Débito directo SEPA"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
msgid "Bancontact"
msgstr "Bancontact"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:44
msgid "giropay"
msgstr "giropay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
msgid "SOFORT"
msgstr "SOFORT"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
#, fuzzy
#| msgid "Yes"
msgid "eps"
msgstr "Si"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
msgid "MyBank"
msgstr "MyBank"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
msgid "Przelewy24"
msgstr "Przelewy24"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
msgid "Verkkopankki"
msgstr "Verkkopankki"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
msgid "PayU"
msgstr "PayU"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
msgid "BLIK"
msgstr "BLIK"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
msgid "Trustly"
msgstr "De confianza"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
msgid "Zimpler"
msgstr "Zimpler"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
msgid "Maxima"
msgstr "Máxima"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
msgid "OXXO"
msgstr "OXXO"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
msgid "Boleto"
msgstr "Ticket"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
msgid "WeChat Pay"
msgstr "Pagar con WeChat"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
msgid "Mercado Pago"
msgstr "Mercado Pago"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:167
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:50
@@ -147,7 +149,7 @@ msgstr "Confirmando o pagamento…"
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
msgid "Payment method unavailable"
msgstr "O método de pago non está dispoñible"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
@@ -238,11 +240,11 @@ msgstr "Cancelado"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
msgid "Confirmed"
msgstr "Confirmado"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
msgid "Approval pending"
msgstr "Aprobación pendente"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Redeemed"
@@ -298,12 +300,16 @@ msgid "Ticket code revoked/changed"
msgstr "Código de tícket revogado/cambiado"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
#, fuzzy
#| msgid "Ticket not paid"
msgid "Ticket blocked"
msgstr "Ticket bloqueado"
msgstr "Tícket pendente de pago"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
#, fuzzy
#| msgid "Ticket not paid"
msgid "Ticket not valid at this time"
msgstr "O ticket non é válido neste momento"
msgstr "cket pendente de pago"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
msgid "Order canceled"
@@ -311,11 +317,11 @@ msgstr "Pedido cancelado"
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
msgid "Ticket code is ambiguous on list"
msgstr "O código do ticket é ambiguo na lista"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
msgid "Order not approved"
msgstr "Orde non aprobada"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:68
msgid "Checked-in Tickets"
@@ -416,7 +422,7 @@ msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:276
msgid "If this takes longer than a few minutes, please contact us."
msgstr "Se isto leva máis duns minutos, póñase en contacto connosco."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:331
msgid "Close message"
@@ -446,7 +452,7 @@ msgstr "está despois"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
msgid "="
msgstr "="
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
msgid "Product"
@@ -458,7 +464,7 @@ msgstr "Ver variacións do produto"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
msgid "Gate"
msgstr "Porta"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
msgid "Current date and time"
@@ -466,11 +472,11 @@ msgstr "Data e hora actual"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
msgstr "Día actual da semana (1 = luns, 7 = domingo)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
msgid "Current entry status"
msgstr "Estado de entrada actual"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
msgid "Number of previous entries"
@@ -481,32 +487,40 @@ msgid "Number of previous entries since midnight"
msgstr "Número de entradas previas desde a medianoite"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
#, fuzzy
#| msgid "Number of previous entries"
msgid "Number of previous entries since"
msgstr "Número de entradas anteriores desde"
msgstr "Número de entradas previas"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
#, fuzzy
#| msgid "Number of previous entries"
msgid "Number of previous entries before"
msgstr "Número de entradas anteriores antes de"
msgstr "Número de entradas previas"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:139
msgid "Number of days with a previous entry"
msgstr "Número de días cunha entrada previa"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
#, fuzzy
#| msgid "Number of days with a previous entry"
msgid "Number of days with a previous entry since"
msgstr "Número de días cunha entrada previa desde"
msgstr "Número de días cunha entrada previa"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
#, fuzzy
#| msgid "Number of days with a previous entry"
msgid "Number of days with a previous entry before"
msgstr "Número de días cunha entrada previa"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
msgid "Minutes since last entry (-1 on first entry)"
msgstr "Minutos desde a última entrada (-1 na primeira entrada)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:155
msgid "Minutes since first entry (-1 on first entry)"
msgstr "Minutos desde a primeira entrada (-1 na primeira entrada)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:182
msgid "All of the conditions below (AND)"
@@ -550,25 +564,25 @@ msgstr "minutos"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
msgid "Duplicate"
msgstr "Duplicar"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
msgctxt "entry_status"
msgid "present"
msgstr "presente"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
msgctxt "entry_status"
msgid "absent"
msgstr "ausente"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
msgid "Error: Product not found!"
msgstr "Erro: Non se atopou o produto!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
msgid "Error: Variation not found!"
msgstr "Erro: Variación non atopada!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:171
msgid "Check-in QR"
@@ -583,12 +597,16 @@ msgid "Group of objects"
msgstr "Grupo de obxectos"
#: pretix/static/pretixcontrol/js/ui/editor.js:909
#, fuzzy
#| msgid "Text object"
msgid "Text object (deprecated)"
msgstr "Obxecto de texto (obsoleto)"
msgstr "Obxecto de texto"
#: pretix/static/pretixcontrol/js/ui/editor.js:911
#, fuzzy
#| msgid "Text object"
msgid "Text box"
msgstr "Caixa de texto"
msgstr "Obxecto de texto"
#: pretix/static/pretixcontrol/js/ui/editor.js:913
msgid "Barcode area"
@@ -637,26 +655,26 @@ msgid "Unknown error."
msgstr "Erro descoñecido."
#: pretix/static/pretixcontrol/js/ui/main.js:309
#, fuzzy
#| msgid "Your color has great contrast and is very easy to read!"
msgid "Your color has great contrast and will provide excellent accessibility."
msgstr ""
"A túa cor ten un gran contraste e proporcionará unha excelente "
"accesibilidade."
msgstr "A túa cor ten moito contraste e é moi doada de ler!"
#: pretix/static/pretixcontrol/js/ui/main.js:313
#, fuzzy
#| msgid "Your color has decent contrast and is probably good-enough to read!"
msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility "
"requirements."
msgstr ""
"A túa cor ten un contraste decente e é suficiente para os requisitos mínimos "
"de accesibilidade."
"A túa cor ten un contraste axeitado e probablemente sexa suficientemente "
"lexible!"
#: pretix/static/pretixcontrol/js/ui/main.js:317
msgid ""
"Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted."
msgstr ""
"A túa cor non ten suficiente contraste co branco. A accesibilidade do teu "
"sitio web verase afectada."
#: pretix/static/pretixcontrol/js/ui/main.js:443
#: pretix/static/pretixcontrol/js/ui/main.js:463
@@ -677,11 +695,11 @@ msgstr "Soamente seleccionados"
#: pretix/static/pretixcontrol/js/ui/main.js:839
msgid "Enter page number between 1 and %(max)s."
msgstr "Introduza o número de páxina entre 1 e %(max)s."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842
msgid "Invalid page number."
msgstr "Número de páxina non válido."
msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1000
msgid "Use a different name internally"
@@ -700,8 +718,10 @@ msgid "Calculating default price…"
msgstr "Calculando o prezo por defecto…"
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
#, fuzzy
#| msgid "Search results"
msgid "No results"
msgstr "Sen resultados"
msgstr "Resultados da procura"
#: pretix/static/pretixcontrol/js/ui/question.js:41
msgid "Others"
@@ -732,7 +752,7 @@ msgstr "O carro da compra caducou"
#: pretix/static/pretixpresale/js/ui/cart.js:58
#: pretix/static/pretixpresale/js/ui/cart.js:84
msgid "Your cart is about to expire."
msgstr "O teu carriño está a piques de caducar."
msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:62
msgid "The items in your cart are reserved for you for one minute."
@@ -742,10 +762,16 @@ msgstr[1] ""
"Os artigos da túa cesta están reservados para ti durante {num} minutos."
#: pretix/static/pretixpresale/js/ui/cart.js:83
#, fuzzy
#| msgid "Cart expired"
msgid "Your cart has expired."
msgstr "O carro da compra caducou."
msgstr "O carro da compra caducou"
#: pretix/static/pretixpresale/js/ui/cart.js:86
#, fuzzy
#| msgid ""
#| "The items in your cart are no longer reserved for you. You can still "
#| "complete your order as long as theyre available."
msgid ""
"The items in your cart are no longer reserved for you. You can still "
"complete your order as long as they're available."
@@ -755,11 +781,11 @@ msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:87
msgid "Do you want to renew the reservation period?"
msgstr "Queres renovar o período de reserva?"
msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:90
msgid "Renew reservation"
msgstr "Renovar reserva"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:194
msgid "The organizer keeps %(currency)s %(amount)s"
@@ -779,66 +805,71 @@ msgstr "A súa hora local:"
#: pretix/static/pretixpresale/js/walletdetection.js:39
msgid "Google Pay"
msgstr "Google Pay"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:16
msgctxt "widget"
msgid "Quantity"
msgstr "Cantidade"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:17
msgctxt "widget"
msgid "Decrease quantity"
msgstr "Diminuír a cantidade"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:18
msgctxt "widget"
msgid "Increase quantity"
msgstr "Aumentar a cantidade"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:19
msgctxt "widget"
msgid "Filter events by"
msgstr "Filtrar eventos por"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:20
msgctxt "widget"
msgid "Filter"
msgstr "Filtro"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:21
msgctxt "widget"
msgid "Price"
msgstr "Prezo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:22
#, javascript-format
msgctxt "widget"
msgid "Original price: %s"
msgstr "Prezo orixinal: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:23
#, javascript-format
msgctxt "widget"
msgid "New price: %s"
msgstr "Novo prezo: %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:24
#, fuzzy
#| msgid "Selected only"
msgctxt "widget"
msgid "Select"
msgstr "Seleccione"
msgstr "Soamente seleccionados"
#: pretix/static/pretixpresale/js/widget/widget.js:25
#, javascript-format
#, fuzzy, javascript-format
#| msgid "Selected only"
msgctxt "widget"
msgid "Select %s"
msgstr "Seleccione %s"
msgstr "Soamente seleccionados"
#: pretix/static/pretixpresale/js/widget/widget.js:26
#, javascript-format
#, fuzzy, javascript-format
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Select variant %s"
msgstr "Seleccione a variante %s"
msgstr "Ver variacións"
#: pretix/static/pretixpresale/js/widget/widget.js:27
msgctxt "widget"
@@ -874,7 +905,7 @@ msgstr "dende %(currency)s %(price)s"
#, javascript-format
msgctxt "widget"
msgid "Image of %s"
msgstr "Imaxe de %s"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:34
msgctxt "widget"
@@ -909,19 +940,25 @@ msgstr "Só dispoñible mediante vale"
#: pretix/static/pretixpresale/js/widget/widget.js:40
#: pretix/static/pretixpresale/js/widget/widget.js:43
#, fuzzy
#| msgctxt "widget"
#| msgid "currently available: %s"
msgctxt "widget"
msgid "Not yet available"
msgstr "Aínda non dispoñible"
msgstr "dispoñible actualmente: %s"
#: pretix/static/pretixpresale/js/widget/widget.js:41
msgctxt "widget"
msgid "Not available anymore"
msgstr "Xa non está dispoñible"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:42
#, fuzzy
#| msgctxt "widget"
#| msgid "currently available: %s"
msgctxt "widget"
msgid "Currently not available"
msgstr "Non dispoñible actualmente"
msgstr "dispoñible actualmente: %s"
#: pretix/static/pretixpresale/js/widget/widget.js:44
#, javascript-format
@@ -954,6 +991,9 @@ msgid "Open ticket shop"
msgstr "Abrir a tenda de tíckets"
#: pretix/static/pretixpresale/js/widget/widget.js:50
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Checkout"
msgstr "Continuar co pagamento"
@@ -1013,14 +1053,17 @@ msgid "Close"
msgstr "Cerrar"
#: pretix/static/pretixpresale/js/widget/widget.js:62
#, fuzzy
#| msgctxt "widget"
#| msgid "Resume checkout"
msgctxt "widget"
msgid "Close checkout"
msgstr "Pagamento pechado"
msgstr "Continuar co pagamento"
#: pretix/static/pretixpresale/js/widget/widget.js:63
msgctxt "widget"
msgid "You cannot cancel this operation. Please wait for loading to finish."
msgstr "Non podes cancelar esta operación. Agarda a que remate a carga."
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:64
msgctxt "widget"
@@ -1028,14 +1071,20 @@ msgid "Continue"
msgstr "Continuar"
#: pretix/static/pretixpresale/js/widget/widget.js:65
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Show variants"
msgstr "Ver variacións"
#: pretix/static/pretixpresale/js/widget/widget.js:66
#, fuzzy
#| msgctxt "widget"
#| msgid "See variations"
msgctxt "widget"
msgid "Hide variants"
msgstr "Ocultar variantes"
msgstr "Ver variacións"
#: pretix/static/pretixpresale/js/widget/widget.js:67
msgctxt "widget"
@@ -1084,9 +1133,6 @@ msgid ""
"add yourself to the waiting list. We will then notify if seats are available "
"again."
msgstr ""
"Algunhas ou todas as categorías de entradas están esgotadas. Se queres, "
"podes engadirte á lista de espera. Despois avisarémosche se volven quedar "
"asentos dispoñibles."
#: pretix/static/pretixpresale/js/widget/widget.js:76
msgctxt "widget"
@@ -1123,31 +1169,31 @@ msgstr "Dom"
#: pretix/static/pretixpresale/js/widget/widget.js:85
msgid "Monday"
msgstr "Luns"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:86
msgid "Tuesday"
msgstr "Martes"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:87
msgid "Wednesday"
msgstr "Mércores"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:88
msgid "Thursday"
msgstr "Xoves"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:89
msgid "Friday"
msgstr "Venres"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:90
msgid "Saturday"
msgstr "Sábado"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:91
msgid "Sunday"
msgstr "Domingo"
msgstr ""
#: pretix/static/pretixpresale/js/widget/widget.js:94
msgid "January"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-05 18:00+0000\n"
"PO-Revision-Date: 2025-11-26 17:00+0000\n"
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
"ja/>\n"
@@ -2149,7 +2149,7 @@ msgstr "クライアントID"
#: pretix/base/exporters/items.py:91 pretix/base/models/items.py:667
#: pretix/base/models/items.py:1168
msgid "Original price"
msgstr "通常価格"
msgstr "元の価格"
#: pretix/base/exporters/items.py:92 pretix/base/models/items.py:684
msgid "This product is a gift card"
@@ -22741,8 +22741,9 @@ msgid ""
"This position has been created with a voucher with a limited budget. If you "
"change the price or item, the discount will still be calculated from the "
"original price at the time of purchase."
msgstr "このポジションは限られた予算のバウチャーで作成されました。価格やアイテムを変"
"更しても、割引は購入時の通常価格から計算されます。"
msgstr ""
"このポジションは限られた予算のバウチャーで作成されました。価格やアイテムを変"
"更しても、割引は購入時の元の価格から計算されます。"
#: pretix/control/templates/pretixcontrol/order/change.html:101
#: pretix/control/templates/pretixcontrol/order/change.html:413
@@ -33769,7 +33770,7 @@ msgstr "バリエーションを表示する"
#: pretix/presale/templates/pretixpresale/event/voucher.html:147
#: pretix/presale/templates/pretixpresale/event/voucher.html:304
msgid "Original price:"
msgstr "通常価格:"
msgstr "元の価格:"
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:136
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:278

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-03 23:00+0000\n"
"Last-Translator: SJang1 <git@sjang.dev>\n"
"PO-Revision-Date: 2025-11-18 17:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/ko/"
">\n"
"Language: ko\n"
@@ -290,27 +290,33 @@ msgstr "묶음 상품은 그 자체로 또 다른 묶음을 포함 할 수 없
#: pretix/api/serializers/item.py:235
msgid "The program start must not be empty."
msgstr "프로그램 시작일정은 비어 있어서는 안 됩니다."
msgstr ""
#: pretix/api/serializers/item.py:239
msgid "The program end must not be empty."
msgstr "프로그램 종료일정은 비어 있어서는 안 됩니다."
msgstr ""
#: pretix/api/serializers/item.py:242 pretix/base/models/items.py:2321
#, fuzzy
#| msgid "The maximum date must not be before the minimum value."
msgid "The program end must not be before the program start."
msgstr "종료일은 시작일보다 앞서면 안됩니다."
msgstr "종료일(최대 날짜)은 시작일(최소값)보다 앞서면 안됩니다."
#: pretix/api/serializers/item.py:247 pretix/base/models/items.py:2315
#, fuzzy
#| msgid "You can not select a subevent if your event is not an event series."
msgid "You cannot use program times on an event series."
msgstr "이벤트 시리즈에 있는 시간은 사용하실 수 없습니다."
msgstr ""
"당신의이벤트가 이벤트 시리즈가 아닌 경우 하위 이벤트를 선택할 수 없습니다."
#: pretix/api/serializers/item.py:337
#, fuzzy
msgid ""
"Updating add-ons, bundles, program times or variations via PATCH/PUT is not "
"supported. Please use the dedicated nested endpoint."
msgstr ""
"추가 기능, 묶음 상품들, 또는 변형은 PATCH/PUT를 통해 업데이트 할 수 없습니다."
" 전용 중첩은 마지막 지점에서 사용하세요."
"추가 기능, 묶음 상품들, 또는 변형은 PATCH/PUT를 통해 업데이트 할 수 없습니"
"다. 전용 중첩은 마지막 지점에서 사용하세요"
#: pretix/api/serializers/item.py:345
msgid "Only admission products can currently be personalized."
@@ -567,15 +573,22 @@ msgid "Event series date deleted"
msgstr "이벤트 시리즈 날짜 삭제"
#: pretix/api/webhooks.py:374
#, fuzzy
#| msgid "Product name"
msgid "Product changed"
msgstr "제품 변경됨"
msgstr "제품"
#: pretix/api/webhooks.py:375
#, fuzzy
#| msgid ""
#| "Product changed (including product added or deleted and including changes "
#| "to nested objects like variations or bundles)"
msgid ""
"This includes product added or deleted and changes to nested objects like "
"variations or bundles."
msgstr "여기에는 추가되거나 삭제되거나 변경된 중첩오브젝트나 번들과 같은 사항이 포함"
"됩니다."
msgstr ""
"제품 변경(제품 추가 또는 삭제, 변형 또는 번들과 같은 중첩된 객체에 대한 변경 "
"포함)"
#: pretix/api/webhooks.py:380
msgid "Shop taken live"
@@ -610,12 +623,16 @@ msgid "Waiting list entry received voucher"
msgstr "대기자 명단 항목이 바우처를 받았습니다"
#: pretix/api/webhooks.py:412
#, fuzzy
#| msgid "Voucher code"
msgid "Voucher added"
msgstr "바우처 추가됨"
msgstr "바우처 코드"
#: pretix/api/webhooks.py:416
#, fuzzy
#| msgid "Voucher assigned"
msgid "Voucher changed"
msgstr "바우처 변경됨"
msgstr "바우처 할당"
#: pretix/api/webhooks.py:417
msgid ""
@@ -626,8 +643,10 @@ msgstr ""
"하지 않습니다."
#: pretix/api/webhooks.py:421
#, fuzzy
#| msgid "Voucher redeemed"
msgid "Voucher deleted"
msgstr "바우처 제거됨"
msgstr "바우처 상환"
#: pretix/api/webhooks.py:425
msgid "Customer account created"
@@ -652,7 +671,7 @@ msgstr "고객 계정 익명화되었습니다"
#: pretix/plugins/banktransfer/payment.py:513
#: pretix/presale/forms/customer.py:152
msgid "This field is required."
msgstr "이 필드는 필수입니다."
msgstr "이 필드는 필수입니다"
#: pretix/base/addressvalidation.py:213
msgid "Enter a postal code in the format XXX."
@@ -702,7 +721,7 @@ msgstr "비밀번호"
#: pretix/base/auth.py:176 pretix/base/auth.py:183
msgid "Your password must contain both numeric and alphabetic characters."
msgstr "비밀번호는 숫자와 알파벳 문자가 모두 포함되어야 합니다."
msgstr "비밀번호는 숫자와 알파벳 문자가 모두 포함되어야 합니다"
#: pretix/base/auth.py:202 pretix/base/auth.py:212
#, python-format
@@ -796,21 +815,28 @@ msgstr ""
"소를 확인해 주십시요."
#: pretix/base/datasync/datasync.py:263
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
#| "your {provider_name} settings."
msgid ""
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
"settings."
msgstr "필드 \"{field_name}\"은 존재하지 않습니다. 당신의 {provider_name} 설정을 확인"
"해 주세요."
msgstr ""
"필드 \"{field_name}\"은 {available_inputs}에 유효하지 않습니다. "
"{provider_name} 설정을 확인해 주세요."
#: pretix/base/datasync/datasync.py:270
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
#| "your {provider_name} settings."
msgid ""
"Field \"{field_name}\" requires {required_input}, but only got "
"{available_inputs}. Please check your {provider_name} settings."
msgstr ""
"필드 \"{field_name}\"는 {required_input}을 필요로 하지만, {available_inputs}"
"만 받았습니다. 당신의 {provider_name} 설정을 확인해 주세요."
"필드 \"{field_name}\" {available_inputs}에 유효하지 않습니다. "
"{provider_name} 설정을 확인해 주세요."
#: pretix/base/datasync/datasync.py:281
#, python-brace-format
@@ -822,12 +848,16 @@ msgstr ""
"지 않았습니다"
#: pretix/base/datasync/sourcefields.py:128
#, fuzzy
#| msgid "Order positions"
msgid "Order position details"
msgstr "주문 위치 세부 정보"
msgstr "주문 위치"
#: pretix/base/datasync/sourcefields.py:129
#, fuzzy
#| msgid "Attendee email"
msgid "Attendee details"
msgstr "참석자 정보들"
msgstr "참석자 이메일"
#: pretix/base/datasync/sourcefields.py:130 pretix/base/exporters/answers.py:66
#: pretix/base/models/items.py:1766 pretix/control/navigation.py:172
@@ -837,8 +867,10 @@ msgid "Questions"
msgstr "질문들"
#: pretix/base/datasync/sourcefields.py:131
#, fuzzy
#| msgid "Product data"
msgid "Product details"
msgstr "상품 정보"
msgstr "상품 데이터"
#: pretix/base/datasync/sourcefields.py:132
#: pretix/control/templates/pretixcontrol/event/settings.html:279
@@ -863,13 +895,17 @@ msgid "Invoice address"
msgstr "송장 주소"
#: pretix/base/datasync/sourcefields.py:134
#, fuzzy
#| msgid "Meta information"
msgid "Event information"
msgstr "이벤트 정보"
msgstr "메타 정보(데이타에 대한 정보)"
#: pretix/base/datasync/sourcefields.py:135
#, fuzzy
#| msgid "Send recovery information"
msgctxt "subevent"
msgid "Event or date information"
msgstr "이벤트 또는 날짜 정보"
msgstr "복구 정보를 전송하다"
#: pretix/base/datasync/sourcefields.py:175
#: pretix/base/exporters/orderlist.py:605
@@ -894,8 +930,10 @@ msgstr "참석자 이름"
#: pretix/base/datasync/sourcefields.py:187
#: pretix/base/datasync/sourcefields.py:604
#: pretix/base/datasync/sourcefields.py:628
#, fuzzy
#| msgid "Attendee name"
msgid "Attendee"
msgstr "참석자"
msgstr "참석자 이름"
#: pretix/base/datasync/sourcefields.py:207
#: pretix/base/exporters/orderlist.py:612 pretix/base/forms/questions.py:687
@@ -909,8 +947,10 @@ msgid "Attendee email"
msgstr "참석자 이메일"
#: pretix/base/datasync/sourcefields.py:219
#, fuzzy
#| msgid "Attendee email"
msgid "Attendee or order email"
msgstr "참석자 또는 구매 이메일"
msgstr "참석자 이메일"
#: pretix/base/datasync/sourcefields.py:232
#: pretix/base/exporters/orderlist.py:613 pretix/base/pdf.py:189
@@ -923,20 +963,28 @@ msgid "Attendee company"
msgstr "참석자 회사"
#: pretix/base/datasync/sourcefields.py:241
#, fuzzy
#| msgid "Attendee address"
msgid "Attendee address street"
msgstr "참석자 주소 도로명"
msgstr "참석자 주소"
#: pretix/base/datasync/sourcefields.py:250
#, fuzzy
#| msgid "Attendee ZIP code"
msgid "Attendee address ZIP code"
msgstr "참석자 주소 우편번호"
msgstr "참석자 우편번호"
#: pretix/base/datasync/sourcefields.py:259
#, fuzzy
#| msgid "Attendee address"
msgid "Attendee address city"
msgstr "참석자 주소 도시"
msgstr "참석자 주소"
#: pretix/base/datasync/sourcefields.py:268
#, fuzzy
#| msgid "Attendee address"
msgid "Attendee address country"
msgstr "참석자 주소 국가"
msgstr "참석자 주소"
#: pretix/base/datasync/sourcefields.py:279
#: pretix/base/exporters/orderlist.py:653 pretix/base/pdf.py:347
@@ -972,12 +1020,16 @@ msgid "Invoice address country"
msgstr "송장 주소 국가"
#: pretix/base/datasync/sourcefields.py:353
#, fuzzy
#| msgid "Order total"
msgid "Order email"
msgstr "주문 이메일"
msgstr "주문 합계"
#: pretix/base/datasync/sourcefields.py:362
#, fuzzy
#| msgid "Order time"
msgid "Order email domain"
msgstr "주문 이메일 도메인"
msgstr "주문 시간"
#: pretix/base/datasync/sourcefields.py:371
#: pretix/base/exporters/invoices.py:203 pretix/base/exporters/invoices.py:332
@@ -1009,8 +1061,10 @@ msgid "Order code"
msgstr "주문 코드"
#: pretix/base/datasync/sourcefields.py:380
#, fuzzy
#| msgid "Event end date and time"
msgid "Event and order code"
msgstr "이벤트와 주문 번호"
msgstr "이벤트 종료 날짜 및 시간"
#: pretix/base/datasync/sourcefields.py:389
#: pretix/base/exporters/orderlist.py:263 pretix/base/notifications.py:201
@@ -1022,8 +1076,10 @@ msgid "Order total"
msgstr "주문 합계"
#: pretix/base/datasync/sourcefields.py:398
#, fuzzy
#| msgid "Product name and variation"
msgid "Product and variation name"
msgstr "제품명 및 변형 이름"
msgstr "제품명 및 변형"
#: pretix/base/datasync/sourcefields.py:410 pretix/base/exporters/items.py:57
#: pretix/base/exporters/orderlist.py:598
@@ -1033,12 +1089,16 @@ msgid "Product ID"
msgstr "상품 식별 아이디"
#: pretix/base/datasync/sourcefields.py:419
#, fuzzy
#| msgid "Count add-on products"
msgid "Product is admission product"
msgstr "상품은 입장 상품입니다"
msgstr "추가된 제품을 포함합니다"
#: pretix/base/datasync/sourcefields.py:428
#, fuzzy
#| msgid "Short form"
msgid "Event short form"
msgstr "이벤트 짧은 형식"
msgstr "짧은 형식"
#: pretix/base/datasync/sourcefields.py:437 pretix/base/exporters/events.py:57
#: pretix/base/exporters/orderlist.py:263
@@ -1081,8 +1141,10 @@ msgid "Order code and position number"
msgstr "주문 코드 및 위치 번호"
#: pretix/base/datasync/sourcefields.py:482
#, fuzzy
#| msgid "Ticket code"
msgid "Ticket price"
msgstr "티켓 가격"
msgstr "티켓 코드"
#: pretix/base/datasync/sourcefields.py:491 pretix/base/notifications.py:204
#: pretix/control/forms/filter.py:216 pretix/control/forms/modelimport.py:90
@@ -1090,16 +1152,22 @@ msgid "Order status"
msgstr "주문 상태"
#: pretix/base/datasync/sourcefields.py:500
#, fuzzy
#| msgid "Device status"
msgid "Ticket status"
msgstr "티켓 상태"
msgstr "기기 상태"
#: pretix/base/datasync/sourcefields.py:509
#, fuzzy
#| msgid "Purchase date and time"
msgid "Order date and time"
msgstr "구매 날짜 및 시간"
#: pretix/base/datasync/sourcefields.py:518
#, fuzzy
#| msgid "Printing date and time"
msgid "Payment date and time"
msgstr "결제 날짜 및 시간"
msgstr "인쇄 날짜 및 시간"
#: pretix/base/datasync/sourcefields.py:527
#: pretix/base/exporters/orderlist.py:272
@@ -1110,27 +1178,35 @@ msgid "Order locale"
msgstr "주문 지역 설정"
#: pretix/base/datasync/sourcefields.py:536
#, fuzzy
#| msgid "Order position"
msgid "Order position ID"
msgstr "주문 위치 ID"
msgstr "주문 위치"
#: pretix/base/datasync/sourcefields.py:545
#: pretix/base/exporters/orderlist.py:292
#, fuzzy
#| msgid "Order time"
msgid "Order link"
msgstr "주문 링크"
msgstr "주문 시간"
#: pretix/base/datasync/sourcefields.py:560
#, fuzzy
#| msgid "Ticket design"
msgid "Ticket link"
msgstr "티켓 링크"
msgstr "티켓 디자인"
#: pretix/base/datasync/sourcefields.py:578
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Check-in list {val}"
msgid "Check-in datetime on list {}"
msgstr "{} 리스트에 있는 체크인 날짜와 시간"
msgstr "체크인 목록 {val}"
#: pretix/base/datasync/sourcefields.py:590
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Question {val}"
msgid "Question: {name}"
msgstr "질문: {name}"
msgstr "질문 {val}"
#: pretix/base/datasync/sourcefields.py:604
#: pretix/base/datasync/sourcefields.py:614 pretix/base/settings.py:3642
@@ -2346,9 +2422,9 @@ msgid "Fees"
msgstr "수수료"
#: pretix/base/exporters/orderlist.py:277
#, python-brace-format
#, fuzzy, python-brace-format
msgid "Gross at {rate} % tax"
msgstr "세율 {rate}%의 세금으로 총합"
msgstr "세율{%}의 세금으로 총합"
#: pretix/base/exporters/orderlist.py:278
#, python-brace-format
@@ -2396,9 +2472,9 @@ msgid "External customer ID"
msgstr "외부고객 아이디"
#: pretix/base/exporters/orderlist.py:296
#, python-brace-format
#, fuzzy, python-brace-format
msgid "Paid by {method}"
msgstr "{method}에 의해 결제됨"
msgstr "{방법}에 의해 결제됨"
#: pretix/base/exporters/orderlist.py:458
#: pretix/base/exporters/orderlist.py:914
@@ -2601,8 +2677,10 @@ msgid "Check-in lists"
msgstr "체크인 목록"
#: pretix/base/exporters/orderlist.py:672
#, fuzzy
#| msgid "Additional footer link"
msgid "Position order link"
msgstr "주문 링크 위치"
msgstr "추가 하단 링크"
#: pretix/base/exporters/orderlist.py:841
msgid "Order transaction data"
@@ -3242,13 +3320,15 @@ msgid "Repeat password"
msgstr "반복 비밀번호"
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
#, fuzzy
#| msgid "Email address"
msgid "Your email address"
msgstr "당신의 이메일 주소"
msgstr "이메일 주소"
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
msgid "Confirmation code"
msgstr "확인 코드"
msgstr ""
#: pretix/base/forms/questions.py:137 pretix/base/forms/questions.py:264
msgctxt "name_salutation"
@@ -3331,12 +3411,14 @@ msgstr ""
"야 할 수도 있습니다."
#: pretix/base/forms/questions.py:1181
#, fuzzy
#| msgid "Cancellation requested"
msgid "No invoice requested"
msgstr "청구서 요청되지 않음"
msgstr "취소 요청"
#: pretix/base/forms/questions.py:1183
msgid "Invoice transmission method"
msgstr "청구서 전송 방식"
msgstr ""
#: pretix/base/forms/questions.py:1329
msgid "You need to provide a company name."
@@ -3350,20 +3432,21 @@ msgstr "이름을 입력해야 합니다."
msgid ""
"If you enter an invoice address, you also need to select an invoice "
"transmission method."
msgstr "당신이 청구서 주소를 입력하신다면, 청구서 수신 방법도 선택하셔야 합니다."
msgstr ""
#: pretix/base/forms/questions.py:1385
#, fuzzy
#| msgid "The selected media type is not enabled in your organizer settings."
msgid ""
"The selected transmission type is not available in your country or for your "
"type of address."
msgstr "선택한 전송 유형은 당신의 국가 또는 지역에서 이용하실 수 없습니다."
msgstr "선택한 미디어 유형이 정리함 설정에서 활성화되지 않았습니다."
#: pretix/base/forms/questions.py:1394
msgid ""
"The selected type of invoice transmission requires a field that is currently "
"not available, please reach out to the organizer."
msgstr "선택하신 청구서 전송 유형은 현재 사용할 수 없는 필드의 입력을 필요로 하니, 주"
"최자에게 문의 해 주세요."
msgstr ""
#: pretix/base/forms/questions.py:1398
msgid "This field is required for the selected type of invoice transmission."
@@ -3383,8 +3466,10 @@ msgstr ""
"대가 대신 사용됩니다."
#: pretix/base/forms/user.py:77
#, fuzzy
#| msgid "Attendee email address"
msgid "Change email address"
msgstr "이메일 주소 변경"
msgstr "참석자 이메일 주소"
#: pretix/base/forms/user.py:83
msgid "Device name"
@@ -3433,12 +3518,16 @@ msgstr ""
"이 이메일 주소와 관련된 계정이 이미 있습니다. 다른 계정을 선택해 주세요."
#: pretix/base/forms/user.py:179
#, fuzzy
#| msgid "Email address"
msgid "Old email address"
msgstr "이전 이메일 주소"
msgstr "이메일 주소"
#: pretix/base/forms/user.py:180
#, fuzzy
#| msgid "Email address"
msgid "New email address"
msgstr "이메일 주소"
msgstr "이메일 주소"
#: pretix/base/forms/validators.py:51
msgid ""
@@ -3483,22 +3572,23 @@ msgstr "개별 고객"
#: pretix/base/invoicing/email.py:50
msgid "Email invoice directly to accounting department"
msgstr "청구서를 회계 부서로 이메일로 바로 보내기"
msgstr ""
#: pretix/base/invoicing/email.py:51
msgid ""
"If not selected, the invoice will be sent to you using the email address "
"listed above."
msgstr "선택되지 않은 경우, 청구서는 위의 이메일 주소를 통해 당신에게 보내질 것 입니"
"다."
msgstr ""
#: pretix/base/invoicing/email.py:55
#, fuzzy
#| msgid "Email address verified"
msgid "Email address for invoice"
msgstr "청구서용 이메일 주소"
msgstr "이메일 주소 확인"
#: pretix/base/invoicing/email.py:91
msgid "PDF via email"
msgstr "이메일로 PDF"
msgstr ""
#: pretix/base/invoicing/national.py:37
msgctxt "italian_invoice"
@@ -3523,9 +3613,11 @@ msgid "Address for certified electronic mail"
msgstr ""
#: pretix/base/invoicing/national.py:57
#, fuzzy
#| msgid "Recipient"
msgctxt "italian_invoice"
msgid "Recipient code"
msgstr "영수증 코드"
msgstr "영수증"
#: pretix/base/invoicing/national.py:81
msgctxt "italian_invoice"
@@ -3605,6 +3697,7 @@ msgid ""
"until {to_date}"
msgstr ""
"{from_date}\n"
"\n"
"{to_date}까지"
#: pretix/base/invoicing/pdf.py:609 pretix/base/services/mail.py:512
@@ -3684,10 +3777,10 @@ msgid "Single price: {net_price} net / {gross_price} gross"
msgstr "단일 가격: {net_price} 순 / {gross_price} 총합"
#: pretix/base/invoicing/pdf.py:901
#, python-brace-format
#, fuzzy, python-brace-format
msgctxt "invoice"
msgid "Single price: {price}"
msgstr "단일 가격: {price}"
msgstr "단일 가격: {가격}"
#: pretix/base/invoicing/pdf.py:944 pretix/base/invoicing/pdf.py:949
msgctxt "invoice"
@@ -3715,10 +3808,12 @@ msgid "Remaining amount"
msgstr "잔액"
#: pretix/base/invoicing/pdf.py:1009
#, python-brace-format
#, fuzzy, python-brace-format
#| msgctxt "invoice"
#| msgid "Event date: {date_range}"
msgctxt "invoice"
msgid "Invoice period: {daterange}"
msgstr "청구서 기간: {daterange}"
msgstr "이벤트 날짜: {date_range}"
#: pretix/base/invoicing/pdf.py:1040
msgctxt "invoice"
@@ -3741,12 +3836,13 @@ msgid "Included taxes"
msgstr "세금 포함"
#: pretix/base/invoicing/pdf.py:1100
#, python-brace-format
#, fuzzy, python-brace-format
msgctxt "invoice"
msgid ""
"Using the conversion rate of 1:{rate} as published by the {authority} on "
"{date}, this corresponds to:"
msgstr "{date}에 {authority}에서 발표한 1:{rate}의 변환율을 사용하면 다음과 같습니다:"
msgstr ""
"{날짜}에 {당국}에서 발표한 1:{세율}의 변환율을 사용하면 다음과 같습니다:"
#: pretix/base/invoicing/pdf.py:1115
#, fuzzy, python-brace-format
@@ -3754,8 +3850,9 @@ msgctxt "invoice"
msgid ""
"Using the conversion rate of 1:{rate} as published by the {authority} on "
"{date}, the invoice total corresponds to {total}."
msgstr "{date}에 {authority}에서 게시한 1:{rate}의 변환율을 사용하면 송장 총액이 "
"{total}에 해당합니다."
msgstr ""
"{날짜}에 {당국}에서 게시한 1:{세율}의 변환율을 사용하면 송장 총액이 {총합}에 "
"해당합니다."
#: pretix/base/invoicing/pdf.py:1129
msgid "Default invoice renderer (European-style letter)"

View File

@@ -7,16 +7,16 @@ msgstr ""
"Project-Id-Version: 1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-08 07:00+0000\n"
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
"\n"
"PO-Revision-Date: 2025-10-26 18:00+0000\n"
"Last-Translator: Jan Van Haver <jan.van.haver@gmail.com>\n"
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/"
">\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.14.3\n"
"X-Generator: Weblate 5.14\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -44,7 +44,7 @@ msgstr "Catalaans"
#: pretix/_base_settings.py:93
msgid "Chinese (simplified)"
msgstr "Chinees (vereenvoudigd)"
msgstr "Chinees (versimpeld)"
#: pretix/_base_settings.py:94
msgid "Chinese (traditional)"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-08 07:00+0000\n"
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
"PO-Revision-Date: 2024-02-13 16:00+0000\n"
"Last-Translator: Wessel Stam <info@wesselstam.nl>\n"
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
"pretix/nl_Informal/>\n"
"Language: nl_Informal\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.14.3\n"
"X-Generator: Weblate 5.3.1\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -37,15 +37,15 @@ msgstr "Arabisch"
#: pretix/_base_settings.py:91
msgid "Basque"
msgstr "Baskisch"
msgstr ""
#: pretix/_base_settings.py:92
msgid "Catalan"
msgstr "Catalaans"
msgstr ""
#: pretix/_base_settings.py:93
msgid "Chinese (simplified)"
msgstr "Chinees (vereenvoudigd)"
msgstr "Chinees (versimpeld)"
#: pretix/_base_settings.py:94
msgid "Chinese (traditional)"
@@ -57,7 +57,7 @@ msgstr "Tsjechisch"
#: pretix/_base_settings.py:96
msgid "Croatian"
msgstr "Kroatisch"
msgstr ""
#: pretix/_base_settings.py:97
msgid "Danish"
@@ -89,7 +89,7 @@ msgstr "Grieks"
#: pretix/_base_settings.py:104
msgid "Hebrew"
msgstr "Hebreeuws"
msgstr ""
#: pretix/_base_settings.py:105
msgid "Indonesian"
@@ -101,7 +101,7 @@ msgstr "Italiaans"
#: pretix/_base_settings.py:107
msgid "Japanese"
msgstr "Japans"
msgstr ""
#: pretix/_base_settings.py:108
msgid "Latvian"
@@ -133,11 +133,11 @@ msgstr "Russisch"
#: pretix/_base_settings.py:115
msgid "Slovak"
msgstr "Slowaaks"
msgstr ""
#: pretix/_base_settings.py:116
msgid "Swedish"
msgstr "Zweeds"
msgstr ""
#: pretix/_base_settings.py:117
msgid "Spanish"
@@ -145,7 +145,7 @@ msgstr "Spaans"
#: pretix/_base_settings.py:118
msgid "Spanish (Latin America)"
msgstr "Spaans (Latijns-Amerika)"
msgstr ""
#: pretix/_base_settings.py:119
msgid "Turkish"
@@ -261,7 +261,7 @@ msgstr ""
#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554
#, python-brace-format
msgid "Meta data property '{name}' does not exist."
msgstr "Metadata-eigenschap '{name}' bestaat niet."
msgstr "Metadataeigenschap '{name}' bestaat niet."
#: pretix/api/serializers/event.py:237 pretix/api/serializers/event.py:557
#, python-brace-format
@@ -32970,7 +32970,7 @@ msgstr ""
#: pretix/plugins/reports/exporters.py:257
msgctxt "export_category"
msgid "Analysis"
msgstr "Analyse"
msgstr ""
#: pretix/plugins/reports/accountingreport.py:83
#, fuzzy

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-11 01:00+0000\n"
"PO-Revision-Date: 2025-09-10 05:00+0000\n"
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_BR/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.14.3\n"
"X-Generator: Weblate 5.13.2\n"
#: pretix/_base_settings.py:87
msgid "English"
@@ -253,8 +253,9 @@ msgid ""
"Events cannot be created as 'live'. Quotas and payment must be added to the "
"event before sales can go live."
msgstr ""
"Eventos não podem ser criados como 'ativo'. Cotas e métodos de pagamento "
"devem ser adicionados ao evento antes que as vendas se iniciem."
"Os eventos não podem ser criados como 'ativo'. As cotas e métodos de "
"pagamento devem ser adicionados ao evento antes que as vendas possam ser "
"iniciadas."
#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554
#, python-brace-format
@@ -357,8 +358,7 @@ msgstr ""
#: pretix/api/serializers/item.py:587 pretix/control/forms/item.py:177
msgid "Question cannot depend on a question asked during check-in."
msgstr ""
"A pergunta não pode depender de outra pergunta feita durante o check-in."
msgstr "A pergunta não pode depender de uma pergunta feita durante o check-in."
#: pretix/api/serializers/item.py:592 pretix/control/forms/item.py:182
msgid "Circular dependency between questions detected."
@@ -816,22 +816,28 @@ msgstr ""
"confirme primeiro o endereço de email na sua conta."
#: pretix/base/datasync/datasync.py:263
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
#| "your {provider_name} settings."
msgid ""
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
"settings."
msgstr ""
"O campo \"{field_name}\" não existe. Por favor, verifique as configurações "
"de {provider_name}."
"O campo \"{field_name}\" não é válido para {available_inputs}. Verifique as "
"configurações de {provider_name}."
#: pretix/base/datasync/datasync.py:270
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
#| "your {provider_name} settings."
msgid ""
"Field \"{field_name}\" requires {required_input}, but only got "
"{available_inputs}. Please check your {provider_name} settings."
msgstr ""
"Campo \"{field_name}\" exige {required_input}, mas apenas {available_inputs} "
"foram fornecidas. Por favor, verifique as configurações de {provider_name}."
"O campo \"{field_name}\" não é válido para {available_inputs}. Verifique as "
"configurações de {provider_name}."
#: pretix/base/datasync/datasync.py:281
#, python-brace-format
@@ -2131,7 +2137,7 @@ msgstr "Comprar este produto requer aprovação"
#: pretix/base/exporters/items.py:85 pretix/base/models/items.py:627
msgid "Only sell this product as part of a bundle"
msgstr "Venda este produto apenas como parte de um pacote"
msgstr "Disponível apenas como parte de um pacote"
#: pretix/base/exporters/items.py:86 pretix/base/models/items.py:634
msgid "Allow product to be canceled or changed"
@@ -2833,7 +2839,7 @@ msgstr "Código de Status"
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:25
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13
msgid "Amount"
msgstr "Quantidade"
msgstr "Valor"
#: pretix/base/exporters/orderlist.py:1098
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:102
@@ -3280,8 +3286,10 @@ msgid "Repeat password"
msgstr "Repita a senha"
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
#, fuzzy
#| msgid "Email address"
msgid "Your email address"
msgstr "Seu endereço de e-mail"
msgstr "Endereço de email"
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
@@ -3392,8 +3400,6 @@ msgid ""
"If you enter an invoice address, you also need to select an invoice "
"transmission method."
msgstr ""
"Se você informar um endereço para a fatura, você também deverá selecionar um "
"método para transmissão da fatura."
#: pretix/base/forms/questions.py:1385
msgid ""
@@ -3408,8 +3414,6 @@ msgid ""
"The selected type of invoice transmission requires a field that is currently "
"not available, please reach out to the organizer."
msgstr ""
"O tipo de transmissão de fatura selecionado exige um campo que não está "
"disponível atualmente. Por favor, entre em contato com a organização."
#: pretix/base/forms/questions.py:1398
msgid "This field is required for the selected type of invoice transmission."
@@ -3429,8 +3433,10 @@ msgstr ""
"as exibições de eventos, o fuso horário do evento é usado."
#: pretix/base/forms/user.py:77
#, fuzzy
#| msgid "Attendee email address"
msgid "Change email address"
msgstr "Alterar endereço de e-mail"
msgstr "Email do participante"
#: pretix/base/forms/user.py:83
msgid "Device name"
@@ -3480,12 +3486,16 @@ msgstr ""
"um diferente."
#: pretix/base/forms/user.py:179
#, fuzzy
#| msgid "Email address"
msgid "Old email address"
msgstr "Endereço de e-mail antigo"
msgstr "Endereço de email"
#: pretix/base/forms/user.py:180
#, fuzzy
#| msgid "Email address"
msgid "New email address"
msgstr "Endereço de e-mail novo"
msgstr "Endereço de email"
#: pretix/base/forms/validators.py:51
msgid ""
@@ -3530,17 +3540,22 @@ msgid "Individual customer"
msgstr "Cliente pessoa física"
#: pretix/base/invoicing/email.py:50
#, fuzzy
#| msgid ""
#| "To send the invoice directly to your accounting department, please enter "
#| "their email address:"
msgid "Email invoice directly to accounting department"
msgstr ""
"Enviar e-mail com a fatura diretamente para departamento de contabilidade"
"Para enviar a fatura diretamente ao seu departamento de contabilidade, "
"insira o endereço de e-mail:"
#: pretix/base/invoicing/email.py:51
#, fuzzy
#| msgid "The invoice was sent to the designated email address."
msgid ""
"If not selected, the invoice will be sent to you using the email address "
"listed above."
msgstr ""
"Se não selecionado, a fatura será enviada para o endereço de e-mail listado "
"a seguir."
msgstr "A fatura foi enviada para o endereço de e-mail designado."
#: pretix/base/invoicing/email.py:55
msgid "Email address for invoice"
@@ -3763,10 +3778,12 @@ msgid "Remaining amount"
msgstr "Valor restante"
#: pretix/base/invoicing/pdf.py:1009
#, python-brace-format
#, fuzzy, python-brace-format
#| msgctxt "invoice"
#| msgid "Event date: {date_range}"
msgctxt "invoice"
msgid "Invoice period: {daterange}"
msgstr "Período da fatura: {daterange}"
msgstr "Data do evento: {date_range}"
#: pretix/base/invoicing/pdf.py:1040
msgctxt "invoice"
@@ -3851,9 +3868,12 @@ msgid "Peppol participant ID"
msgstr ""
#: pretix/base/invoicing/peppol.py:170
#, fuzzy
#| msgctxt "italian_invoice"
#| msgid "Fiscal code"
msgctxt "peppol_invoice"
msgid "Visual copy"
msgstr "Cópia visual"
msgstr "Código fiscal"
#: pretix/base/invoicing/peppol.py:175
msgctxt "peppol_invoice"
@@ -4337,8 +4357,10 @@ msgid ""
msgstr ""
#: pretix/base/models/auth.py:392
#, fuzzy
#| msgid "Confirmation code"
msgid "pretix confirmation code"
msgstr "código de confirmação do pretix"
msgstr "Código de confirmação"
#: pretix/base/models/auth.py:435
#: pretix/control/templates/pretixcontrol/auth/forgot.html:7
@@ -4840,11 +4862,11 @@ msgid ""
"you can also choose to use a random value. This will be used in URLs, order "
"codes, invoice numbers, and bank transfer references."
msgstr ""
"Deve conter apenas letras minúsculas, números, pontos e traços, sendo "
"exclusiva para suas eventos. Recomendamos uma abreviação ou data com menos "
"de 10 caracteres e que seja facilmente lembrada, mas você também pode usar "
"um valor aleatório. Esta informação será usada em URLs, códigos de pedido, "
"número de faturas e referências de transações bancárias."
"Deve ser curts, conter apenas letras minúsculas, números, pontos e traços, e "
"ser exclusiva entre seus eventos. Recomendamos algum tipo de abreviação ou "
"uma data com menos de 10 caracteres que sejam facilmente lembradas, mas você "
"também pode usar um valor aleatório. Esta informação será usada em URLs, "
"códigos de pedido, números de fatura e referências de transferência bancária."
#: pretix/base/models/event.py:607 pretix/base/models/organizer.py:89
msgid "The slug may only contain letters, numbers, dots and dashes."
@@ -5372,16 +5394,24 @@ msgstr ""
"não tiver variações, este preço será usado."
#: pretix/base/models/items.py:506
#, fuzzy
#| msgid ""
#| "If this option is active, your users can choose the price themselves. The "
#| "price configured above is then interpreted as the minimum price a user "
#| "has to enter. You could use this e.g. to collect additional donations for "
#| "your event. This is currently not supported for products that are bought "
#| "as an add-on to other products."
msgid ""
"If this option is active, your users can choose the price themselves. The "
"price configured above is then interpreted as the minimum price a user has "
"to enter. You could use this e.g. to collect additional donations for your "
"event."
msgstr ""
"Se esta opção está selecionada, os usuários poderão pagar o preço que "
"desejarem. O preço padrão acima será interpretado como o preço mínimo que o "
"usuário deverá pagar. Você pode usar esta opção, por exemplo, para coletar "
"doações adicionais para o seu evento."
"Se esta opção estiver ativa, seus usuários podem escolher o próprio preço. O "
"preço configurado acima é então interpretado como o preço mínimo que um "
"usuário deve inserir. Você pode usar isso, por exemplo, para coletar doações "
"adicionais para o seu evento. No momento, isto não é suportado por produtos "
"comprados como um complemento de outros produtos."
#: pretix/base/models/items.py:511 pretix/base/models/items.py:1175
msgid "Suggested price"
@@ -6268,6 +6298,9 @@ msgstr ""
"insira um valor possível por linha."
#: pretix/base/models/items.py:2310
#, fuzzy
#| msgctxt "timeframe"
#| msgid "Start"
msgid "Start"
msgstr "Início"
@@ -7879,8 +7912,10 @@ msgid "123.45 EUR"
msgstr "123.45 BRL"
#: pretix/base/pdf.py:166
#, fuzzy
#| msgid "Price including add-ons"
msgid "Price including bundled products"
msgstr "Preços incluindo produtos empacotados"
msgstr "Preço incluindo complementos"
#: pretix/base/pdf.py:175
#, fuzzy
@@ -9843,8 +9878,10 @@ msgid "Require a phone number per order"
msgstr "Exigir um número de telefone por pedido"
#: pretix/base/settings.py:482
#, fuzzy
#| msgid "including all taxes"
msgid "Rounding of taxes"
msgstr "Arredondamento dos impostos"
msgstr "incluindo todos os impostos"
#: pretix/base/settings.py:486
msgid ""
@@ -10387,12 +10424,18 @@ msgid "Automatic, but prefer invoice date over event date"
msgstr ""
#: pretix/base/settings.py:1142 pretix/base/settings.py:1153
#, fuzzy
#| msgctxt "invoice"
#| msgid "Invoice date"
msgid "Invoice date"
msgstr "Data da fatura"
#: pretix/base/settings.py:1146
#, fuzzy
#| msgctxt "subevent"
#| msgid "Date ordering"
msgid "Date of service"
msgstr "Data do serviço"
msgstr "Ordenação de datas"
#: pretix/base/settings.py:1155
msgid ""
@@ -11256,8 +11299,8 @@ msgstr "Endereço de contato"
#: pretix/base/settings.py:2161 pretix/control/forms/event.py:1824
msgid "We'll show this publicly to allow attendees to contact you."
msgstr ""
"Será exibido publicamente para que participantes possam entrar em contato "
"com você."
"Mostraremos isso publicamente para permitir que os participantes entrem em "
"contato com você."
#: pretix/base/settings.py:2169 pretix/control/forms/event.py:1816
msgid "Imprint URL"
@@ -12123,7 +12166,17 @@ msgid "Invoice {invoice_number}"
msgstr "Fatura {invoice_number}"
#: pretix/base/settings.py:2789
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "Hello,\n"
#| "\n"
#| "somebody requested a list of your orders for {event}.\n"
#| "The list is as follows:\n"
#| "\n"
#| "{orders}\n"
#| "\n"
#| "Best regards, \n"
#| "Your {event} team"
msgid ""
"Hello,\n"
"\n"
@@ -12136,12 +12189,12 @@ msgid ""
msgstr ""
"Olá,\n"
"\n"
"Em anexo você encontrará uma nova fatura para o pedido {code} para {event}. "
"Este pedido foi feito por {order_email}.\n"
"Segue anexo uma nova fatura para o pedido {code} para {evento} . Este pedido "
"foi feito por {order_email}.\n"
"\n"
"Atenciosamente, \n"
"\n"
"Organização {event}"
"Equipe organizadora de {event}"
#: pretix/base/settings.py:2807 pretix/base/settings.py:2823
#, python-brace-format
@@ -13203,13 +13256,13 @@ msgid "Contact:"
msgstr "Contato:"
#: pretix/base/templates/pretixbase/email/order_details.html:54
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You are receiving this email because you placed an order for {event}."
msgid ""
"You are receiving this email because you placed an order for "
"<strong>%(event)s</strong>."
msgstr ""
"Você está recebendo este email por ter realizado um pedido para <strong>%"
"(event)s</strong>."
msgstr "Você está recebendo este email porque fez um pedido para {event}."
#: pretix/base/templates/pretixbase/email/order_details.html:93
#: pretix/control/templates/pretixcontrol/organizers/customer.html:23
@@ -13884,7 +13937,7 @@ msgstr "Padrão ({value})"
#: pretix/control/forms/event.py:380
msgid "The currency cannot be changed because orders already exist."
msgstr "A moeda não pode ser alterada pois já foram realizados pedidos."
msgstr ""
#: pretix/control/forms/event.py:391 pretix/control/forms/event.py:404
msgid "Domain"
@@ -13970,16 +14023,21 @@ msgstr ""
"que o cartão-presente é emitido."
#: pretix/control/forms/event.py:813
#, fuzzy
#| msgid "including all taxes"
msgid "Prices including tax"
msgstr "Preços incluindo impostos"
msgstr "incluindo todos os impostos"
#: pretix/control/forms/event.py:814
msgid "Recommended if you sell tickets at least partly to consumers."
msgstr ""
#: pretix/control/forms/event.py:818
#, fuzzy
#| msgctxt "reporting_timeframe"
#| msgid "All future (excluding today)"
msgid "Prices excluding tax"
msgstr "Preços excluindo impostos"
msgstr "Todos os futuros (excluindo hoje)"
#: pretix/control/forms/event.py:819
msgid "Recommended only if you sell tickets primarily to business customers."
@@ -17343,14 +17401,19 @@ msgid "Your account has been disabled."
msgstr "Sua conta foi desativada."
#: pretix/control/logdisplay.py:672
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid ""
#| "The email address has been changed from \"{old_email}\" to \"{new_email}"
#| "\"."
msgid "Your email address has been changed from {old_email} to {email}."
msgstr "Seu endereço de email foi modificado de {old_email} para {email}."
msgstr ""
"O endereço de e-mail foi alterado de \"{old_email}\" para \"{new_email}\"."
#: pretix/control/logdisplay.py:673
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Your email address has been updated."
msgid "Your email address {email} has been confirmed."
msgstr "Seu endereço de e-mail {email} foi confirmado."
msgstr "Seu endereço de email foi atualizado."
#: pretix/control/logdisplay.py:685
#, python-brace-format
@@ -19627,20 +19690,6 @@ msgid ""
"Best regards,\n"
"Your pretix team\n"
msgstr ""
"Olá,\n"
"\n"
"%(reason)s\n"
"\n"
" %(code)s\n"
"\n"
"Por favor, nunca forneça este código para outra pessoa. Nosso time de "
"suporte nunca irá solicitar este código.\n"
"\n"
"Se você não solicitou este código, por favor entre em contato conosco "
"imediatamente.\n"
"\n"
"Atenciosamente,\n"
"Time pretix\n"
#: pretix/control/templates/pretixcontrol/email/email_setup.txt:1
#, python-format
@@ -21265,8 +21314,10 @@ msgid "with custom rules"
msgstr "Regras personalizadas"
#: pretix/control/templates/pretixcontrol/event/tax.html:110
#, fuzzy
#| msgid "Base settings"
msgid "Tax settings"
msgstr "Configurações de impostos"
msgstr "Configurações base"
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
@@ -21929,9 +21980,6 @@ msgid ""
"your event. By default, we will only offer ticket downloads for these "
"products."
msgstr ""
"Cada compra deste produto representa uma pessoa que terá permissão de entrar "
"no seu evento. Por padrão, só oferecemos o download de ingressos para estes "
"produtos."
#: pretix/control/templates/pretixcontrol/item/create.html:33
#: pretix/control/templates/pretixcontrol/item/index.html:41
@@ -26096,7 +26144,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/shredder/download.html:29
msgid "Download data"
msgstr "Baixar dados"
msgstr ""
#: pretix/control/templates/pretixcontrol/shredder/download.html:34
msgid "Step 2: Confirm deletion"
@@ -26427,7 +26475,7 @@ msgstr "Adicionar um dispositivo de autenticação de dois fatores"
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
msgid "To set up this device, please follow the following steps:"
msgstr "Para configurar este dispositivo, por favor siga os passos a seguir:"
msgstr ""
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:12
msgid "Download the Google Authenticator application to your phone:"
@@ -26853,11 +26901,11 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:6
msgid "Session notes"
msgstr "Notas de sessão"
msgstr ""
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:17
msgid "Audit log"
msgstr "Log de auditoria"
msgstr ""
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:30
msgid "Method"
@@ -27901,7 +27949,7 @@ msgstr ""
#: pretix/control/views/item.py:237
msgid "The selected category has been deleted."
msgstr "A categoria selecionada foi excluída"
msgstr ""
#: pretix/control/views/item.py:322
msgid "The new category has been created."
@@ -29826,7 +29874,7 @@ msgstr ""
#: pretix/plugins/banktransfer/payment.py:239
msgid "Please fill out your bank account details."
msgstr "Por favor, preencha os detalhes da sua conta bancária."
msgstr ""
#: pretix/plugins/banktransfer/payment.py:243
msgid "Please enter your bank account details."
@@ -30127,7 +30175,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:122
msgid "Scan the QR code with your banking app"
msgstr "Escanear o QR Code com o seu aplicativo bancário"
msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:5
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:7
@@ -30698,8 +30746,6 @@ msgid ""
"We're waiting for an answer from PayPal regarding your payment. Please "
"contact us, if this takes more than a few hours."
msgstr ""
"Estamos aguardando por informações do PayPal referentes ao seu pagamento. "
"Por favor, entre em contato conosco se isso demorar mais que algumas horas."
#: pretix/plugins/paypal/templates/pretixplugins/paypal/redirect.html:17
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/redirect.html:17
@@ -33324,17 +33370,19 @@ msgstr "Organizador: {organizer}"
#: pretix/presale/ical.py:139
#, python-brace-format
msgid "{event} - {item}"
msgstr "{event} - {item}"
msgstr ""
#: pretix/presale/ical.py:147
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Start date"
msgid "Start: {datetime}"
msgstr "Início: {datetime}"
msgstr "Data inicial"
#: pretix/presale/ical.py:150
#, python-brace-format
#, fuzzy, python-brace-format
#| msgid "Admission: {datetime}"
msgid "End: {datetime}"
msgstr "Término: {datetime}"
msgstr "Admissão: {datetime}"
#: pretix/presale/templates/pretixpresale/base.html:44
#, fuzzy
@@ -33726,11 +33774,12 @@ msgstr "Selecione como deseja pagar o saldo restante:"
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:82
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:45
#, python-format
#, fuzzy, python-format
#| msgid "%(num)s available"
msgid "(%(count)s available)"
msgid_plural "(%(count)s available)"
msgstr[0] "(%(count)s disponível)"
msgstr[1] "(%(count)s disponíveis)"
msgstr[0] "%(num)s disponíveis"
msgstr[1] "%(num)s disponíveis"
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:101
msgid "This sales channel does not provide support for test mode."
@@ -34509,11 +34558,13 @@ msgstr "Mostrar imagem em tamanho real de %(item)s"
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:131
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:288
#, python-format
#, fuzzy, python-format
#| msgid "%(count)s event"
#| msgid_plural "%(count)s events"
msgid "%(amount)s× in your cart"
msgid_plural "%(amount)s× in your cart"
msgstr[0] "%(amount)s× no seu carrinho"
msgstr[1] "%(amount)s× no seu carrinho"
msgstr[0] "%(count)s evento"
msgstr[1] "%(count)s events"
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:209
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:374
@@ -35581,8 +35632,10 @@ msgid "The following gift cards are available in your customer account:"
msgstr ""
#: pretix/presale/templates/pretixpresale/giftcard/checkout.html:24
#, fuzzy
#| msgid "Issued gift cards"
msgid "Use gift card"
msgstr "Usar cartão-presente"
msgstr "Cartões-presente emitidos"
#: pretix/presale/templates/pretixpresale/giftcard/checkout_confirm.html:4
#, python-format
@@ -35599,7 +35652,7 @@ msgid ""
"This is a self-hosted installation of <a %(a_attr)s>pretix, your free and "
"open source ticket sales software</a>."
msgstr ""
"Esta é uma instalação auto-hospedada do <a %(a_attr)s>pretix, seu aplicativo "
"Está é uma instalação self-hosted do <a %(a_attr)s>pretix, seu aplicativo "
"livre e de código aberto para venda de ingressos.</a>."
#: pretix/presale/templates/pretixpresale/index.html:15
@@ -35695,18 +35748,22 @@ msgid "Issued on %(date)s"
msgstr "Leitura negada: %(date)s"
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:38
#, python-format
#, fuzzy, python-format
#| msgid "Expired since"
msgid "Expired since %(date)s"
msgstr "Expirado desde %(date)s"
msgstr "Expirado desde"
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:46
#, python-format
#, fuzzy, python-format
#| msgid "Valid until %(datetime)s"
msgid "Valid until %(date)s"
msgstr "Válido até %(date)s"
msgstr "Válido até %(datetime)s"
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:66
#, fuzzy
#| msgid "Remaining balance"
msgid "Remaining value:"
msgstr "Valor restante:"
msgstr "Saldo restante"
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:76
#, fuzzy
@@ -36230,8 +36287,10 @@ msgid "The selected date does not exist in this event series."
msgstr "A data selecionada não existe nesta série de eventos."
#: pretix/presale/views/widget.py:412
#, fuzzy
#| msgid "The selected seat \"{seat}\" is not available."
msgid "The selected date is not available."
msgstr "A data selecionada não está disponível."
msgstr "O assento selecionado \"{seat}\" não está disponível."
#: pretix/presale/views/widget.py:476
#, python-format

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
"PO-Revision-Date: 2025-12-09 00:47+0000\n"
"PO-Revision-Date: 2025-08-28 13:43+0000\n"
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
"pretix/pretix-js/pt_BR/>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.14.3\n"
"X-Generator: Weblate 5.13\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -566,11 +566,11 @@ msgstr "ausente"
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
msgid "Error: Product not found!"
msgstr "Erro: Produto não encontrado!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
msgid "Error: Variation not found!"
msgstr "Erro: Variação não encontrada!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:171
msgid "Check-in QR"

View File

@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-11 01:00+0000\n"
"Last-Translator: Ana Rute Pacheco Vivas <rute.vivas@om.org>\n"
"PO-Revision-Date: 2025-12-01 12:48+0000\n"
"Last-Translator: José Manuel Silva <prof.jmas@gmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
"pretix/pretix/pt_PT/>\n"
"Language: pt_PT\n"
@@ -3522,7 +3522,8 @@ msgstr "Participante individual"
#: pretix/base/invoicing/email.py:50
msgid "Email invoice directly to accounting department"
msgstr "Envia a fatura diretamente por e-mail para o departamento financeiro"
msgstr ""
"Envie a fatura diretamente por e-mail para o departamento de contabilidade"
#: pretix/base/invoicing/email.py:51
msgid ""
@@ -6701,8 +6702,10 @@ msgstr ""
"tua fatura, caso assim o desejes."
#: pretix/base/models/orders.py:3534
#, fuzzy
#| msgid "Transaction time"
msgid "Transmission type"
msgstr "Modo de comunicação"
msgstr "Hora de transação"
#: pretix/base/models/orders.py:3632
#: pretix/plugins/badges/templates/pretixplugins/badges/control_order_position_buttons.html:9
@@ -13315,13 +13318,13 @@ msgid "Contact:"
msgstr "Contacto:"
#: pretix/base/templates/pretixbase/email/order_details.html:54
#, python-format
#, fuzzy, python-format
#| msgid ""
#| "You are receiving this email because you placed an order for {event}."
msgid ""
"You are receiving this email because you placed an order for "
"<strong>%(event)s</strong>."
msgstr ""
"Estás a receber este email porque fizeste um pedido para o <strong>%(event)"
"s</strong>."
msgstr "Estás a receber este email porque fizeste um pedido para o {event}."
#: pretix/base/templates/pretixbase/email/order_details.html:93
#: pretix/control/templates/pretixcontrol/organizers/customer.html:23
@@ -20183,8 +20186,8 @@ msgid ""
"email address is owned by you. Please enter the verification code below:"
msgstr ""
"Enviamos um e-mail para %(recp)s com um código de confirmação para verificar "
"se este endereço de e-mail te pertence. Por favor, indica o código de "
"verificação abaixo:"
"se este endereço de e-mail é da sua propriedade. Por favor, insira o código "
"de verificação abaixo:"
#: pretix/control/templates/pretixcontrol/email_setup_simple.html:63
msgid "Verification code"
@@ -27451,9 +27454,6 @@ msgid ""
"We will send a confirmation code to your new email address, which you need "
"to enter in the next step to confirm the email address is correct."
msgstr ""
"Enviaremos um código de confirmação para o teu novo endereço de e-mail, que "
"precisas de inserir na próxima etapa para confirmar que o endereço de e-mail "
"está correto."
#: pretix/control/templates/pretixcontrol/user/change_password.html:4
#: pretix/control/templates/pretixcontrol/user/change_password.html:8
@@ -27567,9 +27567,6 @@ msgid ""
"confirm your email address using a confirmation code we will send to your "
"email address."
msgstr ""
"O teu endereço de e-mail ainda não foi confirmado. Para proteger a tua "
"conta, confirma o teu endereço de e-mail usando um código de confirmação que "
"te enviaremos."
#: pretix/control/templates/pretixcontrol/user/settings.html:18
#, fuzzy
@@ -28881,7 +28878,7 @@ msgstr ""
#: pretix/control/views/mailsetup.py:216
msgid "The verification code was incorrect, please try again."
msgstr "O código de verificação estava incorreto, tenta novamente."
msgstr "O código de verificação estava incorreto, tente novamente."
#: pretix/control/views/mailsetup.py:221
msgid "Sender address verification"
@@ -29940,8 +29937,6 @@ msgid ""
"Please enter the confirmation code we sent to your email address "
"<strong>{email}</strong>."
msgstr ""
"Indica o código de confirmação que enviámos para o teu endereço de e-mail "
"<strong>{email}</strong>."
#: pretix/control/views/user.py:947
#, fuzzy
@@ -34944,7 +34939,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:9
msgid "Before we continue, we need you to answer some questions."
msgstr "Antes de continuares, precisamos que respondas a algumas perguntas."
msgstr "Antes de continuarmos, precisamos que respondas a algumas perguntas."
#: pretix/presale/templates/pretixpresale/event/checkout_questions.html:49
msgid "Auto-fill with address"
@@ -35379,8 +35374,10 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:514
#: pretix/presale/templates/pretixpresale/fragment_modals.html:48
#, fuzzy
#| msgid "Event description"
msgid "Renew reservation"
msgstr "Renovar a reserva"
msgstr "Descrição do Evento"
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:526
#, fuzzy
@@ -35965,8 +35962,8 @@ msgid ""
"Please note that we still await approval by the event organizer before you "
"can pay and complete this order."
msgstr ""
"Por favor, nota que ainda estamos à espera da aprovação do organizador do "
"evento antes de poderes pagar e concluir esta encomenda."
"Por favor, note que a aprovação ainda aguardam pelo organizador do evento "
"antes que pode pagar e concluir este pedido."
#: pretix/presale/templates/pretixpresale/event/order.html:43
msgid "Please note that we still await your payment to complete the process."
@@ -35975,14 +35972,19 @@ msgstr ""
"processo."
#: pretix/presale/templates/pretixpresale/event/order.html:55
#, fuzzy
#| msgid ""
#| "Please bookmark or save the link to this exact page if you want to access "
#| "your order later. We also sent you an email containing the link to the "
#| "address you specified."
msgid ""
"Please bookmark or save the link to this exact page if you want to access "
"your order later. We also sent you an email to the address you specified "
"containing the link to this page."
msgstr ""
"Por favor, guarda o link desta página, se quiseres aceder à tua encomenda "
"mais tarde. Também enviámos um e-mail para o endereço que indicaste com o "
"link para esta página."
"Por favor, guarda o link para esta página, caso queiras aceder ao teu pedido "
"mais tarde. Também iremos enviar-te um email com o link para o endereço que "
"indicaste."
#: pretix/presale/templates/pretixpresale/event/order.html:59
#, fuzzy

View File

@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
"PO-Revision-Date: 2025-12-10 15:49+0000\n"
"PO-Revision-Date: 2025-11-11 21:00+0000\n"
"Last-Translator: Ana Rute Pacheco Vivas <rute.vivas@om.org>\n"
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
"pretix/pretix-js/pt_PT/>\n"
@@ -798,7 +798,7 @@ msgstr ""
#: pretix/static/pretixpresale/js/ui/cart.js:90
msgid "Renew reservation"
msgstr "Renovar a reserva"
msgstr ""
#: pretix/static/pretixpresale/js/ui/main.js:194
msgid "The organizer keeps %(currency)s %(amount)s"

View File

@@ -8,20 +8,18 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
"PO-Revision-Date: 2025-12-09 22:00+0000\n"
"Last-Translator: Lachlan Struthers <lachlan.struthers@om.org>\n"
"Language-Team: Albanian <https://translate.pretix.eu/projects/pretix/pretix/"
"sq/>\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: sq\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.14.3\n"
#: pretix/_base_settings.py:87
msgid "English"
msgstr "Anglisht"
msgstr ""
#: pretix/_base_settings.py:88
msgid "German"
@@ -452,7 +450,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/mail.html:114
#: pretix/control/views/orders.py:1569
msgid "Order canceled"
msgstr "Porositja ësthë anuluar"
msgstr ""
#: pretix/api/webhooks.py:278 pretix/base/notifications.py:257
msgid "Order reactivated"
@@ -1409,7 +1407,7 @@ msgstr ""
#: pretix/plugins/checkinlists/exporters.py:827
#: pretix/plugins/checkinlists/exporters.py:828
msgid "Yes"
msgstr "Po"
msgstr ""
#: pretix/base/exporters/customers.py:100
#: pretix/base/exporters/customers.py:101 pretix/base/exporters/events.py:83
@@ -1433,7 +1431,7 @@ msgstr "Po"
#: pretix/plugins/checkinlists/exporters.py:827
#: pretix/plugins/checkinlists/exporters.py:828
msgid "No"
msgstr "Jo"
msgstr ""
#: pretix/base/exporters/dekodi.py:42 pretix/base/exporters/invoices.py:66
msgctxt "export_category"
@@ -2447,7 +2445,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:12
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:91
msgid "Product"
msgstr "Produkti"
msgstr ""
#: pretix/base/exporters/orderlist.py:619 pretix/base/models/vouchers.py:315
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:5
@@ -2785,7 +2783,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/cancel.html:20
#: pretix/control/views/item.py:971
msgid "Paid orders"
msgstr "Porositje të paguara"
msgstr ""
#: pretix/base/exporters/orderlist.py:1155 pretix/control/views/item.py:976
msgid "Pending orders"
@@ -3881,7 +3879,7 @@ msgstr ""
#: pretix/base/modelimport_vouchers.py:205 pretix/base/models/items.py:1256
#: pretix/base/models/vouchers.py:266 pretix/base/models/waitinglist.py:99
msgid "Product variation"
msgstr "Varianti i produktit"
msgstr ""
#: pretix/base/modelimport_orders.py:161
msgid "The variation can be specified by its internal ID or full name."
@@ -4280,19 +4278,19 @@ msgstr ""
#: pretix/base/models/checkin.py:336
msgid "Entry"
msgstr "Hyrje"
msgstr ""
#: pretix/base/models/checkin.py:337
msgid "Exit"
msgstr "Dalje"
msgstr ""
#: pretix/base/models/checkin.py:356
msgid "Unknown ticket"
msgstr "Biletë e panjohur"
msgstr ""
#: pretix/base/models/checkin.py:357
msgid "Ticket not paid"
msgstr "Bileta nuk është paguar"
msgstr ""
#: pretix/base/models/checkin.py:358
msgid "Forbidden by custom rule"
@@ -4300,23 +4298,23 @@ msgstr ""
#: pretix/base/models/checkin.py:359
msgid "Ticket code revoked/changed"
msgstr "Kodi i biletës është anuluar/ndryshuar"
msgstr ""
#: pretix/base/models/checkin.py:360
msgid "Information required"
msgstr "Informacion i domosdoshëm"
msgstr ""
#: pretix/base/models/checkin.py:361
msgid "Ticket already used"
msgstr "Bileta tashmë është përdorur"
msgstr ""
#: pretix/base/models/checkin.py:362
msgid "Ticket type not allowed here"
msgstr "Ky lloj bilete nuk lejohet këtu"
msgstr ""
#: pretix/base/models/checkin.py:363
msgid "Ticket code is ambiguous on list"
msgstr "Kodi i biletës është e paqartë në listë"
msgstr ""
#: pretix/base/models/checkin.py:364
msgid "Server error"
@@ -4324,15 +4322,15 @@ msgstr ""
#: pretix/base/models/checkin.py:365
msgid "Ticket blocked"
msgstr "Bileta u bllokua"
msgstr ""
#: pretix/base/models/checkin.py:366
msgid "Order not approved"
msgstr "Porositje nuk është aprovuar"
msgstr ""
#: pretix/base/models/checkin.py:367
msgid "Ticket not valid at this time"
msgstr "Bileta nuk është e vlefshme për momentin"
msgstr ""
#: pretix/base/models/checkin.py:368
msgid "Check-in annulled"
@@ -4462,7 +4460,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/organizers/gates.html:16
#: pretix/plugins/checkinlists/exporters.py:769
msgid "Gate"
msgstr "Porta"
msgstr ""
#: pretix/base/models/devices.py:131
#: pretix/control/templates/pretixcontrol/organizers/devices.html:83
@@ -5930,7 +5928,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:34
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:44
msgid "Canceled"
msgstr "e anuluar"
msgstr ""
#: pretix/base/models/memberships.py:134
#: pretix/control/templates/pretixcontrol/organizers/customer.html:117
@@ -6673,7 +6671,7 @@ msgstr ""
#: pretix/base/models/vouchers.py:204 pretix/control/views/vouchers.py:120
msgid "Redeemed"
msgstr "e përdorur"
msgstr ""
#: pretix/base/models/vouchers.py:209
msgid ""
@@ -7706,15 +7704,15 @@ msgstr ""
#: pretix/base/reldate.py:38
msgid "Event start"
msgstr "Fillimi i eventit"
msgstr ""
#: pretix/base/reldate.py:39
msgid "Event end"
msgstr "Mbarimi i eventit"
msgstr ""
#: pretix/base/reldate.py:40
msgid "Event admission"
msgstr "Hyrja në event"
msgstr ""
#: pretix/base/reldate.py:41
msgid "Presale start"
@@ -12891,7 +12889,7 @@ msgstr ""
#: pretix/plugins/reports/exporters.py:391
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7
msgid "Approval pending"
msgstr "Duke pritur aprovimin"
msgstr ""
#: pretix/control/forms/filter.py:247
msgid "Follow-up configured"
@@ -13159,7 +13157,7 @@ msgstr ""
#: pretix/control/forms/filter.py:2117
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:51
msgid "Valid"
msgstr "e vlefshme"
msgstr ""
#: pretix/control/forms/filter.py:2118
msgid "Unredeemed"
@@ -16429,7 +16427,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:75
#: pretix/presale/templates/pretixpresale/event/position_change.html:29
msgid "Continue"
msgstr "Vazhdoni"
msgstr ""
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html:8
msgid "Authorize an application"
@@ -16677,7 +16675,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/postmessage.html:27
#: pretix/presale/templates/pretixpresale/waiting.html:42
msgid "If this takes longer than a few minutes, please contact us."
msgstr "Nëse kalon më shumë se disa minuta, ju lutemi t'na kontaktoni."
msgstr ""
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:4
#: pretix/control/templates/pretixcontrol/organizers/devices.html:71
@@ -16907,7 +16905,7 @@ msgstr[1] ""
#: pretix/presale/templates/pretixpresale/event/position_change.html:24
#: pretix/presale/templates/pretixpresale/event/position_modify.html:44
msgid "Cancel"
msgstr "Anuloni"
msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:27
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html:24
@@ -17021,7 +17019,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:14
#: pretix/plugins/checkinlists/exporters.py:770
msgid "Result"
msgstr "Rezultati"
msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:78
#: pretix/control/templates/pretixcontrol/order/index.html:437
@@ -17365,7 +17363,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:68
msgid "Additional information required"
msgstr "Më shumë informacione kërkohen"
msgstr ""
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:70
msgid ""
@@ -18479,7 +18477,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/event/plugins.html:34
#: pretix/control/templates/pretixcontrol/organizers/plugins.html:34
msgid "Search results"
msgstr "Rezultatet e kërkimit"
msgstr ""
#: pretix/control/templates/pretixcontrol/event/plugins.html:56
#: pretix/control/templates/pretixcontrol/organizers/plugins.html:56
@@ -19745,7 +19743,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:355
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:364
msgid "minutes"
msgstr "minuta"
msgstr ""
#: pretix/control/templates/pretixcontrol/item/index.html:229
msgid "hours"
@@ -21016,7 +21014,7 @@ msgstr ""
#: pretix/plugins/reports/exporters.py:969
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:469
msgid "Total"
msgstr "Shuma totale"
msgstr ""
#: pretix/control/templates/pretixcontrol/order/index.html:789
#: pretix/presale/templates/pretixpresale/event/order.html:210
@@ -23137,7 +23135,7 @@ msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:107
msgid "Duplicate"
msgstr "Kopjoni"
msgstr ""
#: pretix/control/templates/pretixcontrol/pdf/index.html:117
msgid "Undo"
@@ -27331,7 +27329,7 @@ msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:80
msgid "Comment:"
msgstr "Komente:"
msgstr ""
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:98
msgid "No order code detected"
@@ -27574,7 +27572,7 @@ msgstr ""
#: pretix/plugins/paypal2/payment.py:1097
#: pretix/plugins/paypal2/payment.py:1098 pretix/plugins/stripe/payment.py:1816
msgid "PayPal"
msgstr "PayPal"
msgstr ""
#: pretix/plugins/paypal/apps.py:53
msgid ""
@@ -29014,9 +29012,8 @@ msgid "Credit card payments"
msgstr ""
#: pretix/plugins/stripe/payment.py:342 pretix/plugins/stripe/payment.py:1527
#, fuzzy
msgid "iDEAL"
msgstr "iDEAL"
msgstr ""
#: pretix/plugins/stripe/payment.py:344 pretix/plugins/stripe/payment.py:352
#: pretix/plugins/stripe/payment.py:360 pretix/plugins/stripe/payment.py:395
@@ -29035,14 +29032,12 @@ msgid "Alipay"
msgstr ""
#: pretix/plugins/stripe/payment.py:358 pretix/plugins/stripe/payment.py:1564
#, fuzzy
msgid "Bancontact"
msgstr "Bancontact"
msgstr ""
#: pretix/plugins/stripe/payment.py:366
#, fuzzy
msgid "SEPA Direct Debit"
msgstr "Debit direkt me SEPA"
msgstr ""
#: pretix/plugins/stripe/payment.py:369
msgid ""
@@ -29077,14 +29072,12 @@ msgid "Multibanco"
msgstr ""
#: pretix/plugins/stripe/payment.py:409 pretix/plugins/stripe/payment.py:1730
#, fuzzy
msgid "Przelewy24"
msgstr "Przelewy24"
msgstr ""
#: pretix/plugins/stripe/payment.py:417 pretix/plugins/stripe/payment.py:1769
#, fuzzy
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgstr ""
#: pretix/plugins/stripe/payment.py:433 pretix/plugins/stripe/payment.py:1824
msgid "Swish"
@@ -29228,9 +29221,8 @@ msgid "giropay via Stripe"
msgstr ""
#: pretix/plugins/stripe/payment.py:1480
#, fuzzy
msgid "giropay"
msgstr "giropay"
msgstr ""
#: pretix/plugins/stripe/payment.py:1483
msgid ""
@@ -32452,7 +32444,7 @@ msgstr ""
#: pretix/presale/templates/pretixpresale/postmessage.html:21
#: pretix/presale/templates/pretixpresale/waiting.html:22
msgid "We are processing your request …"
msgstr "Ne po e proçesojmë kërkesën tuaj …"
msgstr ""
#: pretix/presale/utils.py:271 pretix/presale/utils.py:417
#: pretix/presale/utils.py:418

View File

@@ -3,159 +3,137 @@
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
"PO-Revision-Date: 2025-12-09 22:00+0000\n"
"Last-Translator: Lachlan Struthers <lachlan.struthers@om.org>\n"
"Language-Team: Albanian <https://translate.pretix.eu/projects/pretix/"
"pretix-js/sq/>\n"
"Language: sq\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \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.14.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:68
msgid "Marked as paid"
msgstr "Shënuar se u pagua"
msgstr ""
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:76
msgid "Comment:"
msgstr "Komente:"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
msgid "PayPal"
msgstr "PayPal"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
msgid "Venmo"
msgstr "Venmo"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
#: pretix/static/pretixpresale/js/walletdetection.js:38
#, fuzzy
msgid "Apple Pay"
msgstr "Apple Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
#, fuzzy
msgid "Itaú"
msgstr "Itaú"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
#, fuzzy
msgid "PayPal Credit"
msgstr "PayPal Credit"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
msgid "Credit Card"
msgstr "Kartë Krediti"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
msgid "PayPal Pay Later"
msgstr "Bëj PayPal Pay më vonë"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
#, fuzzy
msgid "iDEAL"
msgstr "iDEAL"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
#, fuzzy
msgid "SEPA Direct Debit"
msgstr "Debit direkt me SEPA"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
#, fuzzy
msgid "Bancontact"
msgstr "Bancontact"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:44
#, fuzzy
msgid "giropay"
msgstr "giropay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
#, fuzzy
msgid "SOFORT"
msgstr "SOFORT"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
#, fuzzy
msgid "eps"
msgstr "eps"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
#, fuzzy
msgid "MyBank"
msgstr "MyBank"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
#, fuzzy
msgid "Przelewy24"
msgstr "Przelewy24"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
#, fuzzy
msgid "Verkkopankki"
msgstr "Verkkopankki"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
#, fuzzy
msgid "PayU"
msgstr "PayU"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
#, fuzzy
msgid "BLIK"
msgstr "BLIK"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
#, fuzzy
msgid "Trustly"
msgstr "Trustly"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
#, fuzzy
msgid "Zimpler"
msgstr "Zimpler"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
#, fuzzy
msgid "Maxima"
msgstr "Maxima"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
#, fuzzy
msgid "OXXO"
msgstr "OXXO"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
#, fuzzy
msgid "Boleto"
msgstr "Boleto"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
#, fuzzy
msgid "WeChat Pay"
msgstr "WeChat Pay"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
#, fuzzy
msgid "Mercado Pago"
msgstr "Mercado Pago"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:167
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:50
#: pretix/static/pretixpresale/js/ui/cart.js:89
msgid "Continue"
msgstr "Vazhdoni"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:225
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:244
@@ -164,224 +142,222 @@ msgstr "Vazhdoni"
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:317
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:341
msgid "Confirming your payment …"
msgstr "Duke e konfirmuar pagesën …"
msgstr ""
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
msgid "Payment method unavailable"
msgstr "Metodë e padisponueshme të pagesës"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
msgid "Placed orders"
msgstr "Porositje të bëra"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
msgid "Paid orders"
msgstr "Porositje të paguara"
msgstr ""
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:27
msgid "Total revenue"
msgstr "Të ardhurat totale"
msgstr ""
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:15
msgid "Contacting Stripe …"
msgstr "Duke e kontaktuar Stripe …"
msgstr ""
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:72
msgid "Total"
msgstr "Shuma totale"
msgstr ""
#: pretix/plugins/stripe/static/pretixplugins/stripe/pretix-stripe.js:291
msgid "Contacting your bank …"
msgstr "Duke e kontaktuar bankën tuaj …"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:30
msgid "Select a check-in list"
msgstr "Zgjidhni një listë check-in"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:31
msgid "No active check-in lists found."
msgstr "Nuk u gjet asnjë listë check-in."
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:32
msgid "Switch check-in list"
msgstr "Shkëmbeni listë check-in"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:33
msgid "Search results"
msgstr "Rezultatet e kërkimit"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:34
msgid "No tickets found"
msgstr "Nuk u gjetën bileta"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:35
msgid "Result"
msgstr "Rezultati"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:36
msgid "This ticket requires special attention"
msgstr "Kjo biletë duhet kujdes të veçantë"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:37
msgid "Switch direction"
msgstr "Ndryshoni drejtimin"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:38
msgid "Entry"
msgstr "Hyrje"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:39
msgid "Exit"
msgstr "Dalje"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:40
msgid "Scan a ticket or search and press return…"
msgstr "Skanoni një biletë ose kërkoni dhe shtypni butonin 'Enter'…"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:41
msgid "Load more"
msgstr "Ngarkoni më shumë"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:42
msgid "Valid"
msgstr "e vlefshme"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:43
msgid "Unpaid"
msgstr "e papaguar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:44
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:45
msgid "Canceled"
msgstr "e anuluar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
msgid "Confirmed"
msgstr "e konfirmuar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
msgid "Approval pending"
msgstr "Duke pritur aprovimin"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
msgid "Redeemed"
msgstr "e përdorur"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:49
msgid "Cancel"
msgstr "Anuloni"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:51
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:60
msgid "Ticket not paid"
msgstr "Bileta nuk është paguar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:52
msgid "This ticket is not yet paid. Do you want to continue anyways?"
msgstr "Kjo biletë ende nuk është paguar. A dëshironi të vazhdoni gjithsesi?"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:53
msgid "Additional information required"
msgstr "Më shumë informacione kërkohen"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:54
msgid "Valid ticket"
msgstr "Biletë të vlefshme"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:55
msgid "Exit recorded"
msgstr "Dalja u regjistrua"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:56
msgid "Ticket already used"
msgstr "Bileta tashmë është përdorur"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:57
msgid "Information required"
msgstr "Informacion i domosdoshëm"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:58
msgid "Unknown ticket"
msgstr "Biletë e panjohur"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:59
msgid "Ticket type not allowed here"
msgstr "Ky lloj bilete nuk lejohet këtu"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:61
msgid "Entry not allowed"
msgstr "Hyrja nuk lejohet"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:62
msgid "Ticket code revoked/changed"
msgstr "Kodi i biletës është anuluar/ndryshuar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
msgid "Ticket blocked"
msgstr "Bileta u bllokua"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
msgid "Ticket not valid at this time"
msgstr "Bileta nuk është e vlefshme për momentin"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
msgid "Order canceled"
msgstr "Porositja ësthë anuluar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
msgid "Ticket code is ambiguous on list"
msgstr "Kodi i biletës është e paqartë në listë"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
msgid "Order not approved"
msgstr "Porositje nuk është aprovuar"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:68
msgid "Checked-in Tickets"
msgstr "Bileta të regjistruara"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:69
msgid "Valid Tickets"
msgstr "Bileta të vlefshme"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:70
msgid "Currently inside"
msgstr "Aktualisht brenda"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:71
#: pretix/static/pretixcontrol/js/ui/question.js:136
#: pretix/static/pretixpresale/js/ui/questions.js:271
msgid "Yes"
msgstr "Po"
msgstr ""
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:72
#: pretix/static/pretixcontrol/js/ui/question.js:137
#: pretix/static/pretixpresale/js/ui/questions.js:271
msgid "No"
msgstr "Jo"
msgstr ""
#: pretix/static/lightbox/js/lightbox.js:96
msgid "close"
msgstr "Mbyllni"
msgstr ""
#: pretix/static/pretixbase/js/addressform.js:98
#: pretix/static/pretixpresale/js/ui/main.js:529
msgid "required"
msgstr "të domosdoshme"
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:13
msgid ""
"Your request is currently being processed. Depending on the size of your "
"event, this might take up to a few minutes."
msgstr ""
"Këkesa juaj po proçesohet tani. Në varësi të masës së eventit tuaj, mund të "
"kërkojë disa minuta."
#: pretix/static/pretixbase/js/asynctask.js:17
msgid "Your request has been queued on the server and will soon be processed."
msgstr "Kërkesa juaj është në pritje në server dhe do të proçesohet së shpejti."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:21
msgid ""
@@ -389,41 +365,34 @@ msgid ""
"If this takes longer than two minutes, please contact us or go back in your "
"browser and try again."
msgstr ""
"Kërkesa juaj arriti në server por ende presim të proçesohet. Nëse kalon më "
"shumë se dy minuta, ju lutemi t'na kontaktoni ose të ktheheni më përpara dhe "
"të provoni përsëri."
#: pretix/static/pretixbase/js/asynctask.js:125
#: pretix/static/pretixbase/js/asynctask.js:182
#: pretix/static/pretixbase/js/asynctask.js:186
#: pretix/static/pretixcontrol/js/ui/mail.js:24
msgid "An error of type {code} occurred."
msgstr "Një gabim të llojit {kodi} ka ndodhur."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:128
msgid ""
"We currently cannot reach the server, but we keep trying. Last error code: "
"{code}"
msgstr ""
"Nuk mund t'a kontaktojmë serverin për momentin, por vazhdojmë t'a provojmë. "
"Kodi gabimi i fundit: {kodi}"
#: pretix/static/pretixbase/js/asynctask.js:162
#: pretix/static/pretixcontrol/js/ui/mail.js:21
msgid "The request took too long. Please try again."
msgstr "Kërkesa juaj kërkonte tepër kohë. Ju lutemi të provoni përsëri."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:188
#: pretix/static/pretixcontrol/js/ui/mail.js:26
msgid ""
"We currently cannot reach the server. Please try again. Error code: {code}"
msgstr ""
"Nuk mund t'a kontaktojmë serverin për momentin. Ju lutemi, provoni përsëri. "
"Kodi gabimi i fundit: {kodi}"
#: pretix/static/pretixbase/js/asynctask.js:216
msgid "We are processing your request …"
msgstr "Ne po e proçesojmë kërkesën tuaj …"
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:219
msgid ""
@@ -431,169 +400,166 @@ msgid ""
"than one minute, please check your internet connection and then reload this "
"page and try again."
msgstr ""
"Tani po e dërgojmë kërkesën tuaj në server. Nëse kalon më shumë se një "
"minutë, ju lutemi t'a kontrolloni lidhjen tuaj në internet dhe pastak t'a "
"rifreskoni këtë faqe që të provoni përsëri."
#: pretix/static/pretixbase/js/asynctask.js:276
msgid "If this takes longer than a few minutes, please contact us."
msgstr "Nëse kalon më shumë se disa minuta, ju lutemi t'na kontaktoni."
msgstr ""
#: pretix/static/pretixbase/js/asynctask.js:331
msgid "Close message"
msgstr "Mbyllni mesazhin"
msgstr ""
#: pretix/static/pretixcontrol/js/clipboard.js:23
msgid "Copied!"
msgstr "E kopjuar!"
msgstr ""
#: pretix/static/pretixcontrol/js/clipboard.js:29
msgid "Press Ctrl-C to copy!"
msgstr "Shtypni Ctrl+C për të kopjuar!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:12
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:18
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:24
msgid "is one of"
msgstr "është një nga"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:30
msgid "is before"
msgstr "është para"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:34
msgid "is after"
msgstr "është pas"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
msgid "="
msgstr "="
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
msgid "Product"
msgstr "Produkti"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:103
msgid "Product variation"
msgstr "Varianti i produktit"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
msgid "Gate"
msgstr "Porta"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
msgid "Current date and time"
msgstr "Datë dhe orë aktuale"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
msgstr "Dita aktuale e javës (1 = Të hënën, 7 = Të dielën)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
msgid "Current entry status"
msgstr "Gjendja aktuale e hyrjes"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
msgid "Number of previous entries"
msgstr "Shuma e hyrjeve të mëparshme"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:127
msgid "Number of previous entries since midnight"
msgstr "Shuma e hyrjeve të mëparshme nga mesnata"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
msgid "Number of previous entries since"
msgstr "Shuma e hyrjeve të mëparshme nga"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
msgid "Number of previous entries before"
msgstr "Shuma e hyrjeve të mëparshme përpara"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:139
msgid "Number of days with a previous entry"
msgstr "Shuma e ditëve me një hyrje të mëparshme"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
msgid "Number of days with a previous entry since"
msgstr "Shuma e ditëve me një hyrje të mëparshme nga"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
msgid "Number of days with a previous entry before"
msgstr "Shuma e ditëve me një hyrje të mëparshme përpara"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
msgid "Minutes since last entry (-1 on first entry)"
msgstr "Minuta nga hyrja e fundit (-1 në hyrjen e parë)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:155
msgid "Minutes since first entry (-1 on first entry)"
msgstr "Minuta nga hyrja e parë (-1 në hyrjen e parë)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:182
msgid "All of the conditions below (AND)"
msgstr "Të gjitha gjendjet më poshtë (DHE)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:183
msgid "At least one of the conditions below (OR)"
msgstr "Të paktën një nga gjendjet më poshtë (OSE)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:184
msgid "Event start"
msgstr "Fillimi i eventit"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:185
msgid "Event end"
msgstr "Mbarimi i eventit"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:186
msgid "Event admission"
msgstr "Hyrja në event"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:187
msgid "custom date and time"
msgstr "datë dhe orë e kustomizuar"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:188
msgid "custom time"
msgstr "orë e kustomizuar"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:189
msgid "Tolerance (minutes)"
msgstr "Toleranca (minuta)"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:190
msgid "Add condition"
msgstr "Shtoni gjendje"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:191
msgid "minutes"
msgstr "minuta"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
msgid "Duplicate"
msgstr "Kopjoni"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
msgctxt "entry_status"
msgid "present"
msgstr "pranishëm"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
msgctxt "entry_status"
msgid "absent"
msgstr "munguar"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
msgid "Error: Product not found!"
msgstr "Gabim: Produkti nuk u gjet!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
msgid "Error: Variation not found!"
msgstr "Gabim: Varianti nuk u gjet!"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:171
msgid "Check-in QR"
msgstr "Kodi QR për check-in"
msgstr ""
#: pretix/static/pretixcontrol/js/ui/editor.js:549
msgid "The PDF background file could not be loaded for the following reason:"

View File

@@ -41,20 +41,15 @@ for app in apps.get_app_configs():
if hasattr(app, 'PretixPluginMeta'):
if importlib.util.find_spec(app.name + '.urls'):
urlmod = importlib.import_module(app.name + '.urls')
single_plugin_patterns = []
if hasattr(urlmod, 'event_patterns'):
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
single_plugin_patterns.append(
re_path(r'^(?P<event>[^/]+)/', include(patterns))
)
if hasattr(urlmod, 'organizer_patterns'):
single_plugin_patterns += plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
if single_plugin_patterns:
raw_plugin_patterns.append(
re_path(r'', include((single_plugin_patterns, app.label)))
re_path(r'^(?P<event>[^/]+)/', include((patterns, app.label)))
)
if hasattr(urlmod, 'organizer_patterns'):
patterns = plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
raw_plugin_patterns.append(
re_path(r'', include((patterns, app.label)))
)
plugin_patterns = [

View File

@@ -42,20 +42,15 @@ for app in apps.get_app_configs():
if hasattr(app, 'PretixPluginMeta'):
if importlib.util.find_spec(app.name + '.urls'):
urlmod = importlib.import_module(app.name + '.urls')
single_plugin_patterns = []
if hasattr(urlmod, 'organizer_patterns'):
single_plugin_patterns += plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
if hasattr(urlmod, 'event_patterns'):
plugin_event_patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
single_plugin_patterns.append(
re_path(r'^(?P<event>[^/]+)/', include(plugin_event_patterns))
)
if single_plugin_patterns:
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
raw_plugin_patterns.append(
re_path(r'', include((single_plugin_patterns, app.label)))
re_path(r'^(?P<event>[^/]+)/', include((patterns, app.label)))
)
if hasattr(urlmod, 'organizer_patterns'):
patterns = plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
raw_plugin_patterns.append(
re_path(r'', include((patterns, app.label)))
)
plugin_patterns = [

View File

@@ -1,71 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# 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/>.
#
from django.utils.translation import gettext_lazy as _
from lxml import etree
def parse(file):
# Spec: https://www.ebics.de/de/datenformate
data = file.read()
root = etree.fromstring(data)
statements = root.findall("{*}BkToCstmrStmt/{*}Stmt")
if not statements:
raise ValueError(_("Empty file or unknown format."))
def get_text(findall_result):
if len(findall_result) == 1:
return findall_result[0].text
return ""
rows = []
for stmt in statements:
for ntry in stmt.findall("{*}Ntry"):
minus = ""
otherparty = "Dbtr"
if ntry.findall("{*}CdtDbtInd")[0].text == "DBIT":
otherparty = "Cdtr"
minus = "-"
reference_parts = [
get_text(ntry.findall("{*}NtryDtls/{*}TxDtls/{*}RmtInf/{*}Ustrd")),
get_text(ntry.findall("{*}NtryDtls/{*}TxDtls/{*}Refs/{*}EndToEndId")),
get_text(ntry.findall("{*}NtryDtls/{*}TxDtls/{*}Refs/{*}InstructionIdentification")),
]
if ntry.findall("{*}NtryDtls/{*}Btch"):
# Batch booking, we do not support splitting yet
reference_parts.insert(0, get_text(ntry.findall("{*}NtryDtls/{*}Btch/{*}PmtInfId")))
row = {
'amount': minus + ntry.findall("{*}Amt")[0].text,
'date': get_text(ntry.findall("{*}BookgDt/{*}Dt")),
'reference': "\n".join(filter(lambda a: bool(a) and a != "NOTPROVIDED", reference_parts))
}
if ext_id := get_text(ntry.findall("{*}AcctSvcrRef")):
row['external_id'] = ext_id
if iban := get_text(ntry.findall(f"{{*}}NtryDtls/{{*}}TxDtls/{{*}}RltdPties/{{*}}{otherparty}Acct/{{*}}Id/{{*}}IBAN")):
row['iban'] = iban
if bic := get_text(ntry.findall(f"{{*}}NtryDtls/{{*}}TxDtls/{{*}}RltdAgts/{{*}}{otherparty}Agt/{{*}}FinInstnId/{{*}}BICFI")):
row['bic'] = bic
if payer := get_text(ntry.findall(f"{{*}}NtryDtls/{{*}}TxDtls/{{*}}RltdPties/{{*}}{otherparty}/{{*}}Nm")):
row['payer'] = payer
rows.append(row)
return rows

View File

@@ -46,12 +46,12 @@ from i18nfield.forms import I18nTextInput
from i18nfield.strings import LazyI18nString
from localflavor.generic.forms import BICFormField, IBANFormField
from localflavor.generic.validators import IBANValidator
from text_unidecode import unidecode
from pretix.base.forms import I18nMarkdownTextarea
from pretix.base.models import InvoiceAddress, Order, OrderPayment, OrderRefund
from pretix.base.payment import BasePaymentProvider
from pretix.base.templatetags.money import money_filter
from pretix.helpers.payment import generate_payment_qr_codes
from pretix.plugins.banktransfer.templatetags.ibanformat import ibanformat
from pretix.presale.views.cart import cart_session
@@ -313,6 +313,51 @@ class BankTransfer(BasePaymentProvider):
t += str(self.settings.get('bank_details', as_type=LazyI18nString))
return t
def swiss_qrbill(self, payment):
if not self.settings.get('bank_details_sepa_iban') or not self.settings.get('bank_details_sepa_iban')[:2] in ('CH', 'LI'):
return
if self.event.currency not in ('EUR', 'CHF'):
return
if not self.event.settings.invoice_address_from or not self.event.settings.invoice_address_from_country:
return
data_fields = [
'SPC',
'0200',
'1',
self.settings.get('bank_details_sepa_iban'),
'K',
self.settings.get('bank_details_sepa_name')[:70],
self.event.settings.invoice_address_from.replace('\n', ', ')[:70],
(self.event.settings.invoice_address_from_zipcode + ' ' + self.event.settings.invoice_address_from_city)[:70],
'',
'',
str(self.event.settings.invoice_address_from_country),
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
'', # rfu
str(payment.amount),
self.event.currency,
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'', # debtor address
'NON',
'', # structured reference
self._code(payment.order),
'EPD',
]
data_fields = [unidecode(d or '') for d in data_fields]
return '\r\n'.join(data_fields)
def payment_pending_render(self, request: HttpRequest, payment: OrderPayment):
template = get_template('pretixplugins/banktransfer/pending.html')
ctx = {
@@ -322,18 +367,13 @@ class BankTransfer(BasePaymentProvider):
'amount': payment.amount,
'payment_info': payment.info_data,
'settings': self.settings,
'payment_qr_codes': generate_payment_qr_codes(
event=self.event,
code=self._code(payment.order),
amount=payment.amount,
bank_details_sepa_bic=self.settings.get('bank_details_sepa_bic'),
bank_details_sepa_name=self.settings.get('bank_details_sepa_name'),
bank_details_sepa_iban=self.settings.get('bank_details_sepa_iban'),
) if self.settings.bank_details_type == "sepa" else None,
'swiss_qrbill': self.swiss_qrbill(payment),
'eu_barcodes': self.event.currency == 'EUR',
'pending_description': self.settings.get('pending_description', as_type=LazyI18nString),
'details': self.settings.get('bank_details', as_type=LazyI18nString),
'has_invoices': payment.order.invoices.exists(),
}
ctx['any_barcodes'] = ctx['swiss_qrbill'] or ctx['eu_barcodes']
return template.render(ctx, request=request)
def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:

View File

@@ -34,10 +34,8 @@
import json
import logging
import operator
import re
from decimal import Decimal
from functools import reduce
import dateutil.parser
from celery.exceptions import MaxRetriesExceededError
@@ -119,26 +117,20 @@ def _find_order_for_code(base_qs, code):
pass
def _find_order_for_invoice_id(base_qs, prefixes, number):
def _find_order_for_invoice_id(base_qs, prefix, number):
try:
# Working with __iregex here is an experiment, if this turns out to be too slow in production
# we might need to switch to a different approach.
r = [
Q(
prefix__istartswith=prefix, # redundant, but hopefully makes it a little faster
full_invoice_no__iregex=prefix + r'[\- ]*0*' + number
)
for prefix in set(prefixes)
]
return base_qs.select_related('order').get(
reduce(operator.or_, r)
prefix__istartswith=prefix, # redundant, but hopefully makes it a little faster
full_invoice_no__iregex=prefix + r'[\- ]*0*' + number
).order
except (Invoice.DoesNotExist, Invoice.MultipleObjectsReturned):
pass
@transaction.atomic
def _handle_transaction(trans: BankTransaction, matches: tuple, regex_match_to_slug, event: Event = None, organizer: Organizer = None):
def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = None, organizer: Organizer = None):
orders = []
if event:
for slug, code in matches:
@@ -147,19 +139,18 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, regex_match_to_s
if order.code not in {o.code for o in orders}:
orders.append(order)
else:
order = _find_order_for_invoice_id(Invoice.objects.filter(event=event), (slug, regex_match_to_slug.get(slug, slug)), code)
order = _find_order_for_invoice_id(Invoice.objects.filter(event=event), slug, code)
if order and order.code not in {o.code for o in orders}:
orders.append(order)
else:
qs = Order.objects.filter(event__organizer=organizer)
for slug, code in matches:
original_slug = regex_match_to_slug.get(slug, slug)
order = _find_order_for_code(qs.filter(Q(event__slug__iexact=slug) | Q(event__slug__iexact=original_slug)), code)
order = _find_order_for_code(qs.filter(event__slug__iexact=slug), code)
if order:
if order.code not in {o.code for o in orders}:
orders.append(order)
else:
order = _find_order_for_invoice_id(Invoice.objects.filter(event__organizer=organizer), (slug, original_slug), code)
order = _find_order_for_invoice_id(Invoice.objects.filter(event__organizer=organizer), slug, code)
if order and order.code not in {o.code for o in orders}:
orders.append(order)
@@ -375,37 +366,22 @@ def process_banktransfers(self, job: int, data: list) -> None:
transactions = _get_unknown_transactions(job, data, **job.owner_kwargs)
# Match order codes
regex_match_to_slug = {}
code_len_agg = Order.objects.filter(event__organizer=job.organizer).annotate(
clen=Length('code')
).aggregate(min=Min('clen'), max=Max('clen'))
if job.event:
prefixes = {job.event.slug.upper(), job.event.slug.upper().replace("-", "")}
if "-" in job.event.slug:
regex_match_to_slug[job.event.slug.upper().replace("-", "")] = job.event.slug
prefixes = {job.event.slug.upper()}
else:
prefixes = set()
for e in job.organizer.events.all():
prefixes.add(e.slug.upper())
if "-" in e.slug:
prefixes.add(e.slug.upper().replace("-", ""))
regex_match_to_slug[e.slug.upper().replace("-", "")] = e.slug
prefixes = {e.slug.upper() for e in job.organizer.events.all()}
# Match invoice numbers
inr_len_agg = Invoice.objects.filter(event__organizer=job.organizer).annotate(
clen=Length('invoice_no')
).aggregate(min=Min('clen'), max=Max('clen'))
if job.event:
invoice_prefixes = Invoice.objects.filter(event=job.event)
prefixes |= {p.rstrip(' -') for p in Invoice.objects.filter(event=job.event).distinct().values_list('prefix', flat=True)}
else:
invoice_prefixes = Invoice.objects.filter(event__organizer=job.organizer)
for p in invoice_prefixes.order_by().distinct().values_list('prefix', flat=True):
prefix = p.rstrip(" -")
prefixes.add(prefix)
if "-" in prefix:
prefix_nodash = prefix.replace("-", "")
prefixes.add(prefix_nodash)
regex_match_to_slug[prefix_nodash] = prefix
prefixes |= {p.rstrip(' -') for p in Invoice.objects.filter(event__organizer=job.organizer).distinct().values_list('prefix', flat=True)}
pattern = re.compile(
"(%s)[ \\-_]*([A-Z0-9]{%s,%s})" % (
@@ -419,11 +395,6 @@ def process_banktransfers(self, job: int, data: list) -> None:
)
for trans in transactions:
if trans.amount == Decimal("0.00"):
# Ignore all zero-valued transactions
trans.state = BankTransaction.STATE_DISCARDED
trans.save()
continue
# Whitespace in references is unreliable since linebreaks and spaces can occur almost anywhere, e.g.
# DEMOCON-123\n45 should be matched to DEMOCON-12345. However, sometimes whitespace is important,
# e.g. when there are two references. "DEMOCON-12345 DEMOCON-45678" would otherwise be parsed as
@@ -438,9 +409,9 @@ def process_banktransfers(self, job: int, data: list) -> None:
if matches:
if job.event:
_handle_transaction(trans, matches, regex_match_to_slug, event=job.event)
_handle_transaction(trans, matches, event=job.event)
else:
_handle_transaction(trans, matches, regex_match_to_slug, organizer=job.organizer)
_handle_transaction(trans, matches, organizer=job.organizer)
else:
trans.state = BankTransaction.STATE_NOMATCH
trans.save()

View File

@@ -1,6 +1,7 @@
{% load i18n %}
{% load l10n %}
{% load commadecimal %}
{% load static %}
{% load dotdecimal %}
{% load ibanformat %}
{% load money %}
@@ -16,7 +17,7 @@
{% endblocktrans %}</p>
<div class="row">
<div class="{% if payment_qr_codes %}col-md-6{% else %}col-md-12{% endif %} col-xs-12">
<div class="{% if settings.bank_details_type == "sepa" %}col-md-6{% else %}col-md-12{% endif %} col-xs-12">
<dl class="dl-horizontal">
<dt>{% trans "Reference code (important):" %}</dt><dd><b>{{ code }}</b></dd>
<dt>{% trans "Amount:" %}</dt><dd>{{ amount|money:event.currency }}</dd>
@@ -35,7 +36,94 @@
{% trans "We will send you an email as soon as we received your payment." %}
</p>
</div>
{% if payment_qr_codes %}
{% include "pretixpresale/event/payment_qr_codes.html" %}
{% if settings.bank_details_type == "sepa" and any_barcodes %}
<div class="tabcontainer col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
<div id="banktransfer_qrcodes_tabs_content" class="tabpanels blank-after">
{% if swiss_qrbill %}
<div id="banktransfer_qrcodes_qrbill"
role="tabpanel"
tabindex="0"
aria-labelledby="banktransfer_qrcodes_qrbill_tab"
>
<div class="banktransfer-swiss-cross-overlay" role="figure" aria-labelledby="banktransfer_qrcodes_qrbill_tab banktransfer_qrcodes_label">
<svg class="banktransfer-swiss-cross" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.8 19.8"><path stroke="#fff" stroke-width="1.436" d="M.7.7h18.4v18.4H.7z"/><path fill="#fff" d="M8.3 4h3.3v11H8.3z"/><path fill="#fff" d="M4.4 7.9h11v3.3h-11z"/></svg>
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">{{swiss_qrbill}}</script>
</div>
</div>
{% endif %}
{% if eu_barcodes %}
<div id="banktransfer_qrcodes_girocode"
role="tabpanel"
tabindex="0"
{{ swiss_qrbill|yesno:'hidden,' }}
aria-labelledby="banktransfer_qrcodes_girocode_tab"
>
<div role="figure" aria-labelledby="banktransfer_qrcodes_girocode_tab banktransfer_qrcodes_label">
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">BCD
002
2
SCT
{{ settings.bank_details_sepa_bic }}
{{ settings.bank_details_sepa_name|unidecode }}
{{ settings.bank_details_sepa_iban }}
{{ event.currency }}{{ amount|dotdecimal }}
{{ code }}
</script>
</div>
</div>
<div id="banktransfer_qrcodes_bezahlcode"
role="tabpanel"
tabindex="0"
hidden
aria-labelledby="banktransfer_qrcodes_bezahlcode_tab"
>
<a aria-label="{% trans "Open BezahlCode in your banking app to start the payment process." %}" href="bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}">
<div role="figure" aria-labelledby="banktransfer_qrcodes_bezahlcode_tab banktransfer_qrcodes_label">
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">bank://singlepaymentsepa?name={{ settings.bank_details_sepa_name|urlencode }}&iban={{ settings.bank_details_sepa_iban }}&bic={{ settings.bank_details_sepa_bic }}&amount={{ amount|commadecimal }}&reason={{ code }}&currency={{ event.currency }}</script>
</div>
</a>
</div>
{% endif %}
</div>
<div id="banktransfer_qrcodes_tabs" role="tablist" aria-labelledby="banktransfer_qrcodes_label" class="blank-after btn-group">
{% if swiss_qrbill %}
<button
class="btn btn-default"
id="banktransfer_qrcodes_qrbill_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_qrbill"
aria-selected="true"
tabindex="-1">QR-bill</button>
{% endif %}
{% if eu_barcodes %}
<button
class="btn btn-default"
id="banktransfer_qrcodes_girocode_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_girocode"
aria-selected="{{ swiss_qrbill|yesno:"false,true" }}"
tabindex="-1">EPC-QR</button>
<button
class="btn btn-default"
id="banktransfer_qrcodes_bezahlcode_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_bezahlcode"
aria-selected="false"
tabindex="-1">BezahlCode</button>
{% endif %}
</div>
<p class="text-muted" id="banktransfer_qrcodes_label">
{% trans "Scan the QR code with your banking app" %}
</p>
</div>
{% endif %}
</div>
</div>
{% if swiss_qrbill %}
<link rel="stylesheet" href="{% static "pretixplugins/banktransfer/swisscross.css" %}">
{% endif %}

View File

@@ -66,7 +66,7 @@ from pretix.control.permissions import (
)
from pretix.control.views.organizer import OrganizerDetailViewMixin
from pretix.helpers.json import CustomJSONEncoder
from pretix.plugins.banktransfer import camtimport, csvimport, mt940import
from pretix.plugins.banktransfer import csvimport, mt940import
from pretix.plugins.banktransfer.models import (
BankImportJob, BankTransaction, RefundExport,
)
@@ -419,9 +419,6 @@ class ImportView(ListView):
):
return self.process_mt940()
elif 'file' in self.request.FILES and '.xml' in self.request.FILES.get('file').name.lower():
return self.process_camt()
elif self.request.FILES.get('file') is None:
messages.error(self.request, _('You must choose a file to import.'))
return self.redirect_back()
@@ -435,14 +432,6 @@ class ImportView(ListView):
def settings(self):
return SettingsSandbox('payment', 'banktransfer', getattr(self.request, 'event', self.request.organizer))
def process_camt(self):
try:
return self.start_processing(camtimport.parse(self.request.FILES.get('file')))
except:
logger.exception('Failed to import CAMT file')
messages.error(self.request, _('We were unable to process your input.'))
return self.redirect_back()
def process_mt940(self):
try:
return self.start_processing(mt940import.parse(self.request.FILES.get('file')))

View File

@@ -644,9 +644,7 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
FontFallbackParagraph(
_("Pending payments at {datetime}").format(
datetime=date_format(
(df_start - datetime.timedelta.resolution).astimezone(
self.timezone
),
df_start - datetime.timedelta.resolution,
"SHORT_DATETIME_FORMAT",
)
),
@@ -696,9 +694,7 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
Paragraph(
_("Pending payments at {datetime}").format(
datetime=date_format(
((df_end or now()) - datetime.timedelta.resolution).astimezone(
self.timezone
),
(df_end or now()) - datetime.timedelta.resolution,
"SHORT_DATETIME_FORMAT",
)
),
@@ -755,9 +751,7 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
Paragraph(
_("Total gift card value at {datetime}").format(
datetime=date_format(
(df_start - datetime.timedelta.resolution).astimezone(
self.timezone
),
df_start - datetime.timedelta.resolution,
"SHORT_DATETIME_FORMAT",
)
),
@@ -795,9 +789,7 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
Paragraph(
_("Total gift card value at {datetime}").format(
datetime=date_format(
((df_end or now()) - datetime.timedelta.resolution).astimezone(
self.timezone
),
(df_end or now()) - datetime.timedelta.resolution,
"SHORT_DATETIME_FORMAT",
)
),

View File

@@ -47,6 +47,14 @@ from pretix.celery_app import app
from pretix.helpers.format import format_map
def _chunks(lst, n):
"""
Yield successive n-sized chunks from lst.
"""
for i in range(0, len(lst), n):
yield lst[i:i + n]
@app.task(base=ProfiledEventTask, acks_late=True)
def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, objects: list, items: list,
subevent: int, subevents_from: datetime, subevents_to: datetime,
@@ -55,12 +63,11 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
attach_ical: bool = False) -> None:
failures = []
user = User.objects.get(pk=user) if user else None
orders = Order.objects.filter(pk__in=objects, event=event)
subject = LazyI18nString(subject)
message = LazyI18nString(message)
attachments_for_log = [cf.filename for cf in CachedFile.objects.filter(pk__in=attachments)] if attachments else []
for o in orders:
def _send_to_order(o):
send_to_order = recipients in ('both', 'orders')
try:
@@ -179,6 +186,11 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
except SendMailException:
failures.append(o.email)
for chunk in _chunks(objects, 1000):
orders = Order.objects.filter(pk__in=chunk, event=event)
for o in orders:
_send_to_order(o)
@app.task(base=ProfiledEventTask, acks_late=True)
def send_mails_to_waitinglist(event: Event, user: int, subject: dict, message: dict, objects: list,

View File

@@ -137,7 +137,7 @@ logger = logging.getLogger('pretix.plugins.stripe')
# Real-time payments
# - Swish: ✓
# - PayNow: ✗
# - PromptPay:
# - PromptPay:
# - Pix: ✗
#
# Vouchers
@@ -412,18 +412,6 @@ class StripeSettingsHolder(BasePaymentProvider):
'before they work properly.'),
required=False,
)),
('method_pay_by_bank',
forms.BooleanField(
label=_('Pay by bank'),
disabled=self.event.currency not in ['EUR', 'GBP'],
help_text=' '.join([
str(_('Some payment methods might need to be enabled in the settings of your Stripe account '
'before they work properly.')),
str(_('Currently only available for charges in GBP and customers with UK bank accounts, and '
'in private preview for France and Germany.'))
]),
required=False,
)),
('method_wechatpay',
forms.BooleanField(
label=_('WeChat Pay'),
@@ -440,14 +428,6 @@ class StripeSettingsHolder(BasePaymentProvider):
'before they work properly.'),
required=False,
)),
('method_promptpay',
forms.BooleanField(
label='PromptPay',
disabled=self.event.currency != 'THB',
help_text=_('Some payment methods might need to be enabled in the settings of your Stripe account '
'before they work properly.'),
required=False,
)),
('method_swish',
forms.BooleanField(
label=_('Swish'),
@@ -1830,32 +1810,6 @@ class StripeRevolutPay(StripeRedirectMethod):
}
class StripePayByBank(StripeRedirectMethod):
identifier = 'stripe_pay_by_bank'
verbose_name = _('Pay by bank via Stripe')
public_name = _('Pay by bank')
method = 'pay_by_bank'
redirect_in_widget_allowed = False
confirmation_method = 'automatic'
explanation = _(
'Pay by bank allows you to authorize a secure Open Banking payment from your banking app. Currently available '
'only with a UK bank account.'
)
def is_allowed(self, request: HttpRequest, total: Decimal=None) -> bool:
return super().is_allowed(request, total) and self.event.currency == 'GBP'
def _payment_intent_kwargs(self, request, payment):
return {
"payment_method_data": {
"type": "pay_by_bank",
"billing_details": {
"email": payment.order.email,
},
},
}
class StripePayPal(StripeRedirectMethod):
identifier = 'stripe_paypal'
verbose_name = _('PayPal via Stripe')
@@ -1888,30 +1842,6 @@ class StripeSwish(StripeRedirectMethod):
}
class StripePromptPay(StripeRedirectMethod):
identifier = 'stripe_promptpay'
verbose_name = _('PromptPay via Stripe')
public_name = 'PromptPay'
method = 'promptpay'
confirmation_method = 'automatic'
explanation = _(
'This payment method is available to PromptPay users in Thailand. Please have your app ready.'
)
def is_allowed(self, request: HttpRequest, total: Decimal=None) -> bool:
return super().is_allowed(request, total) and request.event.currency == "THB"
def _payment_intent_kwargs(self, request, payment):
return {
"payment_method_data": {
"type": "promptpay",
"billing_details": {
"email": payment.order.email,
},
},
}
class StripeTwint(StripeRedirectMethod):
identifier = 'stripe_twint'
verbose_name = _('TWINT via Stripe')

View File

@@ -38,6 +38,7 @@ from pretix.base.signals import (
)
from pretix.control.signals import nav_organizer
from pretix.plugins.stripe.forms import StripeKeyValidator
from pretix.plugins.stripe.payment import StripeMethod
from pretix.presale.signals import html_head, process_response
@@ -46,17 +47,15 @@ def register_payment_provider(sender, **kwargs):
from .payment import (
StripeAffirm, StripeAlipay, StripeBancontact, StripeCC, StripeEPS,
StripeGiropay, StripeIdeal, StripeKlarna, StripeMobilePay,
StripeMultibanco, StripePayByBank, StripePayPal, StripePromptPay,
StripePrzelewy24, StripeRevolutPay, StripeSEPADirectDebit,
StripeSettingsHolder, StripeSofort, StripeSwish, StripeTwint,
StripeWeChatPay,
StripeMultibanco, StripePayPal, StripePrzelewy24, StripeRevolutPay,
StripeSEPADirectDebit, StripeSettingsHolder, StripeSofort, StripeSwish,
StripeTwint, StripeWeChatPay,
)
return [
StripeSettingsHolder, StripeCC, StripeGiropay, StripeIdeal, StripeAlipay, StripeBancontact,
StripeSofort, StripeEPS, StripeMultibanco, StripePayByBank, StripePrzelewy24, StripePromptPay, StripeRevolutPay,
StripeWeChatPay, StripeSEPADirectDebit, StripeAffirm, StripeKlarna, StripePayPal, StripeSwish,
StripeTwint, StripeMobilePay
StripeSofort, StripeEPS, StripeMultibanco, StripePrzelewy24, StripeRevolutPay, StripeWeChatPay,
StripeSEPADirectDebit, StripeAffirm, StripeKlarna, StripePayPal, StripeSwish, StripeTwint, StripeMobilePay
]
@@ -190,8 +189,6 @@ def nav_o(sender, request, organizer, **kwargs):
@receiver(signal=process_response, dispatch_uid="stripe_middleware_resp")
def signal_process_response(sender, request: HttpRequest, response: HttpResponse, **kwargs):
from pretix.plugins.stripe.payment import StripeMethod
provider = StripeMethod(sender)
url = resolve(request.path_info)

View File

@@ -79,9 +79,3 @@
.vcenter {
margin: auto;
}
.stripe-qr-code {
max-width: 80%;
width: 200px;
height: auto;
}

View File

@@ -325,8 +325,6 @@ $(function () {
} else if ($("#stripe_payment_intent_next_action_redirect_url").length) {
let payment_intent_next_action_redirect_url = $.trim($("#stripe_payment_intent_next_action_redirect_url").html());
pretixstripe.handlePaymentRedirectAction(payment_intent_next_action_redirect_url);
} else if ($.trim($("#stripe_payment_intent_action_type").html()) === "promptpay_display_qr_code") {
waitingDialog.hide();
} else if ($.trim($("#stripe_payment_intent_action_type").html()) === "wechat_pay_display_qr_code") {
let payment_intent_client_secret = $.trim($("#stripe_payment_intent_client_secret").html());
pretixstripe.handleWechatAction(payment_intent_client_secret);

View File

@@ -22,6 +22,7 @@
import logging
from urllib.parse import urlsplit
import stripe
from django.conf import settings
from pretix.base.services.tasks import EventTask
@@ -49,10 +50,7 @@ def get_stripe_account_key(prov):
@app.task(base=EventTask, max_retries=5, default_retry_delay=1)
def stripe_verify_domain(event, domain):
import stripe
from pretix.plugins.stripe.payment import StripeCC
prov = StripeCC(event)
account = get_stripe_account_key(prov)

View File

@@ -27,21 +27,9 @@
<div class="stripe-errors sr-only panel-body">
</div>
{% if payment_intent_promptpay_image_url %}
<div class="panel-body">
<p>{% blocktrans trimmed %}
Please scan the QR code below to complete your PromptPay payment.
Once you have completed your payment, you can refresh this page.
{% endblocktrans %}</p>
<div class="text-center">
<img src="{{ payment_intent_promptpay_image_url }}" alt="{% trans 'PromptPay QR code' %}"
class="stripe-qr-code" />
</div>
</div>
{% else %}
<div class="panel-body embed-responsive embed-responsive-sca" id="scacontainer">
</div>
{% endif %}
<div class="panel-body embed-responsive embed-responsive-sca" id="scacontainer">
</div>
</div>
<div class="row checkout-button-row">
<div class="col-md-4">

View File

@@ -37,6 +37,7 @@ import logging
import urllib.parse
import requests
import stripe
from django.contrib import messages
from django.core import signing
from django.db import transaction
@@ -67,6 +68,7 @@ from pretix.helpers.http import redirect_to_url
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
from pretix.plugins.stripe.forms import OrganizerStripeSettingsForm
from pretix.plugins.stripe.models import ReferencedStripeObject
from pretix.plugins.stripe.payment import StripeCC, StripeSettingsHolder
from pretix.plugins.stripe.tasks import (
get_domain_for_event, stripe_verify_domain,
)
@@ -98,8 +100,6 @@ def redirect_view(request, *args, **kwargs):
@scopes_disabled()
def oauth_return(request, *args, **kwargs):
import stripe
if 'payment_stripe_oauth_event' not in request.session:
messages.error(request, _('An error occurred during connecting with Stripe, please try again.'))
return redirect('control:index')
@@ -268,10 +268,6 @@ SOURCE_TYPES = {
def charge_webhook(event, event_json, charge_id, rso):
import stripe
from pretix.plugins.stripe.payment import StripeCC
prov = StripeCC(event)
prov._init_api()
@@ -375,10 +371,6 @@ def charge_webhook(event, event_json, charge_id, rso):
def source_webhook(event, event_json, source_id, rso):
import stripe
from pretix.plugins.stripe.payment import StripeCC
prov = StripeCC(event)
prov._init_api()
try:
@@ -448,10 +440,6 @@ def source_webhook(event, event_json, source_id, rso):
def paymentintent_webhook(event, event_json, paymentintent_id, rso):
import stripe
from pretix.plugins.stripe.payment import StripeCC
prov = StripeCC(event)
prov._init_api()
@@ -528,8 +516,6 @@ class StripeOrderView:
@method_decorator(xframe_options_exempt, 'dispatch')
class ReturnView(StripeOrderView, View):
def get(self, request, *args, **kwargs):
import stripe
prov = self.pprov
prov._init_api()
try:
@@ -582,10 +568,6 @@ class ReturnView(StripeOrderView, View):
class ScaView(StripeOrderView, View):
def get(self, request, *args, **kwargs):
import stripe
from pretix.plugins.stripe.payment import StripeSettingsHolder
prov = self.pprov
prov._init_api()
@@ -613,7 +595,7 @@ class ScaView(StripeOrderView, View):
if intent.status == 'requires_action' and intent.next_action.type in [
'use_stripe_sdk', 'redirect_to_url', 'alipay_handle_redirect', 'wechat_pay_display_qr_code',
'swish_handle_redirect_or_display_qr_code', 'multibanco_display_details', 'promptpay_display_qr_code',
'swish_handle_redirect_or_display_qr_code', 'multibanco_display_details',
]:
ctx = {
'order': self.order,
@@ -631,8 +613,6 @@ class ScaView(StripeOrderView, View):
elif intent.next_action.type == 'multibanco_display_details':
ctx['payment_intent_next_action_redirect_url'] = intent.next_action.multibanco_display_details['hosted_voucher_url']
ctx['payment_intent_redirect_action_handling'] = 'iframe'
elif intent.next_action.type == 'promptpay_display_qr_code':
ctx['payment_intent_promptpay_image_url'] = intent.next_action.promptpay_display_qr_code['image_url_svg']
r = render(request, 'pretixplugins/stripe/sca.html', ctx)
r._csp_ignore = True

View File

@@ -1,44 +0,0 @@
{% load i18n %}
{% load static %}
{% if payment_qr_codes %}
<div class="tabcontainer col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
<div id="banktransfer_qrcodes_tabs_content" class="tabpanels blank-after">
{% for code_info in payment_qr_codes %}
<div id="banktransfer_qrcodes_{{ code_info.id }}"
role="tabpanel"
tabindex="0"
{% if not forloop.first %}hidden{% endif %}
aria-labelledby="banktransfer_qrcodes_{{ code_info.id }}_tab"
>
{% if code_info.link %}<a aria-label="{{ code_info.link_aria_label }}" href="{{ code_info.link }}">{% endif %}
<div class="{{ code_info.css_class }}" role="figure" aria-labelledby="banktransfer_qrcodes_{{ code_info.id }}_tab banktransfer_qrcodes_label">
{{ code_info.html_prefix }}
<script type="text/plain" data-size="150" data-replace-with-qr data-desc="{% trans 'Scan this image with your banking apps QR-Reader to start the payment process.' %}">{{ code_info.qr_data }}</script>
</div>
{% if code_info.link %}</a>{% endif %}
</div>
{% endfor %}
</div>
<div id="banktransfer_qrcodes_tabs" role="tablist" aria-labelledby="banktransfer_qrcodes_label" class="blank-after btn-group">
{% for code_info in payment_qr_codes %}
<button
class="btn btn-default"
id="banktransfer_qrcodes_{{ code_info.id }}_tab"
type="button"
role="tab"
aria-controls="banktransfer_qrcodes_{{ code_info.id }}"
aria-selected="{{ forloop.first|yesno:"true,false" }}"
tabindex="-1">{{ code_info.label }}</button>
{% endfor %}
</div>
<p class="text-muted" id="banktransfer_qrcodes_label">
{% trans "Scan the QR code with your banking app" %}
</p>
</div>
{% for code_info in payment_qr_codes %}
{% if code_info.id == "qrbill" %}
<link rel="stylesheet" href="{% static "pretixplugins/banktransfer/swisscross.css" %}">
{% endif %}
{% endfor %}
{% endif %}

View File

@@ -82,9 +82,6 @@ $(function () {
if ('label' in options) {
dependent.closest(".form-group").find(".control-label").text(options.label);
}
if ('helptext_visible' in options) {
dependent.closest(".form-group").find(".help-block").toggle(options.helptext_visible);
}
const required = 'required' in options && visible && (
(options.required === 'if_any' && isAnyRequired) ||

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 163 KiB

View File

@@ -34,7 +34,7 @@ def test_no_invoice_address(client):
'data': [],
'state': {'label': 'State', 'required': False, 'visible': False},
'street': {'required': 'if_any'},
'vat_id': {'helptext_visible': True, 'label': 'VAT ID', 'required': False, 'visible': True},
'vat_id': {'required': False, 'visible': True},
'zipcode': {'required': 'if_any'}
}
@@ -44,7 +44,7 @@ def test_no_invoice_address(client):
'data': [],
'state': {'label': 'State', 'required': False, 'visible': False},
'street': {'required': 'if_any'},
'vat_id': {'helptext_visible': True, 'label': 'VAT ID', 'required': False, 'visible': False},
'vat_id': {'required': False, 'visible': False},
'zipcode': {'required': False}
}
@@ -98,7 +98,7 @@ def test_provider_only_email_available(client, event):
'transmission_peppol_participant_id': {'required': False, 'visible': False},
'transmission_type': {'visible': False},
'transmission_types': [{'code': 'email', 'name': 'Email'}],
'vat_id': {'helptext_visible': True, 'label': 'VAT ID', 'required': False, 'visible': True},
'vat_id': {'required': False, 'visible': True},
'zipcode': {'required': 'if_any'}
}
@@ -123,7 +123,7 @@ def test_provider_italy_sdi_not_enforced_when_optional(client, event):
'transmission_peppol_participant_id': {'required': False, 'visible': False},
'transmission_type': {'visible': True},
'transmission_types': [{'code': 'it_sdi', 'name': 'Exchange System (SdI)'}],
'vat_id': {'helptext_visible': True, 'label': 'VAT ID / P.IVA', 'required': False, 'visible': True},
'vat_id': {'required': False, 'visible': True},
'zipcode': {'required': 'if_any'}
}
@@ -148,7 +148,7 @@ def test_provider_italy_sdi_enforced_individual(client, event):
'transmission_peppol_participant_id': {'required': False, 'visible': False},
'transmission_type': {'visible': True},
'transmission_types': [{'code': 'it_sdi', 'name': 'Exchange System (SdI)'}],
'vat_id': {'helptext_visible': True, 'label': 'VAT ID / P.IVA', 'required': False, 'visible': True},
'vat_id': {'required': False, 'visible': True},
'zipcode': {'required': True}
}
@@ -174,37 +174,11 @@ def test_provider_italy_sdi_enforced_business(client, event):
'transmission_peppol_participant_id': {'required': False, 'visible': False},
'transmission_type': {'visible': True},
'transmission_types': [{'code': 'it_sdi', 'name': 'Exchange System (SdI)'}],
'vat_id': {'helptext_visible': False, 'label': 'VAT ID / P.IVA', 'required': True, 'visible': True},
'vat_id': {'required': True, 'visible': True},
'zipcode': {'required': True}
}
@pytest.mark.django_db
def test_vat_id_enforced(client, event):
response = client.get(
'/js_helpers/address_form/?country=GR&invoice=true&organizer=org&event=ev'
'&is_business=business'
)
assert response.status_code == 200
d = response.json()
del d['data']
assert d == {
'city': {'required': 'if_any'},
'state': {'label': 'State', 'required': False, 'visible': False},
'street': {'required': 'if_any'},
'transmission_email_address': {'required': False, 'visible': False},
'transmission_email_other': {'required': False, 'visible': False},
'transmission_it_sdi_codice_fiscale': {'required': False, 'visible': False},
'transmission_it_sdi_pec': {'required': False, 'visible': False},
'transmission_it_sdi_recipient_code': {'required': False, 'visible': False},
'transmission_peppol_participant_id': {'required': False, 'visible': False},
'transmission_type': {'visible': True},
'transmission_types': [{'code': 'email', 'name': 'Email'}, {'code': 'peppol', 'name': 'Peppol'}],
'vat_id': {'helptext_visible': False, 'label': 'VAT ID / TIN', 'required': True, 'visible': True},
'zipcode': {'required': 'if_any'}
}
@pytest.mark.django_db
def test_email_peppol_choice(client, event):
response = client.get(
@@ -229,7 +203,7 @@ def test_email_peppol_choice(client, event):
{'code': 'email', 'name': 'Email'},
{'code': 'peppol', 'name': 'Peppol'},
],
'vat_id': {'helptext_visible': True, 'label': 'VAT ID', 'required': False, 'visible': True},
'vat_id': {'required': False, 'visible': True},
'zipcode': {'required': 'if_any'}
}
@@ -255,6 +229,6 @@ def test_email_peppol_choice(client, event):
{'code': 'email', 'name': 'Email'},
{'code': 'peppol', 'name': 'Peppol'},
],
'vat_id': {'helptext_visible': True, 'label': 'VAT ID', 'required': False, 'visible': True},
'vat_id': {'required': False, 'visible': True},
'zipcode': {'required': True}
}

View File

@@ -24,7 +24,7 @@ import responses
from requests import Timeout
from pretix.base.services.tax import (
VATIDFinalError, VATIDTemporaryError, normalize_vat_id, validate_vat_id,
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
)
@@ -51,18 +51,6 @@ def test_eu_country_mismatch():
validate_vat_id('AT12345', 'DE')
@responses.activate
def test_normalize():
assert normalize_vat_id('AT U 12345678', 'AT') == 'ATU12345678'
assert normalize_vat_id('U12345678', 'AT') == 'ATU12345678'
assert normalize_vat_id('IT.123.456.789.00', 'IT') == 'IT12345678900'
assert normalize_vat_id('12345678900', 'IT') == 'IT12345678900'
assert normalize_vat_id('123456789MVA', 'NO') == "NO123456789MVA"
assert normalize_vat_id('CHE 123456789 MWST', 'CH') == "CHE123456789"
# Bad combination is left for validation
assert normalize_vat_id('ATU12345678', 'IT') == 'ATU12345678'
@responses.activate
def test_eu_server_down():
def _callback(request):

View File

@@ -1,141 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# 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/>.
#
from datetime import timedelta
from decimal import Decimal
import pytest
from django.utils.timezone import now
from pretix.base.models import Event, Organizer
from pretix.helpers.payment import generate_payment_qr_codes
@pytest.fixture
def env():
o = Organizer.objects.create(name='Verein für Testzwecke e.V.', slug='testverein')
event = Event.objects.create(
organizer=o, name='Testveranstaltung', slug='testveranst',
date_from=now() + timedelta(days=10),
live=True, is_public=False, currency='EUR',
)
event.settings.invoice_address_from = 'Verein für Testzwecke e.V.'
event.settings.invoice_address_from_zipcode = '1234'
event.settings.invoice_address_from_city = 'Testhausen'
event.settings.invoice_address_from_country = 'CH'
return o, event
@pytest.mark.django_db
def test_payment_qr_codes_euro(env):
o, event = env
codes = generate_payment_qr_codes(
event=event,
code='TESTVERANST-12345',
amount=Decimal('123.00'),
bank_details_sepa_bic='BYLADEM1MIL',
bank_details_sepa_iban='DE37796500000069799047',
bank_details_sepa_name='Verein für Testzwecke e.V.',
)
assert len(codes) == 2
assert codes[0]['label'] == 'EPC-QR'
assert codes[0]['qr_data'] == '''BCD
002
2
SCT
BYLADEM1MIL
Verein fur Testzwecke e.V.
DE37796500000069799047
EUR123.00
TESTVERANST-12345
'''
assert codes[1]['label'] == 'BezahlCode'
assert codes[1]['qr_data'] == ('bank://singlepaymentsepa?name=Verein%20f%C3%BCr%20Testzwecke%20e.V.&iban=DE37796500000069799047'
'&bic=BYLADEM1MIL&amount=123%2C00&reason=TESTVERANST-12345&currency=EUR')
@pytest.mark.django_db
def test_payment_qr_codes_swiss(env):
o, event = env
codes = generate_payment_qr_codes(
event=event,
code='TESTVERANST-12345',
amount=Decimal('123.00'),
bank_details_sepa_bic='TESTCHXXXXX',
bank_details_sepa_iban='CH6389144757654882127',
bank_details_sepa_name='Verein für Testzwecke e.V.',
)
assert codes[0]['label'] == 'QR-bill'
assert codes[0]['qr_data'] == "\r\n".join([
"SPC",
"0200",
"1",
"CH6389144757654882127",
"K",
"Verein fur Testzwecke e.V.",
"Verein fur Testzwecke e.V.",
"1234 Testhausen",
"",
"",
"CH",
"",
"",
"",
"",
"",
"",
"",
"123.00",
"EUR",
"",
"",
"",
"",
"",
"",
"",
"NON",
"",
"TESTVERANST-12345",
"EPD",
])
@pytest.mark.django_db
def test_payment_qr_codes_spayd(env):
o, event = env
codes = generate_payment_qr_codes(
event=event,
code='TESTVERANST-12345',
amount=Decimal('123.00'),
bank_details_sepa_bic='TESTCZXXXXX',
bank_details_sepa_iban='CZ7450513769129174398769',
bank_details_sepa_name='Verein für Testzwecke e.V.',
)
assert len(codes) == 2
assert codes[0]['label'] == 'SPAYD'
assert codes[0]['qr_data'] == 'SPD*1.0*ACC:CZ7450513769129174398769*AM:123.00*CC:EUR*MSG:TESTVERANST-12345'
assert codes[1]['label'] == 'EPC-QR'

View File

@@ -45,8 +45,6 @@ def env():
def test_event_main_domain_front_page(env):
assert eventreverse(env[1], 'presale:event.index') == '/mrmcd/2015/'
assert eventreverse(env[0], 'presale:organizer.index') == '/mrmcd/'
assert eventreverse(env[1], 'plugins:testdummy:view') == '/mrmcd/2015/testdummy'
assert eventreverse(env[0], 'plugins:testdummy:view') == '/mrmcd/testdummy'
@pytest.mark.django_db
@@ -54,16 +52,12 @@ def test_event_custom_domain_kwargs(env):
KnownDomain.objects.create(domainname='foobar', organizer=env[0])
KnownDomain.objects.create(domainname='barfoo', organizer=env[0], event=env[1])
assert eventreverse(env[1], 'presale:event.checkout', {'step': 'payment'}) == 'http://barfoo/checkout/payment/'
assert eventreverse(env[0], 'plugins:testdummy:view') == 'http://foobar/testdummy'
assert eventreverse(env[1], 'plugins:testdummy:view') == 'http://barfoo/testdummy'
@pytest.mark.django_db
def test_event_org_domain_kwargs(env):
KnownDomain.objects.create(domainname='foobar', organizer=env[0])
assert eventreverse(env[1], 'presale:event.checkout', {'step': 'payment'}) == 'http://foobar/2015/checkout/payment/'
assert eventreverse(env[0], 'plugins:testdummy:view') == 'http://foobar/testdummy'
assert eventreverse(env[1], 'plugins:testdummy:view') == 'http://foobar/2015/testdummy'
@pytest.mark.django_db
@@ -71,13 +65,9 @@ def test_event_org_alt_domain_kwargs(env):
KnownDomain.objects.create(domainname='foobar', organizer=env[0])
d = KnownDomain.objects.create(domainname='altfoo', organizer=env[0], mode=KnownDomain.MODE_ORG_ALT_DOMAIN)
assert eventreverse(env[1], 'presale:event.checkout', {'step': 'payment'}) == 'http://foobar/2015/checkout/payment/'
assert eventreverse(env[1], 'plugins:testdummy:view') == 'http://foobar/2015/testdummy'
d.event_assignments.create(event=env[1])
with scopes_disabled():
event = Event.objects.get(pk=env[1].pk)
assert eventreverse(event, 'presale:event.checkout', {'step': 'payment'}) == 'http://altfoo/2015/checkout/payment/'
assert eventreverse(env[0], 'plugins:testdummy:view') == 'http://foobar/testdummy'
assert eventreverse(event, 'plugins:testdummy:view') == 'http://altfoo/2015/testdummy'
assert eventreverse(Event.objects.get(pk=env[1].pk), 'presale:event.checkout', {'step': 'payment'}) == 'http://altfoo/2015/checkout/payment/'
@pytest.mark.django_db

View File

@@ -1,756 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--Beispielnachricht_camt.053_BankToCustomerStatement_via_EBICS-->
<!-- Source https://www.bundesbank.de/de/startseite/beispieldateien-zur-bereitstellung-der-elektronischen-kontoinformationen-zu-dotationskonten-von-banken-im-format-camt-052-und-camt-053-bei-kommunikation-via-ebics-example-files-for-the-provision-of-electronic-account-information-for-cash-handling-accounts-of-banks-in-camt-052-and-camt-053-format-when-communicating-via-ebics-943090 -->
<Document xmlns:n0="urn:iso:std:iso:20022:tech:xsd:camt.053.001.08">
<BkToCstmrStmt>
<GrpHdr>
<MsgId>20240313C0098170</MsgId>
<CreDtTm>2024-03-13T18:40:42.8734727+01:00</CreDtTm>
</GrpHdr>
<Stmt>
<Id>20240313C0098170</Id>
<StmtPgntn>
<PgNb>00001</PgNb>
<LastPgInd>true</LastPgInd>
</StmtPgntn>
<ElctrncSeqNb>1</ElctrncSeqNb>
<CreDtTm>2024-03-13T18:40:42.8734727+01:00</CreDtTm>
<Acct>
<Id>
<IBAN>DE00IBANdesDotationskontos</IBAN>
</Id>
<Tp>
<Cd>CACC</Cd>
</Tp>
<Ccy>EUR</Ccy>
<Nm>Testbank, Hamburg</Nm>
<Ownr>
<Nm>Testbank-Inhaber</Nm>
</Ownr>
<Svcr>
<FinInstnId>
<BICFI>MARKDEF1200</BICFI>
<ClrSysMmbId>
<ClrSysId>
<Cd>DEBLZ</Cd>
</ClrSysId>
<MmbId>20000000</MmbId>
</ClrSysMmbId>
<Nm>Deutsche Bundesbank</Nm>
<Othr>
<Id>DE114103555</Id>
<Issr>UmsStId</Issr>
</Othr>
</FinInstnId>
<BrnchId>
<Nm>Filiale Hamburg</Nm>
</BrnchId>
</Svcr>
</Acct>
<Bal>
<Tp>
<CdOrPrtry>
<Cd>OPBD</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="EUR">0.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2024-03-13</Dt>
</Dt>
</Bal>
<Bal>
<Tp>
<CdOrPrtry>
<Cd>CLBD</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="EUR">0.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2024-03-13</Dt>
</Dt>
</Bal>
<Ntry>
<NtryRef>2000000011240313</NtryRef>
<Amt Ccy="EUR">100000.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>103600002791/0019200002</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>CNTR</Cd>
<SubFmlyCd>CDPT</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCMI+082+0019200002</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>2000000011240313</AcctSvcrRef>
</Refs>
<Amt Ccy="EUR">100000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>CNTR</Cd>
<SubFmlyCd>CDPT</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCMI+082+0019200002</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>Einzahlung</Prtry>
</Purp>
<AddtlTxInf>Einzahlungen</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Einzahlungen</AddtlNtryInf>
</Ntry>
<Ntry>
<NtryRef>2000000012240313</NtryRef>
<Amt Ccy="EUR">25000.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>049000039704/0019000002</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>CNTR</Cd>
<SubFmlyCd>CWDL</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCMI+083+0019000002</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>2000000012240313</AcctSvcrRef>
<InstrId>9998770</InstrId>
<ChqNb>9998770</ChqNb>
</Refs>
<Amt Ccy="EUR">25000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>CNTR</Cd>
<SubFmlyCd>CWDL</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCMI+083+0019000002</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>Auszahlung</Prtry>
</Purp>
<AddtlTxInf>Auszahlungen</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Auszahlungen</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">20000.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>047200003598/0002000001</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICHQ</Cd>
<SubFmlyCd>CCHQ</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCHK+101+0002000001</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<InstrId>9998771</InstrId>
<ChqNb>9998771</ChqNb>
</Refs>
<Amt Ccy="EUR">250000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICHQ</Cd>
<SubFmlyCd>CCHQ</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCHK+101+0002000001</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Cdtr>
<Pty>
<Nm>Deutsche Bundesbank KBS HMS Hamburg</Nm>
</Pty>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE98200000000020002633</IBAN>
</Id>
</CdtrAcct>
</RltdPties>
<RltdAgts>
<CdtrAgt>
<FinInstnId>
<ClrSysMmbId>
<ClrSysId>
<Cd>DEBLZ</Cd>
</ClrSysId>
<MmbId>20000000</MmbId>
</ClrSysMmbId>
</FinInstnId>
</CdtrAgt>
</RltdAgts>
<Purp>
<Prtry>LS bestätigter Scheck</Prtry>
</Purp>
<RmtInf>
<Ustrd>Bestätigter Scheck vom 13.03.2024</Ustrd>
<Ustrd>Scheck Nr. 135469</Ustrd>
</RmtInf>
<AddtlTxInf>Inhaberscheck</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Inhaberscheck</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">15.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>047200003598/0002000001</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>ACMT</Cd>
<Fmly>
<Cd>MDOP</Cd>
<SubFmlyCd>CHRG</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCHG+808+0002000001</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Amt Ccy="EUR">15.00</Amt>
<BkTxCd>
<Domn>
<Cd>ACMT</Cd>
<Fmly>
<Cd>MDOP</Cd>
<SubFmlyCd>CHRG</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NCHG+808+0002000001</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>LS Entgelte Giro, SchE</Prtry>
</Purp>
<AddtlTxInf>Gebühren</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Gebühren</AddtlNtryInf>
</Ntry>
<Ntry>
<NtryRef>H202403135000000107</NtryRef>
<Amt Ccy="EUR">145015.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>051500000059/0019000003</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>RCDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+088+0019000003</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>H202403135000000107</AcctSvcrRef>
<InstrId>H202403135000000107</InstrId>
</Refs>
<Amt Ccy="EUR">145015.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>RCDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+088+0019000003</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>Überw Prior1/SWI</Prtry>
</Purp>
<AddtlTxInf>Überweisungsgutschrift mit Festvaluta</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Überweisungsgutschrift mit Festvaluta</AddtlNtryInf>
</Ntry>
<Ntry>
<NtryRef>H202403135000000108</NtryRef>
<Amt Ccy="EUR">50000.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>105600004525/0019200003</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>RCDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+088+0019200003</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>H202403135000000108</AcctSvcrRef>
<InstrId>H202403135000000108</InstrId>
</Refs>
<Amt Ccy="EUR">50000.00</Amt>
<AmtDtls>
<InstdAmt>
<Amt Ccy="EUR">50000.00</Amt>
</InstdAmt>
</AmtDtls>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>RCDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+088+0019200003</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Dbtr>
<Pty>
<Nm>Testbank</Nm>
</Pty>
</Dbtr>
<DbtrAcct>
<Id>
<Othr>
<Id>0123456789</Id>
</Othr>
</Id>
</DbtrAcct>
</RltdPties>
<Purp>
<Prtry>Überw Prior1/SWI</Prtry>
</Purp>
<RmtInf>
<Ustrd>VWZ pacs008 RTGS nach DOTA</Ustrd>
</RmtInf>
<AddtlTxInf>Überweisungsgutschrift mit Festvaluta</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Überweisungsgutschrift mit Festvaluta</AddtlNtryInf>
</Ntry>
<Ntry>
<NtryRef>H202403135000000109</NtryRef>
<Amt Ccy="EUR">80000.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>051800000156/0019000004</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>RCDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+088+0019000004</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>H202403135000000109</AcctSvcrRef>
<InstrId>pacs009-EndToEndId-00004</InstrId>
</Refs>
<Amt Ccy="EUR">80000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>RCDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+088+0019000004</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>Überw Prior1/SWI</Prtry>
</Purp>
<RmtInf>
<Ustrd>VWZ pacs009 RTGS nach DOTA</Ustrd>
</RmtInf>
<AddtlTxInf>Überweisungsgutschrift mit Festvaluta</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Überweisungsgutschrift mit Festvaluta</AddtlNtryInf>
</Ntry>
<Ntry>
<NtryRef>pacs009-InstrId-00005</NtryRef>
<Amt Ccy="EUR">30000.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>055100000086/0019000005</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+087+0019000005</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>pacs009-InstrId-00005</AcctSvcrRef>
<InstrId>pacs009-InstrId-00005</InstrId>
</Refs>
<Amt Ccy="EUR">30000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+087+0019000005</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>Überw Prior1/SWI</Prtry>
</Purp>
<RmtInf>
<Ustrd>VWZ pacs009 DOTA nach MCA</Ustrd>
</RmtInf>
<AddtlTxInf>Eilüberweisung</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Eilüberweisung</AddtlNtryInf>
</Ntry>
<Ntry>
<NtryRef>pacs009-InstrId-00006</NtryRef>
<Amt Ccy="EUR">120000.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>001400001221/0019000006</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+087+0019000006</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>pacs009-InstrId-00006</AcctSvcrRef>
<InstrId>pacs009-InstrId-00006</InstrId>
</Refs>
<Amt Ccy="EUR">120000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+087+0019000006</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<Purp>
<Prtry>Überw Prior1/SWI</Prtry>
</Purp>
<RmtInf>
<Ustrd>VWZ pacs009 DOTA nach RTGS</Ustrd>
</RmtInf>
<AddtlTxInf>Eilüberweisung</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Eilüberweisung</AddtlNtryInf>
</Ntry>
<Ntry>
<Amt Ccy="EUR">100000.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>016900004681/0002000002</AcctSvcrRef>
<BkTxCd>
<Prtry>
<Cd>NCHK+070+0002000002</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Amt Ccy="EUR">100000.00</Amt>
<BkTxCd>
<Prtry>
<Cd>NCHK+070+0002000002</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Dbtr>
<Pty>
<Nm>Deutsche Bundesbank / 22772 Hamburg</Nm>
</Pty>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>DE98200000000020002633</IBAN>
</Id>
</DbtrAcct>
</RltdPties>
<RltdAgts>
<DbtrAgt>
<FinInstnId>
<ClrSysMmbId>
<ClrSysId>
<Cd>DEBLZ</Cd>
</ClrSysId>
<MmbId>20000000</MmbId>
</ClrSysMmbId>
</FinInstnId>
</DbtrAgt>
</RltdAgts>
<Purp>
<Prtry>GS bestätigter Scheck</Prtry>
</Purp>
<RmtInf>
<Ustrd>Rückgabe Best. Scheck vom 28.02.2024</Ustrd>
<Ustrd>Scheck Nr. 135468</Ustrd>
</RmtInf>
</TxDtls>
</NtryDtls>
</Ntry>
<Ntry>
<NtryRef>pacs008-InstrId-00007</NtryRef>
<Amt Ccy="EUR">280000.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>
<Cd>BOOK</Cd>
</Sts>
<BookgDt>
<Dt>2024-03-13</Dt>
</BookgDt>
<ValDt>
<Dt>2024-03-13</Dt>
</ValDt>
<AcctSvcrRef>010300005153/0019000007</AcctSvcrRef>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+087+0019000007</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<NtryDtls>
<TxDtls>
<Refs>
<AcctSvcrRef>pacs008-InstrId-00007</AcctSvcrRef>
<InstrId>pacs008-InstrId-00007</InstrId>
</Refs>
<Amt Ccy="EUR">280000.00</Amt>
<BkTxCd>
<Domn>
<Cd>PMNT</Cd>
<Fmly>
<Cd>ICDT</Cd>
<SubFmlyCd>SDVA</SubFmlyCd>
</Fmly>
</Domn>
<Prtry>
<Cd>NTRF+087+0019000007</Cd>
<Issr>DK</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Cdtr>
<Pty>
<Nm>Testbank, Hamburg</Nm>
</Pty>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE00IBANbeiTestbank</IBAN>
</Id>
</CdtrAcct>
</RltdPties>
<Purp>
<Prtry>Überw Prior1/SWI</Prtry>
</Purp>
<RmtInf>
<Ustrd>VWZ pacs008 DOTA nach RTGS</Ustrd>
</RmtInf>
<AddtlTxInf>Eilüberweisung</AddtlTxInf>
</TxDtls>
</NtryDtls>
<AddtlNtryInf>Eilüberweisung</AddtlNtryInf>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>

View File

@@ -1,312 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:camt.053.001.02 camt.053.001.02.xsd">
<BkToCstmrStmt>
<GrpHdr>
<MsgId>053D2013-12-27T22:05:03.0N130000005</MsgId>
<CreDtTm>2013-12-27T22:04:52.0+01:00</CreDtTm>
<MsgPgntn>
<PgNb>1</PgNb>
<LastPgInd>true</LastPgInd>
</MsgPgntn>
</GrpHdr>
<Stmt>
<Id>0352C5320131227220503</Id>
<ElctrncSeqNb>130000005</ElctrncSeqNb>
<CreDtTm>2013-12-27T22:04:52.0+01:00</CreDtTm>
<Acct>
<Id>
<IBAN>DE14740618130000033626</IBAN>
</Id>
<Ccy>EUR</Ccy>
<Ownr>
<Nm>Testkonto Nummer 1</Nm>
</Ownr>
<Svcr>
<FinInstnId>
<BIC>GENODEF1PFK</BIC>
<Nm>VR-Bank Rottal-Inn eG</Nm>
<Othr>
<Id>DE 129267947</Id>
<Issr>UmsStId</Issr>
</Othr>
</FinInstnId>
</Svcr>
</Acct>
<Bal>
<Tp>
<CdOrPrtry>
<Cd>PRCD</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="EUR">33.06</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2013-12-27</Dt>
</Dt>
</Bal>
<Bal>
<Tp>
<CdOrPrtry>
<Cd>CLBD</Cd>
</CdOrPrtry>
</Tp>
<Amt Ccy="EUR">23.06</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2013-12-27</Dt>
</Dt>
</Bal>
<Ntry>
<Amt Ccy="EUR">2.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-12-27</Dt>
</BookgDt>
<ValDt>
<Dt>2013-12-27</Dt>
</ValDt>
<AcctSvcrRef>2013122710583450000</AcctSvcrRef>
<BkTxCd/>
<NtryDtls>
<TxDtls>
<BkTxCd>
<Prtry>
<Cd>NTRF+020</Cd>
<Issr>ZKA</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Cdtr>
<Nm>Testkonto Nummer 2</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<Othr>
<Id> 740618130100033626</Id>
<SchmeNm>
<Cd>BBAN</Cd>
</SchmeNm>
</Othr>
</Id>
</CdtrAcct>
</RltdPties>
<RmtInf>
<Ustrd>TEST BERWEISUNG MITTELS BLZUND KONTONUMMER - DTA</Ustrd>
</RmtInf>
</TxDtls>
</NtryDtls>
</Ntry>
<Ntry>
<Amt Ccy="EUR">3.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-12-27</Dt>
</BookgDt>
<ValDt>
<Dt>2013-12-27</Dt>
</ValDt>
<AcctSvcrRef>2013122710583600000</AcctSvcrRef>
<BkTxCd/>
<NtryDtls>
<TxDtls>
<Refs>
<MsgId>CCTI/VRNWSW/b044f24cddb92a502b8a1b5</MsgId>
<EndToEndId>NOTPROVIDED</EndToEndId>
</Refs>
<BkTxCd>
<Prtry>
<Cd>NMSC+201</Cd>
<Issr>ZKA</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Dbtr>
<Nm>Testkonto Nummer 1</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>DE14740618130000033626</IBAN>
</Id>
</DbtrAcct>
<UltmtDbtr>
<Nm>keine Information vorhanden</Nm>
</UltmtDbtr>
<Cdtr>
<Nm>Testkonto Nummer 2</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE58740618130100033626</IBAN>
</Id>
</CdtrAcct>
<UltmtCdtr>
<Nm>keine Information vorhanden</Nm>
</UltmtCdtr>
</RltdPties>
<RltdAgts>
<CdtrAgt>
<FinInstnId>
<BIC>GENODEF1PFK</BIC>
</FinInstnId>
</CdtrAgt>
</RltdAgts>
<RmtInf>
<Ustrd>Test+berweisung mit BIC und IBAN SEPA IBAN: DE58740618130100033626 BIC: GENODEF1PFK</Ustrd>
</RmtInf>
</TxDtls>
</NtryDtls>
</Ntry>
<Ntry>
<Amt Ccy="EUR">1.00</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-12-27</Dt>
</BookgDt>
<ValDt>
<Dt>2013-12-27</Dt>
</ValDt>
<AcctSvcrRef>2013122711085260000</AcctSvcrRef>
<BkTxCd/>
<NtryDtls>
<TxDtls>
<BkTxCd>
<Prtry>
<Cd>NMSC+051</Cd>
<Issr>ZKA</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Dbtr>
<Nm>Testkonto Nummer 2</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<Othr>
<Id> 740618130100033626</Id>
<SchmeNm>
<Cd>BBAN</Cd>
</SchmeNm>
</Othr>
</Id>
</DbtrAcct>
</RltdPties>
<RmtInf>
<Ustrd>R CKBUCHUNG</Ustrd>
</RmtInf>
</TxDtls>
</NtryDtls>
</Ntry>
<Ntry>
<Amt Ccy="EUR">6.00</Amt>
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-12-27</Dt>
</BookgDt>
<ValDt>
<Dt>2013-12-27</Dt>
</ValDt>
<AcctSvcrRef>2013122711513230000</AcctSvcrRef>
<BkTxCd/>
<NtryDtls>
<Btch>
<PmtInfId>STZV-PmInf27122013-11:02-2</PmtInfId>
<NbOfTxs>2</NbOfTxs>
</Btch>
<TxDtls>
<Refs>
<MsgId>STZV-Msg27122013-11:02</MsgId>
<EndToEndId>STZV-EtE27122013-11:02-1</EndToEndId>
</Refs>
<AmtDtls>
<TxAmt>
<Amt Ccy="EUR">3.50</Amt>
</TxAmt>
</AmtDtls>
<BkTxCd>
<Prtry>
<Cd>NMSC+201</Cd>
<Issr>ZKA</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Dbtr>
<Nm>Testkonto Nummer 2</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>DE58740618130100033626</IBAN>
</Id>
</DbtrAcct>
<UltmtDbtr>
<Nm>keine Information vorhanden</Nm>
</UltmtDbtr>
<Cdtr>
<Nm>Testkonto Nummer 1</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE14740618130000033626</IBAN>
</Id>
</CdtrAcct>
<UltmtCdtr>
<Nm>Testkonto</Nm>
</UltmtCdtr>
</RltdPties>
<RmtInf>
<Ustrd>Sammelueberwseisung 2. Zahlung TAN:283044 </Ustrd>
</RmtInf>
</TxDtls>
<TxDtls>
<Refs>
<MsgId>STZV-Msg27122013-11:02</MsgId>
<EndToEndId>STZV-EtE27122013-11:02-2</EndToEndId>
</Refs>
<AmtDtls>
<TxAmt>
<Amt Ccy="EUR">2.50</Amt>
</TxAmt>
</AmtDtls>
<BkTxCd>
<Prtry>
<Cd>NMSC+201</Cd>
<Issr>ZKA</Issr>
</Prtry>
</BkTxCd>
<RltdPties>
<Dbtr>
<Nm>Testkonto Nummer 2</Nm>
</Dbtr>
<DbtrAcct>
<Id>
<IBAN>DE58740618130100033626</IBAN>
</Id>
</DbtrAcct>
<UltmtDbtr>
<Nm>keine Information vorhanden</Nm>
</UltmtDbtr>
<Cdtr>
<Nm>Testkonto Nummer 1</Nm>
</Cdtr>
<CdtrAcct>
<Id>
<IBAN>DE14740618130000033626</IBAN>
</Id>
</CdtrAcct>
<UltmtCdtr>
<Nm>Testkonto</Nm>
</UltmtCdtr>
</RltdPties>
<RmtInf>
<Ustrd>Sammelueberweisung 1. Zahlung TAN:283044 </Ustrd>
</RmtInf>
</TxDtls>
</NtryDtls>
</Ntry>
</Stmt>
</BkToCstmrStmt>
</Document>

View File

@@ -1,146 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# 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 os.path
from django.test import TestCase
from pretix.plugins.banktransfer import camtimport
DATA_DIR = os.path.dirname(__file__)
class CamtImportTest(TestCase):
def _test_from_sample_file(self, filename, expected_parsed):
with open(os.path.join(DATA_DIR, filename), "rb") as f:
parsed = camtimport.parse(f)
print(parsed)
self.assertEqual(parsed, expected_parsed)
def test_sample_file_sepatools(self):
expected_parsed = [
{
"amount": "-2.00",
"date": "2013-12-27",
"reference": "TEST BERWEISUNG MITTELS BLZUND KONTONUMMER - DTA",
"external_id": "2013122710583450000",
"payer": "Testkonto Nummer 2",
},
{
"amount": "-3.00",
"date": "2013-12-27",
"reference": "Test+berweisung mit BIC und IBAN SEPA IBAN: DE58740618130100033626 BIC: GENODEF1PFK",
"external_id": "2013122710583600000",
"iban": "DE58740618130100033626",
"payer": "Testkonto Nummer 2",
},
{
"amount": "1.00",
"date": "2013-12-27",
"reference": "R CKBUCHUNG",
"external_id": "2013122711085260000",
"payer": "Testkonto Nummer 2",
},
{
"amount": "-6.00",
"date": "2013-12-27",
"reference": "STZV-PmInf27122013-11:02-2",
"external_id": "2013122711513230000",
},
]
filename = "camt.053_sepatools.xml"
self._test_from_sample_file(filename, expected_parsed)
def test_sample_file_bundesbank(self):
expected_parsed = [
{
"amount": "100000.00",
"date": "2024-03-13",
"reference": "",
"external_id": "103600002791/0019200002",
},
{
"amount": "-25000.00",
"date": "2024-03-13",
"reference": "",
"external_id": "049000039704/0019000002",
},
{
"amount": "-20000.00",
"date": "2024-03-13",
"reference": "",
"external_id": "047200003598/0002000001",
"iban": "DE98200000000020002633",
},
{
"amount": "-15.00",
"date": "2024-03-13",
"reference": "",
"external_id": "047200003598/0002000001",
},
{
"amount": "145015.00",
"date": "2024-03-13",
"reference": "",
"external_id": "051500000059/0019000003",
},
{
"amount": "50000.00",
"date": "2024-03-13",
"reference": "VWZ pacs008 RTGS nach DOTA",
"external_id": "105600004525/0019200003",
},
{
"amount": "80000.00",
"date": "2024-03-13",
"reference": "VWZ pacs009 RTGS nach DOTA",
"external_id": "051800000156/0019000004",
},
{
"amount": "-30000.00",
"date": "2024-03-13",
"reference": "VWZ pacs009 DOTA nach MCA",
"external_id": "055100000086/0019000005",
},
{
"amount": "-120000.00",
"date": "2024-03-13",
"reference": "VWZ pacs009 DOTA nach RTGS",
"external_id": "001400001221/0019000006",
},
{
"amount": "100000.00",
"date": "2024-03-13",
"reference": "",
"external_id": "016900004681/0002000002",
"iban": "DE98200000000020002633",
},
{
"amount": "-280000.00",
"date": "2024-03-13",
"reference": "VWZ pacs008 DOTA nach RTGS",
"external_id": "010300005153/0019000007",
"iban": "DE00IBANbeiTestbank",
},
]
filename = "camt.053_bundesbank.xml"
self._test_from_sample_file(filename, expected_parsed)

View File

@@ -385,20 +385,6 @@ def test_mark_paid_organizer_dash_in_slug(env, orga_job):
assert env[2].status == Order.STATUS_PAID
@pytest.mark.django_db
def test_mark_paid_organizer_dash_in_slug_missing(env, orga_job):
env[0].slug = "foo-bar"
env[0].save()
process_banktransfers(orga_job, [{
'payer': 'Karla Kundin',
'reference': 'Bestellung FOOBAR1234S',
'date': '2016-01-26',
'amount': '23.00'
}])
env[2].refresh_from_db()
assert env[2].status == Order.STATUS_PAID
@pytest.mark.django_db
def test_mark_paid_organizer_varying_order_code_length(env, orga_job):
env[2].code = "123412341234"
@@ -504,7 +490,7 @@ def test_valid_plus_invalid_match(env, orga_job):
'payer': 'Karla Kundin',
'reference': 'Bestellungen DUMMY-1Z3AS DUMMY-99999',
'date': '2016-01-26',
'amount': '2.00'
'amount': '.00'
}])
with scopes_disabled():
job = BankImportJob.objects.last()

View File

@@ -1428,29 +1428,6 @@ class CartTest(CartTestMixin, TestCase):
self.assertEqual(cp2.expires, now() + self.cart_reservation_time)
self.assertEqual(cp2.max_extend, now() + 11 * self.cart_reservation_time)
def test_expired_cart_extend_fails_partially_on_bundled(self):
start_time = datetime.datetime(2024, 1, 1, 10, 00, 00, tzinfo=datetime.timezone.utc)
max_extend = start_time + 11 * self.cart_reservation_time
self.quota_shirts.size = 0
self.quota_shirts.save()
with scopes_disabled():
cp1 = CartPosition.objects.create(
event=self.event, cart_id=self.session_key, item=self.ticket,
price=23, expires=max_extend, max_extend=max_extend
)
cp2 = CartPosition.objects.create(
event=self.event, cart_id=self.session_key, item=self.shirt, variation=self.shirt_blue,
price=23, expires=max_extend, max_extend=max_extend, addon_to=cp1, is_bundled=True,
)
with freezegun.freeze_time(max_extend + timedelta(hours=1)):
response = self.client.post('/%s/%s/cart/extend' % (self.orga.slug, self.event.slug), {
}, follow=True)
doc = BeautifulSoup(response.rendered_content, "lxml")
self.assertIn('no longer available', doc.select('.alert-danger')[0].text)
with scopes_disabled():
self.assertFalse(CartPosition.objects.filter(id=cp1.id).exists())
self.assertFalse(CartPosition.objects.filter(id=cp2.id).exists())
def test_subevent_renew_expired_successfully(self):
self.event.has_subevents = True
self.event.save()

View File

@@ -411,69 +411,6 @@ class CheckoutTestCase(BaseCheckoutTestCase, TimemachineTestMixin, TestCase):
with scopes_disabled():
ia = InvoiceAddress.objects.get(pk=self.client.session['carts'][self.session_key].get('invoice_address'))
assert ia.vat_id == "AT123456"
assert not ia.vat_id_validated
def test_reverse_charge_vatid_required(self):
self.event.settings.invoice_address_vatid = True
self.event.settings.invoice_address_vatid_required_countries = ["AT"]
with scopes_disabled():
CartPosition.objects.create(
event=self.event, cart_id=self.session_key, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
resp = self.client.post('/%s/%s/checkout/questions/' % (self.orga.slug, self.event.slug), {
'is_business': 'business',
'company': 'Foo',
'name': 'Bar',
'street': 'Baz',
'zipcode': '1234',
'city': 'Here',
'country': 'AT',
'email': 'admin@localhost',
'transmission_type': 'email',
}, follow=True)
assert 'has-error' in resp.content.decode()
def test_reverse_charge_vatid_check_unavailable_but_required(self):
self.tr19.eu_reverse_charge = True
self.tr19.home_country = Country('DE')
self.tr19.save()
self.event.settings.invoice_address_vatid = True
self.event.settings.invoice_address_vatid_required_countries = ["AT"]
with scopes_disabled():
cr1 = CartPosition.objects.create(
event=self.event, cart_id=self.session_key, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
with mock.patch('pretix.base.services.tax._validate_vat_id_EU') as mock_validate:
def raiser(*args, **kwargs):
raise VATIDTemporaryError('temp')
mock_validate.side_effect = raiser
self.client.post('/%s/%s/checkout/questions/' % (self.orga.slug, self.event.slug), {
'is_business': 'business',
'company': 'Foo',
'name': 'Bar',
'street': 'Baz',
'zipcode': '1234',
'city': 'Here',
'country': 'AT',
'vat_id': 'AT123456',
'email': 'admin@localhost',
'transmission_type': 'email',
}, follow=True)
cr1.refresh_from_db()
assert cr1.price == Decimal('23.00')
with scopes_disabled():
ia = InvoiceAddress.objects.get(pk=self.client.session['carts'][self.session_key].get('invoice_address'))
assert ia.vat_id == "AT123456"
assert not ia.vat_id_validated
def test_reverse_charge_keep_gross(self):
@@ -511,7 +448,6 @@ class CheckoutTestCase(BaseCheckoutTestCase, TimemachineTestMixin, TestCase):
with scopes_disabled():
ia = InvoiceAddress.objects.get(pk=self.client.session['carts'][self.session_key].get('invoice_address'))
assert ia.vat_id == "AT123456"
assert ia.vat_id_validated
def test_custom_tax_rules(self):
@@ -1516,7 +1452,7 @@ class CheckoutTestCase(BaseCheckoutTestCase, TimemachineTestMixin, TestCase):
'transmission_type': 'it_sdi',
'vat_id': '',
}, follow=True)
assert "This field is required" in response.content.decode()
assert "This field is required for the selected type" in response.content.decode()
response = self.client.post('/%s/%s/checkout/questions/' % (self.orga.slug, self.event.slug), {
'is_business': 'business',
@@ -1532,7 +1468,6 @@ class CheckoutTestCase(BaseCheckoutTestCase, TimemachineTestMixin, TestCase):
'state': 'MI',
'email': 'admin@localhost',
'transmission_type': 'email',
'vat_id': 'IT01234567890',
}, follow=True)
assert "must be used for this country" in response.content.decode()

View File

@@ -1,52 +0,0 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-today pretix GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# 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/>.
#
from django.http import HttpResponse
from django.urls import path
def view(request):
return HttpResponse("")
urlpatterns = [
path(
"testdummy",
view,
name="view",
),
]
organizer_patterns = [
path(
"testdummy",
view,
name="view",
),
]
event_patterns = [
path(
"testdummy",
view,
name="view",
),
]