forked from CGM_Public/pretix_original
Compare commits
22 Commits
unify-unca
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
052aaf937b | ||
|
|
bc6da2512a | ||
|
|
6378dc69b8 | ||
|
|
2b53d04a19 | ||
|
|
7efe7b5ff7 | ||
|
|
ae5464d486 | ||
|
|
67fec8d1f6 | ||
|
|
95a081676b | ||
|
|
7228a6304d | ||
|
|
04b9134e36 | ||
|
|
2e0769bc41 | ||
|
|
4d2f854710 | ||
|
|
b9ac9496d2 | ||
|
|
a975f5dc50 | ||
|
|
4ea1f6284a | ||
|
|
a01d105829 | ||
|
|
b1bfa1acee | ||
|
|
0b4e99c2d8 | ||
|
|
0cdce7a9cd | ||
|
|
464f625301 | ||
|
|
0c1072503c | ||
|
|
9ead82839a |
@@ -203,7 +203,8 @@ checkins list of objects List of **succe
|
||||
├ datetime datetime Time of check-in
|
||||
├ type string Type of scan (defaults to ``entry``)
|
||||
├ gate integer Internal ID of the gate. Can be ``null``.
|
||||
├ device integer Internal ID of the device. Can be ``null``.
|
||||
├ device integer Internal ID of the device. Can be ``null``. **Deprecated**, since this ID is not otherwise used in the API and is therefore not very useful.
|
||||
├ device_id integer Attribute ``device_id`` of the device. Can be ``null``.
|
||||
└ auto_checked_in boolean Indicates if this check-in been performed automatically by the system
|
||||
downloads list of objects List of ticket download options
|
||||
├ output string Ticket output provider (e.g. ``pdf``, ``passbook``)
|
||||
|
||||
@@ -175,7 +175,7 @@ without any special behavior.
|
||||
Connecting SSO providers (pretix as the SSO client)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To connect an external application as a SSO client, go to "Customer accounts" → "SSO providers" → "Create a new SSO provider"
|
||||
To connect an external application as a SSO provider, go to "Customer accounts" → "SSO providers" → "Create a new SSO provider"
|
||||
in your organizer account.
|
||||
|
||||
.. thumbnail:: ../../screens/organizer/customer_ssoprovider_add.png
|
||||
|
||||
@@ -48,7 +48,7 @@ dependencies = [
|
||||
"django-libsass==0.9",
|
||||
"django-localflavor==4.0",
|
||||
"django-markup",
|
||||
"django-oauth-toolkit==2.3.*",
|
||||
"django-oauth-toolkit==3.0.*",
|
||||
"django-otp==1.5.*",
|
||||
"django-phonenumber-field==7.3.*",
|
||||
"django-redis==5.4.*",
|
||||
@@ -76,7 +76,7 @@ dependencies = [
|
||||
"phonenumberslite==8.13.*",
|
||||
"Pillow==10.4.*",
|
||||
"pretix-plugin-build",
|
||||
"protobuf==5.27.*",
|
||||
"protobuf==5.28.*",
|
||||
"psycopg2-binary",
|
||||
"pycountry",
|
||||
"pycparser==2.22",
|
||||
|
||||
@@ -80,6 +80,7 @@ ALL_LANGUAGES = [
|
||||
('de', _('German')),
|
||||
('de-informal', _('German (informal)')),
|
||||
('ar', _('Arabic')),
|
||||
('eu', _('Basque')),
|
||||
('ca', _('Catalan')),
|
||||
('zh-hans', _('Chinese (simplified)')),
|
||||
('zh-hant', _('Chinese (traditional)')),
|
||||
|
||||
@@ -896,6 +896,7 @@ class DeviceEventSettingsSerializer(EventSettingsSerializer):
|
||||
'locale',
|
||||
'last_order_modification_date',
|
||||
'show_quota_left',
|
||||
'show_dates_on_frontpage',
|
||||
'max_items_per_order',
|
||||
'attendee_names_asked',
|
||||
'attendee_names_required',
|
||||
|
||||
@@ -273,9 +273,15 @@ class AnswerSerializer(I18nAwareModelSerializer):
|
||||
|
||||
|
||||
class CheckinSerializer(I18nAwareModelSerializer):
|
||||
device_id = serializers.SlugRelatedField(
|
||||
source='device',
|
||||
slug_field='device_id',
|
||||
read_only=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Checkin
|
||||
fields = ('id', 'datetime', 'list', 'auto_checked_in', 'gate', 'device', 'type')
|
||||
fields = ('id', 'datetime', 'list', 'auto_checked_in', 'gate', 'device', 'device_id', 'type')
|
||||
|
||||
|
||||
class FailedCheckinSerializer(I18nAwareModelSerializer):
|
||||
|
||||
@@ -377,7 +377,7 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
||||
Prefetch(
|
||||
'positions',
|
||||
OrderPosition.objects.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
'item', 'variation', 'answers', 'answers__options', 'answers__question',
|
||||
)
|
||||
)
|
||||
|
||||
@@ -78,7 +78,7 @@ class ReusableMediaViewSet(viewsets.ModelViewSet):
|
||||
queryset=OrderPosition.objects.select_related(
|
||||
'order', 'order__event', 'order__event__organizer', 'seat',
|
||||
).prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
'answers', 'answers__options', 'answers__question',
|
||||
)
|
||||
),
|
||||
|
||||
@@ -258,7 +258,7 @@ class OrderViewSetMixin:
|
||||
return Prefetch(
|
||||
'positions',
|
||||
opq.all().prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'), to_attr='meta_values_cached')
|
||||
)),
|
||||
@@ -279,7 +279,7 @@ class OrderViewSetMixin:
|
||||
return Prefetch(
|
||||
'positions',
|
||||
opq.all().prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
'item', 'variation',
|
||||
Prefetch('answers', queryset=QuestionAnswer.objects.prefetch_related('options', 'question').order_by('question__position')),
|
||||
'seat',
|
||||
@@ -1092,7 +1092,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
||||
'item_meta_properties',
|
||||
)
|
||||
qs = qs.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'),
|
||||
to_attr='meta_values_cached')
|
||||
@@ -1111,7 +1111,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
||||
Prefetch(
|
||||
'positions',
|
||||
qs.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related('device')),
|
||||
Prefetch('item', queryset=self.request.event.items.prefetch_related(
|
||||
Prefetch('meta_values', ItemMetaValue.objects.select_related('property'),
|
||||
to_attr='meta_values_cached')
|
||||
@@ -1135,7 +1135,7 @@ class OrderPositionViewSet(viewsets.ModelViewSet):
|
||||
)
|
||||
else:
|
||||
qs = qs.prefetch_related(
|
||||
Prefetch('checkins', queryset=Checkin.objects.all()),
|
||||
Prefetch('checkins', queryset=Checkin.objects.select_related("device")),
|
||||
'answers', 'answers__options', 'answers__question',
|
||||
).select_related(
|
||||
'item', 'order', 'order__event', 'order__event__organizer', 'seat'
|
||||
|
||||
@@ -1295,7 +1295,8 @@ DEFAULTS = {
|
||||
'form_kwargs': dict(
|
||||
label=_("Show event times and dates on the ticket shop"),
|
||||
help_text=_("If disabled, no date or time will be shown on the ticket shop's front page. This settings "
|
||||
"does however not affect the display in other locations."),
|
||||
"also affects a few other locations, however it should not be expected that the date of the "
|
||||
"event is shown nowhere to users."),
|
||||
)
|
||||
},
|
||||
'show_date_to': {
|
||||
|
||||
@@ -1143,12 +1143,12 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm):
|
||||
widget=I18nTextInput,
|
||||
)
|
||||
mail_subject_order_incomplete_payment = I18nFormField(
|
||||
label=_("Subject"),
|
||||
label=_("Subject (if an incomplete payment was received)"),
|
||||
required=False,
|
||||
widget=I18nTextInput,
|
||||
)
|
||||
mail_text_order_incomplete_payment = I18nFormField(
|
||||
label=_("Text"),
|
||||
label=_("Text (if an incomplete payment was received)"),
|
||||
required=False,
|
||||
widget=I18nMarkdownTextarea,
|
||||
help_text=_("This email only applies to payment methods that can receive incomplete payments, "
|
||||
|
||||
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
|
||||
"PO-Revision-Date: 2024-07-23 10:22+0000\n"
|
||||
"PO-Revision-Date: 2024-09-03 00:00+0000\n"
|
||||
"Last-Translator: Alberto Ortega <ortega16.cieza@gmail.com>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix/"
|
||||
"es/>\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.6.2\n"
|
||||
"X-Generator: Weblate 5.7\n"
|
||||
|
||||
#: pretix/_base_settings.py:79
|
||||
msgid "English"
|
||||
@@ -3984,8 +3984,9 @@ msgstr ""
|
||||
|
||||
#: pretix/base/models/customers.py:299 pretix/base/models/orders.py:1513
|
||||
#: pretix/base/models/orders.py:3175 pretix/base/settings.py:1096
|
||||
#, fuzzy
|
||||
msgid "Company name"
|
||||
msgstr "Nombre de la Compañía"
|
||||
msgstr "Razón Social / Organización"
|
||||
|
||||
#: pretix/base/models/customers.py:303 pretix/base/models/orders.py:1517
|
||||
#: pretix/base/models/orders.py:3182 pretix/base/settings.py:81
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-08-27 13:34+0000\n"
|
||||
"PO-Revision-Date: 2024-08-26 15:00+0000\n"
|
||||
"PO-Revision-Date: 2024-09-06 08:47+0000\n"
|
||||
"Last-Translator: Albizuri <oier@puntu.eus>\n"
|
||||
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
"eu/>\n"
|
||||
@@ -602,7 +602,7 @@ msgstr ""
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:913
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:673
|
||||
msgid "Ticket design"
|
||||
msgstr ""
|
||||
msgstr "Sarrera diseinua"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:1250
|
||||
#: pretix/static/pretixcontrol/js/ui/editor.js:972
|
||||
@@ -720,16 +720,18 @@ msgid ""
|
||||
"The items in your cart are no longer reserved for you. You can still "
|
||||
"complete your order as long as they’re available."
|
||||
msgstr ""
|
||||
"Zure saskiko produktuak ez daude zuretzat erreserbatuta. Oraindik ere zure "
|
||||
"eskaera bete dezakezu, baldin eta eskuragarri badaude."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:45
|
||||
msgid "Cart expired"
|
||||
msgstr ""
|
||||
msgstr "Saskia iraungita"
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/cart.js:50
|
||||
msgid "The items in your cart are reserved for you for one minute."
|
||||
msgid_plural "The items in your cart are reserved for you for {num} minutes."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "Zure saskiko produktuak minutu -ez erreserbatuta daude zuretzat."
|
||||
msgstr[1] "Zure saskiko produktuak {num} minutuz erreserbatuta daude zuretzat."
|
||||
|
||||
#: pretix/static/pretixpresale/js/ui/main.js:203
|
||||
msgid "The organizer keeps %(currency)s %(amount)s"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -162,6 +162,21 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = N
|
||||
else:
|
||||
trans.order = orders[0]
|
||||
|
||||
if len(orders) > 1:
|
||||
# Multi-match! Can we split this automatically?
|
||||
order_pending_sum = sum(o.pending_sum for o in orders)
|
||||
if order_pending_sum != trans.amount:
|
||||
# we can't :( this needs to be dealt with by a human
|
||||
trans.state = BankTransaction.STATE_NOMATCH
|
||||
trans.message = gettext_noop('Automatic split to multiple orders not possible.')
|
||||
trans.save()
|
||||
return
|
||||
|
||||
# we can!
|
||||
splits = [(o, o.pending_sum) for o in orders]
|
||||
else:
|
||||
splits = [(orders[0], trans.amount)]
|
||||
|
||||
for o in orders:
|
||||
if o.status == Order.STATUS_PAID and o.pending_sum <= Decimal('0.00'):
|
||||
trans.state = BankTransaction.STATE_DUPLICATE
|
||||
@@ -179,21 +194,6 @@ def _handle_transaction(trans: BankTransaction, matches: tuple, event: Event = N
|
||||
trans.save()
|
||||
return
|
||||
|
||||
if len(orders) > 1:
|
||||
# Multi-match! Can we split this automatically?
|
||||
order_pending_sum = sum(o.pending_sum for o in orders)
|
||||
if order_pending_sum != trans.amount:
|
||||
# we can't :( this needs to be dealt with by a human
|
||||
trans.state = BankTransaction.STATE_NOMATCH
|
||||
trans.message = gettext_noop('Automatic split to multiple orders not possible.')
|
||||
trans.save()
|
||||
return
|
||||
|
||||
# we can!
|
||||
splits = [(o, o.pending_sum) for o in orders]
|
||||
else:
|
||||
splits = [(orders[0], trans.amount)]
|
||||
|
||||
trans.state = BankTransaction.STATE_VALID
|
||||
for order, amount in splits:
|
||||
info_data = {
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
|
||||
{% if waitinglist_seated %}
|
||||
<aside class="front-page" aria-labelledby="waiting-list">
|
||||
<h3 id="waiting-list">{% trans "Waiting list" %}</h3>
|
||||
<h3 id="waiting-list" class="sr-only">{% trans "Waiting list" %}</h3>
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-sm-6 col-xs-12">
|
||||
<p>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{% extends "pretixpresale/event/base.html" %}
|
||||
{% load i18n %}
|
||||
{% load eventurl %}
|
||||
{% load rich_text %}
|
||||
{% load money %}
|
||||
{% block title %}{% trans "Change payment method" %}{% endblock %}
|
||||
{% block custom_header %}
|
||||
@@ -23,6 +24,9 @@
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{% if event.settings.payment_explanation %}
|
||||
{{ event.settings.payment_explanation|rich_text }}
|
||||
{% endif %}
|
||||
<div class="panel-group" id="payment_accordion">
|
||||
{% for p in providers %}
|
||||
<div class="panel panel-default" data-total="{{ p.total|money_numberfield:request.event.currency }}">
|
||||
|
||||
@@ -498,6 +498,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
|
||||
'datetime': c.datetime.isoformat().replace('+00:00', 'Z'),
|
||||
'auto_checked_in': False,
|
||||
'device': None,
|
||||
'device_id': None,
|
||||
'gate': None,
|
||||
'type': 'entry',
|
||||
}
|
||||
@@ -540,6 +541,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
|
||||
'datetime': c.datetime.isoformat().replace('+00:00', 'Z'),
|
||||
'auto_checked_in': False,
|
||||
'device': None,
|
||||
'device_id': None,
|
||||
'gate': None,
|
||||
'type': 'entry',
|
||||
}
|
||||
|
||||
@@ -959,7 +959,7 @@ def test_refund_cancel(token_client, organizer, event, order):
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_orderposition_list(token_client, organizer, event, order, item, subevent, subevent2, question):
|
||||
def test_orderposition_list(token_client, organizer, device, event, order, item, subevent, subevent2, question, django_assert_num_queries):
|
||||
i2 = copy.copy(item)
|
||||
i2.pk = None
|
||||
i2.save()
|
||||
@@ -1060,19 +1060,22 @@ 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=datetime.timezone.utc), list=cl)
|
||||
c = op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=datetime.timezone.utc), list=cl, device=device)
|
||||
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',
|
||||
'list': cl.pk,
|
||||
'auto_checked_in': False,
|
||||
'device': None,
|
||||
'device': device.pk,
|
||||
'device_id': device.device_id,
|
||||
'gate': None,
|
||||
'type': 'entry'
|
||||
}]
|
||||
resp = token_client.get(
|
||||
'/api/v1/organizers/{}/events/{}/orderpositions/?has_checkin=true'.format(organizer.slug, event.slug))
|
||||
with django_assert_num_queries(15):
|
||||
resp = token_client.get(
|
||||
'/api/v1/organizers/{}/events/{}/orderpositions/?has_checkin=true'.format(organizer.slug, event.slug)
|
||||
)
|
||||
assert [res] == resp.data['results']
|
||||
|
||||
op.subevent = subevent
|
||||
|
||||
@@ -471,6 +471,33 @@ def test_split_payment_success(env, orga_job):
|
||||
assert o4.payments.get().amount == Decimal('12.00')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_valid_plus_invalid_match(env, orga_job):
|
||||
with scopes_disabled():
|
||||
o4 = Order.objects.create(
|
||||
code='99999', event=env[0],
|
||||
status=Order.STATUS_PAID,
|
||||
datetime=now(), expires=now() + timedelta(days=10),
|
||||
total=12,
|
||||
sales_channel=env[0].organizer.sales_channels.get(identifier="web"),
|
||||
)
|
||||
o4.payments.create(
|
||||
provider='paypal',
|
||||
state=OrderPayment.PAYMENT_STATE_CONFIRMED,
|
||||
amount=o4.total
|
||||
)
|
||||
process_banktransfers(orga_job, [{
|
||||
'payer': 'Karla Kundin',
|
||||
'reference': 'Bestellungen DUMMY-1Z3AS DUMMY-99999',
|
||||
'date': '2016-01-26',
|
||||
'amount': '.00'
|
||||
}])
|
||||
with scopes_disabled():
|
||||
job = BankImportJob.objects.last()
|
||||
t = job.transactions.last()
|
||||
assert t.state == BankTransaction.STATE_NOMATCH
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_split_payment_mismatch(env, orga_job):
|
||||
with scopes_disabled():
|
||||
|
||||
Reference in New Issue
Block a user