Skip to content

Commit

Permalink
Moved calculateDues to helper and added dues to WFC export (thewca#8158)
Browse files Browse the repository at this point in the history
* Moved calculateDues to helper and added dues to WFC export

* Moved dues calculator to lib

* Changes in arguments of dues calculator

* Some more fixes

* Added test case

* Review changes

* Review changes

* Test fail fixed
  • Loading branch information
danieljames-dj authored Oct 14, 2023
1 parent 2f12efb commit 275fc2a
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 41 deletions.
36 changes: 5 additions & 31 deletions WcaOnRails/app/controllers/competitions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -414,31 +414,11 @@ def time_until_competition

def calculate_dues
country_iso2 = Country.find_by(id: params[:country_id])&.iso2
country_band = CountryBand.find_by(iso2: country_iso2)&.number

update_exchange_rates_if_needed
input_money_us_dollars = Money.new(params[:entry_fee_cents].to_i, params[:currency_code]).exchange_to("USD").amount

registration_fee_dues_us_dollars = input_money_us_dollars * CountryBand::PERCENT_REGISTRATION_FEE_USED_FOR_DUE_AMOUNT
country_band_dues_us_dollars = CountryBand::BANDS[country_band][:value] if country_band.present? && country_band > 0

# times 100 because later currency conversions require lowest currency subunit, which is cents for USD
price_per_competitor_us_cents = [registration_fee_dues_us_dollars, country_band_dues_us_dollars].compact.max * 100

if ActiveRecord::Type::Boolean.new.cast(params[:competitor_limit_enabled])
estimated_dues_us_cents = price_per_competitor_us_cents * params[:competitor_limit].to_i
estimated_dues = Money.new(estimated_dues_us_cents, "USD").exchange_to(params[:currency_code]).format

render json: {
dues_value: estimated_dues,
}
else
price_per_competitor = Money.new(price_per_competitor_us_cents, "USD").exchange_to(params[:currency_code]).format

render json: {
dues_value: price_per_competitor,
}
end
multiplier = ActiveRecord::Type::Boolean.new.cast(params[:competitor_limit_enabled]) ? params[:competitor_limit].to_i : 1
total_dues = DuesCalculator.dues_for_n_competitors(country_iso2, params[:base_entry_fee_lowest_denomination].to_i, params[:currency_code], multiplier)
render json: {
dues_value: total_dues.present? ? total_dues.format : nil,
}
end

def show
Expand Down Expand Up @@ -640,12 +620,6 @@ def for_senior
params[:commit] == "Confirm"
end

private def update_exchange_rates_if_needed
if !Money.default_bank.rates_updated_at || Money.default_bank.rates_updated_at < 1.day.ago
Money.default_bank.update_rates
end
end

private def competition_params
permitted_competition_params = [
:receive_registration_emails,
Expand Down
5 changes: 5 additions & 0 deletions WcaOnRails/app/models/competition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1997,4 +1997,9 @@ def find_round_for(event_id, round_type_id, format_id = nil)
(format_id.nil? || format_id == r.format_id)
end
end

def dues_per_competitor_in_usd
dues = DuesCalculator.dues_per_competitor_in_usd(self.country_iso2, self.base_entry_fee_lowest_denomination.to_i, self.currency_code)
dues.present? ? dues : 0
end
end
13 changes: 6 additions & 7 deletions WcaOnRails/app/views/competitions/_competition_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,14 @@
competitor_limit: compLimit,
currency_code: currencyCode,
country_id: countryId,
entry_fee_cents: entryFee,
base_entry_fee_lowest_denomination: entryFee,
},
success: function(data) {
if (compLimitEnabled) {
if (data.dues_value == null) {
<% # i18n-tasks-use t('competitions.competition_form.dues_estimate.ajax_error') %>
$('#dues_estimate').html("<b>" + I18n.t('competitions.competition_form.dues_estimate.ajax_error') + "</b>");
}
else if (compLimitEnabled) {
<% # i18n-tasks-use t('competitions.competition_form.dues_estimate.calculated') %>
$('#dues_estimate').html("<b>" + I18n.t('competitions.competition_form.dues_estimate.calculated', {limit: compLimit, estimate: data.dues_value}) + " (" + currencyCode + ")</b>");
}
Expand All @@ -275,11 +279,6 @@
$('#dues_estimate').html("<b>" + I18n.t('competitions.competition_form.dues_estimate.per_competitor', {estimate: data.dues_value}) + " (" + currencyCode + ")</b>");
}
},
error: function(){
// This error will occur if there are no available exchange rates for the selected currency, and there are quite a few of such currencies.
<% # i18n-tasks-use t('competitions.competition_form.dues_estimate.ajax_error') %>
$('#dues_estimate').html("<b>" + I18n.t('competitions.competition_form.dues_estimate.ajax_error') + "</b>");
}
});
}
Expand Down
5 changes: 3 additions & 2 deletions WcaOnRails/app/views/wfc/competition_export.csv.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"Start", "End", "Announced", "Posted",
"Link on WCA", "Competitors", "Delegates",
"Currency Code", "Base Registration Fee", "Currency Subunit",
"Championship Type", "Exempt from WCA Dues", "Organizers"
"Championship Type", "Exempt from WCA Dues", "Organizers", "Calculated Dues"
] %>
<%= CSV.generate_line(headers, col_sep: "\t").html_safe -%>
<% @competitions.each do |c| %>
Expand All @@ -13,6 +13,7 @@
c.start_date, c.end_date, c.announced_at, c.results_posted_at,
competition_url(c.id), c.num_competitors, c.delegates.reject(&:trainee_delegate?).map(&:name).sort.join(","),
c.currency_code, c.base_entry_fee_lowest_denomination, Money::Currency.new(c.currency_code).subunit_to_unit,
c.championships.map(&:championship_type).sort.join(","), c.exempt_from_wca_dues?, c.organizers.map(&:name).sort.join(",")
c.championships.map(&:championship_type).sort.join(","), c.exempt_from_wca_dues?, c.organizers.map(&:name).sort.join(","),
c.dues_per_competitor_in_usd * c.num_competitors
], col_sep: "\t").html_safe -%>
<% end %>
36 changes: 36 additions & 0 deletions WcaOnRails/lib/dues_calculator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

