Compare commits
72 Commits
v2025.10.0
...
hide-invis
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49b1c61dd1 | ||
|
|
db47f5638e | ||
|
|
a2dc467d0b | ||
|
|
dc1a115863 | ||
|
|
d0d7670ca5 | ||
|
|
a17a098b15 | ||
|
|
40516ab8e0 | ||
|
|
3ca343fabc | ||
|
|
7304b7f24b | ||
|
|
abaf968103 | ||
|
|
86e2f5a155 | ||
|
|
4c64af02c1 | ||
|
|
11df4398e1 | ||
|
|
2e89fc0a94 | ||
|
|
510c4850a5 | ||
|
|
b13368d614 | ||
|
|
b5cc8b368b | ||
|
|
87c30d0acb | ||
|
|
ffed8b29b1 | ||
|
|
53fbb64225 | ||
|
|
e10ec4074b | ||
|
|
7f2dc77aca | ||
|
|
199a3bf1e7 | ||
|
|
904aa807a3 | ||
|
|
0e41353a0e | ||
|
|
82ca50c7ff | ||
|
|
3437b64947 | ||
|
|
b895d9bbca | ||
|
|
f214edaf34 | ||
|
|
165a47b593 | ||
|
|
e06f281f1e | ||
|
|
203c7e660d | ||
|
|
8c360b8754 | ||
|
|
90b6511d11 | ||
|
|
bb356257cb | ||
|
|
e1950e408e | ||
|
|
99d5722ce1 | ||
|
|
324eeb8d40 | ||
|
|
449e8dc905 | ||
|
|
c491c8232e | ||
|
|
aa02cc7968 | ||
|
|
cfa13d6b9d | ||
|
|
af4eabc800 | ||
|
|
e1f5678d7c | ||
|
|
609b7c82ee | ||
|
|
8d66e1e732 | ||
|
|
c925f094f2 | ||
|
|
5caaa8586d | ||
|
|
1b1cf1557d | ||
|
|
35d8a7eec5 | ||
|
|
d428c3e1a4 | ||
|
|
63850f3139 | ||
|
|
04c8270d43 | ||
|
|
74a960e239 | ||
|
|
5a1bcae085 | ||
|
|
051eb78312 | ||
|
|
15808e55fd | ||
|
|
c886c0b415 | ||
|
|
47472447eb | ||
|
|
1a40215e91 | ||
|
|
d3fde85c39 | ||
|
|
40bd66cb86 | ||
|
|
bdd94b1f8a | ||
|
|
1c907f6a6f | ||
|
|
39e3ed9c25 | ||
|
|
4b5711253e | ||
|
|
bd554c7c29 | ||
|
|
2261951b15 | ||
|
|
0f82e1cae6 | ||
|
|
b0760157ce | ||
|
|
de2dec9089 | ||
|
|
446c8e622b |
@@ -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)
|
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
|
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 499.98). This becomes a problem when juristictions, data formats, or external systems expect this calculation
|
(instead of 500.00). 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
|
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.
|
does not allow the computation as created by pretix.
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,12 @@ dependencies = [
|
|||||||
"babel",
|
"babel",
|
||||||
"BeautifulSoup4==4.14.*",
|
"BeautifulSoup4==4.14.*",
|
||||||
"bleach==6.2.*",
|
"bleach==6.2.*",
|
||||||
"celery==5.5.*",
|
"celery==5.6.*",
|
||||||
"chardet==5.2.*",
|
"chardet==5.2.*",
|
||||||
"cryptography>=44.0.0",
|
"cryptography>=44.0.0",
|
||||||
"css-inline==0.18.*",
|
"css-inline==0.18.*",
|
||||||
"defusedcsv>=1.1.0",
|
"defusedcsv>=1.1.0",
|
||||||
|
"dnspython==2.*",
|
||||||
"Django[argon2]==4.2.*,>=4.2.26",
|
"Django[argon2]==4.2.*,>=4.2.26",
|
||||||
"django-bootstrap3==25.2",
|
"django-bootstrap3==25.2",
|
||||||
"django-compressor==4.5.1",
|
"django-compressor==4.5.1",
|
||||||
@@ -61,7 +62,7 @@ dependencies = [
|
|||||||
"importlib_metadata==8.*", # Polyfill, we can probably drop this once we require Python 3.10+
|
"importlib_metadata==8.*", # Polyfill, we can probably drop this once we require Python 3.10+
|
||||||
"isoweek",
|
"isoweek",
|
||||||
"jsonschema",
|
"jsonschema",
|
||||||
"kombu==5.5.*",
|
"kombu==5.6.*",
|
||||||
"libsass==0.23.*",
|
"libsass==0.23.*",
|
||||||
"lxml",
|
"lxml",
|
||||||
"markdown==3.9", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
|
"markdown==3.9", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
|
||||||
@@ -81,7 +82,7 @@ dependencies = [
|
|||||||
"pycountry",
|
"pycountry",
|
||||||
"pycparser==2.23",
|
"pycparser==2.23",
|
||||||
"pycryptodome==3.23.*",
|
"pycryptodome==3.23.*",
|
||||||
"pypdf==6.3.*",
|
"pypdf==6.4.*",
|
||||||
"python-bidi==0.6.*", # Support for Arabic in reportlab
|
"python-bidi==0.6.*", # Support for Arabic in reportlab
|
||||||
"python-dateutil==2.9.*",
|
"python-dateutil==2.9.*",
|
||||||
"pytz",
|
"pytz",
|
||||||
@@ -91,14 +92,13 @@ dependencies = [
|
|||||||
"redis==6.4.*",
|
"redis==6.4.*",
|
||||||
"reportlab==4.4.*",
|
"reportlab==4.4.*",
|
||||||
"requests==2.32.*",
|
"requests==2.32.*",
|
||||||
"sentry-sdk==2.45.*",
|
"sentry-sdk==2.47.*",
|
||||||
"sepaxml==2.7.*",
|
"sepaxml==2.7.*",
|
||||||
"stripe==7.9.*",
|
"stripe==7.9.*",
|
||||||
"text-unidecode==1.*",
|
"text-unidecode==1.*",
|
||||||
"tlds>=2020041600",
|
"tlds>=2020041600",
|
||||||
"tqdm==4.*",
|
"tqdm==4.*",
|
||||||
"ua-parser==1.0.*",
|
"ua-parser==1.0.*",
|
||||||
"vat_moss_forked==2020.3.20.0.11.0",
|
|
||||||
"vobject==0.9.*",
|
"vobject==0.9.*",
|
||||||
"webauthn==2.7.*",
|
"webauthn==2.7.*",
|
||||||
"zeep==4.3.*"
|
"zeep==4.3.*"
|
||||||
|
|||||||
@@ -19,4 +19,4 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
# 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/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
__version__ = "2025.10.0"
|
__version__ = "2025.11.0.dev0"
|
||||||
|
|||||||
@@ -795,6 +795,7 @@ class EventSettingsSerializer(SettingsSerializer):
|
|||||||
'invoice_address_asked',
|
'invoice_address_asked',
|
||||||
'invoice_address_required',
|
'invoice_address_required',
|
||||||
'invoice_address_vatid',
|
'invoice_address_vatid',
|
||||||
|
'invoice_address_vatid_required_countries',
|
||||||
'invoice_address_company_required',
|
'invoice_address_company_required',
|
||||||
'invoice_address_beneficiary',
|
'invoice_address_beneficiary',
|
||||||
'invoice_address_custom_field',
|
'invoice_address_custom_field',
|
||||||
@@ -943,6 +944,7 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer):
|
|||||||
'invoice_address_asked',
|
'invoice_address_asked',
|
||||||
'invoice_address_required',
|
'invoice_address_required',
|
||||||
'invoice_address_vatid',
|
'invoice_address_vatid',
|
||||||
|
'invoice_address_vatid_required_countries',
|
||||||
'invoice_address_company_required',
|
'invoice_address_company_required',
|
||||||
'invoice_address_beneficiary',
|
'invoice_address_beneficiary',
|
||||||
'invoice_address_custom_field',
|
'invoice_address_custom_field',
|
||||||
|
|||||||
@@ -567,7 +567,7 @@ class QuotaViewSet(ConditionalListView, viewsets.ModelViewSet):
|
|||||||
write_permission = 'can_change_items'
|
write_permission = 'can_change_items'
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.request.event.quotas.all()
|
return self.request.event.quotas.select_related('subevent').prefetch_related('items', 'variations').all()
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def list(self, request, *args, **kwargs):
|
||||||
queryset = self.filter_queryset(self.get_queryset()).distinct()
|
queryset = self.filter_queryset(self.get_queryset()).distinct()
|
||||||
|
|||||||
@@ -721,7 +721,7 @@ class MembershipViewSet(viewsets.ModelViewSet):
|
|||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return Membership.objects.filter(
|
return Membership.objects.filter(
|
||||||
customer__organizer=self.request.organizer
|
customer__organizer=self.request.organizer
|
||||||
)
|
).select_related('customer')
|
||||||
|
|
||||||
def get_serializer_context(self):
|
def get_serializer_context(self):
|
||||||
ctx = super().get_serializer_context()
|
ctx = super().get_serializer_context()
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
# 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/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import F, Q
|
from django.db.models import F, Q
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
@@ -64,8 +65,13 @@ class VoucherViewSet(viewsets.ModelViewSet):
|
|||||||
permission = 'can_view_vouchers'
|
permission = 'can_view_vouchers'
|
||||||
write_permission = 'can_change_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):
|
def get_queryset(self):
|
||||||
return self.request.event.vouchers.select_related('seat').all()
|
return Voucher.annotate_budget_used(
|
||||||
|
self.request.event.vouchers
|
||||||
|
).select_related(
|
||||||
|
'item', 'quota', 'seat', 'variation'
|
||||||
|
)
|
||||||
|
|
||||||
@transaction.atomic()
|
@transaction.atomic()
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ from pretix.base.services.tasks import ProfiledTask, TransactionAwareTask
|
|||||||
from pretix.base.signals import periodic_task
|
from pretix.base.signals import periodic_task
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
|
from pretix.helpers.celery import get_task_priority
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
_ALL_EVENTS = None
|
_ALL_EVENTS = None
|
||||||
@@ -474,7 +475,10 @@ def notify_webhooks(logentry_ids: list):
|
|||||||
)
|
)
|
||||||
|
|
||||||
for wh in webhooks:
|
for wh in webhooks:
|
||||||
send_webhook.apply_async(args=(logentry.id, notification_type.action_type, wh.pk))
|
send_webhook.apply_async(
|
||||||
|
args=(logentry.id, notification_type.action_type, wh.pk),
|
||||||
|
priority=get_task_priority("notifications", logentry.organizer_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=60, acks_late=True, autoretry_for=(DatabaseError,),)
|
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=60, acks_late=True, autoretry_for=(DatabaseError,),)
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ StaticMapping = namedtuple('StaticMapping', ('id', 'pretix_model', 'external_obj
|
|||||||
|
|
||||||
class OutboundSyncProvider:
|
class OutboundSyncProvider:
|
||||||
max_attempts = 5
|
max_attempts = 5
|
||||||
|
list_field_joiner = "," # set to None to keep native lists in properties
|
||||||
|
|
||||||
def __init__(self, event):
|
def __init__(self, event):
|
||||||
self.event = event
|
self.event = event
|
||||||
@@ -281,7 +282,8 @@ class OutboundSyncProvider:
|
|||||||
'Please update value mapping for field "{field_name}" - option "{val}" not assigned'
|
'Please update value mapping for field "{field_name}" - option "{val}" not assigned'
|
||||||
).format(field_name=key, val=val)])
|
).format(field_name=key, val=val)])
|
||||||
|
|
||||||
val = ",".join(val)
|
if self.list_field_joiner:
|
||||||
|
val = self.list_field_joiner.join(val)
|
||||||
return val
|
return val
|
||||||
|
|
||||||
def get_properties(self, inputs: dict, property_mappings: List[dict]):
|
def get_properties(self, inputs: dict, property_mappings: List[dict]):
|
||||||
|
|||||||
@@ -71,15 +71,20 @@ def assign_properties(
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def _add_to_list(out, field_name, current_value, new_item, list_sep):
|
def _add_to_list(out, field_name, current_value, new_item_input, list_sep):
|
||||||
new_item = str(new_item)
|
|
||||||
if list_sep is not None:
|
if list_sep is not None:
|
||||||
new_item = new_item.replace(list_sep, "")
|
new_items = str(new_item_input).split(list_sep)
|
||||||
current_value = current_value.split(list_sep) if current_value else []
|
current_value = current_value.split(list_sep) if current_value else []
|
||||||
elif not isinstance(current_value, (list, tuple)):
|
else:
|
||||||
current_value = [str(current_value)]
|
new_items = [str(new_item_input)]
|
||||||
if new_item not in current_value:
|
if not isinstance(current_value, (list, tuple)):
|
||||||
new_list = current_value + [new_item]
|
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:
|
||||||
if list_sep is not None:
|
if list_sep is not None:
|
||||||
new_list = list_sep.join(new_list)
|
new_list = list_sep.join(new_list)
|
||||||
out[field_name] = new_list
|
out[field_name] = new_list
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ from pretix.base.invoicing.transmission import (
|
|||||||
from pretix.base.models import InvoiceAddress, Item, Question, QuestionOption
|
from pretix.base.models import InvoiceAddress, Item, Question, QuestionOption
|
||||||
from pretix.base.models.tax import ask_for_vat_id
|
from pretix.base.models.tax import ask_for_vat_id
|
||||||
from pretix.base.services.tax import (
|
from pretix.base.services.tax import (
|
||||||
VATIDFinalError, VATIDTemporaryError, validate_vat_id,
|
VATIDFinalError, VATIDTemporaryError, normalize_vat_id, validate_vat_id,
|
||||||
)
|
)
|
||||||
from pretix.base.settings import (
|
from pretix.base.settings import (
|
||||||
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
|
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
|
||||||
@@ -1165,13 +1165,11 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
self.fields['vat_id'].help_text = '<br/>'.join([
|
self.fields['vat_id'].help_text = '<br/>'.join([
|
||||||
str(_('Optional, but depending on the country you reside in we might need to charge you '
|
str(_('Optional, but depending on the country you reside in we might need to charge you '
|
||||||
'additional taxes if you do not enter it.')),
|
'additional taxes if you do not enter it.')),
|
||||||
str(_('If you are registered in Switzerland, you can enter your UID instead.')),
|
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
self.fields['vat_id'].help_text = '<br/>'.join([
|
self.fields['vat_id'].help_text = '<br/>'.join([
|
||||||
str(_('Optional, but it might be required for you to claim tax benefits on your invoice '
|
str(_('Optional, but it might be required for you to claim tax benefits on your invoice '
|
||||||
'depending on your and the seller’s country of residence.')),
|
'depending on your and the seller’s country of residence.')),
|
||||||
str(_('If you are registered in Switzerland, you can enter your UID instead.')),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
transmission_type_choices = [
|
transmission_type_choices = [
|
||||||
@@ -1358,13 +1356,24 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
"transmission method.")}
|
"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:
|
if self.validate_vat_id and self.instance.vat_id_validated and 'vat_id' not in self.changed_data:
|
||||||
pass
|
pass # Skip re-validation if it is validated
|
||||||
elif self.validate_vat_id and data.get('is_business') and ask_for_vat_id(data.get('country')) and data.get('vat_id'):
|
elif self.validate_vat_id and vat_id_applicable:
|
||||||
try:
|
try:
|
||||||
normalized_id = validate_vat_id(data.get('vat_id'), str(data.get('country')))
|
normalized_id = validate_vat_id(data.get('vat_id'), str(data.get('country')))
|
||||||
self.instance.vat_id_validated = True
|
self.instance.vat_id_validated = True
|
||||||
self.instance.vat_id = normalized_id
|
self.instance.vat_id = data['vat_id'] = normalized_id
|
||||||
except VATIDFinalError as e:
|
except VATIDFinalError as e:
|
||||||
if self.all_optional:
|
if self.all_optional:
|
||||||
self.instance.vat_id_validated = False
|
self.instance.vat_id_validated = False
|
||||||
@@ -1372,6 +1381,9 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
else:
|
else:
|
||||||
raise ValidationError({"vat_id": e.message})
|
raise ValidationError({"vat_id": e.message})
|
||||||
except VATIDTemporaryError as e:
|
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
|
self.instance.vat_id_validated = False
|
||||||
if self.request and self.vat_warning:
|
if self.request and self.vat_warning:
|
||||||
messages.warning(self.request, e.message)
|
messages.warning(self.request, e.message)
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ from itertools import groupby
|
|||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import bleach
|
import bleach
|
||||||
import vat_moss.exchange_rates
|
|
||||||
from bidi import get_display
|
from bidi import get_display
|
||||||
from django.contrib.staticfiles import finders
|
from django.contrib.staticfiles import finders
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
@@ -1059,7 +1058,7 @@ class ClassicInvoiceRenderer(BaseReportlabInvoiceRenderer):
|
|||||||
|
|
||||||
def fmt(val):
|
def fmt(val):
|
||||||
try:
|
try:
|
||||||
return vat_moss.exchange_rates.format(val, self.invoice.foreign_currency_display)
|
return money_filter(val, self.invoice.foreign_currency_display)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return localize(val) + ' ' + self.invoice.foreign_currency_display
|
return localize(val) + ' ' + self.invoice.foreign_currency_display
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,11 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
# 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/>.
|
# <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import dns.resolver
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import gettext_lazy as _, pgettext
|
from django.utils.translation import gettext_lazy as _, pgettext
|
||||||
@@ -123,6 +126,9 @@ class PeppolIdValidator:
|
|||||||
"9959": ".*",
|
"9959": ".*",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def __init__(self, validate_online=False):
|
||||||
|
self.validate_online = validate_online
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
if ":" not in value:
|
if ":" not in value:
|
||||||
raise ValidationError(_("A Peppol participant ID always starts with a prefix, followed by a colon (:)."))
|
raise ValidationError(_("A Peppol participant ID always starts with a prefix, followed by a colon (:)."))
|
||||||
@@ -136,6 +142,28 @@ class PeppolIdValidator:
|
|||||||
raise ValidationError(_("The Peppol participant ID does not match the validation rules for the prefix "
|
raise ValidationError(_("The Peppol participant ID does not match the validation rules for the prefix "
|
||||||
"%(number)s. Please reach out to us if you are sure this ID is correct."),
|
"%(number)s. Please reach out to us if you are sure this ID is correct."),
|
||||||
params={"number": prefix})
|
params={"number": prefix})
|
||||||
|
|
||||||
|
if self.validate_online:
|
||||||
|
base_hostnames = ['edelivery.tech.ec.europa.eu', 'acc.edelivery.tech.ec.europa.eu']
|
||||||
|
smp_id = base64.b32encode(hashlib.sha256(value.lower().encode()).digest()).decode().rstrip("=")
|
||||||
|
for base_hostname in base_hostnames:
|
||||||
|
smp_domain = f'{smp_id}.iso6523-actorid-upis.{base_hostname}'
|
||||||
|
resolver = dns.resolver.Resolver()
|
||||||
|
try:
|
||||||
|
answers = resolver.resolve(smp_domain, 'NAPTR', lifetime=1.0)
|
||||||
|
if answers:
|
||||||
|
return value
|
||||||
|
except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
|
||||||
|
# ID not registered, do not set found=True
|
||||||
|
pass
|
||||||
|
except Exception: # noqa
|
||||||
|
# Error likely on our end or infrastructure is down, allow user to proceed
|
||||||
|
return value
|
||||||
|
|
||||||
|
raise ValidationError(
|
||||||
|
_("The Peppol participant ID is not registered on the Peppol network."),
|
||||||
|
)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
@@ -155,7 +183,9 @@ class PeppolTransmissionType(TransmissionType):
|
|||||||
"transmission_peppol_participant_id": forms.CharField(
|
"transmission_peppol_participant_id": forms.CharField(
|
||||||
label=_("Peppol participant ID"),
|
label=_("Peppol participant ID"),
|
||||||
validators=[
|
validators=[
|
||||||
PeppolIdValidator(),
|
PeppolIdValidator(
|
||||||
|
validate_online=True,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,19 @@ class DataImportError(LazyLocaleException):
|
|||||||
super().__init__(msg)
|
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):
|
def parse_csv(file, length=None, mode="strict", charset=None):
|
||||||
file.seek(0)
|
file.seek(0)
|
||||||
data = file.read(length)
|
data = file.read(length)
|
||||||
@@ -70,6 +83,7 @@ def parse_csv(file, length=None, mode="strict", charset=None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
reader = csv.DictReader(io.StringIO(data), dialect=dialect)
|
reader = csv.DictReader(io.StringIO(data), dialect=dialect)
|
||||||
|
reader._had_duplicates = rename_duplicates(reader.fieldnames)
|
||||||
return reader
|
return reader
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ from django.utils.timezone import now
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_otp.models import Device
|
from django_otp.models import Device
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
|
|
||||||
|
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.helpers.urls import build_absolute_uri
|
from pretix.helpers.urls import build_absolute_uri
|
||||||
@@ -708,6 +707,8 @@ class U2FDevice(Device):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def webauthndevice(self):
|
def webauthndevice(self):
|
||||||
|
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
|
||||||
|
|
||||||
d = json.loads(self.json_data)
|
d = json.loads(self.json_data)
|
||||||
return PublicKeyCredentialDescriptor(websafe_decode(d['keyHandle']))
|
return PublicKeyCredentialDescriptor(websafe_decode(d['keyHandle']))
|
||||||
|
|
||||||
@@ -737,6 +738,8 @@ class WebAuthnDevice(Device):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def webauthndevice(self):
|
def webauthndevice(self):
|
||||||
|
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
|
||||||
|
|
||||||
return PublicKeyCredentialDescriptor(websafe_decode(self.credential_id))
|
return PublicKeyCredentialDescriptor(websafe_decode(self.credential_id))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from django.urls import reverse
|
|||||||
from django.utils.crypto import get_random_string
|
from django.utils.crypto import get_random_string
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
|
from pretix.helpers.celery import get_task_priority
|
||||||
from pretix.helpers.json import CustomJSONEncoder
|
from pretix.helpers.json import CustomJSONEncoder
|
||||||
|
|
||||||
|
|
||||||
@@ -131,9 +132,15 @@ class LoggingMixin:
|
|||||||
logentry.save()
|
logentry.save()
|
||||||
|
|
||||||
if logentry.notification_type:
|
if logentry.notification_type:
|
||||||
notify.apply_async(args=(logentry.pk,))
|
notify.apply_async(
|
||||||
|
args=(logentry.pk,),
|
||||||
|
priority=get_task_priority("notifications", logentry.organizer_id),
|
||||||
|
)
|
||||||
if logentry.webhook_type:
|
if logentry.webhook_type:
|
||||||
notify_webhooks.apply_async(args=(logentry.pk,))
|
notify_webhooks.apply_async(
|
||||||
|
args=(logentry.pk,),
|
||||||
|
priority=get_task_priority("notifications", logentry.organizer_id),
|
||||||
|
)
|
||||||
|
|
||||||
return logentry
|
return logentry
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,14 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db import connections, models
|
from django.db import connections, models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
|
from pretix.helpers.celery import get_task_priority
|
||||||
|
|
||||||
|
|
||||||
class VisibleOnlyManager(models.Manager):
|
class VisibleOnlyManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
@@ -186,7 +189,19 @@ class LogEntry(models.Model):
|
|||||||
|
|
||||||
to_notify = [o.id for o in objects if o.notification_type]
|
to_notify = [o.id for o in objects if o.notification_type]
|
||||||
if to_notify:
|
if to_notify:
|
||||||
notify.apply_async(args=(to_notify,))
|
organizer_ids = set(o.organizer_id for o in objects if o.notification_type)
|
||||||
|
notify.apply_async(
|
||||||
|
args=(to_notify,),
|
||||||
|
priority=settings.PRIORITY_CELERY_HIGHEST_FUNC(
|
||||||
|
get_task_priority("notifications", oid) for oid in organizer_ids
|
||||||
|
),
|
||||||
|
)
|
||||||
to_wh = [o.id for o in objects if o.webhook_type]
|
to_wh = [o.id for o in objects if o.webhook_type]
|
||||||
if to_wh:
|
if to_wh:
|
||||||
notify_webhooks.apply_async(args=(to_wh,))
|
organizer_ids = set(o.organizer_id for o in objects if o.webhook_type)
|
||||||
|
notify_webhooks.apply_async(
|
||||||
|
args=(to_wh,),
|
||||||
|
priority=settings.PRIORITY_CELERY_HIGHEST_FUNC(
|
||||||
|
get_task_priority("notifications", oid) for oid in organizer_ids
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|||||||
@@ -3526,11 +3526,30 @@ class InvoiceAddress(models.Model):
|
|||||||
})
|
})
|
||||||
return d
|
return d
|
||||||
|
|
||||||
def describe_transmission(self):
|
def describe_transmission(self, event=None):
|
||||||
|
# we only need an explicit event if the order is not yet created and we do not want to show unnecessary data to customers
|
||||||
from pretix.base.invoicing.transmission import transmission_types
|
from pretix.base.invoicing.transmission import transmission_types
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
t, __ = transmission_types.get(identifier=self.transmission_type)
|
t, m = transmission_types.get(identifier=self.transmission_type)
|
||||||
|
|
||||||
|
d_event = self.order.event if self.order else event
|
||||||
|
# reusing hack from questions.py for default transmission -- this should at least be fast
|
||||||
|
if d_event:
|
||||||
|
if (
|
||||||
|
t.identifier == "email" and
|
||||||
|
m in ("transmission_email_other", "transmission_email_address") and
|
||||||
|
(
|
||||||
|
d_event.settings.invoice_generate == "False" or
|
||||||
|
not d_event.settings.invoice_email_attachment
|
||||||
|
)
|
||||||
|
):
|
||||||
|
return data
|
||||||
|
|
||||||
|
# we also don't show transmission data if we never showed the corresponding form fields
|
||||||
|
if not t.invoice_address_form_fields_visible(country=self.country, is_business=self.is_business):
|
||||||
|
return data
|
||||||
|
|
||||||
data.append((_("Transmission type"), t.public_name))
|
data.append((_("Transmission type"), t.public_name))
|
||||||
form_data = t.transmission_info_to_form_data(self.transmission_info or {})
|
form_data = t.transmission_info_to_form_data(self.transmission_info or {})
|
||||||
for k, f in t.invoice_address_form_fields.items():
|
for k, f in t.invoice_address_form_fields.items():
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
import json
|
import json
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
import jsonschema
|
|
||||||
from django.contrib.staticfiles import finders
|
from django.contrib.staticfiles import finders
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@@ -38,6 +37,8 @@ from pretix.base.models import Event, Item, LoggedModel, Organizer, SubEvent
|
|||||||
@deconstructible
|
@deconstructible
|
||||||
class SeatingPlanLayoutValidator:
|
class SeatingPlanLayoutValidator:
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
|
import jsonschema
|
||||||
|
|
||||||
if not isinstance(value, dict):
|
if not isinstance(value, dict):
|
||||||
try:
|
try:
|
||||||
val = json.loads(value)
|
val = json.loads(value)
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import json
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import jsonschema
|
|
||||||
from django.contrib.staticfiles import finders
|
from django.contrib.staticfiles import finders
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import MaxValueValidator, MinValueValidator
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||||
@@ -298,6 +297,8 @@ def cc_to_vat_prefix(country_code):
|
|||||||
@deconstructible
|
@deconstructible
|
||||||
class CustomRulesValidator:
|
class CustomRulesValidator:
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
|
import jsonschema
|
||||||
|
|
||||||
if not isinstance(value, dict):
|
if not isinstance(value, dict):
|
||||||
try:
|
try:
|
||||||
val = json.loads(value)
|
val = json.loads(value)
|
||||||
|
|||||||
@@ -623,7 +623,7 @@ class Voucher(LoggedModel):
|
|||||||
return max(1, self.min_usages - self.redeemed)
|
return max(1, self.min_usages - self.redeemed)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def annotate_budget_used_orders(cls, qs):
|
def annotate_budget_used(cls, qs):
|
||||||
opq = OrderPosition.objects.filter(
|
opq = OrderPosition.objects.filter(
|
||||||
voucher_id=OuterRef('pk'),
|
voucher_id=OuterRef('pk'),
|
||||||
voucher_budget_use__isnull=False,
|
voucher_budget_use__isnull=False,
|
||||||
@@ -632,7 +632,7 @@ class Voucher(LoggedModel):
|
|||||||
Order.STATUS_PENDING
|
Order.STATUS_PENDING
|
||||||
]
|
]
|
||||||
).order_by().values('voucher_id').annotate(s=Sum('voucher_budget_use')).values('s')
|
).order_by().values('voucher_id').annotate(s=Sum('voucher_budget_use')).values('s')
|
||||||
return qs.annotate(budget_used_orders=Coalesce(Subquery(opq, output_field=models.DecimalField(max_digits=13, decimal_places=2)), Decimal('0.00')))
|
return qs.annotate(budget_used=Coalesce(Subquery(opq, output_field=models.DecimalField(max_digits=13, decimal_places=2)), Decimal('0.00')))
|
||||||
|
|
||||||
def budget_used(self):
|
def budget_used(self):
|
||||||
ops = OrderPosition.objects.filter(
|
ops = OrderPosition.objects.filter(
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ from collections import OrderedDict, defaultdict
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import jsonschema
|
|
||||||
import pypdf
|
import pypdf
|
||||||
import pypdf.generic
|
import pypdf.generic
|
||||||
import reportlab.rl_config
|
import reportlab.rl_config
|
||||||
@@ -1311,6 +1310,8 @@ def _correct_page_media_box(page: pypdf.PageObject):
|
|||||||
@deconstructible
|
@deconstructible
|
||||||
class PdfLayoutValidator:
|
class PdfLayoutValidator:
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
|
import jsonschema
|
||||||
|
|
||||||
if not isinstance(value, dict):
|
if not isinstance(value, dict):
|
||||||
try:
|
try:
|
||||||
val = json.loads(value)
|
val = json.loads(value)
|
||||||
|
|||||||
@@ -1361,6 +1361,11 @@ class CartManager:
|
|||||||
deleted_positions.add(op.position.pk)
|
deleted_positions.add(op.position.pk)
|
||||||
addons.delete()
|
addons.delete()
|
||||||
op.position.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:
|
else:
|
||||||
raise AssertionError("ExtendOperation cannot affect more than one item")
|
raise AssertionError("ExtendOperation cannot affect more than one item")
|
||||||
elif isinstance(op, self.VoucherOperation):
|
elif isinstance(op, self.VoucherOperation):
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ from urllib.parse import urljoin, urlparse
|
|||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
from celery import chain
|
from celery import chain
|
||||||
from celery.exceptions import MaxRetriesExceededError
|
from celery.exceptions import MaxRetriesExceededError
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -764,6 +763,8 @@ def render_mail(template, context, placeholder_mode=SafeFormatter.MODE_RICH_TO_P
|
|||||||
|
|
||||||
|
|
||||||
def replace_images_with_cid_paths(body_html):
|
def replace_images_with_cid_paths(body_html):
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
if body_html:
|
if body_html:
|
||||||
email = BeautifulSoup(body_html, "lxml")
|
email = BeautifulSoup(body_html, "lxml")
|
||||||
cid_images = []
|
cid_images = []
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ from pretix.base.services.mail import mail_send_task
|
|||||||
from pretix.base.services.tasks import ProfiledTask, TransactionAwareTask
|
from pretix.base.services.tasks import ProfiledTask, TransactionAwareTask
|
||||||
from pretix.base.signals import notification
|
from pretix.base.signals import notification
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
|
from pretix.helpers.celery import get_task_priority
|
||||||
from pretix.helpers.urls import build_absolute_uri
|
from pretix.helpers.urls import build_absolute_uri
|
||||||
|
|
||||||
|
|
||||||
@@ -88,12 +89,18 @@ def notify(logentry_ids: list):
|
|||||||
for um, enabled in notify_specific.items():
|
for um, enabled in notify_specific.items():
|
||||||
user, method = um
|
user, method = um
|
||||||
if enabled:
|
if enabled:
|
||||||
send_notification.apply_async(args=(logentry.id, notification_type.action_type, user.pk, method))
|
send_notification.apply_async(
|
||||||
|
args=(logentry.id, notification_type.action_type, user.pk, method),
|
||||||
|
priority=get_task_priority("notifications", logentry.organizer_id),
|
||||||
|
)
|
||||||
|
|
||||||
for um, enabled in notify_global.items():
|
for um, enabled in notify_global.items():
|
||||||
user, method = um
|
user, method = um
|
||||||
if enabled and um not in notify_specific:
|
if enabled and um not in notify_specific:
|
||||||
send_notification.apply_async(args=(logentry.id, notification_type.action_type, user.pk, method))
|
send_notification.apply_async(
|
||||||
|
args=(logentry.id, notification_type.action_type, user.pk, method),
|
||||||
|
priority=get_task_priority("notifications", logentry.organizer_id),
|
||||||
|
)
|
||||||
|
|
||||||
notification.send(logentry.event, logentry_id=logentry.id, notification_type=notification_type.action_type)
|
notification.send(logentry.event, logentry_id=logentry.id, notification_type=notification_type.action_type)
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ from decimal import Decimal
|
|||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import vat_moss.id
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from zeep import Client, Transport
|
from zeep import Client, Transport
|
||||||
@@ -42,14 +41,142 @@ logger = logging.getLogger(__name__)
|
|||||||
error_messages = {
|
error_messages = {
|
||||||
'unavailable': _(
|
'unavailable': _(
|
||||||
'Your VAT ID could not be checked, as the VAT checking service of '
|
'Your VAT ID could not be checked, as the VAT checking service of '
|
||||||
'your country is currently not available. We will therefore '
|
'your country is currently not available. We will therefore need to '
|
||||||
'need to charge VAT on your invoice. You can get the tax amount '
|
'charge you the same tax rate as if you did not enter a VAT ID.'
|
||||||
'back via the VAT reimbursement process.'
|
|
||||||
),
|
),
|
||||||
'invalid': _('This VAT ID is not valid. Please re-check your input.'),
|
'invalid': _('This VAT ID is not valid. Please re-check your input.'),
|
||||||
'country_mismatch': _('Your VAT ID does not match the selected country.'),
|
'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):
|
class VATIDError(Exception):
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
@@ -64,13 +191,57 @@ class VATIDTemporaryError(VATIDError):
|
|||||||
pass
|
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):
|
def _validate_vat_id_NO(vat_id, country_code):
|
||||||
# Inspired by vat_moss library
|
# 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:
|
try:
|
||||||
vat_id = vat_moss.id.normalize(vat_id)
|
vat_id = normalize_vat_id(vat_id, country_code)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise VATIDFinalError(error_messages['invalid'])
|
raise VATIDFinalError(error_messages['invalid'])
|
||||||
|
|
||||||
@@ -104,7 +275,7 @@ def _validate_vat_id_NO(vat_id, country_code):
|
|||||||
def _validate_vat_id_EU(vat_id, country_code):
|
def _validate_vat_id_EU(vat_id, country_code):
|
||||||
# Inspired by vat_moss library
|
# Inspired by vat_moss library
|
||||||
try:
|
try:
|
||||||
vat_id = vat_moss.id.normalize(vat_id)
|
vat_id = normalize_vat_id(vat_id, country_code)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise VATIDFinalError(error_messages['invalid'])
|
raise VATIDFinalError(error_messages['invalid'])
|
||||||
|
|
||||||
@@ -112,11 +283,10 @@ def _validate_vat_id_EU(vat_id, country_code):
|
|||||||
raise VATIDFinalError(error_messages['invalid'])
|
raise VATIDFinalError(error_messages['invalid'])
|
||||||
|
|
||||||
number = vat_id[2:]
|
number = vat_id[2:]
|
||||||
|
|
||||||
if vat_id[:2] != cc_to_vat_prefix(country_code):
|
if vat_id[:2] != cc_to_vat_prefix(country_code):
|
||||||
raise VATIDFinalError(error_messages['country_mismatch'])
|
raise VATIDFinalError(error_messages['country_mismatch'])
|
||||||
|
|
||||||
if not re.match(vat_moss.id.ID_PATTERNS[cc_to_vat_prefix(country_code)]['regex'], number):
|
if not re.match(VAT_ID_PATTERNS[cc_to_vat_prefix(country_code)]['regex'], number):
|
||||||
raise VATIDFinalError(error_messages['invalid'])
|
raise VATIDFinalError(error_messages['invalid'])
|
||||||
|
|
||||||
# We are relying on the country code of the normalized VAT-ID and not the user/InvoiceAddress-provided
|
# We are relying on the country code of the normalized VAT-ID and not the user/InvoiceAddress-provided
|
||||||
@@ -175,9 +345,12 @@ def _validate_vat_id_EU(vat_id, country_code):
|
|||||||
|
|
||||||
def _validate_vat_id_CH(vat_id, country_code):
|
def _validate_vat_id_CH(vat_id, country_code):
|
||||||
if vat_id[:3] != 'CHE':
|
if vat_id[:3] != 'CHE':
|
||||||
raise VATIDFinalError(_('Your VAT ID does not match the selected country.'))
|
raise VATIDFinalError(error_messages['country_mismatch'])
|
||||||
|
|
||||||
vat_id = re.sub('[^A-Z0-9]', '', vat_id.replace('HR', '').replace('MWST', ''))
|
try:
|
||||||
|
vat_id = normalize_vat_id(vat_id, country_code)
|
||||||
|
except ValueError:
|
||||||
|
raise VATIDFinalError(error_messages['invalid'])
|
||||||
try:
|
try:
|
||||||
transport = Transport(
|
transport = Transport(
|
||||||
cache=SqliteCache(os.path.join(settings.CACHE_DIR, "validate_vat_id_ch_zeep_cache.db")),
|
cache=SqliteCache(os.path.join(settings.CACHE_DIR, "validate_vat_id_ch_zeep_cache.db")),
|
||||||
|
|||||||
@@ -113,6 +113,11 @@ def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None)
|
|||||||
|
|
||||||
lock_objects(quotas, shared_lock_objects=[event])
|
lock_objects(quotas, shared_lock_objects=[event])
|
||||||
for wle in qs:
|
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:
|
if (wle.item_id, wle.variation_id, wle.subevent_id) in gone:
|
||||||
continue
|
continue
|
||||||
ev = (wle.subevent or event)
|
ev = (wle.subevent or event)
|
||||||
|
|||||||
@@ -629,13 +629,40 @@ DEFAULTS = {
|
|||||||
'form_kwargs': dict(
|
'form_kwargs': dict(
|
||||||
label=_("Ask for VAT ID"),
|
label=_("Ask for VAT ID"),
|
||||||
help_text=format_lazy(
|
help_text=format_lazy(
|
||||||
_("Only works if an invoice address is asked for. VAT ID is never required and only requested from "
|
_("Only works if an invoice address is asked for. VAT ID is only requested from business customers "
|
||||||
"business customers in the following countries: {countries}"),
|
"in the following countries: {countries}."),
|
||||||
countries=lazy(lambda *args: ', '.join(sorted(gettext(Country(cc).name) for cc in VAT_ID_COUNTRIES)), str)()
|
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'}),
|
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': {
|
'invoice_address_explanation_text': {
|
||||||
'default': '',
|
'default': '',
|
||||||
'type': LazyI18nString,
|
'type': LazyI18nString,
|
||||||
|
|||||||
65
src/pretix/base/templatetags/html_time.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#
|
||||||
|
# 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 datetime
|
||||||
|
|
||||||
|
from django import template
|
||||||
|
from django.utils.html import format_html
|
||||||
|
from django.utils.timezone import get_current_timezone
|
||||||
|
|
||||||
|
from pretix.base.i18n import LazyExpiresDate
|
||||||
|
from pretix.helpers.templatetags.date_fast import date_fast
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def html_time(value: datetime, dt_format: str = "SHORT_DATE_FORMAT", **kwargs):
|
||||||
|
"""
|
||||||
|
Building a <time datetime='{html-datetime}'>{human-readable datetime}</time> html string,
|
||||||
|
where the html-datetime as well as the human-readable datetime can be set
|
||||||
|
to a value from django's FORMAT_SETTINGS or "format_expires".
|
||||||
|
|
||||||
|
If attr_fmt isn’t provided, it will be set to isoformat.
|
||||||
|
|
||||||
|
Usage example:
|
||||||
|
{% html_time event_start "SHORT_DATETIME_FORMAT" %}
|
||||||
|
or
|
||||||
|
{% html_time event_start "TIME_FORMAT" attr_fmt="H:i" %}
|
||||||
|
"""
|
||||||
|
if value in (None, ''):
|
||||||
|
return ''
|
||||||
|
value = value.astimezone(get_current_timezone())
|
||||||
|
attr_fmt = kwargs["attr_fmt"] if kwargs else None
|
||||||
|
|
||||||
|
try:
|
||||||
|
if not attr_fmt:
|
||||||
|
date_html = value.isoformat()
|
||||||
|
else:
|
||||||
|
date_html = date_fast(value, attr_fmt)
|
||||||
|
|
||||||
|
if dt_format == "format_expires":
|
||||||
|
date_human = LazyExpiresDate(value)
|
||||||
|
else:
|
||||||
|
date_human = date_fast(value, dt_format)
|
||||||
|
return format_html("<time datetime='{}'>{}</time>", date_html, date_human)
|
||||||
|
except AttributeError:
|
||||||
|
return ''
|
||||||
@@ -93,7 +93,9 @@ def timeline_for_event(event, subevent=None):
|
|||||||
description=format_lazy(
|
description=format_lazy(
|
||||||
'{} ({})',
|
'{} ({})',
|
||||||
pgettext_lazy('timeline', 'End of ticket sales'),
|
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', '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')
|
||||||
),
|
),
|
||||||
edit_url=ev_edit_url + '#id_presale_end_0'
|
edit_url=ev_edit_url + '#id_presale_end_0'
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
import pycountry
|
import pycountry
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.utils.translation import pgettext
|
from django.utils.translation import gettext, pgettext, pgettext_lazy
|
||||||
from django_countries.fields import Country
|
from django_countries.fields import Country
|
||||||
from django_scopes import scope
|
from django_scopes import scope
|
||||||
|
|
||||||
@@ -36,6 +36,22 @@ from pretix.base.settings import (
|
|||||||
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
|
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):
|
def _info(cc):
|
||||||
info = {
|
info = {
|
||||||
@@ -47,7 +63,12 @@ def _info(cc):
|
|||||||
'required': 'if_any' if cc in COUNTRIES_WITH_STATE_IN_ADDRESS else False,
|
'required': 'if_any' if cc in COUNTRIES_WITH_STATE_IN_ADDRESS else False,
|
||||||
'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')),
|
'label': COUNTRY_STATE_LABEL.get(cc, pgettext('address', 'State')),
|
||||||
},
|
},
|
||||||
'vat_id': {'visible': cc in VAT_ID_COUNTRIES, 'required': False},
|
'vat_id': {
|
||||||
|
'visible': cc in VAT_ID_COUNTRIES,
|
||||||
|
'required': False,
|
||||||
|
'label': VAT_ID_LABELS.get(cc, gettext("VAT ID")),
|
||||||
|
'helptext_visible': True,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
|
if cc not in COUNTRIES_WITH_STATE_IN_ADDRESS:
|
||||||
return {'data': [], **info}
|
return {'data': [], **info}
|
||||||
@@ -124,4 +145,10 @@ def address_form(request):
|
|||||||
"required": transmission_type.identifier == selected_transmission_type and k in required
|
"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)
|
return JsonResponse(info)
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ class EventWizardBasicsForm(I18nModelForm):
|
|||||||
'Sample Conference Center\nHeidelberg, Germany'
|
'Sample Conference Center\nHeidelberg, Germany'
|
||||||
)
|
)
|
||||||
self.fields['slug'].widget.prefix = build_absolute_uri(self.organizer, 'presale:organizer.index')
|
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:
|
if self.has_subevents:
|
||||||
del self.fields['presale_start']
|
del self.fields['presale_start']
|
||||||
del self.fields['presale_end']
|
del self.fields['presale_end']
|
||||||
@@ -927,6 +928,7 @@ class InvoiceSettingsForm(EventSettingsValidationMixin, SettingsForm):
|
|||||||
'invoice_address_asked',
|
'invoice_address_asked',
|
||||||
'invoice_address_required',
|
'invoice_address_required',
|
||||||
'invoice_address_vatid',
|
'invoice_address_vatid',
|
||||||
|
'invoice_address_vatid_required_countries',
|
||||||
'invoice_address_company_required',
|
'invoice_address_company_required',
|
||||||
'invoice_address_beneficiary',
|
'invoice_address_beneficiary',
|
||||||
'invoice_address_custom_field',
|
'invoice_address_custom_field',
|
||||||
@@ -1957,6 +1959,13 @@ class EventFooterLinkForm(I18nModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = EventFooterLink
|
model = EventFooterLink
|
||||||
fields = ('label', 'url')
|
fields = ('label', 'url')
|
||||||
|
widgets = {
|
||||||
|
"url": forms.URLInput(
|
||||||
|
attrs={
|
||||||
|
"placeholder": "https://..."
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class BaseEventFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):
|
class BaseEventFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ from pretix.base.models import (
|
|||||||
SubEvent, SubEventMetaValue, Team, TeamAPIToken, TeamInvite, Voucher,
|
SubEvent, SubEventMetaValue, Team, TeamAPIToken, TeamInvite, Voucher,
|
||||||
)
|
)
|
||||||
from pretix.base.signals import register_payment_providers
|
from pretix.base.signals import register_payment_providers
|
||||||
|
from pretix.base.timeframes import (
|
||||||
|
DateFrameField,
|
||||||
|
resolve_timeframe_to_datetime_start_inclusive_end_exclusive,
|
||||||
|
)
|
||||||
from pretix.control.forms import SplitDateTimeField
|
from pretix.control.forms import SplitDateTimeField
|
||||||
from pretix.control.forms.widgets import Select2, Select2ItemVarQuota
|
from pretix.control.forms.widgets import Select2, Select2ItemVarQuota
|
||||||
from pretix.control.signals import order_search_filter_q
|
from pretix.control.signals import order_search_filter_q
|
||||||
@@ -1219,6 +1223,129 @@ class OrderPaymentSearchFilterForm(forms.Form):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
|
class QuestionAnswerFilterForm(forms.Form):
|
||||||
|
STATUS_VARIANTS = [
|
||||||
|
("", _("All orders")),
|
||||||
|
(Order.STATUS_PAID, _("Paid")),
|
||||||
|
(Order.STATUS_PAID + 'v', _("Paid or confirmed")),
|
||||||
|
(Order.STATUS_PENDING, _("Pending")),
|
||||||
|
(Order.STATUS_PENDING + Order.STATUS_PAID, _("Pending or paid")),
|
||||||
|
("o", _("Pending (overdue)")),
|
||||||
|
(Order.STATUS_EXPIRED, _("Expired")),
|
||||||
|
(Order.STATUS_PENDING + Order.STATUS_EXPIRED, _("Pending or expired")),
|
||||||
|
(Order.STATUS_CANCELED, _("Canceled"))
|
||||||
|
]
|
||||||
|
|
||||||
|
status = forms.ChoiceField(
|
||||||
|
choices=STATUS_VARIANTS,
|
||||||
|
required=False,
|
||||||
|
label=_("Order status"),
|
||||||
|
)
|
||||||
|
item = forms.ChoiceField(
|
||||||
|
choices=[],
|
||||||
|
required=False,
|
||||||
|
label=_("Products"),
|
||||||
|
)
|
||||||
|
subevent = forms.ModelChoiceField(
|
||||||
|
queryset=SubEvent.objects.none(),
|
||||||
|
required=False,
|
||||||
|
empty_label=pgettext_lazy('subevent', 'All dates'),
|
||||||
|
label=pgettext_lazy("subevent", "Date"),
|
||||||
|
)
|
||||||
|
date_range = DateFrameField(
|
||||||
|
required=False,
|
||||||
|
include_future_frames=True,
|
||||||
|
label=_('Event date'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.event = kwargs.pop('event')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.initial['status'] = Order.STATUS_PENDING + Order.STATUS_PAID
|
||||||
|
|
||||||
|
choices = [('', _('All products'))]
|
||||||
|
for i in self.event.items.prefetch_related('variations').all():
|
||||||
|
variations = list(i.variations.all())
|
||||||
|
if variations:
|
||||||
|
choices.append((str(i.pk), _('{product} – Any variation').format(product=str(i))))
|
||||||
|
for v in variations:
|
||||||
|
choices.append(('%d-%d' % (i.pk, v.pk), '%s – %s' % (str(i), v.value)))
|
||||||
|
else:
|
||||||
|
choices.append((str(i.pk), str(i)))
|
||||||
|
self.fields['item'].choices = choices
|
||||||
|
|
||||||
|
if self.event.has_subevents:
|
||||||
|
self.fields["subevent"].queryset = self.event.subevents.all()
|
||||||
|
self.fields['subevent'].widget = Select2(
|
||||||
|
attrs={
|
||||||
|
'data-model-select2': 'event',
|
||||||
|
'data-select2-url': reverse('control:event.subevents.select2', kwargs={
|
||||||
|
'event': self.event.slug,
|
||||||
|
'organizer': self.event.organizer.slug,
|
||||||
|
}),
|
||||||
|
'data-placeholder': pgettext_lazy('subevent', 'All dates')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.fields['subevent'].widget.choices = self.fields['subevent'].choices
|
||||||
|
else:
|
||||||
|
del self.fields['subevent']
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super().clean()
|
||||||
|
subevent = cleaned_data.get('subevent')
|
||||||
|
date_range = cleaned_data.get('date_range')
|
||||||
|
|
||||||
|
if subevent is not None and date_range is not None:
|
||||||
|
d_start, d_end = resolve_timeframe_to_datetime_start_inclusive_end_exclusive(now(), date_range, self.event.timezone)
|
||||||
|
if (
|
||||||
|
(d_start and not (d_start <= subevent.date_from)) or
|
||||||
|
(d_end and not (subevent.date_from < d_end))
|
||||||
|
):
|
||||||
|
self.add_error('subevent', pgettext_lazy('subevent', "Date doesn't start in selected date range."))
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
def filter_qs(self, opqs):
|
||||||
|
fdata = self.cleaned_data
|
||||||
|
|
||||||
|
subevent = fdata.get('subevent', None)
|
||||||
|
date_range = fdata.get('date_range', None)
|
||||||
|
|
||||||
|
if subevent is not None:
|
||||||
|
opqs = opqs.filter(subevent=subevent)
|
||||||
|
|
||||||
|
if date_range is not None:
|
||||||
|
d_start, d_end = resolve_timeframe_to_datetime_start_inclusive_end_exclusive(now(), date_range, self.event.timezone)
|
||||||
|
opqs = opqs.filter(
|
||||||
|
subevent__date_from__gte=d_start,
|
||||||
|
subevent__date_from__lt=d_end
|
||||||
|
)
|
||||||
|
|
||||||
|
s = fdata.get("status", Order.STATUS_PENDING + Order.STATUS_PAID)
|
||||||
|
if s != "":
|
||||||
|
if s == Order.STATUS_PENDING:
|
||||||
|
opqs = opqs.filter(order__status=Order.STATUS_PENDING,
|
||||||
|
order__expires__lt=now().replace(hour=0, minute=0, second=0))
|
||||||
|
elif s == Order.STATUS_PENDING + Order.STATUS_PAID:
|
||||||
|
opqs = opqs.filter(order__status__in=[Order.STATUS_PENDING, Order.STATUS_PAID])
|
||||||
|
elif s == Order.STATUS_PAID + 'v':
|
||||||
|
opqs = opqs.filter(
|
||||||
|
Q(order__status=Order.STATUS_PAID) |
|
||||||
|
Q(order__status=Order.STATUS_PENDING, order__valid_if_pending=True)
|
||||||
|
)
|
||||||
|
elif s == Order.STATUS_PENDING + Order.STATUS_EXPIRED:
|
||||||
|
opqs = opqs.filter(order__status__in=[Order.STATUS_PENDING, Order.STATUS_EXPIRED])
|
||||||
|
else:
|
||||||
|
opqs = opqs.filter(order__status=s)
|
||||||
|
|
||||||
|
if s not in (Order.STATUS_CANCELED, ""):
|
||||||
|
opqs = opqs.filter(canceled=False)
|
||||||
|
if fdata.get("item", "") != "":
|
||||||
|
i = fdata.get("item", "")
|
||||||
|
opqs = opqs.filter(item_id__in=(i,))
|
||||||
|
|
||||||
|
return opqs
|
||||||
|
|
||||||
|
|
||||||
class SubEventFilterForm(FilterForm):
|
class SubEventFilterForm(FilterForm):
|
||||||
orders = {
|
orders = {
|
||||||
'date_from': 'date_from',
|
'date_from': 'date_from',
|
||||||
|
|||||||
@@ -974,7 +974,7 @@ class EventCancelForm(FormPlaceholderMixin, forms.Form):
|
|||||||
self._set_field_placeholders('send_subject', ['event_or_subevent', 'refund_amount', 'position_or_address',
|
self._set_field_placeholders('send_subject', ['event_or_subevent', 'refund_amount', 'position_or_address',
|
||||||
'order', 'event'])
|
'order', 'event'])
|
||||||
self._set_field_placeholders('send_message', ['event_or_subevent', 'refund_amount', 'position_or_address',
|
self._set_field_placeholders('send_message', ['event_or_subevent', 'refund_amount', 'position_or_address',
|
||||||
'order', 'event'])
|
'order', 'event'], rich=True)
|
||||||
self.fields['send_waitinglist_subject'] = I18nFormField(
|
self.fields['send_waitinglist_subject'] = I18nFormField(
|
||||||
label=_("Subject"),
|
label=_("Subject"),
|
||||||
required=True,
|
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_subject', ['event_or_subevent', 'event'])
|
||||||
self._set_field_placeholders('send_waitinglist_message', ['event_or_subevent', 'event'])
|
self._set_field_placeholders('send_waitinglist_message', ['event_or_subevent', 'event'], rich=True)
|
||||||
|
|
||||||
if self.event.has_subevents:
|
if self.event.has_subevents:
|
||||||
self.fields['subevent'].queryset = self.event.subevents.all()
|
self.fields['subevent'].queryset = self.event.subevents.all()
|
||||||
|
|||||||
@@ -1024,6 +1024,13 @@ class OrganizerFooterLinkForm(I18nModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = OrganizerFooterLink
|
model = OrganizerFooterLink
|
||||||
fields = ('label', 'url')
|
fields = ('label', 'url')
|
||||||
|
widgets = {
|
||||||
|
"url": forms.URLInput(
|
||||||
|
attrs={
|
||||||
|
"placeholder": "https://..."
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class BaseOrganizerFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):
|
class BaseOrganizerFooterLinkFormSet(I18nFormSetMixin, forms.BaseInlineFormSet):
|
||||||
|
|||||||
@@ -126,7 +126,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="navbar-brand" href="{% url "control:index" %}">
|
<a class="navbar-brand" href="{% url "control:index" %}">
|
||||||
<img src="{% static "pretixbase/img/pretix-icon-white-mini.svg" %}" />
|
<img src="{% static "pretixbase/img/pretix-icon-white-mini.svg" %}" />
|
||||||
{{ settings.PRETIX_INSTANCE_NAME }}
|
<span>
|
||||||
|
{{ settings.PRETIX_INSTANCE_NAME }}
|
||||||
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ul class="nav navbar-nav navbar-top-links navbar-left flip hidden-xs">
|
<ul class="nav navbar-nav navbar-top-links navbar-left flip hidden-xs">
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
{% bootstrap_field form.invoice_name_required layout="control" %}
|
{% bootstrap_field form.invoice_name_required layout="control" %}
|
||||||
{% bootstrap_field form.invoice_address_company_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 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_beneficiary layout="control" %}
|
||||||
{% bootstrap_field form.invoice_address_not_asked_free layout="control" %}
|
{% bootstrap_field form.invoice_address_not_asked_free layout="control" %}
|
||||||
{% bootstrap_field form.invoice_address_custom_field layout="control" %}
|
{% bootstrap_field form.invoice_address_custom_field layout="control" %}
|
||||||
|
|||||||
@@ -20,35 +20,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<form class="panel-body filter-form" action="" method="get">
|
<form class="panel-body filter-form" action="" method="get">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-2 col-sm-6 col-xs-6">
|
<div class="col-md-2 col-xs-6">
|
||||||
<select name="status" class="form-control">
|
{% bootstrap_field form.status %}
|
||||||
<option value="" {% if request.GET.status == "" %}selected="selected"{% endif %}>{% trans "All orders" %}</option>
|
</div>
|
||||||
<option value="p" {% if request.GET.status == "p" %}selected="selected"{% endif %}>{% trans "Paid" %}</option>
|
<div class="col-md-3 col-xs-6">
|
||||||
<option value="pv" {% if request.GET.status == "pv" %}selected="selected"{% endif %}>{% trans "Paid or confirmed" %}</option>
|
{% bootstrap_field form.item %}
|
||||||
<option value="n" {% if request.GET.status == "n" %}selected="selected"{% endif %}>{% trans "Pending" %}</option>
|
</div>
|
||||||
<option value="np" {% if request.GET.status == "np" or "status" not in request.GET %}selected="selected"{% endif %}>{% trans "Pending or paid" %}</option>
|
{% if has_subevents %}
|
||||||
<option value="o" {% if request.GET.status == "o" %}selected="selected"{% endif %}>{% trans "Pending (overdue)" %}</option>
|
<div class="col-md-3 col-xs-6">
|
||||||
<option value="e" {% if request.GET.status == "e" %}selected="selected"{% endif %}>{% trans "Expired" %}</option>
|
{% bootstrap_field form.subevent %}
|
||||||
<option value="ne" {% if request.GET.status == "ne" %}selected="selected"{% endif %}>{% trans "Pending or expired" %}</option>
|
|
||||||
<option value="c" {% if request.GET.status == "c" %}selected="selected"{% endif %}>{% trans "Canceled" %}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-5 col-sm-6 col-xs-6">
|
<div class="col-md-4 col-xs-6">
|
||||||
<select name="item" class="form-control">
|
{% bootstrap_field form.date_range %}
|
||||||
<option value="">{% trans "All products" %}</option>
|
|
||||||
{% for item in items %}
|
|
||||||
<option value="{{ item.id }}"
|
|
||||||
{% if request.GET.item|add:0 == item.id %}selected="selected"{% endif %}>
|
|
||||||
{{ item.name }}
|
|
||||||
</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
{% if request.event.has_subevents %}
|
{% endif %}
|
||||||
<div class="col-lg-5 col-sm-6 col-xs-6">
|
|
||||||
{% include "pretixcontrol/event/fragment_subevent_choice_simple.html" %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<button class="btn btn-primary btn-lg" type="submit">
|
<button class="btn btn-primary btn-lg" type="submit">
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
{% if v.budget|default_if_none:"NONE" != "NONE" %}
|
{% if v.budget|default_if_none:"NONE" != "NONE" %}
|
||||||
<br>
|
<br>
|
||||||
<small class="text-muted">
|
<small class="text-muted">
|
||||||
{{ v.budget_used_orders|money:request.event.currency }} / {{ v.budget|money:request.event.currency }}
|
{{ v.budget_used|money:request.event.currency }} / {{ v.budget|money:request.event.currency }}
|
||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ from pretix.base.models import (
|
|||||||
)
|
)
|
||||||
from pretix.base.services.quotas import QuotaAvailability
|
from pretix.base.services.quotas import QuotaAvailability
|
||||||
from pretix.base.timeline import timeline_for_event
|
from pretix.base.timeline import timeline_for_event
|
||||||
from pretix.control.forms.event import CommentForm
|
|
||||||
from pretix.control.signals import (
|
from pretix.control.signals import (
|
||||||
event_dashboard_widgets, user_dashboard_widgets,
|
event_dashboard_widgets, user_dashboard_widgets,
|
||||||
)
|
)
|
||||||
@@ -341,6 +340,8 @@ def welcome_wizard_widget(sender, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def event_index(request, organizer, event):
|
def event_index(request, organizer, event):
|
||||||
|
from pretix.control.forms.event import CommentForm
|
||||||
|
|
||||||
subevent = None
|
subevent = None
|
||||||
if request.GET.get("subevent", "") != "" and request.event.has_subevents:
|
if request.GET.get("subevent", "") != "" and request.event.has_subevents:
|
||||||
i = request.GET.get("subevent", "")
|
i = request.GET.get("subevent", "")
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ from pretix.control.views.mailsetup import MailSettingsSetupView
|
|||||||
from pretix.control.views.user import RecentAuthenticationRequiredMixin
|
from pretix.control.views.user import RecentAuthenticationRequiredMixin
|
||||||
from pretix.helpers.database import rolledback_transaction
|
from pretix.helpers.database import rolledback_transaction
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri, get_event_domain
|
from pretix.multidomain.urlreverse import build_absolute_uri, get_event_domain
|
||||||
from pretix.plugins.stripe.payment import StripeSettingsHolder
|
|
||||||
from pretix.presale.views.widget import (
|
from pretix.presale.views.widget import (
|
||||||
version_default as widget_version_default,
|
version_default as widget_version_default,
|
||||||
)
|
)
|
||||||
@@ -1666,6 +1665,8 @@ class QuickSetupView(FormView):
|
|||||||
'or take your event live to start selling!'))
|
'or take your event live to start selling!'))
|
||||||
|
|
||||||
if form.cleaned_data.get('payment_stripe__enabled', False):
|
if form.cleaned_data.get('payment_stripe__enabled', False):
|
||||||
|
from pretix.plugins.stripe.payment import StripeSettingsHolder
|
||||||
|
|
||||||
self.request.session['payment_stripe_oauth_enable'] = True
|
self.request.session['payment_stripe_oauth_enable'] = True
|
||||||
return redirect(StripeSettingsHolder(self.request.event).get_connect_url(self.request))
|
return redirect(StripeSettingsHolder(self.request.event).get_connect_url(self.request))
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ from pretix.api.serializers.item import (
|
|||||||
)
|
)
|
||||||
from pretix.base.forms import I18nFormSet
|
from pretix.base.forms import I18nFormSet
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
CartPosition, Item, ItemCategory, ItemProgramTime, ItemVariation, Order,
|
CartPosition, Item, ItemCategory, ItemProgramTime, ItemVariation,
|
||||||
OrderPosition, Question, QuestionAnswer, QuestionOption, Quota,
|
OrderPosition, Question, QuestionAnswer, QuestionOption, Quota,
|
||||||
SeatCategoryMapping, Voucher,
|
SeatCategoryMapping, Voucher,
|
||||||
)
|
)
|
||||||
@@ -74,6 +74,7 @@ from pretix.base.models.items import ItemAddOn, ItemBundle, ItemMetaValue
|
|||||||
from pretix.base.services.quotas import QuotaAvailability
|
from pretix.base.services.quotas import QuotaAvailability
|
||||||
from pretix.base.services.tickets import invalidate_cache
|
from pretix.base.services.tickets import invalidate_cache
|
||||||
from pretix.base.signals import quota_availability
|
from pretix.base.signals import quota_availability
|
||||||
|
from pretix.control.forms.filter import QuestionAnswerFilterForm
|
||||||
from pretix.control.forms.item import (
|
from pretix.control.forms.item import (
|
||||||
CategoryForm, ItemAddOnForm, ItemAddOnsFormSet, ItemBundleForm,
|
CategoryForm, ItemAddOnForm, ItemAddOnsFormSet, ItemBundleForm,
|
||||||
ItemBundleFormSet, ItemCreateForm, ItemMetaValueForm, ItemProgramTimeForm,
|
ItemBundleFormSet, ItemCreateForm, ItemMetaValueForm, ItemProgramTimeForm,
|
||||||
@@ -660,46 +661,26 @@ class QuestionMixin:
|
|||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
class QuestionView(EventPermissionRequiredMixin, QuestionMixin, ChartContainingView, DetailView):
|
class QuestionView(EventPermissionRequiredMixin, ChartContainingView, DetailView):
|
||||||
model = Question
|
model = Question
|
||||||
template_name = 'pretixcontrol/items/question.html'
|
template_name = 'pretixcontrol/items/question.html'
|
||||||
permission = 'can_change_items'
|
permission = 'can_change_items'
|
||||||
template_name_field = 'question'
|
template_name_field = 'question'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def filter_form(self):
|
||||||
|
return QuestionAnswerFilterForm(event=self.request.event, data=self.request.GET)
|
||||||
|
|
||||||
def get_answer_statistics(self):
|
def get_answer_statistics(self):
|
||||||
opqs = OrderPosition.objects.filter(
|
opqs = OrderPosition.objects.filter(
|
||||||
order__event=self.request.event,
|
order__event=self.request.event,
|
||||||
)
|
)
|
||||||
|
if self.filter_form.is_valid():
|
||||||
|
opqs = self.filter_form.filter_qs(opqs)
|
||||||
|
|
||||||
qs = QuestionAnswer.objects.filter(
|
qs = QuestionAnswer.objects.filter(
|
||||||
question=self.object, orderposition__isnull=False,
|
question=self.object, orderposition__isnull=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.request.GET.get("subevent", "") != "":
|
|
||||||
opqs = opqs.filter(subevent=self.request.GET["subevent"])
|
|
||||||
|
|
||||||
s = self.request.GET.get("status", "np")
|
|
||||||
if s != "":
|
|
||||||
if s == 'o':
|
|
||||||
opqs = opqs.filter(order__status=Order.STATUS_PENDING,
|
|
||||||
order__expires__lt=now().replace(hour=0, minute=0, second=0))
|
|
||||||
elif s == 'np':
|
|
||||||
opqs = opqs.filter(order__status__in=[Order.STATUS_PENDING, Order.STATUS_PAID])
|
|
||||||
elif s == 'pv':
|
|
||||||
opqs = opqs.filter(
|
|
||||||
Q(order__status=Order.STATUS_PAID) |
|
|
||||||
Q(order__status=Order.STATUS_PENDING, order__valid_if_pending=True)
|
|
||||||
)
|
|
||||||
elif s == 'ne':
|
|
||||||
opqs = opqs.filter(order__status__in=[Order.STATUS_PENDING, Order.STATUS_EXPIRED])
|
|
||||||
else:
|
|
||||||
opqs = opqs.filter(order__status=s)
|
|
||||||
|
|
||||||
if s not in (Order.STATUS_CANCELED, ""):
|
|
||||||
opqs = opqs.filter(canceled=False)
|
|
||||||
if self.request.GET.get("item", "") != "":
|
|
||||||
i = self.request.GET.get("item", "")
|
|
||||||
opqs = opqs.filter(item_id__in=(i,))
|
|
||||||
|
|
||||||
qs = qs.filter(orderposition__in=opqs)
|
qs = qs.filter(orderposition__in=opqs)
|
||||||
op_cnt = opqs.filter(item__in=self.object.items.all()).count()
|
op_cnt = opqs.filter(item__in=self.object.items.all()).count()
|
||||||
|
|
||||||
@@ -746,9 +727,11 @@ class QuestionView(EventPermissionRequiredMixin, QuestionMixin, ChartContainingV
|
|||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
ctx = super().get_context_data()
|
ctx = super().get_context_data()
|
||||||
ctx['items'] = self.object.items.all()
|
ctx['items'] = self.object.items.exists()
|
||||||
|
ctx['has_subevents'] = self.request.event.has_subevents
|
||||||
stats = self.get_answer_statistics()
|
stats = self.get_answer_statistics()
|
||||||
ctx['stats'], ctx['total'] = stats
|
ctx['stats'], ctx['total'] = stats
|
||||||
|
ctx['form'] = self.filter_form
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
def get_object(self, queryset=None) -> Question:
|
def get_object(self, queryset=None) -> Question:
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class BaseProcessView(AsyncAction, FormView):
|
|||||||
else:
|
else:
|
||||||
charset = None
|
charset = None
|
||||||
try:
|
try:
|
||||||
return parse_csv(self.file.file, 1024 * 1024, charset=charset)
|
reader = parse_csv(self.file.file, 1024 * 1024, charset=charset)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
messages.warning(
|
messages.warning(
|
||||||
self.request,
|
self.request,
|
||||||
@@ -155,7 +155,16 @@ class BaseProcessView(AsyncAction, FormView):
|
|||||||
"Some characters were replaced with a placeholder."
|
"Some characters were replaced with a placeholder."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return parse_csv(self.file.file, 1024 * 1024, "replace", charset=charset)
|
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
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def parsed_list(self):
|
def parsed_list(self):
|
||||||
|
|||||||
@@ -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
|
@scopes_disabled() # we have an event check here, and we can save some performance on subqueries
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = Voucher.annotate_budget_used_orders(self.request.event.vouchers.exclude(
|
qs = Voucher.annotate_budget_used(self.request.event.vouchers.exclude(
|
||||||
Exists(WaitingListEntry.objects.filter(voucher_id=OuterRef('pk')))
|
Exists(WaitingListEntry.objects.filter(voucher_id=OuterRef('pk')))
|
||||||
).select_related(
|
).select_related(
|
||||||
'item', 'variation', 'seat'
|
'item', 'variation', 'seat'
|
||||||
|
|||||||
62
src/pretix/helpers/celery.py
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#
|
||||||
|
# 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.conf import settings
|
||||||
|
|
||||||
|
THRESHOLD_DOWNGRADE_TO_MID = 50
|
||||||
|
THRESHOLD_DOWNGRADE_TO_LOW = 250
|
||||||
|
|
||||||
|
|
||||||
|
def get_task_priority(shard, organizer_id):
|
||||||
|
"""
|
||||||
|
This is an attempt to build a simple "fair-use" policy for webhooks and notifications. The problem is that when
|
||||||
|
one organizer creates e.g. 20,000 orders through the API, that might schedule 20,000 webhooks and every other
|
||||||
|
organizer will need to wait for these webhooks to go through.
|
||||||
|
|
||||||
|
We try to fix that by building three queues: high-prio, mid-prio, and low-prio. Every organizer starts in the
|
||||||
|
high-prio queue, and all their tasks are routed immediately. Once an organizer submits more than X jobs of a
|
||||||
|
certain type per minute, they get downgraded to the mid-prio queue, and then – if they submit even more – to the
|
||||||
|
low-prio queue. That way, if another organizer has "regular usage", they are prioritized over the organizer with
|
||||||
|
high load.
|
||||||
|
"""
|
||||||
|
from django_redis import get_redis_connection
|
||||||
|
|
||||||
|
if not settings.HAS_REDIS:
|
||||||
|
return settings.PRIORITY_CELERY_HIGH
|
||||||
|
|
||||||
|
# We use redis directly instead of the Django cache API since the Django cache API does not support INCR for
|
||||||
|
# nonexistant keys
|
||||||
|
rc = get_redis_connection("redis")
|
||||||
|
|
||||||
|
cache_key = f"pretix:task_priority:{shard}:{organizer_id}"
|
||||||
|
|
||||||
|
# Make sure counters expire after a while when not used
|
||||||
|
p = rc.pipeline()
|
||||||
|
p.incr(cache_key)
|
||||||
|
p.expire(cache_key, 60)
|
||||||
|
new_counter = p.execute()[0]
|
||||||
|
|
||||||
|
if new_counter >= THRESHOLD_DOWNGRADE_TO_LOW:
|
||||||
|
return settings.PRIORITY_CELERY_LOW
|
||||||
|
elif new_counter >= THRESHOLD_DOWNGRADE_TO_MID:
|
||||||
|
return settings.PRIORITY_CELERY_MID
|
||||||
|
else:
|
||||||
|
return settings.PRIORITY_CELERY_HIGH
|
||||||
210
src/pretix/helpers/payment.py
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
#
|
||||||
|
# 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,
|
||||||
|
}
|
||||||
@@ -8,16 +8,16 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
|
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
|
||||||
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
"PO-Revision-Date: 2025-12-03 23:00+0000\n"
|
||||||
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
"Last-Translator: sandra r <sandrarial@gestiontickets.online>\n"
|
||||||
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/"
|
||||||
"js/gl/>\n"
|
"pretix-js/gl/>\n"
|
||||||
"Language: gl\n"
|
"Language: gl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 4.8\n"
|
"X-Generator: Weblate 5.14.3\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: 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:62
|
||||||
@@ -31,106 +31,104 @@ msgstr "Comentario:"
|
|||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:34
|
||||||
msgid "PayPal"
|
msgid "PayPal"
|
||||||
msgstr ""
|
msgstr "PayPal"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:35
|
||||||
msgid "Venmo"
|
msgid "Venmo"
|
||||||
msgstr ""
|
msgstr "Venmo"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:36
|
||||||
#: pretix/static/pretixpresale/js/walletdetection.js:38
|
#: pretix/static/pretixpresale/js/walletdetection.js:38
|
||||||
msgid "Apple Pay"
|
msgid "Apple Pay"
|
||||||
msgstr ""
|
msgstr "Apple Pay"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:37
|
||||||
msgid "Itaú"
|
msgid "Itaú"
|
||||||
msgstr ""
|
msgstr "Itaú"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:38
|
||||||
msgid "PayPal Credit"
|
msgid "PayPal Credit"
|
||||||
msgstr ""
|
msgstr "Crédito PayPal"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:39
|
||||||
msgid "Credit Card"
|
msgid "Credit Card"
|
||||||
msgstr ""
|
msgstr "Tarxeta de crédito"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:40
|
||||||
msgid "PayPal Pay Later"
|
msgid "PayPal Pay Later"
|
||||||
msgstr ""
|
msgstr "PayPal Pagar Máis Tarde"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:41
|
||||||
msgid "iDEAL"
|
msgid "iDEAL"
|
||||||
msgstr ""
|
msgstr "iDEAL"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:42
|
||||||
msgid "SEPA Direct Debit"
|
msgid "SEPA Direct Debit"
|
||||||
msgstr ""
|
msgstr "Débito directo SEPA"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:43
|
||||||
msgid "Bancontact"
|
msgid "Bancontact"
|
||||||
msgstr ""
|
msgstr "Bancontact"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:44
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:44
|
||||||
msgid "giropay"
|
msgid "giropay"
|
||||||
msgstr ""
|
msgstr "giropay"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:45
|
||||||
msgid "SOFORT"
|
msgid "SOFORT"
|
||||||
msgstr ""
|
msgstr "SOFORT"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:46
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Yes"
|
|
||||||
msgid "eps"
|
msgid "eps"
|
||||||
msgstr "Si"
|
msgstr "Si"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:47
|
||||||
msgid "MyBank"
|
msgid "MyBank"
|
||||||
msgstr ""
|
msgstr "MyBank"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:48
|
||||||
msgid "Przelewy24"
|
msgid "Przelewy24"
|
||||||
msgstr ""
|
msgstr "Przelewy24"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:49
|
||||||
msgid "Verkkopankki"
|
msgid "Verkkopankki"
|
||||||
msgstr ""
|
msgstr "Verkkopankki"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:50
|
||||||
msgid "PayU"
|
msgid "PayU"
|
||||||
msgstr ""
|
msgstr "PayU"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:51
|
||||||
msgid "BLIK"
|
msgid "BLIK"
|
||||||
msgstr ""
|
msgstr "BLIK"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:52
|
||||||
msgid "Trustly"
|
msgid "Trustly"
|
||||||
msgstr ""
|
msgstr "De confianza"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:53
|
||||||
msgid "Zimpler"
|
msgid "Zimpler"
|
||||||
msgstr ""
|
msgstr "Zimpler"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:54
|
||||||
msgid "Maxima"
|
msgid "Maxima"
|
||||||
msgstr ""
|
msgstr "Máxima"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:55
|
||||||
msgid "OXXO"
|
msgid "OXXO"
|
||||||
msgstr ""
|
msgstr "OXXO"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:56
|
||||||
msgid "Boleto"
|
msgid "Boleto"
|
||||||
msgstr ""
|
msgstr "Ticket"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:57
|
||||||
msgid "WeChat Pay"
|
msgid "WeChat Pay"
|
||||||
msgstr ""
|
msgstr "Pagar con WeChat"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:58
|
||||||
msgid "Mercado Pago"
|
msgid "Mercado Pago"
|
||||||
msgstr ""
|
msgstr "Mercado Pago"
|
||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:167
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:167
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:50
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:50
|
||||||
@@ -149,7 +147,7 @@ msgstr "Confirmando o pagamento…"
|
|||||||
|
|
||||||
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
|
#: pretix/plugins/paypal2/static/pretixplugins/paypal2/pretix-paypal.js:254
|
||||||
msgid "Payment method unavailable"
|
msgid "Payment method unavailable"
|
||||||
msgstr ""
|
msgstr "O método de pago non está dispoñible"
|
||||||
|
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:15
|
||||||
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
#: pretix/plugins/statistics/static/pretixplugins/statistics/statistics.js:39
|
||||||
@@ -240,11 +238,11 @@ msgstr "Cancelado"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:46
|
||||||
msgid "Confirmed"
|
msgid "Confirmed"
|
||||||
msgstr ""
|
msgstr "Confirmado"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:47
|
||||||
msgid "Approval pending"
|
msgid "Approval pending"
|
||||||
msgstr ""
|
msgstr "Aprobación pendente"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:48
|
||||||
msgid "Redeemed"
|
msgid "Redeemed"
|
||||||
@@ -300,16 +298,12 @@ msgid "Ticket code revoked/changed"
|
|||||||
msgstr "Código de tícket revogado/cambiado"
|
msgstr "Código de tícket revogado/cambiado"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:63
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Ticket not paid"
|
|
||||||
msgid "Ticket blocked"
|
msgid "Ticket blocked"
|
||||||
msgstr "Tícket pendente de pago"
|
msgstr "Ticket bloqueado"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:64
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Ticket not paid"
|
|
||||||
msgid "Ticket not valid at this time"
|
msgid "Ticket not valid at this time"
|
||||||
msgstr "Tícket pendente de pago"
|
msgstr "O ticket non é válido neste momento"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:65
|
||||||
msgid "Order canceled"
|
msgid "Order canceled"
|
||||||
@@ -317,11 +311,11 @@ msgstr "Pedido cancelado"
|
|||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:66
|
||||||
msgid "Ticket code is ambiguous on list"
|
msgid "Ticket code is ambiguous on list"
|
||||||
msgstr ""
|
msgstr "O código do ticket é ambiguo na lista"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:67
|
||||||
msgid "Order not approved"
|
msgid "Order not approved"
|
||||||
msgstr ""
|
msgstr "Orde non aprobada"
|
||||||
|
|
||||||
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:68
|
#: pretix/plugins/webcheckin/static/pretixplugins/webcheckin/main.js:68
|
||||||
msgid "Checked-in Tickets"
|
msgid "Checked-in Tickets"
|
||||||
@@ -422,7 +416,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/static/pretixbase/js/asynctask.js:276
|
#: pretix/static/pretixbase/js/asynctask.js:276
|
||||||
msgid "If this takes longer than a few minutes, please contact us."
|
msgid "If this takes longer than a few minutes, please contact us."
|
||||||
msgstr ""
|
msgstr "Se isto leva máis duns minutos, póñase en contacto connosco."
|
||||||
|
|
||||||
#: pretix/static/pretixbase/js/asynctask.js:331
|
#: pretix/static/pretixbase/js/asynctask.js:331
|
||||||
msgid "Close message"
|
msgid "Close message"
|
||||||
@@ -452,7 +446,7 @@ msgstr "está despois"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:40
|
||||||
msgid "="
|
msgid "="
|
||||||
msgstr ""
|
msgstr "="
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:99
|
||||||
msgid "Product"
|
msgid "Product"
|
||||||
@@ -464,7 +458,7 @@ msgstr "Ver variacións do produto"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:107
|
||||||
msgid "Gate"
|
msgid "Gate"
|
||||||
msgstr ""
|
msgstr "Porta"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:111
|
||||||
msgid "Current date and time"
|
msgid "Current date and time"
|
||||||
@@ -472,11 +466,11 @@ msgstr "Data e hora actual"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:115
|
||||||
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
msgid "Current day of the week (1 = Monday, 7 = Sunday)"
|
||||||
msgstr ""
|
msgstr "Día actual da semana (1 = luns, 7 = domingo)"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:119
|
||||||
msgid "Current entry status"
|
msgid "Current entry status"
|
||||||
msgstr ""
|
msgstr "Estado de entrada actual"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:123
|
||||||
msgid "Number of previous entries"
|
msgid "Number of previous entries"
|
||||||
@@ -487,40 +481,32 @@ msgid "Number of previous entries since midnight"
|
|||||||
msgstr "Número de entradas previas desde a medianoite"
|
msgstr "Número de entradas previas desde a medianoite"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:131
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of previous entries"
|
|
||||||
msgid "Number of previous entries since"
|
msgid "Number of previous entries since"
|
||||||
msgstr "Número de entradas previas"
|
msgstr "Número de entradas anteriores desde"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:135
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Number of previous entries"
|
|
||||||
msgid "Number of previous entries before"
|
msgid "Number of previous entries before"
|
||||||
msgstr "Número de entradas previas"
|
msgstr "Número de entradas anteriores antes de"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:139
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:139
|
||||||
msgid "Number of days with a previous entry"
|
msgid "Number of days with a previous entry"
|
||||||
msgstr "Número de días cunha entrada previa"
|
msgstr "Número de días cunha entrada previa"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:143
|
#: 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"
|
msgid "Number of days with a previous entry since"
|
||||||
msgstr "Número de días cunha entrada previa"
|
msgstr "Número de días cunha entrada previa desde"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:147
|
#: 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"
|
msgid "Number of days with a previous entry before"
|
||||||
msgstr "Número de días cunha entrada previa"
|
msgstr "Número de días cunha entrada previa"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:151
|
||||||
msgid "Minutes since last entry (-1 on first entry)"
|
msgid "Minutes since last entry (-1 on first entry)"
|
||||||
msgstr ""
|
msgstr "Minutos desde a última entrada (-1 na primeira entrada)"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:155
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:155
|
||||||
msgid "Minutes since first entry (-1 on first entry)"
|
msgid "Minutes since first entry (-1 on first entry)"
|
||||||
msgstr ""
|
msgstr "Minutos desde a primeira entrada (-1 na primeira entrada)"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:182
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:182
|
||||||
msgid "All of the conditions below (AND)"
|
msgid "All of the conditions below (AND)"
|
||||||
@@ -564,25 +550,25 @@ msgstr "minutos"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:192
|
||||||
msgid "Duplicate"
|
msgid "Duplicate"
|
||||||
msgstr ""
|
msgstr "Duplicar"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:193
|
||||||
msgctxt "entry_status"
|
msgctxt "entry_status"
|
||||||
msgid "present"
|
msgid "present"
|
||||||
msgstr ""
|
msgstr "presente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:194
|
||||||
msgctxt "entry_status"
|
msgctxt "entry_status"
|
||||||
msgid "absent"
|
msgid "absent"
|
||||||
msgstr ""
|
msgstr "ausente"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
|
||||||
msgid "Error: Product not found!"
|
msgid "Error: Product not found!"
|
||||||
msgstr ""
|
msgstr "Erro: Non se atopou o produto!"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
|
||||||
msgid "Error: Variation not found!"
|
msgid "Error: Variation not found!"
|
||||||
msgstr ""
|
msgstr "Erro: Variación non atopada!"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||||
msgid "Check-in QR"
|
msgid "Check-in QR"
|
||||||
@@ -597,16 +583,12 @@ msgid "Group of objects"
|
|||||||
msgstr "Grupo de obxectos"
|
msgstr "Grupo de obxectos"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
#: pretix/static/pretixcontrol/js/ui/editor.js:909
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Text object"
|
|
||||||
msgid "Text object (deprecated)"
|
msgid "Text object (deprecated)"
|
||||||
msgstr "Obxecto de texto"
|
msgstr "Obxecto de texto (obsoleto)"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
#: pretix/static/pretixcontrol/js/ui/editor.js:911
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Text object"
|
|
||||||
msgid "Text box"
|
msgid "Text box"
|
||||||
msgstr "Obxecto de texto"
|
msgstr "Caixa de texto"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||||
msgid "Barcode area"
|
msgid "Barcode area"
|
||||||
@@ -655,26 +637,26 @@ msgid "Unknown error."
|
|||||||
msgstr "Erro descoñecido."
|
msgstr "Erro descoñecido."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:309
|
#: 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."
|
msgid "Your color has great contrast and will provide excellent accessibility."
|
||||||
msgstr "A túa cor ten moito contraste e é moi doada de ler!"
|
msgstr ""
|
||||||
|
"A túa cor ten un gran contraste e proporcionará unha excelente "
|
||||||
|
"accesibilidade."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
#: pretix/static/pretixcontrol/js/ui/main.js:313
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Your color has decent contrast and is probably good-enough to read!"
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your color has decent contrast and is sufficient for minimum accessibility "
|
"Your color has decent contrast and is sufficient for minimum accessibility "
|
||||||
"requirements."
|
"requirements."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"A túa cor ten un contraste axeitado e probablemente sexa suficientemente "
|
"A túa cor ten un contraste decente e é suficiente para os requisitos mínimos "
|
||||||
"lexible!"
|
"de accesibilidade."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
#: pretix/static/pretixcontrol/js/ui/main.js:317
|
||||||
msgid ""
|
msgid ""
|
||||||
"Your color has insufficient contrast to white. Accessibility of your site "
|
"Your color has insufficient contrast to white. Accessibility of your site "
|
||||||
"will be impacted."
|
"will be impacted."
|
||||||
msgstr ""
|
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:443
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:463
|
#: pretix/static/pretixcontrol/js/ui/main.js:463
|
||||||
@@ -695,11 +677,11 @@ msgstr "Soamente seleccionados"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:839
|
#: pretix/static/pretixcontrol/js/ui/main.js:839
|
||||||
msgid "Enter page number between 1 and %(max)s."
|
msgid "Enter page number between 1 and %(max)s."
|
||||||
msgstr ""
|
msgstr "Introduza o número de páxina entre 1 e %(max)s."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:842
|
#: pretix/static/pretixcontrol/js/ui/main.js:842
|
||||||
msgid "Invalid page number."
|
msgid "Invalid page number."
|
||||||
msgstr ""
|
msgstr "Número de páxina non válido."
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/main.js:1000
|
#: pretix/static/pretixcontrol/js/ui/main.js:1000
|
||||||
msgid "Use a different name internally"
|
msgid "Use a different name internally"
|
||||||
@@ -718,10 +700,8 @@ msgid "Calculating default price…"
|
|||||||
msgstr "Calculando o prezo por defecto…"
|
msgstr "Calculando o prezo por defecto…"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
|
#: pretix/static/pretixcontrol/js/ui/plugins.js:69
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Search results"
|
|
||||||
msgid "No results"
|
msgid "No results"
|
||||||
msgstr "Resultados da procura"
|
msgstr "Sen resultados"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/question.js:41
|
#: pretix/static/pretixcontrol/js/ui/question.js:41
|
||||||
msgid "Others"
|
msgid "Others"
|
||||||
@@ -752,7 +732,7 @@ msgstr "O carro da compra caducou"
|
|||||||
#: pretix/static/pretixpresale/js/ui/cart.js:58
|
#: pretix/static/pretixpresale/js/ui/cart.js:58
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:84
|
#: pretix/static/pretixpresale/js/ui/cart.js:84
|
||||||
msgid "Your cart is about to expire."
|
msgid "Your cart is about to expire."
|
||||||
msgstr ""
|
msgstr "O teu carriño está a piques de caducar."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:62
|
#: pretix/static/pretixpresale/js/ui/cart.js:62
|
||||||
msgid "The items in your cart are reserved for you for one minute."
|
msgid "The items in your cart are reserved for you for one minute."
|
||||||
@@ -762,16 +742,10 @@ msgstr[1] ""
|
|||||||
"Os artigos da túa cesta están reservados para ti durante {num} minutos."
|
"Os artigos da túa cesta están reservados para ti durante {num} minutos."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:83
|
#: pretix/static/pretixpresale/js/ui/cart.js:83
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Cart expired"
|
|
||||||
msgid "Your cart has 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
|
#: 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 they’re available."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The items in your cart are no longer reserved for you. You can still "
|
"The items in your cart are no longer reserved for you. You can still "
|
||||||
"complete your order as long as they're available."
|
"complete your order as long as they're available."
|
||||||
@@ -781,11 +755,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:87
|
#: pretix/static/pretixpresale/js/ui/cart.js:87
|
||||||
msgid "Do you want to renew the reservation period?"
|
msgid "Do you want to renew the reservation period?"
|
||||||
msgstr ""
|
msgstr "Queres renovar o período de reserva?"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:90
|
#: pretix/static/pretixpresale/js/ui/cart.js:90
|
||||||
msgid "Renew reservation"
|
msgid "Renew reservation"
|
||||||
msgstr ""
|
msgstr "Renovar reserva"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:194
|
#: pretix/static/pretixpresale/js/ui/main.js:194
|
||||||
msgid "The organizer keeps %(currency)s %(amount)s"
|
msgid "The organizer keeps %(currency)s %(amount)s"
|
||||||
@@ -805,71 +779,66 @@ msgstr "A súa hora local:"
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/walletdetection.js:39
|
#: pretix/static/pretixpresale/js/walletdetection.js:39
|
||||||
msgid "Google Pay"
|
msgid "Google Pay"
|
||||||
msgstr ""
|
msgstr "Google Pay"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:16
|
#: pretix/static/pretixpresale/js/widget/widget.js:16
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Quantity"
|
msgid "Quantity"
|
||||||
msgstr ""
|
msgstr "Cantidade"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:17
|
#: pretix/static/pretixpresale/js/widget/widget.js:17
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Decrease quantity"
|
msgid "Decrease quantity"
|
||||||
msgstr ""
|
msgstr "Diminuír a cantidade"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:18
|
#: pretix/static/pretixpresale/js/widget/widget.js:18
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Increase quantity"
|
msgid "Increase quantity"
|
||||||
msgstr ""
|
msgstr "Aumentar a cantidade"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:19
|
#: pretix/static/pretixpresale/js/widget/widget.js:19
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Filter events by"
|
msgid "Filter events by"
|
||||||
msgstr ""
|
msgstr "Filtrar eventos por"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:20
|
#: pretix/static/pretixpresale/js/widget/widget.js:20
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Filter"
|
msgid "Filter"
|
||||||
msgstr ""
|
msgstr "Filtro"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:21
|
#: pretix/static/pretixpresale/js/widget/widget.js:21
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Price"
|
msgid "Price"
|
||||||
msgstr ""
|
msgstr "Prezo"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:22
|
#: pretix/static/pretixpresale/js/widget/widget.js:22
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Original price: %s"
|
msgid "Original price: %s"
|
||||||
msgstr ""
|
msgstr "Prezo orixinal: %s"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:23
|
#: pretix/static/pretixpresale/js/widget/widget.js:23
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "New price: %s"
|
msgid "New price: %s"
|
||||||
msgstr ""
|
msgstr "Novo prezo: %s"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:24
|
#: pretix/static/pretixpresale/js/widget/widget.js:24
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Selected only"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Soamente seleccionados"
|
msgstr "Seleccione"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:25
|
#: pretix/static/pretixpresale/js/widget/widget.js:25
|
||||||
#, fuzzy, javascript-format
|
#, javascript-format
|
||||||
#| msgid "Selected only"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Select %s"
|
msgid "Select %s"
|
||||||
msgstr "Soamente seleccionados"
|
msgstr "Seleccione %s"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:26
|
#: pretix/static/pretixpresale/js/widget/widget.js:26
|
||||||
#, fuzzy, javascript-format
|
#, javascript-format
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "See variations"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Select variant %s"
|
msgid "Select variant %s"
|
||||||
msgstr "Ver variacións"
|
msgstr "Seleccione a variante %s"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:27
|
#: pretix/static/pretixpresale/js/widget/widget.js:27
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
@@ -905,7 +874,7 @@ msgstr "dende %(currency)s %(price)s"
|
|||||||
#, javascript-format
|
#, javascript-format
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Image of %s"
|
msgid "Image of %s"
|
||||||
msgstr ""
|
msgstr "Imaxe de %s"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:34
|
#: pretix/static/pretixpresale/js/widget/widget.js:34
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
@@ -940,25 +909,19 @@ msgstr "Só dispoñible mediante vale"
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:40
|
#: pretix/static/pretixpresale/js/widget/widget.js:40
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:43
|
#: pretix/static/pretixpresale/js/widget/widget.js:43
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "currently available: %s"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Not yet available"
|
msgid "Not yet available"
|
||||||
msgstr "dispoñible actualmente: %s"
|
msgstr "Aínda non dispoñible"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:41
|
#: pretix/static/pretixpresale/js/widget/widget.js:41
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Not available anymore"
|
msgid "Not available anymore"
|
||||||
msgstr ""
|
msgstr "Xa non está dispoñible"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:42
|
#: pretix/static/pretixpresale/js/widget/widget.js:42
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "currently available: %s"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Currently not available"
|
msgid "Currently not available"
|
||||||
msgstr "dispoñible actualmente: %s"
|
msgstr "Non dispoñible actualmente"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:44
|
#: pretix/static/pretixpresale/js/widget/widget.js:44
|
||||||
#, javascript-format
|
#, javascript-format
|
||||||
@@ -991,9 +954,6 @@ msgid "Open ticket shop"
|
|||||||
msgstr "Abrir a tenda de tíckets"
|
msgstr "Abrir a tenda de tíckets"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:50
|
#: pretix/static/pretixpresale/js/widget/widget.js:50
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "Resume checkout"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Checkout"
|
msgid "Checkout"
|
||||||
msgstr "Continuar co pagamento"
|
msgstr "Continuar co pagamento"
|
||||||
@@ -1053,17 +1013,14 @@ msgid "Close"
|
|||||||
msgstr "Cerrar"
|
msgstr "Cerrar"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:62
|
#: pretix/static/pretixpresale/js/widget/widget.js:62
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "Resume checkout"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Close checkout"
|
msgid "Close checkout"
|
||||||
msgstr "Continuar co pagamento"
|
msgstr "Pagamento pechado"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:63
|
#: pretix/static/pretixpresale/js/widget/widget.js:63
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "You cannot cancel this operation. Please wait for loading to finish."
|
msgid "You cannot cancel this operation. Please wait for loading to finish."
|
||||||
msgstr ""
|
msgstr "Non podes cancelar esta operación. Agarda a que remate a carga."
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:64
|
#: pretix/static/pretixpresale/js/widget/widget.js:64
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
@@ -1071,20 +1028,14 @@ msgid "Continue"
|
|||||||
msgstr "Continuar"
|
msgstr "Continuar"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:65
|
#: pretix/static/pretixpresale/js/widget/widget.js:65
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "See variations"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Show variants"
|
msgid "Show variants"
|
||||||
msgstr "Ver variacións"
|
msgstr "Ver variacións"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:66
|
#: pretix/static/pretixpresale/js/widget/widget.js:66
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "widget"
|
|
||||||
#| msgid "See variations"
|
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
msgid "Hide variants"
|
msgid "Hide variants"
|
||||||
msgstr "Ver variacións"
|
msgstr "Ocultar variantes"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:67
|
#: pretix/static/pretixpresale/js/widget/widget.js:67
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
@@ -1133,6 +1084,9 @@ msgid ""
|
|||||||
"add yourself to the waiting list. We will then notify if seats are available "
|
"add yourself to the waiting list. We will then notify if seats are available "
|
||||||
"again."
|
"again."
|
||||||
msgstr ""
|
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
|
#: pretix/static/pretixpresale/js/widget/widget.js:76
|
||||||
msgctxt "widget"
|
msgctxt "widget"
|
||||||
@@ -1169,31 +1123,31 @@ msgstr "Dom"
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:85
|
#: pretix/static/pretixpresale/js/widget/widget.js:85
|
||||||
msgid "Monday"
|
msgid "Monday"
|
||||||
msgstr ""
|
msgstr "Luns"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:86
|
#: pretix/static/pretixpresale/js/widget/widget.js:86
|
||||||
msgid "Tuesday"
|
msgid "Tuesday"
|
||||||
msgstr ""
|
msgstr "Martes"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:87
|
#: pretix/static/pretixpresale/js/widget/widget.js:87
|
||||||
msgid "Wednesday"
|
msgid "Wednesday"
|
||||||
msgstr ""
|
msgstr "Mércores"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:88
|
#: pretix/static/pretixpresale/js/widget/widget.js:88
|
||||||
msgid "Thursday"
|
msgid "Thursday"
|
||||||
msgstr ""
|
msgstr "Xoves"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:89
|
#: pretix/static/pretixpresale/js/widget/widget.js:89
|
||||||
msgid "Friday"
|
msgid "Friday"
|
||||||
msgstr ""
|
msgstr "Venres"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:90
|
#: pretix/static/pretixpresale/js/widget/widget.js:90
|
||||||
msgid "Saturday"
|
msgid "Saturday"
|
||||||
msgstr ""
|
msgstr "Sábado"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:91
|
#: pretix/static/pretixpresale/js/widget/widget.js:91
|
||||||
msgid "Sunday"
|
msgid "Sunday"
|
||||||
msgstr ""
|
msgstr "Domingo"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/widget/widget.js:94
|
#: pretix/static/pretixpresale/js/widget/widget.js:94
|
||||||
msgid "January"
|
msgid "January"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
||||||
"PO-Revision-Date: 2025-11-26 17:00+0000\n"
|
"PO-Revision-Date: 2025-12-05 18:00+0000\n"
|
||||||
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
|
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
|
||||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
|
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||||
"ja/>\n"
|
"ja/>\n"
|
||||||
@@ -2149,7 +2149,7 @@ msgstr "クライアントID"
|
|||||||
#: pretix/base/exporters/items.py:91 pretix/base/models/items.py:667
|
#: pretix/base/exporters/items.py:91 pretix/base/models/items.py:667
|
||||||
#: pretix/base/models/items.py:1168
|
#: pretix/base/models/items.py:1168
|
||||||
msgid "Original price"
|
msgid "Original price"
|
||||||
msgstr "元の価格"
|
msgstr "通常価格"
|
||||||
|
|
||||||
#: pretix/base/exporters/items.py:92 pretix/base/models/items.py:684
|
#: pretix/base/exporters/items.py:92 pretix/base/models/items.py:684
|
||||||
msgid "This product is a gift card"
|
msgid "This product is a gift card"
|
||||||
@@ -22741,9 +22741,8 @@ msgid ""
|
|||||||
"This position has been created with a voucher with a limited budget. If you "
|
"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 "
|
"change the price or item, the discount will still be calculated from the "
|
||||||
"original price at the time of purchase."
|
"original price at the time of purchase."
|
||||||
msgstr ""
|
msgstr "このポジションは限られた予算のバウチャーで作成されました。価格やアイテムを変"
|
||||||
"このポジションは限られた予算のバウチャーで作成されました。価格やアイテムを変"
|
"更しても、割引は購入時の通常価格から計算されます。"
|
||||||
"更しても、割引は購入時の元の価格から計算されます。"
|
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/order/change.html:101
|
#: pretix/control/templates/pretixcontrol/order/change.html:101
|
||||||
#: pretix/control/templates/pretixcontrol/order/change.html:413
|
#: pretix/control/templates/pretixcontrol/order/change.html:413
|
||||||
@@ -33770,7 +33769,7 @@ msgstr "バリエーションを表示する"
|
|||||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:147
|
#: pretix/presale/templates/pretixpresale/event/voucher.html:147
|
||||||
#: pretix/presale/templates/pretixpresale/event/voucher.html:304
|
#: pretix/presale/templates/pretixpresale/event/voucher.html:304
|
||||||
msgid "Original price:"
|
msgid "Original price:"
|
||||||
msgstr "元の価格:"
|
msgstr "通常価格:"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:136
|
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:136
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:278
|
#: pretix/presale/templates/pretixpresale/event/fragment_addon_choice.html:278
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
||||||
"PO-Revision-Date: 2025-11-18 17:00+0000\n"
|
"PO-Revision-Date: 2025-12-03 23:00+0000\n"
|
||||||
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
|
"Last-Translator: SJang1 <git@sjang.dev>\n"
|
||||||
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/ko/"
|
"Language-Team: Korean <https://translate.pretix.eu/projects/pretix/pretix/ko/"
|
||||||
">\n"
|
">\n"
|
||||||
"Language: ko\n"
|
"Language: ko\n"
|
||||||
@@ -290,33 +290,27 @@ msgstr "묶음 상품은 그 자체로 또 다른 묶음을 포함 할 수 없
|
|||||||
|
|
||||||
#: pretix/api/serializers/item.py:235
|
#: pretix/api/serializers/item.py:235
|
||||||
msgid "The program start must not be empty."
|
msgid "The program start must not be empty."
|
||||||
msgstr ""
|
msgstr "프로그램 시작일정은 비어 있어서는 안 됩니다."
|
||||||
|
|
||||||
#: pretix/api/serializers/item.py:239
|
#: pretix/api/serializers/item.py:239
|
||||||
msgid "The program end must not be empty."
|
msgid "The program end must not be empty."
|
||||||
msgstr ""
|
msgstr "프로그램 종료일정은 비어 있어서는 안 됩니다."
|
||||||
|
|
||||||
#: pretix/api/serializers/item.py:242 pretix/base/models/items.py:2321
|
#: 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."
|
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
|
#: 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."
|
msgid "You cannot use program times on an event series."
|
||||||
msgstr ""
|
msgstr "이벤트 시리즈에 있는 시간은 사용하실 수 없습니다."
|
||||||
"당신의이벤트가 이벤트 시리즈가 아닌 경우 하위 이벤트를 선택할 수 없습니다."
|
|
||||||
|
|
||||||
#: pretix/api/serializers/item.py:337
|
#: pretix/api/serializers/item.py:337
|
||||||
#, fuzzy
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Updating add-ons, bundles, program times or variations via PATCH/PUT is not "
|
"Updating add-ons, bundles, program times or variations via PATCH/PUT is not "
|
||||||
"supported. Please use the dedicated nested endpoint."
|
"supported. Please use the dedicated nested endpoint."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"추가 기능, 묶음 상품들, 또는 변형은 PATCH/PUT를 통해 업데이트 할 수 없습니"
|
"추가 기능, 묶음 상품들, 또는 변형은 PATCH/PUT를 통해 업데이트 할 수 없습니다."
|
||||||
"다. 전용 중첩은 마지막 지점에서 사용하세요"
|
" 전용 중첩은 마지막 지점에서 사용하세요."
|
||||||
|
|
||||||
#: pretix/api/serializers/item.py:345
|
#: pretix/api/serializers/item.py:345
|
||||||
msgid "Only admission products can currently be personalized."
|
msgid "Only admission products can currently be personalized."
|
||||||
@@ -573,22 +567,15 @@ msgid "Event series date deleted"
|
|||||||
msgstr "이벤트 시리즈 날짜 삭제"
|
msgstr "이벤트 시리즈 날짜 삭제"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:374
|
#: pretix/api/webhooks.py:374
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Product name"
|
|
||||||
msgid "Product changed"
|
msgid "Product changed"
|
||||||
msgstr "제품명"
|
msgstr "제품 변경됨"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:375
|
#: 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 ""
|
msgid ""
|
||||||
"This includes product added or deleted and changes to nested objects like "
|
"This includes product added or deleted and changes to nested objects like "
|
||||||
"variations or bundles."
|
"variations or bundles."
|
||||||
msgstr ""
|
msgstr "여기에는 추가되거나 삭제되거나 변경된 중첩오브젝트나 번들과 같은 사항이 포함"
|
||||||
"제품 변경(제품 추가 또는 삭제, 변형 또는 번들과 같은 중첩된 객체에 대한 변경 "
|
"됩니다."
|
||||||
"포함)"
|
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:380
|
#: pretix/api/webhooks.py:380
|
||||||
msgid "Shop taken live"
|
msgid "Shop taken live"
|
||||||
@@ -623,16 +610,12 @@ msgid "Waiting list entry received voucher"
|
|||||||
msgstr "대기자 명단 항목이 바우처를 받았습니다"
|
msgstr "대기자 명단 항목이 바우처를 받았습니다"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:412
|
#: pretix/api/webhooks.py:412
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Voucher code"
|
|
||||||
msgid "Voucher added"
|
msgid "Voucher added"
|
||||||
msgstr "바우처 코드"
|
msgstr "바우처 추가됨"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:416
|
#: pretix/api/webhooks.py:416
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Voucher assigned"
|
|
||||||
msgid "Voucher changed"
|
msgid "Voucher changed"
|
||||||
msgstr "바우처 할당"
|
msgstr "바우처 변경됨"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:417
|
#: pretix/api/webhooks.py:417
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -643,10 +626,8 @@ msgstr ""
|
|||||||
"하지 않습니다."
|
"하지 않습니다."
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:421
|
#: pretix/api/webhooks.py:421
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Voucher redeemed"
|
|
||||||
msgid "Voucher deleted"
|
msgid "Voucher deleted"
|
||||||
msgstr "바우처 상환"
|
msgstr "바우처 제거됨"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:425
|
#: pretix/api/webhooks.py:425
|
||||||
msgid "Customer account created"
|
msgid "Customer account created"
|
||||||
@@ -671,7 +652,7 @@ msgstr "고객 계정 익명화되었습니다"
|
|||||||
#: pretix/plugins/banktransfer/payment.py:513
|
#: pretix/plugins/banktransfer/payment.py:513
|
||||||
#: pretix/presale/forms/customer.py:152
|
#: pretix/presale/forms/customer.py:152
|
||||||
msgid "This field is required."
|
msgid "This field is required."
|
||||||
msgstr "이 필드는 필수입니다"
|
msgstr "이 필드는 필수입니다."
|
||||||
|
|
||||||
#: pretix/base/addressvalidation.py:213
|
#: pretix/base/addressvalidation.py:213
|
||||||
msgid "Enter a postal code in the format XXX."
|
msgid "Enter a postal code in the format XXX."
|
||||||
@@ -721,7 +702,7 @@ msgstr "비밀번호"
|
|||||||
|
|
||||||
#: pretix/base/auth.py:176 pretix/base/auth.py:183
|
#: pretix/base/auth.py:176 pretix/base/auth.py:183
|
||||||
msgid "Your password must contain both numeric and alphabetic characters."
|
msgid "Your password must contain both numeric and alphabetic characters."
|
||||||
msgstr "비밀번호는 숫자와 알파벳 문자가 모두 포함되어야 합니다"
|
msgstr "비밀번호는 숫자와 알파벳 문자가 모두 포함되어야 합니다."
|
||||||
|
|
||||||
#: pretix/base/auth.py:202 pretix/base/auth.py:212
|
#: pretix/base/auth.py:202 pretix/base/auth.py:212
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -815,28 +796,21 @@ msgstr ""
|
|||||||
"소를 확인해 주십시요."
|
"소를 확인해 주십시요."
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:263
|
#: pretix/base/datasync/datasync.py:263
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid ""
|
|
||||||
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
|
|
||||||
#| "your {provider_name} settings."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
|
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
|
||||||
"settings."
|
"settings."
|
||||||
msgstr ""
|
msgstr "필드 \"{field_name}\"은 존재하지 않습니다. 당신의 {provider_name} 설정을 확인"
|
||||||
"필드 \"{field_name}\"은 {available_inputs}에 유효하지 않습니다. "
|
"해 주세요."
|
||||||
"{provider_name} 설정을 확인해 주세요."
|
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:270
|
#: pretix/base/datasync/datasync.py:270
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid ""
|
|
||||||
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
|
|
||||||
#| "your {provider_name} settings."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Field \"{field_name}\" requires {required_input}, but only got "
|
"Field \"{field_name}\" requires {required_input}, but only got "
|
||||||
"{available_inputs}. Please check your {provider_name} settings."
|
"{available_inputs}. Please check your {provider_name} settings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"필드 \"{field_name}\"은 {available_inputs}에 유효하지 않습니다. "
|
"필드 \"{field_name}\"는 {required_input}을 필요로 하지만, {available_inputs}"
|
||||||
"{provider_name} 설정을 확인해 주세요."
|
"만 받았습니다. 당신의 {provider_name} 설정을 확인해 주세요."
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:281
|
#: pretix/base/datasync/datasync.py:281
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -848,16 +822,12 @@ msgstr ""
|
|||||||
"지 않았습니다"
|
"지 않았습니다"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:128
|
#: pretix/base/datasync/sourcefields.py:128
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Order positions"
|
|
||||||
msgid "Order position details"
|
msgid "Order position details"
|
||||||
msgstr "주문 위치"
|
msgstr "주문 위치 세부 정보"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:129
|
#: pretix/base/datasync/sourcefields.py:129
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee email"
|
|
||||||
msgid "Attendee details"
|
msgid "Attendee details"
|
||||||
msgstr "참석자 이메일"
|
msgstr "참석자 정보들"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:130 pretix/base/exporters/answers.py:66
|
#: pretix/base/datasync/sourcefields.py:130 pretix/base/exporters/answers.py:66
|
||||||
#: pretix/base/models/items.py:1766 pretix/control/navigation.py:172
|
#: pretix/base/models/items.py:1766 pretix/control/navigation.py:172
|
||||||
@@ -867,10 +837,8 @@ msgid "Questions"
|
|||||||
msgstr "질문들"
|
msgstr "질문들"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:131
|
#: pretix/base/datasync/sourcefields.py:131
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Product data"
|
|
||||||
msgid "Product details"
|
msgid "Product details"
|
||||||
msgstr "상품 데이터"
|
msgstr "상품 정보"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:132
|
#: pretix/base/datasync/sourcefields.py:132
|
||||||
#: pretix/control/templates/pretixcontrol/event/settings.html:279
|
#: pretix/control/templates/pretixcontrol/event/settings.html:279
|
||||||
@@ -895,17 +863,13 @@ msgid "Invoice address"
|
|||||||
msgstr "송장 주소"
|
msgstr "송장 주소"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:134
|
#: pretix/base/datasync/sourcefields.py:134
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Meta information"
|
|
||||||
msgid "Event information"
|
msgid "Event information"
|
||||||
msgstr "메타 정보(데이타에 대한 정보)"
|
msgstr "이벤트 정보"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:135
|
#: pretix/base/datasync/sourcefields.py:135
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Send recovery information"
|
|
||||||
msgctxt "subevent"
|
msgctxt "subevent"
|
||||||
msgid "Event or date information"
|
msgid "Event or date information"
|
||||||
msgstr "복구 정보를 전송하다"
|
msgstr "이벤트 또는 날짜 정보"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:175
|
#: pretix/base/datasync/sourcefields.py:175
|
||||||
#: pretix/base/exporters/orderlist.py:605
|
#: pretix/base/exporters/orderlist.py:605
|
||||||
@@ -930,10 +894,8 @@ msgstr "참석자 이름"
|
|||||||
#: pretix/base/datasync/sourcefields.py:187
|
#: pretix/base/datasync/sourcefields.py:187
|
||||||
#: pretix/base/datasync/sourcefields.py:604
|
#: pretix/base/datasync/sourcefields.py:604
|
||||||
#: pretix/base/datasync/sourcefields.py:628
|
#: pretix/base/datasync/sourcefields.py:628
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee name"
|
|
||||||
msgid "Attendee"
|
msgid "Attendee"
|
||||||
msgstr "참석자 이름"
|
msgstr "참석자"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:207
|
#: pretix/base/datasync/sourcefields.py:207
|
||||||
#: pretix/base/exporters/orderlist.py:612 pretix/base/forms/questions.py:687
|
#: pretix/base/exporters/orderlist.py:612 pretix/base/forms/questions.py:687
|
||||||
@@ -947,10 +909,8 @@ msgid "Attendee email"
|
|||||||
msgstr "참석자 이메일"
|
msgstr "참석자 이메일"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:219
|
#: pretix/base/datasync/sourcefields.py:219
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee email"
|
|
||||||
msgid "Attendee or order email"
|
msgid "Attendee or order email"
|
||||||
msgstr "참석자 이메일"
|
msgstr "참석자 또는 구매 이메일"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:232
|
#: pretix/base/datasync/sourcefields.py:232
|
||||||
#: pretix/base/exporters/orderlist.py:613 pretix/base/pdf.py:189
|
#: pretix/base/exporters/orderlist.py:613 pretix/base/pdf.py:189
|
||||||
@@ -963,28 +923,20 @@ msgid "Attendee company"
|
|||||||
msgstr "참석자 회사"
|
msgstr "참석자 회사"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:241
|
#: pretix/base/datasync/sourcefields.py:241
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee address"
|
|
||||||
msgid "Attendee address street"
|
msgid "Attendee address street"
|
||||||
msgstr "참석자 주소"
|
msgstr "참석자 주소 도로명"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:250
|
#: pretix/base/datasync/sourcefields.py:250
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee ZIP code"
|
|
||||||
msgid "Attendee address ZIP code"
|
msgid "Attendee address ZIP code"
|
||||||
msgstr "참석자 우편번호"
|
msgstr "참석자 주소 우편번호"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:259
|
#: pretix/base/datasync/sourcefields.py:259
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee address"
|
|
||||||
msgid "Attendee address city"
|
msgid "Attendee address city"
|
||||||
msgstr "참석자 주소"
|
msgstr "참석자 주소 도시"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:268
|
#: pretix/base/datasync/sourcefields.py:268
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee address"
|
|
||||||
msgid "Attendee address country"
|
msgid "Attendee address country"
|
||||||
msgstr "참석자 주소"
|
msgstr "참석자 주소 국가"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:279
|
#: pretix/base/datasync/sourcefields.py:279
|
||||||
#: pretix/base/exporters/orderlist.py:653 pretix/base/pdf.py:347
|
#: pretix/base/exporters/orderlist.py:653 pretix/base/pdf.py:347
|
||||||
@@ -1020,16 +972,12 @@ msgid "Invoice address country"
|
|||||||
msgstr "송장 주소 국가"
|
msgstr "송장 주소 국가"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:353
|
#: pretix/base/datasync/sourcefields.py:353
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Order total"
|
|
||||||
msgid "Order email"
|
msgid "Order email"
|
||||||
msgstr "주문 합계"
|
msgstr "주문 이메일"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:362
|
#: pretix/base/datasync/sourcefields.py:362
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Order time"
|
|
||||||
msgid "Order email domain"
|
msgid "Order email domain"
|
||||||
msgstr "주문 시간"
|
msgstr "주문 이메일 도메인"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:371
|
#: pretix/base/datasync/sourcefields.py:371
|
||||||
#: pretix/base/exporters/invoices.py:203 pretix/base/exporters/invoices.py:332
|
#: pretix/base/exporters/invoices.py:203 pretix/base/exporters/invoices.py:332
|
||||||
@@ -1061,10 +1009,8 @@ msgid "Order code"
|
|||||||
msgstr "주문 코드"
|
msgstr "주문 코드"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:380
|
#: pretix/base/datasync/sourcefields.py:380
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Event end date and time"
|
|
||||||
msgid "Event and order code"
|
msgid "Event and order code"
|
||||||
msgstr "이벤트 종료 날짜 및 시간"
|
msgstr "이벤트와 주문 번호"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:389
|
#: pretix/base/datasync/sourcefields.py:389
|
||||||
#: pretix/base/exporters/orderlist.py:263 pretix/base/notifications.py:201
|
#: pretix/base/exporters/orderlist.py:263 pretix/base/notifications.py:201
|
||||||
@@ -1076,10 +1022,8 @@ msgid "Order total"
|
|||||||
msgstr "주문 합계"
|
msgstr "주문 합계"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:398
|
#: pretix/base/datasync/sourcefields.py:398
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Product name and variation"
|
|
||||||
msgid "Product and variation name"
|
msgid "Product and variation name"
|
||||||
msgstr "제품명 및 변형"
|
msgstr "제품명 및 변형 이름"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:410 pretix/base/exporters/items.py:57
|
#: pretix/base/datasync/sourcefields.py:410 pretix/base/exporters/items.py:57
|
||||||
#: pretix/base/exporters/orderlist.py:598
|
#: pretix/base/exporters/orderlist.py:598
|
||||||
@@ -1089,16 +1033,12 @@ msgid "Product ID"
|
|||||||
msgstr "상품 식별 아이디"
|
msgstr "상품 식별 아이디"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:419
|
#: pretix/base/datasync/sourcefields.py:419
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Count add-on products"
|
|
||||||
msgid "Product is admission product"
|
msgid "Product is admission product"
|
||||||
msgstr "추가된 제품을 포함합니다"
|
msgstr "상품은 입장 상품입니다"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:428
|
#: pretix/base/datasync/sourcefields.py:428
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Short form"
|
|
||||||
msgid "Event short form"
|
msgid "Event short form"
|
||||||
msgstr "짧은 형식"
|
msgstr "이벤트 짧은 형식"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:437 pretix/base/exporters/events.py:57
|
#: pretix/base/datasync/sourcefields.py:437 pretix/base/exporters/events.py:57
|
||||||
#: pretix/base/exporters/orderlist.py:263
|
#: pretix/base/exporters/orderlist.py:263
|
||||||
@@ -1141,10 +1081,8 @@ msgid "Order code and position number"
|
|||||||
msgstr "주문 코드 및 위치 번호"
|
msgstr "주문 코드 및 위치 번호"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:482
|
#: pretix/base/datasync/sourcefields.py:482
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Ticket code"
|
|
||||||
msgid "Ticket price"
|
msgid "Ticket price"
|
||||||
msgstr "티켓 코드"
|
msgstr "티켓 가격"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:491 pretix/base/notifications.py:204
|
#: pretix/base/datasync/sourcefields.py:491 pretix/base/notifications.py:204
|
||||||
#: pretix/control/forms/filter.py:216 pretix/control/forms/modelimport.py:90
|
#: pretix/control/forms/filter.py:216 pretix/control/forms/modelimport.py:90
|
||||||
@@ -1152,22 +1090,16 @@ msgid "Order status"
|
|||||||
msgstr "주문 상태"
|
msgstr "주문 상태"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:500
|
#: pretix/base/datasync/sourcefields.py:500
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Device status"
|
|
||||||
msgid "Ticket status"
|
msgid "Ticket status"
|
||||||
msgstr "기기 상태"
|
msgstr "티켓 상태"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:509
|
#: pretix/base/datasync/sourcefields.py:509
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Purchase date and time"
|
|
||||||
msgid "Order date and time"
|
msgid "Order date and time"
|
||||||
msgstr "구매 날짜 및 시간"
|
msgstr "구매 날짜 및 시간"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:518
|
#: pretix/base/datasync/sourcefields.py:518
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Printing date and time"
|
|
||||||
msgid "Payment date and time"
|
msgid "Payment date and time"
|
||||||
msgstr "인쇄 날짜 및 시간"
|
msgstr "결제 날짜 및 시간"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:527
|
#: pretix/base/datasync/sourcefields.py:527
|
||||||
#: pretix/base/exporters/orderlist.py:272
|
#: pretix/base/exporters/orderlist.py:272
|
||||||
@@ -1178,35 +1110,27 @@ msgid "Order locale"
|
|||||||
msgstr "주문 지역 설정"
|
msgstr "주문 지역 설정"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:536
|
#: pretix/base/datasync/sourcefields.py:536
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Order position"
|
|
||||||
msgid "Order position ID"
|
msgid "Order position ID"
|
||||||
msgstr "주문 위치"
|
msgstr "주문 위치 ID"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:545
|
#: pretix/base/datasync/sourcefields.py:545
|
||||||
#: pretix/base/exporters/orderlist.py:292
|
#: pretix/base/exporters/orderlist.py:292
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Order time"
|
|
||||||
msgid "Order link"
|
msgid "Order link"
|
||||||
msgstr "주문 시간"
|
msgstr "주문 링크"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:560
|
#: pretix/base/datasync/sourcefields.py:560
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Ticket design"
|
|
||||||
msgid "Ticket link"
|
msgid "Ticket link"
|
||||||
msgstr "티켓 디자인"
|
msgstr "티켓 링크"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:578
|
#: pretix/base/datasync/sourcefields.py:578
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid "Check-in list {val}"
|
|
||||||
msgid "Check-in datetime on list {}"
|
msgid "Check-in datetime on list {}"
|
||||||
msgstr "체크인 목록 {val}"
|
msgstr "{} 리스트에 있는 체크인 날짜와 시간"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:590
|
#: pretix/base/datasync/sourcefields.py:590
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid "Question {val}"
|
|
||||||
msgid "Question: {name}"
|
msgid "Question: {name}"
|
||||||
msgstr "질문 {val}"
|
msgstr "질문: {name}"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:604
|
#: pretix/base/datasync/sourcefields.py:604
|
||||||
#: pretix/base/datasync/sourcefields.py:614 pretix/base/settings.py:3642
|
#: pretix/base/datasync/sourcefields.py:614 pretix/base/settings.py:3642
|
||||||
@@ -2422,9 +2346,9 @@ msgid "Fees"
|
|||||||
msgstr "수수료"
|
msgstr "수수료"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:277
|
#: pretix/base/exporters/orderlist.py:277
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Gross at {rate} % tax"
|
msgid "Gross at {rate} % tax"
|
||||||
msgstr "세율{%}의 세금으로 총합"
|
msgstr "세율 {rate}%의 세금으로 총합"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:278
|
#: pretix/base/exporters/orderlist.py:278
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -2472,9 +2396,9 @@ msgid "External customer ID"
|
|||||||
msgstr "외부고객 아이디"
|
msgstr "외부고객 아이디"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:296
|
#: pretix/base/exporters/orderlist.py:296
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Paid by {method}"
|
msgid "Paid by {method}"
|
||||||
msgstr "{방법}에 의해 결제됨"
|
msgstr "{method}에 의해 결제됨"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:458
|
#: pretix/base/exporters/orderlist.py:458
|
||||||
#: pretix/base/exporters/orderlist.py:914
|
#: pretix/base/exporters/orderlist.py:914
|
||||||
@@ -2677,10 +2601,8 @@ msgid "Check-in lists"
|
|||||||
msgstr "체크인 목록"
|
msgstr "체크인 목록"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:672
|
#: pretix/base/exporters/orderlist.py:672
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Additional footer link"
|
|
||||||
msgid "Position order link"
|
msgid "Position order link"
|
||||||
msgstr "추가 하단 링크"
|
msgstr "주문 링크 위치"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:841
|
#: pretix/base/exporters/orderlist.py:841
|
||||||
msgid "Order transaction data"
|
msgid "Order transaction data"
|
||||||
@@ -3320,15 +3242,13 @@ msgid "Repeat password"
|
|||||||
msgstr "반복 비밀번호"
|
msgstr "반복 비밀번호"
|
||||||
|
|
||||||
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
|
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address"
|
|
||||||
msgid "Your email address"
|
msgid "Your email address"
|
||||||
msgstr "이메일 주소"
|
msgstr "당신의 이메일 주소"
|
||||||
|
|
||||||
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
|
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
|
||||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
||||||
msgid "Confirmation code"
|
msgid "Confirmation code"
|
||||||
msgstr ""
|
msgstr "확인 코드"
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:137 pretix/base/forms/questions.py:264
|
#: pretix/base/forms/questions.py:137 pretix/base/forms/questions.py:264
|
||||||
msgctxt "name_salutation"
|
msgctxt "name_salutation"
|
||||||
@@ -3411,14 +3331,12 @@ msgstr ""
|
|||||||
"야 할 수도 있습니다."
|
"야 할 수도 있습니다."
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:1181
|
#: pretix/base/forms/questions.py:1181
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Cancellation requested"
|
|
||||||
msgid "No invoice requested"
|
msgid "No invoice requested"
|
||||||
msgstr "취소 요청"
|
msgstr "청구서 요청되지 않음"
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:1183
|
#: pretix/base/forms/questions.py:1183
|
||||||
msgid "Invoice transmission method"
|
msgid "Invoice transmission method"
|
||||||
msgstr ""
|
msgstr "청구서 전송 방식"
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:1329
|
#: pretix/base/forms/questions.py:1329
|
||||||
msgid "You need to provide a company name."
|
msgid "You need to provide a company name."
|
||||||
@@ -3432,21 +3350,20 @@ msgstr "이름을 입력해야 합니다."
|
|||||||
msgid ""
|
msgid ""
|
||||||
"If you enter an invoice address, you also need to select an invoice "
|
"If you enter an invoice address, you also need to select an invoice "
|
||||||
"transmission method."
|
"transmission method."
|
||||||
msgstr ""
|
msgstr "당신이 청구서 주소를 입력하신다면, 청구서 수신 방법도 선택하셔야 합니다."
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:1385
|
#: pretix/base/forms/questions.py:1385
|
||||||
#, fuzzy
|
|
||||||
#| msgid "The selected media type is not enabled in your organizer settings."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The selected transmission type is not available in your country or for your "
|
"The selected transmission type is not available in your country or for your "
|
||||||
"type of address."
|
"type of address."
|
||||||
msgstr "선택한 미디어 유형이 정리함 설정에서 활성화되지 않았습니다."
|
msgstr "선택한 전송 유형은 당신의 국가 또는 지역에서 이용하실 수 없습니다."
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:1394
|
#: pretix/base/forms/questions.py:1394
|
||||||
msgid ""
|
msgid ""
|
||||||
"The selected type of invoice transmission requires a field that is currently "
|
"The selected type of invoice transmission requires a field that is currently "
|
||||||
"not available, please reach out to the organizer."
|
"not available, please reach out to the organizer."
|
||||||
msgstr ""
|
msgstr "선택하신 청구서 전송 유형은 현재 사용할 수 없는 필드의 입력을 필요로 하니, 주"
|
||||||
|
"최자에게 문의 해 주세요."
|
||||||
|
|
||||||
#: pretix/base/forms/questions.py:1398
|
#: pretix/base/forms/questions.py:1398
|
||||||
msgid "This field is required for the selected type of invoice transmission."
|
msgid "This field is required for the selected type of invoice transmission."
|
||||||
@@ -3466,10 +3383,8 @@ msgstr ""
|
|||||||
"대가 대신 사용됩니다."
|
"대가 대신 사용됩니다."
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:77
|
#: pretix/base/forms/user.py:77
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee email address"
|
|
||||||
msgid "Change email address"
|
msgid "Change email address"
|
||||||
msgstr "참석자 이메일 주소"
|
msgstr "이메일 주소 변경"
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:83
|
#: pretix/base/forms/user.py:83
|
||||||
msgid "Device name"
|
msgid "Device name"
|
||||||
@@ -3518,16 +3433,12 @@ msgstr ""
|
|||||||
"이 이메일 주소와 관련된 계정이 이미 있습니다. 다른 계정을 선택해 주세요."
|
"이 이메일 주소와 관련된 계정이 이미 있습니다. 다른 계정을 선택해 주세요."
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:179
|
#: pretix/base/forms/user.py:179
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address"
|
|
||||||
msgid "Old email address"
|
msgid "Old email address"
|
||||||
msgstr "이메일 주소"
|
msgstr "이전 이메일 주소"
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:180
|
#: pretix/base/forms/user.py:180
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address"
|
|
||||||
msgid "New email address"
|
msgid "New email address"
|
||||||
msgstr "이메일 주소"
|
msgstr "새 이메일 주소"
|
||||||
|
|
||||||
#: pretix/base/forms/validators.py:51
|
#: pretix/base/forms/validators.py:51
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -3572,23 +3483,22 @@ msgstr "개별 고객"
|
|||||||
|
|
||||||
#: pretix/base/invoicing/email.py:50
|
#: pretix/base/invoicing/email.py:50
|
||||||
msgid "Email invoice directly to accounting department"
|
msgid "Email invoice directly to accounting department"
|
||||||
msgstr ""
|
msgstr "청구서를 회계 부서로 이메일로 바로 보내기"
|
||||||
|
|
||||||
#: pretix/base/invoicing/email.py:51
|
#: pretix/base/invoicing/email.py:51
|
||||||
msgid ""
|
msgid ""
|
||||||
"If not selected, the invoice will be sent to you using the email address "
|
"If not selected, the invoice will be sent to you using the email address "
|
||||||
"listed above."
|
"listed above."
|
||||||
msgstr ""
|
msgstr "선택되지 않은 경우, 청구서는 위의 이메일 주소를 통해 당신에게 보내질 것 입니"
|
||||||
|
"다."
|
||||||
|
|
||||||
#: pretix/base/invoicing/email.py:55
|
#: pretix/base/invoicing/email.py:55
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address verified"
|
|
||||||
msgid "Email address for invoice"
|
msgid "Email address for invoice"
|
||||||
msgstr "이메일 주소 확인"
|
msgstr "청구서용 이메일 주소"
|
||||||
|
|
||||||
#: pretix/base/invoicing/email.py:91
|
#: pretix/base/invoicing/email.py:91
|
||||||
msgid "PDF via email"
|
msgid "PDF via email"
|
||||||
msgstr ""
|
msgstr "이메일로 PDF"
|
||||||
|
|
||||||
#: pretix/base/invoicing/national.py:37
|
#: pretix/base/invoicing/national.py:37
|
||||||
msgctxt "italian_invoice"
|
msgctxt "italian_invoice"
|
||||||
@@ -3613,11 +3523,9 @@ msgid "Address for certified electronic mail"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/base/invoicing/national.py:57
|
#: pretix/base/invoicing/national.py:57
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Recipient"
|
|
||||||
msgctxt "italian_invoice"
|
msgctxt "italian_invoice"
|
||||||
msgid "Recipient code"
|
msgid "Recipient code"
|
||||||
msgstr "영수증"
|
msgstr "영수증 코드"
|
||||||
|
|
||||||
#: pretix/base/invoicing/national.py:81
|
#: pretix/base/invoicing/national.py:81
|
||||||
msgctxt "italian_invoice"
|
msgctxt "italian_invoice"
|
||||||
@@ -3697,7 +3605,6 @@ msgid ""
|
|||||||
"until {to_date}"
|
"until {to_date}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"{from_date}\n"
|
"{from_date}\n"
|
||||||
"\n"
|
|
||||||
"{to_date}까지"
|
"{to_date}까지"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:609 pretix/base/services/mail.py:512
|
#: pretix/base/invoicing/pdf.py:609 pretix/base/services/mail.py:512
|
||||||
@@ -3777,10 +3684,10 @@ msgid "Single price: {net_price} net / {gross_price} gross"
|
|||||||
msgstr "단일 가격: {net_price} 순 / {gross_price} 총합"
|
msgstr "단일 가격: {net_price} 순 / {gross_price} 총합"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:901
|
#: pretix/base/invoicing/pdf.py:901
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
msgid "Single price: {price}"
|
msgid "Single price: {price}"
|
||||||
msgstr "단일 가격: {가격}"
|
msgstr "단일 가격: {price}"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:944 pretix/base/invoicing/pdf.py:949
|
#: pretix/base/invoicing/pdf.py:944 pretix/base/invoicing/pdf.py:949
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
@@ -3808,12 +3715,10 @@ msgid "Remaining amount"
|
|||||||
msgstr "잔액"
|
msgstr "잔액"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1009
|
#: pretix/base/invoicing/pdf.py:1009
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgctxt "invoice"
|
|
||||||
#| msgid "Event date: {date_range}"
|
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
msgid "Invoice period: {daterange}"
|
msgid "Invoice period: {daterange}"
|
||||||
msgstr "이벤트 날짜: {date_range}"
|
msgstr "청구서 기간: {daterange}"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1040
|
#: pretix/base/invoicing/pdf.py:1040
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
@@ -3836,13 +3741,12 @@ msgid "Included taxes"
|
|||||||
msgstr "세금 포함"
|
msgstr "세금 포함"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1100
|
#: pretix/base/invoicing/pdf.py:1100
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
msgid ""
|
msgid ""
|
||||||
"Using the conversion rate of 1:{rate} as published by the {authority} on "
|
"Using the conversion rate of 1:{rate} as published by the {authority} on "
|
||||||
"{date}, this corresponds to:"
|
"{date}, this corresponds to:"
|
||||||
msgstr ""
|
msgstr "{date}에 {authority}에서 발표한 1:{rate}의 변환율을 사용하면 다음과 같습니다:"
|
||||||
"{날짜}에 {당국}에서 발표한 1:{세율}의 변환율을 사용하면 다음과 같습니다:"
|
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1115
|
#: pretix/base/invoicing/pdf.py:1115
|
||||||
#, fuzzy, python-brace-format
|
#, fuzzy, python-brace-format
|
||||||
@@ -3850,9 +3754,8 @@ msgctxt "invoice"
|
|||||||
msgid ""
|
msgid ""
|
||||||
"Using the conversion rate of 1:{rate} as published by the {authority} on "
|
"Using the conversion rate of 1:{rate} as published by the {authority} on "
|
||||||
"{date}, the invoice total corresponds to {total}."
|
"{date}, the invoice total corresponds to {total}."
|
||||||
msgstr ""
|
msgstr "{date}에 {authority}에서 게시한 1:{rate}의 변환율을 사용하면 송장 총액이 "
|
||||||
"{날짜}에 {당국}에서 게시한 1:{세율}의 변환율을 사용하면 송장 총액이 {총합}에 "
|
"{total}에 해당합니다."
|
||||||
"해당합니다."
|
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1129
|
#: pretix/base/invoicing/pdf.py:1129
|
||||||
msgid "Default invoice renderer (European-style letter)"
|
msgid "Default invoice renderer (European-style letter)"
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ msgstr ""
|
|||||||
"Project-Id-Version: 1\n"
|
"Project-Id-Version: 1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-26 18:00+0000\n"
|
"PO-Revision-Date: 2025-12-08 07:00+0000\n"
|
||||||
"Last-Translator: Jan Van Haver <jan.van.haver@gmail.com>\n"
|
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
|
||||||
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/"
|
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix/nl/>"
|
||||||
">\n"
|
"\n"
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.14\n"
|
"X-Generator: Weblate 5.14.3\n"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:87
|
#: pretix/_base_settings.py:87
|
||||||
msgid "English"
|
msgid "English"
|
||||||
@@ -44,7 +44,7 @@ msgstr "Catalaans"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:93
|
#: pretix/_base_settings.py:93
|
||||||
msgid "Chinese (simplified)"
|
msgid "Chinese (simplified)"
|
||||||
msgstr "Chinees (versimpeld)"
|
msgstr "Chinees (vereenvoudigd)"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:94
|
#: pretix/_base_settings.py:94
|
||||||
msgid "Chinese (traditional)"
|
msgid "Chinese (traditional)"
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
||||||
"PO-Revision-Date: 2024-02-13 16:00+0000\n"
|
"PO-Revision-Date: 2025-12-08 07:00+0000\n"
|
||||||
"Last-Translator: Wessel Stam <info@wesselstam.nl>\n"
|
"Last-Translator: Ruud Hendrickx <ruud@leckxicon.eu>\n"
|
||||||
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
|
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
|
||||||
"pretix/nl_Informal/>\n"
|
"pretix/nl_Informal/>\n"
|
||||||
"Language: nl_Informal\n"
|
"Language: nl_Informal\n"
|
||||||
@@ -17,7 +17,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.3.1\n"
|
"X-Generator: Weblate 5.14.3\n"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:87
|
#: pretix/_base_settings.py:87
|
||||||
msgid "English"
|
msgid "English"
|
||||||
@@ -37,15 +37,15 @@ msgstr "Arabisch"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:91
|
#: pretix/_base_settings.py:91
|
||||||
msgid "Basque"
|
msgid "Basque"
|
||||||
msgstr ""
|
msgstr "Baskisch"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:92
|
#: pretix/_base_settings.py:92
|
||||||
msgid "Catalan"
|
msgid "Catalan"
|
||||||
msgstr ""
|
msgstr "Catalaans"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:93
|
#: pretix/_base_settings.py:93
|
||||||
msgid "Chinese (simplified)"
|
msgid "Chinese (simplified)"
|
||||||
msgstr "Chinees (versimpeld)"
|
msgstr "Chinees (vereenvoudigd)"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:94
|
#: pretix/_base_settings.py:94
|
||||||
msgid "Chinese (traditional)"
|
msgid "Chinese (traditional)"
|
||||||
@@ -57,7 +57,7 @@ msgstr "Tsjechisch"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:96
|
#: pretix/_base_settings.py:96
|
||||||
msgid "Croatian"
|
msgid "Croatian"
|
||||||
msgstr ""
|
msgstr "Kroatisch"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:97
|
#: pretix/_base_settings.py:97
|
||||||
msgid "Danish"
|
msgid "Danish"
|
||||||
@@ -89,7 +89,7 @@ msgstr "Grieks"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:104
|
#: pretix/_base_settings.py:104
|
||||||
msgid "Hebrew"
|
msgid "Hebrew"
|
||||||
msgstr ""
|
msgstr "Hebreeuws"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:105
|
#: pretix/_base_settings.py:105
|
||||||
msgid "Indonesian"
|
msgid "Indonesian"
|
||||||
@@ -101,7 +101,7 @@ msgstr "Italiaans"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:107
|
#: pretix/_base_settings.py:107
|
||||||
msgid "Japanese"
|
msgid "Japanese"
|
||||||
msgstr ""
|
msgstr "Japans"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:108
|
#: pretix/_base_settings.py:108
|
||||||
msgid "Latvian"
|
msgid "Latvian"
|
||||||
@@ -133,11 +133,11 @@ msgstr "Russisch"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:115
|
#: pretix/_base_settings.py:115
|
||||||
msgid "Slovak"
|
msgid "Slovak"
|
||||||
msgstr ""
|
msgstr "Slowaaks"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:116
|
#: pretix/_base_settings.py:116
|
||||||
msgid "Swedish"
|
msgid "Swedish"
|
||||||
msgstr ""
|
msgstr "Zweeds"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:117
|
#: pretix/_base_settings.py:117
|
||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
@@ -145,7 +145,7 @@ msgstr "Spaans"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:118
|
#: pretix/_base_settings.py:118
|
||||||
msgid "Spanish (Latin America)"
|
msgid "Spanish (Latin America)"
|
||||||
msgstr ""
|
msgstr "Spaans (Latijns-Amerika)"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:119
|
#: pretix/_base_settings.py:119
|
||||||
msgid "Turkish"
|
msgid "Turkish"
|
||||||
@@ -261,7 +261,7 @@ msgstr ""
|
|||||||
#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554
|
#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Meta data property '{name}' does not exist."
|
msgid "Meta data property '{name}' does not exist."
|
||||||
msgstr "Metadataeigenschap '{name}' bestaat niet."
|
msgstr "Metadata-eigenschap '{name}' bestaat niet."
|
||||||
|
|
||||||
#: pretix/api/serializers/event.py:237 pretix/api/serializers/event.py:557
|
#: pretix/api/serializers/event.py:237 pretix/api/serializers/event.py:557
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -32970,7 +32970,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/reports/exporters.py:257
|
#: pretix/plugins/reports/exporters.py:257
|
||||||
msgctxt "export_category"
|
msgctxt "export_category"
|
||||||
msgid "Analysis"
|
msgid "Analysis"
|
||||||
msgstr ""
|
msgstr "Analyse"
|
||||||
|
|
||||||
#: pretix/plugins/reports/accountingreport.py:83
|
#: pretix/plugins/reports/accountingreport.py:83
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
||||||
"PO-Revision-Date: 2025-09-10 05:00+0000\n"
|
"PO-Revision-Date: 2025-12-11 01:00+0000\n"
|
||||||
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
|
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
|
||||||
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
||||||
"pretix/pretix/pt_BR/>\n"
|
"pretix/pretix/pt_BR/>\n"
|
||||||
@@ -17,7 +17,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 5.13.2\n"
|
"X-Generator: Weblate 5.14.3\n"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:87
|
#: pretix/_base_settings.py:87
|
||||||
msgid "English"
|
msgid "English"
|
||||||
@@ -253,9 +253,8 @@ msgid ""
|
|||||||
"Events cannot be created as 'live'. Quotas and payment must be added to the "
|
"Events cannot be created as 'live'. Quotas and payment must be added to the "
|
||||||
"event before sales can go live."
|
"event before sales can go live."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Os eventos não podem ser criados como 'ativo'. As cotas e métodos de "
|
"Eventos não podem ser criados como 'ativo'. Cotas e métodos de pagamento "
|
||||||
"pagamento devem ser adicionados ao evento antes que as vendas possam ser "
|
"devem ser adicionados ao evento antes que as vendas se iniciem."
|
||||||
"iniciadas."
|
|
||||||
|
|
||||||
#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554
|
#: pretix/api/serializers/event.py:234 pretix/api/serializers/event.py:554
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -358,7 +357,8 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/api/serializers/item.py:587 pretix/control/forms/item.py:177
|
#: pretix/api/serializers/item.py:587 pretix/control/forms/item.py:177
|
||||||
msgid "Question cannot depend on a question asked during check-in."
|
msgid "Question cannot depend on a question asked during check-in."
|
||||||
msgstr "A pergunta não pode depender de uma pergunta feita durante o check-in."
|
msgstr ""
|
||||||
|
"A pergunta não pode depender de outra pergunta feita durante o check-in."
|
||||||
|
|
||||||
#: pretix/api/serializers/item.py:592 pretix/control/forms/item.py:182
|
#: pretix/api/serializers/item.py:592 pretix/control/forms/item.py:182
|
||||||
msgid "Circular dependency between questions detected."
|
msgid "Circular dependency between questions detected."
|
||||||
@@ -816,28 +816,22 @@ msgstr ""
|
|||||||
"confirme primeiro o endereço de email na sua conta."
|
"confirme primeiro o endereço de email na sua conta."
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:263
|
#: pretix/base/datasync/datasync.py:263
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid ""
|
|
||||||
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
|
|
||||||
#| "your {provider_name} settings."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
|
"Field \"{field_name}\" does not exist. Please check your {provider_name} "
|
||||||
"settings."
|
"settings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"O campo \"{field_name}\" não é válido para {available_inputs}. Verifique as "
|
"O campo \"{field_name}\" não existe. Por favor, verifique as configurações "
|
||||||
"configurações de {provider_name}."
|
"de {provider_name}."
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:270
|
#: pretix/base/datasync/datasync.py:270
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid ""
|
|
||||||
#| "Field \"{field_name}\" is not valid for {available_inputs}. Please check "
|
|
||||||
#| "your {provider_name} settings."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Field \"{field_name}\" requires {required_input}, but only got "
|
"Field \"{field_name}\" requires {required_input}, but only got "
|
||||||
"{available_inputs}. Please check your {provider_name} settings."
|
"{available_inputs}. Please check your {provider_name} settings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"O campo \"{field_name}\" não é válido para {available_inputs}. Verifique as "
|
"Campo \"{field_name}\" exige {required_input}, mas apenas {available_inputs} "
|
||||||
"configurações de {provider_name}."
|
"foram fornecidas. Por favor, verifique as configurações de {provider_name}."
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:281
|
#: pretix/base/datasync/datasync.py:281
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -2137,7 +2131,7 @@ msgstr "Comprar este produto requer aprovação"
|
|||||||
|
|
||||||
#: pretix/base/exporters/items.py:85 pretix/base/models/items.py:627
|
#: pretix/base/exporters/items.py:85 pretix/base/models/items.py:627
|
||||||
msgid "Only sell this product as part of a bundle"
|
msgid "Only sell this product as part of a bundle"
|
||||||
msgstr "Disponível apenas como parte de um pacote"
|
msgstr "Venda este produto apenas como parte de um pacote"
|
||||||
|
|
||||||
#: pretix/base/exporters/items.py:86 pretix/base/models/items.py:634
|
#: pretix/base/exporters/items.py:86 pretix/base/models/items.py:634
|
||||||
msgid "Allow product to be canceled or changed"
|
msgid "Allow product to be canceled or changed"
|
||||||
@@ -2839,7 +2833,7 @@ msgstr "Código de Status"
|
|||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:25
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/import_assign.html:25
|
||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:13
|
||||||
msgid "Amount"
|
msgid "Amount"
|
||||||
msgstr "Valor"
|
msgstr "Quantidade"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:1098
|
#: pretix/base/exporters/orderlist.py:1098
|
||||||
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:102
|
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:102
|
||||||
@@ -3286,10 +3280,8 @@ msgid "Repeat password"
|
|||||||
msgstr "Repita a senha"
|
msgstr "Repita a senha"
|
||||||
|
|
||||||
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
|
#: pretix/base/forms/auth.py:220 pretix/base/forms/user.py:99
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address"
|
|
||||||
msgid "Your email address"
|
msgid "Your email address"
|
||||||
msgstr "Endereço de email"
|
msgstr "Seu endereço de e-mail"
|
||||||
|
|
||||||
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
|
#: pretix/base/forms/auth.py:327 pretix/control/forms/orders.py:1041
|
||||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
#: pretix/control/templates/pretixcontrol/shredder/download.html:53
|
||||||
@@ -3400,6 +3392,8 @@ msgid ""
|
|||||||
"If you enter an invoice address, you also need to select an invoice "
|
"If you enter an invoice address, you also need to select an invoice "
|
||||||
"transmission method."
|
"transmission method."
|
||||||
msgstr ""
|
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
|
#: pretix/base/forms/questions.py:1385
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -3414,6 +3408,8 @@ msgid ""
|
|||||||
"The selected type of invoice transmission requires a field that is currently "
|
"The selected type of invoice transmission requires a field that is currently "
|
||||||
"not available, please reach out to the organizer."
|
"not available, please reach out to the organizer."
|
||||||
msgstr ""
|
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
|
#: pretix/base/forms/questions.py:1398
|
||||||
msgid "This field is required for the selected type of invoice transmission."
|
msgid "This field is required for the selected type of invoice transmission."
|
||||||
@@ -3433,10 +3429,8 @@ msgstr ""
|
|||||||
"as exibições de eventos, o fuso horário do evento é usado."
|
"as exibições de eventos, o fuso horário do evento é usado."
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:77
|
#: pretix/base/forms/user.py:77
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Attendee email address"
|
|
||||||
msgid "Change email address"
|
msgid "Change email address"
|
||||||
msgstr "Email do participante"
|
msgstr "Alterar endereço de e-mail"
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:83
|
#: pretix/base/forms/user.py:83
|
||||||
msgid "Device name"
|
msgid "Device name"
|
||||||
@@ -3486,16 +3480,12 @@ msgstr ""
|
|||||||
"um diferente."
|
"um diferente."
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:179
|
#: pretix/base/forms/user.py:179
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address"
|
|
||||||
msgid "Old email address"
|
msgid "Old email address"
|
||||||
msgstr "Endereço de email"
|
msgstr "Endereço de e-mail antigo"
|
||||||
|
|
||||||
#: pretix/base/forms/user.py:180
|
#: pretix/base/forms/user.py:180
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Email address"
|
|
||||||
msgid "New email address"
|
msgid "New email address"
|
||||||
msgstr "Endereço de email"
|
msgstr "Endereço de e-mail novo"
|
||||||
|
|
||||||
#: pretix/base/forms/validators.py:51
|
#: pretix/base/forms/validators.py:51
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -3540,22 +3530,17 @@ msgid "Individual customer"
|
|||||||
msgstr "Cliente pessoa física"
|
msgstr "Cliente pessoa física"
|
||||||
|
|
||||||
#: pretix/base/invoicing/email.py:50
|
#: 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"
|
msgid "Email invoice directly to accounting department"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Para enviar a fatura diretamente ao seu departamento de contabilidade, "
|
"Enviar e-mail com a fatura diretamente para departamento de contabilidade"
|
||||||
"insira o endereço de e-mail:"
|
|
||||||
|
|
||||||
#: pretix/base/invoicing/email.py:51
|
#: pretix/base/invoicing/email.py:51
|
||||||
#, fuzzy
|
|
||||||
#| msgid "The invoice was sent to the designated email address."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"If not selected, the invoice will be sent to you using the email address "
|
"If not selected, the invoice will be sent to you using the email address "
|
||||||
"listed above."
|
"listed above."
|
||||||
msgstr "A fatura foi enviada para o endereço de e-mail designado."
|
msgstr ""
|
||||||
|
"Se não selecionado, a fatura será enviada para o endereço de e-mail listado "
|
||||||
|
"a seguir."
|
||||||
|
|
||||||
#: pretix/base/invoicing/email.py:55
|
#: pretix/base/invoicing/email.py:55
|
||||||
msgid "Email address for invoice"
|
msgid "Email address for invoice"
|
||||||
@@ -3778,12 +3763,10 @@ msgid "Remaining amount"
|
|||||||
msgstr "Valor restante"
|
msgstr "Valor restante"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1009
|
#: pretix/base/invoicing/pdf.py:1009
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgctxt "invoice"
|
|
||||||
#| msgid "Event date: {date_range}"
|
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
msgid "Invoice period: {daterange}"
|
msgid "Invoice period: {daterange}"
|
||||||
msgstr "Data do evento: {date_range}"
|
msgstr "Período da fatura: {daterange}"
|
||||||
|
|
||||||
#: pretix/base/invoicing/pdf.py:1040
|
#: pretix/base/invoicing/pdf.py:1040
|
||||||
msgctxt "invoice"
|
msgctxt "invoice"
|
||||||
@@ -3868,12 +3851,9 @@ msgid "Peppol participant ID"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/base/invoicing/peppol.py:170
|
#: pretix/base/invoicing/peppol.py:170
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "italian_invoice"
|
|
||||||
#| msgid "Fiscal code"
|
|
||||||
msgctxt "peppol_invoice"
|
msgctxt "peppol_invoice"
|
||||||
msgid "Visual copy"
|
msgid "Visual copy"
|
||||||
msgstr "Código fiscal"
|
msgstr "Cópia visual"
|
||||||
|
|
||||||
#: pretix/base/invoicing/peppol.py:175
|
#: pretix/base/invoicing/peppol.py:175
|
||||||
msgctxt "peppol_invoice"
|
msgctxt "peppol_invoice"
|
||||||
@@ -4357,10 +4337,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/base/models/auth.py:392
|
#: pretix/base/models/auth.py:392
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Confirmation code"
|
|
||||||
msgid "pretix confirmation code"
|
msgid "pretix confirmation code"
|
||||||
msgstr "Código de confirmação"
|
msgstr "código de confirmação do pretix"
|
||||||
|
|
||||||
#: pretix/base/models/auth.py:435
|
#: pretix/base/models/auth.py:435
|
||||||
#: pretix/control/templates/pretixcontrol/auth/forgot.html:7
|
#: pretix/control/templates/pretixcontrol/auth/forgot.html:7
|
||||||
@@ -4862,11 +4840,11 @@ msgid ""
|
|||||||
"you can also choose to use a random value. This will be used in URLs, order "
|
"you can also choose to use a random value. This will be used in URLs, order "
|
||||||
"codes, invoice numbers, and bank transfer references."
|
"codes, invoice numbers, and bank transfer references."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Deve ser curts, conter apenas letras minúsculas, números, pontos e traços, e "
|
"Deve conter apenas letras minúsculas, números, pontos e traços, sendo "
|
||||||
"ser exclusiva entre seus eventos. Recomendamos algum tipo de abreviação ou "
|
"exclusiva para suas eventos. Recomendamos uma abreviação ou data com menos "
|
||||||
"uma data com menos de 10 caracteres que sejam facilmente lembradas, mas você "
|
"de 10 caracteres e que seja facilmente lembrada, mas você também pode usar "
|
||||||
"também pode usar um valor aleatório. Esta informação será usada em URLs, "
|
"um valor aleatório. Esta informação será usada em URLs, códigos de pedido, "
|
||||||
"códigos de pedido, números de fatura e referências de transferência bancária."
|
"número de faturas e referências de transações bancárias."
|
||||||
|
|
||||||
#: pretix/base/models/event.py:607 pretix/base/models/organizer.py:89
|
#: pretix/base/models/event.py:607 pretix/base/models/organizer.py:89
|
||||||
msgid "The slug may only contain letters, numbers, dots and dashes."
|
msgid "The slug may only contain letters, numbers, dots and dashes."
|
||||||
@@ -5394,24 +5372,16 @@ msgstr ""
|
|||||||
"não tiver variações, este preço será usado."
|
"não tiver variações, este preço será usado."
|
||||||
|
|
||||||
#: pretix/base/models/items.py:506
|
#: 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 ""
|
msgid ""
|
||||||
"If this option is active, your users can choose the price themselves. The "
|
"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 "
|
"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 "
|
"to enter. You could use this e.g. to collect additional donations for your "
|
||||||
"event."
|
"event."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Se esta opção estiver ativa, seus usuários podem escolher o próprio preço. O "
|
"Se esta opção está selecionada, os usuários poderão pagar o preço que "
|
||||||
"preço configurado acima é então interpretado como o preço mínimo que um "
|
"desejarem. O preço padrão acima será interpretado como o preço mínimo que o "
|
||||||
"usuário deve inserir. Você pode usar isso, por exemplo, para coletar doações "
|
"usuário deverá pagar. Você pode usar esta opção, por exemplo, para coletar "
|
||||||
"adicionais para o seu evento. No momento, isto não é suportado por produtos "
|
"doações adicionais para o seu evento."
|
||||||
"comprados como um complemento de outros produtos."
|
|
||||||
|
|
||||||
#: pretix/base/models/items.py:511 pretix/base/models/items.py:1175
|
#: pretix/base/models/items.py:511 pretix/base/models/items.py:1175
|
||||||
msgid "Suggested price"
|
msgid "Suggested price"
|
||||||
@@ -6298,9 +6268,6 @@ msgstr ""
|
|||||||
"insira um valor possível por linha."
|
"insira um valor possível por linha."
|
||||||
|
|
||||||
#: pretix/base/models/items.py:2310
|
#: pretix/base/models/items.py:2310
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "timeframe"
|
|
||||||
#| msgid "Start"
|
|
||||||
msgid "Start"
|
msgid "Start"
|
||||||
msgstr "Início"
|
msgstr "Início"
|
||||||
|
|
||||||
@@ -7912,10 +7879,8 @@ msgid "123.45 EUR"
|
|||||||
msgstr "123.45 BRL"
|
msgstr "123.45 BRL"
|
||||||
|
|
||||||
#: pretix/base/pdf.py:166
|
#: pretix/base/pdf.py:166
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Price including add-ons"
|
|
||||||
msgid "Price including bundled products"
|
msgid "Price including bundled products"
|
||||||
msgstr "Preço incluindo complementos"
|
msgstr "Preços incluindo produtos empacotados"
|
||||||
|
|
||||||
#: pretix/base/pdf.py:175
|
#: pretix/base/pdf.py:175
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -9878,10 +9843,8 @@ msgid "Require a phone number per order"
|
|||||||
msgstr "Exigir um número de telefone por pedido"
|
msgstr "Exigir um número de telefone por pedido"
|
||||||
|
|
||||||
#: pretix/base/settings.py:482
|
#: pretix/base/settings.py:482
|
||||||
#, fuzzy
|
|
||||||
#| msgid "including all taxes"
|
|
||||||
msgid "Rounding of taxes"
|
msgid "Rounding of taxes"
|
||||||
msgstr "incluindo todos os impostos"
|
msgstr "Arredondamento dos impostos"
|
||||||
|
|
||||||
#: pretix/base/settings.py:486
|
#: pretix/base/settings.py:486
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -10424,18 +10387,12 @@ msgid "Automatic, but prefer invoice date over event date"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/base/settings.py:1142 pretix/base/settings.py:1153
|
#: pretix/base/settings.py:1142 pretix/base/settings.py:1153
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "invoice"
|
|
||||||
#| msgid "Invoice date"
|
|
||||||
msgid "Invoice date"
|
msgid "Invoice date"
|
||||||
msgstr "Data da fatura"
|
msgstr "Data da fatura"
|
||||||
|
|
||||||
#: pretix/base/settings.py:1146
|
#: pretix/base/settings.py:1146
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "subevent"
|
|
||||||
#| msgid "Date ordering"
|
|
||||||
msgid "Date of service"
|
msgid "Date of service"
|
||||||
msgstr "Ordenação de datas"
|
msgstr "Data do serviço"
|
||||||
|
|
||||||
#: pretix/base/settings.py:1155
|
#: pretix/base/settings.py:1155
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -11299,8 +11256,8 @@ msgstr "Endereço de contato"
|
|||||||
#: pretix/base/settings.py:2161 pretix/control/forms/event.py:1824
|
#: pretix/base/settings.py:2161 pretix/control/forms/event.py:1824
|
||||||
msgid "We'll show this publicly to allow attendees to contact you."
|
msgid "We'll show this publicly to allow attendees to contact you."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Mostraremos isso publicamente para permitir que os participantes entrem em "
|
"Será exibido publicamente para que participantes possam entrar em contato "
|
||||||
"contato com você."
|
"com você."
|
||||||
|
|
||||||
#: pretix/base/settings.py:2169 pretix/control/forms/event.py:1816
|
#: pretix/base/settings.py:2169 pretix/control/forms/event.py:1816
|
||||||
msgid "Imprint URL"
|
msgid "Imprint URL"
|
||||||
@@ -12166,17 +12123,7 @@ msgid "Invoice {invoice_number}"
|
|||||||
msgstr "Fatura {invoice_number}"
|
msgstr "Fatura {invoice_number}"
|
||||||
|
|
||||||
#: pretix/base/settings.py:2789
|
#: pretix/base/settings.py:2789
|
||||||
#, fuzzy, python-brace-format
|
#, 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 ""
|
msgid ""
|
||||||
"Hello,\n"
|
"Hello,\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -12189,12 +12136,12 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Olá,\n"
|
"Olá,\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Segue anexo uma nova fatura para o pedido {code} para {evento} . Este pedido "
|
"Em anexo você encontrará uma nova fatura para o pedido {code} para {event}. "
|
||||||
"foi feito por {order_email}.\n"
|
"Este pedido foi feito por {order_email}.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Atenciosamente, \n"
|
"Atenciosamente, \n"
|
||||||
"\n"
|
"\n"
|
||||||
"Equipe organizadora de {event}"
|
"Organização {event}"
|
||||||
|
|
||||||
#: pretix/base/settings.py:2807 pretix/base/settings.py:2823
|
#: pretix/base/settings.py:2807 pretix/base/settings.py:2823
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -13256,13 +13203,13 @@ msgid "Contact:"
|
|||||||
msgstr "Contato:"
|
msgstr "Contato:"
|
||||||
|
|
||||||
#: pretix/base/templates/pretixbase/email/order_details.html:54
|
#: pretix/base/templates/pretixbase/email/order_details.html:54
|
||||||
#, fuzzy, python-format
|
#, python-format
|
||||||
#| msgid ""
|
|
||||||
#| "You are receiving this email because you placed an order for {event}."
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"You are receiving this email because you placed an order for "
|
"You are receiving this email because you placed an order for "
|
||||||
"<strong>%(event)s</strong>."
|
"<strong>%(event)s</strong>."
|
||||||
msgstr "Você está recebendo este email porque fez um pedido para {event}."
|
msgstr ""
|
||||||
|
"Você está recebendo este email por ter realizado um pedido para <strong>%"
|
||||||
|
"(event)s</strong>."
|
||||||
|
|
||||||
#: pretix/base/templates/pretixbase/email/order_details.html:93
|
#: pretix/base/templates/pretixbase/email/order_details.html:93
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/customer.html:23
|
#: pretix/control/templates/pretixcontrol/organizers/customer.html:23
|
||||||
@@ -13937,7 +13884,7 @@ msgstr "Padrão ({value})"
|
|||||||
|
|
||||||
#: pretix/control/forms/event.py:380
|
#: pretix/control/forms/event.py:380
|
||||||
msgid "The currency cannot be changed because orders already exist."
|
msgid "The currency cannot be changed because orders already exist."
|
||||||
msgstr ""
|
msgstr "A moeda não pode ser alterada pois já foram realizados pedidos."
|
||||||
|
|
||||||
#: pretix/control/forms/event.py:391 pretix/control/forms/event.py:404
|
#: pretix/control/forms/event.py:391 pretix/control/forms/event.py:404
|
||||||
msgid "Domain"
|
msgid "Domain"
|
||||||
@@ -14023,21 +13970,16 @@ msgstr ""
|
|||||||
"que o cartão-presente é emitido."
|
"que o cartão-presente é emitido."
|
||||||
|
|
||||||
#: pretix/control/forms/event.py:813
|
#: pretix/control/forms/event.py:813
|
||||||
#, fuzzy
|
|
||||||
#| msgid "including all taxes"
|
|
||||||
msgid "Prices including tax"
|
msgid "Prices including tax"
|
||||||
msgstr "incluindo todos os impostos"
|
msgstr "Preços incluindo impostos"
|
||||||
|
|
||||||
#: pretix/control/forms/event.py:814
|
#: pretix/control/forms/event.py:814
|
||||||
msgid "Recommended if you sell tickets at least partly to consumers."
|
msgid "Recommended if you sell tickets at least partly to consumers."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/control/forms/event.py:818
|
#: pretix/control/forms/event.py:818
|
||||||
#, fuzzy
|
|
||||||
#| msgctxt "reporting_timeframe"
|
|
||||||
#| msgid "All future (excluding today)"
|
|
||||||
msgid "Prices excluding tax"
|
msgid "Prices excluding tax"
|
||||||
msgstr "Todos os futuros (excluindo hoje)"
|
msgstr "Preços excluindo impostos"
|
||||||
|
|
||||||
#: pretix/control/forms/event.py:819
|
#: pretix/control/forms/event.py:819
|
||||||
msgid "Recommended only if you sell tickets primarily to business customers."
|
msgid "Recommended only if you sell tickets primarily to business customers."
|
||||||
@@ -17401,19 +17343,14 @@ msgid "Your account has been disabled."
|
|||||||
msgstr "Sua conta foi desativada."
|
msgstr "Sua conta foi desativada."
|
||||||
|
|
||||||
#: pretix/control/logdisplay.py:672
|
#: pretix/control/logdisplay.py:672
|
||||||
#, fuzzy, python-brace-format
|
#, 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}."
|
msgid "Your email address has been changed from {old_email} to {email}."
|
||||||
msgstr ""
|
msgstr "Seu endereço de email foi modificado de {old_email} para {email}."
|
||||||
"O endereço de e-mail foi alterado de \"{old_email}\" para \"{new_email}\"."
|
|
||||||
|
|
||||||
#: pretix/control/logdisplay.py:673
|
#: pretix/control/logdisplay.py:673
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid "Your email address has been updated."
|
|
||||||
msgid "Your email address {email} has been confirmed."
|
msgid "Your email address {email} has been confirmed."
|
||||||
msgstr "Seu endereço de email foi atualizado."
|
msgstr "Seu endereço de e-mail {email} foi confirmado."
|
||||||
|
|
||||||
#: pretix/control/logdisplay.py:685
|
#: pretix/control/logdisplay.py:685
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -19690,6 +19627,20 @@ msgid ""
|
|||||||
"Best regards,\n"
|
"Best regards,\n"
|
||||||
"Your pretix team\n"
|
"Your pretix team\n"
|
||||||
msgstr ""
|
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
|
#: pretix/control/templates/pretixcontrol/email/email_setup.txt:1
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -21314,10 +21265,8 @@ msgid "with custom rules"
|
|||||||
msgstr "Regras personalizadas"
|
msgstr "Regras personalizadas"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
#: pretix/control/templates/pretixcontrol/event/tax.html:110
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Base settings"
|
|
||||||
msgid "Tax settings"
|
msgid "Tax settings"
|
||||||
msgstr "Configurações base"
|
msgstr "Configurações de impostos"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:4
|
||||||
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
#: pretix/control/templates/pretixcontrol/event/tax_delete.html:6
|
||||||
@@ -21980,6 +21929,9 @@ msgid ""
|
|||||||
"your event. By default, we will only offer ticket downloads for these "
|
"your event. By default, we will only offer ticket downloads for these "
|
||||||
"products."
|
"products."
|
||||||
msgstr ""
|
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/create.html:33
|
||||||
#: pretix/control/templates/pretixcontrol/item/index.html:41
|
#: pretix/control/templates/pretixcontrol/item/index.html:41
|
||||||
@@ -26144,7 +26096,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:29
|
#: pretix/control/templates/pretixcontrol/shredder/download.html:29
|
||||||
msgid "Download data"
|
msgid "Download data"
|
||||||
msgstr ""
|
msgstr "Baixar dados"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/shredder/download.html:34
|
#: pretix/control/templates/pretixcontrol/shredder/download.html:34
|
||||||
msgid "Step 2: Confirm deletion"
|
msgid "Step 2: Confirm deletion"
|
||||||
@@ -26475,7 +26427,7 @@ msgstr "Adicionar um dispositivo de autenticação de dois fatores"
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
|
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:8
|
||||||
msgid "To set up this device, please follow the following steps:"
|
msgid "To set up this device, please follow the following steps:"
|
||||||
msgstr ""
|
msgstr "Para configurar este dispositivo, por favor siga os passos a seguir:"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:12
|
#: pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html:12
|
||||||
msgid "Download the Google Authenticator application to your phone:"
|
msgid "Download the Google Authenticator application to your phone:"
|
||||||
@@ -26901,11 +26853,11 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:6
|
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:6
|
||||||
msgid "Session notes"
|
msgid "Session notes"
|
||||||
msgstr ""
|
msgstr "Notas de sessão"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:17
|
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:17
|
||||||
msgid "Audit log"
|
msgid "Audit log"
|
||||||
msgstr ""
|
msgstr "Log de auditoria"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:30
|
#: pretix/control/templates/pretixcontrol/user/staff_session_edit.html:30
|
||||||
msgid "Method"
|
msgid "Method"
|
||||||
@@ -27949,7 +27901,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/views/item.py:237
|
#: pretix/control/views/item.py:237
|
||||||
msgid "The selected category has been deleted."
|
msgid "The selected category has been deleted."
|
||||||
msgstr ""
|
msgstr "A categoria selecionada foi excluída"
|
||||||
|
|
||||||
#: pretix/control/views/item.py:322
|
#: pretix/control/views/item.py:322
|
||||||
msgid "The new category has been created."
|
msgid "The new category has been created."
|
||||||
@@ -29874,7 +29826,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/plugins/banktransfer/payment.py:239
|
#: pretix/plugins/banktransfer/payment.py:239
|
||||||
msgid "Please fill out your bank account details."
|
msgid "Please fill out your bank account details."
|
||||||
msgstr ""
|
msgstr "Por favor, preencha os detalhes da sua conta bancária."
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/payment.py:243
|
#: pretix/plugins/banktransfer/payment.py:243
|
||||||
msgid "Please enter your bank account details."
|
msgid "Please enter your bank account details."
|
||||||
@@ -30175,7 +30127,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:122
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/pending.html:122
|
||||||
msgid "Scan the QR code with your banking app"
|
msgid "Scan the QR code with your banking app"
|
||||||
msgstr ""
|
msgstr "Escanear o QR Code com o seu aplicativo bancário"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:5
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:5
|
||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:7
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/refund_export.html:7
|
||||||
@@ -30746,6 +30698,8 @@ msgid ""
|
|||||||
"We're waiting for an answer from PayPal regarding your payment. Please "
|
"We're waiting for an answer from PayPal regarding your payment. Please "
|
||||||
"contact us, if this takes more than a few hours."
|
"contact us, if this takes more than a few hours."
|
||||||
msgstr ""
|
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/paypal/templates/pretixplugins/paypal/redirect.html:17
|
||||||
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/redirect.html:17
|
#: pretix/plugins/paypal2/templates/pretixplugins/paypal2/redirect.html:17
|
||||||
@@ -33370,19 +33324,17 @@ msgstr "Organizador: {organizer}"
|
|||||||
#: pretix/presale/ical.py:139
|
#: pretix/presale/ical.py:139
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{event} - {item}"
|
msgid "{event} - {item}"
|
||||||
msgstr ""
|
msgstr "{event} - {item}"
|
||||||
|
|
||||||
#: pretix/presale/ical.py:147
|
#: pretix/presale/ical.py:147
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid "Start date"
|
|
||||||
msgid "Start: {datetime}"
|
msgid "Start: {datetime}"
|
||||||
msgstr "Data inicial"
|
msgstr "Início: {datetime}"
|
||||||
|
|
||||||
#: pretix/presale/ical.py:150
|
#: pretix/presale/ical.py:150
|
||||||
#, fuzzy, python-brace-format
|
#, python-brace-format
|
||||||
#| msgid "Admission: {datetime}"
|
|
||||||
msgid "End: {datetime}"
|
msgid "End: {datetime}"
|
||||||
msgstr "Admissão: {datetime}"
|
msgstr "Término: {datetime}"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/base.html:44
|
#: pretix/presale/templates/pretixpresale/base.html:44
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -33774,12 +33726,11 @@ msgstr "Selecione como deseja pagar o saldo restante:"
|
|||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:82
|
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:82
|
||||||
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:45
|
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:45
|
||||||
#, fuzzy, python-format
|
#, python-format
|
||||||
#| msgid "%(num)s available"
|
|
||||||
msgid "(%(count)s available)"
|
msgid "(%(count)s available)"
|
||||||
msgid_plural "(%(count)s available)"
|
msgid_plural "(%(count)s available)"
|
||||||
msgstr[0] "%(num)s disponíveis"
|
msgstr[0] "(%(count)s disponível)"
|
||||||
msgstr[1] "%(num)s disponíveis"
|
msgstr[1] "(%(count)s disponíveis)"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:101
|
#: pretix/presale/templates/pretixpresale/event/checkout_payment.html:101
|
||||||
msgid "This sales channel does not provide support for test mode."
|
msgid "This sales channel does not provide support for test mode."
|
||||||
@@ -34558,13 +34509,11 @@ 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:131
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:288
|
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:288
|
||||||
#, fuzzy, python-format
|
#, python-format
|
||||||
#| msgid "%(count)s event"
|
|
||||||
#| msgid_plural "%(count)s events"
|
|
||||||
msgid "%(amount)s× in your cart"
|
msgid "%(amount)s× in your cart"
|
||||||
msgid_plural "%(amount)s× in your cart"
|
msgid_plural "%(amount)s× in your cart"
|
||||||
msgstr[0] "%(count)s evento"
|
msgstr[0] "%(amount)s× no seu carrinho"
|
||||||
msgstr[1] "%(count)s events"
|
msgstr[1] "%(amount)s× no seu carrinho"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:209
|
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:209
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:374
|
#: pretix/presale/templates/pretixpresale/event/fragment_product_list.html:374
|
||||||
@@ -35632,10 +35581,8 @@ msgid "The following gift cards are available in your customer account:"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/giftcard/checkout.html:24
|
#: pretix/presale/templates/pretixpresale/giftcard/checkout.html:24
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Issued gift cards"
|
|
||||||
msgid "Use gift card"
|
msgid "Use gift card"
|
||||||
msgstr "Cartões-presente emitidos"
|
msgstr "Usar cartão-presente"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/giftcard/checkout_confirm.html:4
|
#: pretix/presale/templates/pretixpresale/giftcard/checkout_confirm.html:4
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -35652,7 +35599,7 @@ msgid ""
|
|||||||
"This is a self-hosted installation of <a %(a_attr)s>pretix, your free and "
|
"This is a self-hosted installation of <a %(a_attr)s>pretix, your free and "
|
||||||
"open source ticket sales software</a>."
|
"open source ticket sales software</a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Está é uma instalação self-hosted do <a %(a_attr)s>pretix, seu aplicativo "
|
"Esta é uma instalação auto-hospedada do <a %(a_attr)s>pretix, seu aplicativo "
|
||||||
"livre e de código aberto para venda de ingressos.</a>."
|
"livre e de código aberto para venda de ingressos.</a>."
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/index.html:15
|
#: pretix/presale/templates/pretixpresale/index.html:15
|
||||||
@@ -35748,22 +35695,18 @@ msgid "Issued on %(date)s"
|
|||||||
msgstr "Leitura negada: %(date)s"
|
msgstr "Leitura negada: %(date)s"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:38
|
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:38
|
||||||
#, fuzzy, python-format
|
#, python-format
|
||||||
#| msgid "Expired since"
|
|
||||||
msgid "Expired since %(date)s"
|
msgid "Expired since %(date)s"
|
||||||
msgstr "Expirado desde"
|
msgstr "Expirado desde %(date)s"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:46
|
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:46
|
||||||
#, fuzzy, python-format
|
#, python-format
|
||||||
#| msgid "Valid until %(datetime)s"
|
|
||||||
msgid "Valid until %(date)s"
|
msgid "Valid until %(date)s"
|
||||||
msgstr "Válido até %(datetime)s"
|
msgstr "Válido até %(date)s"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:66
|
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:66
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Remaining balance"
|
|
||||||
msgid "Remaining value:"
|
msgid "Remaining value:"
|
||||||
msgstr "Saldo restante"
|
msgstr "Valor restante:"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:76
|
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:76
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
@@ -36287,10 +36230,8 @@ msgid "The selected date does not exist in this event series."
|
|||||||
msgstr "A data selecionada não existe nesta série de eventos."
|
msgstr "A data selecionada não existe nesta série de eventos."
|
||||||
|
|
||||||
#: pretix/presale/views/widget.py:412
|
#: pretix/presale/views/widget.py:412
|
||||||
#, fuzzy
|
|
||||||
#| msgid "The selected seat \"{seat}\" is not available."
|
|
||||||
msgid "The selected date is not available."
|
msgid "The selected date is not available."
|
||||||
msgstr "O assento selecionado \"{seat}\" não está disponível."
|
msgstr "A data selecionada não está disponível."
|
||||||
|
|
||||||
#: pretix/presale/views/widget.py:476
|
#: pretix/presale/views/widget.py:476
|
||||||
#, python-format
|
#, python-format
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
|
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
|
||||||
"PO-Revision-Date: 2025-08-28 13:43+0000\n"
|
"PO-Revision-Date: 2025-12-09 00:47+0000\n"
|
||||||
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
|
"Last-Translator: Renne Rocha <renne@rocha.dev.br>\n"
|
||||||
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
||||||
"pretix/pretix-js/pt_BR/>\n"
|
"pretix/pretix-js/pt_BR/>\n"
|
||||||
@@ -17,7 +17,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||||
"X-Generator: Weblate 5.13\n"
|
"X-Generator: Weblate 5.14.3\n"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
#: 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:62
|
||||||
@@ -566,11 +566,11 @@ msgstr "ausente"
|
|||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:289
|
||||||
msgid "Error: Product not found!"
|
msgid "Error: Product not found!"
|
||||||
msgstr ""
|
msgstr "Erro: Produto não encontrado!"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
|
#: pretix/static/pretixcontrol/js/ui/checkinrules.js:296
|
||||||
msgid "Error: Variation not found!"
|
msgid "Error: Variation not found!"
|
||||||
msgstr ""
|
msgstr "Erro: Variação não encontrada!"
|
||||||
|
|
||||||
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
#: pretix/static/pretixcontrol/js/ui/editor.js:171
|
||||||
msgid "Check-in QR"
|
msgid "Check-in QR"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
|
"POT-Creation-Date: 2025-11-20 10:37+0000\n"
|
||||||
"PO-Revision-Date: 2025-11-11 21:00+0000\n"
|
"PO-Revision-Date: 2025-12-10 15:49+0000\n"
|
||||||
"Last-Translator: Ana Rute Pacheco Vivas <rute.vivas@om.org>\n"
|
"Last-Translator: Ana Rute Pacheco Vivas <rute.vivas@om.org>\n"
|
||||||
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
|
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
|
||||||
"pretix/pretix-js/pt_PT/>\n"
|
"pretix/pretix-js/pt_PT/>\n"
|
||||||
@@ -798,7 +798,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/cart.js:90
|
#: pretix/static/pretixpresale/js/ui/cart.js:90
|
||||||
msgid "Renew reservation"
|
msgid "Renew reservation"
|
||||||
msgstr ""
|
msgstr "Renovar a reserva"
|
||||||
|
|
||||||
#: pretix/static/pretixpresale/js/ui/main.js:194
|
#: pretix/static/pretixpresale/js/ui/main.js:194
|
||||||
msgid "The organizer keeps %(currency)s %(amount)s"
|
msgid "The organizer keeps %(currency)s %(amount)s"
|
||||||
|
|||||||
@@ -8,34 +8,36 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
"POT-Creation-Date: 2025-11-27 13:57+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: 2025-12-14 00:00+0000\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Lachlan Struthers <lachlan.struthers@om.org>\n"
|
||||||
"Language-Team: none\n"
|
"Language-Team: Albanian <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||||
|
"sq/>\n"
|
||||||
"Language: sq\n"
|
"Language: sq\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
|
"X-Generator: Weblate 5.14.3\n"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:87
|
#: pretix/_base_settings.py:87
|
||||||
msgid "English"
|
msgid "English"
|
||||||
msgstr ""
|
msgstr "Anglisht"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:88
|
#: pretix/_base_settings.py:88
|
||||||
msgid "German"
|
msgid "German"
|
||||||
msgstr ""
|
msgstr "Gjermanisht"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:89
|
#: pretix/_base_settings.py:89
|
||||||
msgid "German (informal)"
|
msgid "German (informal)"
|
||||||
msgstr ""
|
msgstr "Gjermanisht (joformale)"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:90
|
#: pretix/_base_settings.py:90
|
||||||
msgid "Arabic"
|
msgid "Arabic"
|
||||||
msgstr ""
|
msgstr "Arabisht"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:91
|
#: pretix/_base_settings.py:91
|
||||||
msgid "Basque"
|
msgid "Basque"
|
||||||
msgstr ""
|
msgstr "Baskisht"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:92
|
#: pretix/_base_settings.py:92
|
||||||
msgid "Catalan"
|
msgid "Catalan"
|
||||||
@@ -450,7 +452,7 @@ msgstr ""
|
|||||||
#: pretix/control/templates/pretixcontrol/event/mail.html:114
|
#: pretix/control/templates/pretixcontrol/event/mail.html:114
|
||||||
#: pretix/control/views/orders.py:1569
|
#: pretix/control/views/orders.py:1569
|
||||||
msgid "Order canceled"
|
msgid "Order canceled"
|
||||||
msgstr ""
|
msgstr "Porositja ësthë anuluar"
|
||||||
|
|
||||||
#: pretix/api/webhooks.py:278 pretix/base/notifications.py:257
|
#: pretix/api/webhooks.py:278 pretix/base/notifications.py:257
|
||||||
msgid "Order reactivated"
|
msgid "Order reactivated"
|
||||||
@@ -1407,7 +1409,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/checkinlists/exporters.py:827
|
#: pretix/plugins/checkinlists/exporters.py:827
|
||||||
#: pretix/plugins/checkinlists/exporters.py:828
|
#: pretix/plugins/checkinlists/exporters.py:828
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr ""
|
msgstr "Po"
|
||||||
|
|
||||||
#: pretix/base/exporters/customers.py:100
|
#: pretix/base/exporters/customers.py:100
|
||||||
#: pretix/base/exporters/customers.py:101 pretix/base/exporters/events.py:83
|
#: pretix/base/exporters/customers.py:101 pretix/base/exporters/events.py:83
|
||||||
@@ -1431,7 +1433,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/checkinlists/exporters.py:827
|
#: pretix/plugins/checkinlists/exporters.py:827
|
||||||
#: pretix/plugins/checkinlists/exporters.py:828
|
#: pretix/plugins/checkinlists/exporters.py:828
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr ""
|
msgstr "Jo"
|
||||||
|
|
||||||
#: pretix/base/exporters/dekodi.py:42 pretix/base/exporters/invoices.py:66
|
#: pretix/base/exporters/dekodi.py:42 pretix/base/exporters/invoices.py:66
|
||||||
msgctxt "export_category"
|
msgctxt "export_category"
|
||||||
@@ -2445,7 +2447,7 @@ msgstr ""
|
|||||||
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:12
|
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:12
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:91
|
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:91
|
||||||
msgid "Product"
|
msgid "Product"
|
||||||
msgstr ""
|
msgstr "Produkti"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:619 pretix/base/models/vouchers.py:315
|
#: pretix/base/exporters/orderlist.py:619 pretix/base/models/vouchers.py:315
|
||||||
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:5
|
#: pretix/control/templates/pretixcontrol/vouchers/bulk.html:5
|
||||||
@@ -2783,7 +2785,7 @@ msgstr ""
|
|||||||
#: pretix/control/templates/pretixcontrol/event/cancel.html:20
|
#: pretix/control/templates/pretixcontrol/event/cancel.html:20
|
||||||
#: pretix/control/views/item.py:971
|
#: pretix/control/views/item.py:971
|
||||||
msgid "Paid orders"
|
msgid "Paid orders"
|
||||||
msgstr ""
|
msgstr "Porositje të paguara"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:1155 pretix/control/views/item.py:976
|
#: pretix/base/exporters/orderlist.py:1155 pretix/control/views/item.py:976
|
||||||
msgid "Pending orders"
|
msgid "Pending orders"
|
||||||
@@ -2952,7 +2954,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/reports/accountingreport.py:105
|
#: pretix/plugins/reports/accountingreport.py:105
|
||||||
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:67
|
#: pretix/plugins/sendmail/templates/pretixplugins/sendmail/rule_list.html:67
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr ""
|
msgstr "Të gjitha"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:1329 pretix/control/forms/filter.py:1450
|
#: pretix/base/exporters/orderlist.py:1329 pretix/control/forms/filter.py:1450
|
||||||
msgid "Live"
|
msgid "Live"
|
||||||
@@ -3879,7 +3881,7 @@ msgstr ""
|
|||||||
#: pretix/base/modelimport_vouchers.py:205 pretix/base/models/items.py:1256
|
#: pretix/base/modelimport_vouchers.py:205 pretix/base/models/items.py:1256
|
||||||
#: pretix/base/models/vouchers.py:266 pretix/base/models/waitinglist.py:99
|
#: pretix/base/models/vouchers.py:266 pretix/base/models/waitinglist.py:99
|
||||||
msgid "Product variation"
|
msgid "Product variation"
|
||||||
msgstr ""
|
msgstr "Varianti i produktit"
|
||||||
|
|
||||||
#: pretix/base/modelimport_orders.py:161
|
#: pretix/base/modelimport_orders.py:161
|
||||||
msgid "The variation can be specified by its internal ID or full name."
|
msgid "The variation can be specified by its internal ID or full name."
|
||||||
@@ -4278,19 +4280,19 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/base/models/checkin.py:336
|
#: pretix/base/models/checkin.py:336
|
||||||
msgid "Entry"
|
msgid "Entry"
|
||||||
msgstr ""
|
msgstr "Hyrje"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:337
|
#: pretix/base/models/checkin.py:337
|
||||||
msgid "Exit"
|
msgid "Exit"
|
||||||
msgstr ""
|
msgstr "Dalje"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:356
|
#: pretix/base/models/checkin.py:356
|
||||||
msgid "Unknown ticket"
|
msgid "Unknown ticket"
|
||||||
msgstr ""
|
msgstr "Biletë e panjohur"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:357
|
#: pretix/base/models/checkin.py:357
|
||||||
msgid "Ticket not paid"
|
msgid "Ticket not paid"
|
||||||
msgstr ""
|
msgstr "Bileta nuk është paguar"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:358
|
#: pretix/base/models/checkin.py:358
|
||||||
msgid "Forbidden by custom rule"
|
msgid "Forbidden by custom rule"
|
||||||
@@ -4298,23 +4300,23 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/base/models/checkin.py:359
|
#: pretix/base/models/checkin.py:359
|
||||||
msgid "Ticket code revoked/changed"
|
msgid "Ticket code revoked/changed"
|
||||||
msgstr ""
|
msgstr "Kodi i biletës është anuluar/ndryshuar"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:360
|
#: pretix/base/models/checkin.py:360
|
||||||
msgid "Information required"
|
msgid "Information required"
|
||||||
msgstr ""
|
msgstr "Informacion i domosdoshëm"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:361
|
#: pretix/base/models/checkin.py:361
|
||||||
msgid "Ticket already used"
|
msgid "Ticket already used"
|
||||||
msgstr ""
|
msgstr "Bileta tashmë është përdorur"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:362
|
#: pretix/base/models/checkin.py:362
|
||||||
msgid "Ticket type not allowed here"
|
msgid "Ticket type not allowed here"
|
||||||
msgstr ""
|
msgstr "Ky lloj bilete nuk lejohet këtu"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:363
|
#: pretix/base/models/checkin.py:363
|
||||||
msgid "Ticket code is ambiguous on list"
|
msgid "Ticket code is ambiguous on list"
|
||||||
msgstr ""
|
msgstr "Kodi i biletës është e paqartë në listë"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:364
|
#: pretix/base/models/checkin.py:364
|
||||||
msgid "Server error"
|
msgid "Server error"
|
||||||
@@ -4322,15 +4324,15 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/base/models/checkin.py:365
|
#: pretix/base/models/checkin.py:365
|
||||||
msgid "Ticket blocked"
|
msgid "Ticket blocked"
|
||||||
msgstr ""
|
msgstr "Bileta u bllokua"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:366
|
#: pretix/base/models/checkin.py:366
|
||||||
msgid "Order not approved"
|
msgid "Order not approved"
|
||||||
msgstr ""
|
msgstr "Porositje nuk është aprovuar"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:367
|
#: pretix/base/models/checkin.py:367
|
||||||
msgid "Ticket not valid at this time"
|
msgid "Ticket not valid at this time"
|
||||||
msgstr ""
|
msgstr "Bileta nuk është e vlefshme për momentin"
|
||||||
|
|
||||||
#: pretix/base/models/checkin.py:368
|
#: pretix/base/models/checkin.py:368
|
||||||
msgid "Check-in annulled"
|
msgid "Check-in annulled"
|
||||||
@@ -4460,7 +4462,7 @@ msgstr ""
|
|||||||
#: pretix/control/templates/pretixcontrol/organizers/gates.html:16
|
#: pretix/control/templates/pretixcontrol/organizers/gates.html:16
|
||||||
#: pretix/plugins/checkinlists/exporters.py:769
|
#: pretix/plugins/checkinlists/exporters.py:769
|
||||||
msgid "Gate"
|
msgid "Gate"
|
||||||
msgstr ""
|
msgstr "Porta"
|
||||||
|
|
||||||
#: pretix/base/models/devices.py:131
|
#: pretix/base/models/devices.py:131
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/devices.html:83
|
#: pretix/control/templates/pretixcontrol/organizers/devices.html:83
|
||||||
@@ -5928,7 +5930,7 @@ msgstr ""
|
|||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:34
|
#: pretix/presale/templates/pretixpresale/organizers/customer_membership.html:34
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:44
|
#: pretix/presale/templates/pretixpresale/organizers/customer_memberships.html:44
|
||||||
msgid "Canceled"
|
msgid "Canceled"
|
||||||
msgstr ""
|
msgstr "e anuluar"
|
||||||
|
|
||||||
#: pretix/base/models/memberships.py:134
|
#: pretix/base/models/memberships.py:134
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/customer.html:117
|
#: pretix/control/templates/pretixcontrol/organizers/customer.html:117
|
||||||
@@ -6671,7 +6673,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/base/models/vouchers.py:204 pretix/control/views/vouchers.py:120
|
#: pretix/base/models/vouchers.py:204 pretix/control/views/vouchers.py:120
|
||||||
msgid "Redeemed"
|
msgid "Redeemed"
|
||||||
msgstr ""
|
msgstr "e përdorur"
|
||||||
|
|
||||||
#: pretix/base/models/vouchers.py:209
|
#: pretix/base/models/vouchers.py:209
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -7432,7 +7434,7 @@ msgstr ""
|
|||||||
#: pretix/base/pdf.py:278 pretix/base/pdf.py:307
|
#: pretix/base/pdf.py:278 pretix/base/pdf.py:307
|
||||||
#: pretix/base/services/checkin.py:362 pretix/control/forms/filter.py:1271
|
#: pretix/base/services/checkin.py:362 pretix/control/forms/filter.py:1271
|
||||||
msgid "Friday"
|
msgid "Friday"
|
||||||
msgstr ""
|
msgstr "E Premte"
|
||||||
|
|
||||||
#: pretix/base/pdf.py:282
|
#: pretix/base/pdf.py:282
|
||||||
msgid "Event end date and time"
|
msgid "Event end date and time"
|
||||||
@@ -7704,15 +7706,15 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/base/reldate.py:38
|
#: pretix/base/reldate.py:38
|
||||||
msgid "Event start"
|
msgid "Event start"
|
||||||
msgstr ""
|
msgstr "Fillimi i eventit"
|
||||||
|
|
||||||
#: pretix/base/reldate.py:39
|
#: pretix/base/reldate.py:39
|
||||||
msgid "Event end"
|
msgid "Event end"
|
||||||
msgstr ""
|
msgstr "Mbarimi i eventit"
|
||||||
|
|
||||||
#: pretix/base/reldate.py:40
|
#: pretix/base/reldate.py:40
|
||||||
msgid "Event admission"
|
msgid "Event admission"
|
||||||
msgstr ""
|
msgstr "Hyrja në event"
|
||||||
|
|
||||||
#: pretix/base/reldate.py:41
|
#: pretix/base/reldate.py:41
|
||||||
msgid "Presale start"
|
msgid "Presale start"
|
||||||
@@ -8130,27 +8132,27 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/base/services/checkin.py:358 pretix/control/forms/filter.py:1267
|
#: pretix/base/services/checkin.py:358 pretix/control/forms/filter.py:1267
|
||||||
msgid "Monday"
|
msgid "Monday"
|
||||||
msgstr ""
|
msgstr "E Hënë"
|
||||||
|
|
||||||
#: pretix/base/services/checkin.py:359 pretix/control/forms/filter.py:1268
|
#: pretix/base/services/checkin.py:359 pretix/control/forms/filter.py:1268
|
||||||
msgid "Tuesday"
|
msgid "Tuesday"
|
||||||
msgstr ""
|
msgstr "E Martë"
|
||||||
|
|
||||||
#: pretix/base/services/checkin.py:360 pretix/control/forms/filter.py:1269
|
#: pretix/base/services/checkin.py:360 pretix/control/forms/filter.py:1269
|
||||||
msgid "Wednesday"
|
msgid "Wednesday"
|
||||||
msgstr ""
|
msgstr "E Mërkurë"
|
||||||
|
|
||||||
#: pretix/base/services/checkin.py:361 pretix/control/forms/filter.py:1270
|
#: pretix/base/services/checkin.py:361 pretix/control/forms/filter.py:1270
|
||||||
msgid "Thursday"
|
msgid "Thursday"
|
||||||
msgstr ""
|
msgstr "E Enjte"
|
||||||
|
|
||||||
#: pretix/base/services/checkin.py:363 pretix/control/forms/filter.py:1272
|
#: pretix/base/services/checkin.py:363 pretix/control/forms/filter.py:1272
|
||||||
msgid "Saturday"
|
msgid "Saturday"
|
||||||
msgstr ""
|
msgstr "E Shtunë"
|
||||||
|
|
||||||
#: pretix/base/services/checkin.py:364 pretix/control/forms/filter.py:1273
|
#: pretix/base/services/checkin.py:364 pretix/control/forms/filter.py:1273
|
||||||
msgid "Sunday"
|
msgid "Sunday"
|
||||||
msgstr ""
|
msgstr "E Diel"
|
||||||
|
|
||||||
#: pretix/base/services/checkin.py:368
|
#: pretix/base/services/checkin.py:368
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -12889,7 +12891,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/reports/exporters.py:391
|
#: pretix/plugins/reports/exporters.py:391
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7
|
#: pretix/presale/templates/pretixpresale/event/fragment_order_status.html:7
|
||||||
msgid "Approval pending"
|
msgid "Approval pending"
|
||||||
msgstr ""
|
msgstr "Duke pritur aprovimin"
|
||||||
|
|
||||||
#: pretix/control/forms/filter.py:247
|
#: pretix/control/forms/filter.py:247
|
||||||
msgid "Follow-up configured"
|
msgid "Follow-up configured"
|
||||||
@@ -13042,7 +13044,7 @@ msgstr ""
|
|||||||
#: pretix/control/forms/filter.py:2052 pretix/control/forms/filter.py:2054
|
#: pretix/control/forms/filter.py:2052 pretix/control/forms/filter.py:2054
|
||||||
#: pretix/control/forms/filter.py:2620 pretix/control/forms/filter.py:2622
|
#: pretix/control/forms/filter.py:2620 pretix/control/forms/filter.py:2622
|
||||||
msgid "Search query"
|
msgid "Search query"
|
||||||
msgstr ""
|
msgstr "Kërkim"
|
||||||
|
|
||||||
#: pretix/control/forms/filter.py:1528 pretix/control/forms/filter.py:1600
|
#: pretix/control/forms/filter.py:1528 pretix/control/forms/filter.py:1600
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/customer.html:47
|
#: pretix/control/templates/pretixcontrol/organizers/customer.html:47
|
||||||
@@ -13157,7 +13159,7 @@ msgstr ""
|
|||||||
#: pretix/control/forms/filter.py:2117
|
#: pretix/control/forms/filter.py:2117
|
||||||
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:51
|
#: pretix/presale/templates/pretixpresale/organizers/customer_giftcards.html:51
|
||||||
msgid "Valid"
|
msgid "Valid"
|
||||||
msgstr ""
|
msgstr "e vlefshme"
|
||||||
|
|
||||||
#: pretix/control/forms/filter.py:2118
|
#: pretix/control/forms/filter.py:2118
|
||||||
msgid "Unredeemed"
|
msgid "Unredeemed"
|
||||||
@@ -16427,7 +16429,7 @@ msgstr ""
|
|||||||
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:75
|
#: pretix/presale/templates/pretixpresale/event/order_pay_change.html:75
|
||||||
#: pretix/presale/templates/pretixpresale/event/position_change.html:29
|
#: pretix/presale/templates/pretixpresale/event/position_change.html:29
|
||||||
msgid "Continue"
|
msgid "Continue"
|
||||||
msgstr ""
|
msgstr "Vazhdoni"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html:8
|
#: pretix/control/templates/pretixcontrol/auth/oauth_authorization.html:8
|
||||||
msgid "Authorize an application"
|
msgid "Authorize an application"
|
||||||
@@ -16675,7 +16677,7 @@ msgstr ""
|
|||||||
#: pretix/presale/templates/pretixpresale/postmessage.html:27
|
#: pretix/presale/templates/pretixpresale/postmessage.html:27
|
||||||
#: pretix/presale/templates/pretixpresale/waiting.html:42
|
#: pretix/presale/templates/pretixpresale/waiting.html:42
|
||||||
msgid "If this takes longer than a few minutes, please contact us."
|
msgid "If this takes longer than a few minutes, please contact us."
|
||||||
msgstr ""
|
msgstr "Nëse kalon më shumë se disa minuta, ju lutemi t'na kontaktoni."
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:4
|
#: pretix/control/templates/pretixcontrol/boxoffice/payment.html:4
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/devices.html:71
|
#: pretix/control/templates/pretixcontrol/organizers/devices.html:71
|
||||||
@@ -16905,7 +16907,7 @@ msgstr[1] ""
|
|||||||
#: pretix/presale/templates/pretixpresale/event/position_change.html:24
|
#: pretix/presale/templates/pretixpresale/event/position_change.html:24
|
||||||
#: pretix/presale/templates/pretixpresale/event/position_modify.html:44
|
#: pretix/presale/templates/pretixpresale/event/position_modify.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr "Anuloni"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:27
|
#: pretix/control/templates/pretixcontrol/checkin/bulk_revert_confirm.html:27
|
||||||
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html:24
|
#: pretix/control/templates/pretixcontrol/checkin/list_delete.html:24
|
||||||
@@ -17019,7 +17021,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:14
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:14
|
||||||
#: pretix/plugins/checkinlists/exporters.py:770
|
#: pretix/plugins/checkinlists/exporters.py:770
|
||||||
msgid "Result"
|
msgid "Result"
|
||||||
msgstr ""
|
msgstr "Rezultati"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:78
|
#: pretix/control/templates/pretixcontrol/checkin/checkins.html:78
|
||||||
#: pretix/control/templates/pretixcontrol/order/index.html:437
|
#: pretix/control/templates/pretixcontrol/order/index.html:437
|
||||||
@@ -17363,7 +17365,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:68
|
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:68
|
||||||
msgid "Additional information required"
|
msgid "Additional information required"
|
||||||
msgstr ""
|
msgstr "Më shumë informacione kërkohen"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:70
|
#: pretix/control/templates/pretixcontrol/checkin/simulator.html:70
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -18272,7 +18274,7 @@ msgstr ""
|
|||||||
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html:50
|
#: pretix/control/templates/pretixcontrol/organizers/device_logs.html:50
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/logs.html:80
|
#: pretix/control/templates/pretixcontrol/organizers/logs.html:80
|
||||||
msgid "No results"
|
msgid "No results"
|
||||||
msgstr ""
|
msgstr "S'ka rezultate"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/event/mail.html:7
|
#: pretix/control/templates/pretixcontrol/event/mail.html:7
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/mail.html:11
|
#: pretix/control/templates/pretixcontrol/organizers/mail.html:11
|
||||||
@@ -18477,7 +18479,7 @@ msgstr ""
|
|||||||
#: pretix/control/templates/pretixcontrol/event/plugins.html:34
|
#: pretix/control/templates/pretixcontrol/event/plugins.html:34
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/plugins.html:34
|
#: pretix/control/templates/pretixcontrol/organizers/plugins.html:34
|
||||||
msgid "Search results"
|
msgid "Search results"
|
||||||
msgstr ""
|
msgstr "Rezultatet e kërkimit"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/event/plugins.html:56
|
#: pretix/control/templates/pretixcontrol/event/plugins.html:56
|
||||||
#: pretix/control/templates/pretixcontrol/organizers/plugins.html:56
|
#: pretix/control/templates/pretixcontrol/organizers/plugins.html:56
|
||||||
@@ -19324,51 +19326,51 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:16
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:16
|
||||||
msgid "January"
|
msgid "January"
|
||||||
msgstr ""
|
msgstr "Janar"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:17
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:17
|
||||||
msgid "February"
|
msgid "February"
|
||||||
msgstr ""
|
msgstr "Shkurt"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:18
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:18
|
||||||
msgid "March"
|
msgid "March"
|
||||||
msgstr ""
|
msgstr "Mars"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:19
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:19
|
||||||
msgid "April"
|
msgid "April"
|
||||||
msgstr ""
|
msgstr "Prill"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:20
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:20
|
||||||
msgid "May"
|
msgid "May"
|
||||||
msgstr ""
|
msgstr "Maj"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:21
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:21
|
||||||
msgid "June"
|
msgid "June"
|
||||||
msgstr ""
|
msgstr "Qershor"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:22
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:22
|
||||||
msgid "July"
|
msgid "July"
|
||||||
msgstr ""
|
msgstr "Korrik"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:23
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:23
|
||||||
msgid "August"
|
msgid "August"
|
||||||
msgstr ""
|
msgstr "Gusht"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:24
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:24
|
||||||
msgid "September"
|
msgid "September"
|
||||||
msgstr ""
|
msgstr "Shtator"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:25
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:25
|
||||||
msgid "October"
|
msgid "October"
|
||||||
msgstr ""
|
msgstr "Tetor"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:26
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:26
|
||||||
msgid "November"
|
msgid "November"
|
||||||
msgstr ""
|
msgstr "Nëntor"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:27
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:27
|
||||||
msgid "December"
|
msgid "December"
|
||||||
msgstr ""
|
msgstr "Dhjetor"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/global_sysreport.html:32
|
#: pretix/control/templates/pretixcontrol/global_sysreport.html:32
|
||||||
msgid "Generate report"
|
msgid "Generate report"
|
||||||
@@ -19743,7 +19745,7 @@ msgstr ""
|
|||||||
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:355
|
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:355
|
||||||
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:364
|
#: pretix/control/templates/pretixcontrol/subevents/bulk.html:364
|
||||||
msgid "minutes"
|
msgid "minutes"
|
||||||
msgstr ""
|
msgstr "minuta"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/item/index.html:229
|
#: pretix/control/templates/pretixcontrol/item/index.html:229
|
||||||
msgid "hours"
|
msgid "hours"
|
||||||
@@ -20096,7 +20098,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/items/question.html:91
|
#: pretix/control/templates/pretixcontrol/items/question.html:91
|
||||||
msgid "Count"
|
msgid "Count"
|
||||||
msgstr ""
|
msgstr "Sasia"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/items/question.html:92
|
#: pretix/control/templates/pretixcontrol/items/question.html:92
|
||||||
#, python-format
|
#, python-format
|
||||||
@@ -21014,7 +21016,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/reports/exporters.py:969
|
#: pretix/plugins/reports/exporters.py:969
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:469
|
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:469
|
||||||
msgid "Total"
|
msgid "Total"
|
||||||
msgstr ""
|
msgstr "Shuma totale"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/order/index.html:789
|
#: pretix/control/templates/pretixcontrol/order/index.html:789
|
||||||
#: pretix/presale/templates/pretixpresale/event/order.html:210
|
#: pretix/presale/templates/pretixpresale/event/order.html:210
|
||||||
@@ -23096,7 +23098,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/pdf/index.html:52
|
#: pretix/control/templates/pretixcontrol/pdf/index.html:52
|
||||||
msgid "Text box"
|
msgid "Text box"
|
||||||
msgstr ""
|
msgstr "Kutia teksti"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/pdf/index.html:59
|
#: pretix/control/templates/pretixcontrol/pdf/index.html:59
|
||||||
msgid "QR Code"
|
msgid "QR Code"
|
||||||
@@ -23135,7 +23137,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/pdf/index.html:107
|
#: pretix/control/templates/pretixcontrol/pdf/index.html:107
|
||||||
msgid "Duplicate"
|
msgid "Duplicate"
|
||||||
msgstr ""
|
msgstr "Kopjoni"
|
||||||
|
|
||||||
#: pretix/control/templates/pretixcontrol/pdf/index.html:117
|
#: pretix/control/templates/pretixcontrol/pdf/index.html:117
|
||||||
msgid "Undo"
|
msgid "Undo"
|
||||||
@@ -27329,7 +27331,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:80
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:80
|
||||||
msgid "Comment:"
|
msgid "Comment:"
|
||||||
msgstr ""
|
msgstr "Komente:"
|
||||||
|
|
||||||
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:98
|
#: pretix/plugins/banktransfer/templates/pretixplugins/banktransfer/transaction_list.html:98
|
||||||
msgid "No order code detected"
|
msgid "No order code detected"
|
||||||
@@ -27572,7 +27574,7 @@ msgstr ""
|
|||||||
#: pretix/plugins/paypal2/payment.py:1097
|
#: pretix/plugins/paypal2/payment.py:1097
|
||||||
#: pretix/plugins/paypal2/payment.py:1098 pretix/plugins/stripe/payment.py:1816
|
#: pretix/plugins/paypal2/payment.py:1098 pretix/plugins/stripe/payment.py:1816
|
||||||
msgid "PayPal"
|
msgid "PayPal"
|
||||||
msgstr ""
|
msgstr "PayPal"
|
||||||
|
|
||||||
#: pretix/plugins/paypal/apps.py:53
|
#: pretix/plugins/paypal/apps.py:53
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -29012,8 +29014,9 @@ msgid "Credit card payments"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:342 pretix/plugins/stripe/payment.py:1527
|
#: pretix/plugins/stripe/payment.py:342 pretix/plugins/stripe/payment.py:1527
|
||||||
|
#, fuzzy
|
||||||
msgid "iDEAL"
|
msgid "iDEAL"
|
||||||
msgstr ""
|
msgstr "iDEAL"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:344 pretix/plugins/stripe/payment.py:352
|
#: pretix/plugins/stripe/payment.py:344 pretix/plugins/stripe/payment.py:352
|
||||||
#: pretix/plugins/stripe/payment.py:360 pretix/plugins/stripe/payment.py:395
|
#: pretix/plugins/stripe/payment.py:360 pretix/plugins/stripe/payment.py:395
|
||||||
@@ -29032,12 +29035,14 @@ msgid "Alipay"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:358 pretix/plugins/stripe/payment.py:1564
|
#: pretix/plugins/stripe/payment.py:358 pretix/plugins/stripe/payment.py:1564
|
||||||
|
#, fuzzy
|
||||||
msgid "Bancontact"
|
msgid "Bancontact"
|
||||||
msgstr ""
|
msgstr "Bancontact"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:366
|
#: pretix/plugins/stripe/payment.py:366
|
||||||
|
#, fuzzy
|
||||||
msgid "SEPA Direct Debit"
|
msgid "SEPA Direct Debit"
|
||||||
msgstr ""
|
msgstr "Debit direkt me SEPA"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:369
|
#: pretix/plugins/stripe/payment.py:369
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -29072,12 +29077,14 @@ msgid "Multibanco"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:409 pretix/plugins/stripe/payment.py:1730
|
#: pretix/plugins/stripe/payment.py:409 pretix/plugins/stripe/payment.py:1730
|
||||||
|
#, fuzzy
|
||||||
msgid "Przelewy24"
|
msgid "Przelewy24"
|
||||||
msgstr ""
|
msgstr "Przelewy24"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:417 pretix/plugins/stripe/payment.py:1769
|
#: pretix/plugins/stripe/payment.py:417 pretix/plugins/stripe/payment.py:1769
|
||||||
|
#, fuzzy
|
||||||
msgid "WeChat Pay"
|
msgid "WeChat Pay"
|
||||||
msgstr ""
|
msgstr "WeChat Pay"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:433 pretix/plugins/stripe/payment.py:1824
|
#: pretix/plugins/stripe/payment.py:433 pretix/plugins/stripe/payment.py:1824
|
||||||
msgid "Swish"
|
msgid "Swish"
|
||||||
@@ -29221,8 +29228,9 @@ msgid "giropay via Stripe"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:1480
|
#: pretix/plugins/stripe/payment.py:1480
|
||||||
|
#, fuzzy
|
||||||
msgid "giropay"
|
msgid "giropay"
|
||||||
msgstr ""
|
msgstr "giropay"
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:1483
|
#: pretix/plugins/stripe/payment.py:1483
|
||||||
msgid ""
|
msgid ""
|
||||||
@@ -29757,7 +29765,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/edit.html:23
|
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/edit.html:23
|
||||||
msgid "Ticket design"
|
msgid "Ticket design"
|
||||||
msgstr ""
|
msgstr "Dizajni i biletës"
|
||||||
|
|
||||||
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/edit.html:27
|
#: pretix/plugins/ticketoutputpdf/templates/pretixplugins/ticketoutputpdf/edit.html:27
|
||||||
msgid "You can modify the design after you saved this page."
|
msgid "You can modify the design after you saved this page."
|
||||||
@@ -30320,7 +30328,7 @@ msgstr ""
|
|||||||
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:27
|
#: pretix/presale/templates/pretixpresale/event/checkout_confirm.html:27
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:18
|
#: pretix/presale/templates/pretixpresale/event/fragment_cart_box.html:18
|
||||||
msgid "Cart expired"
|
msgid "Cart expired"
|
||||||
msgstr ""
|
msgstr "Shporta juaj u skadua"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/checkout_base.html:36
|
#: pretix/presale/templates/pretixpresale/event/checkout_base.html:36
|
||||||
msgid "Show full cart"
|
msgid "Show full cart"
|
||||||
@@ -30928,11 +30936,13 @@ msgid ""
|
|||||||
"The items in your cart are no longer reserved for you. You can still "
|
"The items in your cart are no longer reserved for you. You can still "
|
||||||
"complete your order as long as they’re available."
|
"complete your order as long as they’re available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"Sendet në shportën tuaj nuk janë të rezervuar më për ju. Ju mund t'a "
|
||||||
|
"përmbushni porosinë tuaj derisa janë ende të disponueshëm."
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:514
|
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:514
|
||||||
#: pretix/presale/templates/pretixpresale/fragment_modals.html:48
|
#: pretix/presale/templates/pretixpresale/fragment_modals.html:48
|
||||||
msgid "Renew reservation"
|
msgid "Renew reservation"
|
||||||
msgstr ""
|
msgstr "Rivendosni rezervimin"
|
||||||
|
|
||||||
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:526
|
#: pretix/presale/templates/pretixpresale/event/fragment_cart.html:526
|
||||||
msgid "Reservation renewed"
|
msgid "Reservation renewed"
|
||||||
@@ -32444,7 +32454,7 @@ msgstr ""
|
|||||||
#: pretix/presale/templates/pretixpresale/postmessage.html:21
|
#: pretix/presale/templates/pretixpresale/postmessage.html:21
|
||||||
#: pretix/presale/templates/pretixpresale/waiting.html:22
|
#: pretix/presale/templates/pretixpresale/waiting.html:22
|
||||||
msgid "We are processing your request …"
|
msgid "We are processing your request …"
|
||||||
msgstr ""
|
msgstr "Ne po e proçesojmë kërkesën tuaj …"
|
||||||
|
|
||||||
#: pretix/presale/utils.py:271 pretix/presale/utils.py:417
|
#: pretix/presale/utils.py:271 pretix/presale/utils.py:417
|
||||||
#: pretix/presale/utils.py:418
|
#: pretix/presale/utils.py:418
|
||||||
|
|||||||
@@ -41,15 +41,20 @@ for app in apps.get_app_configs():
|
|||||||
if hasattr(app, 'PretixPluginMeta'):
|
if hasattr(app, 'PretixPluginMeta'):
|
||||||
if importlib.util.find_spec(app.name + '.urls'):
|
if importlib.util.find_spec(app.name + '.urls'):
|
||||||
urlmod = importlib.import_module(app.name + '.urls')
|
urlmod = importlib.import_module(app.name + '.urls')
|
||||||
|
single_plugin_patterns = []
|
||||||
|
|
||||||
if hasattr(urlmod, 'event_patterns'):
|
if hasattr(urlmod, 'event_patterns'):
|
||||||
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
|
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
|
||||||
raw_plugin_patterns.append(
|
single_plugin_patterns.append(
|
||||||
re_path(r'^(?P<event>[^/]+)/', include((patterns, app.label)))
|
re_path(r'^(?P<event>[^/]+)/', include(patterns))
|
||||||
)
|
)
|
||||||
|
|
||||||
if hasattr(urlmod, 'organizer_patterns'):
|
if hasattr(urlmod, 'organizer_patterns'):
|
||||||
patterns = plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
|
single_plugin_patterns += plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
|
||||||
|
|
||||||
|
if single_plugin_patterns:
|
||||||
raw_plugin_patterns.append(
|
raw_plugin_patterns.append(
|
||||||
re_path(r'', include((patterns, app.label)))
|
re_path(r'', include((single_plugin_patterns, app.label)))
|
||||||
)
|
)
|
||||||
|
|
||||||
plugin_patterns = [
|
plugin_patterns = [
|
||||||
|
|||||||
@@ -42,15 +42,20 @@ for app in apps.get_app_configs():
|
|||||||
if hasattr(app, 'PretixPluginMeta'):
|
if hasattr(app, 'PretixPluginMeta'):
|
||||||
if importlib.util.find_spec(app.name + '.urls'):
|
if importlib.util.find_spec(app.name + '.urls'):
|
||||||
urlmod = importlib.import_module(app.name + '.urls')
|
urlmod = importlib.import_module(app.name + '.urls')
|
||||||
if hasattr(urlmod, 'event_patterns'):
|
single_plugin_patterns = []
|
||||||
patterns = plugin_event_urls(urlmod.event_patterns, plugin=app.name)
|
|
||||||
raw_plugin_patterns.append(
|
|
||||||
re_path(r'^(?P<event>[^/]+)/', include((patterns, app.label)))
|
|
||||||
)
|
|
||||||
if hasattr(urlmod, 'organizer_patterns'):
|
if hasattr(urlmod, 'organizer_patterns'):
|
||||||
patterns = plugin_event_urls(urlmod.organizer_patterns, plugin=app.name)
|
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:
|
||||||
raw_plugin_patterns.append(
|
raw_plugin_patterns.append(
|
||||||
re_path(r'', include((patterns, app.label)))
|
re_path(r'', include((single_plugin_patterns, app.label)))
|
||||||
)
|
)
|
||||||
|
|
||||||
plugin_patterns = [
|
plugin_patterns = [
|
||||||
|
|||||||
71
src/pretix/plugins/banktransfer/camtimport.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#
|
||||||
|
# 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
|
||||||
@@ -46,12 +46,12 @@ from i18nfield.forms import I18nTextInput
|
|||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
from localflavor.generic.forms import BICFormField, IBANFormField
|
from localflavor.generic.forms import BICFormField, IBANFormField
|
||||||
from localflavor.generic.validators import IBANValidator
|
from localflavor.generic.validators import IBANValidator
|
||||||
from text_unidecode import unidecode
|
|
||||||
|
|
||||||
from pretix.base.forms import I18nMarkdownTextarea
|
from pretix.base.forms import I18nMarkdownTextarea
|
||||||
from pretix.base.models import InvoiceAddress, Order, OrderPayment, OrderRefund
|
from pretix.base.models import InvoiceAddress, Order, OrderPayment, OrderRefund
|
||||||
from pretix.base.payment import BasePaymentProvider
|
from pretix.base.payment import BasePaymentProvider
|
||||||
from pretix.base.templatetags.money import money_filter
|
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.plugins.banktransfer.templatetags.ibanformat import ibanformat
|
||||||
from pretix.presale.views.cart import cart_session
|
from pretix.presale.views.cart import cart_session
|
||||||
|
|
||||||
@@ -313,51 +313,6 @@ class BankTransfer(BasePaymentProvider):
|
|||||||
t += str(self.settings.get('bank_details', as_type=LazyI18nString))
|
t += str(self.settings.get('bank_details', as_type=LazyI18nString))
|
||||||
return t
|
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):
|
def payment_pending_render(self, request: HttpRequest, payment: OrderPayment):
|
||||||
template = get_template('pretixplugins/banktransfer/pending.html')
|
template = get_template('pretixplugins/banktransfer/pending.html')
|
||||||
ctx = {
|
ctx = {
|
||||||
@@ -367,13 +322,18 @@ class BankTransfer(BasePaymentProvider):
|
|||||||
'amount': payment.amount,
|
'amount': payment.amount,
|
||||||
'payment_info': payment.info_data,
|
'payment_info': payment.info_data,
|
||||||
'settings': self.settings,
|
'settings': self.settings,
|
||||||
'swiss_qrbill': self.swiss_qrbill(payment),
|
'payment_qr_codes': generate_payment_qr_codes(
|
||||||
'eu_barcodes': self.event.currency == 'EUR',
|
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,
|
||||||
'pending_description': self.settings.get('pending_description', as_type=LazyI18nString),
|
'pending_description': self.settings.get('pending_description', as_type=LazyI18nString),
|
||||||
'details': self.settings.get('bank_details', as_type=LazyI18nString),
|
'details': self.settings.get('bank_details', as_type=LazyI18nString),
|
||||||
'has_invoices': payment.order.invoices.exists(),
|
'has_invoices': payment.order.invoices.exists(),
|
||||||
}
|
}
|
||||||
ctx['any_barcodes'] = ctx['swiss_qrbill'] or ctx['eu_barcodes']
|
|
||||||
return template.render(ctx, request=request)
|
return template.render(ctx, request=request)
|
||||||
|
|
||||||
def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
|
def payment_control_render(self, request: HttpRequest, payment: OrderPayment) -> str:
|
||||||
|
|||||||
@@ -34,8 +34,10 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import operator
|
||||||
import re
|
import re
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
from functools import reduce
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
from celery.exceptions import MaxRetriesExceededError
|
from celery.exceptions import MaxRetriesExceededError
|
||||||
@@ -117,20 +119,26 @@ def _find_order_for_code(base_qs, code):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def _find_order_for_invoice_id(base_qs, prefix, number):
|
def _find_order_for_invoice_id(base_qs, prefixes, number):
|
||||||
try:
|
try:
|
||||||
# Working with __iregex here is an experiment, if this turns out to be too slow in production
|
# 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.
|
# 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(
|
return base_qs.select_related('order').get(
|
||||||
prefix__istartswith=prefix, # redundant, but hopefully makes it a little faster
|
reduce(operator.or_, r)
|
||||||
full_invoice_no__iregex=prefix + r'[\- ]*0*' + number
|
|
||||||
).order
|
).order
|
||||||
except (Invoice.DoesNotExist, Invoice.MultipleObjectsReturned):
|
except (Invoice.DoesNotExist, Invoice.MultipleObjectsReturned):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = None, organizer: Organizer = None):
|
def _handle_transaction(trans: BankTransaction, matches: tuple, regex_match_to_slug, event: Event = None, organizer: Organizer = None):
|
||||||
orders = []
|
orders = []
|
||||||
if event:
|
if event:
|
||||||
for slug, code in matches:
|
for slug, code in matches:
|
||||||
@@ -139,18 +147,19 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = N
|
|||||||
if order.code not in {o.code for o in orders}:
|
if order.code not in {o.code for o in orders}:
|
||||||
orders.append(order)
|
orders.append(order)
|
||||||
else:
|
else:
|
||||||
order = _find_order_for_invoice_id(Invoice.objects.filter(event=event), slug, code)
|
order = _find_order_for_invoice_id(Invoice.objects.filter(event=event), (slug, regex_match_to_slug.get(slug, slug)), code)
|
||||||
if order and order.code not in {o.code for o in orders}:
|
if order and order.code not in {o.code for o in orders}:
|
||||||
orders.append(order)
|
orders.append(order)
|
||||||
else:
|
else:
|
||||||
qs = Order.objects.filter(event__organizer=organizer)
|
qs = Order.objects.filter(event__organizer=organizer)
|
||||||
for slug, code in matches:
|
for slug, code in matches:
|
||||||
order = _find_order_for_code(qs.filter(event__slug__iexact=slug), code)
|
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)
|
||||||
if order:
|
if order:
|
||||||
if order.code not in {o.code for o in orders}:
|
if order.code not in {o.code for o in orders}:
|
||||||
orders.append(order)
|
orders.append(order)
|
||||||
else:
|
else:
|
||||||
order = _find_order_for_invoice_id(Invoice.objects.filter(event__organizer=organizer), slug, code)
|
order = _find_order_for_invoice_id(Invoice.objects.filter(event__organizer=organizer), (slug, original_slug), code)
|
||||||
if order and order.code not in {o.code for o in orders}:
|
if order and order.code not in {o.code for o in orders}:
|
||||||
orders.append(order)
|
orders.append(order)
|
||||||
|
|
||||||
@@ -366,22 +375,37 @@ def process_banktransfers(self, job: int, data: list) -> None:
|
|||||||
transactions = _get_unknown_transactions(job, data, **job.owner_kwargs)
|
transactions = _get_unknown_transactions(job, data, **job.owner_kwargs)
|
||||||
|
|
||||||
# Match order codes
|
# Match order codes
|
||||||
|
regex_match_to_slug = {}
|
||||||
code_len_agg = Order.objects.filter(event__organizer=job.organizer).annotate(
|
code_len_agg = Order.objects.filter(event__organizer=job.organizer).annotate(
|
||||||
clen=Length('code')
|
clen=Length('code')
|
||||||
).aggregate(min=Min('clen'), max=Max('clen'))
|
).aggregate(min=Min('clen'), max=Max('clen'))
|
||||||
if job.event:
|
if job.event:
|
||||||
prefixes = {job.event.slug.upper()}
|
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
|
||||||
else:
|
else:
|
||||||
prefixes = {e.slug.upper() for e in job.organizer.events.all()}
|
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
|
||||||
|
|
||||||
# Match invoice numbers
|
# Match invoice numbers
|
||||||
inr_len_agg = Invoice.objects.filter(event__organizer=job.organizer).annotate(
|
inr_len_agg = Invoice.objects.filter(event__organizer=job.organizer).annotate(
|
||||||
clen=Length('invoice_no')
|
clen=Length('invoice_no')
|
||||||
).aggregate(min=Min('clen'), max=Max('clen'))
|
).aggregate(min=Min('clen'), max=Max('clen'))
|
||||||
if job.event:
|
if job.event:
|
||||||
prefixes |= {p.rstrip(' -') for p in Invoice.objects.filter(event=job.event).distinct().values_list('prefix', flat=True)}
|
invoice_prefixes = Invoice.objects.filter(event=job.event)
|
||||||
else:
|
else:
|
||||||
prefixes |= {p.rstrip(' -') for p in Invoice.objects.filter(event__organizer=job.organizer).distinct().values_list('prefix', flat=True)}
|
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
|
||||||
|
|
||||||
pattern = re.compile(
|
pattern = re.compile(
|
||||||
"(%s)[ \\-_]*([A-Z0-9]{%s,%s})" % (
|
"(%s)[ \\-_]*([A-Z0-9]{%s,%s})" % (
|
||||||
@@ -395,6 +419,11 @@ def process_banktransfers(self, job: int, data: list) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
for trans in transactions:
|
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.
|
# 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,
|
# 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
|
# e.g. when there are two references. "DEMOCON-12345 DEMOCON-45678" would otherwise be parsed as
|
||||||
@@ -409,9 +438,9 @@ def process_banktransfers(self, job: int, data: list) -> None:
|
|||||||
|
|
||||||
if matches:
|
if matches:
|
||||||
if job.event:
|
if job.event:
|
||||||
_handle_transaction(trans, matches, event=job.event)
|
_handle_transaction(trans, matches, regex_match_to_slug, event=job.event)
|
||||||
else:
|
else:
|
||||||
_handle_transaction(trans, matches, organizer=job.organizer)
|
_handle_transaction(trans, matches, regex_match_to_slug, organizer=job.organizer)
|
||||||
else:
|
else:
|
||||||
trans.state = BankTransaction.STATE_NOMATCH
|
trans.state = BankTransaction.STATE_NOMATCH
|
||||||
trans.save()
|
trans.save()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load l10n %}
|
{% load l10n %}
|
||||||
{% load commadecimal %}
|
{% load commadecimal %}
|
||||||
{% load static %}
|
|
||||||
{% load dotdecimal %}
|
{% load dotdecimal %}
|
||||||
{% load ibanformat %}
|
{% load ibanformat %}
|
||||||
{% load money %}
|
{% load money %}
|
||||||
@@ -17,7 +16,7 @@
|
|||||||
{% endblocktrans %}</p>
|
{% endblocktrans %}</p>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="{% if settings.bank_details_type == "sepa" %}col-md-6{% else %}col-md-12{% endif %} col-xs-12">
|
<div class="{% if payment_qr_codes %}col-md-6{% else %}col-md-12{% endif %} col-xs-12">
|
||||||
<dl class="dl-horizontal">
|
<dl class="dl-horizontal">
|
||||||
<dt>{% trans "Reference code (important):" %}</dt><dd><b>{{ code }}</b></dd>
|
<dt>{% trans "Reference code (important):" %}</dt><dd><b>{{ code }}</b></dd>
|
||||||
<dt>{% trans "Amount:" %}</dt><dd>{{ amount|money:event.currency }}</dd>
|
<dt>{% trans "Amount:" %}</dt><dd>{{ amount|money:event.currency }}</dd>
|
||||||
@@ -36,94 +35,7 @@
|
|||||||
{% trans "We will send you an email as soon as we received your payment." %}
|
{% trans "We will send you an email as soon as we received your payment." %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% if settings.bank_details_type == "sepa" and any_barcodes %}
|
{% if payment_qr_codes %}
|
||||||
<div class="tabcontainer col-md-6 col-sm-6 hidden-xs text-center js-only blank-after">
|
{% include "pretixpresale/event/payment_qr_codes.html" %}
|
||||||
<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 app’s 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 app’s 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 }}¤cy={{ 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 app’s 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 }}¤cy={{ 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 %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if swiss_qrbill %}
|
|
||||||
<link rel="stylesheet" href="{% static "pretixplugins/banktransfer/swisscross.css" %}">
|
|
||||||
{% endif %}
|
|
||||||
@@ -66,7 +66,7 @@ from pretix.control.permissions import (
|
|||||||
)
|
)
|
||||||
from pretix.control.views.organizer import OrganizerDetailViewMixin
|
from pretix.control.views.organizer import OrganizerDetailViewMixin
|
||||||
from pretix.helpers.json import CustomJSONEncoder
|
from pretix.helpers.json import CustomJSONEncoder
|
||||||
from pretix.plugins.banktransfer import csvimport, mt940import
|
from pretix.plugins.banktransfer import camtimport, csvimport, mt940import
|
||||||
from pretix.plugins.banktransfer.models import (
|
from pretix.plugins.banktransfer.models import (
|
||||||
BankImportJob, BankTransaction, RefundExport,
|
BankImportJob, BankTransaction, RefundExport,
|
||||||
)
|
)
|
||||||
@@ -419,6 +419,9 @@ class ImportView(ListView):
|
|||||||
):
|
):
|
||||||
return self.process_mt940()
|
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:
|
elif self.request.FILES.get('file') is None:
|
||||||
messages.error(self.request, _('You must choose a file to import.'))
|
messages.error(self.request, _('You must choose a file to import.'))
|
||||||
return self.redirect_back()
|
return self.redirect_back()
|
||||||
@@ -432,6 +435,14 @@ class ImportView(ListView):
|
|||||||
def settings(self):
|
def settings(self):
|
||||||
return SettingsSandbox('payment', 'banktransfer', getattr(self.request, 'event', self.request.organizer))
|
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):
|
def process_mt940(self):
|
||||||
try:
|
try:
|
||||||
return self.start_processing(mt940import.parse(self.request.FILES.get('file')))
|
return self.start_processing(mt940import.parse(self.request.FILES.get('file')))
|
||||||
|
|||||||
@@ -711,7 +711,7 @@ class PaypalMethod(BasePaymentProvider):
|
|||||||
description = '{prefix}{orderstring}{postfix}'.format(
|
description = '{prefix}{orderstring}{postfix}'.format(
|
||||||
prefix='{} '.format(self.settings.prefix) if self.settings.prefix else '',
|
prefix='{} '.format(self.settings.prefix) if self.settings.prefix else '',
|
||||||
orderstring=__('Order {order} for {event}').format(
|
orderstring=__('Order {order} for {event}').format(
|
||||||
event=request.event.name,
|
event=self.event.name,
|
||||||
order=payment.order.code
|
order=payment.order.code
|
||||||
),
|
),
|
||||||
postfix=' {}'.format(self.settings.postfix) if self.settings.postfix else ''
|
postfix=' {}'.format(self.settings.postfix) if self.settings.postfix else ''
|
||||||
|
|||||||
@@ -644,7 +644,9 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
|
|||||||
FontFallbackParagraph(
|
FontFallbackParagraph(
|
||||||
_("Pending payments at {datetime}").format(
|
_("Pending payments at {datetime}").format(
|
||||||
datetime=date_format(
|
datetime=date_format(
|
||||||
df_start - datetime.timedelta.resolution,
|
(df_start - datetime.timedelta.resolution).astimezone(
|
||||||
|
self.timezone
|
||||||
|
),
|
||||||
"SHORT_DATETIME_FORMAT",
|
"SHORT_DATETIME_FORMAT",
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@@ -694,7 +696,9 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
|
|||||||
Paragraph(
|
Paragraph(
|
||||||
_("Pending payments at {datetime}").format(
|
_("Pending payments at {datetime}").format(
|
||||||
datetime=date_format(
|
datetime=date_format(
|
||||||
(df_end or now()) - datetime.timedelta.resolution,
|
((df_end or now()) - datetime.timedelta.resolution).astimezone(
|
||||||
|
self.timezone
|
||||||
|
),
|
||||||
"SHORT_DATETIME_FORMAT",
|
"SHORT_DATETIME_FORMAT",
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@@ -751,7 +755,9 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
|
|||||||
Paragraph(
|
Paragraph(
|
||||||
_("Total gift card value at {datetime}").format(
|
_("Total gift card value at {datetime}").format(
|
||||||
datetime=date_format(
|
datetime=date_format(
|
||||||
df_start - datetime.timedelta.resolution,
|
(df_start - datetime.timedelta.resolution).astimezone(
|
||||||
|
self.timezone
|
||||||
|
),
|
||||||
"SHORT_DATETIME_FORMAT",
|
"SHORT_DATETIME_FORMAT",
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@@ -789,7 +795,9 @@ class ReportExporter(ReportlabExportMixin, BaseExporter):
|
|||||||
Paragraph(
|
Paragraph(
|
||||||
_("Total gift card value at {datetime}").format(
|
_("Total gift card value at {datetime}").format(
|
||||||
datetime=date_format(
|
datetime=date_format(
|
||||||
(df_end or now()) - datetime.timedelta.resolution,
|
((df_end or now()) - datetime.timedelta.resolution).astimezone(
|
||||||
|
self.timezone
|
||||||
|
),
|
||||||
"SHORT_DATETIME_FORMAT",
|
"SHORT_DATETIME_FORMAT",
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ logger = logging.getLogger('pretix.plugins.stripe')
|
|||||||
# Real-time payments
|
# Real-time payments
|
||||||
# - Swish: ✓
|
# - Swish: ✓
|
||||||
# - PayNow: ✗
|
# - PayNow: ✗
|
||||||
# - PromptPay: ✗
|
# - PromptPay: ✓
|
||||||
# - Pix: ✗
|
# - Pix: ✗
|
||||||
#
|
#
|
||||||
# Vouchers
|
# Vouchers
|
||||||
@@ -412,6 +412,18 @@ class StripeSettingsHolder(BasePaymentProvider):
|
|||||||
'before they work properly.'),
|
'before they work properly.'),
|
||||||
required=False,
|
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',
|
('method_wechatpay',
|
||||||
forms.BooleanField(
|
forms.BooleanField(
|
||||||
label=_('WeChat Pay'),
|
label=_('WeChat Pay'),
|
||||||
@@ -428,6 +440,14 @@ class StripeSettingsHolder(BasePaymentProvider):
|
|||||||
'before they work properly.'),
|
'before they work properly.'),
|
||||||
required=False,
|
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',
|
('method_swish',
|
||||||
forms.BooleanField(
|
forms.BooleanField(
|
||||||
label=_('Swish'),
|
label=_('Swish'),
|
||||||
@@ -1810,6 +1830,32 @@ 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):
|
class StripePayPal(StripeRedirectMethod):
|
||||||
identifier = 'stripe_paypal'
|
identifier = 'stripe_paypal'
|
||||||
verbose_name = _('PayPal via Stripe')
|
verbose_name = _('PayPal via Stripe')
|
||||||
@@ -1842,6 +1888,30 @@ 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):
|
class StripeTwint(StripeRedirectMethod):
|
||||||
identifier = 'stripe_twint'
|
identifier = 'stripe_twint'
|
||||||
verbose_name = _('TWINT via Stripe')
|
verbose_name = _('TWINT via Stripe')
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ from pretix.base.signals import (
|
|||||||
)
|
)
|
||||||
from pretix.control.signals import nav_organizer
|
from pretix.control.signals import nav_organizer
|
||||||
from pretix.plugins.stripe.forms import StripeKeyValidator
|
from pretix.plugins.stripe.forms import StripeKeyValidator
|
||||||
from pretix.plugins.stripe.payment import StripeMethod
|
|
||||||
from pretix.presale.signals import html_head, process_response
|
from pretix.presale.signals import html_head, process_response
|
||||||
|
|
||||||
|
|
||||||
@@ -47,15 +46,17 @@ def register_payment_provider(sender, **kwargs):
|
|||||||
from .payment import (
|
from .payment import (
|
||||||
StripeAffirm, StripeAlipay, StripeBancontact, StripeCC, StripeEPS,
|
StripeAffirm, StripeAlipay, StripeBancontact, StripeCC, StripeEPS,
|
||||||
StripeGiropay, StripeIdeal, StripeKlarna, StripeMobilePay,
|
StripeGiropay, StripeIdeal, StripeKlarna, StripeMobilePay,
|
||||||
StripeMultibanco, StripePayPal, StripePrzelewy24, StripeRevolutPay,
|
StripeMultibanco, StripePayByBank, StripePayPal, StripePromptPay,
|
||||||
StripeSEPADirectDebit, StripeSettingsHolder, StripeSofort, StripeSwish,
|
StripePrzelewy24, StripeRevolutPay, StripeSEPADirectDebit,
|
||||||
StripeTwint, StripeWeChatPay,
|
StripeSettingsHolder, StripeSofort, StripeSwish, StripeTwint,
|
||||||
|
StripeWeChatPay,
|
||||||
)
|
)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
StripeSettingsHolder, StripeCC, StripeGiropay, StripeIdeal, StripeAlipay, StripeBancontact,
|
StripeSettingsHolder, StripeCC, StripeGiropay, StripeIdeal, StripeAlipay, StripeBancontact,
|
||||||
StripeSofort, StripeEPS, StripeMultibanco, StripePrzelewy24, StripeRevolutPay, StripeWeChatPay,
|
StripeSofort, StripeEPS, StripeMultibanco, StripePayByBank, StripePrzelewy24, StripePromptPay, StripeRevolutPay,
|
||||||
StripeSEPADirectDebit, StripeAffirm, StripeKlarna, StripePayPal, StripeSwish, StripeTwint, StripeMobilePay
|
StripeWeChatPay, StripeSEPADirectDebit, StripeAffirm, StripeKlarna, StripePayPal, StripeSwish,
|
||||||
|
StripeTwint, StripeMobilePay
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -189,6 +190,8 @@ def nav_o(sender, request, organizer, **kwargs):
|
|||||||
|
|
||||||
@receiver(signal=process_response, dispatch_uid="stripe_middleware_resp")
|
@receiver(signal=process_response, dispatch_uid="stripe_middleware_resp")
|
||||||
def signal_process_response(sender, request: HttpRequest, response: HttpResponse, **kwargs):
|
def signal_process_response(sender, request: HttpRequest, response: HttpResponse, **kwargs):
|
||||||
|
from pretix.plugins.stripe.payment import StripeMethod
|
||||||
|
|
||||||
provider = StripeMethod(sender)
|
provider = StripeMethod(sender)
|
||||||
url = resolve(request.path_info)
|
url = resolve(request.path_info)
|
||||||
|
|
||||||
|
|||||||
@@ -79,3 +79,9 @@
|
|||||||
.vcenter {
|
.vcenter {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stripe-qr-code {
|
||||||
|
max-width: 80%;
|
||||||
|
width: 200px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
@@ -325,6 +325,8 @@ $(function () {
|
|||||||
} else if ($("#stripe_payment_intent_next_action_redirect_url").length) {
|
} 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());
|
let payment_intent_next_action_redirect_url = $.trim($("#stripe_payment_intent_next_action_redirect_url").html());
|
||||||
pretixstripe.handlePaymentRedirectAction(payment_intent_next_action_redirect_url);
|
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") {
|
} 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());
|
let payment_intent_client_secret = $.trim($("#stripe_payment_intent_client_secret").html());
|
||||||
pretixstripe.handleWechatAction(payment_intent_client_secret);
|
pretixstripe.handleWechatAction(payment_intent_client_secret);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from urllib.parse import urlsplit
|
from urllib.parse import urlsplit
|
||||||
|
|
||||||
import stripe
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from pretix.base.services.tasks import EventTask
|
from pretix.base.services.tasks import EventTask
|
||||||
@@ -50,7 +49,10 @@ def get_stripe_account_key(prov):
|
|||||||
|
|
||||||
@app.task(base=EventTask, max_retries=5, default_retry_delay=1)
|
@app.task(base=EventTask, max_retries=5, default_retry_delay=1)
|
||||||
def stripe_verify_domain(event, domain):
|
def stripe_verify_domain(event, domain):
|
||||||
|
import stripe
|
||||||
|
|
||||||
from pretix.plugins.stripe.payment import StripeCC
|
from pretix.plugins.stripe.payment import StripeCC
|
||||||
|
|
||||||
prov = StripeCC(event)
|
prov = StripeCC(event)
|
||||||
account = get_stripe_account_key(prov)
|
account = get_stripe_account_key(prov)
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,21 @@
|
|||||||
<div class="stripe-errors sr-only panel-body">
|
<div class="stripe-errors sr-only panel-body">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body embed-responsive embed-responsive-sca" id="scacontainer">
|
{% if payment_intent_promptpay_image_url %}
|
||||||
|
<div class="panel-body">
|
||||||
</div>
|
<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>
|
</div>
|
||||||
<div class="row checkout-button-row">
|
<div class="row checkout-button-row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ import logging
|
|||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import stripe
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
@@ -68,7 +67,6 @@ from pretix.helpers.http import redirect_to_url
|
|||||||
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
|
from pretix.multidomain.urlreverse import build_absolute_uri, eventreverse
|
||||||
from pretix.plugins.stripe.forms import OrganizerStripeSettingsForm
|
from pretix.plugins.stripe.forms import OrganizerStripeSettingsForm
|
||||||
from pretix.plugins.stripe.models import ReferencedStripeObject
|
from pretix.plugins.stripe.models import ReferencedStripeObject
|
||||||
from pretix.plugins.stripe.payment import StripeCC, StripeSettingsHolder
|
|
||||||
from pretix.plugins.stripe.tasks import (
|
from pretix.plugins.stripe.tasks import (
|
||||||
get_domain_for_event, stripe_verify_domain,
|
get_domain_for_event, stripe_verify_domain,
|
||||||
)
|
)
|
||||||
@@ -100,6 +98,8 @@ def redirect_view(request, *args, **kwargs):
|
|||||||
|
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def oauth_return(request, *args, **kwargs):
|
def oauth_return(request, *args, **kwargs):
|
||||||
|
import stripe
|
||||||
|
|
||||||
if 'payment_stripe_oauth_event' not in request.session:
|
if 'payment_stripe_oauth_event' not in request.session:
|
||||||
messages.error(request, _('An error occurred during connecting with Stripe, please try again.'))
|
messages.error(request, _('An error occurred during connecting with Stripe, please try again.'))
|
||||||
return redirect('control:index')
|
return redirect('control:index')
|
||||||
@@ -268,6 +268,10 @@ SOURCE_TYPES = {
|
|||||||
|
|
||||||
|
|
||||||
def charge_webhook(event, event_json, charge_id, rso):
|
def charge_webhook(event, event_json, charge_id, rso):
|
||||||
|
import stripe
|
||||||
|
|
||||||
|
from pretix.plugins.stripe.payment import StripeCC
|
||||||
|
|
||||||
prov = StripeCC(event)
|
prov = StripeCC(event)
|
||||||
prov._init_api()
|
prov._init_api()
|
||||||
|
|
||||||
@@ -371,6 +375,10 @@ def charge_webhook(event, event_json, charge_id, rso):
|
|||||||
|
|
||||||
|
|
||||||
def source_webhook(event, event_json, source_id, rso):
|
def source_webhook(event, event_json, source_id, rso):
|
||||||
|
import stripe
|
||||||
|
|
||||||
|
from pretix.plugins.stripe.payment import StripeCC
|
||||||
|
|
||||||
prov = StripeCC(event)
|
prov = StripeCC(event)
|
||||||
prov._init_api()
|
prov._init_api()
|
||||||
try:
|
try:
|
||||||
@@ -440,6 +448,10 @@ def source_webhook(event, event_json, source_id, rso):
|
|||||||
|
|
||||||
|
|
||||||
def paymentintent_webhook(event, event_json, paymentintent_id, rso):
|
def paymentintent_webhook(event, event_json, paymentintent_id, rso):
|
||||||
|
import stripe
|
||||||
|
|
||||||
|
from pretix.plugins.stripe.payment import StripeCC
|
||||||
|
|
||||||
prov = StripeCC(event)
|
prov = StripeCC(event)
|
||||||
prov._init_api()
|
prov._init_api()
|
||||||
|
|
||||||
@@ -516,6 +528,8 @@ class StripeOrderView:
|
|||||||
@method_decorator(xframe_options_exempt, 'dispatch')
|
@method_decorator(xframe_options_exempt, 'dispatch')
|
||||||
class ReturnView(StripeOrderView, View):
|
class ReturnView(StripeOrderView, View):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
import stripe
|
||||||
|
|
||||||
prov = self.pprov
|
prov = self.pprov
|
||||||
prov._init_api()
|
prov._init_api()
|
||||||
try:
|
try:
|
||||||
@@ -568,6 +582,10 @@ class ReturnView(StripeOrderView, View):
|
|||||||
class ScaView(StripeOrderView, View):
|
class ScaView(StripeOrderView, View):
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
import stripe
|
||||||
|
|
||||||
|
from pretix.plugins.stripe.payment import StripeSettingsHolder
|
||||||
|
|
||||||
prov = self.pprov
|
prov = self.pprov
|
||||||
prov._init_api()
|
prov._init_api()
|
||||||
|
|
||||||
@@ -595,7 +613,7 @@ class ScaView(StripeOrderView, View):
|
|||||||
|
|
||||||
if intent.status == 'requires_action' and intent.next_action.type in [
|
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',
|
'use_stripe_sdk', 'redirect_to_url', 'alipay_handle_redirect', 'wechat_pay_display_qr_code',
|
||||||
'swish_handle_redirect_or_display_qr_code', 'multibanco_display_details',
|
'swish_handle_redirect_or_display_qr_code', 'multibanco_display_details', 'promptpay_display_qr_code',
|
||||||
]:
|
]:
|
||||||
ctx = {
|
ctx = {
|
||||||
'order': self.order,
|
'order': self.order,
|
||||||
@@ -613,6 +631,8 @@ class ScaView(StripeOrderView, View):
|
|||||||
elif intent.next_action.type == 'multibanco_display_details':
|
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_next_action_redirect_url'] = intent.next_action.multibanco_display_details['hosted_voucher_url']
|
||||||
ctx['payment_intent_redirect_action_handling'] = 'iframe'
|
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 = render(request, 'pretixplugins/stripe/sca.html', ctx)
|
||||||
r._csp_ignore = True
|
r._csp_ignore = True
|
||||||
|
|||||||
@@ -1545,6 +1545,8 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
|
|||||||
ctx['invoice_address_asked'] = self.address_asked
|
ctx['invoice_address_asked'] = self.address_asked
|
||||||
ctx['customer'] = self.cart_customer
|
ctx['customer'] = self.cart_customer
|
||||||
|
|
||||||
|
ctx['transmission_fields'] = self.invoice_address.describe_transmission(self.event)
|
||||||
|
|
||||||
self.cart_session['shown_total'] = str(ctx['cart']['total'])
|
self.cart_session['shown_total'] = str(ctx['cart']['total'])
|
||||||
|
|
||||||
email = self.cart_session.get('contact_form_data', {}).get('email')
|
email = self.cart_session.get('contact_form_data', {}).get('email')
|
||||||
|
|||||||
@@ -111,7 +111,7 @@
|
|||||||
<dt>{% trans "Internal reference" %}</dt>
|
<dt>{% trans "Internal reference" %}</dt>
|
||||||
<dd>{{ addr.internal_reference }}</dd>
|
<dd>{{ addr.internal_reference }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for k, v in addr.describe_transmission %}
|
{% for k, v in transmission_fields %}
|
||||||
<dt>{{ k }}</dt>
|
<dt>{{ k }}</dt>
|
||||||
<dd>{{ v }}</dd>
|
<dd>{{ v }}</dd>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load html_time %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load icon %}
|
{% load icon %}
|
||||||
{% load eventurl %}
|
{% load eventurl %}
|
||||||
@@ -21,20 +22,18 @@
|
|||||||
{% if event.settings.show_times %}
|
{% if event.settings.show_times %}
|
||||||
<br>
|
<br>
|
||||||
<span data-time="{{ ev.date_from.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
<span data-time="{{ ev.date_from.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
||||||
{% with time_human=ev.date_from|date:"TIME_FORMAT" time_24=ev.date_from|time:"H:i" %}
|
{% html_time ev.date_from "TIME_FORMAT" attr_fmt="H:i" as time%}
|
||||||
{% blocktrans trimmed with time='<time datetime="'|add:time_24|add:'">'|add:time_human|add:"</time>"|safe %}
|
{% blocktrans with time=time %}
|
||||||
Begin: {{ time }}
|
Begin: {{ time }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
</span>
|
</span>
|
||||||
{% if event.settings.show_date_to and ev.date_to %}
|
{% if event.settings.show_date_to and ev.date_to %}
|
||||||
<br>
|
<br>
|
||||||
<span data-time="{{ ev.date_to.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
<span data-time="{{ ev.date_to.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
||||||
{% with time_human=ev.date_to|date:"TIME_FORMAT" time_24=ev.date_to|time:"H:i" %}
|
{% html_time ev.date_to "TIME_FORMAT" attr_fmt="H:i" as time%}
|
||||||
{% blocktrans trimmed with time='<time datetime="'|add:time_24|add:'">'|add:time_human|add:"</time>"|safe %}
|
{% blocktrans with time=time %}
|
||||||
End: {{ time }}
|
End: {{ time }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -42,19 +41,17 @@
|
|||||||
<br>
|
<br>
|
||||||
{% if ev.date_admission|date:"SHORT_DATE_FORMAT" == ev.date_from|date:"SHORT_DATE_FORMAT" %}
|
{% if ev.date_admission|date:"SHORT_DATE_FORMAT" == ev.date_from|date:"SHORT_DATE_FORMAT" %}
|
||||||
<span data-time="{{ ev.date_admission.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
<span data-time="{{ ev.date_admission.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
||||||
{% with time_human=ev.date_admission|date:"TIME_FORMAT" time_24=ev.date_admission|time:"H:i" %}
|
{% html_time ev.date_admission "TIME_FORMAT" attr_fmt="H:i" as time%}
|
||||||
{% blocktrans trimmed with time='<time datetime="'|add:time_24|add:'">'|add:time_human|add:"</time>"|safe %}
|
{% blocktrans trimmed with time=time %}
|
||||||
Admission: {{ time }}
|
Admission: {{ time }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span data-time="{{ ev.date_admission.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
<span data-time="{{ ev.date_admission.isoformat }}" data-timezone="{{ request.event.timezone }}">
|
||||||
{% with datetime_human=ev.date_admission|date:"SHORT_DATETIME_FORMAT" datetime_iso=ev.date_admission|time:"Y-m-d H:i" %}
|
{% html_time ev.date_admission "SHORT_DATETIME_FORMAT" attr_fmt="Y-m-d H:i" as datetime%}
|
||||||
{% blocktrans trimmed with datetime='<time datetime="'|add:datetime_iso|add:'">'|add:datetime_human|add:"</time>"|safe %}
|
{% blocktrans trimmed with datetime=datetime %}
|
||||||
Admission: {{ datetime }}
|
Admission: {{ datetime }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{% extends "pretixpresale/event/base.html" %}
|
{% extends "pretixpresale/event/base.html" %}
|
||||||
|
{% load html_time %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
{% load eventsignal %}
|
{% load eventsignal %}
|
||||||
@@ -92,11 +93,10 @@
|
|||||||
A payment of {{ total }} is still pending for this order.
|
A payment of {{ total }} is still pending for this order.
|
||||||
{% endblocktrans %}</strong>
|
{% endblocktrans %}</strong>
|
||||||
<strong>
|
<strong>
|
||||||
{% with date_human=order|format_expires|safe date_iso=order.expires|date:"c" %}
|
{% html_time order.expires "format_expires" as date %}
|
||||||
{% blocktrans trimmed with date='<time datetime="'|add:date_iso|add:'">'|add:date_human|add:"</time>"|safe %}
|
{% blocktrans trimmed with date=date %}
|
||||||
Please complete your payment before {{ date }}
|
Please complete your payment before {{ date }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
</strong>
|
</strong>
|
||||||
</p>
|
</p>
|
||||||
{% if last_payment %}
|
{% if last_payment %}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{% 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 app’s 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 %}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load html_time %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load date_fast %}
|
{% load date_fast %}
|
||||||
{% load calendarhead %}
|
{% load calendarhead %}
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
running
|
running
|
||||||
{% elif event.event.presale_has_ended %}
|
{% elif event.event.presale_has_ended %}
|
||||||
over
|
over
|
||||||
{% elif event.event.settings.presale_start_show_date and event.event.presale_start %}
|
{% elif event.event.settings.presale_start_show_date and event.event.effective_presale_start %}
|
||||||
soon
|
soon
|
||||||
{% else %}
|
{% else %}
|
||||||
soon
|
soon
|
||||||
@@ -108,13 +109,12 @@
|
|||||||
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Book now" %}
|
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Book now" %}
|
||||||
{% elif event.event.presale_has_ended %}
|
{% elif event.event.presale_has_ended %}
|
||||||
{% trans "Sale over" %}
|
{% trans "Sale over" %}
|
||||||
{% elif event.event.settings.presale_start_show_date and event.event.presale_start %}
|
{% elif event.event.settings.presale_start_show_date and event.event.effective_presale_start %}
|
||||||
<span class="fa fa-ticket" aria-hidden="true"></span>
|
<span class="fa fa-ticket" aria-hidden="true"></span>
|
||||||
{% with date_human=event.event.presale_start|date_fast:"SHORT_DATE_FORMAT" date_iso=event.event.presale_start|date_fast:"c" %}
|
{% html_time event.event.effective_presale_start "SHORT_DATE_FORMAT" as start_date %}
|
||||||
{% blocktrans with start_date="<time datetime='"|add:date_iso|add:"'>"|add:date_human|add:"</time>"|safe %}
|
{% blocktrans with start_date=start_date %}
|
||||||
from {{ start_date }}
|
from {{ start_date }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Soon" %}
|
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Soon" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load html_time %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load eventurl %}
|
{% load eventurl %}
|
||||||
<div class="day-calendar cal-size-{{ raster_to_shortest_ratio }}{% if no_headlines %} no-headlines{% endif %}"
|
<div class="day-calendar cal-size-{{ raster_to_shortest_ratio }}{% if no_headlines %} no-headlines{% endif %}"
|
||||||
@@ -52,7 +53,7 @@
|
|||||||
running
|
running
|
||||||
{% elif event.event.presale_has_ended %}
|
{% elif event.event.presale_has_ended %}
|
||||||
over
|
over
|
||||||
{% elif event.event.settings.presale_start_show_date and event.event.presale_start %}
|
{% elif event.event.settings.presale_start_show_date and event.event.effective_presale_start %}
|
||||||
soon
|
soon
|
||||||
{% else %}
|
{% else %}
|
||||||
soon
|
soon
|
||||||
@@ -114,9 +115,10 @@
|
|||||||
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Book now" %}
|
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Book now" %}
|
||||||
{% elif event.event.presale_has_ended %}
|
{% elif event.event.presale_has_ended %}
|
||||||
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Sale over" %}
|
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Sale over" %}
|
||||||
{% elif event.event.settings.presale_start_show_date and event.event.presale_start %}
|
{% elif event.event.settings.presale_start_show_date and event.event.effective_presale_start %}
|
||||||
<span class="fa fa-ticket" aria-hidden="true"></span>
|
<span class="fa fa-ticket" aria-hidden="true"></span>
|
||||||
{% blocktrans with start_date=event.event.presale_start|date:"SHORT_DATE_FORMAT" %}
|
{% html_time event.event.effective_presale_start "SHORT_DATE_FORMAT" as start_date %}
|
||||||
|
{% blocktrans with start_date=start_date %}
|
||||||
from {{ start_date }}
|
from {{ start_date }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load html_time %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load icon %}
|
{% load icon %}
|
||||||
{% load textbubble %}
|
{% load textbubble %}
|
||||||
@@ -52,11 +53,10 @@
|
|||||||
{% endtextbubble %}
|
{% endtextbubble %}
|
||||||
{% if event.settings.presale_start_show_date %}
|
{% if event.settings.presale_start_show_date %}
|
||||||
<br><span class="text-muted">
|
<br><span class="text-muted">
|
||||||
{% with date_iso=event.effective_presale_start.isoformat date_human=event.effective_presale_start|date:"SHORT_DATE_FORMAT" %}
|
{% html_time event.event.effective_presale_start "SHORT_DATE_FORMAT" as date %}
|
||||||
{% blocktrans trimmed with date='<time datetime="'|add:date_iso|add:'">'|add:date_human|add:"</time>"|safe %}
|
{% blocktrans with date=date %}
|
||||||
Sale starts {{ date }}
|
Sale starts {{ date }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% endwith %}
|
|
||||||
</span>
|
</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{% load html_time %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load date_fast %}
|
{% load date_fast %}
|
||||||
<div class="week-calendar">
|
<div class="week-calendar">
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
running
|
running
|
||||||
{% elif event.event.presale_has_ended %}
|
{% elif event.event.presale_has_ended %}
|
||||||
over
|
over
|
||||||
{% elif event.event.settings.presale_start_show_date and event.event.presale_start %}
|
{% elif event.event.settings.presale_start_show_date and event.event.effective_presale_start %}
|
||||||
soon
|
soon
|
||||||
{% else %}
|
{% else %}
|
||||||
soon
|
soon
|
||||||
@@ -77,9 +78,10 @@
|
|||||||
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Book now" %}
|
<span class="fa fa-ticket" aria-hidden="true"></span> {% trans "Book now" %}
|
||||||
{% elif event.event.presale_has_ended %}
|
{% elif event.event.presale_has_ended %}
|
||||||
{% trans "Sale over" %}
|
{% trans "Sale over" %}
|
||||||
{% elif event.event.settings.presale_start_show_date and event.event.presale_start %}
|
{% elif event.event.settings.presale_start_show_date and event.event.effective_presale_start %}
|
||||||
<span class="fa fa-ticket" aria-hidden="true"></span>
|
<span class="fa fa-ticket" aria-hidden="true"></span>
|
||||||
{% blocktrans with start_date=event.event.presale_start|date_fast:"SHORT_DATE_FORMAT" %}
|
{% html_time event.event.effective_presale_start "SHORT_DATE_FORMAT" as start_date %}
|
||||||
|
{% blocktrans with start_date=start_date %}
|
||||||
from {{ start_date }}
|
from {{ start_date }}
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -438,9 +438,6 @@ def get_grouped_items(event, *, channel: SalesChannel, subevent=None, voucher=No
|
|||||||
base_price_is='net' if event.settings.display_net_prices else 'gross') # backwards-compat
|
base_price_is='net' if event.settings.display_net_prices else 'gross') # backwards-compat
|
||||||
) if var.original_price or item.original_price else None
|
) if var.original_price or item.original_price else None
|
||||||
|
|
||||||
if not display_add_to_cart:
|
|
||||||
display_add_to_cart = not item.requires_seat and var.order_max > 0
|
|
||||||
|
|
||||||
var.current_unavailability_reason = var.unavailability_reason(has_voucher=voucher, subevent=subevent)
|
var.current_unavailability_reason = var.unavailability_reason(has_voucher=voucher, subevent=subevent)
|
||||||
|
|
||||||
item.original_price = (
|
item.original_price = (
|
||||||
@@ -471,6 +468,8 @@ def get_grouped_items(event, *, channel: SalesChannel, subevent=None, voucher=No
|
|||||||
item.best_variation_availability = max([v.cached_availability[0] for v in item.available_variations])
|
item.best_variation_availability = max([v.cached_availability[0] for v in item.available_variations])
|
||||||
|
|
||||||
item._remove = not bool(item.available_variations)
|
item._remove = not bool(item.available_variations)
|
||||||
|
if not item._remove and not display_add_to_cart:
|
||||||
|
display_add_to_cart = not item.requires_seat and any(v.order_max > 0 for v in item.available_variations)
|
||||||
|
|
||||||
if not quota_cache_existed and not voucher and not allow_addons and not base_qs_set and not filter_items and not filter_categories:
|
if not quota_cache_existed and not voucher and not allow_addons and not base_qs_set and not filter_items and not filter_categories:
|
||||||
event.cache.set(quota_cache_key, quota_cache, 5)
|
event.cache.set(quota_cache_key, quota_cache, 5)
|
||||||
|
|||||||
@@ -471,10 +471,11 @@ class WidgetAPIProductList(EventListMixin, View):
|
|||||||
availability['color'] = 'red'
|
availability['color'] = 'red'
|
||||||
availability['text'] = gettext('Sale over')
|
availability['text'] = gettext('Sale over')
|
||||||
availability['reason'] = 'over'
|
availability['reason'] = 'over'
|
||||||
elif event.settings.presale_start_show_date and ev.presale_start:
|
elif event.settings.presale_start_show_date and ev.effective_presale_start:
|
||||||
availability['color'] = 'orange'
|
availability['color'] = 'orange'
|
||||||
availability['text'] = gettext('from %(start_date)s') % {
|
availability['text'] = gettext('from %(start_date)s') % {
|
||||||
'start_date': date_format(ev.presale_start.astimezone(tz or event.timezone), "SHORT_DATE_FORMAT")
|
'start_date': date_format(ev.effective_presale_start.astimezone(tz or event.timezone),
|
||||||
|
"SHORT_DATE_FORMAT")
|
||||||
}
|
}
|
||||||
availability['reason'] = 'soon'
|
availability['reason'] = 'soon'
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -347,11 +347,53 @@ if HAS_CELERY:
|
|||||||
CELERY_RESULT_BACKEND = config.get('celery', 'backend')
|
CELERY_RESULT_BACKEND = config.get('celery', 'backend')
|
||||||
if HAS_CELERY_BROKER_TRANSPORT_OPTS:
|
if HAS_CELERY_BROKER_TRANSPORT_OPTS:
|
||||||
CELERY_BROKER_TRANSPORT_OPTIONS = loads(config.get('celery', 'broker_transport_options'))
|
CELERY_BROKER_TRANSPORT_OPTIONS = loads(config.get('celery', 'broker_transport_options'))
|
||||||
|
else:
|
||||||
|
CELERY_BROKER_TRANSPORT_OPTIONS = {}
|
||||||
if HAS_CELERY_BACKEND_TRANSPORT_OPTS:
|
if HAS_CELERY_BACKEND_TRANSPORT_OPTS:
|
||||||
CELERY_RESULT_BACKEND_TRANSPORT_OPTIONS = loads(config.get('celery', 'backend_transport_options'))
|
CELERY_RESULT_BACKEND_TRANSPORT_OPTIONS = loads(config.get('celery', 'backend_transport_options'))
|
||||||
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
|
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
|
||||||
|
|
||||||
|
if CELERY_BROKER_URL.startswith("amqp://"):
|
||||||
|
# https://docs.celeryq.dev/en/latest/userguide/routing.html#routing-options-rabbitmq-priorities
|
||||||
|
# Enable priorities for all queues
|
||||||
|
CELERY_TASK_QUEUE_MAX_PRIORITY = 3
|
||||||
|
# On RabbitMQ, higher number is higher priority, and having less levels makes rabbitmq use less CPU and RAM
|
||||||
|
PRIORITY_CELERY_LOW = 1
|
||||||
|
PRIORITY_CELERY_MID = 2
|
||||||
|
PRIORITY_CELERY_HIGH = 3
|
||||||
|
PRIORITY_CELERY_LOWEST_FUNC = min
|
||||||
|
PRIORITY_CELERY_HIGHEST_FUNC = max
|
||||||
|
# Set default
|
||||||
|
CELERY_TASK_DEFAULT_PRIORITY = PRIORITY_CELERY_MID
|
||||||
|
elif CELERY_BROKER_URL.startswith("redis://"):
|
||||||
|
# https://docs.celeryq.dev/en/latest/userguide/routing.html#redis-message-priorities
|
||||||
|
CELERY_BROKER_TRANSPORT_OPTIONS.update({
|
||||||
|
"queue_order_strategy": "priority",
|
||||||
|
"sep": ":",
|
||||||
|
"priority_steps": [0, 4, 8]
|
||||||
|
})
|
||||||
|
# On redis, lower number is higher priority, and it appears that there are always levels 0-9 even though it
|
||||||
|
# is only really executed based on the 3 steps listed above.
|
||||||
|
PRIORITY_CELERY_LOW = 9
|
||||||
|
PRIORITY_CELERY_MID = 5
|
||||||
|
PRIORITY_CELERY_HIGH = 0
|
||||||
|
PRIORITY_CELERY_LOWEST_FUNC = max
|
||||||
|
PRIORITY_CELERY_HIGHEST_FUNC = min
|
||||||
|
CELERY_TASK_DEFAULT_PRIORITY = PRIORITY_CELERY_MID
|
||||||
|
else:
|
||||||
|
# No priority support assumed
|
||||||
|
PRIORITY_CELERY_LOW = 0
|
||||||
|
PRIORITY_CELERY_MID = 0
|
||||||
|
PRIORITY_CELERY_HIGH = 0
|
||||||
|
PRIORITY_CELERY_LOWEST_FUNC = min
|
||||||
|
PRIORITY_CELERY_HIGHEST_FUNC = max
|
||||||
else:
|
else:
|
||||||
CELERY_TASK_ALWAYS_EAGER = True
|
CELERY_TASK_ALWAYS_EAGER = True
|
||||||
|
PRIORITY_CELERY_LOW = 0
|
||||||
|
PRIORITY_CELERY_MID = 0
|
||||||
|
PRIORITY_CELERY_HIGH = 0
|
||||||
|
PRIORITY_CELERY_LOWEST_FUNC = min
|
||||||
|
PRIORITY_CELERY_HIGHEST_FUNC = max
|
||||||
|
|
||||||
CACHE_TICKETS_HOURS = config.getint('cache', 'tickets', fallback=24 * 3)
|
CACHE_TICKETS_HOURS = config.getint('cache', 'tickets', fallback=24 * 3)
|
||||||
|
|
||||||
|
|||||||
BIN
src/pretix/static/pretixbase/img/favicon-16.png
Normal file
|
After Width: | Height: | Size: 512 B |
BIN
src/pretix/static/pretixbase/img/favicon-32.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/pretix/static/pretixbase/img/favicon-64.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/pretix/static/pretixbase/img/favicon-debug-16.png
Normal file
|
After Width: | Height: | Size: 429 B |
BIN
src/pretix/static/pretixbase/img/favicon-debug-32.png
Normal file
|
After Width: | Height: | Size: 842 B |
BIN
src/pretix/static/pretixbase/img/favicon-debug-64.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 512 B |
BIN
src/pretix/static/pretixbase/img/icons/favicon-180x180.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 7.2 KiB |