Created
March 18, 2014 02:50
-
-
Save bhfailor/9612692 to your computer and use it in GitHub Desktop.
fee calculation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.