From 42e5732e8d4805c3d10d062520f44a427324cf75 Mon Sep 17 00:00:00 2001 From: Richard Schreiber Date: Mon, 11 May 2026 10:53:49 +0200 Subject: [PATCH] Improve op_candidate-selection for error message if no op matches check-in --- src/pretix/api/views/checkin.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/pretix/api/views/checkin.py b/src/pretix/api/views/checkin.py index 86f92a25ad..45adbb8497 100644 --- a/src/pretix/api/views/checkin.py +++ b/src/pretix/api/views/checkin.py @@ -721,8 +721,29 @@ def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force, if len(op_candidates_filtered) == 0: # None of the ops is valid today or has the correct product, too bad! We could just error out here, but # instead we just continue with *any* product and have it rejected by the check in perform_checkin. - # This has the advantage of a better error message. - op_candidates = [op_candidates[0]] + # To improve the error message, we select the op that will "work next" or - if none matches - "worked last". + now_dt = now() + op_candidate = None + for op in op_candidates: + if ( + op.valid_from and op.valid_from > now_dt and + (not op_candidate or op.valid_from < op_candidate.valid_from) + ): + op_candidate = op + + if not op_candidate: + # no candidate in the future, get closest in the past + for op in op_candidates: + if ( + op.valid_until and op.valid_until < now_dt and + (not op_candidate or op.valid_from > op_candidate.valid_from) + ): + op_candidate = op + + if not op_candidate: + op_candidate = op_candidates[0] + + op_candidates = [op_candidate] elif len(op_candidates_filtered) > 1: # It's still ambiguous, we'll error out. # We choose the first match (regardless of product) for the logging since it's most likely to be the