fix multi-op media filter

This commit is contained in:
Richard Schreiber
2025-12-17 09:07:34 +01:00
parent 90a05c87f8
commit b9035e8c6d
2 changed files with 31 additions and 24 deletions

View File

@@ -667,19 +667,19 @@ def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force,
# key on the same list, we're probably dealing with the ``addon_match`` case here and need to figure out # key on the same list, we're probably dealing with the ``addon_match`` case here and need to figure out
# which add-on has the right product. # which add-on has the right product.
if len(op_candidates) > 1: if len(op_candidates) > 1:
op_candidates_matching_product = [ # only check addons if at most one non-addon-op is in op_candidates
op for op in op_candidates # otherwise it is likely a medium linked to multiple orderpositions, which we need to filter based on validity
if ( if len([op for op in op_candidates if not op.addon_to]) <= 1:
(list_by_event[op.order.event_id].addon_match or op.secret == raw_barcode or legacy_url_support) and
(list_by_event[op.order.event_id].all_products or op.item_id in {i.pk for i in list_by_event[op.order.event_id].limit_products.all()})
)
]
if len(op_candidates_matching_product) > 1:
# if none of the above filters the results to 1, filter based on op.valid_from/until
# keep ops without valid_from/until
op_candidates_matching_product = [ op_candidates_matching_product = [
op for op in op_candidates_matching_product op for op in op_candidates
if (
(list_by_event[op.order.event_id].addon_match or op.secret == raw_barcode or legacy_url_support) and
(list_by_event[op.order.event_id].all_products or op.item_id in {i.pk for i in list_by_event[op.order.event_id].limit_products.all()})
)
]
else:
op_candidates_matching_product = [
op for op in op_candidates
if ( if (
(not op.valid_from or op.valid_from < now()) and (not op.valid_from or op.valid_from < now()) and
(not op.valid_until or op.valid_until > now()) (not op.valid_until or op.valid_until > now())

View File

@@ -310,30 +310,37 @@ def test_by_medium_multiple_orderpositions(token_client, organizer, clist, event
organizer=organizer, organizer=organizer,
) )
rm.linked_orderpositions.add(order.positions.first()) rm.linked_orderpositions.add(order.positions.first())
rm.linked_orderpositions.add(order.positions.all()[1]) op_item_other = order.positions.all()[1]
rm.linked_orderpositions.add(op_item_other)
# multiple tickets are valid => no check-in
resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"}) resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"})
# TODO: AMBIGIOUS assert resp.status_code == 400
assert resp.status_code == 201 assert resp.data['status'] == 'error'
assert resp.data['reason'] == 'ambiguous'
with scopes_disabled(): with scopes_disabled():
op = order.positions.first() op_item_other.valid_from = datetime.datetime(2020, 1, 1, 12, 0, 0, tzinfo=event.timezone)
op.valid_from = datetime.datetime(2020, 1, 1, 12, 0, 0, tzinfo=event.timezone) op_item_other.valid_until = datetime.datetime(2020, 1, 1, 15, 0, 0, tzinfo=event.timezone)
op.save() op_item_other.save()
with freeze_time("2020-01-01 13:45:00"): with freeze_time("2020-01-01 13:45:00"):
# multiple tickets are valid => no check-in
resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"}) resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"})
# TODO: AMBIGIOUS assert resp.status_code == 400
assert resp.status_code == 201 assert resp.data['status'] == 'error'
assert resp.data['reason'] == 'ambiguous'
with freeze_time("2020-01-01 10:45:00"): with freeze_time("2020-01-01 10:45:00"):
resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"}) resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"})
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
with scopes_disabled(): with freeze_time("2020-01-01 15:45:00"):
ci = clist.checkins.get(position=order.positions.first()) resp = _redeem(token_client, organizer, clist, "abcdef", {"source_type": "barcode"})
assert ci.raw_barcode == "abcdef" assert resp.status_code == 400
assert ci.raw_source_type == "barcode" assert resp.data['status'] == 'error'
assert resp.data['reason'] == 'already_redeemed'
@pytest.mark.django_db @pytest.mark.django_db