mirror of
https://github.com/pretix/pretix.git
synced 2026-09-14 16:24:43 +00:00
Check-in: New error reason for unapproved orders (#3741)
* Check-in: New error reason for unapproved orders * Fix documentation verbiage
This commit is contained in:
@@ -217,6 +217,7 @@ Checking a ticket in
|
|||||||
* ``rules`` - Check-in prevented by a user-defined rule.
|
* ``rules`` - Check-in prevented by a user-defined rule.
|
||||||
* ``ambiguous`` - Multiple tickets match scan, rejected.
|
* ``ambiguous`` - Multiple tickets match scan, rejected.
|
||||||
* ``revoked`` - Ticket code has been revoked.
|
* ``revoked`` - Ticket code has been revoked.
|
||||||
|
* ``unapproved`` - Order has not yet been approved.
|
||||||
* ``error`` - Internal error.
|
* ``error`` - Internal error.
|
||||||
|
|
||||||
In case of reason ``rules`` and ``invalid_time``, there might be an additional response field ``reason_explanation``
|
In case of reason ``rules`` and ``invalid_time``, there might be an additional response field ``reason_explanation``
|
||||||
|
|||||||
@@ -632,7 +632,8 @@ Order position endpoints
|
|||||||
set this to ``false``. In that case, questions will just be ignored. Defaults
|
set this to ``false``. In that case, questions will just be ignored. Defaults
|
||||||
to ``true``.
|
to ``true``.
|
||||||
:<json boolean canceled_supported: When this parameter is set to ``true``, the response code ``canceled`` may be
|
:<json boolean canceled_supported: When this parameter is set to ``true``, the response code ``canceled`` may be
|
||||||
returned. Otherwise, canceled orders will return ``unpaid``.
|
returned. Otherwise, canceled orders will return ``unpaid``. (**Deprecated**, in
|
||||||
|
the future, this will be ignored and ``canceled`` may always be returned.)
|
||||||
:<json datetime datetime: Specifies the datetime of the check-in. If not supplied, the current time will be used.
|
:<json datetime datetime: Specifies the datetime of the check-in. If not supplied, the current time will be used.
|
||||||
:<json boolean force: Specifies that the check-in should succeed regardless of revoked barcode, previous check-ins or required
|
:<json boolean force: Specifies that the check-in should succeed regardless of revoked barcode, previous check-ins or required
|
||||||
questions that have not been filled. This is usually used to upload offline scans that already happened,
|
questions that have not been filled. This is usually used to upload offline scans that already happened,
|
||||||
@@ -758,6 +759,7 @@ Order position endpoints
|
|||||||
* ``rules`` - Check-in prevented by a user-defined rule.
|
* ``rules`` - Check-in prevented by a user-defined rule.
|
||||||
* ``ambiguous`` - Multiple tickets match scan, rejected.
|
* ``ambiguous`` - Multiple tickets match scan, rejected.
|
||||||
* ``revoked`` - Ticket code has been revoked.
|
* ``revoked`` - Ticket code has been revoked.
|
||||||
|
* ``unapproved`` - Order has not yet been approved.
|
||||||
|
|
||||||
In case of reason ``rules`` or ``invalid_time``, there might be an additional response field ``reason_explanation``
|
In case of reason ``rules`` or ``invalid_time``, there might be an additional response field ``reason_explanation``
|
||||||
with a human-readable description of the violated rules. However, that field can also be missing or be ``null``.
|
with a human-readable description of the violated rules. However, that field can also be missing or be ``null``.
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 278 KiB After Width: | Height: | Size: 287 KiB |
@@ -25,27 +25,27 @@ partition "data-based check" {
|
|||||||
else
|
else
|
||||||
-down->[yes] "Is one or more block set on the ticket?"
|
-down->[yes] "Is one or more block set on the ticket?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no] "Return error BLOCKED"
|
-right->[yes] "Return error BLOCKED"
|
||||||
else
|
else
|
||||||
-down->[yes] "If this is not an exit, is the valid_from/valid_until\nconstraint on the ticket fulfilled?"
|
-down->[no] "Is the order in status PENDING and not yet approved?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no] "Return error INVALID_TIME"
|
-right->[yes] "Return error UNAPPROVED"
|
||||||
else
|
else
|
||||||
-down->[yes] "Is the product part of the check-in list?"
|
-down->[no] "If this is not an exit, is the valid_from/valid_until\nconstraint on the ticket fulfilled?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no] "Return error PRODUCT"
|
-right->[no] "Return error INVALID_TIME"
|
||||||
else
|
else
|
||||||
-down->[yes] "Is the subevent part of the check-in list?"
|
-down->[yes] "Is the product part of the check-in list?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no] "Return error INVALID"
|
-right->[no] "Return error PRODUCT"
|
||||||
note bottom: TODO\ninconsistent\nwith online\ncheck
|
|
||||||
else
|
else
|
||||||
-down->[yes] "Is the order in status PAID?"
|
-down->[yes] "Is the subevent part of the check-in list?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no] "Is Order.require_approval set?"
|
-right->[no] "Return error INVALID"
|
||||||
|
note bottom: TODO\ninconsistent\nwith online\ncheck
|
||||||
|
else
|
||||||
|
-down->[yes] "Is the order in status PAID?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-->[yes] "Return error UNPAID "
|
|
||||||
else
|
|
||||||
-right->[no] "Is Order.valid_if_pending set?"
|
-right->[no] "Is Order.valid_if_pending set?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-->[yes] "Is this an entry or exit?"
|
-->[yes] "Is this an entry or exit?"
|
||||||
@@ -62,9 +62,9 @@ partition "data-based check" {
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
else
|
||||||
|
-down->[yes] "Is this an entry or exit?"
|
||||||
endif
|
endif
|
||||||
else
|
|
||||||
-down->[yes] "Is this an entry or exit?"
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 183 KiB |
@@ -42,23 +42,25 @@ endif
|
|||||||
else
|
else
|
||||||
-down->[yes || force] "Is one or more block set on the ticket?"
|
-down->[yes || force] "Is one or more block set on the ticket?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no && !force] "Return error BLOCKED"
|
-right->[yes && !force] "Return error BLOCKED"
|
||||||
else
|
else
|
||||||
-down->[yes || force] "If this is not an exit, is the valid_from/valid_until\nconstraint on the ticket fulfilled?"
|
-down->[no || force] "Is the order in status PENDING and not yet approved?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no && !force] "Return error INVALID_TIME"
|
-right->[yes && !force] "Return error UNAPPROVED"
|
||||||
else
|
else
|
||||||
-down->[yes || force] "Is the product part of the check-in list?"
|
-down->[no || force] "If this is not an exit, is the valid_from/valid_until\nconstraint on the ticket fulfilled?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no && !force] "Return error PRODUCT"
|
-right->[no && !force] "Return error INVALID_TIME"
|
||||||
else
|
else
|
||||||
-down->[yes || force] "Is the subevent part of the check-in list?"
|
-down->[yes || force] "Is the product part of the check-in list?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no && !force] "Return error PRODUCT "
|
-right->[no && !force] "Return error PRODUCT"
|
||||||
else
|
else
|
||||||
-down->[yes] "Is the order in status PAID?"
|
-down->[yes || force] "Is the subevent part of the check-in list?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-right->[no && !force] "Is Order.require_approval set?"
|
-right->[no && !force] "Return error PRODUCT "
|
||||||
|
else
|
||||||
|
-down->[yes] "Is the order in status PAID?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
-->[no] "Is Order.valid_if_pending set?"
|
-->[no] "Is Order.valid_if_pending set?"
|
||||||
--> if "" then
|
--> if "" then
|
||||||
@@ -77,10 +79,8 @@ else
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
-->[yes] "Return error UNPAID "
|
-down->[yes || force] "Is this an entry or exit?\nIs the upload forced?"
|
||||||
endif
|
endif
|
||||||
else
|
|
||||||
-down->[yes || force] "Is this an entry or exit?\nIs the upload forced?"
|
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ class Checkin(models.Model):
|
|||||||
REASON_AMBIGUOUS = 'ambiguous'
|
REASON_AMBIGUOUS = 'ambiguous'
|
||||||
REASON_ERROR = 'error'
|
REASON_ERROR = 'error'
|
||||||
REASON_BLOCKED = 'blocked'
|
REASON_BLOCKED = 'blocked'
|
||||||
|
REASON_UNAPPROVED = 'unapproved'
|
||||||
REASON_INVALID_TIME = 'invalid_time'
|
REASON_INVALID_TIME = 'invalid_time'
|
||||||
REASONS = (
|
REASONS = (
|
||||||
(REASON_CANCELED, _('Order canceled')),
|
(REASON_CANCELED, _('Order canceled')),
|
||||||
@@ -365,6 +366,7 @@ class Checkin(models.Model):
|
|||||||
(REASON_AMBIGUOUS, _('Ticket code is ambiguous on list')),
|
(REASON_AMBIGUOUS, _('Ticket code is ambiguous on list')),
|
||||||
(REASON_ERROR, _('Server error')),
|
(REASON_ERROR, _('Server error')),
|
||||||
(REASON_BLOCKED, _('Ticket blocked')),
|
(REASON_BLOCKED, _('Ticket blocked')),
|
||||||
|
(REASON_UNAPPROVED, _('Order not approved')),
|
||||||
(REASON_INVALID_TIME, _('Ticket not valid at this time')),
|
(REASON_INVALID_TIME, _('Ticket not valid at this time')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -874,6 +874,15 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
|
|||||||
'blocked'
|
'blocked'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if op.order.status == Order.STATUS_PENDING and op.order.require_approval:
|
||||||
|
if force:
|
||||||
|
force_used = True
|
||||||
|
else:
|
||||||
|
raise CheckInError(
|
||||||
|
_('This order is not yet approved.'),
|
||||||
|
'unapproved',
|
||||||
|
)
|
||||||
|
|
||||||
if type != Checkin.TYPE_EXIT and op.valid_from and op.valid_from > dt:
|
if type != Checkin.TYPE_EXIT and op.valid_from and op.valid_from > dt:
|
||||||
if force:
|
if force:
|
||||||
force_used = True
|
force_used = True
|
||||||
@@ -941,14 +950,6 @@ def perform_checkin(op: OrderPosition, clist: CheckinList, given_answers: dict,
|
|||||||
'product'
|
'product'
|
||||||
)
|
)
|
||||||
|
|
||||||
if op.order.status != Order.STATUS_PAID and op.order.require_approval:
|
|
||||||
if force:
|
|
||||||
force_used = True
|
|
||||||
else:
|
|
||||||
raise CheckInError(
|
|
||||||
_('This order is not yet approved.'),
|
|
||||||
'unpaid'
|
|
||||||
)
|
|
||||||
elif op.order.status != Order.STATUS_PAID and not op.order.valid_if_pending and not (
|
elif op.order.status != Order.STATUS_PAID and not op.order.valid_if_pending and not (
|
||||||
ignore_unpaid and clist.include_pending and op.order.status == Order.STATUS_PENDING
|
ignore_unpaid and clist.include_pending and op.order.status == Order.STATUS_PENDING
|
||||||
):
|
):
|
||||||
|
|||||||
@@ -278,8 +278,10 @@ export default {
|
|||||||
return this.$root.strings['result.ok']
|
return this.$root.strings['result.ok']
|
||||||
} else if (this.checkResult.status === 'incomplete') {
|
} else if (this.checkResult.status === 'incomplete') {
|
||||||
return this.$root.strings['result.questions']
|
return this.$root.strings['result.questions']
|
||||||
} else {
|
} else if (this.$root.strings['result.' + this.checkResult.reason]) {
|
||||||
return this.$root.strings['result.' + this.checkResult.reason]
|
return this.$root.strings['result.' + this.checkResult.reason]
|
||||||
|
} else {
|
||||||
|
return this.checkResult.reason
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
checkResultColor () {
|
checkResultColor () {
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ window.vapp = new Vue({
|
|||||||
'result.invalid_time': gettext('Ticket not valid at this time'),
|
'result.invalid_time': gettext('Ticket not valid at this time'),
|
||||||
'result.canceled': gettext('Order canceled'),
|
'result.canceled': gettext('Order canceled'),
|
||||||
'result.ambiguous': gettext('Ticket code is ambiguous on list'),
|
'result.ambiguous': gettext('Ticket code is ambiguous on list'),
|
||||||
|
'result.unapproved': gettext('Order not approved'),
|
||||||
'status.checkin': gettext('Checked-in Tickets'),
|
'status.checkin': gettext('Checked-in Tickets'),
|
||||||
'status.position': gettext('Valid Tickets'),
|
'status.position': gettext('Valid Tickets'),
|
||||||
'status.inside': gettext('Currently inside'),
|
'status.inside': gettext('Currently inside'),
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ def test_require_approval(position, clist):
|
|||||||
clist.save()
|
clist.save()
|
||||||
with pytest.raises(CheckInError) as excinfo:
|
with pytest.raises(CheckInError) as excinfo:
|
||||||
perform_checkin(position, clist, {}, ignore_unpaid=True)
|
perform_checkin(position, clist, {}, ignore_unpaid=True)
|
||||||
assert excinfo.value.code == 'unpaid'
|
assert excinfo.value.code == 'unapproved'
|
||||||
perform_checkin(position, clist, {}, ignore_unpaid=True, force=True)
|
perform_checkin(position, clist, {}, ignore_unpaid=True, force=True)
|
||||||
assert position.checkins.count() == 1
|
assert position.checkins.count() == 1
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user