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