Skip to content

Commit

Permalink
API: Support expires attribute during order creation
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelm committed Dec 19, 2023
1 parent c7c9c95 commit 7f0ed37
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
10 changes: 8 additions & 2 deletions doc/api/resources/orders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,17 @@ last_modified datetime Last modificati

The ``event`` attribute has been added. The organizer-level endpoint has been added.

.. versionchanged:: 2023.9

The ``customer`` query parameter has been added.

.. versionchanged:: 2023.10

The ``checkin_text`` attribute has been added.

.. versionchanged:: 2023.9
.. versionchanged:: 2024.1

The ``customer`` query parameter has been added.
The ``expires`` attribute can now be passed during order creation.


.. _order-position-resource:
Expand Down Expand Up @@ -729,6 +733,8 @@ Updating order fields

* ``valid_if_pending``

* ``expires``

**Example request**:

.. sourcecode:: http
Expand Down
11 changes: 9 additions & 2 deletions src/pretix/api/serializers/order.py
Original file line number Diff line number Diff line change
Expand Up @@ -1035,13 +1035,14 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['positions'].child.fields['voucher'].queryset = self.context['event'].vouchers.all()
self.fields['customer'].queryset = self.context['event'].organizer.customers.all()
self.fields['expires'].required = False

class Meta:
model = Order
fields = ('code', 'status', 'testmode', 'email', 'phone', 'locale', 'payment_provider', 'fees', 'comment', 'sales_channel',
'invoice_address', 'positions', 'checkin_attention', 'checkin_text', 'payment_info', 'payment_date',
'consume_carts', 'force', 'send_email', 'simulate', 'customer', 'custom_followup_at',
'require_approval', 'valid_if_pending')
'require_approval', 'valid_if_pending', 'expires')

def validate_payment_provider(self, pp):
if pp is None:
Expand All @@ -1050,6 +1051,11 @@ def validate_payment_provider(self, pp):
raise ValidationError('The given payment provider is not known.')
return pp

def validate_expires(self, expires):
if expires < now():
raise ValidationError('Expiration date must be in the future.')
return expires

def validate_sales_channel(self, channel):
if channel not in get_all_sales_channels():
raise ValidationError('Unknown sales channel.')
Expand Down Expand Up @@ -1356,7 +1362,8 @@ def create(self, validated_data):
if validated_data.get('locale', None) is None:
validated_data['locale'] = self.context['event'].settings.locale
order = Order(event=self.context['event'], **validated_data)
order.set_expires(subevents=[p.get('subevent') for p in positions_data])
if not validated_data.get('expires'):
order.set_expires(subevents=[p.get('subevent') for p in positions_data])
order.meta_info = "{}"
order.total = Decimal('0.00')
if validated_data.get('require_approval') is not None:
Expand Down
32 changes: 32 additions & 0 deletions src/tests/api/test_order_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def test_order_create(token_client, organizer, event, item, quota, question):
assert o.status == Order.STATUS_PENDING
assert o.sales_channel == "web"
assert o.valid_if_pending
assert o.expires > now()
assert not o.testmode

with scopes_disabled():
Expand Down Expand Up @@ -277,6 +278,37 @@ def test_order_create(token_client, organizer, event, item, quota, question):
assert o.transactions.count() == 2


@pytest.mark.django_db
def test_order_create_expires(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
res['positions'][0]['item'] = item.pk
res['positions'][0]['answers'][0]['question'] = question.pk

expires = now() - datetime.timedelta(hours=7)
res['expires'] = expires.isoformat()
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 400
assert resp.data == {"expires": ["Expiration date must be in the future."]}

expires = now() + datetime.timedelta(hours=7)
res['expires'] = expires.isoformat()
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 201
assert not resp.data['positions'][0].get('pdf_data')
with scopes_disabled():
o = Order.objects.get(code=resp.data['code'])
assert o.expires == expires
assert o.status == Order.STATUS_PENDING


@pytest.mark.django_db
def test_order_create_simulate(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
Expand Down

0 comments on commit 7f0ed37

Please sign in to comment.