module DuesCalculator
def self.update_exchange_rates_if_needed
if !Money.default_bank.rates_updated_at || Money.default_bank.rates_updated_at < 1.day.ago
Money.default_bank.update_rates
end
end

def self.dues_for_n_competitors(country_iso2, base_entry_fee_lowest_denomination, currency_code, n)
dues_per_competitor_in_usd_money = dues_per_competitor_in_usd(country_iso2, base_entry_fee_lowest_denomination, currency_code)
if dues_per_competitor_in_usd_money.present?
(dues_per_competitor_in_usd_money * n).exchange_to(currency_code)
else
nil
end
rescue CurrencyUnavailable
nil
end

def self.dues_per_competitor_in_usd(country_iso2, base_entry_fee_lowest_denomination, currency_code)
country_band = CountryBand.find_by(iso2: country_iso2)&.number

DuesCalculator.update_exchange_rates_if_needed
input_money_us_dollars = Money.new(base_entry_fee_lowest_denomination, currency_code).exchange_to("USD")

registration_fee_dues_us_dollars = input_money_us_dollars * CountryBand::PERCENT_REGISTRATION_FEE_USED_FOR_DUE_AMOUNT
country_band_dues_us_dollars = country_band.present? && country_band > 0 ? CountryBand::BANDS[country_band][:value] : 0
# times 100 because Money require lowest currency subunit, which is cents for USD
country_band_dues_us_dollars_money = Money.new(country_band_dues_us_dollars * 100, "USD")

[registration_fee_dues_us_dollars, country_band_dues_us_dollars_money].max
rescue Money::Currency::UnknownCurrency, CurrencyUnavailable
nil
end
end
3 changes: 2 additions & 1 deletion WcaOnRails/spec/views/wfc/competition_export.csv.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"Start", "End", "Announced", "Posted",
"Link on WCA", "Competitors", "Delegates",
"Currency Code", "Base Registration Fee", "Currency Subunit",
"Championship Type", "Exempt from WCA Dues", "Organizers"
"Championship Type", "Exempt from WCA Dues", "Organizers",
"Calculated Dues"
]

assign(:competitions, [])
Expand Down

0 comments on commit 275fc2a

Please sign in to comment.