mirror of
https://github.com/pretix/pretix.git
synced 2025-12-14 13:32:28 +00:00
Compare commits
2 Commits
no-ordinal
...
fix-datasy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6baf11c6d | ||
|
|
cfbe00d24d |
@@ -91,7 +91,7 @@ dependencies = [
|
|||||||
"redis==6.4.*",
|
"redis==6.4.*",
|
||||||
"reportlab==4.4.*",
|
"reportlab==4.4.*",
|
||||||
"requests==2.32.*",
|
"requests==2.32.*",
|
||||||
"sentry-sdk==2.40.*",
|
"sentry-sdk==2.38.*",
|
||||||
"sepaxml==2.6.*",
|
"sepaxml==2.6.*",
|
||||||
"stripe==7.9.*",
|
"stripe==7.9.*",
|
||||||
"text-unidecode==1.*",
|
"text-unidecode==1.*",
|
||||||
|
|||||||
@@ -764,13 +764,7 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
|
|||||||
) and not order.invoices.last()
|
) and not order.invoices.last()
|
||||||
invoice = None
|
invoice = None
|
||||||
if gen_invoice:
|
if gen_invoice:
|
||||||
try:
|
|
||||||
invoice = generate_invoice(order, trigger_pdf=True)
|
invoice = generate_invoice(order, trigger_pdf=True)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
# Refresh serializer only after running signals
|
# Refresh serializer only after running signals
|
||||||
prefetch_related_objects([order], self._positions_prefetch(request))
|
prefetch_related_objects([order], self._positions_prefetch(request))
|
||||||
|
|||||||
@@ -439,12 +439,8 @@ def register_default_webhook_events(sender, **kwargs):
|
|||||||
def notify_webhooks(logentry_ids: list):
|
def notify_webhooks(logentry_ids: list):
|
||||||
if not isinstance(logentry_ids, list):
|
if not isinstance(logentry_ids, list):
|
||||||
logentry_ids = [logentry_ids]
|
logentry_ids = [logentry_ids]
|
||||||
qs = LogEntry.all.select_related(
|
qs = LogEntry.all.select_related('event', 'event__organizer', 'organizer').filter(id__in=logentry_ids)
|
||||||
'event', 'event__organizer', 'organizer'
|
_org, _at, webhooks = None, None, None
|
||||||
).order_by(
|
|
||||||
'action_type', 'organizer_id', 'event_id',
|
|
||||||
).filter(id__in=logentry_ids)
|
|
||||||
_org, _at, _ev, webhooks = None, None, None, None
|
|
||||||
for logentry in qs:
|
for logentry in qs:
|
||||||
if not logentry.organizer:
|
if not logentry.organizer:
|
||||||
break # We need to know the organizer
|
break # We need to know the organizer
|
||||||
@@ -454,7 +450,7 @@ def notify_webhooks(logentry_ids: list):
|
|||||||
if not notification_type:
|
if not notification_type:
|
||||||
break # Ignore, no webhooks for this event type
|
break # Ignore, no webhooks for this event type
|
||||||
|
|
||||||
if _org != logentry.organizer or _at != logentry.action_type or _ev != logentry.event_id or webhooks is None:
|
if _org != logentry.organizer or _at != logentry.action_type or webhooks is None:
|
||||||
_org = logentry.organizer
|
_org = logentry.organizer
|
||||||
_at = logentry.action_type
|
_at = logentry.action_type
|
||||||
|
|
||||||
|
|||||||
@@ -105,18 +105,6 @@ class BaseExporter:
|
|||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@property
|
|
||||||
def repeatable_read(self) -> bool:
|
|
||||||
"""
|
|
||||||
If ``True``, this exporter will be run in a REPEATABLE READ transaction. This ensures consistent results for
|
|
||||||
all queries performed by the exporter, but creates a performance burden on the database server. We recommend to
|
|
||||||
disable this for exporters that take very long to run and do not rely on this behavior, such as export of lists
|
|
||||||
to CSV files.
|
|
||||||
|
|
||||||
Defaults to ``True`` for now, but default may change in future versions.
|
|
||||||
"""
|
|
||||||
return True
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ class InvoiceExporter(InvoiceExporterMixin, BaseExporter):
|
|||||||
identifier = 'invoices'
|
identifier = 'invoices'
|
||||||
verbose_name = _('All invoices')
|
verbose_name = _('All invoices')
|
||||||
description = _('Download all invoices created by the system as a ZIP file of PDF files.')
|
description = _('Download all invoices created by the system as a ZIP file of PDF files.')
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
def render(self, form_data: dict, output_file=None):
|
def render(self, form_data: dict, output_file=None):
|
||||||
qs = self.invoices_queryset(form_data).filter(shredded=False)
|
qs = self.invoices_queryset(form_data).filter(shredded=False)
|
||||||
@@ -181,7 +180,6 @@ class InvoiceDataExporter(InvoiceExporterMixin, MultiSheetListExporter):
|
|||||||
'includes two sheets, one with a line for every invoice, and one with a line for every position of '
|
'includes two sheets, one with a line for every invoice, and one with a line for every position of '
|
||||||
'every invoice.')
|
'every invoice.')
|
||||||
featured = True
|
featured = True
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_form_fields(self):
|
def additional_form_fields(self):
|
||||||
|
|||||||
@@ -90,7 +90,6 @@ class OrderListExporter(MultiSheetListExporter):
|
|||||||
'with a line for every order, one with a line for every order position, and one with '
|
'with a line for every order, one with a line for every order position, and one with '
|
||||||
'a line for every additional fee charged in an order.')
|
'a line for every additional fee charged in an order.')
|
||||||
featured = True
|
featured = True
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def providers(self):
|
def providers(self):
|
||||||
@@ -843,7 +842,6 @@ class TransactionListExporter(ListExporter):
|
|||||||
description = gettext_lazy('Download a spreadsheet of all substantial changes to orders, i.e. all changes to '
|
description = gettext_lazy('Download a spreadsheet of all substantial changes to orders, i.e. all changes to '
|
||||||
'products, prices or tax rates. The information is only accurate for changes made with '
|
'products, prices or tax rates. The information is only accurate for changes made with '
|
||||||
'pretix versions released after October 2021.')
|
'pretix versions released after October 2021.')
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def providers(self):
|
def providers(self):
|
||||||
@@ -1022,7 +1020,6 @@ class PaymentListExporter(ListExporter):
|
|||||||
category = pgettext_lazy('export_category', 'Order data')
|
category = pgettext_lazy('export_category', 'Order data')
|
||||||
description = gettext_lazy('Download a spreadsheet of all payments or refunds of every order.')
|
description = gettext_lazy('Download a spreadsheet of all payments or refunds of every order.')
|
||||||
featured = True
|
featured = True
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_form_fields(self):
|
def additional_form_fields(self):
|
||||||
@@ -1162,7 +1159,7 @@ class QuotaListExporter(ListExporter):
|
|||||||
yield headers
|
yield headers
|
||||||
|
|
||||||
quotas = list(self.event.quotas.select_related('subevent'))
|
quotas = list(self.event.quotas.select_related('subevent'))
|
||||||
qa = QuotaAvailability(full_results=True, allow_repeatable_read=True)
|
qa = QuotaAvailability(full_results=True)
|
||||||
qa.queue(*quotas)
|
qa.queue(*quotas)
|
||||||
qa.compute()
|
qa.compute()
|
||||||
|
|
||||||
@@ -1203,7 +1200,6 @@ class GiftcardTransactionListExporter(OrganizerLevelExportMixin, ListExporter):
|
|||||||
organizer_required_permission = 'can_manage_gift_cards'
|
organizer_required_permission = 'can_manage_gift_cards'
|
||||||
category = pgettext_lazy('export_category', 'Gift cards')
|
category = pgettext_lazy('export_category', 'Gift cards')
|
||||||
description = gettext_lazy('Download a spreadsheet of all gift card transactions.')
|
description = gettext_lazy('Download a spreadsheet of all gift card transactions.')
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_form_fields(self):
|
def additional_form_fields(self):
|
||||||
@@ -1262,7 +1258,6 @@ class GiftcardRedemptionListExporter(ListExporter):
|
|||||||
verbose_name = gettext_lazy('Gift card redemptions')
|
verbose_name = gettext_lazy('Gift card redemptions')
|
||||||
category = pgettext_lazy('export_category', 'Order data')
|
category = pgettext_lazy('export_category', 'Order data')
|
||||||
description = gettext_lazy('Download a spreadsheet of all payments or refunds that involve gift cards.')
|
description = gettext_lazy('Download a spreadsheet of all payments or refunds that involve gift cards.')
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
def iterate_list(self, form_data):
|
def iterate_list(self, form_data):
|
||||||
payments = OrderPayment.objects.filter(
|
payments = OrderPayment.objects.filter(
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ class ReusableMediaExporter(OrganizerLevelExportMixin, ListExporter):
|
|||||||
verbose_name = _('Reusable media')
|
verbose_name = _('Reusable media')
|
||||||
category = pgettext_lazy('export_category', 'Reusable media')
|
category = pgettext_lazy('export_category', 'Reusable media')
|
||||||
description = _('Download a spread sheet with the data of all reusable medias on your account.')
|
description = _('Download a spread sheet with the data of all reusable medias on your account.')
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
def iterate_list(self, form_data):
|
def iterate_list(self, form_data):
|
||||||
media = ReusableMedium.objects.filter(
|
media = ReusableMedium.objects.filter(
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ class WaitingListExporter(ListExporter):
|
|||||||
verbose_name = _('Waiting list')
|
verbose_name = _('Waiting list')
|
||||||
category = pgettext_lazy('export_category', 'Waiting list')
|
category = pgettext_lazy('export_category', 'Waiting list')
|
||||||
description = _('Download a spread sheet with all your waiting list data.')
|
description = _('Download a spread sheet with all your waiting list data.')
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
# map selected status to label and queryset-filter
|
# map selected status to label and queryset-filter
|
||||||
status_filters = [
|
status_filters = [
|
||||||
|
|||||||
@@ -1840,10 +1840,6 @@ class OrderPayment(models.Model):
|
|||||||
))
|
))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if locked_instance.state == OrderPayment.PAYMENT_STATE_CANCELED:
|
|
||||||
# Never send mails when the payment was already canceled intentionally
|
|
||||||
send_mail = False
|
|
||||||
|
|
||||||
if isinstance(info, str):
|
if isinstance(info, str):
|
||||||
locked_instance.info = info
|
locked_instance.info = info
|
||||||
elif info:
|
elif info:
|
||||||
@@ -1859,10 +1855,6 @@ class OrderPayment(models.Model):
|
|||||||
'data': log_data,
|
'data': log_data,
|
||||||
}, user=user, auth=auth)
|
}, user=user, auth=auth)
|
||||||
|
|
||||||
if self.order.status in (Order.STATUS_PAID, Order.STATUS_CANCELED, Order.STATUS_EXPIRED):
|
|
||||||
# No reason to send mail, as the payment is no longer really expected
|
|
||||||
send_mail = False
|
|
||||||
|
|
||||||
if send_mail:
|
if send_mail:
|
||||||
with language(self.order.locale, self.order.event.settings.region):
|
with language(self.order.locale, self.order.event.settings.region):
|
||||||
email_subject = self.order.event.settings.mail_subject_order_payment_failed
|
email_subject = self.order.event.settings.mail_subject_order_payment_failed
|
||||||
@@ -1969,7 +1961,6 @@ class OrderPayment(models.Model):
|
|||||||
self.order.invoice_dirty
|
self.order.invoice_dirty
|
||||||
)
|
)
|
||||||
if gen_invoice:
|
if gen_invoice:
|
||||||
try:
|
|
||||||
if invoices:
|
if invoices:
|
||||||
last_i = self.order.invoices.filter(is_cancellation=False).last()
|
last_i = self.order.invoices.filter(is_cancellation=False).last()
|
||||||
if not last_i.canceled:
|
if not last_i.canceled:
|
||||||
@@ -1978,11 +1969,6 @@ class OrderPayment(models.Model):
|
|||||||
self.order,
|
self.order,
|
||||||
trigger_pdf=not send_mail or not self.order.event.settings.invoice_email_attachment
|
trigger_pdf=not send_mail or not self.order.event.settings.invoice_email_attachment
|
||||||
)
|
)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
self.order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
transmit_invoice_task = invoice_transmission_separately(invoice)
|
transmit_invoice_task = invoice_transmission_separately(invoice)
|
||||||
transmit_invoice_mail = not transmit_invoice_task and self.order.event.settings.invoice_email_attachment and self.order.email
|
transmit_invoice_mail = not transmit_invoice_task and self.order.event.settings.invoice_email_attachment and self.order.email
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ from pretix.base.signals import (
|
|||||||
periodic_task, register_data_exporters, register_multievent_data_exporters,
|
periodic_task, register_data_exporters, register_multievent_data_exporters,
|
||||||
)
|
)
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
from pretix.helpers import OF_SELF, repeatable_reads_transaction
|
from pretix.helpers import OF_SELF
|
||||||
from pretix.helpers.urls import build_absolute_uri
|
from pretix.helpers.urls import build_absolute_uri
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -80,12 +80,7 @@ def export(self, event: Event, fileid: str, provider: str, form_data: Dict[str,
|
|||||||
continue
|
continue
|
||||||
ex = response(event, event.organizer, set_progress)
|
ex = response(event, event.organizer, set_progress)
|
||||||
if ex.identifier == provider:
|
if ex.identifier == provider:
|
||||||
if ex.repeatable_read:
|
|
||||||
with repeatable_reads_transaction():
|
|
||||||
d = ex.render(form_data)
|
d = ex.render(form_data)
|
||||||
else:
|
|
||||||
d = ex.render(form_data)
|
|
||||||
|
|
||||||
if d is None:
|
if d is None:
|
||||||
raise ExportError(
|
raise ExportError(
|
||||||
gettext('Your export did not contain any data.')
|
gettext('Your export did not contain any data.')
|
||||||
@@ -156,10 +151,6 @@ def multiexport(self, organizer: Organizer, user: User, device: int, token: int,
|
|||||||
gettext('You do not have sufficient permission to perform this export.')
|
gettext('You do not have sufficient permission to perform this export.')
|
||||||
)
|
)
|
||||||
|
|
||||||
if ex.repeatable_read:
|
|
||||||
with repeatable_reads_transaction():
|
|
||||||
d = ex.render(form_data)
|
|
||||||
else:
|
|
||||||
d = ex.render(form_data)
|
d = ex.render(form_data)
|
||||||
if d is None:
|
if d is None:
|
||||||
raise ExportError(
|
raise ExportError(
|
||||||
@@ -218,10 +209,6 @@ def _run_scheduled_export(schedule, context: Union[Event, Organizer], exporter,
|
|||||||
try:
|
try:
|
||||||
if not exporter:
|
if not exporter:
|
||||||
raise ExportError("Export type not found.")
|
raise ExportError("Export type not found.")
|
||||||
if exporter.repeatable_read:
|
|
||||||
with repeatable_reads_transaction():
|
|
||||||
d = exporter.render(schedule.export_form_data)
|
|
||||||
else:
|
|
||||||
d = exporter.render(schedule.export_form_data)
|
d = exporter.render(schedule.export_form_data)
|
||||||
if d is None:
|
if d is None:
|
||||||
raise ExportEmptyError(
|
raise ExportEmptyError(
|
||||||
|
|||||||
@@ -671,7 +671,6 @@ def send_invoices_to_organizer(sender, **kwargs):
|
|||||||
event=i.event,
|
event=i.event,
|
||||||
invoices=[i],
|
invoices=[i],
|
||||||
auto_email=True,
|
auto_email=True,
|
||||||
plain_text_only=True,
|
|
||||||
)
|
)
|
||||||
i.sent_to_organizer = True
|
i.sent_to_organizer = True
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
# 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 logging
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
@@ -34,8 +33,8 @@ from pretix.base.modelimport import DataImportError, ImportColumn, parse_csv
|
|||||||
from pretix.base.modelimport_orders import get_order_import_columns
|
from pretix.base.modelimport_orders import get_order_import_columns
|
||||||
from pretix.base.modelimport_vouchers import get_voucher_import_columns
|
from pretix.base.modelimport_vouchers import get_voucher_import_columns
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
CachedFile, Event, InvoiceAddress, LogEntry, Order, OrderPayment,
|
CachedFile, Event, InvoiceAddress, Order, OrderPayment, OrderPosition,
|
||||||
OrderPosition, User, Voucher,
|
User, Voucher,
|
||||||
)
|
)
|
||||||
from pretix.base.models.orders import Transaction
|
from pretix.base.models.orders import Transaction
|
||||||
from pretix.base.services.invoices import generate_invoice, invoice_qualified
|
from pretix.base.services.invoices import generate_invoice, invoice_qualified
|
||||||
@@ -44,8 +43,6 @@ from pretix.base.services.tasks import ProfiledEventTask
|
|||||||
from pretix.base.signals import order_paid, order_placed
|
from pretix.base.signals import order_paid, order_placed
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def _validate(cf: CachedFile, charset: str, cols: List[ImportColumn], settings: dict):
|
def _validate(cf: CachedFile, charset: str, cols: List[ImportColumn], settings: dict):
|
||||||
try:
|
try:
|
||||||
@@ -178,7 +175,6 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
raise DataImportError(_('The seat you selected has already been taken. Please select a different seat.'))
|
raise DataImportError(_('The seat you selected has already been taken. Please select a different seat.'))
|
||||||
|
|
||||||
save_transactions = []
|
save_transactions = []
|
||||||
save_logentries = []
|
|
||||||
for o in orders:
|
for o in orders:
|
||||||
o.total = sum([c.price for c in o._positions]) # currently no support for fees
|
o.total = sum([c.price for c in o._positions]) # currently no support for fees
|
||||||
if o.total == Decimal('0.00'):
|
if o.total == Decimal('0.00'):
|
||||||
@@ -215,15 +211,13 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
o._address.save()
|
o._address.save()
|
||||||
for c in cols:
|
for c in cols:
|
||||||
c.save(o)
|
c.save(o)
|
||||||
save_logentries.append(o.log_action(
|
o.log_action(
|
||||||
'pretix.event.order.placed',
|
'pretix.event.order.placed',
|
||||||
user=user,
|
user=user,
|
||||||
data={'source': 'import'},
|
data={'source': 'import'}
|
||||||
save=False,
|
)
|
||||||
))
|
|
||||||
save_transactions += o.create_transactions(is_new=True, fees=[], positions=o._positions, save=False)
|
save_transactions += o.create_transactions(is_new=True, fees=[], positions=o._positions, save=False)
|
||||||
Transaction.objects.bulk_create(save_transactions)
|
Transaction.objects.bulk_create(save_transactions)
|
||||||
LogEntry.bulk_create_and_postprocess(save_logentries)
|
|
||||||
|
|
||||||
for o in orders:
|
for o in orders:
|
||||||
with language(o.locale, event.settings.region):
|
with language(o.locale, event.settings.region):
|
||||||
@@ -236,13 +230,7 @@ def import_orders(event: Event, fileid: str, settings: dict, locale: str, user,
|
|||||||
(event.settings.get('invoice_generate') == 'paid' and o.status == Order.STATUS_PAID)
|
(event.settings.get('invoice_generate') == 'paid' and o.status == Order.STATUS_PAID)
|
||||||
) and not o.invoices.last()
|
) and not o.invoices.last()
|
||||||
if gen_invoice:
|
if gen_invoice:
|
||||||
try:
|
|
||||||
generate_invoice(o, trigger_pdf=True)
|
generate_invoice(o, trigger_pdf=True)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
o.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
except DataImportError:
|
except DataImportError:
|
||||||
raise ValidationError(_('We were not able to process your request completely as the server was too busy. '
|
raise ValidationError(_('We were not able to process your request completely as the server was too busy. '
|
||||||
'Please try again.'))
|
'Please try again.'))
|
||||||
@@ -298,16 +286,13 @@ def import_vouchers(event: Event, fileid: str, settings: dict, locale: str, user
|
|||||||
raise DataImportError(
|
raise DataImportError(
|
||||||
_('The seat you selected has already been taken. Please select a different seat.'))
|
_('The seat you selected has already been taken. Please select a different seat.'))
|
||||||
|
|
||||||
save_logentries = []
|
|
||||||
for v in vouchers:
|
for v in vouchers:
|
||||||
v.save()
|
v.save()
|
||||||
save_logentries.append(v.log_action(
|
v.log_action(
|
||||||
'pretix.voucher.added',
|
'pretix.voucher.added',
|
||||||
user=user,
|
user=user,
|
||||||
data={'source': 'import'},
|
data={'source': 'import'}
|
||||||
save=False,
|
)
|
||||||
))
|
|
||||||
for c in cols:
|
for c in cols:
|
||||||
c.save(v)
|
c.save(v)
|
||||||
LogEntry.bulk_create_and_postprocess(save_logentries)
|
|
||||||
cf.delete()
|
cf.delete()
|
||||||
|
|||||||
@@ -41,11 +41,7 @@ def notify(logentry_ids: list):
|
|||||||
if not isinstance(logentry_ids, list):
|
if not isinstance(logentry_ids, list):
|
||||||
logentry_ids = [logentry_ids]
|
logentry_ids = [logentry_ids]
|
||||||
|
|
||||||
qs = LogEntry.all.select_related(
|
qs = LogEntry.all.select_related('event', 'event__organizer').filter(id__in=logentry_ids)
|
||||||
'event', 'event__organizer'
|
|
||||||
).order_by(
|
|
||||||
'action_type', 'event_id',
|
|
||||||
).filter(id__in=logentry_ids)
|
|
||||||
|
|
||||||
_event, _at, notify_specific, notify_global = None, None, None, None
|
_event, _at, notify_specific, notify_global = None, None, None, None
|
||||||
for logentry in qs:
|
for logentry in qs:
|
||||||
|
|||||||
@@ -264,13 +264,7 @@ def reactivate_order(order: Order, force: bool=False, user: User=None, auth=None
|
|||||||
|
|
||||||
num_invoices = order.invoices.filter(is_cancellation=False).count()
|
num_invoices = order.invoices.filter(is_cancellation=False).count()
|
||||||
if num_invoices > 0 and order.invoices.filter(is_cancellation=True).count() >= num_invoices and invoice_qualified(order):
|
if num_invoices > 0 and order.invoices.filter(is_cancellation=True).count() >= num_invoices and invoice_qualified(order):
|
||||||
try:
|
|
||||||
generate_invoice(order)
|
generate_invoice(order)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def extend_order(order: Order, new_date: datetime, force: bool=False, valid_if_pending: bool=None, user: User=None, auth=None):
|
def extend_order(order: Order, new_date: datetime, force: bool=False, valid_if_pending: bool=None, user: User=None, auth=None):
|
||||||
@@ -318,13 +312,7 @@ def extend_order(order: Order, new_date: datetime, force: bool=False, valid_if_p
|
|||||||
if was_expired:
|
if was_expired:
|
||||||
num_invoices = order.invoices.filter(is_cancellation=False).count()
|
num_invoices = order.invoices.filter(is_cancellation=False).count()
|
||||||
if num_invoices > 0 and order.invoices.filter(is_cancellation=True).count() >= num_invoices and invoice_qualified(order):
|
if num_invoices > 0 and order.invoices.filter(is_cancellation=True).count() >= num_invoices and invoice_qualified(order):
|
||||||
try:
|
|
||||||
generate_invoice(order)
|
generate_invoice(order)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
order.create_transactions()
|
order.create_transactions()
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
@@ -409,7 +397,6 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False
|
|||||||
|
|
||||||
if order.event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
|
if order.event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
|
||||||
if not invoice:
|
if not invoice:
|
||||||
try:
|
|
||||||
invoice = generate_invoice(
|
invoice = generate_invoice(
|
||||||
order,
|
order,
|
||||||
# send_mail will trigger PDF generation later
|
# send_mail will trigger PDF generation later
|
||||||
@@ -417,11 +404,6 @@ def approve_order(order, user=None, send_mail: bool=True, auth=None, force=False
|
|||||||
)
|
)
|
||||||
if transmit_invoice_task:
|
if transmit_invoice_task:
|
||||||
transmit_invoice.apply_async(args=(order.event_id, invoice.pk, False))
|
transmit_invoice.apply_async(args=(order.event_id, invoice.pk, False))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
if send_mail:
|
if send_mail:
|
||||||
with language(order.locale, order.event.settings.region):
|
with language(order.locale, order.event.settings.region):
|
||||||
@@ -626,13 +608,7 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
|||||||
order.save(update_fields=['status', 'cancellation_date', 'total'])
|
order.save(update_fields=['status', 'cancellation_date', 'total'])
|
||||||
|
|
||||||
if cancel_invoice and i:
|
if cancel_invoice and i:
|
||||||
try:
|
|
||||||
invoices.append(generate_invoice(order))
|
invoices.append(generate_invoice(order))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
else:
|
else:
|
||||||
order.status = Order.STATUS_CANCELED
|
order.status = Order.STATUS_CANCELED
|
||||||
order.cancellation_date = now()
|
order.cancellation_date = now()
|
||||||
@@ -1330,7 +1306,6 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
if invoice_required:
|
if invoice_required:
|
||||||
try:
|
|
||||||
invoice = generate_invoice(
|
invoice = generate_invoice(
|
||||||
order,
|
order,
|
||||||
# send_mail will trigger PDF generation later
|
# send_mail will trigger PDF generation later
|
||||||
@@ -1338,11 +1313,6 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
|||||||
)
|
)
|
||||||
if transmit_invoice_task:
|
if transmit_invoice_task:
|
||||||
transmit_invoice.apply_async(args=(event.pk, invoice.pk, False))
|
transmit_invoice.apply_async(args=(event.pk, invoice.pk, False))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
if order.email:
|
if order.email:
|
||||||
if order.require_approval:
|
if order.require_approval:
|
||||||
@@ -2731,13 +2701,7 @@ class OrderChangeManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if split_order.total != Decimal('0.00') and self.order.invoices.filter(is_cancellation=False).last():
|
if split_order.total != Decimal('0.00') and self.order.invoices.filter(is_cancellation=False).last():
|
||||||
try:
|
|
||||||
generate_invoice(split_order)
|
generate_invoice(split_order)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
split_order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
order_split.send(sender=self.order.event, original=self.order, split_order=split_order)
|
order_split.send(sender=self.order.event, original=self.order, split_order=split_order)
|
||||||
return split_order
|
return split_order
|
||||||
@@ -2848,27 +2812,15 @@ class OrderChangeManager:
|
|||||||
|
|
||||||
if order_now_qualified:
|
if order_now_qualified:
|
||||||
if invoice_should_be_generated_now:
|
if invoice_should_be_generated_now:
|
||||||
try:
|
|
||||||
if i and not i.canceled:
|
if i and not i.canceled:
|
||||||
self._invoices.append(generate_cancellation(i))
|
self._invoices.append(generate_cancellation(i))
|
||||||
self._invoices.append(generate_invoice(self.order))
|
self._invoices.append(generate_invoice(self.order))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
self.order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
elif invoice_should_be_generated_later:
|
elif invoice_should_be_generated_later:
|
||||||
self.order.invoice_dirty = True
|
self.order.invoice_dirty = True
|
||||||
self.order.save(update_fields=["invoice_dirty"])
|
self.order.save(update_fields=["invoice_dirty"])
|
||||||
else:
|
else:
|
||||||
try:
|
|
||||||
if i and not i.canceled:
|
if i and not i.canceled:
|
||||||
self._invoices.append(generate_cancellation(i))
|
self._invoices.append(generate_cancellation(i))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
self.order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
def _check_complete_cancel(self):
|
def _check_complete_cancel(self):
|
||||||
current = self.order.positions.count()
|
current = self.order.positions.count()
|
||||||
@@ -3294,14 +3246,8 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
|
|||||||
has_active_invoice = i and not i.canceled
|
has_active_invoice = i and not i.canceled
|
||||||
|
|
||||||
if has_active_invoice and order.total != oldtotal:
|
if has_active_invoice and order.total != oldtotal:
|
||||||
try:
|
|
||||||
generate_cancellation(i)
|
generate_cancellation(i)
|
||||||
generate_invoice(order)
|
generate_invoice(order)
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
new_invoice_created = True
|
new_invoice_created = True
|
||||||
|
|
||||||
elif (not has_active_invoice or order.invoice_dirty) and invoice_qualified(order):
|
elif (not has_active_invoice or order.invoice_dirty) and invoice_qualified(order):
|
||||||
@@ -3309,7 +3255,6 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
|
|||||||
order.event.settings.get('invoice_generate') == 'paid' and
|
order.event.settings.get('invoice_generate') == 'paid' and
|
||||||
new_payment.payment_provider.requires_invoice_immediately
|
new_payment.payment_provider.requires_invoice_immediately
|
||||||
):
|
):
|
||||||
try:
|
|
||||||
if has_active_invoice:
|
if has_active_invoice:
|
||||||
generate_cancellation(i)
|
generate_cancellation(i)
|
||||||
i = generate_invoice(order)
|
i = generate_invoice(order)
|
||||||
@@ -3317,11 +3262,6 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
|
|||||||
order.log_action('pretix.event.order.invoice.generated', data={
|
order.log_action('pretix.event.order.invoice.generated', data={
|
||||||
'invoice': i.pk
|
'invoice': i.pk
|
||||||
})
|
})
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
|
|
||||||
order.create_transactions()
|
order.create_transactions()
|
||||||
return old_fee, new_fee, fee, new_payment, new_invoice_created
|
return old_fee, new_fee, fee, new_payment, new_invoice_created
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ from itertools import zip_longest
|
|||||||
|
|
||||||
import django_redis
|
import django_redis
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import connection, models
|
from django.db import models
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Case, Count, F, Func, Max, OuterRef, Q, Subquery, Sum, Value, When,
|
Case, Count, F, Func, Max, OuterRef, Q, Subquery, Sum, Value, When,
|
||||||
prefetch_related_objects,
|
prefetch_related_objects,
|
||||||
@@ -64,8 +64,7 @@ class QuotaAvailability:
|
|||||||
* count_cart (dict mapping quotas to ints)
|
* count_cart (dict mapping quotas to ints)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, count_waitinglist=True, ignore_closed=False, full_results=False, early_out=True,
|
def __init__(self, count_waitinglist=True, ignore_closed=False, full_results=False, early_out=True):
|
||||||
allow_repeatable_read=False):
|
|
||||||
"""
|
"""
|
||||||
Initialize a new quota availability calculator
|
Initialize a new quota availability calculator
|
||||||
|
|
||||||
@@ -87,8 +86,6 @@ class QuotaAvailability:
|
|||||||
keep the database-level quota cache up to date so backend overviews render quickly. If you
|
keep the database-level quota cache up to date so backend overviews render quickly. If you
|
||||||
do not care about keeping the cache up to date, you can set this to ``False`` for further
|
do not care about keeping the cache up to date, you can set this to ``False`` for further
|
||||||
performance improvements.
|
performance improvements.
|
||||||
|
|
||||||
:param allow_repeatable_read: Allow to run this even in REPEATABLE READ mode, generally not advised.
|
|
||||||
"""
|
"""
|
||||||
self._queue = []
|
self._queue = []
|
||||||
self._count_waitinglist = count_waitinglist
|
self._count_waitinglist = count_waitinglist
|
||||||
@@ -98,7 +95,6 @@ class QuotaAvailability:
|
|||||||
self._var_to_quotas = defaultdict(set)
|
self._var_to_quotas = defaultdict(set)
|
||||||
self._early_out = early_out
|
self._early_out = early_out
|
||||||
self._quota_objects = {}
|
self._quota_objects = {}
|
||||||
self._allow_repeatable_read = allow_repeatable_read
|
|
||||||
self.results = {}
|
self.results = {}
|
||||||
self.count_paid_orders = defaultdict(int)
|
self.count_paid_orders = defaultdict(int)
|
||||||
self.count_pending_orders = defaultdict(int)
|
self.count_pending_orders = defaultdict(int)
|
||||||
@@ -123,10 +119,6 @@ class QuotaAvailability:
|
|||||||
Compute the queued quotas. If ``allow_cache`` is set, results may also be taken from a cache that might
|
Compute the queued quotas. If ``allow_cache`` is set, results may also be taken from a cache that might
|
||||||
be a few minutes outdated. In this case, you may not rely on the results in the ``count_*`` properties.
|
be a few minutes outdated. In this case, you may not rely on the results in the ``count_*`` properties.
|
||||||
"""
|
"""
|
||||||
if not self._allow_repeatable_read and getattr(connection, "tx_in_repeatable_read", False):
|
|
||||||
raise ValueError("You cannot compute quotas in REPEATABLE READ mode unless you explicitly opted in to "
|
|
||||||
"do so.")
|
|
||||||
|
|
||||||
now_dt = now_dt or now()
|
now_dt = now_dt or now()
|
||||||
quota_ids_set = {q.id for q in self._queue}
|
quota_ids_set = {q.id for q in self._queue}
|
||||||
if not quota_ids_set:
|
if not quota_ids_set:
|
||||||
|
|||||||
@@ -21,8 +21,6 @@
|
|||||||
#
|
#
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.functional import lazy
|
|
||||||
from django.utils.html import format_html
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from pretix.base.modelimport_orders import get_order_import_columns
|
from pretix.base.modelimport_orders import get_order_import_columns
|
||||||
@@ -73,9 +71,6 @@ class ProcessForm(forms.Form):
|
|||||||
raise NotImplementedError() # noqa
|
raise NotImplementedError() # noqa
|
||||||
|
|
||||||
|
|
||||||
format_html_lazy = lazy(format_html, str)
|
|
||||||
|
|
||||||
|
|
||||||
class OrdersProcessForm(ProcessForm):
|
class OrdersProcessForm(ProcessForm):
|
||||||
orders = forms.ChoiceField(
|
orders = forms.ChoiceField(
|
||||||
label=_('Import mode'),
|
label=_('Import mode'),
|
||||||
@@ -96,11 +91,7 @@ class OrdersProcessForm(ProcessForm):
|
|||||||
)
|
)
|
||||||
testmode = forms.BooleanField(
|
testmode = forms.BooleanField(
|
||||||
label=_('Create orders as test mode orders'),
|
label=_('Create orders as test mode orders'),
|
||||||
required=False,
|
required=False
|
||||||
help_text=format_html_lazy(
|
|
||||||
'<div class="alert alert-warning" data-display-dependency="#id_testmode" data-inverse>{}</div>',
|
|
||||||
_('Orders not created in test mode cannot be deleted again after import.')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@@ -109,8 +100,6 @@ class OrdersProcessForm(ProcessForm):
|
|||||||
initital['testmode'] = self.event.testmode
|
initital['testmode'] = self.event.testmode
|
||||||
kwargs['initial'] = initital
|
kwargs['initial'] = initital
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
if not self.event.testmode:
|
|
||||||
self.fields["testmode"].help_text = ""
|
|
||||||
|
|
||||||
def get_columns(self):
|
def get_columns(self):
|
||||||
return get_order_import_columns(self.event)
|
return get_order_import_columns(self.event)
|
||||||
|
|||||||
@@ -455,7 +455,7 @@ class OrderDataSyncSuccessLogEntryType(OrderDataSyncLogEntryType):
|
|||||||
links.append(", ".join(
|
links.append(", ".join(
|
||||||
prov.get_external_link_html(logentry.event, obj['external_link_href'], obj['external_link_display_name'])
|
prov.get_external_link_html(logentry.event, obj['external_link_href'], obj['external_link_display_name'])
|
||||||
for obj in objs
|
for obj in objs
|
||||||
if obj and obj.get('external_link_href') and obj.get('external_link_display_name')
|
if obj and 'external_link_href' in obj and 'external_link_display_name' in obj
|
||||||
))
|
))
|
||||||
|
|
||||||
return mark_safe(escape(super().display(logentry, data)) + "".join("<p>" + link + "</p>" for link in links))
|
return mark_safe(escape(super().display(logentry, data)) + "".join("<p>" + link + "</p>" for link in links))
|
||||||
@@ -522,7 +522,6 @@ def pretixcontrol_orderposition_blocked_display(sender: Event, orderposition, bl
|
|||||||
'pretix.event.order.customer.changed': _('The customer account has been changed.'),
|
'pretix.event.order.customer.changed': _('The customer account has been changed.'),
|
||||||
'pretix.event.order.locale.changed': _('The order locale has been changed.'),
|
'pretix.event.order.locale.changed': _('The order locale has been changed.'),
|
||||||
'pretix.event.order.invoice.generated': _('The invoice has been generated.'),
|
'pretix.event.order.invoice.generated': _('The invoice has been generated.'),
|
||||||
'pretix.event.order.invoice.failed': _('The invoice could not be generated.'),
|
|
||||||
'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
|
'pretix.event.order.invoice.regenerated': _('The invoice has been regenerated.'),
|
||||||
'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
|
'pretix.event.order.invoice.reissued': _('The invoice has been reissued.'),
|
||||||
'pretix.event.order.invoice.sent': _('The invoice {full_invoice_no} has been sent.'),
|
'pretix.event.order.invoice.sent': _('The invoice {full_invoice_no} has been sent.'),
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ class ControlSyncJob(OrderView):
|
|||||||
prov, meta = datasync_providers.get(active_in=self.request.event, identifier=provider)
|
prov, meta = datasync_providers.get(active_in=self.request.event, identifier=provider)
|
||||||
|
|
||||||
if self.request.POST.get("queue_sync") == "true":
|
if self.request.POST.get("queue_sync") == "true":
|
||||||
prov.enqueue_order(self.order, 'user', immediate=True)
|
prov.enqueue_order(self.order, 'user')
|
||||||
messages.success(self.request, _('The sync job has been set to run as soon as possible.'))
|
messages.success(self.request, _('The sync job has been enqueued and will run in the next minutes.'))
|
||||||
elif self.request.POST.get("cancel_job"):
|
elif self.request.POST.get("cancel_job"):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -21,8 +21,7 @@
|
|||||||
#
|
#
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
from django.conf import settings
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
|
|
||||||
from django.db import connection, transaction
|
from django.db import connection, transaction
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
Aggregate, Expression, F, Field, Lookup, OrderBy, Value,
|
Aggregate, Expression, F, Field, Lookup, OrderBy, Value,
|
||||||
@@ -63,43 +62,6 @@ def casual_reads():
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def repeatable_reads_transaction():
|
|
||||||
"""
|
|
||||||
pretix, and Django, operate in the transaction isolation level READ COMMITTED by default. This is not a strong level
|
|
||||||
of isolation, but we NEED to use it: Otherwise e.g. our quota logic breaks, because we need to be able to get the
|
|
||||||
*current* number of tickets sold at any time in a transaction, not the number of tickets sold *before* our transaction
|
|
||||||
started.
|
|
||||||
|
|
||||||
However, this isolation mode has drawbacks, for example during reporting. When a user retrieves a report from the
|
|
||||||
system, it should return numbers that are consistent with each other. However, if the report makes multiple SQL
|
|
||||||
queries in READ COMMITTED mode, the results might be different for each query, causing numbers to be inconsistent
|
|
||||||
with each other.
|
|
||||||
|
|
||||||
This context manager creates a transaction that is running in REPEATABLE READ mode to avoid this problem.
|
|
||||||
|
|
||||||
**You should only make read-only queries during this transaction and not rely on quota calculations.**
|
|
||||||
"""
|
|
||||||
is_under_test = 'tests.testdummy' in settings.INSTALLED_APPS
|
|
||||||
try:
|
|
||||||
with transaction.atomic(durable=not is_under_test):
|
|
||||||
if not is_under_test:
|
|
||||||
# We're not running this in tests, where we can basically not use this since the test runner does its
|
|
||||||
# own transaction logic for efficiency
|
|
||||||
with connection.cursor() as cursor:
|
|
||||||
if 'postgresql' in settings.DATABASES['default']['ENGINE']:
|
|
||||||
cursor.execute('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;')
|
|
||||||
elif 'sqlite' in settings.DATABASES['default']['ENGINE']:
|
|
||||||
pass # noop
|
|
||||||
else:
|
|
||||||
raise ImproperlyConfigured("Cannot set transaction isolation mode on this database backend")
|
|
||||||
|
|
||||||
connection.tx_in_repeatable_read = True
|
|
||||||
yield
|
|
||||||
finally:
|
|
||||||
connection.tx_in_repeatable_read = False
|
|
||||||
|
|
||||||
|
|
||||||
class GroupConcat(Aggregate):
|
class GroupConcat(Aggregate):
|
||||||
function = 'group_concat'
|
function = 'group_concat'
|
||||||
template = '%(function)s(%(distinct)s%(field)s, "%(separator)s")'
|
template = '%(function)s(%(distinct)s%(field)s, "%(separator)s")'
|
||||||
|
|||||||
@@ -76,11 +76,11 @@ def daterange(df, dt, as_html=False):
|
|||||||
return format_html(base_format, _date(df, "j F"), until, _date(dt, "j F Y"))
|
return format_html(base_format, _date(df, "j F"), until, _date(dt, "j F Y"))
|
||||||
elif lng.startswith("en"):
|
elif lng.startswith("en"):
|
||||||
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
|
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
|
||||||
return format_html(base_format, _date(df, "D, N j, Y"))
|
return format_html(base_format, _date(df, "D, N jS, Y"))
|
||||||
elif df.year == dt.year and df.month == dt.month:
|
elif df.year == dt.year and df.month == dt.month:
|
||||||
return format_html(base_format, _date(df, "N j"), until, _date(dt, "j, Y"))
|
return format_html(base_format, _date(df, "N jS"), until, _date(dt, "jS, Y"))
|
||||||
elif df.year == dt.year:
|
elif df.year == dt.year:
|
||||||
return format_html(base_format, _date(df, "N j"), until, _date(dt, "N j, Y"))
|
return format_html(base_format, _date(df, "N jS"), until, _date(dt, "N jS, Y"))
|
||||||
elif lng.startswith("es"):
|
elif lng.startswith("es"):
|
||||||
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
|
if df.year == dt.year and df.month == dt.month and df.day == dt.day:
|
||||||
return format_html(base_format, _date(df, "DATE_FORMAT"))
|
return format_html(base_format, _date(df, "DATE_FORMAT"))
|
||||||
|
|||||||
@@ -38,5 +38,5 @@ SHORT_DATE_FORMAT = 'Y-m-d'
|
|||||||
SHORT_DATETIME_FORMAT = 'Y-m-d H:i'
|
SHORT_DATETIME_FORMAT = 'Y-m-d H:i'
|
||||||
TIME_FORMAT = 'H:i'
|
TIME_FORMAT = 'H:i'
|
||||||
WEEK_FORMAT = '\\W W, o'
|
WEEK_FORMAT = '\\W W, o'
|
||||||
WEEK_DAY_FORMAT = 'D, M j'
|
WEEK_DAY_FORMAT = 'D, M jS'
|
||||||
SHORT_MONTH_DAY_FORMAT = 'd.m.'
|
SHORT_MONTH_DAY_FORMAT = 'd.m.'
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ SHORT_DATE_FORMAT = "Y-m-d"
|
|||||||
SHORT_DATETIME_FORMAT = 'Y-m-d P'
|
SHORT_DATETIME_FORMAT = 'Y-m-d P'
|
||||||
TIME_FORMAT = 'P'
|
TIME_FORMAT = 'P'
|
||||||
WEEK_FORMAT = '\\W W, o'
|
WEEK_FORMAT = '\\W W, o'
|
||||||
WEEK_DAY_FORMAT = 'D, M j'
|
WEEK_DAY_FORMAT = 'D, M jS'
|
||||||
SHORT_MONTH_DAY_FORMAT = 'm/d'
|
SHORT_MONTH_DAY_FORMAT = 'm/d'
|
||||||
|
|
||||||
DATE_INPUT_FORMATS = [
|
DATE_INPUT_FORMATS = [
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ SHORT_DATE_FORMAT = 'm/d/Y'
|
|||||||
SHORT_DATETIME_FORMAT = 'm/d/Y P'
|
SHORT_DATETIME_FORMAT = 'm/d/Y P'
|
||||||
TIME_FORMAT = 'P'
|
TIME_FORMAT = 'P'
|
||||||
WEEK_FORMAT = '\\W W, o'
|
WEEK_FORMAT = '\\W W, o'
|
||||||
WEEK_DAY_FORMAT = 'D, M j'
|
WEEK_DAY_FORMAT = 'D, M jS'
|
||||||
SHORT_MONTH_DAY_FORMAT = 'm/d'
|
SHORT_MONTH_DAY_FORMAT = 'm/d'
|
||||||
|
|
||||||
DATE_INPUT_FORMATS = [
|
DATE_INPUT_FORMATS = [
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ 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-09-26 11:16+0000\n"
|
"POT-Creation-Date: 2025-09-26 11:16+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-03 01:00+0000\n"
|
"PO-Revision-Date: 2025-09-26 13:02+0000\n"
|
||||||
"Last-Translator: Mira <weller@rami.io>\n"
|
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/de/"
|
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix/de/"
|
||||||
">\n"
|
">\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -28214,7 +28214,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/views/modelimport.py:174
|
#: pretix/control/views/modelimport.py:174
|
||||||
msgid "The import was successful."
|
msgid "The import was successful."
|
||||||
msgstr "Der Import war erfolgreich."
|
msgstr "Die Import war erfolgreich."
|
||||||
|
|
||||||
#: pretix/control/views/modelimport.py:186
|
#: pretix/control/views/modelimport.py:186
|
||||||
msgid "We've been unable to parse the uploaded file as a CSV file."
|
msgid "We've been unable to parse the uploaded file as a CSV file."
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ 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-09-26 11:16+0000\n"
|
"POT-Creation-Date: 2025-09-26 11:16+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-03 01:00+0000\n"
|
"PO-Revision-Date: 2025-09-26 13:02+0000\n"
|
||||||
"Last-Translator: Mira <weller@rami.io>\n"
|
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||||
"pretix/pretix/de_Informal/>\n"
|
"pretix/pretix/de_Informal/>\n"
|
||||||
"Language: de_Informal\n"
|
"Language: de_Informal\n"
|
||||||
@@ -28172,7 +28172,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: pretix/control/views/modelimport.py:174
|
#: pretix/control/views/modelimport.py:174
|
||||||
msgid "The import was successful."
|
msgid "The import was successful."
|
||||||
msgstr "Der Import war erfolgreich."
|
msgstr "Die Import war erfolgreich."
|
||||||
|
|
||||||
#: pretix/control/views/modelimport.py:186
|
#: pretix/control/views/modelimport.py:186
|
||||||
msgid "We've been unable to parse the uploaded file as a CSV file."
|
msgid "We've been unable to parse the uploaded file as a CSV file."
|
||||||
|
|||||||
@@ -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-09-26 11:16+0000\n"
|
"POT-Creation-Date: 2025-09-26 11:16+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-04 10:10+0000\n"
|
"PO-Revision-Date: 2025-05-04 16:00+0000\n"
|
||||||
"Last-Translator: Sebastian Bożek <sebastian@log-mar.pl>\n"
|
"Last-Translator: Pekka Sarkola <pekka.sarkola@gispo.fi>\n"
|
||||||
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix/"
|
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||||
"fi/>\n"
|
"fi/>\n"
|
||||||
"Language: fi\n"
|
"Language: fi\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.3\n"
|
"X-Generator: Weblate 5.11.1\n"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:87
|
#: pretix/_base_settings.py:87
|
||||||
msgid "English"
|
msgid "English"
|
||||||
@@ -113,7 +113,7 @@ msgstr "norja (kirjakieli)"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:110
|
#: pretix/_base_settings.py:110
|
||||||
msgid "Polish"
|
msgid "Polish"
|
||||||
msgstr "Puola"
|
msgstr "puola"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:111
|
#: pretix/_base_settings.py:111
|
||||||
msgid "Portuguese (Portugal)"
|
msgid "Portuguese (Portugal)"
|
||||||
|
|||||||
@@ -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-08-19 16:35+0000\n"
|
"POT-Creation-Date: 2025-08-19 16:35+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-03 20:00+0000\n"
|
"PO-Revision-Date: 2025-09-30 16:00+0000\n"
|
||||||
"Last-Translator: Yasunobu YesNo Kawaguchi <kawaguti@gmail.com>\n"
|
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\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"
|
||||||
"Language: ja\n"
|
"Language: ja\n"
|
||||||
@@ -30760,7 +30760,7 @@ msgstr "このイベントのメール設定でチケットの添付が無効に
|
|||||||
#: pretix/plugins/sendmail/forms.py:234 pretix/plugins/sendmail/forms.py:386
|
#: pretix/plugins/sendmail/forms.py:234 pretix/plugins/sendmail/forms.py:386
|
||||||
#: pretix/plugins/sendmail/views.py:267
|
#: pretix/plugins/sendmail/views.py:267
|
||||||
msgid "payment pending but already confirmed"
|
msgid "payment pending but already confirmed"
|
||||||
msgstr "支払い保留中だが確認済み"
|
msgstr "支払い保留中ですが、すでに確認済み"
|
||||||
|
|
||||||
#: pretix/plugins/sendmail/forms.py:235 pretix/plugins/sendmail/forms.py:388
|
#: pretix/plugins/sendmail/forms.py:235 pretix/plugins/sendmail/forms.py:388
|
||||||
#: pretix/plugins/sendmail/views.py:268
|
#: pretix/plugins/sendmail/views.py:268
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ 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-09-26 11:16+0000\n"
|
"POT-Creation-Date: 2025-09-26 11:16+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-04 19:00+0000\n"
|
"PO-Revision-Date: 2025-09-30 01:00+0000\n"
|
||||||
"Last-Translator: Jan Van Haver <jan.van.haver@gmail.com>\n"
|
"Last-Translator: Jan Van Haver <jan.van.haver@gmail.com>\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"
|
||||||
@@ -808,8 +808,6 @@ 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 ""
|
||||||
"Het veld \"{field_name}\" bestaat niet. Controleer uw {provider_name} "
|
|
||||||
"instellingen."
|
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:262
|
#: pretix/base/datasync/datasync.py:262
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -817,8 +815,6 @@ 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 ""
|
||||||
"Het veld \"{field_name}\" vereist {required_input}, maar heeft alleen "
|
|
||||||
"{available_inputs}. Controleer uw {provider_name} instellingen."
|
|
||||||
|
|
||||||
#: pretix/base/datasync/datasync.py:273
|
#: pretix/base/datasync/datasync.py:273
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@@ -826,16 +822,18 @@ msgid ""
|
|||||||
"Please update value mapping for field \"{field_name}\" - option \"{val}\" "
|
"Please update value mapping for field \"{field_name}\" - option \"{val}\" "
|
||||||
"not assigned"
|
"not assigned"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Werk de mapping van de waarden bij voor veld \"{field_name}\" - optie "
|
|
||||||
"\"{val}\" is niet toegewezen"
|
|
||||||
|
|
||||||
#: 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 "Details bestelde producten"
|
msgstr "Bestelde producten"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:129
|
#: pretix/base/datasync/sourcefields.py:129
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Attendee email"
|
||||||
msgid "Attendee details"
|
msgid "Attendee details"
|
||||||
msgstr "Details van aanwezige"
|
msgstr "E-mailadres van aanwezige"
|
||||||
|
|
||||||
#: 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:1767 pretix/control/navigation.py:172
|
#: pretix/base/models/items.py:1767 pretix/control/navigation.py:172
|
||||||
@@ -845,8 +843,10 @@ msgid "Questions"
|
|||||||
msgstr "Vragen"
|
msgstr "Vragen"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:131
|
#: pretix/base/datasync/sourcefields.py:131
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Product data"
|
||||||
msgid "Product details"
|
msgid "Product details"
|
||||||
msgstr "Productdetails"
|
msgstr "Productgegevens"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:132
|
#: pretix/base/datasync/sourcefields.py:132
|
||||||
#: pretix/control/templates/pretixcontrol/event/settings.html:280
|
#: pretix/control/templates/pretixcontrol/event/settings.html:280
|
||||||
@@ -1038,12 +1038,16 @@ msgid "Product ID"
|
|||||||
msgstr "Product ID"
|
msgstr "Product ID"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:419
|
#: pretix/base/datasync/sourcefields.py:419
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Non-admission product"
|
||||||
msgid "Product is admission product"
|
msgid "Product is admission product"
|
||||||
msgstr "Product is een toegangsbewijs"
|
msgstr "Geen toegangsbewijs"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:428
|
#: pretix/base/datasync/sourcefields.py:428
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Event short name"
|
||||||
msgid "Event short form"
|
msgid "Event short form"
|
||||||
msgstr "Kort formulier evenement"
|
msgstr "Korte naam evenement"
|
||||||
|
|
||||||
#: 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:262
|
#: pretix/base/exporters/orderlist.py:262
|
||||||
@@ -1086,8 +1090,10 @@ msgid "Order code and position number"
|
|||||||
msgstr "Bestelcode en plaatsnummer"
|
msgstr "Bestelcode en plaatsnummer"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:482
|
#: pretix/base/datasync/sourcefields.py:482
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Ticket page"
|
||||||
msgid "Ticket price"
|
msgid "Ticket price"
|
||||||
msgstr "Ticketprijs"
|
msgstr "Ticketpagina"
|
||||||
|
|
||||||
#: 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:85
|
#: pretix/control/forms/filter.py:216 pretix/control/forms/modelimport.py:85
|
||||||
@@ -1095,16 +1101,22 @@ msgid "Order status"
|
|||||||
msgstr "Bestelstatus"
|
msgstr "Bestelstatus"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:500
|
#: pretix/base/datasync/sourcefields.py:500
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Device status"
|
||||||
msgid "Ticket status"
|
msgid "Ticket status"
|
||||||
msgstr "Ticketstatus"
|
msgstr "Apparaatstatus"
|
||||||
|
|
||||||
#: 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 "Besteldatum en -tijd"
|
msgstr "Aankoopdatum en -tijd"
|
||||||
|
|
||||||
#: 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 "Betaaldatum en -tijd"
|
msgstr "Printdatum en -tijd"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:527
|
#: pretix/base/datasync/sourcefields.py:527
|
||||||
#: pretix/base/exporters/orderlist.py:271
|
#: pretix/base/exporters/orderlist.py:271
|
||||||
@@ -1115,17 +1127,23 @@ msgid "Order locale"
|
|||||||
msgstr "Taal van bestelling"
|
msgstr "Taal van bestelling"
|
||||||
|
|
||||||
#: 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 "ID besteld product"
|
msgstr "Besteld product"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:545
|
#: pretix/base/datasync/sourcefields.py:545
|
||||||
#: pretix/base/exporters/orderlist.py:291
|
#: pretix/base/exporters/orderlist.py:291
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Order time"
|
||||||
msgid "Order link"
|
msgid "Order link"
|
||||||
msgstr "Bestellink"
|
msgstr "Besteltijd"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:560
|
#: pretix/base/datasync/sourcefields.py:560
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Ticket block"
|
||||||
msgid "Ticket link"
|
msgid "Ticket link"
|
||||||
msgstr "Ticketlink"
|
msgstr "Ticketblok"
|
||||||
|
|
||||||
#: pretix/base/datasync/sourcefields.py:578
|
#: pretix/base/datasync/sourcefields.py:578
|
||||||
#, fuzzy, python-brace-format
|
#, fuzzy, python-brace-format
|
||||||
|
|||||||
@@ -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-09-26 11:16+0000\n"
|
"POT-Creation-Date: 2025-09-26 11:16+0000\n"
|
||||||
"PO-Revision-Date: 2025-10-04 19:00+0000\n"
|
"PO-Revision-Date: 2025-06-02 23:00+0000\n"
|
||||||
"Last-Translator: Sebastian Bożek <sebastian@log-mar.pl>\n"
|
"Last-Translator: Anarion Dunedain <anarion80@gmail.com>\n"
|
||||||
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix/pl/"
|
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix/pl/"
|
||||||
">\n"
|
">\n"
|
||||||
"Language: pl\n"
|
"Language: pl\n"
|
||||||
@@ -18,7 +18,7 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||||
"|| n%100>=20) ? 1 : 2;\n"
|
"|| n%100>=20) ? 1 : 2;\n"
|
||||||
"X-Generator: Weblate 5.13.3\n"
|
"X-Generator: Weblate 5.11.4\n"
|
||||||
|
|
||||||
#: pretix/_base_settings.py:87
|
#: pretix/_base_settings.py:87
|
||||||
msgid "English"
|
msgid "English"
|
||||||
@@ -90,7 +90,7 @@ msgstr "Grecki"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:104
|
#: pretix/_base_settings.py:104
|
||||||
msgid "Hebrew"
|
msgid "Hebrew"
|
||||||
msgstr "Hebrajski"
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/_base_settings.py:105
|
#: pretix/_base_settings.py:105
|
||||||
msgid "Indonesian"
|
msgid "Indonesian"
|
||||||
@@ -146,7 +146,7 @@ msgstr "Hiszpański"
|
|||||||
|
|
||||||
#: pretix/_base_settings.py:118
|
#: pretix/_base_settings.py:118
|
||||||
msgid "Spanish (Latin America)"
|
msgid "Spanish (Latin America)"
|
||||||
msgstr "Hiszpański (Ameryka Łacińska)"
|
msgstr ""
|
||||||
|
|
||||||
#: pretix/_base_settings.py:119
|
#: pretix/_base_settings.py:119
|
||||||
msgid "Turkish"
|
msgid "Turkish"
|
||||||
@@ -2328,7 +2328,7 @@ msgstr ""
|
|||||||
#: pretix/base/exporters/waitinglist.py:115 pretix/control/forms/event.py:1671
|
#: pretix/base/exporters/waitinglist.py:115 pretix/control/forms/event.py:1671
|
||||||
#: pretix/control/forms/organizer.py:116
|
#: pretix/control/forms/organizer.py:116
|
||||||
msgid "Event slug"
|
msgid "Event slug"
|
||||||
msgstr "Fragment adresu URL, który pojawia się po nazwie domeny."
|
msgstr "Kod wydarzenia"
|
||||||
|
|
||||||
#: pretix/base/exporters/orderlist.py:262
|
#: pretix/base/exporters/orderlist.py:262
|
||||||
#: pretix/base/exporters/orderlist.py:452
|
#: pretix/base/exporters/orderlist.py:452
|
||||||
@@ -32680,7 +32680,7 @@ msgid ""
|
|||||||
"banks. Please keep your online banking account and login information "
|
"banks. Please keep your online banking account and login information "
|
||||||
"available."
|
"available."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Przelewy24 to metoda płatności online dostępna dla klientów Polskich banków. "
|
"Przelewy24 to metoda płatności online dostępna dla klientów polskich banków. "
|
||||||
"Prosimy o zachowanie danych logowania i konta bankowego."
|
"Prosimy o zachowanie danych logowania i konta bankowego."
|
||||||
|
|
||||||
#: pretix/plugins/stripe/payment.py:1768
|
#: pretix/plugins/stripe/payment.py:1768
|
||||||
|
|||||||
@@ -476,7 +476,6 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
|
|||||||
category = pgettext_lazy('export_category', 'Check-in')
|
category = pgettext_lazy('export_category', 'Check-in')
|
||||||
description = gettext_lazy("Download a spreadsheet with all attendees that are included in a check-in list.")
|
description = gettext_lazy("Download a spreadsheet with all attendees that are included in a check-in list.")
|
||||||
featured = True
|
featured = True
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_form_fields(self):
|
def additional_form_fields(self):
|
||||||
@@ -674,7 +673,6 @@ class CSVCheckinCodeList(CheckInListMixin, ListExporter):
|
|||||||
category = pgettext_lazy('export_category', 'Check-in')
|
category = pgettext_lazy('export_category', 'Check-in')
|
||||||
description = gettext_lazy("Download a spreadsheet with all valid check-in barcodes e.g. for import into a "
|
description = gettext_lazy("Download a spreadsheet with all valid check-in barcodes e.g. for import into a "
|
||||||
"different system. Does not included blocked codes or personal data.")
|
"different system. Does not included blocked codes or personal data.")
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_form_fields(self):
|
def additional_form_fields(self):
|
||||||
@@ -745,7 +743,6 @@ class CheckinLogList(ListExporter):
|
|||||||
category = pgettext_lazy('export_category', 'Check-in')
|
category = pgettext_lazy('export_category', 'Check-in')
|
||||||
description = gettext_lazy("Download a spreadsheet with one line for every scan that happened at your check-in "
|
description = gettext_lazy("Download a spreadsheet with one line for every scan that happened at your check-in "
|
||||||
"stations.")
|
"stations.")
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def additional_form_fields(self):
|
def additional_form_fields(self):
|
||||||
|
|||||||
@@ -661,7 +661,6 @@ class OrderTaxListReport(MultiSheetListExporter):
|
|||||||
verbose_name = gettext_lazy('Tax split list')
|
verbose_name = gettext_lazy('Tax split list')
|
||||||
category = pgettext_lazy('export_category', 'Order data')
|
category = pgettext_lazy('export_category', 'Order data')
|
||||||
description = gettext_lazy("Download a spreadsheet with the tax amounts included in each order.")
|
description = gettext_lazy("Download a spreadsheet with the tax amounts included in each order.")
|
||||||
repeatable_read = False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sheets(self):
|
def sheets(self):
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import copy
|
|||||||
import hmac
|
import hmac
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
import logging
|
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
@@ -99,8 +98,6 @@ from pretix.presale.views import (
|
|||||||
from pretix.presale.views.event import get_grouped_items
|
from pretix.presale.views.event import get_grouped_items
|
||||||
from pretix.presale.views.robots import NoSearchIndexViewMixin
|
from pretix.presale.views.robots import NoSearchIndexViewMixin
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class OrderDetailMixin(NoSearchIndexViewMixin):
|
class OrderDetailMixin(NoSearchIndexViewMixin):
|
||||||
|
|
||||||
@@ -737,18 +734,11 @@ class OrderInvoiceCreate(EventViewMixin, OrderDetailMixin, View):
|
|||||||
elif self.order.invoices.exists():
|
elif self.order.invoices.exists():
|
||||||
messages.error(self.request, _('An invoice for this order already exists.'))
|
messages.error(self.request, _('An invoice for this order already exists.'))
|
||||||
else:
|
else:
|
||||||
try:
|
|
||||||
i = generate_invoice(self.order)
|
i = generate_invoice(self.order)
|
||||||
self.order.log_action('pretix.event.order.invoice.generated', data={
|
self.order.log_action('pretix.event.order.invoice.generated', data={
|
||||||
'invoice': i.pk
|
'invoice': i.pk
|
||||||
})
|
})
|
||||||
messages.success(self.request, _('The invoice has been generated.'))
|
messages.success(self.request, _('The invoice has been generated.'))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
self.order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
messages.error(self.request, _('Invoice generation has failed, please reach out to the organizer.'))
|
|
||||||
return redirect(self.get_order_url())
|
return redirect(self.get_order_url())
|
||||||
|
|
||||||
|
|
||||||
@@ -817,21 +807,13 @@ class OrderModify(EventViewMixin, OrderDetailMixin, OrderQuestionsViewMixin, Tem
|
|||||||
elif self.order.invoices.exists():
|
elif self.order.invoices.exists():
|
||||||
messages.error(self.request, _('An invoice for this order already exists.'))
|
messages.error(self.request, _('An invoice for this order already exists.'))
|
||||||
else:
|
else:
|
||||||
try:
|
|
||||||
i = generate_invoice(self.order)
|
i = generate_invoice(self.order)
|
||||||
self.order.log_action('pretix.event.order.invoice.generated', data={
|
self.order.log_action('pretix.event.order.invoice.generated', data={
|
||||||
'invoice': i.pk
|
'invoice': i.pk
|
||||||
})
|
})
|
||||||
messages.success(self.request, _('The invoice has been generated.'))
|
messages.success(self.request, _('The invoice has been generated.'))
|
||||||
except Exception as e:
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
self.order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
messages.error(self.request, _('Invoice generation has failed, please reach out to the organizer.'))
|
|
||||||
elif self.request.event.settings.invoice_reissue_after_modify:
|
elif self.request.event.settings.invoice_reissue_after_modify:
|
||||||
if self.invoice_form.changed_data:
|
if self.invoice_form.changed_data:
|
||||||
try:
|
|
||||||
inv = self.order.invoices.last()
|
inv = self.order.invoices.last()
|
||||||
if inv and not inv.canceled and not inv.shredded:
|
if inv and not inv.canceled and not inv.shredded:
|
||||||
c = generate_cancellation(inv)
|
c = generate_cancellation(inv)
|
||||||
@@ -843,11 +825,6 @@ class OrderModify(EventViewMixin, OrderDetailMixin, OrderQuestionsViewMixin, Tem
|
|||||||
'invoice': inv.pk
|
'invoice': inv.pk
|
||||||
})
|
})
|
||||||
messages.success(self.request, _('The invoice has been reissued.'))
|
messages.success(self.request, _('The invoice has been reissued.'))
|
||||||
except Exception as e:
|
|
||||||
self.order.log_action("pretix.event.order.invoice.failed", data={
|
|
||||||
"exception": str(e)
|
|
||||||
})
|
|
||||||
logger.exception("Could not generate invoice.")
|
|
||||||
|
|
||||||
invalidate_cache.apply_async(kwargs={'event': self.request.event.pk, 'order': self.order.pk})
|
invalidate_cache.apply_async(kwargs={'event': self.request.event.pk, 'order': self.order.pk})
|
||||||
CachedTicket.objects.filter(order_position__order=self.order).delete()
|
CachedTicket.objects.filter(order_position__order=self.order).delete()
|
||||||
|
|||||||
@@ -330,11 +330,9 @@ var ajaxErrDialog = {
|
|||||||
$("#ajaxerr .links").html("<a class='btn btn-default ajaxerr-close'>"
|
$("#ajaxerr .links").html("<a class='btn btn-default ajaxerr-close'>"
|
||||||
+ gettext("Close message") + "</a>");
|
+ gettext("Close message") + "</a>");
|
||||||
$("body").addClass("ajaxerr has-modal-dialog");
|
$("body").addClass("ajaxerr has-modal-dialog");
|
||||||
$("#ajaxerr").prop("hidden", false);
|
|
||||||
},
|
},
|
||||||
hide: function () {
|
hide: function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
$("body").removeClass("ajaxerr has-modal-dialog");
|
$("body").removeClass("ajaxerr has-modal-dialog");
|
||||||
$("#ajaxerr").prop("hidden", true);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ var i18nToString = function (i18nstring) {
|
|||||||
$(document).ajaxError(function (event, jqXHR, settings, thrownError) {
|
$(document).ajaxError(function (event, jqXHR, settings, thrownError) {
|
||||||
waitingDialog.hide();
|
waitingDialog.hide();
|
||||||
var c = $(jqXHR.responseText).filter('.container');
|
var c = $(jqXHR.responseText).filter('.container');
|
||||||
if (jqXHR.responseText && jqXHR.responseText.indexOf("<!-- pretix-login-marker -->") !== -1) {
|
if (jqXHR.responseText.indexOf("<!-- pretix-login-marker -->") !== -1) {
|
||||||
location.href = '/control/login?next=' + encodeURIComponent(location.pathname + location.search + location.hash)
|
location.href = '/control/login?next=' + encodeURIComponent(location.pathname + location.search + location.hash)
|
||||||
} else if (c.length > 0) {
|
} else if (c.length > 0) {
|
||||||
ajaxErrDialog.show(c.first().html());
|
ajaxErrDialog.show(c.first().html());
|
||||||
@@ -485,7 +485,6 @@ var form_handlers = function (el) {
|
|||||||
theme: "bootstrap",
|
theme: "bootstrap",
|
||||||
language: $("body").attr("data-select2-locale"),
|
language: $("body").attr("data-select2-locale"),
|
||||||
data: JSON.parse($(this.getAttribute('data-select2-src')).text()),
|
data: JSON.parse($(this.getAttribute('data-select2-src')).text()),
|
||||||
width: '100%',
|
|
||||||
}).val(selectedValue).trigger('change');
|
}).val(selectedValue).trigger('change');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ td > .form-group > .checkbox {
|
|||||||
@include box-shadow(none);
|
@include box-shadow(none);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div[data-formset-body], div[data-formset-form], div[data-nested-formset-form], div[data-nested-formset-body], details[data-formset-form] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.form-plugins .panel-title {
|
.form-plugins .panel-title {
|
||||||
line-height: 34px;
|
line-height: 34px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ def test_2f1r_discount_cross_selling_eventseries_mixed(eventseries):
|
|||||||
Regular Ticket 42.00 42.00 Date1
|
Regular Ticket 42.00 42.00 Date1
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -424,8 +424,8 @@ def test_2f1r_discount_cross_selling_eventseries_mixed(eventseries):
|
|||||||
Regular Ticket 42.00 42.00 Date2
|
Regular Ticket 42.00 42.00 Date2
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
Tickets (Date2 - Wed, Jan. 1, 2020 11:00) Reduced Ticket 23.00 11.50 1 {prefix_date2}
|
Tickets (Date2 - Wed, Jan. 1st, 2020 11:00) Reduced Ticket 23.00 11.50 1 {prefix_date2}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -460,8 +460,8 @@ def test_2f1r_discount_cross_selling_eventseries_mixed(eventseries):
|
|||||||
Regular Ticket 42.00 42.00 Date2
|
Regular Ticket 42.00 42.00 Date2
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 2 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 2 {prefix_date1}
|
||||||
Tickets (Date2 - Wed, Jan. 1, 2020 11:00) Reduced Ticket 23.00 11.50 2 {prefix_date2}
|
Tickets (Date2 - Wed, Jan. 1st, 2020 11:00) Reduced Ticket 23.00 11.50 2 {prefix_date2}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -475,7 +475,7 @@ def test_2f1r_discount_cross_selling_eventseries_mixed(eventseries):
|
|||||||
Reduced Ticket 23.00 11.50 Date1
|
Reduced Ticket 23.00 11.50 Date1
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -490,7 +490,7 @@ def test_2f1r_discount_cross_selling_eventseries_mixed(eventseries):
|
|||||||
Reduced Ticket 23.00 11.50 Date1
|
Reduced Ticket 23.00 11.50 Date1
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -506,7 +506,7 @@ def test_2f1r_discount_cross_selling_eventseries_mixed(eventseries):
|
|||||||
Reduced Ticket 23.00 11.50 Date1
|
Reduced Ticket 23.00 11.50 Date1
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 2 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 2 {prefix_date1}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -531,8 +531,8 @@ def test_2f1r_discount_cross_selling_eventseries_same(eventseries):
|
|||||||
Regular Ticket 42.00 42.00 Date2
|
Regular Ticket 42.00 42.00 Date2
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
Tickets (Date2 - Wed, Jan. 1, 2020 11:00) Reduced Ticket 23.00 11.50 1 {prefix_date2}
|
Tickets (Date2 - Wed, Jan. 1st, 2020 11:00) Reduced Ticket 23.00 11.50 1 {prefix_date2}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -546,8 +546,8 @@ def test_2f1r_discount_cross_selling_eventseries_same(eventseries):
|
|||||||
Regular Ticket 42.00 42.00 Date2
|
Regular Ticket 42.00 42.00 Date2
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
Tickets (Date2 - Wed, Jan. 1, 2020 11:00) Reduced Ticket 23.00 11.50 2 {prefix_date2}
|
Tickets (Date2 - Wed, Jan. 1st, 2020 11:00) Reduced Ticket 23.00 11.50 2 {prefix_date2}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -561,7 +561,7 @@ def test_2f1r_discount_cross_selling_eventseries_same(eventseries):
|
|||||||
Reduced Ticket 23.00 11.50 Date1
|
Reduced Ticket 23.00 11.50 Date1
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date1 - Wed, Jan. 1, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
Tickets (Date1 - Wed, Jan. 1st, 2020 10:00) Reduced Ticket 23.00 11.50 1 {prefix_date1}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
check_cart_behaviour(
|
check_cart_behaviour(
|
||||||
@@ -589,7 +589,7 @@ def test_2f1r_discount_cross_selling_eventseries_same(eventseries):
|
|||||||
Reduced Ticket 23.00 11.50 Date1
|
Reduced Ticket 23.00 11.50 Date1
|
||||||
''',
|
''',
|
||||||
recommendations=f''' Price Discounted Price Max Count Prefix
|
recommendations=f''' Price Discounted Price Max Count Prefix
|
||||||
Tickets (Date2 - Wed, Jan. 1, 2020 11:00) Reduced Ticket 23.00 11.50 1 {prefix_date2}
|
Tickets (Date2 - Wed, Jan. 1st, 2020 11:00) Reduced Ticket 23.00 11.50 1 {prefix_date2}
|
||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ from pretix.base.models.items import (
|
|||||||
from pretix.base.reldate import RelativeDate, RelativeDateWrapper
|
from pretix.base.reldate import RelativeDate, RelativeDateWrapper
|
||||||
from pretix.base.services.orders import OrderError, cancel_order, perform_order
|
from pretix.base.services.orders import OrderError, cancel_order, perform_order
|
||||||
from pretix.base.services.quotas import QuotaAvailability
|
from pretix.base.services.quotas import QuotaAvailability
|
||||||
from pretix.helpers import repeatable_reads_transaction
|
|
||||||
from pretix.testutils.scope import classscope
|
from pretix.testutils.scope import classscope
|
||||||
|
|
||||||
|
|
||||||
@@ -100,29 +99,6 @@ class BaseQuotaTestCase(TestCase):
|
|||||||
self.var3 = ItemVariation.objects.create(item=self.item3, value='Fancy')
|
self.var3 = ItemVariation.objects.create(item=self.item3, value='Fancy')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db(transaction=True)
|
|
||||||
@scopes_disabled()
|
|
||||||
def test_verify_repeatable_read_check():
|
|
||||||
if 'sqlite' in settings.DATABASES['default']['ENGINE']:
|
|
||||||
pytest.skip('Not supported on SQLite')
|
|
||||||
|
|
||||||
o = Organizer.objects.create(name='Dummy', slug='dummy')
|
|
||||||
event = Event.objects.create(
|
|
||||||
organizer=o, name='Dummy', slug='dummy',
|
|
||||||
date_from=now(), plugins='tests.testdummy'
|
|
||||||
)
|
|
||||||
quota = Quota.objects.create(name="Test", size=2, event=event)
|
|
||||||
|
|
||||||
with repeatable_reads_transaction():
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
qa = QuotaAvailability(full_results=True)
|
|
||||||
qa.queue(quota)
|
|
||||||
qa.compute()
|
|
||||||
qa = QuotaAvailability(full_results=True, allow_repeatable_read=True)
|
|
||||||
qa.queue(quota)
|
|
||||||
qa.compute()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("fakeredis_client")
|
@pytest.mark.usefixtures("fakeredis_client")
|
||||||
class QuotaTestCase(BaseQuotaTestCase):
|
class QuotaTestCase(BaseQuotaTestCase):
|
||||||
@classscope(attr='o')
|
@classscope(attr='o')
|
||||||
@@ -2489,44 +2465,44 @@ class EventTest(TestCase):
|
|||||||
(
|
(
|
||||||
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
||||||
datetime.datetime(2025, 3, 9, 22, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 9, 22, 0, 0, tzinfo=tz),
|
||||||
'Sun, March 9, 2025',
|
'Sun, March 9th, 2025',
|
||||||
'<time datetime="2025-03-09">Sun, March 9, 2025</time>',
|
'<time datetime="2025-03-09">Sun, March 9th, 2025</time>',
|
||||||
'Sun, March 9, 2025 20:00–21:00',
|
'Sun, March 9th, 2025 20:00–21:00',
|
||||||
'<time datetime="2025-03-09">Sun, March 9, 2025</time> '
|
'<time datetime="2025-03-09">Sun, March 9th, 2025</time> '
|
||||||
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00–21:00</time>'
|
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00–21:00</time>'
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
||||||
datetime.datetime(2025, 3, 10, 3, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 10, 3, 0, 0, tzinfo=tz),
|
||||||
'March 9 – 10, 2025',
|
'March 9th – 10th, 2025',
|
||||||
'<time datetime="2025-03-09">March 9</time> '
|
'<time datetime="2025-03-09">March 9th</time> '
|
||||||
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
||||||
'<time datetime="2025-03-10">10, 2025</time>',
|
'<time datetime="2025-03-10">10th, 2025</time>',
|
||||||
'March 9 – 10, 2025 20:00–02:00',
|
'March 9th – 10th, 2025 20:00–02:00',
|
||||||
'<time datetime="2025-03-09">March 9</time> '
|
'<time datetime="2025-03-09">March 9th</time> '
|
||||||
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
||||||
'<time datetime="2025-03-10">10, 2025</time> '
|
'<time datetime="2025-03-10">10th, 2025</time> '
|
||||||
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00–02:00</time>'
|
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00–02:00</time>'
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
||||||
datetime.datetime(2025, 3, 12, 14, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 12, 14, 0, 0, tzinfo=tz),
|
||||||
'March 9 – 12, 2025',
|
'March 9th – 12th, 2025',
|
||||||
'<time datetime="2025-03-09">March 9</time> '
|
'<time datetime="2025-03-09">March 9th</time> '
|
||||||
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
||||||
'<time datetime="2025-03-12">12, 2025</time>',
|
'<time datetime="2025-03-12">12th, 2025</time>',
|
||||||
'March 9 – 12, 2025',
|
'March 9th – 12th, 2025',
|
||||||
'<time datetime="2025-03-09">March 9</time> '
|
'<time datetime="2025-03-09">March 9th</time> '
|
||||||
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> '
|
||||||
'<time datetime="2025-03-12">12, 2025</time>',
|
'<time datetime="2025-03-12">12th, 2025</time>',
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
datetime.datetime(2025, 3, 9, 21, 0, 0, tzinfo=tz),
|
||||||
None,
|
None,
|
||||||
'Sun, March 9, 2025',
|
'Sun, March 9th, 2025',
|
||||||
'<time datetime="2025-03-09">Sun, March 9, 2025</time>',
|
'<time datetime="2025-03-09">Sun, March 9th, 2025</time>',
|
||||||
'Sun, March 9, 2025 20:00',
|
'Sun, March 9th, 2025 20:00',
|
||||||
'<time datetime="2025-03-09">Sun, March 9, 2025</time> '
|
'<time datetime="2025-03-09">Sun, March 9th, 2025</time> '
|
||||||
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00</time>'
|
'<time datetime="2025-03-09T21:00:00+01:00" data-timezone="UTC" data-time-short>20:00</time>'
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -48,10 +48,10 @@ ref_date = date(2023, 3, 28)
|
|||||||
(ref_date, 'days_tomorrow', date(2023, 3, 29), date(2023, 3, 29), None),
|
(ref_date, 'days_tomorrow', date(2023, 3, 29), date(2023, 3, 29), None),
|
||||||
(ref_date, 'days_next7', date(2023, 3, 29), date(2023, 4, 4), None),
|
(ref_date, 'days_next7', date(2023, 3, 29), date(2023, 4, 4), None),
|
||||||
(ref_date, 'days_next14', date(2023, 3, 29), date(2023, 4, 11), None),
|
(ref_date, 'days_next14', date(2023, 3, 29), date(2023, 4, 11), None),
|
||||||
(ref_date, 'week_this', date(2023, 3, 27), date(2023, 4, 2), 'W 13, 2023 - March 27 – April 2, 2023'),
|
(ref_date, 'week_this', date(2023, 3, 27), date(2023, 4, 2), 'W 13, 2023 - March 27th – April 2nd, 2023'),
|
||||||
(ref_date, 'week_to_date', date(2023, 3, 27), date(2023, 3, 28), 'W 13, 2023 - March 27 – 28, 2023'),
|
(ref_date, 'week_to_date', date(2023, 3, 27), date(2023, 3, 28), 'W 13, 2023 - March 27th – 28th, 2023'),
|
||||||
(ref_date, 'week_previous', date(2023, 3, 20), date(2023, 3, 26), 'W 12, 2023 - March 20 – 26, 2023'),
|
(ref_date, 'week_previous', date(2023, 3, 20), date(2023, 3, 26), 'W 12, 2023 - March 20th – 26th, 2023'),
|
||||||
(ref_date, 'week_next', date(2023, 4, 3), date(2023, 4, 9), 'W 14, 2023 - April 3 – 9, 2023'),
|
(ref_date, 'week_next', date(2023, 4, 3), date(2023, 4, 9), 'W 14, 2023 - April 3rd – 9th, 2023'),
|
||||||
(ref_date, 'month_this', date(2023, 3, 1), date(2023, 3, 31), 'March 2023'),
|
(ref_date, 'month_this', date(2023, 3, 1), date(2023, 3, 31), 'March 2023'),
|
||||||
(ref_date, 'month_to_date', date(2023, 3, 1), date(2023, 3, 28), 'March 2023'),
|
(ref_date, 'month_to_date', date(2023, 3, 1), date(2023, 3, 28), 'March 2023'),
|
||||||
(ref_date, 'month_previous', date(2023, 2, 1), date(2023, 2, 28), 'February 2023'),
|
(ref_date, 'month_previous', date(2023, 2, 1), date(2023, 2, 28), 'February 2023'),
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ def test_same_day_german():
|
|||||||
def test_same_day_english():
|
def test_same_day_english():
|
||||||
with translation.override('en'):
|
with translation.override('en'):
|
||||||
df = date(2003, 2, 1)
|
df = date(2003, 2, 1)
|
||||||
assert daterange(df, df) == "Sat, Feb. 1, 2003"
|
assert daterange(df, df) == "Sat, Feb. 1st, 2003"
|
||||||
assert daterange(df, df, as_html=True) == '<time datetime="2003-02-01">Sat, Feb. 1, 2003</time>'
|
assert daterange(df, df, as_html=True) == '<time datetime="2003-02-01">Sat, Feb. 1st, 2003</time>'
|
||||||
|
|
||||||
|
|
||||||
def test_same_day_spanish():
|
def test_same_day_spanish():
|
||||||
@@ -82,10 +82,10 @@ def test_same_month_english():
|
|||||||
with translation.override('en'):
|
with translation.override('en'):
|
||||||
df = date(2003, 2, 1)
|
df = date(2003, 2, 1)
|
||||||
dt = date(2003, 2, 3)
|
dt = date(2003, 2, 3)
|
||||||
assert daterange(df, dt) == "Feb. 1 – 3, 2003"
|
assert daterange(df, dt) == "Feb. 1st – 3rd, 2003"
|
||||||
assert daterange(df, dt, as_html=True) == '<time datetime="2003-02-01">Feb. 1</time> ' \
|
assert daterange(df, dt, as_html=True) == '<time datetime="2003-02-01">Feb. 1st</time> ' \
|
||||||
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> ' \
|
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> ' \
|
||||||
'<time datetime="2003-02-03">3, 2003</time>'
|
'<time datetime="2003-02-03">3rd, 2003</time>'
|
||||||
|
|
||||||
|
|
||||||
def test_same_month_spanish():
|
def test_same_month_spanish():
|
||||||
@@ -112,10 +112,10 @@ def test_same_year_english():
|
|||||||
with translation.override('en'):
|
with translation.override('en'):
|
||||||
df = date(2003, 2, 1)
|
df = date(2003, 2, 1)
|
||||||
dt = date(2003, 4, 3)
|
dt = date(2003, 4, 3)
|
||||||
assert daterange(df, dt) == "Feb. 1 – April 3, 2003"
|
assert daterange(df, dt) == "Feb. 1st – April 3rd, 2003"
|
||||||
assert daterange(df, dt, as_html=True) == '<time datetime="2003-02-01">Feb. 1</time> ' \
|
assert daterange(df, dt, as_html=True) == '<time datetime="2003-02-01">Feb. 1st</time> ' \
|
||||||
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> ' \
|
'<span aria-hidden="true">–</span><span class="sr-only"> until </span> ' \
|
||||||
'<time datetime="2003-04-03">April 3, 2003</time>'
|
'<time datetime="2003-04-03">April 3rd, 2003</time>'
|
||||||
|
|
||||||
|
|
||||||
def test_same_year_spanish():
|
def test_same_year_spanish():
|
||||||
|
|||||||
@@ -1621,7 +1621,7 @@ class EventLocaleTest(EventTestMixin, SoupTest):
|
|||||||
'/%s/%s/' % (self.orga.slug, self.event.slug)
|
'/%s/%s/' % (self.orga.slug, self.event.slug)
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertIn('Thu, Dec. 26,', response.rendered_content)
|
self.assertIn('Thu, Dec. 26th,', response.rendered_content)
|
||||||
self.assertIn('14:00', response.rendered_content)
|
self.assertIn('14:00', response.rendered_content)
|
||||||
|
|
||||||
def test_english_region_US(self):
|
def test_english_region_US(self):
|
||||||
@@ -1631,7 +1631,7 @@ class EventLocaleTest(EventTestMixin, SoupTest):
|
|||||||
'/%s/%s/' % (self.orga.slug, self.event.slug)
|
'/%s/%s/' % (self.orga.slug, self.event.slug)
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertIn('Thu, Dec. 26,', response.rendered_content)
|
self.assertIn('Thu, Dec. 26th,', response.rendered_content)
|
||||||
self.assertIn('2 p.m.', response.rendered_content)
|
self.assertIn('2 p.m.', response.rendered_content)
|
||||||
|
|
||||||
def test_german_region_US(self):
|
def test_german_region_US(self):
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
"target_url": "http://example.com/ccc/30c3/",
|
"target_url": "http://example.com/ccc/30c3/",
|
||||||
"subevent": None,
|
"subevent": None,
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26th, {self.event.date_from.year} 00:00",
|
||||||
"frontpage_text": "",
|
"frontpage_text": "",
|
||||||
"location": "",
|
"location": "",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
@@ -375,7 +375,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
"target_url": "http://example.com/ccc/30c3/",
|
"target_url": "http://example.com/ccc/30c3/",
|
||||||
"subevent": None,
|
"subevent": None,
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26th, {self.event.date_from.year} 00:00",
|
||||||
"frontpage_text": "",
|
"frontpage_text": "",
|
||||||
"location": "",
|
"location": "",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
@@ -435,7 +435,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
"target_url": "http://example.com/ccc/30c3/",
|
"target_url": "http://example.com/ccc/30c3/",
|
||||||
"subevent": None,
|
"subevent": None,
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26th, {self.event.date_from.year} 00:00",
|
||||||
"frontpage_text": "",
|
"frontpage_text": "",
|
||||||
"location": "",
|
"location": "",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
@@ -520,7 +520,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
"target_url": "http://example.com/ccc/30c3/",
|
"target_url": "http://example.com/ccc/30c3/",
|
||||||
"subevent": None,
|
"subevent": None,
|
||||||
"name": "30C3",
|
"name": "30C3",
|
||||||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26th, {self.event.date_from.year} 00:00",
|
||||||
"frontpage_text": "",
|
"frontpage_text": "",
|
||||||
"location": "",
|
"location": "",
|
||||||
"currency": "EUR",
|
"currency": "EUR",
|
||||||
@@ -627,9 +627,9 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||||||
'has_more_events': False,
|
'has_more_events': False,
|
||||||
'events': [
|
'events': [
|
||||||
{'name': 'Present', 'date_range': 'Tue, Jan. 1, 2019 11:00', 'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
{'name': 'Present', 'date_range': 'Tue, Jan. 1st, 2019 11:00', 'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk, 'location': ''},
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk, 'location': ''},
|
||||||
{'name': 'Future', 'date_range': 'Fri, Jan. 4, 2019 11:00', 'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
{'name': 'Future', 'date_range': 'Fri, Jan. 4th, 2019 11:00', 'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk, 'location': ''}
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk, 'location': ''}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -659,14 +659,14 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
[
|
[
|
||||||
None,
|
None,
|
||||||
{'day': 1, 'date': '2019-01-01', 'events': [
|
{'day': 1, 'date': '2019-01-01', 'events': [
|
||||||
{'name': 'Present', 'time': '11:00', 'continued': False, 'date_range': 'Tue, Jan. 1, 2019 11:00',
|
{'name': 'Present', 'time': '11:00', 'continued': False, 'date_range': 'Tue, Jan. 1st, 2019 11:00',
|
||||||
'location': '',
|
'location': '',
|
||||||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk}]},
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk}]},
|
||||||
{'day': 2, 'date': '2019-01-02', 'events': []},
|
{'day': 2, 'date': '2019-01-02', 'events': []},
|
||||||
{'day': 3, 'date': '2019-01-03', 'events': []},
|
{'day': 3, 'date': '2019-01-03', 'events': []},
|
||||||
{'day': 4, 'date': '2019-01-04', 'events': [
|
{'day': 4, 'date': '2019-01-04', 'events': [
|
||||||
{'name': 'Future', 'time': '11:00', 'continued': False, 'date_range': 'Fri, Jan. 4, 2019 11:00',
|
{'name': 'Future', 'time': '11:00', 'continued': False, 'date_range': 'Fri, Jan. 4th, 2019 11:00',
|
||||||
'location': '',
|
'location': '',
|
||||||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk}]},
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk}]},
|
||||||
@@ -732,21 +732,21 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'week': [2019, 1],
|
'week': [2019, 1],
|
||||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||||||
'days': [
|
'days': [
|
||||||
{'day_formatted': 'Mon, Dec 31', 'date': '2018-12-31', 'events': [], 'today': False},
|
{'day_formatted': 'Mon, Dec 31st', 'date': '2018-12-31', 'events': [], 'today': False},
|
||||||
{'day_formatted': 'Tue, Jan 1', 'date': '2019-01-01', 'events': [
|
{'day_formatted': 'Tue, Jan 1st', 'date': '2019-01-01', 'events': [
|
||||||
{'name': 'Present', 'time': '11:00', 'continued': False, 'date_range': 'Tue, Jan. 1, 2019 11:00',
|
{'name': 'Present', 'time': '11:00', 'continued': False, 'date_range': 'Tue, Jan. 1st, 2019 11:00',
|
||||||
'location': '',
|
'location': '',
|
||||||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk}], 'today': True},
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk}], 'today': True},
|
||||||
{'day_formatted': 'Wed, Jan 2', 'date': '2019-01-02', 'events': [], 'today': False},
|
{'day_formatted': 'Wed, Jan 2nd', 'date': '2019-01-02', 'events': [], 'today': False},
|
||||||
{'day_formatted': 'Thu, Jan 3', 'date': '2019-01-03', 'events': [], 'today': False},
|
{'day_formatted': 'Thu, Jan 3rd', 'date': '2019-01-03', 'events': [], 'today': False},
|
||||||
{'day_formatted': 'Fri, Jan 4', 'date': '2019-01-04', 'events': [
|
{'day_formatted': 'Fri, Jan 4th', 'date': '2019-01-04', 'events': [
|
||||||
{'name': 'Future', 'time': '11:00', 'continued': False, 'date_range': 'Fri, Jan. 4, 2019 11:00',
|
{'name': 'Future', 'time': '11:00', 'continued': False, 'date_range': 'Fri, Jan. 4th, 2019 11:00',
|
||||||
'location': '',
|
'location': '',
|
||||||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk}], 'today': False},
|
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk}], 'today': False},
|
||||||
{'day_formatted': 'Sat, Jan 5', 'date': '2019-01-05', 'events': [], 'today': False},
|
{'day_formatted': 'Sat, Jan 5th', 'date': '2019-01-05', 'events': [], 'today': False},
|
||||||
{'day_formatted': 'Sun, Jan 6', 'date': '2019-01-06', 'events': [], 'today': False}
|
{'day_formatted': 'Sun, Jan 6th', 'date': '2019-01-06', 'events': [], 'today': False}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,17 +773,17 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||||||
'events': [
|
'events': [
|
||||||
{'availability': {'color': 'none', 'text': 'Event series'},
|
{'availability': {'color': 'none', 'text': 'Event series'},
|
||||||
'date_range': 'Jan. 1 – 4, 2019',
|
'date_range': 'Jan. 1st – 4th, 2019',
|
||||||
'event_url': 'http://example.com/ccc/30c3/',
|
'event_url': 'http://example.com/ccc/30c3/',
|
||||||
'location': '',
|
'location': '',
|
||||||
'name': '30C3'},
|
'name': '30C3'},
|
||||||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'date_range': 'Tue, Jan. 1, 2019 10:00',
|
'date_range': 'Tue, Jan. 1st, 2019 10:00',
|
||||||
'location': '',
|
'location': '',
|
||||||
'event_url': 'http://example.com/ccc/present/',
|
'event_url': 'http://example.com/ccc/present/',
|
||||||
'name': 'Present'},
|
'name': 'Present'},
|
||||||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'date_range': 'Fri, Jan. 4, 2019 10:00',
|
'date_range': 'Fri, Jan. 4th, 2019 10:00',
|
||||||
'location': '',
|
'location': '',
|
||||||
'event_url': 'http://example.com/ccc/future/',
|
'event_url': 'http://example.com/ccc/future/',
|
||||||
'name': 'Future'}
|
'name': 'Future'}
|
||||||
@@ -884,7 +884,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'day': 1,
|
'day': 1,
|
||||||
'events': [{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
'events': [{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'continued': False,
|
'continued': False,
|
||||||
'date_range': 'Tue, Jan. 1, 2019 10:00',
|
'date_range': 'Tue, Jan. 1st, 2019 10:00',
|
||||||
'event_url': 'http://example.com/ccc/present/',
|
'event_url': 'http://example.com/ccc/present/',
|
||||||
'name': 'Present',
|
'name': 'Present',
|
||||||
'location': '',
|
'location': '',
|
||||||
@@ -892,7 +892,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'time': '10:00'},
|
'time': '10:00'},
|
||||||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'continued': False,
|
'continued': False,
|
||||||
'date_range': 'Tue, Jan. 1, 2019 11:00',
|
'date_range': 'Tue, Jan. 1st, 2019 11:00',
|
||||||
'event_url': 'http://example.com/ccc/30c3/',
|
'event_url': 'http://example.com/ccc/30c3/',
|
||||||
'name': 'Present',
|
'name': 'Present',
|
||||||
'location': '',
|
'location': '',
|
||||||
@@ -904,7 +904,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'day': 4,
|
'day': 4,
|
||||||
'events': [{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
'events': [{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'continued': False,
|
'continued': False,
|
||||||
'date_range': 'Fri, Jan. 4, 2019 10:00',
|
'date_range': 'Fri, Jan. 4th, 2019 10:00',
|
||||||
'event_url': 'http://example.com/ccc/future/',
|
'event_url': 'http://example.com/ccc/future/',
|
||||||
'name': 'Future',
|
'name': 'Future',
|
||||||
'location': '',
|
'location': '',
|
||||||
@@ -912,7 +912,7 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
|||||||
'time': '10:00'},
|
'time': '10:00'},
|
||||||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||||||
'continued': False,
|
'continued': False,
|
||||||
'date_range': 'Fri, Jan. 4, 2019 11:00',
|
'date_range': 'Fri, Jan. 4th, 2019 11:00',
|
||||||
'event_url': 'http://example.com/ccc/30c3/',
|
'event_url': 'http://example.com/ccc/30c3/',
|
||||||
'name': 'Future',
|
'name': 'Future',
|
||||||
'location': '',
|
'location': '',
|
||||||
|
|||||||
Reference in New Issue
Block a user