Class: Ticket

Inherits:
ActiveRecord::Base
  • Object
show all
Extended by:
ActionView::Helpers::TextHelper
Includes:
ActiveRecord::Transitions, Ext::Integrations::Ticket, Ext::Resellable::Ticket, Ext::Uuid, Locker, Pricing, SaleTransitions, Transfers
Defined in:
app/models/ticket.rb

Defined Under Namespace

Modules: Foundry, Locker, Pricing, Reporting, Reports, SaleTransitions, Transfers Classes: Glance, QRCode, Template, TicketAlreadyValidated

Constant Summary

Constants included from Ext::Uuid

Ext::Uuid::PREFIX

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Ext::Uuid

included, #set_uuid, uuid

Methods included from SaleTransitions

#put_on_sale, #take_off_sale

Methods included from Transfers

#comp_to, #exchange_to, #return!, #sell_to

Methods included from Pricing

#change_price, #exchange_prices_from, #prepare_for_cart_change!, #prepare_for_discount!, #prepare_for_pass!, #remove_from_cart, #reset_price!, #set_cart_price

Methods included from Locker

#locked?

Methods included from Ext::Integrations::Ticket

#record_comp, #record_exchange, #record_sale

Methods included from Ext::Resellable::Ticket

#reseller

Class Method Details

.available(params = {}, limit = 4) ⇒ Object

Unfortunately named. This will return available tickets, not a count of available tickets as is the idiom elsewhere in the app



112
113
114
115
116
117
# File 'app/models/ticket.rb', line 112

def self.available(params = {}, limit = 4)
  conditions = params.dup
  conditions[:state] ||= :on_sale
  conditions[:cart_id] = nil
  where(conditions).limit(limit)
end

.build_one(show, section, quantity, on_sale = false) ⇒ Object

This method does not refresh show stats Callers should do that manually with show.delay.refresh_stats



220
221
222
223
224
225
226
227
228
229
230
# File 'app/models/ticket.rb', line 220

def self.build_one(show, section, quantity, on_sale = false)
  t = Ticket.new({
    :venue => show.event.venue.name,
    :section => section,
  })
  t.show = show
  t.organization = show.organization
  t.set_uuid
  t.state = 'on_sale' if on_sale
  t
end

.create_many(show, section, quantity, on_sale = false) ⇒ Object

Bulk creation of tickets should use this method to ensure all tickets are created the same Reminder that this returns a ActiveRecord::Import::Result, not an array of tickets



205
206
207
208
209
210
211
212
213
214
# File 'app/models/ticket.rb', line 205

def self.create_many(show, section, quantity, on_sale = false)
  new_tickets = []
  quantity.times do
    new_tickets << build_one(show, section, quantity, on_sale)
  end
  
  result = Ticket.import(new_tickets)
  show.refresh_stats
  result
end

.realized_feeObject



147
148
149
# File 'app/models/ticket.rb', line 147

def self.realized_fee
  0
end

.sold_after(datetime) ⇒ Object



37
38
39
# File 'app/models/ticket.rb', line 37

def self.sold_after(datetime)
  sold.where("sold_at > ?", datetime)
end

.sold_before(datetime) ⇒ Object



41
42
43
# File 'app/models/ticket.rb', line 41

def self.sold_before(datetime)
  sold.where("sold_at < ?", datetime)
end

.to_sentence(tickets) ⇒ Object



94
95
96
97
98
99
100
101
102
# File 'app/models/ticket.rb', line 94

def self.to_sentence(tickets)
  if tickets.any?
    shows_string = tickets.map(&:show).uniq.length > 1 ? ", multiple shows" : " on " + I18n.localize(tickets.first.show.datetime_local_to_event, :format => :day_time_at)
    events_string = tickets.map(&:show).map(&:event).uniq.length > 1 ? "multiple events" : tickets.first.show.event.name + shows_string
    pluralize(tickets.length, "ticket") + " to " + events_string
  else
    "No tickets"
  end
end

.unsoldObject



90
91
92
# File 'app/models/ticket.rb', line 90

def self.unsold
  where(:state => [:off_sale, :on_sale])
end

Instance Method Details

#as_json(options = {}) ⇒ Object



86
87
88
# File 'app/models/ticket.rb', line 86

def as_json(options = {})
  super(options).merge!({:ticket_type => ticket_type}).except!("section_id", "buyer_id", "show_id", "ticket_type_id", "cart_id", "discount_id", "organization_id", "old_mongo_id")
end

#can_be_assigned_to(ticket_type) ⇒ Object



141
142
143
144
145
# File 'app/models/ticket.rb', line 141

def can_be_assigned_to(ticket_type)
  return false if ticket_type.nil?
  ticket_type = TicketType.find(ticket_type) unless ticket_type.is_a? TicketType
  self.show == ticket_type.show
