diff --git a/libpretixsync/src/main/java/eu/pretix/libpretixsync/api/PretixApi.kt b/libpretixsync/src/main/java/eu/pretix/libpretixsync/api/PretixApi.kt index 66715694..33e71625 100644 --- a/libpretixsync/src/main/java/eu/pretix/libpretixsync/api/PretixApi.kt +++ b/libpretixsync/src/main/java/eu/pretix/libpretixsync/api/PretixApi.kt @@ -129,6 +129,7 @@ open class PretixApi(url: String, key: String, orgaSlug: String, version: Int, h body.put("answers", answerbody) body.put("questions_supported", questions_supported) body.put("canceled_supported", true) + body.put("media_exchange_supported", true) body.put("secret", secret) val jlists = JSONArray() for (l in lists) { diff --git a/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/AsyncCheckProvider.kt b/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/AsyncCheckProvider.kt index b37f653c..4913ab26 100644 --- a/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/AsyncCheckProvider.kt +++ b/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/AsyncCheckProvider.kt @@ -781,6 +781,15 @@ class AsyncCheckProvider(private val config: ConfigStore, private val db: SyncDa return res } + val linkedReusableMedium = db.reusableMediumQueries.selectByLinkedOrderPosition(position.positionId) + .executeAsOneOrNull()?.toModel() + if (linkedReusableMedium != null) { + res.type = TicketCheckProvider.CheckResult.Type.ALREADY_EXCHANGED + res.isCheckinAllowed = false + storeFailedCheckin(eventSlug, list.serverId, "already_exchanged", position.secret!!, type, position = position.serverId, item = positionItem.serverId, variation = position.variationServerId, subevent = position.subEventServerId, nonce = nonce) + return res + } + // !!! When extending this, also extend checkOfflineWithoutData !!! val rules = list.rules diff --git a/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/OnlineCheckProvider.kt b/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/OnlineCheckProvider.kt index 6e26db3c..a587a925 100644 --- a/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/OnlineCheckProvider.kt +++ b/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/OnlineCheckProvider.kt @@ -163,6 +163,8 @@ class OnlineCheckProvider( res.isCheckinAllowed = includePending && response.has("position") && response.getJSONObject("position").optString("order__status", "n") == "n" } else if ("product" == reason) { res.type = TicketCheckProvider.CheckResult.Type.PRODUCT + } else if ("already_exchanged" == reason) { + res.type = TicketCheckProvider.CheckResult.Type.ALREADY_EXCHANGED } else { res.type = TicketCheckProvider.CheckResult.Type.ERROR } diff --git a/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/TicketCheckProvider.kt b/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/TicketCheckProvider.kt index d2229836..ce7b79a5 100644 --- a/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/TicketCheckProvider.kt +++ b/libpretixsync/src/main/java/eu/pretix/libpretixsync/check/TicketCheckProvider.kt @@ -57,7 +57,7 @@ interface TicketCheckProvider { class CheckResult { enum class Type { INVALID, VALID, USED, ERROR, UNPAID, BLOCKED, INVALID_TIME, CANCELED, PRODUCT, RULES, - ANSWERS_REQUIRED, AMBIGUOUS, REVOKED, UNAPPROVED + ANSWERS_REQUIRED, AMBIGUOUS, REVOKED, UNAPPROVED, ALREADY_EXCHANGED } var type: Type? = null diff --git a/libpretixsync/src/main/sqldelight/common/eu/pretix/libpretixsync/sqldelight/ReusableMedium.sq b/libpretixsync/src/main/sqldelight/common/eu/pretix/libpretixsync/sqldelight/ReusableMedium.sq index ede9a5ad..320e32c4 100644 --- a/libpretixsync/src/main/sqldelight/common/eu/pretix/libpretixsync/sqldelight/ReusableMedium.sq +++ b/libpretixsync/src/main/sqldelight/common/eu/pretix/libpretixsync/sqldelight/ReusableMedium.sq @@ -22,6 +22,12 @@ WHERE ReusableMedium.identifier = :identifier AND ReusableMedium.type = :type AND orders.event_slug IN :event_slugs; +selectByLinkedOrderPosition: +SELECT ReusableMedium.* +FROM ReusableMedium +LEFT JOIN ReusableMedium_OrderPosition ON ReusableMedium_OrderPosition.OrderPositionId = ReusableMedium.id +WHERE OrderPositionId = :order_position_id; + deleteByServerId: DELETE FROM ReusableMedium WHERE server_id = ?;