mirror of
https://github.com/pretix/pretix.git
synced 2025-12-05 21:32:28 +00:00
Compare commits
2 Commits
sold-out-v
...
checkinrpc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c79bf5432 | ||
|
|
2d7f802a7a |
@@ -54,6 +54,11 @@ Checking a ticket in
|
||||
this request twice with the same nonce, the second request will also succeed but will always
|
||||
create only one check-in object even when the previous request was successful as well. This
|
||||
allows for a certain level of idempotency and enables you to re-try after a connection failure.
|
||||
:<json boolean use_order_locale: Specifies that pretix should use the customer's language (``locale`` field from the
|
||||
order) when building texts (currently only the ``reason_explanation`` response field).
|
||||
Defaults to ``false`` in which case the server will determine the language (currently
|
||||
the event default language, might change in the future with support for the
|
||||
``Accept-Language`` header).
|
||||
:>json string status: ``"ok"``, ``"incomplete"``, or ``"error"``
|
||||
:>json string reason: Reason code, only set on status ``"error"``, see below for possible values.
|
||||
:>json string reason_explanation: Human-readable explanation, only set on status ``"error"`` and reason ``"rules"``, can be null.
|
||||
@@ -62,7 +67,9 @@ Checking a ticket in
|
||||
will only include check-ins for the selected list. (2) An additional boolean property
|
||||
``require_attention`` will inform you whether either the order or the item have the
|
||||
``checkin_attention`` flag set. (3) If ``attendee_name`` is empty, it may automatically fall
|
||||
back to values from a parent product or from invoice addresses.
|
||||
back to values from a parent product or from invoice addresses. (4) Additional properties
|
||||
``order__status``, ``order__valid_if_pending``, ``order__require_approval``, and
|
||||
``order__locale`` are included with details form the order for convenience.
|
||||
:>json boolean require_attention: Whether or not the ``require_attention`` flag is set on the item or order.
|
||||
:>json list checkin_texts: List of additional texts to show to the user.
|
||||
:>json object list: Excerpt of information about the matching :ref:`check-in list <rest-checkinlists>` (if any was found),
|
||||
|
||||
@@ -84,6 +84,7 @@ class CheckinRPCRedeemInputSerializer(serializers.Serializer):
|
||||
type = serializers.ChoiceField(choices=Checkin.CHECKIN_TYPES, default=Checkin.TYPE_ENTRY)
|
||||
ignore_unpaid = serializers.BooleanField(default=False, required=False)
|
||||
questions_supported = serializers.BooleanField(default=True, required=False)
|
||||
use_order_locale = serializers.BooleanField(default=False, required=False)
|
||||
nonce = serializers.CharField(required=False, allow_null=True)
|
||||
datetime = serializers.DateTimeField(required=False, allow_null=True)
|
||||
answers = serializers.JSONField(required=False, allow_null=True)
|
||||
|
||||
@@ -607,6 +607,7 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
|
||||
order__status = serializers.SlugRelatedField(read_only=True, slug_field='status', source='order')
|
||||
order__valid_if_pending = serializers.SlugRelatedField(read_only=True, slug_field='valid_if_pending', source='order')
|
||||
order__require_approval = serializers.SlugRelatedField(read_only=True, slug_field='require_approval', source='order')
|
||||
order__locale = serializers.SlugRelatedField(read_only=True, slug_field='locale', source='order')
|
||||
|
||||
class Meta:
|
||||
model = OrderPosition
|
||||
@@ -615,7 +616,7 @@ class CheckinListOrderPositionSerializer(OrderPositionSerializer):
|
||||
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
||||
'print_logs', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat',
|
||||
'require_attention', 'order__status', 'order__valid_if_pending', 'order__require_approval',
|
||||
'valid_from', 'valid_until', 'blocked')
|
||||
'order__locale', 'valid_from', 'valid_until', 'blocked')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -420,7 +420,7 @@ def _checkin_list_position_queryset(checkinlists, ignore_status=False, ignore_pr
|
||||
|
||||
def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force, checkin_type, ignore_unpaid, nonce,
|
||||
untrusted_input, user, auth, expand, pdf_data, request, questions_supported, canceled_supported,
|
||||
source_type='barcode', legacy_url_support=False, simulate=False, gate=None):
|
||||
source_type='barcode', legacy_url_support=False, simulate=False, gate=None, use_order_locale=False):
|
||||
if not checkinlists:
|
||||
raise ValidationError('No check-in list passed.')
|
||||
|
||||
@@ -694,7 +694,11 @@ def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force,
|
||||
pass
|
||||
|
||||
# 6. Pass to our actual check-in logic
|
||||
with language(op.order.event.settings.locale):
|
||||
if use_order_locale:
|
||||
locale = op.order.locale
|
||||
else:
|
||||
locale = op.order.event.settings.locale
|
||||
with language(locale):
|
||||
try:
|
||||
perform_checkin(
|
||||
op=op,
|
||||
@@ -909,6 +913,7 @@ class CheckinRPCRedeemView(views.APIView):
|
||||
expand=self.request.query_params.getlist('expand'),
|
||||
pdf_data=self.request.query_params.get('pdf_data', 'false') == 'true',
|
||||
questions_supported=s.validated_data['questions_supported'],
|
||||
use_order_locale=s.validated_data['use_order_locale'],
|
||||
canceled_supported=True,
|
||||
request=self.request, # this is not clean, but we need it in the serializers for URL generation
|
||||
legacy_url_support=False,
|
||||
|
||||
@@ -108,6 +108,7 @@ TEST_ORDERPOSITION1_RES = {
|
||||
"order__status": "p",
|
||||
"order__require_approval": False,
|
||||
"order__valid_if_pending": False,
|
||||
"order__locale": "en",
|
||||
"order": "FOO",
|
||||
"positionid": 1,
|
||||
"item": 1,
|
||||
@@ -146,6 +147,7 @@ TEST_ORDERPOSITION2_RES = {
|
||||
"order__status": "p",
|
||||
"order__require_approval": False,
|
||||
"order__valid_if_pending": False,
|
||||
"order__locale": "en",
|
||||
"order": "FOO",
|
||||
"positionid": 2,
|
||||
"item": 1,
|
||||
@@ -184,6 +186,7 @@ TEST_ORDERPOSITION3_RES = {
|
||||
"order__status": "p",
|
||||
"order__require_approval": False,
|
||||
"order__valid_if_pending": False,
|
||||
"order__locale": "en",
|
||||
"order": "FOO",
|
||||
"positionid": 3,
|
||||
"item": 1,
|
||||
|
||||
@@ -28,6 +28,7 @@ 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 freezegun import freeze_time
|
||||
from i18nfield.strings import LazyI18nString
|
||||
from tests.const import SAMPLE_PNG
|
||||
|
||||
@@ -148,6 +149,7 @@ TEST_ORDERPOSITION1_RES = {
|
||||
"order__status": "p",
|
||||
"order__require_approval": False,
|
||||
"order__valid_if_pending": False,
|
||||
"order__locale": "en",
|
||||
"order": "FOO",
|
||||
"positionid": 1,
|
||||
"item": 1,
|
||||
@@ -200,7 +202,7 @@ def clist_event2(event2):
|
||||
return c
|
||||
|
||||
|
||||
def _redeem(token_client, org, clist, p, body=None, query=''):
|
||||
def _redeem(token_client, org, clist, p, body=None, query='', headers={}):
|
||||
body = body or {}
|
||||
if isinstance(clist, list):
|
||||
body['lists'] = [c.pk for c in clist]
|
||||
@@ -209,7 +211,7 @@ def _redeem(token_client, org, clist, p, body=None, query=''):
|
||||
body['secret'] = p
|
||||
return token_client.post('/api/v1/organizers/{}/checkinrpc/redeem/{}'.format(
|
||||
org.slug, query,
|
||||
), body, format='json')
|
||||
), body, format='json', headers={})
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -1050,3 +1052,28 @@ def test_checkin_no_pdf_data(token_client, event, team, organizer, clist_all, or
|
||||
resp = token_client.get(
|
||||
'/api/v1/organizers/{}/checkinrpc/search/?list={}&search=dummy&pdf_data=true'.format(organizer.slug, clist_all.pk))
|
||||
assert not resp.data['results'][0].get('pdf_data')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_reason_explanation_localization(token_client, organizer, clist, other_item, event, order):
|
||||
event.settings.locales = ["de", "en"]
|
||||
order.locale = "de"
|
||||
order.save()
|
||||
with scopes_disabled():
|
||||
p = order.positions.first()
|
||||
p.valid_from = datetime.datetime(2020, 1, 1, 12, 0, 0, tzinfo=event.timezone)
|
||||
p.save()
|
||||
with freeze_time("2020-01-01 10:45:00"):
|
||||
resp = _redeem(token_client, organizer, clist, 'z3fsn8jyufm5kpk768q69gkbyr5f4h6w', {})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data["status"] == "error"
|
||||
assert resp.data["reason"] == "invalid_time"
|
||||
assert resp.data["reason_explanation"] == "This ticket is only valid after 2020-01-01 12:00."
|
||||
|
||||
resp = _redeem(token_client, organizer, clist, 'z3fsn8jyufm5kpk768q69gkbyr5f4h6w', {
|
||||
"use_order_locale": True
|
||||
})
|
||||
assert resp.status_code == 400
|
||||
assert resp.data["status"] == "error"
|
||||
assert resp.data["reason"] == "invalid_time"
|
||||
assert resp.data["reason_explanation"] == "Erst ab 01.01.2020 12:00 gültig."
|
||||
|
||||
Reference in New Issue
Block a user