56 lines
1.4 KiB
Elixir
56 lines
1.4 KiB
Elixir
|
defmodule LibraryFees do
|
||
|
def datetime_from_string(string) do
|
||
|
case NaiveDateTime.from_iso8601(string) do
|
||
|
{:ok, naive_date_time} -> naive_date_time
|
||
|
_ -> :error
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def before_noon?(datetime) do
|
||
|
datetime.hour < 12
|
||
|
end
|
||
|
|
||
|
defp days_to_return(checkout_datetime) do
|
||
|
if(before_noon?(checkout_datetime), do: 28, else: 29)
|
||
|
end
|
||
|
|
||
|
def return_date(checkout_datetime) do
|
||
|
checkout_datetime
|
||
|
|> NaiveDateTime.add(days_to_return(checkout_datetime), :day)
|
||
|
|> NaiveDateTime.to_date()
|
||
|
end
|
||
|
|
||
|
def days_late(planned_return_date, actual_return_datetime) do
|
||
|
actual_return_datetime
|
||
|
|> NaiveDateTime.to_date()
|
||
|
|> Date.diff(planned_return_date)
|
||
|
|> case do
|
||
|
late_in_days when late_in_days > 0 -> late_in_days
|
||
|
_late_in_days -> 0
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def monday?(datetime) do
|
||
|
datetime
|
||
|
|> NaiveDateTime.to_date()
|
||
|
|> Date.day_of_week(:monday)
|
||
|
|> case do
|
||
|
1 -> true
|
||
|
_ -> false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def calculate_late_fee(checkout, return, rate) do
|
||
|
checkout_date_time = datetime_from_string(checkout)
|
||
|
actual_return_date_time = datetime_from_string(return)
|
||
|
planed_return_date_time = return_date(checkout_date_time)
|
||
|
|
||
|
fee = days_late(planed_return_date_time, actual_return_date_time) * rate
|
||
|
|
||
|
case monday?(actual_return_date_time) do
|
||
|
true -> floor(fee * 0.5)
|
||
|
_ -> fee
|
||
|
end
|
||
|
end
|
||
|
end
|