2018-04-04 10:18:51 -07:00
# frozen_string_literal: true
2017-09-05 22:23:34 +03:00
class TicketPurchase < ApplicationRecord
2014-08-28 15:21:05 +02:00
belongs_to :ticket
belongs_to :user
belongs_to :conference
2017-06-22 18:14:13 +05:30
belongs_to :payment
2014-08-28 15:21:05 +02:00
validates :ticket_id , :user_id , :conference_id , :quantity , presence : true
2017-08-12 03:01:36 +05:30
validate :one_registration_ticket_per_user
validate :registration_ticket_already_purchased , on : :create
2017-03-28 21:47:17 +02:00
validates :quantity , numericality : { greater_than : 0 }
2014-08-28 15:21:05 +02:00
2014-12-05 16:04:34 +01:00
delegate :title , to : :ticket
delegate :description , to : :ticket
delegate :price , to : :ticket
delegate :price_cents , to : :ticket
delegate :price_currency , to : :ticket
2017-06-03 16:05:59 +05:30
has_many :physical_tickets
2016-07-27 19:41:42 +05:30
scope :paid , - > { where ( paid : true ) }
scope :unpaid , - > { where ( paid : false ) }
2017-03-28 21:47:17 +02:00
scope :by_conference , - > ( conference ) { where ( conference_id : conference . id ) }
scope :by_user , - > ( user ) { where ( user_id : user . id ) }
2016-07-27 19:41:42 +05:30
2017-04-19 16:47:59 +03:00
after_create :set_week
2014-08-28 15:21:05 +02:00
def self . purchase ( conference , user , purchases )
errors = [ ]
2017-08-12 03:01:36 +05:30
if count_purchased_registration_tickets ( conference , purchases ) > 1
errors . push ( 'You cannot buy more than one registration tickets.' )
else
ActiveRecord :: Base . transaction do
conference . tickets . each do | ticket |
quantity = purchases [ ticket . id . to_s ] . to_i
# if the user bought the ticket and is still unpaid, just update the quantity
purchase = if ticket . bought? ( user ) && ticket . unpaid? ( user )
update_quantity ( conference , quantity , ticket , user )
else
purchase_ticket ( conference , quantity , ticket , user )
end
2018-04-04 10:18:51 -07:00
errors . push ( purchase . errors . full_messages ) if purchase && ! purchase . save
2014-08-28 15:21:05 +02:00
end
end
end
errors . join ( '. ' )
end
def self . purchase_ticket ( conference , quantity , ticket , user )
2016-08-02 01:37:55 +05:30
if quantity > 0
2016-11-22 14:43:59 +05:30
purchase = new ( ticket_id : ticket . id ,
conference_id : conference . id ,
user_id : user . id ,
2017-09-25 00:38:20 +05:30
quantity : quantity ,
amount_paid : ticket . price )
2017-06-03 16:05:59 +05:30
purchase . pay ( nil ) if ticket . price_cents . zero?
2016-08-02 01:37:55 +05:30
end
2014-08-28 15:21:05 +02:00
purchase
end
def self . update_quantity ( conference , quantity , ticket , user )
purchase = TicketPurchase . where ( ticket_id : ticket . id ,
conference_id : conference . id ,
2016-07-27 19:41:42 +05:30
user_id : user . id ,
paid : false ) . first
2014-08-28 15:21:05 +02:00
purchase . quantity = quantity if quantity > 0
purchase
end
2017-06-03 16:05:59 +05:30
2018-03-24 01:24:49 +05:00
# Total amount
def self . total
sum ( 'amount_paid * quantity' )
end
2017-06-03 16:05:59 +05:30
def pay ( payment )
2018-04-04 10:18:51 -07:00
update ( paid : true , payment : payment )
2017-06-03 16:05:59 +05:30
PhysicalTicket . transaction do
quantity . times { physical_tickets . create }
end
2017-07-17 21:22:53 +05:30
Mailbot . ticket_confirmation_mail ( self ) . deliver_later
2017-06-03 16:05:59 +05:30
end
2017-08-12 03:01:36 +05:30
def one_registration_ticket_per_user
2018-04-04 10:18:51 -07:00
errors . add ( :quantity , 'cannot be greater than one for registration tickets.' ) if ticket . try ( :registration_ticket? ) && quantity != 1
2017-08-12 03:01:36 +05:30
end
def registration_ticket_already_purchased
2018-04-04 10:18:51 -07:00
errors . add ( :quantity , 'cannot be greater than one for registration tickets.' ) if ticket . try ( :registration_ticket? ) && user . tickets . for_registration ( conference ) . present?
2017-08-12 03:01:36 +05:30
end
2014-08-28 15:21:05 +02:00
end
2017-04-19 16:47:59 +03:00
private
def set_week
self . week = created_at . strftime ( '%W' )
save!
end
2017-08-12 03:01:36 +05:30
def count_purchased_registration_tickets ( conference , purchases )
conference . tickets . for_registration . inject ( 0 ) do | sum , registration_ticket |
sum + purchases [ registration_ticket . id . to_s ] . to_i
end
end