Class: SeatLayer::Inventory

Inherits:
Resource show all
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

Methods inherited from Resource

#initialize

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).



80
81
82
# File 'lib/seatlayer/inventory.rb', line 80

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, idempotency_key: nil) ⇒ Object



63
64
65
66
# File 'lib/seatlayer/inventory.rb', line 63

def book(event_key, hold_id: nil, labels: nil, booking_ref: nil, idempotency_key: nil)
  body = compact({ "holdId" => hold_id, "labels" => labels, "bookingRef" => booking_ref })
  @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, 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.



37
38
39
40
41
42
# File 'lib/seatlayer/inventory.rb', line 37

def book_best_available(event_key, qty:, booking_ref:, category_key: nil,
                        zone_id: nil, idempotency_key: nil)
  body = compact({ "qty" => qty, "bookingRef" => booking_ref,
                   "categoryKey" => category_key, "zoneId" => zone_id })
  @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



68
69
70
71
72
# File 'lib/seatlayer/inventory.rb', line 68

def box_office_book(event_key, labels:, booking_ref:, idempotency_key: nil)
  @client.post(path(event_key, "/box-book"),
               { "labels" => labels, "bookingRef" => 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.



50
51
52
# File 'lib/seatlayer/inventory.rb', line 50

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, idempotency_key: nil) ⇒ Object



14
15
16
17
18
19
# File 'lib/seatlayer/inventory.rb', line 14

def hold(event_key, labels: nil, selections: nil, ttl_ms: nil,
         replace_hold_id: nil, idempotency_key: nil)
  body = compact({ "labels" => labels, "selections" => selections,
                   "ttlMs" => ttl_ms, "replaceHoldId" => replace_hold_id })
  @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, 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.



26
27
28
29
30
31
# File 'lib/seatlayer/inventory.rb', line 26

def hold_best_available(event_key, qty:, category_key: nil, zone_id: nil,
                        ttl_ms: nil, idempotency_key: nil)
  body = compact({ "qty" => qty, "categoryKey" => category_key,
                   "zoneId" => zone_id, "ttlMs" => ttl_ms })
  @client.post(path(event_key, "/best-available"), body, idempotency_key: idempotency_key)
end

#release(event_key, labels:, hold_id:) ⇒ Object



59
60
61
# File 'lib/seatlayer/inventory.rb', line 59

def release(event_key, labels:, hold_id:)
  @client.post(path(event_key, "/release"), { "labels" => labels, "holdId" => hold_id })
end

#retrieve_availability(event_key) ⇒ Object



92
93
94
# File 'lib/seatlayer/inventory.rb', line 92

def retrieve_availability(event_key)
  @client.get(path(event_key, "/availability"))
end

#retrieve_hold(event_key, hold_id) ⇒ Object

Authoritative items and prices. Charge from this, not the browser.



55
56
57
# File 'lib/seatlayer/inventory.rb', line 55

def retrieve_hold(event_key, hold_id)
  @client.get(path(event_key, "/holds/#{encode(hold_id)}"))
end

#unblock(event_key, labels:) ⇒ Object



84
85
86
# File 'lib/seatlayer/inventory.rb', line 84

def unblock(event_key, labels:)
  @client.post(path(event_key, "/unblock"), { "labels" => labels })
end

#unblock_all(event_key) ⇒ Object



88
89
90
# File 'lib/seatlayer/inventory.rb', line 88

def unblock_all(event_key)
  @client.post(path(event_key, "/unblock-all"))
end

#unbook(event_key, labels:) ⇒ Object

Reverse a booking. Requires a key with cancel authority.



75
76
77
# File 'lib/seatlayer/inventory.rb', line 75

def unbook(event_key, labels:)
  @client.post(path(event_key, "/unbook"), { "labels" => labels })
end

#update_availability(event_key, fields) ⇒ Object



96
97
98
# File 'lib/seatlayer/inventory.rb', line 96

def update_availability(event_key, fields)
  @client.post(path(event_key, "/availability"), fields)
end