Permalink
Browse files

Merge pull request #1 from gitlaura/refactor_currency_converter

Refactor currency converter
  • Loading branch information...
2 parents 6373f50 + d3c8346 commit badb5059c066134348848c0d1031fa753e971227 @ryanzverner ryanzverner committed Jul 15, 2014
View
@@ -1,5 +0,0 @@
-class AddAmounts
- def add(amounts)
- amounts.reduce(:+)
- end
-end
View
@@ -2,31 +2,27 @@
require_relative 'transaction_parser.rb'
require_relative 'sort_by_sku.rb'
require_relative 'currency_converter.rb'
-require_relative 'add_amounts.rb'
class Calculator
- attr_reader :rates, :transactions, :sorted_transactions, :converted_amounts
+ class << self
+ def get_conversion_rates(rate_file)
+ RatesParser.parse(rate_file)
+ end
- def get_conversion_rates(rate_file)
- rates_parser = RatesParser.new
- @rates = rates_parser.parse(rate_file)
- end
+ def get_transactions(trans_file)
+ TransactionParser.parse(trans_file)
+ end
- def get_transactions(trans_file)
- transaction_parser = TransactionParser.new
- @transactions = transaction_parser.parse(trans_file)
- end
+ def sort_transactions(sku, transactions)
+ SortBySku.sort(sku, transactions)
+ end
- def sort_transactions(sku, transactions = @transactions)
- sort_by_sku = SortBySku.new
- @sorted_transactions = sort_by_sku.sort(sku, transactions)
- end
-
- def convert_transactions(to_currency, rates = @rates, sorted_transactions = @sorted_transactions)
- @converted_amounts = CurrencyConverter.new.convert(to_currency, rates, sorted_transactions)
- end
+ def convert_transactions(to_currency, rates, sorted_transactions)
+ CurrencyConverter.new(to_currency, rates).convert(sorted_transactions)
+ end
- def add_sorted_transactions(amounts = @converted_amounts)
- AddAmounts.new.add(amounts)
+ def add_sorted_transactions(amounts)
+ amounts.reduce(:+).round(2)
+ end
end
end
View
@@ -1,12 +1,14 @@
class CurrencyConverter
- def convert(to_currency, rates, transactions)
+ attr_reader :to_currency, :rates, :transactions, :amounts
+
+ def initialize(to_currency, rates)
@to_currency = to_currency
@rates = rates
- @transactions = transactions
@amounts = []
- @final_conversion_rate = 1.0
+ end
- @transactions.each do |trans|
+ def convert(transactions)
+ transactions.each do |trans|
if conversion_unnecessary?(trans)
@amounts << trans.original_amount.to_f
else
@@ -16,47 +18,41 @@ def convert(to_currency, rates, transactions)
@amounts
end
- def conversion_unnecessary?(trans, to_currency = @to_currency)
- return true if trans.original_currency == to_currency
+ def conversion_unnecessary?(trans)
+ return true if trans.original_currency == @to_currency
return false
end
- def convert_amount(original_currency, original_amount, to_currency = @to_currency, rates = @rates)
+ def convert_amount(original_currency, original_amount)
rate = get_conversion_rate(original_currency)
(rate * original_amount.to_f).round(2)
end
- def get_conversion_rate(original_currency, final_conversion_rate = @final_conversion_rate, to_currency = @to_currency, rates = @rates)
+ def get_conversion_rate(original_currency, final_conversion_rate = 1.00)
if exact_match?(original_currency)
- new_rate = calculate_final_rate(original_currency)
- return final_conversion_rate *= new_rate
- elsif from_currency_matches?(original_currency)
- final_conversion_rate *= calculate_rate(original_currency)
- new_original_currency = update_original_currency(original_currency)
+ new_rate = get_exact_matching_rate(original_currency)
+ return final_conversion_rate * new_rate.rate
+ else
+ current_rate = rate_with_same_from_currency(original_currency)
+ final_conversion_rate *= current_rate.rate
+ new_original_currency = current_rate.to_currency
get_conversion_rate(new_original_currency, final_conversion_rate)
end
end
- def exact_match?(original_currency, to_currency = @to_currency, rates = @rates)
- !(rates.select {|rate| rate.from_currency == original_currency && rate.to_currency == to_currency}).empty?
- end
-
- def calculate_final_rate(original_currency, to_currency = @to_currency, rates = @rates)
- matching_rates = rates.select {|rate| rate.from_currency == original_currency && rate.to_currency == to_currency}
- matching_rates[0].rate
+ def exact_match?(original_currency)
+ rates_with_exact_matches(original_currency).size > 0
end
- def from_currency_matches?(original_currency, to_currency = @to_currency, rates = @rates)
- !(rates.select {|rate| rate.from_currency == original_currency}).empty?
+ def get_exact_matching_rate(original_currency)
+ rates_with_exact_matches(original_currency)[0]
end
- def calculate_rate(original_currency, rates = @rates)
- matching_rates = rates.select {|rate| rate.from_currency == original_currency}
- matching_rates[0].rate
+ def rates_with_exact_matches(original_currency)
+ @rates.select {|rate| rate.from_currency == original_currency && rate.to_currency == @to_currency}
end
- def update_original_currency(original_currency, rates = @rates)
- matching_rates = rates.select {|rate| rate.from_currency == original_currency}
- matching_rates[0].to_currency
+ def rate_with_same_from_currency(original_currency)
+ (@rates.select {|rate| rate.from_currency == original_currency})[0]
end
end
View
@@ -1,9 +0,0 @@
-class Rate
- attr_accessor :from_currency, :to_currency, :rate
-
- def initialize(from_currency = nil, to_currency = nil, rate = nil)
- @from_currency = from_currency
- @to_currency = to_currency
- @rate = rate
- end
-end
View
@@ -1,62 +1,55 @@
-require_relative 'rate.rb'
+require 'ostruct'
class RatesParser
attr_reader :all_rates
- def initialize
- @all_rates = []
- end
-
- def parse(xml_file)
- file = File.open(xml_file).read
-
- file.each_line do |line|
- line.strip!
- create_new_rate if is_rate?(line)
- set_from_currency(line) if is_from_currency?(line)
- set_to_currency(line) if is_to_currency?(line)
- set_rate(line) if is_conversion?(line)
- @all_rates << @new_rate if is_end_rate?(line)
+ class << self
+
+ def parse(xml_file)
+ file = File.open(xml_file)
+ all_rates = []
+
+ file.each_line do |line|
+ line.strip!
+ @from_currency = get_from_currency(line) if is_from_currency?(line)
+ @to_currency = get_to_currency(line) if is_to_currency?(line)
+ @rate = get_rate(line) if is_conversion?(line)
+ if is_end_rate?(line)
+ new_rate = OpenStruct.new(:from_currency => @from_currency, :to_currency => @to_currency, :rate => @rate)
+ all_rates << new_rate
+ end
+ end
+ all_rates
end
-
- @all_rates
- end
-
- private
- def is_rate?(line)
- line[1..5] == "rate>"
- end
+ private
- def is_from_currency?(line)
- line[1..4] == "from"
- end
-
- def is_to_currency?(line)
- line[1..2] == "to"
- end
+ def is_from_currency?(line)
+ line[1..4] == "from"
+ end
- def is_conversion?(line)
- line[1..3] == "con"
- end
+ def is_to_currency?(line)
+ line[1..2] == "to"
+ end
- def is_end_rate?(line)
- line[1..6] == "/rate>"
- end
+ def is_conversion?(line)
+ line[1..3] == "con"
+ end
- def create_new_rate
- @new_rate = Rate.new
- end
+ def is_end_rate?(line)
+ line[1..6] == "/rate>"
+ end
- def set_from_currency(line)
- @new_rate.from_currency = line[6..8]
- end
+ def get_from_currency(line)
+ line[6..8]
+ end
- def set_to_currency(line)
- @new_rate.to_currency = line[4..6]
- end
+ def get_to_currency(line)
+ line[4..6]
+ end
- def set_rate(line)
- @new_rate.rate = line[12..17].to_f
+ def get_rate(line)
+ line[12..17].to_f
+ end
end
end
View
@@ -1,17 +1,11 @@
require_relative 'calculator.rb'
class Runner
- attr_reader :calculator
-
- def initialize
- @calculator = Calculator.new
- end
-
- def run_international_calculator(sku = "DM1210", transactions_file = "SAMPLE_TRANS.csv", rates_file = "SAMPLE_RATES.xml", final_currency = "USD")
- @calculator.get_conversion_rates(rates_file)
- @calculator.get_transactions(transactions_file)
- @calculator.sort_transactions(sku)
- @calculator.convert_transactions(final_currency)
- @calculator.add_sorted_transactions
+ def run_international_calculator(sku, transactions_file, rates_file, final_currency)
+ rates = Calculator.get_conversion_rates(rates_file)
+ transactions = Calculator.get_transactions(transactions_file)
+ sorted_transactions = Calculator.sort_transactions(sku, transactions)
+ converted_totals = Calculator.convert_transactions(final_currency,rates,sorted_transactions)
+ Calculator.add_sorted_transactions(converted_totals)
end
end
View
@@ -1,5 +1,5 @@
class SortBySku
- def sort(sku, transactions)
+ def self.sort(sku, transactions)
output = []
transactions.each do |trans|
if trans.sku == sku
View
@@ -1,9 +0,0 @@
-class Transaction
- attr_reader :store, :sku, :original_currency, :original_amount
-
- def initialize(store, sku, amount)
- @store = store
- @sku = sku
- @original_amount, @original_currency = amount.split(" ")
- end
-end
View
@@ -1,17 +1,22 @@
-require_relative 'transaction.rb'
+require 'ostruct'
class TransactionParser
- def parse(csv_file)
- all_transactions = []
- file = File.open(csv_file).read
- file.each_line do |line|
- all_transactions << create_transaction(line)
+ class << self
+
+ def parse(csv_file)
+ all_transactions = []
+ file = File.open(csv_file).read
+ file.each_line do |line|
+ all_transactions << create_transaction(line)
+ end
+ all_transactions
+ end
+
+ def create_transaction(line)
+ store, sku, amount = line.chomp.split(",")
+ original_amount, original_currency = amount.split(" ")
+ OpenStruct.new(:store => store, :sku => sku, :original_amount => original_amount, :original_currency => original_currency)
end
- all_transactions
- end
- def create_transaction(line)
- store, sku, amount = line.chomp.split(",")
- Transaction.new(store, sku, amount)
end
end
View
@@ -1,12 +0,0 @@
-require 'add_amounts'
-
-describe "Add Amounts" do
- before(:each) do
- @add_amounts = AddAmounts.new
- end
-
- it "adds together numbers in an array" do
- expect(@add_amounts.add([5.00,6.00])).to eq(11.00)
- expect(@add_amounts.add([5.50,6.25,3.32])).to eq(15.07)
- end
-end
Oops, something went wrong.

0 comments on commit badb505

Please sign in to comment.