Bump Django to 4.1.* (#2989)

This commit is contained in:
Raphael Michel
2023-06-05 09:56:31 +02:00
committed by GitHub
parent 3a8556bb78
commit bd32b33ba9
119 changed files with 742 additions and 613 deletions
+3 -3
View File
@@ -18,13 +18,13 @@ If you want to add a custom view to the control area of an event, just register
.. code-block:: python
from django.conf.urls import url
from django.urls import re_path
from . import views
urlpatterns = [
url(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.admin_view, name='backend'),
re_path(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.admin_view, name='backend'),
]
It is required that your URL parameters are called ``organizer`` and ``event``. If you want to
+3 -3
View File
@@ -35,13 +35,13 @@ automatically and should be provided by any plugin that provides any view.
A very basic example that provides one view in the admin panel and one view in the frontend
could look like this::
from django.conf.urls import url
from django.urls import re_path
from . import views
urlpatterns = [
url(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.AdminView.as_view(), name='backend'),
re_path(r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/mypluginname/',
views.AdminView.as_view(), name='backend'),
]
event_patterns = [
+3 -2
View File
@@ -22,7 +22,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.1",
]
dependencies = [
@@ -36,7 +36,7 @@ dependencies = [
"css-inline==0.8.*",
"defusedcsv>=1.1.0",
"dj-static",
"Django==3.2.*,>=3.2.18",
"Django==4.1.*",
"django-bootstrap3==23.1.*",
"django-compressor==4.3.*",
"django-countries==7.5.*",
@@ -87,6 +87,7 @@ dependencies = [
"python-dateutil==2.8.*",
"python-u2flib-server==4.*",
"pytz",
"pytz-deprecation-shim==0.1.*",
"pyuca",
"qrcode==7.4.*",
"redis==4.5.*,>=4.5.4",
+3 -1
View File
@@ -30,7 +30,6 @@ from django.utils.translation import gettext_lazy as _ # NOQA
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
USE_I18N = True
USE_L10N = True
USE_TZ = True
INSTALLED_APPS = [
@@ -68,6 +67,7 @@ INSTALLED_APPS = [
'oauth2_provider',
'phonenumber_field',
'statici18n',
'django.forms', # after pretix.base for overrides
]
FORMAT_MODULE_PATH = [
@@ -180,6 +180,8 @@ TEMPLATES = [
},
]
FORM_RENDERER = "django.forms.renderers.TemplatesSetting"
STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static.dist')
STATICFILES_FINDERS = (
+9 -5
View File
@@ -535,8 +535,9 @@ class OrderPaymentTypeField(serializers.Field):
# TODO: Remove after pretix 2.2
def to_representation(self, instance: Order):
t = None
for p in instance.payments.all():
t = p.provider
if instance.pk:
for p in instance.payments.all():
t = p.provider
return t
@@ -544,10 +545,10 @@ class OrderPaymentDateField(serializers.DateField):
# TODO: Remove after pretix 2.2
def to_representation(self, instance: Order):
t = None
for p in instance.payments.all():
t = p.payment_date or t
if instance.pk:
for p in instance.payments.all():
t = p.payment_date or t
if t:
return super().to_representation(t.date())
@@ -1363,6 +1364,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
answers.append(answ)
pos.answers = answers
pos.pseudonymization_id = "PREVIEW"
pos.checkins = []
pos_map[pos.positionid] = pos
else:
if pos.voucher:
@@ -1459,6 +1461,8 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
if simulate:
order.fees = fees
order.positions = pos_map.values()
order.payments = []
order.refunds = []
return order # ignore payments
else:
order.save(update_fields=['total'])
+1 -2
View File
@@ -35,8 +35,7 @@
import importlib
from django.apps import apps
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from rest_framework import routers
from pretix.api.views import cart
+2 -2
View File
@@ -23,9 +23,9 @@ import datetime
import mimetypes
import os
from decimal import Decimal
from zoneinfo import ZoneInfo
import django_filters
import pytz
from django.db import transaction
from django.db.models import (
Exists, F, OuterRef, Prefetch, Q, Subquery, prefetch_related_objects,
@@ -612,7 +612,7 @@ class OrderViewSet(viewsets.ModelViewSet):
status=status.HTTP_400_BAD_REQUEST
)
tz = pytz.timezone(self.request.event.settings.timezone)
tz = ZoneInfo(self.request.event.settings.timezone)
new_date = make_aware(datetime.datetime.combine(
new_date,
datetime.time(hour=23, minute=59, second=59)
+2 -2
View File
@@ -37,8 +37,8 @@ import tempfile
from collections import OrderedDict, namedtuple
from decimal import Decimal
from typing import Optional, Tuple
from zoneinfo import ZoneInfo
import pytz
from defusedcsv import csv
from django import forms
from django.conf import settings
@@ -68,7 +68,7 @@ class BaseExporter:
self.events = event
self.event = None
e = self.events.first()
self.timezone = e.timezone if e else pytz.timezone(settings.TIME_ZONE)
self.timezone = e.timezone if e else ZoneInfo(settings.TIME_ZONE)
else:
self.events = Event.objects.filter(pk=event.pk)
self.timezone = event.timezone
+6 -6
View File
@@ -34,8 +34,8 @@
from collections import OrderedDict
from decimal import Decimal
from zoneinfo import ZoneInfo
import pytz
from django import forms
from django.db.models import (
Case, CharField, Count, DateTimeField, F, IntegerField, Max, Min, OuterRef,
@@ -326,7 +326,7 @@ class OrderListExporter(MultiSheetListExporter):
yield self.ProgressSetTotal(total=qs.count())
for order in qs.order_by('datetime').iterator():
tz = pytz.timezone(self.event_object_cache[order.event_id].settings.timezone)
tz = ZoneInfo(self.event_object_cache[order.event_id].settings.timezone)
row = [
self.event_object_cache[order.event_id].slug,
@@ -459,7 +459,7 @@ class OrderListExporter(MultiSheetListExporter):
yield self.ProgressSetTotal(total=qs.count())
for op in qs.order_by('order__datetime').iterator():
order = op.order
tz = pytz.timezone(order.event.settings.timezone)
tz = ZoneInfo(order.event.settings.timezone)
row = [
self.event_object_cache[order.event_id].slug,
order.code,
@@ -631,7 +631,7 @@ class OrderListExporter(MultiSheetListExporter):
for op in ops:
order = op.order
tz = pytz.timezone(self.event_object_cache[order.event_id].settings.timezone)
tz = ZoneInfo(self.event_object_cache[order.event_id].settings.timezone)
row = [
self.event_object_cache[order.event_id].slug,
order.code,
@@ -1024,7 +1024,7 @@ class PaymentListExporter(ListExporter):
yield self.ProgressSetTotal(total=len(objs))
for obj in objs:
tz = pytz.timezone(obj.order.event.settings.timezone)
tz = ZoneInfo(obj.order.event.settings.timezone)
if isinstance(obj, OrderPayment) and obj.payment_date:
d2 = obj.payment_date.astimezone(tz).date().strftime('%Y-%m-%d')
elif isinstance(obj, OrderRefund) and obj.execution_date:
@@ -1203,7 +1203,7 @@ class GiftcardRedemptionListExporter(ListExporter):
yield headers
for obj in objs:
tz = pytz.timezone(obj.order.event.settings.timezone)
tz = ZoneInfo(obj.order.event.settings.timezone)
gc = GiftCard.objects.get(pk=obj.info_data.get('gift_card'))
row = [
obj.order.event.slug,
+2 -2
View File
@@ -20,8 +20,8 @@
# <https://www.gnu.org/licenses/>.
#
from collections import OrderedDict
from zoneinfo import ZoneInfo
import pytz
from django import forms
from django.db.models import F, Q
from django.dispatch import receiver
@@ -137,7 +137,7 @@ class WaitingListExporter(ListExporter):
# which event should be used to output dates in columns "Start date" and "End date"
event_for_date_columns = entry.subevent if entry.subevent else entry.event
tz = pytz.timezone(entry.event.settings.timezone)
tz = ZoneInfo(entry.event.settings.timezone)
datetime_format = '%Y-%m-%d %H:%M:%S'
row = [
+1
View File
@@ -167,6 +167,7 @@ class SettingsForm(i18nfield.forms.I18nFormMixin, HierarkeyForm):
class PrefixForm(forms.Form):
prefix = forms.CharField(widget=forms.HiddenInput)
template_name = 'django/forms/formsets/table.html'
class SafeSessionWizardView(SessionWizardView):
+2 -2
View File
@@ -38,10 +38,10 @@ import logging
from datetime import timedelta
from decimal import Decimal
from io import BytesIO
from zoneinfo import ZoneInfo
import dateutil.parser
import pycountry
import pytz
from django import forms
from django.conf import settings
from django.contrib import messages
@@ -733,7 +733,7 @@ class BaseQuestionsForm(forms.Form):
initial = answers[0]
else:
initial = None
tz = pytz.timezone(event.settings.timezone)
tz = ZoneInfo(event.settings.timezone)
help_text = rich_text(q.help_text)
label = escape(q.question) # django-bootstrap3 calls mark_safe
required = q.required and not self.all_optional
+63
View File
@@ -0,0 +1,63 @@
#
# This file is part of pretix (Community Edition).
#
# Copyright (C) 2014-2020 Raphael Michel and contributors
# Copyright (C) 2020-2021 rami.io GmbH and contributors
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
# Public License as published by the Free Software Foundation in version 3 of the License.
#
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
# this file, see <https://pretix.eu/about/en/license>.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from bootstrap3.renderers import (
FieldRenderer as BaseFieldRenderer,
InlineFieldRenderer as BaseInlineFieldRenderer,
)
from django.forms import (
CheckboxInput, CheckboxSelectMultiple, ClearableFileInput, RadioSelect,
SelectDateWidget,
)
class FieldRenderer(BaseFieldRenderer):
# Local application of https://github.com/zostera/django-bootstrap3/pull/859
def post_widget_render(self, html):
if isinstance(self.widget, CheckboxSelectMultiple):
html = self.list_to_class(html, "checkbox")
elif isinstance(self.widget, RadioSelect):
html = self.list_to_class(html, "radio")
elif isinstance(self.widget, SelectDateWidget):
html = self.fix_date_select_input(html)
elif isinstance(self.widget, ClearableFileInput):
html = self.fix_clearable_file_input(html)
elif isinstance(self.widget, CheckboxInput):
html = self.put_inside_label(html)
return html
class InlineFieldRenderer(BaseInlineFieldRenderer):
# Local application of https://github.com/zostera/django-bootstrap3/pull/859
def post_widget_render(self, html):
if isinstance(self.widget, CheckboxSelectMultiple):
html = self.list_to_class(html, "checkbox")
elif isinstance(self.widget, RadioSelect):
html = self.list_to_class(html, "radio")
elif isinstance(self.widget, SelectDateWidget):
html = self.fix_date_select_input(html)
elif isinstance(self.widget, ClearableFileInput):
html = self.fix_clearable_file_input(html)
elif isinstance(self.widget, CheckboxInput):
html = self.put_inside_label(html)
return html
@@ -22,7 +22,7 @@
import json
import sys
import pytz
import pytz_deprecation_shim
from django.core.management.base import BaseCommand
from django.utils.timezone import override
from django_scopes import scope
@@ -60,7 +60,7 @@ class Command(BaseCommand):
sys.exit(1)
locale = options.get("locale", None)
timezone = pytz.timezone(options['timezone']) if options.get('timezone') else None
timezone = pytz_deprecation_shim.timezone(options['timezone']) if options.get('timezone') else None
with scope(organizer=o):
if options['event_slug']:
+3 -3
View File
@@ -21,8 +21,8 @@
#
from collections import OrderedDict
from urllib.parse import urlsplit
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
import pytz
from django.conf import settings
from django.http import Http404, HttpRequest, HttpResponse
from django.middleware.common import CommonMiddleware
@@ -98,9 +98,9 @@ class LocaleMiddleware(MiddlewareMixin):
tzname = request.user.timezone
if tzname:
try:
timezone.activate(pytz.timezone(tzname))
timezone.activate(ZoneInfo(tzname))
request.timezone = tzname
except pytz.UnknownTimeZoneError:
except ZoneInfoNotFoundError:
pass
else:
timezone.deactivate()
@@ -2,6 +2,8 @@
# Generated by Django 1.10.4 on 2017-02-03 14:21
from __future__ import unicode_literals
from zoneinfo import ZoneInfo
import django.core.validators
import django.db.migrations.operations.special
import django.db.models.deletion
@@ -26,7 +28,7 @@ def forwards42(apps, schema_editor):
for s in EventSetting.objects.filter(key='timezone').values('object_id', 'value')
}
for order in Order.objects.all():
tz = pytz.timezone(etz.get(order.event_id, 'UTC'))
tz = ZoneInfo(etz.get(order.event_id, 'UTC'))
order.expires = order.expires.astimezone(tz).replace(hour=23, minute=59, second=59)
order.save()
@@ -2,9 +2,9 @@
# Generated by Django 1.10.2 on 2016-10-19 17:57
from __future__ import unicode_literals
import pytz
from zoneinfo import ZoneInfo
from django.db import migrations
from django.utils import timezone
def forwards(apps, schema_editor):
@@ -15,7 +15,7 @@ def forwards(apps, schema_editor):
for s in EventSetting.objects.filter(key='timezone').values('object_id', 'value')
}
for order in Order.objects.all():
tz = pytz.timezone(etz.get(order.event_id, 'UTC'))
tz = ZoneInfo(etz.get(order.event_id, 'UTC'))
order.expires = order.expires.astimezone(tz).replace(hour=23, minute=59, second=59)
order.save()
@@ -1,8 +1,7 @@
# Generated by Django 3.2.4 on 2021-09-30 10:25
from datetime import datetime
from datetime import datetime, timezone
from django.db import migrations, models
from pytz import UTC
class Migration(migrations.Migration):
@@ -15,7 +14,7 @@ class Migration(migrations.Migration):
migrations.AddField(
model_name='invoice',
name='sent_to_customer',
field=models.DateTimeField(blank=True, null=True, default=UTC.localize(datetime(1970, 1, 1, 0, 0, 0, 0))),
field=models.DateTimeField(blank=True, null=True, default=datetime(1970, 1, 1, 0, 0, 0, 0, tzinfo=timezone.utc)),
preserve_default=False,
),
]
+13 -4
View File
@@ -121,14 +121,23 @@ class Customer(LoggedModel):
if self.email:
self.email = self.email.lower()
if 'update_fields' in kwargs and 'last_modified' not in kwargs['update_fields']:
kwargs['update_fields'] = list(kwargs['update_fields']) + ['last_modified']
kwargs['update_fields'] = {'last_modified'}.union(kwargs['update_fields'])
if not self.identifier:
self.assign_identifier()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'identifier'}.union(kwargs['update_fields'])
if self.name_parts:
self.name_cached = self.name
name = self.name
if self.name_cached != name:
self.name_cached = name
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'name_cached'}.union(kwargs['update_fields'])
else:
self.name_cached = ""
self.name_parts = {}
if self.name_cached != "" or self.name_parts != {}:
self.name_cached = ""
self.name_parts = {}
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'name_cached', 'name_parts'}.union(kwargs['update_fields'])
super().save(**kwargs)
def anonymize(self):
+4
View File
@@ -98,6 +98,8 @@ class Gate(LoggedModel):
if not Gate.objects.filter(organizer=self.organizer, identifier=code).exists():
self.identifier = code
break
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'identifier'}.union(kwargs['update_fields'])
return super().save(*args, **kwargs)
@@ -173,6 +175,8 @@ class Device(LoggedModel):
def save(self, *args, **kwargs):
if not self.device_id:
self.device_id = (self.organizer.devices.aggregate(m=Max('device_id'))['m'] or 0) + 1
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'device_id'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
def permission_set(self) -> set:
+4 -3
View File
@@ -40,8 +40,9 @@ from collections import Counter, OrderedDict, defaultdict
from datetime import datetime, time, timedelta
from operator import attrgetter
from urllib.parse import urljoin
from zoneinfo import ZoneInfo
import pytz
import pytz_deprecation_shim
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.files.storage import default_storage
@@ -214,7 +215,7 @@ class EventMixin:
@property
def timezone(self):
return pytz.timezone(self.settings.timezone)
return pytz_deprecation_shim.timezone(self.settings.timezone)
@property
def effective_presale_end(self):
@@ -773,7 +774,7 @@ class Event(EventMixin, LoggedModel):
"""
The last datetime of payments for this event.
"""
tz = pytz.timezone(self.settings.timezone)
tz = ZoneInfo(self.settings.timezone)
return make_aware(datetime.combine(
self.settings.get('payment_term_last', as_type=RelativeDateWrapper).datetime(self).date(),
time(hour=23, minute=59, second=59)
+6 -8
View File
@@ -19,10 +19,11 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
import zoneinfo
from datetime import datetime, timedelta
import pytz
from dateutil.rrule import rrulestr
from dateutil.tz import datetime_exists
from django.conf import settings
from django.core.serializers.json import DjangoJSONEncoder
from django.db import models
@@ -108,12 +109,9 @@ class AbstractScheduledExport(LoggedModel):
self.schedule_next_run = None
return
try:
self.schedule_next_run = make_aware(datetime.combine(new_d.date(), self.schedule_rrule_time), tz)
except pytz.exceptions.AmbiguousTimeError:
self.schedule_next_run = make_aware(datetime.combine(new_d.date(), self.schedule_rrule_time), tz, is_dst=False)
except pytz.exceptions.NonExistentTimeError:
self.schedule_next_run = make_aware(datetime.combine(new_d.date(), self.schedule_rrule_time) + timedelta(hours=1), tz)
self.schedule_next_run = make_aware(datetime.combine(new_d.date(), self.schedule_rrule_time), tz)
if not datetime_exists(self.schedule_next_run):
self.schedule_next_run += timedelta(hours=1)
class ScheduledEventExport(AbstractScheduledExport):
@@ -136,4 +134,4 @@ class ScheduledOrganizerExport(AbstractScheduledExport):
@property
def tz(self):
return pytz.timezone(self.timezone)
return zoneinfo.ZoneInfo(self.timezone)
+12 -1
View File
@@ -251,14 +251,20 @@ class Invoice(models.Model):
raise ValueError('Every invoice needs to be connected to an order')
if not self.event:
self.event = self.order.event
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'event'}.union(kwargs['update_fields'])
if not self.organizer:
self.organizer = self.order.event.organizer
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'organizer'}.union(kwargs['update_fields'])
if not self.prefix:
self.prefix = self.event.settings.invoice_numbers_prefix or (self.event.slug.upper() + '-')
if self.is_cancellation:
self.prefix = self.event.settings.invoice_numbers_prefix_cancellations or self.prefix
if '%' in self.prefix:
self.prefix = self.date.strftime(self.prefix)
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'prefix'}.union(kwargs['update_fields'])
if not self.invoice_no:
if self.order.testmode:
@@ -276,8 +282,13 @@ class Invoice(models.Model):
# Suppress duplicate key errors and try again
if i == 9:
raise
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'invoice_no'}.union(kwargs['update_fields'])
self.full_invoice_no = self.prefix + self.invoice_no
if self.full_invoice_no != self.prefix + self.invoice_no:
self.full_invoice_no = self.prefix + self.invoice_no
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'full_invoice_no'}.union(kwargs['update_fields'])
return super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
+16 -8
View File
@@ -40,9 +40,10 @@ from collections import Counter, OrderedDict
from datetime import date, datetime, time, timedelta
from decimal import Decimal, DecimalException
from typing import Optional, Tuple
from zoneinfo import ZoneInfo
import dateutil.parser
import pytz
from dateutil.tz import datetime_exists
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import (
@@ -927,22 +928,22 @@ class Item(LoggedModel):
)
if self.validity_dynamic_duration_days:
replace_date += timedelta(days=self.validity_dynamic_duration_days)
valid_until = tz.localize(valid_until.replace(
valid_until = valid_until.replace(
year=replace_date.year,
month=replace_date.month,
day=replace_date.day,
hour=23, minute=59, second=59, microsecond=0,
tzinfo=None,
))
tzinfo=tz,
)
elif self.validity_dynamic_duration_days:
replace_date = valid_until.date() + timedelta(days=self.validity_dynamic_duration_days - 1)
valid_until = tz.localize(valid_until.replace(
valid_until = valid_until.replace(
year=replace_date.year,
month=replace_date.month,
day=replace_date.day,
hour=23, minute=59, second=59, microsecond=0,
tzinfo=None
))
tzinfo=tz
)
if self.validity_dynamic_duration_hours:
valid_until += timedelta(hours=self.validity_dynamic_duration_hours)
@@ -950,6 +951,9 @@ class Item(LoggedModel):
if self.validity_dynamic_duration_minutes:
valid_until += timedelta(minutes=self.validity_dynamic_duration_minutes)
if not datetime_exists(valid_until):
valid_until += timedelta(hours=1)
return requested_start, valid_until
else:
@@ -1589,6 +1593,8 @@ class Question(LoggedModel):
if not Question.objects.filter(event=self.event, identifier=code).exists():
self.identifier = code
break
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'identifier'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
if self.event:
self.event.cache.clear()
@@ -1678,7 +1684,7 @@ class Question(LoggedModel):
try:
dt = dateutil.parser.parse(answer)
if is_naive(dt):
dt = make_aware(dt, pytz.timezone(self.event.settings.timezone))
dt = make_aware(dt, ZoneInfo(self.event.settings.timezone))
except:
raise ValidationError(_('Invalid datetime input.'))
else:
@@ -1736,6 +1742,8 @@ class QuestionOption(models.Model):
if not QuestionOption.objects.filter(question__event=self.question.event, identifier=code).exists():
self.identifier = code
break
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'identifier'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
@staticmethod
+45 -14
View File
@@ -42,10 +42,10 @@ from collections import Counter
from datetime import datetime, time, timedelta
from decimal import Decimal
from typing import Any, Dict, List, Union
from zoneinfo import ZoneInfo
import dateutil
import pycountry
import pytz
from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models, transaction
@@ -461,14 +461,20 @@ class Order(LockModel, LoggedModel):
return '{event}-{code}'.format(event=self.event.slug.upper(), code=self.code)
def save(self, **kwargs):
if 'update_fields' in kwargs and 'last_modified' not in kwargs['update_fields']:
kwargs['update_fields'] = list(kwargs['update_fields']) + ['last_modified']
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'last_modified'}.union(kwargs['update_fields'])
if not self.code:
self.assign_code()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'code'}.union(kwargs['update_fields'])
if not self.datetime:
self.datetime = now()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'datetime'}.union(kwargs['update_fields'])
if not self.expires:
self.set_expires()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'expires'}.union(kwargs['update_fields'])
is_new = not self.pk
update_fields = kwargs.get('update_fields', [])
@@ -496,7 +502,7 @@ class Order(LockModel, LoggedModel):
def set_expires(self, now_dt=None, subevents=None):
now_dt = now_dt or now()
tz = pytz.timezone(self.event.settings.timezone)
tz = ZoneInfo(self.event.settings.timezone)
mode = self.event.settings.get('payment_term_mode')
if mode == 'days':
exp_by_date = now_dt.astimezone(tz) + timedelta(days=self.event.settings.get('payment_term_days', as_type=int))
@@ -870,7 +876,7 @@ class Order(LockModel, LoggedModel):
@property
def payment_term_last(self):
tz = pytz.timezone(self.event.settings.timezone)
tz = ZoneInfo(self.event.settings.timezone)
term_last = self.event.settings.get('payment_term_last', as_type=RelativeDateWrapper)
if term_last:
if self.event.has_subevents:
@@ -1230,7 +1236,7 @@ class QuestionAnswer(models.Model):
try:
d = dateutil.parser.parse(self.answer)
if self.orderposition:
tz = pytz.timezone(self.orderposition.order.event.settings.timezone)
tz = ZoneInfo(self.orderposition.order.event.settings.timezone)
d = d.astimezone(tz)
return date_format(d, "SHORT_DATETIME_FORMAT")
except ValueError:
@@ -1442,12 +1448,20 @@ class AbstractPosition(models.Model):
else self.variation.quotas.filter(subevent=self.subevent))
def save(self, *args, **kwargs):
update_fields = kwargs.get('update_fields', [])
update_fields = kwargs.get('update_fields', set())
if 'attendee_name_parts' in update_fields:
update_fields.append('attendee_name_cached')
self.attendee_name_cached = self.attendee_name
kwargs['update_fields'] = {'attendee_name_cached'}.union(kwargs['update_fields'])
name = self.attendee_name
if name != self.attendee_name_cached:
self.attendee_name_cached = name
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'attendee_name_cached'}.union(kwargs['update_fields'])
if self.attendee_name_parts is None:
self.attendee_name_parts = {}
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'attendee_name_parts'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
@property
@@ -1827,6 +1841,8 @@ class OrderPayment(models.Model):
def save(self, *args, **kwargs):
if not self.local_id:
self.local_id = (self.order.payments.aggregate(m=Max('local_id'))['m'] or 0) + 1
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'local_id'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
def create_external_refund(self, amount=None, execution_date=None, info='{}'):
@@ -2025,6 +2041,8 @@ class OrderRefund(models.Model):
def save(self, *args, **kwargs):
if not self.local_id:
self.local_id = (self.order.refunds.aggregate(m=Max('local_id'))['m'] or 0) + 1
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'local_id'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
@@ -2443,14 +2461,20 @@ class OrderPosition(AbstractPosition):
assign_ticket_secret(
event=self.order.event, position=self, force_invalidate=True, save=False
)
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'secret'}.union(kwargs['update_fields'])
if not self.blocked:
if not self.blocked and self.blocked is not None:
self.blocked = None
elif not isinstance(self.blocked, list) or any(not isinstance(b, str) for b in self.blocked):
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'blocked'}.union(kwargs['update_fields'])
elif self.blocked and (not isinstance(self.blocked, list) or any(not isinstance(b, str) for b in self.blocked)):
raise TypeError("blocked needs to be a list of strings")
if not self.pseudonymization_id:
self.assign_pseudonymization_id()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'pseudonymization_id'}.union(kwargs['update_fields'])
if not self.get_deferred_fields():
if Transaction.key(self) != self.__initial_transaction_key or self.canceled != self.__initial_canceled or not self.pk:
@@ -2936,10 +2960,17 @@ class InvoiceAddress(models.Model):
self.order.touch()
if self.name_parts:
self.name_cached = self.name
name = self.name
if self.name_cached != name:
self.name_cached = self.name
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'name_cached'}.union(kwargs['update_fields'])
else:
self.name_cached = ""
self.name_parts = {}
if self.name_cached != "" or self.name_parts != {}:
self.name_cached = ""
self.name_parts = {}
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'name_cached', 'name_parts'}.union(kwargs['update_fields'])
super().save(**kwargs)
def describe(self):
+3 -2
View File
@@ -35,7 +35,7 @@
import string
from datetime import date, datetime, time
import pytz
import pytz_deprecation_shim
from django.conf import settings
from django.core.mail import get_connection
from django.core.validators import MinLengthValidator, RegexValidator
@@ -102,6 +102,7 @@ class Organizer(LoggedModel):
is_new = not self.pk
obj = super().save(*args, **kwargs)
if is_new:
kwargs.pop('update_fields', None) # does not make sense here
self.set_defaults()
else:
self.get_cache().clear()
@@ -140,7 +141,7 @@ class Organizer(LoggedModel):
@property
def timezone(self):
return pytz.timezone(self.settings.timezone)
return pytz_deprecation_shim.timezone(self.settings.timezone)
@cached_property
def all_logentries_link(self):
+4 -1
View File
@@ -502,7 +502,10 @@ class Voucher(LoggedModel):
return seat
def save(self, *args, **kwargs):
self.code = self.code.upper()
if self.code != self.code.upper():
self.code = self.code.upper()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'code'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
self.event.cache.set('vouchers_exist', True)
+10 -3
View File
@@ -126,12 +126,19 @@ class WaitingListEntry(LoggedModel):
raise ValidationError('Invalid input')
def save(self, *args, **kwargs):
update_fields = kwargs.get('update_fields', [])
update_fields = kwargs.get('update_fields', set())
if 'name_parts' in update_fields:
update_fields.append('name_cached')
self.name_cached = self.name
kwargs['update_fields'] = {'name_cached'}.union(kwargs['update_fields'])
name = self.name
if name != self.name_cached:
self.name_cached = name
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'name_cached'}.union(kwargs['update_fields'])
if self.name_parts is None:
self.name_parts = {}
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'name_parts'}.union(kwargs['update_fields'])
super().save(*args, **kwargs)
@property
+3 -3
View File
@@ -210,7 +210,7 @@ class SubeventColumn(ImportColumn):
for format in input_formats:
try:
d = datetime.datetime.strptime(value, format)
d = self.event.timezone.localize(d)
d = d.replace(tzinfo=self.event.timezone)
try:
se = self.event.subevents.get(
active=True,
@@ -660,7 +660,7 @@ class ValidFrom(ImportColumn):
for format in input_formats:
try:
d = datetime.datetime.strptime(value, format)
d = self.event.timezone.localize(d)
d = d.replace(tzinfo=self.event.timezone)
return d
except (ValueError, TypeError):
pass
@@ -683,7 +683,7 @@ class ValidUntil(ImportColumn):
for format in input_formats:
try:
d = datetime.datetime.strptime(value, format)
d = self.event.timezone.localize(d)
d = d.replace(tzinfo=self.event.timezone)
return d
except (ValueError, TypeError):
pass
+2 -2
View File
@@ -39,8 +39,8 @@ import logging
from collections import OrderedDict
from decimal import ROUND_HALF_UP, Decimal
from typing import Any, Dict, Union
from zoneinfo import ZoneInfo
import pytz
from django import forms
from django.conf import settings
from django.contrib import messages
@@ -518,7 +518,7 @@ class BasePaymentProvider:
def _is_still_available(self, now_dt=None, cart_id=None, order=None):
now_dt = now_dt or now()
tz = pytz.timezone(self.event.settings.timezone)
tz = ZoneInfo(self.event.settings.timezone)
availability_date = self.settings.get('_availability_date', as_type=RelativeDateWrapper)
if availability_date:
+16 -17
View File
@@ -61,7 +61,6 @@ from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _, pgettext
from i18nfield.strings import LazyI18nString
from pypdf import PdfReader
from pytz import timezone
from reportlab.graphics import renderPDF
from reportlab.graphics.barcode.qr import QrCodeWidget
from reportlab.graphics.shapes import Drawing
@@ -237,7 +236,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event begin date and time"),
"editor_sample": _("2017-05-31 20:00"),
"evaluate": lambda op, order, ev: date_format(
ev.date_from.astimezone(timezone(ev.settings.timezone)),
ev.date_from.astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
) if ev.date_from else ""
}),
@@ -245,7 +244,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event begin date"),
"editor_sample": _("2017-05-31"),
"evaluate": lambda op, order, ev: date_format(
ev.date_from.astimezone(timezone(ev.settings.timezone)),
ev.date_from.astimezone(ev.timezone),
"SHORT_DATE_FORMAT"
) if ev.date_from else ""
}),
@@ -263,7 +262,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event end date and time"),
"editor_sample": _("2017-05-31 22:00"),
"evaluate": lambda op, order, ev: date_format(
ev.date_to.astimezone(timezone(ev.settings.timezone)),
ev.date_to.astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
) if ev.date_to else ""
}),
@@ -271,7 +270,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event end date"),
"editor_sample": _("2017-05-31"),
"evaluate": lambda op, order, ev: date_format(
ev.date_to.astimezone(timezone(ev.settings.timezone)),
ev.date_to.astimezone(ev.timezone),
"SHORT_DATE_FORMAT"
) if ev.date_to else ""
}),
@@ -279,7 +278,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event end time"),
"editor_sample": _("22:00"),
"evaluate": lambda op, order, ev: date_format(
ev.date_to.astimezone(timezone(ev.settings.timezone)),
ev.date_to.astimezone(ev.timezone),
"TIME_FORMAT"
) if ev.date_to else ""
}),
@@ -292,7 +291,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event admission date and time"),
"editor_sample": _("2017-05-31 19:00"),
"evaluate": lambda op, order, ev: date_format(
ev.date_admission.astimezone(timezone(ev.settings.timezone)),
ev.date_admission.astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
) if ev.date_admission else ""
}),
@@ -300,7 +299,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Event admission time"),
"editor_sample": _("19:00"),
"evaluate": lambda op, order, ev: date_format(
ev.date_admission.astimezone(timezone(ev.settings.timezone)),
ev.date_admission.astimezone(ev.timezone),
"TIME_FORMAT"
) if ev.date_admission else ""
}),
@@ -385,7 +384,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Printing date"),
"editor_sample": _("2017-05-31"),
"evaluate": lambda op, order, ev: date_format(
now().astimezone(timezone(ev.settings.timezone)),
now().astimezone(ev.timezone),
"SHORT_DATE_FORMAT"
)
}),
@@ -393,7 +392,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Printing date and time"),
"editor_sample": _("2017-05-31 19:00"),
"evaluate": lambda op, order, ev: date_format(
now().astimezone(timezone(ev.settings.timezone)),
now().astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
)
}),
@@ -401,7 +400,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Printing time"),
"editor_sample": _("19:00"),
"evaluate": lambda op, order, ev: date_format(
now().astimezone(timezone(ev.settings.timezone)),
now().astimezone(ev.timezone),
"TIME_FORMAT"
)
}),
@@ -409,7 +408,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Validity start date"),
"editor_sample": _("2017-05-31"),
"evaluate": lambda op, order, ev: date_format(
op.valid_from.astimezone(timezone(ev.settings.timezone)),
op.valid_from.astimezone(ev.timezone),
"SHORT_DATE_FORMAT"
) if op.valid_from else ""
}),
@@ -417,7 +416,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Validity start date and time"),
"editor_sample": _("2017-05-31 19:00"),
"evaluate": lambda op, order, ev: date_format(
op.valid_from.astimezone(timezone(ev.settings.timezone)),
op.valid_from.astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
) if op.valid_from else ""
}),
@@ -425,7 +424,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Validity start time"),
"editor_sample": _("19:00"),
"evaluate": lambda op, order, ev: date_format(
op.valid_from.astimezone(timezone(ev.settings.timezone)),
op.valid_from.astimezone(ev.timezone),
"TIME_FORMAT"
) if op.valid_from else ""
}),
@@ -433,7 +432,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Validity end date"),
"editor_sample": _("2017-05-31"),
"evaluate": lambda op, order, ev: date_format(
op.valid_until.astimezone(timezone(ev.settings.timezone)),
op.valid_until.astimezone(ev.timezone),
"SHORT_DATE_FORMAT"
) if op.valid_until else ""
}),
@@ -441,7 +440,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Validity end date and time"),
"editor_sample": _("2017-05-31 19:00"),
"evaluate": lambda op, order, ev: date_format(
op.valid_until.astimezone(timezone(ev.settings.timezone)),
op.valid_until.astimezone(ev.timezone),
"SHORT_DATETIME_FORMAT"
) if op.valid_until else ""
}),
@@ -449,7 +448,7 @@ DEFAULT_VARIABLES = OrderedDict((
"label": _("Validity end time"),
"editor_sample": _("19:00"),
"evaluate": lambda op, order, ev: date_format(
op.valid_until.astimezone(timezone(ev.settings.timezone)),
op.valid_until.astimezone(ev.timezone),
"TIME_FORMAT"
) if op.valid_until else ""
}),
+4 -7
View File
@@ -22,8 +22,8 @@
import datetime
from collections import namedtuple
from typing import Union
from zoneinfo import ZoneInfo
import pytz
from dateutil import parser
from django import forms
from django.core.exceptions import ValidationError
@@ -67,7 +67,7 @@ class RelativeDateWrapper:
if self.data.minutes_before is not None:
raise ValueError('A minute-based relative datetime can not be used as a date')
tz = pytz.timezone(event.settings.timezone)
tz = ZoneInfo(event.settings.timezone)
if isinstance(event, SubEvent):
base_date = (
getattr(event, self.data.base_date_name)
@@ -86,7 +86,7 @@ class RelativeDateWrapper:
if isinstance(self.data, (datetime.datetime, datetime.date)):
return self.data
else:
tz = pytz.timezone(event.settings.timezone)
tz = ZoneInfo(event.settings.timezone)
if isinstance(event, SubEvent):
base_date = (
getattr(event, self.data.base_date_name)
@@ -99,8 +99,7 @@ class RelativeDateWrapper:
if self.data.minutes_before is not None:
return base_date.astimezone(tz) - datetime.timedelta(minutes=self.data.minutes_before)
else:
oldoffset = base_date.astimezone(tz).utcoffset()
new_date = base_date.astimezone(tz) - datetime.timedelta(days=self.data.days_before)
new_date = (base_date.astimezone(tz) - datetime.timedelta(days=self.data.days_before)).astimezone(tz)
if self.data.time:
new_date = new_date.replace(
hour=self.data.time.hour,
@@ -108,8 +107,6 @@ class RelativeDateWrapper:
second=self.data.time.second
)
new_date = new_date.astimezone(tz)
new_offset = new_date.utcoffset()
new_date += oldoffset - new_offset
return new_date
def to_string(self) -> str:
+9 -12
View File
@@ -32,12 +32,12 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
import os
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from functools import partial, reduce
import dateutil
import dateutil.parser
import pytz
from dateutil.tz import datetime_exists
from django.core.files import File
from django.db import IntegrityError, transaction
from django.db.models import (
@@ -439,7 +439,7 @@ class SQLLogic:
if operator == 'buildTime':
if values[0] == "custom":
return Value(dateutil.parser.parse(values[1]).astimezone(pytz.UTC))
return Value(dateutil.parser.parse(values[1]).astimezone(timezone.utc))
elif values[0] == "customtime":
parsed = dateutil.parser.parse(values[1])
return Value(now().astimezone(self.list.event.timezone).replace(
@@ -447,7 +447,7 @@ class SQLLogic:
minute=parsed.minute,
second=parsed.second,
microsecond=parsed.microsecond,
).astimezone(pytz.UTC))
).astimezone(timezone.utc))
elif values[0] == 'date_from':
return Coalesce(
F('subevent__date_from'),
@@ -475,7 +475,7 @@ class SQLLogic:
return int(values[1])
elif operator == 'var':
if values[0] == 'now':
return Value(now().astimezone(pytz.UTC))
return Value(now().astimezone(timezone.utc))
elif values[0] == 'now_isoweekday':
return Value(now().astimezone(self.list.event.timezone).isoweekday())
elif values[0] == 'product':
@@ -926,14 +926,11 @@ def process_exit_all(sender, **kwargs):
if cl.event.settings.get(f'autocheckin_dst_hack_{cl.pk}'): # move time back if yesterday was DST switch
d -= timedelta(hours=1)
cl.event.settings.delete(f'autocheckin_dst_hack_{cl.pk}')
try:
cl.exit_all_at = make_aware(datetime.combine(d.date() + timedelta(days=1), d.time()), cl.event.timezone)
except pytz.exceptions.AmbiguousTimeError:
cl.exit_all_at = make_aware(datetime.combine(d.date() + timedelta(days=1), d.time()), cl.event.timezone,
is_dst=False)
except pytz.exceptions.NonExistentTimeError:
cl.exit_all_at = make_aware(datetime.combine(d.date() + timedelta(days=1), d.time().replace(fold=1)), cl.event.timezone)
if not datetime_exists(cl.exit_all_at):
cl.event.settings.set(f'autocheckin_dst_hack_{cl.pk}', True)
d += timedelta(hours=1)
cl.exit_all_at = make_aware(datetime.combine(d.date() + timedelta(days=1), d.time()), cl.event.timezone)
cl.exit_all_at = make_aware(datetime.combine(d.date() + timedelta(days=1), d.time().replace(fold=1)), cl.event.timezone)
# AmbiguousTimeError shouldn't be possible since d.time() includes fold=0
cl.save(update_fields=['exit_all_at'])
+3 -3
View File
@@ -45,8 +45,8 @@ from email.mime.image import MIMEImage
from email.utils import formataddr
from typing import Any, Dict, List, Sequence, Union
from urllib.parse import urljoin, urlparse
from zoneinfo import ZoneInfo
import pytz
import requests
from bs4 import BeautifulSoup
from celery import chain
@@ -226,11 +226,11 @@ def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, La
if event:
timezone = event.timezone
elif user:
timezone = pytz.timezone(user.timezone)
timezone = ZoneInfo(user.timezone)
elif organizer:
timezone = organizer.timezone
else:
timezone = pytz.timezone(settings.TIME_ZONE)
timezone = ZoneInfo(settings.TIME_ZONE)
if settings_holder:
if settings_holder.settings.mail_bcc:
@@ -0,0 +1,6 @@
{# this is the version from django 3.x, prior to https://github.com/django/django/commit/5942ab5eb165ee2e759174e297148a40dd855920 so that django-bootstrap3 can keep doing its magic #}
{% with id=widget.attrs.id %}<ul{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>{% for group, options, index in widget.optgroups %}{% if group %}
<li>{{ group }}<ul{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}{% for option in options %}
<li>{% include option.template_name with widget=option %}</li>{% endfor %}{% if group %}
</ul></li>{% endif %}{% endfor %}
</ul>{% endwith %}
+2 -3
View File
@@ -20,11 +20,10 @@
# <https://www.gnu.org/licenses/>.
#
import calendar
from datetime import date, datetime, time, timedelta
from datetime import date, datetime, time, timedelta, timezone
from itertools import groupby
from typing import Optional, Tuple
import pytz
from django import forms
from django.core.exceptions import ValidationError
from django.utils.formats import date_format
@@ -392,7 +391,7 @@ class SerializerDateFrameField(serializers.CharField):
if data is None:
return None
try:
resolve_timeframe_to_dates_inclusive(now(), data, pytz.UTC)
resolve_timeframe_to_dates_inclusive(now(), data, timezone.utc)
except:
raise ValidationError("Invalid date frame")
+5 -5
View File
@@ -21,9 +21,9 @@
#
import logging
from importlib import import_module
from zoneinfo import ZoneInfo
import celery.exceptions
import pytz
from celery import states
from celery.result import AsyncResult
from django.conf import settings
@@ -252,7 +252,7 @@ class AsyncFormView(AsyncMixin, FormView):
task_self = self
view_instance._task_self = task_self
with translation.override(locale), timezone.override(pytz.timezone(tz)):
with translation.override(locale), timezone.override(ZoneInfo(tz)):
form_class = view_instance.get_form_class()
if form_kwargs.get('instance'):
form_kwargs['instance'] = cls.model.objects.get(pk=form_kwargs['instance'])
@@ -302,7 +302,7 @@ class AsyncFormView(AsyncMixin, FormView):
'url_args': self.args,
'url_kwargs': self.kwargs,
'locale': get_language(),
'tz': get_current_timezone().zone,
'tz': str(get_current_timezone()),
}
if hasattr(self.request, 'organizer'):
kwargs['organizer'] = self.request.organizer.pk
@@ -377,7 +377,7 @@ class AsyncPostView(AsyncMixin, View):
task_self = self
view_instance._task_self = task_self
with translation.override(locale), timezone.override(pytz.timezone(tz)):
with translation.override(locale), timezone.override(ZoneInfo(tz)):
return view_instance.async_post(view_instance.request, *url_args, **url_kwargs)
cls.async_execute = app.task(
@@ -405,7 +405,7 @@ class AsyncPostView(AsyncMixin, View):
'locale': get_language(),
'url_args': args,
'url_kwargs': kwargs,
'tz': get_current_timezone().zone,
'tz': str(get_current_timezone()),
}
if hasattr(self.request, 'organizer'):
kwargs['organizer'] = self.request.organizer.pk
+4 -3
View File
@@ -36,6 +36,7 @@
from decimal import Decimal
from urllib.parse import urlencode, urlparse
from zoneinfo import ZoneInfo
from django import forms
from django.conf import settings
@@ -55,7 +56,7 @@ from django_countries.fields import LazyTypedChoiceField
from i18nfield.forms import (
I18nForm, I18nFormField, I18nFormSetMixin, I18nTextarea, I18nTextInput,
)
from pytz import common_timezones, timezone
from pytz import common_timezones
from pretix.base.channels import get_all_sales_channels
from pretix.base.email import get_available_placeholders
@@ -221,7 +222,7 @@ class EventWizardBasicsForm(I18nModelForm):
})
# change timezone
zone = timezone(data.get('timezone'))
zone = ZoneInfo(data.get('timezone'))
data['date_from'] = self.reset_timezone(zone, data.get('date_from'))
data['date_to'] = self.reset_timezone(zone, data.get('date_to'))
data['presale_start'] = self.reset_timezone(zone, data.get('presale_start'))
@@ -230,7 +231,7 @@ class EventWizardBasicsForm(I18nModelForm):
@staticmethod
def reset_timezone(tz, dt):
return tz.localize(dt.replace(tzinfo=None)) if dt is not None else None
return dt.replace(tzinfo=tz) if dt is not None else None
def clean_slug(self):
slug = self.cleaned_data['slug']
+1 -1
View File
@@ -747,7 +747,7 @@ class ItemVariationsFormSet(I18nFormSet):
def _should_delete_form(self, form):
should_delete = super()._should_delete_form(form)
if should_delete and (form.instance.orderposition_set.exists() or form.instance.cartposition_set.exists()):
if should_delete and form.instance.pk and (form.instance.orderposition_set.exists() or form.instance.cartposition_set.exists()):
form._delete_fail = True
return False
return form.cleaned_data.get(DELETION_FIELD_NAME, False)
+1 -1
View File
@@ -602,7 +602,7 @@ class WebHookForm(forms.ModelForm):
mark_safe('{} <code>{}</code>'.format(a.verbose_name, a.action_type))
) for a in get_all_webhook_events().values()
]
if self.instance:
if self.instance and self.instance.pk:
self.fields['events'].initial = list(self.instance.listeners.values_list('action_type', flat=True))
class Meta:
+2 -1
View File
@@ -19,7 +19,6 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from bootstrap3.renderers import FieldRenderer, InlineFieldRenderer
from bootstrap3.text import text_value
from django.forms import CheckboxInput
from django.forms.utils import flatatt
@@ -28,6 +27,8 @@ from django.utils.safestring import mark_safe
from django.utils.translation import pgettext
from i18nfield.forms import I18nFormField
from pretix.base.forms.renderers import FieldRenderer, InlineFieldRenderer
def render_label(content, label_for=None, label_class=None, label_title='', optional=False):
"""
+2 -3
View File
@@ -39,7 +39,6 @@ from decimal import Decimal
import bleach
import dateutil.parser
import pytz
from django.dispatch import receiver
from django.urls import reverse
from django.utils.formats import date_format
@@ -209,7 +208,7 @@ def _display_checkin(event, logentry):
if 'datetime' in data:
dt = dateutil.parser.parse(data.get('datetime'))
show_dt = abs((logentry.datetime - dt).total_seconds()) > 5 or 'forced' in data
tz = pytz.timezone(event.settings.timezone)
tz = event.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in data:
@@ -627,7 +626,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
if logentry.action_type == 'pretix.control.views.checkin':
# deprecated
dt = dateutil.parser.parse(data.get('datetime'))
tz = pytz.timezone(sender.settings.timezone)
tz = sender.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in data:
try:
+1 -2
View File
@@ -33,8 +33,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from django.views.generic.base import RedirectView
from pretix.control.views import (
+17 -17
View File
@@ -19,18 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of
# the Apache License 2.0 can be obtained at <http://www.apache.org/licenses/LICENSE-2.0>.
#
# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A
# full history of changes and contributors is available at <https://github.com/pretix/pretix>.
#
# This file contains Apache-licensed contributions copyrighted by: Jakob Schnell, jasonwaiting@live.hk, pajowu
#
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from datetime import timezone
import dateutil.parser
from django.contrib import messages
@@ -44,7 +33,6 @@ from django.utils.functional import cached_property
from django.utils.timezone import is_aware, make_aware, now
from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView
from pytz import UTC
from pretix.base.channels import get_all_sales_channels
from pretix.base.models import Checkin, Order, OrderPosition
@@ -60,6 +48,18 @@ from pretix.control.views import CreateView, PaginationMixin, UpdateView
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.models import modelcopy
# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of
# the Apache License 2.0 can be obtained at <http://www.apache.org/licenses/LICENSE-2.0>.
#
# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A
# full history of changes and contributors is available at <https://github.com/pretix/pretix>.
#
# This file contains Apache-licensed contributions copyrighted by: Jakob Schnell, jasonwaiting@live.hk, pajowu
#
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
class CheckInListQueryMixin:
@@ -163,20 +163,20 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList
if e.last_entry:
if isinstance(e.last_entry, str):
# Apparently only happens on SQLite
e.last_entry_aware = make_aware(dateutil.parser.parse(e.last_entry), UTC)
e.last_entry_aware = make_aware(dateutil.parser.parse(e.last_entry), timezone.utc)
elif not is_aware(e.last_entry):
# Apparently only happens on MySQL
e.last_entry_aware = make_aware(e.last_entry, UTC)
e.last_entry_aware = make_aware(e.last_entry, timezone.utc)
else:
# This would be correct, so guess on which database it works… Yes, it's PostgreSQL.
e.last_entry_aware = e.last_entry
if e.last_exit:
if isinstance(e.last_exit, str):
# Apparently only happens on SQLite
e.last_exit_aware = make_aware(dateutil.parser.parse(e.last_exit), UTC)
e.last_exit_aware = make_aware(dateutil.parser.parse(e.last_exit), timezone.utc)
elif not is_aware(e.last_exit):
# Apparently only happens on MySQL
e.last_exit_aware = make_aware(e.last_exit, UTC)
e.last_exit_aware = make_aware(e.last_exit, timezone.utc)
else:
# This would be correct, so guess on which database it works… Yes, it's PostgreSQL.
e.last_exit_aware = e.last_exit
+2 -2
View File
@@ -34,8 +34,8 @@
from datetime import timedelta
from decimal import Decimal
from zoneinfo import ZoneInfo
import pytz
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import (
@@ -510,7 +510,7 @@ def widgets_for_event_qs(request, qs, user, nmax, lazy=False):
for event in events:
if not lazy:
tzname = event.cache.get_or_set('timezone', lambda: event.settings.timezone)
tz = pytz.timezone(tzname)
tz = ZoneInfo(tzname)
if event.has_subevents:
if event.min_from is None:
dr = pgettext("subevent", "No dates")
+3 -3
View File
@@ -41,6 +41,7 @@ from decimal import Decimal
from io import BytesIO
from itertools import groupby
from urllib.parse import urlsplit
from zoneinfo import ZoneInfo
import bleach
import qrcode
@@ -67,7 +68,6 @@ from django.views.generic.base import TemplateView, View
from django.views.generic.detail import SingleObjectMixin
from i18nfield.strings import LazyI18nString
from i18nfield.utils import I18nJSONEncoder
from pytz import timezone
from pretix.base.channels import get_all_sales_channels
from pretix.base.email import get_available_placeholders
@@ -253,7 +253,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
self.item_meta_property_formset.is_valid() and self.confirm_texts_formset.is_valid() and \
self.footer_links_formset.is_valid():
# reset timezone
zone = timezone(self.sform.cleaned_data['timezone'])
zone = ZoneInfo(self.sform.cleaned_data['timezone'])
event = form.instance
event.date_from = self.reset_timezone(zone, event.date_from)
event.date_to = self.reset_timezone(zone, event.date_to)
@@ -266,7 +266,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
@staticmethod
def reset_timezone(tz, dt):
return tz.localize(dt.replace(tzinfo=None)) if dt is not None else None
return dt.replace(tzinfo=tz) if dt is not None else None
@cached_property
def item_meta_property_formset(self):
+3 -4
View File
@@ -60,8 +60,7 @@ from django.utils.timezone import get_current_timezone, now
from django.utils.translation import gettext, gettext_lazy as _
from django.views import View
from django.views.generic import (
CreateView, DeleteView, DetailView, FormView, ListView, TemplateView,
UpdateView,
CreateView, DetailView, FormView, ListView, TemplateView, UpdateView,
)
from pretix.api.models import ApiCall, WebHook
@@ -1775,7 +1774,7 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
instance = self.scheduled or ScheduledOrganizerExport(
organizer=self.request.organizer,
owner=self.request.user,
timezone=get_current_timezone().zone,
timezone=str(get_current_timezone()),
)
if not self.scheduled:
initial = {
@@ -1811,7 +1810,7 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
return ctx
class DeleteScheduledExportView(OrganizerPermissionRequiredMixin, ExportMixin, DeleteView):
class DeleteScheduledExportView(OrganizerPermissionRequiredMixin, ExportMixin, CompatDeleteView):
template_name = 'pretixcontrol/organizers/export_delete.html'
context_object_name = 'export'
+16 -10
View File
@@ -260,7 +260,7 @@ class SubEventEditorMixin(MetaDataEditorMixin):
form=SimpleCheckinListForm, formset=CheckinListFormSet,
can_order=False, can_delete=True, extra=extra,
)
if self.object:
if self.object and self.object.pk:
kwargs['queryset'] = self.object.checkinlist_set.prefetch_related('limit_products')
return formsetclass(self.request.POST if self.request.method == "POST" else None,
@@ -297,7 +297,7 @@ class SubEventEditorMixin(MetaDataEditorMixin):
form=QuotaForm, formset=QuotaFormSet, min_num=1, validate_min=True,
can_order=False, can_delete=True, extra=extra,
)
if self.object:
if self.object and self.object.pk:
kwargs['queryset'] = self.object.quotas.prefetch_related('items', 'variations')
return formsetclass(
@@ -400,10 +400,10 @@ class SubEventEditorMixin(MetaDataEditorMixin):
def itemvar_forms(self):
se_item_instances = {
sei.item_id: sei for sei in SubEventItem.objects.filter(subevent=self.object)
}
} if self.object and self.object.pk else {}
se_var_instances = {
sei.variation_id: sei for sei in SubEventItemVariation.objects.filter(subevent=self.object)
}
} if self.object and self.object.pk else {}
if self.copy_from:
se_item_instances = {
@@ -821,18 +821,18 @@ class SubEventBulkCreate(SubEventEditorMixin, EventPermissionRequiredMixin, Asyn
for t in self.get_times():
se = copy.copy(form.instance)
se.date_from = make_aware(datetime.combine(rdate, t['time_from']), tz, is_dst=False)
se.date_from = make_aware(datetime.combine(rdate, t['time_from'].replace(fold=1)), tz)
if t.get('time_to'):
se.date_to = (
make_aware(datetime.combine(rdate, t['time_to']), tz, is_dst=False)
make_aware(datetime.combine(rdate, t['time_to'].replace(fold=1)), tz)
if t.get('time_to') > t.get('time_from')
else make_aware(datetime.combine(rdate + timedelta(days=1), t['time_to']), tz, is_dst=False)
else make_aware(datetime.combine(rdate + timedelta(days=1), t['time_to'].replace(fold=1)), tz)
)
else:
se.date_to = None
se.date_admission = (
make_aware(datetime.combine(rdate, t['time_admission'].replace(fold=1)), tz, is_dst=False)
make_aware(datetime.combine(rdate, t['time_admission'].replace(fold=1)), tz)
if t.get('time_admission')
else None
)
@@ -1148,6 +1148,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
subevents = list(self.get_queryset().prefetch_related('checkinlist_set'))
to_save_products = []
to_save_gates = []
to_delete_list_ids = []
for f in self.list_formset.forms:
if self.list_formset._should_delete_form(f) and f in self.list_formset.extra_forms:
@@ -1159,7 +1160,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
log_entries += [
q.log_action(action='pretix.event.checkinlist.deleted', user=self.request.user, save=False),
]
q.delete()
to_delete_list_ids.append(q.pk)
elif f in self.list_formset.extra_forms:
change_data = {k: f.cleaned_data.get(k) for k in f.changed_data}
for se in subevents:
@@ -1198,6 +1199,8 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
CheckinList.limit_products.through.objects.bulk_create(to_save_products)
if to_save_gates:
CheckinList.gates.through.objects.bulk_create(to_save_gates)
if to_delete_list_ids:
CheckinList.objects.filter(id__in=to_delete_list_ids).delete()
def save_quota_formset(self, log_entries):
if not self.quota_formset.has_changed():
@@ -1224,6 +1227,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
if to_delete_quota_ids:
Quota.objects.filter(id__in=to_delete_quota_ids).delete()
to_delete_quota_ids = []
for f in self.quota_formset.forms:
if self.quota_formset._should_delete_form(f) and f in self.quota_formset.extra_forms:
@@ -1245,7 +1249,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
'id': q.pk
}, save=False)
]
q.delete()
to_delete_quota_ids.append(q.pk)
elif f in self.quota_formset.extra_forms:
change_data = {k: f.cleaned_data.get(k) for k in f.changed_data}
for se in subevents:
@@ -1288,6 +1292,8 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
Quota.items.through.objects.bulk_create(to_save_items)
if to_save_variations:
Quota.variations.through.objects.bulk_create(to_save_variations)
if to_delete_quota_ids:
Quota.objects.filter(id__in=to_delete_quota_ids).delete()
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
+2 -2
View File
@@ -33,8 +33,8 @@
# License for the specific language governing permissions and limitations under the License.
from datetime import datetime, time
from zoneinfo import ZoneInfo
import pytz
from dateutil.parser import parse
from django.core.exceptions import PermissionDenied
from django.db.models import F, Max, Min, Q
@@ -88,7 +88,7 @@ def serialize_event(e):
if e.min_from is None:
dr = pgettext('subevent', 'No dates')
else:
tz = pytz.timezone(e.settings.timezone)
tz = ZoneInfo(e.settings.timezone)
dr = _('Series:') + ' ' + daterange(
e.min_from.astimezone(tz),
(e.max_fromto or e.max_to or e.max_from).astimezone(tz)
@@ -22,8 +22,7 @@
import importlib.util
from django.apps import apps
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from pretix.multidomain.plugin_handler import plugin_event_urls
from pretix.presale.urls import event_patterns, locale_patterns
+1 -2
View File
@@ -35,8 +35,7 @@
import importlib.util
from django.apps import apps
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from django.views.generic import TemplateView
from pretix.multidomain.plugin_handler import plugin_event_urls
+22 -30
View File
@@ -42,7 +42,9 @@ from django.contrib.sessions.middleware import (
from django.core.cache import cache
from django.core.exceptions import DisallowedHost
from django.http.request import split_domain_port
from django.middleware.csrf import CsrfViewMiddleware as BaseCsrfMiddleware
from django.middleware.csrf import (
CSRF_SESSION_KEY, CsrfViewMiddleware as BaseCsrfMiddleware,
)
from django.shortcuts import render
from django.urls import set_urlconf
from django.utils.cache import patch_vary_headers
@@ -189,35 +191,25 @@ class CsrfViewMiddleware(BaseCsrfMiddleware):
a custom domain.
"""
def process_response(self, request, response):
if getattr(response, 'csrf_processing_done', False):
return response
# If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
# never called, probably because a request middleware returned a response
# (for example, contrib.auth redirecting to a login page).
if request.META.get("CSRF_COOKIE") is None:
return response
if not request.META.get("CSRF_COOKIE_USED", False):
return response
# Set the CSRF cookie even if it's already set, so we renew
# the expiry timer.
set_cookie_without_samesite(
request, response,
settings.CSRF_COOKIE_NAME,
request.META["CSRF_COOKIE"],
max_age=settings.CSRF_COOKIE_AGE,
domain=get_cookie_domain(request),
path=settings.CSRF_COOKIE_PATH,
secure=request.scheme == 'https',
httponly=settings.CSRF_COOKIE_HTTPONLY
)
# Content varies with the CSRF cookie, so set the Vary header.
patch_vary_headers(response, ('Cookie',))
response.csrf_processing_done = True
return response
def _set_csrf_cookie(self, request, response):
if settings.CSRF_USE_SESSIONS:
if request.session.get(CSRF_SESSION_KEY) != request.META["CSRF_COOKIE"]:
request.session[CSRF_SESSION_KEY] = request.META["CSRF_COOKIE"]
else:
# Set the CSRF cookie even if it's already set, so we renew
# the expiry timer.
set_cookie_without_samesite(
request, response,
settings.CSRF_COOKIE_NAME,
request.META["CSRF_COOKIE"],
max_age=settings.CSRF_COOKIE_AGE,
domain=get_cookie_domain(request),
path=settings.CSRF_COOKIE_PATH,
secure=request.scheme == 'https',
httponly=settings.CSRF_COOKIE_HTTPONLY
)
# Content varies with the CSRF cookie, so set the Vary header.
patch_vary_headers(response, ('Cookie',))
def get_cookie_domain(request):
@@ -22,8 +22,7 @@
import importlib.util
from django.apps import apps
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from pretix.multidomain.plugin_handler import plugin_event_urls
from pretix.presale.urls import (
+3
View File
@@ -45,6 +45,9 @@ from .models import KnownDomain
def get_event_domain(event, fallback=False, return_info=False):
assert isinstance(event, Event)
if not event.pk:
# Can happen on the "event deleted" response
return (None, None) if return_info else None
suffix = ('_fallback' if fallback else '') + ('_info' if return_info else '')
domain = getattr(event, '_cached_domain' + suffix, None) or event.cache.get('domain' + suffix)
if domain is None:
+1 -1
View File
@@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import re_path
from pretix.api.urls import event_router
from pretix.plugins.badges.api import BadgeItemViewSet, BadgeLayoutViewSet
+1 -1
View File
@@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import re_path
from pretix.api.urls import orga_router
from pretix.plugins.banktransfer.api import BankImportJobViewSet
+3 -3
View File
@@ -33,6 +33,7 @@
# License for the specific language governing permissions and limitations under the License.
from collections import OrderedDict
from datetime import timezone
import bleach
import dateutil.parser
@@ -47,7 +48,6 @@ from django.utils.timezone import is_aware, make_aware, now
from django.utils.translation import (
gettext as _, gettext_lazy, pgettext, pgettext_lazy,
)
from pytz import UTC
from reportlab.lib.units import mm
from reportlab.platypus import Flowable, Paragraph, Spacer, Table, TableStyle
@@ -513,7 +513,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
elif op.last_checked_in:
last_checked_in = op.last_checked_in
if last_checked_in and not is_aware(last_checked_in):
last_checked_in = make_aware(last_checked_in, UTC)
last_checked_in = make_aware(last_checked_in, timezone.utc)
last_checked_out = None
if isinstance(op.last_checked_out, str): # SQLite
@@ -521,7 +521,7 @@ class CSVCheckinList(CheckInListMixin, ListExporter):
elif op.last_checked_out:
last_checked_out = op.last_checked_out
if last_checked_out and not is_aware(last_checked_out):
last_checked_out = make_aware(last_checked_out, UTC)
last_checked_out = make_aware(last_checked_out, timezone.utc)
row = [
op.order.code,
+1 -2
View File
@@ -19,8 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from .views import abort, oauth_disconnect, redirect_view, success
+5 -2
View File
@@ -29,7 +29,7 @@ from django.http import HttpRequest, HttpResponse
from django.template.loader import get_template
from django.urls import resolve
from django.utils.crypto import get_random_string
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_lazy as _, pgettext_lazy
from pretix.base.forms import SecretKeySettingsField
from pretix.base.middleware import _merge_csp, _parse_csp, _render_csp
@@ -61,7 +61,10 @@ def pretixcontrol_logentry_display(sender, logentry, **kwargs):
'PAYMENT.SALE.REFUNDED': _('Payment refunded.'),
'PAYMENT.SALE.REVERSED': _('Payment reversed.'),
'PAYMENT.SALE.PENDING': _('Payment pending.'),
'CHECKOUT.ORDER.APPROVED': _('Order approved.'),
'CHECKOUT.ORDER.APPROVED': pgettext_lazy('paypal', 'Order approved.'),
'CHECKOUT.ORDER.COMPLETED': pgettext_lazy('paypal', 'Order completed.'),
'PAYMENT.CAPTURE.COMPLETED': pgettext_lazy('paypal', 'Capture completed.'),
'PAYMENT.CAPTURE.PENDING': pgettext_lazy('paypal', 'Capture pending.'),
}
if event_type in plains:
+1 -2
View File
@@ -19,8 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from .views import (
PayView, XHRView, abort, isu_disconnect, isu_return, redirect_view,
+2 -3
View File
@@ -37,7 +37,6 @@ import tempfile
from collections import OrderedDict, defaultdict
from decimal import Decimal
import pytz
from dateutil.parser import parse
from django import forms
from django.conf import settings
@@ -123,7 +122,7 @@ class ReportlabExportMixin:
return 'report-%s.pdf' % self.event.slug, 'application/pdf', self.create(form_data)
def get_filename(self):
tz = pytz.timezone(self.event.settings.timezone)
tz = self.event.timezone
return "%s-%s.pdf" % (self.name, now().astimezone(tz).strftime("%Y-%m-%d-%H-%M-%S"))
@staticmethod
@@ -491,7 +490,7 @@ class OrderTaxListReportPDF(Report):
headlinestyle = self.get_style()
headlinestyle.fontSize = 15
headlinestyle.fontName = 'OpenSansBd'
tz = pytz.timezone(self.event.settings.timezone)
tz = self.event.timezone
tax_rates = set(
a for a
+1 -1
View File
@@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import re_path
from .views import ReturnSettings
+10 -2
View File
@@ -21,6 +21,7 @@
#
from datetime import datetime, time, timedelta
from dateutil.tz import datetime_exists
from django.db import models
from django.db.models import Exists, OuterRef, Q
from django.utils import timezone
@@ -69,6 +70,9 @@ class ScheduledMail(models.Model):
def save(self, **kwargs):
if not self.computed_datetime:
self.recompute()
if 'update_fields' in kwargs:
kwargs['update_fields'] = {'computed_datetime', 'last_computed', 'state'}.union(kwargs['update_fields'])
super().save(**kwargs)
def recompute(self):
@@ -88,10 +92,14 @@ class ScheduledMail(models.Model):
base_time = (e.date_to or e.date_from) if self.rule.offset_to_event_end else e.date_from
d = base_time.astimezone(self.event.timezone).date() + offset
self.computed_datetime = make_aware(
datetime.combine(d, time(hour=st.hour, minute=st.minute, second=st.second, microsecond=0)),
datetime.combine(d, time(hour=st.hour, minute=st.minute, second=st.second, microsecond=0, fold=1)),
self.event.timezone,
is_dst=False, # prevent AmbiguousTimeError
)
if not datetime_exists(self.computed_datetime):
self.computed_datetime = make_aware(
datetime.combine(d, time(hour=st.hour, minute=st.minute, second=st.second, microsecond=0)) + timedelta(hours=1),
self.event.timezone,
)
if self.computed_datetime > timezone.now() and self.state == self.STATE_MISSED:
self.state = self.STATE_SCHEDULED
+1 -1
View File
@@ -32,7 +32,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from django.conf.urls import re_path
from django.urls import re_path
from pretix.api.urls import event_router
+1 -1
View File
@@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import re_path
from . import views
+1 -2
View File
@@ -19,8 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from pretix.multidomain import event_url
+1 -1
View File
@@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import re_path
from pretix.api.urls import event_router
from pretix.plugins.ticketoutputpdf.api import (
+1 -1
View File
@@ -19,7 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from django.conf.urls import re_path
from django.urls import re_path
from .views import IndexView
+2 -1
View File
@@ -19,7 +19,6 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from bootstrap3.renderers import FieldRenderer
from bootstrap3.text import text_value
from bootstrap3.utils import add_css_class
from django.forms import CheckboxInput, CheckboxSelectMultiple, RadioSelect
@@ -28,6 +27,8 @@ from django.utils.html import escape, format_html, strip_tags
from django.utils.safestring import mark_safe
from django.utils.translation import pgettext
from pretix.base.forms.renderers import FieldRenderer
def render_label(content, label_for=None, label_class=None, label_title='', label_id='', optional=False, is_valid=None, attrs=None):
"""
+4 -5
View File
@@ -22,7 +22,6 @@
import datetime
from urllib.parse import urlparse
import pytz
import vobject
from django.conf import settings
from django.utils.formats import date_format
@@ -41,11 +40,11 @@ def get_public_ical(events):
"""
cal = vobject.iCalendar()
cal.add('prodid').value = '-//pretix//{}//'.format(settings.PRETIX_INSTANCE_NAME.replace(" ", "_"))
creation_time = datetime.datetime.now(pytz.utc)
creation_time = datetime.datetime.now(datetime.timezone.utc)
for ev in events:
event = ev if isinstance(ev, Event) else ev.event
tz = pytz.timezone(event.settings.timezone)
tz = event.timezone
if isinstance(ev, Event):
url = build_absolute_uri(event, 'presale:event.index')
else:
@@ -114,9 +113,9 @@ def get_private_icals(event, positions):
- It would be pretty hard to implement it in a way that doesn't require us to use distinct
settings fields for emails to customers and to attendees, which feels like an overcomplication.
"""
tz = pytz.timezone(event.settings.timezone)
tz = event.timezone
creation_time = datetime.datetime.now(pytz.utc)
creation_time = datetime.datetime.now(datetime.timezone.utc)
calobjects = []
evs = set(p.subevent or event for p in positions)
+1 -2
View File
@@ -32,8 +32,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from django.views.decorators.csrf import csrf_exempt
import pretix.presale.views.cart
+3 -3
View File
@@ -29,7 +29,6 @@ from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
from Crypto.PublicKey import RSA
from django.db import transaction
from django.http import Http404, HttpResponse, JsonResponse
from django.middleware.csrf import _compare_masked_tokens
from django.shortcuts import redirect, render
from django.utils.crypto import get_random_string
from django.utils.decorators import method_decorator
@@ -103,8 +102,9 @@ class AuthorizeView(View):
return self._process_auth_request(request, request.GET)
def post(self, request, *args, **kwargs):
request_token = CsrfViewMiddleware(lambda: None)._get_token(request)
if not request_token or not _compare_masked_tokens(request.POST.get('csrfmiddlewaretoken', ''), request_token):
try:
CsrfViewMiddleware(lambda: None)._check_token(request)
except:
# External request, we prefer GET and will redirect to prevent confusion with our login form
return redirect(request.path + '?' + request.POST.urlencode())
return self._process_auth_request(request, request.GET)
+17 -17
View File
@@ -38,10 +38,10 @@ from collections import defaultdict
from datetime import date, datetime, time, timedelta
from functools import reduce
from urllib.parse import quote, urlencode
from zoneinfo import ZoneInfo
import dateutil
import isoweek
import pytz
from django.conf import settings
from django.core.cache import caches
from django.db.models import Exists, Max, Min, OuterRef, Prefetch, Q
@@ -392,7 +392,7 @@ class OrganizerIndex(OrganizerViewMixin, EventListMixin, ListView):
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
for event in ctx['events']:
event.tzname = pytz.timezone(event.cache.get_or_set('timezone', lambda: event.settings.timezone))
event.tzname = ZoneInfo(event.cache.get_or_set('timezone', lambda: event.settings.timezone))
if event.has_subevents:
event.daterange = daterange(
event.min_from.astimezone(event.tzname),
@@ -506,7 +506,7 @@ def add_subevents_for_days(qs, before, after, ebd, timezones, event=None, cart_n
continue
timezones.add(s.timezone)
tz = pytz.timezone(s.timezone)
tz = ZoneInfo(s.timezone)
datetime_from = se.date_from.astimezone(tz)
date_from = datetime_from.date()
if s.show_date_to and se.date_to:
@@ -623,8 +623,8 @@ class CalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
raise Http404()
tz = get_current_timezone()
before = tz.localize(datetime(self.year, self.month, 1, 0, 0, 0)) - timedelta(days=1)
after = tz.localize(datetime(self.year, self.month, ndays, 0, 0, 0)) + timedelta(days=1)
before = datetime(self.year, self.month, 1, 0, 0, 0, tzinfo=tz) - timedelta(days=1)
after = datetime(self.year, self.month, ndays, 0, 0, 0, tzinfo=tz) + timedelta(days=1)
ctx['date'] = date(self.year, self.month, 1)
ctx['before'] = before
@@ -700,12 +700,12 @@ class WeekCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
tz = get_current_timezone()
week = isoweek.Week(self.year, self.week)
before = tz.localize(datetime(
week.monday().year, week.monday().month, week.monday().day, 0, 0, 0,
)) - timedelta(days=1)
after = tz.localize(datetime(
week.sunday().year, week.sunday().month, week.sunday().day, 0, 0, 0,
)) + timedelta(days=1)
before = datetime(
week.monday().year, week.monday().month, week.monday().day, 0, 0, 0, tzinfo=tz,
) - timedelta(days=1)
after = datetime(
week.sunday().year, week.sunday().month, week.sunday().day, 0, 0, 0, tzinfo=tz,
) + timedelta(days=1)
ctx['date'] = week.monday()
ctx['before'] = before
@@ -827,12 +827,12 @@ class DayCalendarView(OrganizerViewMixin, EventListMixin, TemplateView):
ctx = super().get_context_data()
tz = get_current_timezone()
before = tz.localize(datetime(
self.date.year, self.date.month, self.date.day, 0, 0, 0,
)) - timedelta(days=1)
after = tz.localize(datetime(
self.date.year, self.date.month, self.date.day, 0, 0, 0,
)) + timedelta(days=1)
before = datetime(
self.date.year, self.date.month, self.date.day, 0, 0, 0, tzinfo=tz,
) - timedelta(days=1)
after = datetime(
self.date.year, self.date.month, self.date.day, 0, 0, 0, tzinfo=tz,
) + timedelta(days=1)
ctx['date'] = self.date
ctx['cal_tz'] = self.tz
+3 -3
View File
@@ -26,9 +26,9 @@ import logging
from collections import defaultdict
from datetime import date, datetime, timedelta
from urllib.parse import urljoin
from zoneinfo import ZoneInfo
import isoweek
import pytz
from compressor.filters.jsmin import rJSMinFilter
from django.conf import settings
from django.contrib.staticfiles import finders
@@ -438,7 +438,7 @@ class WidgetAPIProductList(EventListMixin, View):
event = ev.event
else:
event = ev
tz = pytz.timezone(e['timezone'])
tz = ZoneInfo(e['timezone'])
time = date_format(ev.date_from.astimezone(tz), 'TIME_FORMAT') if e.get('time') and event.settings.show_times else None
if time and ev.date_to and ev.date_from.astimezone(tz).date() == ev.date_to.astimezone(tz).date() and event.settings.show_date_to:
time += ' ' + date_format(ev.date_to.astimezone(tz), 'TIME_FORMAT')
@@ -626,7 +626,7 @@ class WidgetAPIProductList(EventListMixin, View):
data['events'] = []
qs = self._get_event_queryset()
for event in qs:
tz = pytz.timezone(event.cache.get_or_set('timezone', lambda: event.settings.timezone))
tz = ZoneInfo(event.cache.get_or_set('timezone', lambda: event.settings.timezone))
if event.has_subevents:
dr = daterange(
event.min_from.astimezone(tz),
+3 -3
View File
@@ -174,7 +174,7 @@ SITE_URL = config.get('pretix', 'url', fallback='http://localhost:8000')
if SITE_URL.endswith('/'):
SITE_URL = SITE_URL[:-1]
CSRF_TRUSTED_ORIGINS = [urlparse(SITE_URL).hostname]
CSRF_TRUSTED_ORIGINS = [urlparse(SITE_URL).scheme + '://' + urlparse(SITE_URL).hostname]
TRUST_X_FORWARDED_FOR = config.get('pretix', 'trust_x_forwarded_for', fallback=False)
USE_X_FORWARDED_HOST = config.get('pretix', 'trust_x_forwarded_host', fallback=False)
@@ -638,8 +638,8 @@ CELERY_TASK_ROUTES = ([
BOOTSTRAP3 = {
'success_css_class': '',
'field_renderers': {
'default': 'bootstrap3.renderers.FieldRenderer',
'inline': 'bootstrap3.renderers.InlineFieldRenderer',
'default': 'pretix.base.forms.renderers.FieldRenderer',
'inline': 'pretix.base.forms.renderers.InlineFieldRenderer',
'control': 'pretix.control.forms.renderers.ControlFieldRenderer',
'bulkedit': 'pretix.control.forms.renderers.BulkEditFieldRenderer',
'bulkedit_inline': 'pretix.control.forms.renderers.InlineBulkEditFieldRenderer',
@@ -227,4 +227,3 @@
.colorpicker-inline.colorpicker-visible {
display: inline-block;
}
/*# sourceMappingURL=bootstrap-colorpicker.css.map */
+1 -2
View File
@@ -15613,5 +15613,4 @@ const pdfjsBuild = 'd0823066c';
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=pdf.js.map
});
+1 -2
View File
@@ -64052,5 +64052,4 @@ const pdfjsBuild = 'd0823066c';
/******/ return __webpack_exports__;
/******/ })()
;
});
//# sourceMappingURL=pdf.worker.js.map
});
@@ -177,7 +177,7 @@ input[type=number]::-webkit-outer-spin-button {
}
.pagination > li.page-current > a:hover, .pagination > li.page-current > a:focus {
color: #7f5a91;
color: $brand-primary;
background-color: #fff;
border: 1px solid #ddd;
}
+1 -2
View File
@@ -3799,5 +3799,4 @@ var isFullyConvertible = totext.isFullyConvertible;
/***/ })
/******/ ]);
});
//# sourceMappingURL=rrule.js.map
});
+1 -2
View File
@@ -33,8 +33,7 @@
# License for the specific language governing permissions and limitations under the License.
from django.conf import settings
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from django.views.generic import RedirectView
import pretix.control.urls
+2 -1
View File
@@ -28,11 +28,12 @@ filterwarnings =
ignore::DeprecationWarning:kombu
ignore::DeprecationWarning:django
ignore::DeprecationWarning:cgi
ignore::DeprecationWarning:vat_moss
ignore::pytz_deprecation_shim._exceptions.PytzUsageWarning:vobject
ignore:the load_module.* method is deprecated:DeprecationWarning
ignore::ImportWarning
ignore::ResourceWarning
ignore:django.contrib.staticfiles.templatetags.static:DeprecationWarning
ignore::django.utils.deprecation.RemovedInDjango41Warning:
ignore::DeprecationWarning:compressor
ignore:pkg_resources is deprecated as an API:
+6 -7
View File
@@ -32,13 +32,12 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from datetime import datetime
from datetime import datetime, timezone
import pytest
from django.test import utils
from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC
from rest_framework.test import APIClient
from pretix.base.models import Device, Event, Organizer, Team, User
@@ -67,7 +66,7 @@ def meta_prop(organizer):
def event(organizer, meta_prop):
e = Event.objects.create(
organizer=organizer, name='Dummy', slug='dummy',
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC),
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc),
plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf',
is_public=True
)
@@ -82,7 +81,7 @@ def event(organizer, meta_prop):
def event2(organizer, meta_prop):
e = Event.objects.create(
organizer=organizer, name='Dummy2', slug='dummy2',
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC),
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc),
plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf'
)
e.meta_values.create(property=meta_prop, value="Conference")
@@ -94,7 +93,7 @@ def event2(organizer, meta_prop):
def event3(organizer, meta_prop):
e = Event.objects.create(
organizer=organizer, name='Dummy3', slug='dummy3',
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC),
date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc),
plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf'
)
e.meta_values.create(property=meta_prop, value="Conference")
@@ -173,7 +172,7 @@ def device_client(client, device):
def subevent(event, meta_prop):
event.has_subevents = True
event.save()
se = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc))
se.meta_values.create(property=meta_prop, value="Workshop")
return se
@@ -184,7 +183,7 @@ def subevent(event, meta_prop):
def subevent2(event2, meta_prop):
event2.has_subevents = True
event2.save()
se = event2.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se = event2.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc))
se.meta_values.create(property=meta_prop, value="Workshop")
return se
+14 -15
View File
@@ -28,7 +28,6 @@ import pytest
from django.core.files.base import ContentFile
from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.base.models import Question, SeatingPlan
@@ -95,15 +94,15 @@ TEST_CARTPOSITION_RES = {
@pytest.mark.django_db
def test_cp_list(token_client, organizer, event, item, taxrule, question):
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
cr = CartPosition.objects.create(
event=event, cart_id="aaa", item=item,
price=23, attendee_name_parts={'full_name': 'Peter'},
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
)
res = dict(TEST_CARTPOSITION_RES)
res["id"] = cr.pk
@@ -116,15 +115,15 @@ def test_cp_list(token_client, organizer, event, item, taxrule, question):
@pytest.mark.django_db
def test_cp_list_api(token_client, organizer, event, item, taxrule, question):
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
cr = CartPosition.objects.create(
event=event, cart_id="aaa@api", item=item,
price=23, attendee_name_parts={'full_name': 'Peter'},
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
)
res = dict(TEST_CARTPOSITION_RES)
res["id"] = cr.pk
@@ -137,15 +136,15 @@ def test_cp_list_api(token_client, organizer, event, item, taxrule, question):
@pytest.mark.django_db
def test_cp_detail(token_client, organizer, event, item, taxrule, question):
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
cr = CartPosition.objects.create(
event=event, cart_id="aaa@api", item=item,
price=23, attendee_name_parts={'full_name': 'Peter'},
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
)
res = dict(TEST_CARTPOSITION_RES)
res["id"] = cr.pk
@@ -158,21 +157,21 @@ def test_cp_detail(token_client, organizer, event, item, taxrule, question):
@pytest.mark.django_db
def test_cp_delete(token_client, organizer, event, item, taxrule, question):
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
cr = CartPosition.objects.create(
event=event, cart_id="aaa@api", item=item,
price=23, attendee_name_parts={'full_name': 'Peter'},
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
)
CartPosition.objects.create(
event=event, cart_id="aaa@api", item=item, addon_to=cr,
price=23, attendee_name_parts={'full_name': 'Peter'},
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=UTC)
datetime=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2018, 6, 11, 10, 0, 0, 0, tzinfo=datetime.timezone.utc)
)
res = dict(TEST_CARTPOSITION_RES)
res["id"] = cr.pk
+5 -6
View File
@@ -31,7 +31,6 @@ from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.api.serializers.item import QuestionSerializer
@@ -57,15 +56,15 @@ def other_item(event):
@pytest.fixture
def order(event, item, other_item, taxrule):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PAID, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=46, locale='en'
)
InvoiceAddress.objects.create(order=o, company="Sample company", country=Country('NZ'))
@@ -258,7 +257,7 @@ def test_list_list(token_client, organizer, event, clist, item, subevent, django
'/api/v1/organizers/{}/events/{}/checkinlists/?subevent_match={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
resp = token_client.get(
'/api/v1/organizers/{}/events/{}/checkinlists/?subevent={}'.format(organizer.slug, event.slug, se2.pk))
assert [] == resp.data['results']
@@ -577,7 +576,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
@pytest.mark.django_db
def test_list_all_items_positions_by_subevent(token_client, organizer, event, clist, clist_all, item, other_item, order, subevent):
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
pfirst = order.positions.get(positionid=1)
pfirst.subevent = se2
pfirst.save()
+6 -7
View File
@@ -29,7 +29,6 @@ from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.api.serializers.item import QuestionSerializer
@@ -59,15 +58,15 @@ def other_item(event):
@pytest.fixture
def order(event, item, other_item, taxrule):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PAID, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=46, locale='en'
)
InvoiceAddress.objects.create(order=o, company="Sample company", country=Country('NZ'))
@@ -106,15 +105,15 @@ def order(event, item, other_item, taxrule):
@pytest.fixture
def order2(event2, item_on_event2):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
o = Order.objects.create(
code='BAR', event=event2, email='dummy@dummy.test',
status=Order.STATUS_PAID, secret="ylptCPNOxTyA",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=46, locale='en'
)
InvoiceAddress.objects.create(order=o, company="Sample company", country=Country('NZ'))
+24 -24
View File
@@ -20,13 +20,13 @@
# <https://www.gnu.org/licenses/>.
#
from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
import pytz
from django_scopes import scopes_disabled
from freezegun import freeze_time
tz = pytz.timezone("Asia/Tokyo")
tz = ZoneInfo("Asia/Tokyo")
@pytest.mark.django_db
@@ -40,22 +40,22 @@ def test_choose_between_events(device_client, device):
with scopes_disabled():
e1 = device.organizer.events.create(
name="Event", slug="e1", live=True,
date_from=tz.localize(datetime(2020, 1, 10, 14, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 15, 0)),
date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 15, 0, tzinfo=tz),
)
cl1 = e1.checkin_lists.create(name="Same name")
e2 = device.organizer.events.create(
name="Event", slug="e2", live=True,
date_from=tz.localize(datetime(2020, 1, 10, 16, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 17, 0)),
date_from=datetime(2020, 1, 10, 16, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 17, 0, tzinfo=tz),
)
e2.checkin_lists.create(name="Other name")
cl2 = e2.checkin_lists.create(name="Same name")
e2.checkin_lists.create(name="Yet another name")
tomorrow = device.organizer.events.create(
name="Event", slug="tomorrow", live=True,
date_from=tz.localize(datetime(2020, 1, 11, 15, 0)),
date_to=tz.localize(datetime(2020, 1, 11, 16, 0)),
date_from=datetime(2020, 1, 11, 15, 0, tzinfo=tz),
date_to=datetime(2020, 1, 11, 16, 0, tzinfo=tz),
)
cl3 = tomorrow.checkin_lists.create(name="Just any name")
for e in device.organizer.events.all():
@@ -117,7 +117,7 @@ def test_choose_between_events(device_client, device):
assert resp.data['event']['slug'] == 'e2'
# check for overlapping events
e2.date_admission = tz.localize(datetime(2020, 1, 10, 14, 45))
e2.date_admission = datetime(2020, 1, 10, 14, 45, tzinfo=tz)
e2.save()
with freeze_time("2020-01-10T14:45:00+09:00"):
resp = device_client.get('/api/v1/device/eventselection?current_event=e1')
@@ -131,28 +131,28 @@ def test_choose_between_subevents(device_client, device):
with scopes_disabled():
e = device.organizer.events.create(
name="Event", slug="e1", live=True,
date_from=tz.localize(datetime(2020, 1, 10, 14, 0)),
date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz),
has_subevents=True,
)
e.settings.timezone = "Asia/Tokyo"
se1 = e.subevents.create(
name="Event", active=True,
date_from=tz.localize(datetime(2020, 1, 10, 14, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 15, 0)),
date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 15, 0, tzinfo=tz),
)
cl1 = e.checkin_lists.create(name="Same name", subevent=se1)
se2 = e.subevents.create(
name="Event", active=True,
date_from=tz.localize(datetime(2020, 1, 10, 16, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 17, 0)),
date_from=datetime(2020, 1, 10, 16, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 17, 0, tzinfo=tz),
)
cl2 = e.checkin_lists.create(name="Same name", subevent=se2)
cl3 = e.checkin_lists.create(name="Other name")
e.checkin_lists.create(name="Yet another name", subevent=se2)
se_tomorrow = e.subevents.create(
name="Event", active=True,
date_from=tz.localize(datetime(2020, 1, 11, 15, 0)),
date_to=tz.localize(datetime(2020, 1, 11, 16, 0)),
date_from=datetime(2020, 1, 11, 15, 0, tzinfo=tz),
date_to=datetime(2020, 1, 11, 16, 0, tzinfo=tz),
)
with freeze_time("2020-01-10T14:30:00+09:00"):
resp = device_client.get(f'/api/v1/device/eventselection?current_event=e1&current_subevent={se1.pk}')
@@ -217,7 +217,7 @@ def test_choose_between_subevents(device_client, device):
assert resp.data['subevent'] == se2.pk
# check for overlapping events
se2.date_admission = tz.localize(datetime(2020, 1, 10, 14, 45))
se2.date_admission = datetime(2020, 1, 10, 14, 45, tzinfo=tz)
se2.save()
with freeze_time("2020-01-10T14:45:00+09:00"):
resp = device_client.get(f'/api/v1/device/eventselection?current_event=e1&current_subevent={se1.pk}')
@@ -234,25 +234,25 @@ def test_require_gate(device_client, device):
device.save()
e = device.organizer.events.create(
name="Event", slug="e1", live=True,
date_from=tz.localize(datetime(2020, 1, 10, 14, 0)),
date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz),
has_subevents=True,
)
e.settings.timezone = "Asia/Tokyo"
se0 = e.subevents.create(
name="Event", active=True,
date_from=tz.localize(datetime(2020, 1, 10, 9, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 10, 0)),
date_from=datetime(2020, 1, 10, 9, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 10, 0, tzinfo=tz),
)
e.subevents.create(
name="Event", active=True,
date_from=tz.localize(datetime(2020, 1, 10, 14, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 15, 0)),
date_from=datetime(2020, 1, 10, 14, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 15, 0, tzinfo=tz),
)
cl1 = e.checkin_lists.create(name="Same name", subevent=se0)
se2 = e.subevents.create(
name="Event", active=True,
date_from=tz.localize(datetime(2020, 1, 10, 16, 0)),
date_to=tz.localize(datetime(2020, 1, 10, 17, 0)),
date_from=datetime(2020, 1, 10, 16, 0, tzinfo=tz),
date_to=datetime(2020, 1, 10, 17, 0, tzinfo=tz),
)
e.checkin_lists.create(name="Same name", subevent=se2)
cl3 = e.checkin_lists.create(name="Other name", subevent=se2)
+4 -5
View File
@@ -33,7 +33,7 @@
# License for the specific language governing permissions and limitations under the License.
import copy
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from decimal import Decimal
from unittest import mock
@@ -43,7 +43,6 @@ from django.core.files.base import ContentFile
from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.base.models import (
@@ -63,15 +62,15 @@ def variations(item):
@pytest.fixture
def order(event, item, taxrule):
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc),
total=23, locale='en'
)
o.fees.create(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.25'), tax_rate=Decimal('19.00'),
+2 -3
View File
@@ -24,7 +24,6 @@ import json
import pytest
from django.utils.timezone import now
from pytz import UTC
from pretix.api.models import ApiCall
from pretix.base.models import Order
@@ -159,8 +158,8 @@ def order(event):
return Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=23, locale='en'
)
+4 -5
View File
@@ -27,7 +27,6 @@ import freezegun
import pytest
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from pretix.base.models import InvoiceAddress, Order, OrderPosition
from pretix.base.models.orders import OrderFee
@@ -75,7 +74,7 @@ def quota(event, item):
@pytest.fixture
def order(event, item, taxrule, question):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
event.plugins += ",pretix.plugins.stripe"
event.save()
@@ -84,8 +83,8 @@ def order(event, item, taxrule, question):
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=23, locale='en'
)
p1 = o.payments.create(
@@ -140,7 +139,7 @@ def order(event, item, taxrule, question):
@pytest.fixture
def invoice(order):
testtime = datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
+6 -7
View File
@@ -33,7 +33,7 @@
# License for the specific language governing permissions and limitations under the License.
import os
import time
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from decimal import Decimal
from unittest import mock
@@ -42,7 +42,6 @@ from django.conf import settings
from django.core.files.base import ContentFile
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.base.channels import get_all_sales_channels
@@ -73,15 +72,15 @@ def category3(event, item):
@pytest.fixture
def order(event, item, taxrule):
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc),
total=23, locale='en'
)
o.fees.create(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.25'), tax_rate=Decimal('19.00'),
@@ -108,7 +107,7 @@ def order_position(item, order, taxrule, variations):
@pytest.fixture
def cart_position(event, item, variations):
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
@@ -1786,7 +1785,7 @@ def test_quota_list(token_client, organizer, event, quota, item, subevent):
'/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=timezone.utc))
resp = token_client.get(
'/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, se2.pk))
assert [] == resp.data['results']
+3 -4
View File
@@ -19,10 +19,9 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from datetime import datetime
from datetime import datetime, timezone
import pytest
import pytz
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString
@@ -54,8 +53,8 @@ def customer(organizer):
def membership(organizer, customer, membershiptype):
return customer.memberships.create(
membership_type=membershiptype,
date_start=datetime(2021, 4, 1, 0, 0, 0, 0, tzinfo=pytz.UTC),
date_end=datetime(2021, 4, 8, 23, 59, 59, 999999, tzinfo=pytz.UTC),
date_start=datetime(2021, 4, 1, 0, 0, 0, 0, tzinfo=timezone.utc),
date_end=datetime(2021, 4, 8, 23, 59, 59, 999999, tzinfo=timezone.utc),
attendee_name_parts={
"_scheme": "given_family",
'given_name': 'John',
+8 -9
View File
@@ -30,7 +30,6 @@ from django.core.files.base import ContentFile
from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.base.models import (
@@ -90,7 +89,7 @@ def seat(event, organizer, item):
@pytest.fixture
def order(event, item, taxrule, question):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
event.plugins += ",pretix.plugins.stripe"
event.save()
@@ -99,8 +98,8 @@ def order(event, item, taxrule, question):
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=23, locale='en'
)
p1 = o.payments.create(
@@ -720,7 +719,7 @@ def test_orderposition_price_calculation_subevent(token_client, organizer, event
def test_orderposition_price_calculation_subevent_with_override(token_client, organizer, event, order, subevent):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23)
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
se2.subeventitem_set.create(item=item2, price=12)
op = order.positions.first()
op.subevent = subevent
@@ -1262,7 +1261,7 @@ def test_position_update_change_item_variation_mismatch(token_client, organizer,
@pytest.mark.django_db
def test_position_update_change_subevent(token_client, organizer, event, order, quota, item, subevent):
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
q2 = se2.quotas.create(name="foo", size=1, event=event)
q2.items.add(item)
op = order.positions.first()
@@ -1284,7 +1283,7 @@ def test_position_update_change_subevent(token_client, organizer, event, order,
@pytest.mark.django_db
def test_position_update_change_subevent_quota_empty(token_client, organizer, event, order, quota, item, subevent):
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
q2 = se2.quotas.create(name="foo", size=0, event=event)
q2.items.add(item)
op = order.positions.first()
@@ -1365,7 +1364,7 @@ def test_position_update_change_subevent_keep_seat(token_client, organizer, even
with scopes_disabled():
seat.subevent = subevent
seat.save()
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
seat2 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se2)
q2 = se2.quotas.create(name="foo", size=1, event=event)
q2.items.add(item)
@@ -1392,7 +1391,7 @@ def test_position_update_change_subevent_missing_seat(token_client, organizer, e
with scopes_disabled():
seat.subevent = subevent
seat.save()
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
q2 = se2.quotas.create(name="foo", size=1, event=event)
q2.items.add(item)
op = order.positions.first()
+3 -4
View File
@@ -31,7 +31,6 @@ from django.core.files.base import ContentFile
from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from tests.const import SAMPLE_PNG
from pretix.base.models import (
@@ -101,7 +100,7 @@ def quota(event, item):
@pytest.fixture
def order(event, item, taxrule, question):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
event.plugins += ",pretix.plugins.stripe"
event.save()
@@ -110,8 +109,8 @@ def order(event, item, taxrule, question):
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=23, locale='en'
)
p1 = o.payments.create(
+5 -6
View File
@@ -30,7 +30,6 @@ from django.core import mail as djmail
from django.utils.timezone import now
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from stripe.error import APIConnectionError
from tests.plugins.stripe.test_provider import MockedCharge
@@ -77,7 +76,7 @@ def quota(event, item):
@pytest.fixture
def order(event, item, taxrule, question):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
event.plugins += ",pretix.plugins.stripe"
event.save()
@@ -86,8 +85,8 @@ def order(event, item, taxrule, question):
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc),
expires=datetime.datetime(2017, 12, 10, 10, 0, 0, tzinfo=datetime.timezone.utc),
total=23, locale='en'
)
p1 = o.payments.create(
@@ -947,8 +946,8 @@ def test_orderposition_list(token_client, organizer, event, order, item, subeven
with scopes_disabled():
cl = event.checkin_lists.create(name="Default")
c = op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=UTC), list=cl)
op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=UTC), list=cl, successful=False)
c = op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=datetime.timezone.utc), list=cl)
op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=datetime.timezone.utc), list=cl, successful=False)
res['checkins'] = [{ # successful only
'id': c.pk,
'datetime': '2017-12-26T10:00:00Z',
+2 -3
View File
@@ -22,7 +22,6 @@
import datetime
import pytest
from django.utils.timezone import utc
from django_scopes import scopes_disabled
from pretix.plugins.sendmail.models import Rule
@@ -31,7 +30,7 @@ from pretix.plugins.sendmail.models import Rule
@pytest.fixture
def rule(event):
return event.sendmail_rules.create(subject='test', template='foo',
send_date=datetime.datetime(2021, 7, 8, tzinfo=utc))
send_date=datetime.datetime(2021, 7, 8, tzinfo=datetime.timezone.utc))
TEST_RULE_RES = {
@@ -131,7 +130,7 @@ def test_sendmail_rule_create_minimal(token_client, organizer, event):
'send_date': '2018-03-17T13:31Z',
}
)
assert r.send_date == datetime.datetime(2018, 3, 17, 13, 31, tzinfo=utc)
assert r.send_date == datetime.datetime(2018, 3, 17, 13, 31, tzinfo=datetime.timezone.utc)
@scopes_disabled()
+3 -4
View File
@@ -34,13 +34,12 @@
import copy
import uuid
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from decimal import Decimal
import pytest
from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC
from pretix.base.models import Order, OrderPosition
@@ -56,8 +55,8 @@ def order(event, item):
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc),
total=23, locale='en'
)
OrderPosition.objects.create(
+6 -7
View File
@@ -19,14 +19,13 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from datetime import datetime
from datetime import datetime, timezone
from decimal import Decimal
from unittest import mock
import pytest
from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC
from pretix.base.models import (
InvoiceAddress, Order, OrderPosition, SeatingPlan, SubEvent,
@@ -52,15 +51,15 @@ def variations2(item2):
@pytest.fixture
def order(event, item, taxrule):
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING, secret="k24fiuwvu8kxz3y1",
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=UTC),
datetime=datetime(2017, 12, 1, 10, 0, 0, tzinfo=timezone.utc),
expires=datetime(2017, 12, 10, 10, 0, 0, tzinfo=timezone.utc),
total=23, locale='en'
)
o.fees.create(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.25'), tax_rate=Decimal('19.00'),
@@ -344,8 +343,8 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
assert resp.status_code == 200
with scopes_disabled():
subevent = event.subevents.get(id=subevent.id)
assert subevent.date_from == datetime(2018, 12, 27, 10, 0, tzinfo=UTC)
assert subevent.date_to == datetime(2018, 12, 28, 10, 0, tzinfo=UTC)
assert subevent.date_from == datetime(2018, 12, 27, 10, 0, tzinfo=timezone.utc)
assert subevent.date_to == datetime(2018, 12, 28, 10, 0, tzinfo=timezone.utc)
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/subevents/{}/'.format(organizer.slug, event.slug, subevent.pk),
+9 -11
View File
@@ -37,10 +37,8 @@ import datetime
from decimal import Decimal
import pytest
from django.utils import timezone
from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC
from pretix.base.models import Event, SeatingPlan, Voucher
@@ -234,7 +232,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube
assert [res] == resp.data['results']
voucher.redeemed = 0
voucher.valid_until = (timezone.now() - datetime.timedelta(days=1)).replace(microsecond=0)
voucher.valid_until = (now() - datetime.timedelta(days=1)).replace(microsecond=0)
voucher.save()
res['valid_until'] = voucher.valid_until.isoformat().replace('+00:00', 'Z')
res['redeemed'] = 0
@@ -251,7 +249,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube
'/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
resp = token_client.get(
'/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug,
se2.pk))
@@ -613,7 +611,7 @@ def test_change_to_item_of_other_event(token_client, organizer, event, item):
organizer=organizer,
name='Dummy2',
slug='dummy2',
date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC),
date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc),
plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf'
)
ticket2 = e2.items.create(name='Late-bird ticket', default_price=23)
@@ -1256,8 +1254,8 @@ def test_set_seat_subevent(token_client, organizer, event, seatingplan, seat1, i
with scopes_disabled():
event.has_subevents = True
event.save()
se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
seat1 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se1)
event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se2)
v = event.vouchers.create(item=item)
@@ -1279,8 +1277,8 @@ def test_set_seat_subevent_required(token_client, organizer, event, seatingplan,
with scopes_disabled():
event.has_subevents = True
event.save()
se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
seat1 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se1)
event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se2)
event.vouchers.create(item=item, seat=seat1)
@@ -1299,8 +1297,8 @@ def test_set_seat_subevent_invalid(token_client, organizer, event, seatingplan,
with scopes_disabled():
event.has_subevents = True
event.save()
se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se1 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
se2 = event.subevents.create(name="Baz", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
seat1 = event.seats.create(seat_number="A1", product=item, seat_guid="A1", subevent=se1)
event.seats.create(seat_number="B1", product=item, seat_guid="B1", subevent=se2)
event.vouchers.create(item=item, seat=seat1, subevent=se2)
+2 -3
View File
@@ -25,7 +25,6 @@ from unittest import mock
import pytest
from django_scopes import scopes_disabled
from pytz import UTC
from pretix.base.models import WaitingListEntry
@@ -44,7 +43,7 @@ def quota(event, item):
@pytest.fixture
def wle(event, item):
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=UTC)
testtime = datetime.datetime(2017, 12, 1, 10, 0, 0, tzinfo=datetime.timezone.utc)
with mock.patch('django.utils.timezone.now') as mock_now:
mock_now.return_value = testtime
@@ -140,7 +139,7 @@ def test_wle_list(token_client, organizer, event, wle, item, subevent):
'/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=datetime.timezone.utc))
resp = token_client.get(
'/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug,
se2.pk))

Some files were not shown because too many files have changed in this diff Show More