47 lines
1.3 KiB
Elixir
47 lines
1.3 KiB
Elixir
defmodule TaxCalculator do
|
|
|
|
def calculate_tax_from_file(order_filename) do
|
|
calculate_tax_from_file(order_filename, [ NC: 0.075, TX: 0.08 ])
|
|
end
|
|
|
|
def calculate_tax_from_file(order_filename, tax_rates) do
|
|
read(order_filename)
|
|
|> Stream.map(&TaxCalculator.parse/1)
|
|
|> calculate_tax(tax_rates)
|
|
|> Enum.to_list
|
|
end
|
|
|
|
def read(filename) do
|
|
{:ok, file} = File.open(filename)
|
|
data = IO.read(file, :line)
|
|
IO.stream(file, :line)
|
|
end
|
|
|
|
def parse(line) do
|
|
regex = ~r/(?<id>\d*?),:(?<ship_to>\w{2}),(?<net_amount>.*?)$/
|
|
named_captures = Regex.named_captures(regex, line)
|
|
|
|
[
|
|
id: String.to_integer(named_captures["id"]),
|
|
ship_to: String.to_atom(named_captures["ship_to"]),
|
|
net_amount: String.to_float(named_captures["net_amount"])
|
|
]
|
|
end
|
|
|
|
def calculate_tax(orders, tax_rates) do
|
|
for order <- orders,
|
|
do:
|
|
Keyword.merge(
|
|
order,
|
|
TaxCalculator.calculate_total_amount(tax_rates[order[:ship_to]], order[:net_amount])
|
|
)
|
|
end
|
|
|
|
def calculate_total_amount(nil, net_amount), do: [total_amount: Float.round(net_amount, 2)]
|
|
|
|
def calculate_total_amount(tax_rate, net_amount) do
|
|
total_amount = (1 + tax_rate) * net_amount
|
|
[total_amount: Float.round(total_amount, 2)]
|
|
end
|
|
end
|