end

#committed?Boolean

Returns:

  • (Boolean)


171
172
173
# File 'app/models/ticket.rb', line 171

def committed?
  sold? or comped?
end

#compable?Boolean

Returns:

  • (Boolean)


187
188
189
# File 'app/models/ticket.rb', line 187

def compable?
  on_sale? or off_sale?
end

#datetimeObject



67
68
69
# File 'app/models/ticket.rb', line 67

def datetime
  show.datetime_local_to_event
end

#destroyObject



195
196
197
# File 'app/models/ticket.rb', line 195

def destroy
  super if destroyable?
end

#destroyable?Boolean

Returns:

  • (Boolean)


183
184
185
# File 'app/models/ticket.rb', line 183

def destroyable?
  !sold? and !comped? and items.empty?
end

#exchangeable?Boolean

Returns:

  • (Boolean)


163
164
165
# File 'app/models/ticket.rb', line 163

def exchangeable?
  !expired? and sold?
end

#expired?Boolean

Returns:

  • (Boolean)


155
156
157
# File 'app/models/ticket.rb', line 155

def expired?
  datetime < DateTime.now
end

#generate_qr_codeObject



232
233
234
235
236
237
238
239
240
241
242
243
# File 'app/models/ticket.rb', line 232

def generate_qr_code
  file = Tempfile.new(['qr-code', '.png'])
  QRCode.new(self, sold_item.try(:order)).render(file)
  self.qr_code = file

  # If we don't save the ticket here, paperclip will leak a file handle.
  # Even though we close our Tempfile below, paperclip copies that into
  # another Tempfile, and only closes the handle when the ticket is saved.
  save

  file.close
end

#notesObject



137
138
139
# File 'app/models/ticket.rb', line 137

def notes
  sold_item.try(:order).try(:notes)
end

#off_saleable?Boolean

Returns:

  • (Boolean)


179
180
181
# File 'app/models/ticket.rb', line 179

def off_saleable?
  on_sale?
end

#on_saleable?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'app/models/ticket.rb', line 175

def on_saleable?
  !(sold? or comped?)
end

#order_summary_descriptionObject



104
105
106
# File 'app/models/ticket.rb', line 104

def order_summary_description
  self.try(:ticket_type).try(:name) || ""
end

#priceObject

This is here so that Item.for can add tickets. Ticket is composing what it means to be turned into an item



82
83
84
# File 'app/models/ticket.rb', line 82

def price
  ticket_type_price
end

#realized_feeObject



151
152
153
# File 'app/models/ticket.rb', line 151

def realized_fee
  self.class.realized_fee
end

#refundable?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'app/models/ticket.rb', line 159

def refundable?
  sold?
end

#repriceable?Boolean

Returns:

  • (Boolean)


199
200
201
# File 'app/models/ticket.rb', line 199

def repriceable?
  not committed?
end

#resellable?Boolean

Returns:

  • (Boolean)


191
192
193
# File 'app/models/ticket.rb', line 191

def resellable?
  on_sale?
end

#returnable?Boolean

Returns:

  • (Boolean)


167
168
169
# File 'app/models/ticket.rb', line 167

def returnable?
  !expired?
end

#settled_itemObject



123
124
125
# File 'app/models/ticket.rb', line 123

def settled_item
  @settled_item ||= items.select(&:settled?).first
end

#settlement_idObject



119
120
121
# File 'app/models/ticket.rb', line 119

def settlement_id
  settled_item.settlement_id unless settled_item.nil?
end

#sold_itemObject



127
128
129
130
131
# File 'app/models/ticket.rb', line 127

def sold_item
  items.select(&:purchased?).first ||
  items.select(&:settled?).first ||
  items.select(&:comped?).first
end

#special_instructionsObject



133
134
135
# File 'app/models/ticket.rb', line 133

def special_instructions
  sold_item.try(:order).try(:special_instructions)
end

#ticket_type_priceObject

This intentionally returns nil if the ticket does not yet have a ticket_type assigned



74
75
76
# File 'app/models/ticket.rb', line 74

def ticket_type_price
  self.ticket_type.try(:price)
end

#unvalidate_ticket!Object



259
260
261
262
263
264
265
266
267
# File 'app/models/ticket.rb', line 259

def unvalidate_ticket!
  if validated?
    Ticket.transaction do
      action.destroy unless self.action.tickets.where(validated:true).count > 1
      self.validated = false
      save
    end
  end
end

#validate_ticket!(user = nil) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
# File 'app/models/ticket.rb', line 247

def validate_ticket!(user = nil)
  if committed? && !validated?
    Ticket.transaction do
      self.action = GoAction.for(self.show, self.buyer, Time.now) do |go_action|
        go_action.creator = user
      end
      self.validated = true
      save
    end
  end
end