Class: SeatLayer::Inventory
- Defined in:
- lib/seatlayer/inventory.rb
Overview
Holds, booking, blocking and availability.
Two complete flows, both first-class:
browser holds → retrieve_hold for authoritative pricing → charge → book(hold_id:)
backend books labels directly — box office, phone sales, comps
Never price from what the browser tells you. retrieve_hold is the
authoritative answer, which is why it is a separate call.
Instance Method Summary collapse
-
#block(event_key, labels:) ⇒ Object
Hold inventory back from sale (house seats, production holds).
- #book(event_key, hold_id: nil, labels: nil, booking_ref: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
-
#book_best_available(event_key, qty:, booking_ref:, category_key: nil, zone_id: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
Pick and book in one call — the box-office shape.
- #box_office_book(event_key, labels:, booking_ref:, idempotency_key: nil) ⇒ Object
-
#extend_hold(event_key, hold_id, ttl_ms: nil) ⇒ Object
Push an active hold's expiry out by a fresh window before it lapses.
-
#hold(event_key, labels: nil, selections: nil, ttl_ms: nil, replace_hold_id: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
Explicit keywords keep allocation authority visible at every sale call.
-
#hold_best_available(event_key, qty:, category_key: nil, zone_id: nil, ttl_ms: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
Ask us to pick the best free objects and hold them.
-
#list_bookings(event_key, query: nil, state: nil, limit: nil, cursor: nil) ⇒ Object
One page of inventory booking lifecycles, newest first.
- #release(event_key, labels:, hold_id:) ⇒ Object
- #retrieve_availability(event_key) ⇒ Object
- #retrieve_booking(event_key, booking_ref) ⇒ Object
-
#retrieve_hold(event_key, hold_id) ⇒ Object
Authoritative items and prices.
- #unblock(event_key, labels:) ⇒ Object
- #unblock_all(event_key) ⇒ Object
-
#unbook(event_key, labels:, booking_ref:) ⇒ Object
Reverse a booking.
- #update_availability(event_key, fields) ⇒ Object
Methods inherited from Resource
Constructor Details
This class inherits a constructor from SeatLayer::Resource
Instance Method Details
#block(event_key, labels:) ⇒ Object
Hold inventory back from sale (house seats, production holds).
101 102 103 |
# File 'lib/seatlayer/inventory.rb', line 101 def block(event_key, labels:) @client.post(path(event_key, "/block"), { "labels" => labels }) end |
#book(event_key, hold_id: nil, labels: nil, booking_ref: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
78 79 80 81 82 83 84 85 86 |
# File 'lib/seatlayer/inventory.rb', line 78 def book(event_key, hold_id: nil, labels: nil, booking_ref: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) body = compact({ "holdId" => hold_id, "labels" => labels, "bookingRef" => normalise_booking_ref(booking_ref), "channelIds" => channel_ids, "ignoreChannelRestrictions" => ignore_channel_restrictions, "reason" => reason }) @client.post(path(event_key, "/book"), body, idempotency_key: idempotency_key) end |
#book_best_available(event_key, qty:, booking_ref:, category_key: nil, zone_id: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
Pick and book in one call — the box-office shape.
Prefer this over hold-then-book when payment is already taken: a failure between two calls would strand inventory until the TTL expired.
47 48 49 50 51 52 53 54 55 56 |
# File 'lib/seatlayer/inventory.rb', line 47 def book_best_available(event_key, qty:, booking_ref:, category_key: nil, zone_id: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) body = compact({ "qty" => qty, "bookingRef" => normalise_booking_ref(booking_ref), "categoryKey" => category_key, "zoneId" => zone_id, "channelIds" => channel_ids, "ignoreChannelRestrictions" => ignore_channel_restrictions, "reason" => reason }) @client.post(path(event_key, "/best-available-book"), body, idempotency_key: idempotency_key) end |
#box_office_book(event_key, labels:, booking_ref:, idempotency_key: nil) ⇒ Object
88 89 90 91 92 |
# File 'lib/seatlayer/inventory.rb', line 88 def box_office_book(event_key, labels:, booking_ref:, idempotency_key: nil) @client.post(path(event_key, "/box-book"), { "labels" => labels, "bookingRef" => normalise_booking_ref(booking_ref) }, idempotency_key: idempotency_key) end |
#extend_hold(event_key, hold_id, ttl_ms: nil) ⇒ Object
Push an active hold's expiry out by a fresh window before it lapses.
Use this rather than release-and-re-hold when an order takes longer than
the checkout window — invoiced sales, a phone order on hold. Releasing
first hands the seats to whoever is racing for them in between. A hold that
is gone, expired, or at its renewal cap answers 409 cannot_extend.
65 66 67 |
# File 'lib/seatlayer/inventory.rb', line 65 def extend_hold(event_key, hold_id, ttl_ms: nil) @client.post(path(event_key, "/extend"), compact({ "holdId" => hold_id, "ttlMs" => ttl_ms })) end |
#hold(event_key, labels: nil, selections: nil, ttl_ms: nil, replace_hold_id: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
Explicit keywords keep allocation authority visible at every sale call. rubocop:disable Metrics/ParameterLists
16 17 18 19 20 21 22 23 24 25 |
# File 'lib/seatlayer/inventory.rb', line 16 def hold(event_key, labels: nil, selections: nil, ttl_ms: nil, replace_hold_id: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) body = compact({ "labels" => labels, "selections" => selections, "ttlMs" => ttl_ms, "replaceHoldId" => replace_hold_id, "channelIds" => channel_ids, "ignoreChannelRestrictions" => ignore_channel_restrictions, "reason" => reason }) @client.post(path(event_key, "/hold"), body, idempotency_key: idempotency_key) end |
#hold_best_available(event_key, qty:, category_key: nil, zone_id: nil, ttl_ms: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) ⇒ Object
Ask us to pick the best free objects and hold them.
The picker is the one the buyer widget uses, so a phone order and a web
order get the same answer for the same inventory. A qty above the server
cap is clamped, not rejected.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/seatlayer/inventory.rb', line 32 def hold_best_available(event_key, qty:, category_key: nil, zone_id: nil, ttl_ms: nil, channel_ids: nil, ignore_channel_restrictions: nil, reason: nil, idempotency_key: nil) body = compact({ "qty" => qty, "categoryKey" => category_key, "zoneId" => zone_id, "ttlMs" => ttl_ms, "channelIds" => channel_ids, "ignoreChannelRestrictions" => ignore_channel_restrictions, "reason" => reason }) @client.post(path(event_key, "/best-available"), body, idempotency_key: idempotency_key) end |
#list_bookings(event_key, query: nil, state: nil, limit: nil, cursor: nil) ⇒ Object
One page of inventory booking lifecycles, newest first.
122 123 124 125 |
# File 'lib/seatlayer/inventory.rb', line 122 def list_bookings(event_key, query: nil, state: nil, limit: nil, cursor: nil) @client.get(path(event_key, "/bookings"), compact({ "q" => query, "state" => state, "limit" => limit, "cursor" => cursor })) end |
#release(event_key, labels:, hold_id:) ⇒ Object
74 75 76 |
# File 'lib/seatlayer/inventory.rb', line 74 def release(event_key, labels:, hold_id:) @client.post(path(event_key, "/release"), { "labels" => labels, "holdId" => hold_id }) end |
#retrieve_availability(event_key) ⇒ Object
113 114 115 |
# File 'lib/seatlayer/inventory.rb', line 113 def retrieve_availability(event_key) @client.get(path(event_key, "/availability")) end |
#retrieve_booking(event_key, booking_ref) ⇒ Object
127 128 129 |
# File 'lib/seatlayer/inventory.rb', line 127 def retrieve_booking(event_key, booking_ref) @client.get(path(event_key, "/bookings/#{encode(normalise_booking_ref(booking_ref))}")) end |
#retrieve_hold(event_key, hold_id) ⇒ Object
Authoritative items and prices. Charge from this, not the browser.
70 71 72 |
# File 'lib/seatlayer/inventory.rb', line 70 def retrieve_hold(event_key, hold_id) @client.get(path(event_key, "/holds/#{encode(hold_id)}")) end |
#unblock(event_key, labels:) ⇒ Object
105 106 107 |
# File 'lib/seatlayer/inventory.rb', line 105 def unblock(event_key, labels:) @client.post(path(event_key, "/unblock"), { "labels" => labels }) end |
#unblock_all(event_key) ⇒ Object
109 110 111 |
# File 'lib/seatlayer/inventory.rb', line 109 def unblock_all(event_key) @client.post(path(event_key, "/unblock-all")) end |
#unbook(event_key, labels:, booking_ref:) ⇒ Object
Reverse a booking. Requires a key with cancel authority.
95 96 97 98 |
# File 'lib/seatlayer/inventory.rb', line 95 def unbook(event_key, labels:, booking_ref:) @client.post(path(event_key, "/unbook"), { "labels" => labels, "bookingRef" => normalise_booking_ref(booking_ref) }) end |
#update_availability(event_key, fields) ⇒ Object
117 118 119 |
# File 'lib/seatlayer/inventory.rb', line 117 def update_availability(event_key, fields) @client.post(path(event_key, "/availability"), fields) end |