Refactoring Tickets
- Tickets now independent from registration - Implemented money gem #419
This commit is contained in:
parent
5485fe0e7f
commit
5f8a8ac6d9
63 changed files with 1581 additions and 573 deletions
|
|
@ -97,7 +97,7 @@ class Ability
|
|||
can :manage, Room, conference_id: conf_ids_for_organizer + conf_ids_for_cfp
|
||||
can :manage, Sponsor, conference_id: conf_ids_for_organizer
|
||||
can :manage, SponsorshipLevel, conference_id: conf_ids_for_organizer
|
||||
can :manage, SupporterLevel, conference_id: conf_ids_for_organizer
|
||||
can :manage, Ticket, conference_id: conf_ids_for_organizer
|
||||
can :manage, Target, conference_id: conf_ids_for_organizer
|
||||
can :index, Commercial, commercialable_type: 'Conference'
|
||||
can :manage, Commercial, commercialable_type: 'Conference', commercialable_id: conf_ids_for_organizer
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ class Conference < ActiveRecord::Base
|
|||
|
||||
attr_accessible :title, :short_title, :timezone, :html_export_path,
|
||||
:start_date, :end_date, :rooms_attributes, :tracks_attributes,
|
||||
:dietary_choices_attributes, :use_dietary_choices, :use_supporter_levels,
|
||||
:supporter_levels_attributes, :social_events_attributes, :event_types_attributes,
|
||||
:dietary_choices_attributes, :use_dietary_choices,
|
||||
:tickets_attributes, :social_events_attributes, :event_types_attributes,
|
||||
:logo, :questions_attributes,
|
||||
:question_ids, :answers_attributes, :answer_ids, :difficulty_levels_attributes,
|
||||
:use_difficulty_levels, :use_vpositions, :use_vdays, :vdays_attributes,
|
||||
|
|
@ -33,12 +33,25 @@ class Conference < ActiveRecord::Base
|
|||
has_one :email_settings, dependent: :destroy
|
||||
has_one :call_for_papers, dependent: :destroy
|
||||
has_many :social_events, dependent: :destroy
|
||||
has_many :supporter_registrations, dependent: :destroy
|
||||
has_many :supporter_levels, dependent: :destroy
|
||||
has_many :ticket_purchases
|
||||
has_many :supporters, through: :ticket_purchases, source: :user
|
||||
has_many :tickets, dependent: :destroy
|
||||
has_many :dietary_choices, dependent: :destroy
|
||||
has_many :events, dependent: :destroy
|
||||
has_many :events, dependent: :destroy do
|
||||
def workshops
|
||||
where(require_registration: true, state: :confirmed)
|
||||
end
|
||||
|
||||
def confirmed
|
||||
where(state: :confirmed)
|
||||
end
|
||||
end
|
||||
has_many :event_users, through: :events
|
||||
has_many :speakers, -> { distinct }, through: :event_users, source: :user
|
||||
has_many :speakers, -> { distinct }, through: :event_users, source: :user do
|
||||
def confirmed
|
||||
joins(:events).where(events: { state: :confirmed })
|
||||
end
|
||||
end
|
||||
has_many :event_types, dependent: :destroy
|
||||
has_many :tracks, dependent: :destroy
|
||||
has_many :difficulty_levels, dependent: :destroy
|
||||
|
|
@ -62,7 +75,7 @@ class Conference < ActiveRecord::Base
|
|||
accepts_nested_attributes_for :social_events, allow_destroy: true
|
||||
accepts_nested_attributes_for :venue
|
||||
accepts_nested_attributes_for :dietary_choices, allow_destroy: true
|
||||
accepts_nested_attributes_for :supporter_levels, allow_destroy: true
|
||||
accepts_nested_attributes_for :tickets, allow_destroy: true
|
||||
accepts_nested_attributes_for :sponsorship_levels, allow_destroy: true
|
||||
accepts_nested_attributes_for :sponsors, allow_destroy: true
|
||||
accepts_nested_attributes_for :event_types, allow_destroy: true
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
class DatatableSupporters < Datatable
|
||||
def data
|
||||
arr = []
|
||||
items.each do |i|
|
||||
item = []
|
||||
if i.name.blank?
|
||||
if !i.registration.nil? && !i.registration.user.nil?
|
||||
item << i.registration.user.name
|
||||
else
|
||||
item << 'Unknown'
|
||||
end
|
||||
|
||||
else
|
||||
item << i.name
|
||||
end
|
||||
|
||||
if i.email.blank?
|
||||
if !i.registration.nil? && !i.registration.user.nil?
|
||||
item << i.registration.user.email
|
||||
else
|
||||
item << 'Unknown'
|
||||
end
|
||||
|
||||
else
|
||||
item << i.email
|
||||
end
|
||||
|
||||
item << i.supporter_level.title
|
||||
item << i.code
|
||||
item << i.code_is_valid
|
||||
arr << item
|
||||
end
|
||||
|
||||
arr
|
||||
end
|
||||
|
||||
def columns
|
||||
['name', 'email', 'name', 'name', 'name']
|
||||
end
|
||||
end
|
||||
|
|
@ -206,6 +206,14 @@ class Event < ActiveRecord::Base
|
|||
alert
|
||||
end
|
||||
|
||||
def speaker_names
|
||||
result = []
|
||||
speakers.each do |speaker|
|
||||
result.push(speaker.name)
|
||||
end
|
||||
result.to_sentence
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def abstract_limit
|
||||
|
|
|
|||
6
app/models/events_registration.rb
Normal file
6
app/models/events_registration.rb
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
class EventsRegistration < ActiveRecord::Base
|
||||
attr_accessible :registration_id, :event_id
|
||||
|
||||
belongs_to :registration
|
||||
belongs_to :event
|
||||
end
|
||||
|
|
@ -3,21 +3,21 @@ class Registration < ActiveRecord::Base
|
|||
belongs_to :conference
|
||||
belongs_to :dietary_choice
|
||||
|
||||
has_one :supporter_registration
|
||||
has_one :supporter_level, through: :supporter_registration
|
||||
has_and_belongs_to_many :social_events
|
||||
has_and_belongs_to_many :events
|
||||
has_and_belongs_to_many :qanswers
|
||||
has_and_belongs_to_many :vchoices
|
||||
|
||||
has_many :events_registrations
|
||||
has_many :workshops, through: :events_registrations, source: :event
|
||||
|
||||
attr_accessible :user_id, :conference_id, :attending_social_events, :attending_with_partner,
|
||||
:using_affiliated_lodging, :arrival, :departure, :user_attributes, :attended,
|
||||
:other_dietary_choice, :dietary_choice_id, :handicapped_access_required,
|
||||
:supporter_registration_attributes, :social_event_ids, :other_special_needs,
|
||||
:social_event_ids, :other_special_needs,
|
||||
:event_ids, :volunteer, :vchoice_ids, :qanswer_ids, :qanswers_attributes
|
||||
|
||||
accepts_nested_attributes_for :user
|
||||
accepts_nested_attributes_for :supporter_registration
|
||||
accepts_nested_attributes_for :social_events
|
||||
accepts_nested_attributes_for :qanswers
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ class Registration < ActiveRecord::Base
|
|||
|
||||
validates_uniqueness_of :user_id, scope: :conference_id, message: 'already Registered!'
|
||||
|
||||
after_create :set_week
|
||||
after_create :set_week, :subscribe_to_conference, :send_registration_mail
|
||||
|
||||
def week
|
||||
created_at.strftime('%W').to_i
|
||||
|
|
@ -38,6 +38,16 @@ class Registration < ActiveRecord::Base
|
|||
|
||||
private
|
||||
|
||||
def subscribe_to_conference
|
||||
Subscription.create(conference_id: conference.id, user_id: user.id)
|
||||
end
|
||||
|
||||
def send_registration_mail
|
||||
if conference.email_settings.send_on_registration?
|
||||
Mailbot.delay.registration_mail(conference, user)
|
||||
end
|
||||
end
|
||||
|
||||
def set_week
|
||||
self.week = created_at.strftime('%W')
|
||||
save!
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
class SupporterLevel < ActiveRecord::Base
|
||||
belongs_to :conference
|
||||
has_many :supporter_registrations
|
||||
|
||||
attr_accessible :conference, :title, :url, :description, :ticket_price, :conference_id
|
||||
end
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
class SupporterRegistration < ActiveRecord::Base
|
||||
belongs_to :supporter_level
|
||||
belongs_to :registration
|
||||
before_save :set_attributes_from_user
|
||||
|
||||
attr_accessible :registration, :supporter_level_id, :name, :email, :supporter_level, :code, :code_is_valid, :conference_id
|
||||
|
||||
def set_attributes_from_user
|
||||
self.name ||= registration.try(:user).try(:name)
|
||||
self.email ||= registration.try(:user).try(:email)
|
||||
true
|
||||
end
|
||||
end
|
||||
59
app/models/ticket.rb
Normal file
59
app/models/ticket.rb
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
class Ticket < ActiveRecord::Base
|
||||
belongs_to :conference
|
||||
has_many :ticket_purchases
|
||||
has_many :buyers, -> { distinct }, through: :ticket_purchases, source: :user
|
||||
|
||||
attr_accessible :conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price
|
||||
monetize :price_cents, with_model_currency: :price_currency
|
||||
|
||||
# This validation is for the sake of simplicity.
|
||||
# If we would allow different currencies per conference we also have to handle convertions between currencies!
|
||||
validate :tickets_of_conference_have_same_currency
|
||||
|
||||
validates :price_cents, :price_currency, :title, presence: true
|
||||
|
||||
validates_numericality_of :price_cents, greater_than: 0
|
||||
|
||||
def bought?(user)
|
||||
buyers.include?(user)
|
||||
end
|
||||
|
||||
def paid?(user)
|
||||
ticket_purchases.where(user_id: user.id, paid: false).count == 0
|
||||
end
|
||||
|
||||
def quantity_bought_by(user)
|
||||
result = ticket_purchases.where(user_id: user.id).first
|
||||
result ? result.quantity : 0
|
||||
end
|
||||
|
||||
def total_price(user)
|
||||
quantity_bought_by(user) * price
|
||||
end
|
||||
|
||||
def self.total_price(conference, user)
|
||||
tickets = Ticket.where(conference_id: conference.id)
|
||||
result = nil
|
||||
begin
|
||||
tickets.each do |ticket|
|
||||
price = ticket.total_price(user)
|
||||
if result
|
||||
result += price unless price.zero?
|
||||
else
|
||||
result = price
|
||||
end
|
||||
end
|
||||
rescue Money::Bank::UnknownRate
|
||||
result = Money.new(-1, 'USD')
|
||||
end
|
||||
result ? result : Money.new(0, 'USD')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tickets_of_conference_have_same_currency
|
||||
unless Ticket.where(conference_id: conference_id).all?{|t| t.price_currency == self.price_currency }
|
||||
errors.add(:price_currency, 'Currency is different from the exist ticktes of this conference.')
|
||||
end
|
||||
end
|
||||
end
|
||||
51
app/models/ticket_purchase.rb
Normal file
51
app/models/ticket_purchase.rb
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
class TicketPurchase < ActiveRecord::Base
|
||||
belongs_to :ticket
|
||||
belongs_to :user
|
||||
belongs_to :conference
|
||||
|
||||
attr_accessible :ticket_id, :user_id, :conference_id, :paid, :quantity
|
||||
|
||||
validates :ticket_id, :user_id, :conference_id, :quantity, presence: true
|
||||
|
||||
validates_numericality_of :quantity, greater_than: 0
|
||||
|
||||
validates_uniqueness_of :user_id,
|
||||
scope: :ticket_id,
|
||||
message: 'already bought this ticket!'
|
||||
|
||||
def self.purchase(conference, user, purchases)
|
||||
errors = []
|
||||
ActiveRecord::Base.transaction do
|
||||
conference.tickets.each do |ticket|
|
||||
quantity = purchases[ticket.id.to_s].to_i
|
||||
if ticket.bought?(user)
|
||||
purchase = update_quantity(conference, quantity, ticket, user)
|
||||
else
|
||||
purchase = purchase_ticket(conference, quantity, ticket, user)
|
||||
end
|
||||
|
||||
if purchase && !purchase.save
|
||||
errors.push(purchase.errors.full_messages)
|
||||
end
|
||||
end
|
||||
end
|
||||
errors.join('. ')
|
||||
end
|
||||
|
||||
def self.purchase_ticket(conference, quantity, ticket, user)
|
||||
purchase = new(ticket_id: ticket.id,
|
||||
conference_id: conference.id,
|
||||
user_id: user.id,
|
||||
quantity: quantity) if quantity > 0
|
||||
purchase
|
||||
end
|
||||
|
||||
def self.update_quantity(conference, quantity, ticket, user)
|
||||
purchase = TicketPurchase.where(ticket_id: ticket.id,
|
||||
conference_id: conference.id,
|
||||
user_id: user.id).first
|
||||
|
||||
purchase.quantity = quantity if quantity > 0
|
||||
purchase
|
||||
end
|
||||
end
|
||||
|
|
@ -22,6 +22,8 @@ class User < ActiveRecord::Base
|
|||
has_many :event_users, dependent: :destroy
|
||||
has_many :events, -> { uniq }, through: :event_users
|
||||
has_many :registrations, dependent: :destroy
|
||||
has_many :ticket_purchases
|
||||
has_many :tickets, through: :ticket_purchases, source: :ticket
|
||||
has_many :votes, dependent: :destroy
|
||||
has_many :voted_events, through: :votes, source: :events
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
|
|
@ -29,6 +31,13 @@ class User < ActiveRecord::Base
|
|||
|
||||
validates :name, presence: true
|
||||
|
||||
# Returns the ticket purchased ticket
|
||||
# ====Returns
|
||||
# * +TicketUser::ActiveRecord_Relation+ -> user
|
||||
def ticket(id)
|
||||
ticket_purchases.where(ticket_id: id).first
|
||||
end
|
||||
|
||||
# Searches for user based on email. Returns found user or new user.
|
||||
# ====Returns
|
||||
# * +User::ActiveRecord_Relation+ -> user
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue