Skip to content

Instantly share code, notes, and snippets.

@bhfailor
Created March 18, 2014 02:50
Show Gist options
  • Save bhfailor/9612692 to your computer and use it in GitHub Desktop.
Save bhfailor/9612692 to your computer and use it in GitHub Desktop.
fee calculation
class RegisterController < ApplicationController
# many lines deleted
def payment
# If there are no registrations done, go back to the athlete info page and start over
if session[:reg_ids].nil? or session[:reg_ids].blank?
redirect_to :action => 'athlete_info'
end
@reg = EventRegistration.find(session[:reg_ids].first) # assign the first EventRegistration object to @reg so it will be available in the view
@race = Race.find(session[:race] ) # assign the value of @race to the Race object with id equal to the value of the session key :race so it will be available to the view
# get list of extra races
@extra_races = @reg.extra_races
=begin EventRegistration#extra_races (instance method)
def extra_races
extra_races = Array.new
unless extra_regs.blank? # self.extra_regs (instance variable)
extra_regs.split(',').each do |cnd|
frace = Race.find(cnd)
extra_races << frace
end
end
extra_races # returns an Array instance or object
end
=end
#### Chrono order of events
@events_list = @reg.series_events_order(@race.id)
=begin EventRegistration#series_events_order
def series_events_order(race_id)
all_events = Array.new
all_events << race_id
unless extra_regs.blank? # self.extra_regs
extra_regs.split(',').each do |cnd|
frace = Race.find(cnd)
all_events << frace.id
end
end
events_list = Race.find(:all,:conditions => ["races.id in (#{all_events.join(',')})"],:include => :event, :order => "events.event_date ASC")
return events_list
end
=end
@total_cost = @service_fee = @entry_fee = @total_entry_fee = 0 # zero out the running sums for cost and fees as well as discount
@discount = {}
@total_discount = 0.0
session[:reg_ids].each do |reg_id| # traverse all the EventRegistration.id values in session hash
ev_reg = EventRegistration.find_by_id( reg_id )
@entry_fee += ev_reg.entry_fee
=begin EventRegistration#entry_fee
def entry_fee(with_coupon=true)
fee_value = fee(with_coupon)
fee_value += extra_races_fee
end
=end
=begin EventRegistration#fee
def fee(with_coupon=true)
entry_fee = race.current_fee(created_at).to_f # EventRegistration#race => Race.find(EventRegistration#race_id)
if with_coupon
unless coupon.blank? # self.coupon
if coupon.value.blank? and !coupon.percentage.blank?
discount = race.current_fee(created_at).to_f * (coupon.percentage / 100)
else
discount = coupon.value
end
entry_fee = entry_fee - discount
end
if entry_fee < 0
entry_fee = 0
end
end
return entry_fee
end
=end
=begin EventRegistration#extra_races_fee
# extra races fee
def extra_races_fee
fee_value = 0
#goes through each of the related
extra_races.each do | frace |
if frace.id == extra_races.last.id
#hack
fee_value += frace.current_fee(created_at).to_f
else
fee_value += frace.current_fee( created_at ).to_f
end
end
return fee_value
end
=end
@total_entry_fee += ev_reg.total_cost
@service_fee += ev_reg.total_service_fee(true, false) # coupon set to true and merchandise set to false
=begin EventRegistration#total_service_fee
# service fee on entry fee + extra races fee ( 1 + 5% )
# + service fee on merchandise cost ( 5% )
def total_service_fee(with_coupon=true, with_merchandise=true)
service_fee_t = 0
entry_fee = fee(with_coupon)
service_fee_t += FeeCalculator.service_fee(entry_fee, false, event_id)
service_fee_t += FeeCalculator.merchandise_fee(total_merchandise_cost) if with_merchandise
#goes through each of the related
extra_races.each do | frace |
if frace.id == extra_races.last.id
#hack
entry_fee = frace.current_fee( created_at ).to_f
service_fee_t += FeeCalculator.service_fee(entry_fee, false, event_id)
else
service_fee_t += FeeCalculator.race_service_fee(frace.id, true)
end
end
return service_fee_t
end
=end
=begin FeeCalculator.service_fee(entry_fee, false, event_id)
def self.service_fee(subtotal, inverse_fee=false, event_id=nil, base_fee_count=1)
subtotal = subtotal.to_f
if subtotal <= 0
0
elsif inverse_fee
included_fee(subtotal, inverse_fee, base_fee_count)
else
normal_fee(subtotal, false, base_fee_count)
end
end
=end
=begin FeeCalculator.merchandise_fee(total_merchandise_cost)
def self.merchandise_fee(subtotal)
normal_fee(subtotal, true)
end
=end
=begin FeeCalculator.race_service_fee(frace.id, true)
def self.race_service_fee(race_id,inverse_fee=false)
race = Race.find(race_id)
if race.current_fee.to_f <= 0
0
else
normal_fee(race.current_fee)
end
end
=end
=begin FeeCalculator.included_fee(subtotal, inverse_fee, base_fee_count) [private method]
def self.included_fee(subtotal, inverse_fee, base_fee_count=1)
base_fee_count = [ base_fee_count, 1 ].max
subtotal = subtotal.to_f
# calculate the service fee from the combined reg/fee
# service fee = total fee - entry revenue
# entry revenue = (total fee - 1) / 1.05
entry_revenue = ((subtotal - base_fee_count) / 1.05)
((subtotal - entry_revenue) * 100).to_i / 100.0
end
=end
=begin
def self.normal_fee(subtotal, merchandise=false, base_fee_count=1) [private method]
base_fee_count = [ base_fee_count, 1 ].max
base_fee = merchandise ? 0 : base_fee_count
fee_before_truncate = base_fee + subtotal.to_f * 0.05
((fee_before_truncate * 100).to_i / 100.0)
end
=end
if ev_reg.coupon.present?
unless ev_reg.coupon.percentage.blank?
@discount[ev_reg.race.id] = ((ev_reg.entry_fee * 100) / (100 - ev_reg.coupon.percentage)) - ev_reg.entry_fee
@total_discount += (ev_reg.entry_fee * (ev_reg.coupon.percentage / 100)).to_f
end
end
@total_cost += ev_reg.total_cost_with_service_fee(true,false).to_f
end
for race in @events_list
event = Event.find(race.event_id)
if event.id != session[:reg_event]
event_cost = RaceFeeChange.find_by_race_id(race.id)
first_event = Event.find(session[:reg_event])
end
end
if @reg.event.display_fees?
@sub_total = @total_cost - @service_fee
else
@sub_total = @total_cost
end
session[:reg_total_cost] = @total_cost
#get a bad card if it's there
@card = flash[:order].errors if flash[:order]
#set the order of object
if flash[:order].nil?
#set it the first time
@order = {}
@order.first_name = @reg.first_name
@order.last_name = @reg.last_name
@order.address = @reg.address
@order.city = @reg.city
@order.state = @reg.state
@order.none_us_state = @order.state unless @reg.country == "united_states"
@order.zip = @reg.zip
@order.country = @reg.country
@order.email = @reg.email
else
address = flash[:address]
card = flash[:order]
@order = {}
@order.first_name = card.first_name
@order.last_name = card.last_name
@order.address = address[:address1]
@order.city = address[:city]
@order.state = address[:state]
@order.none_us_state = address[:state] unless address[:state] == "US"
@order.country = flash[:country]
@order.zip = address[:zip]
@order.card_type = card.type
@order.card_number = card.number
@order.card_verification = card.verification_value
@order.email = @reg.email
end
# set registration to pending and timestamp unless it is already complete
unless @reg.status == "Completed"
@reg.status = "rm_pending"
@reg.payment_started_at ||= DateTime.now
end
session[:reg_ids].each do |reg_id|
ev_reg = EventRegistration.find_by_id( reg_id )
ev_reg.service_fee = ev_reg.total_service_fee
ev_reg.cost = ev_reg.race.current_fee(ev_reg.created_at).to_f
# handle coupon
ev_reg.apply_coupon! if ev_reg.coupon.present?
#if it's less than zero, set to 0
if ev_reg.cost < 0
ev_reg.cost = 0
end
#set the IP address
ev_reg.ip_address = request.remote_ip
# at this point there is no need to validate save because a missing team_id
# for piggybacks, which gets assign later, will cause problems
ev_reg.save(validate: false)
end
#if the total cost is 0, dont send to paypal, and set the
@reg.service_fee = @reg.total_service_fee
@reg.cost = @race.current_fee(@reg.created_at).to_f
#handle coupon if it's there
@reg.apply_coupon! if @reg.coupon.present?
#if it's less than zero, set to 0
if @reg.cost < 0
@reg.cost = 0
end
#set the IP address
@reg.ip_address = request.remote_ip
@reg.save
#create an event signup and associate it with the race
es = EventSignup.find_by_event_id_and_rm_user_id(@reg.event.id, current_user.id)
if es.nil?
es = EventSignup.create :event => @reg.event, :rm_user => current_user, :reg_type => 2
else
es.reg_type = 2
es.save
end
@reg.reload
session[:e_reg_to_reload] = @reg.id
@event = Event.find(session[:reg_event])
end
@bhfailor
Copy link
Author

I currently think that RegisterController#payment is the place where fees and other costs are calculated. I have attempted to include in commented out sections (=begin . . . =end) the EventRegistration instance methods and FeeCalculator module methods that are called. The conclusion that Alain came to as we were discussing it was that when more than one ticket was purchased on a registration, the $1 charge per ticket was not being charged. It looks like the calls to FeeCalculator can accept an argument for more than one ticket, i.e. base_fee_count values greater than 1, but it looks like only the default value of one is being used. It looks like multiple registrations are being looped over but in the case of multiple tickets this is not happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment