Skip to content

Instantly share code, notes, and snippets.

@aleDsz
Last active September 25, 2022 19:54
Show Gist options
  • Select an option

  • Save aleDsz/1ad35a16980c1e8d31fcef0a3f614723 to your computer and use it in GitHub Desktop.

Select an option

Save aleDsz/1ad35a16980c1e8d31fcef0a3f614723 to your computer and use it in GitHub Desktop.
Elixir
case Modulo.funcao() do
{:ok, %User{role: "admin"} = user} ->
user |> faca_algo_com_admin()
{:ok, %User{role: "moderator"} = user} ->
user |> faca_algo_com_moderator()
{:ok, %User{role: "user"} = user} ->
user |> faca_algo_com_user()
{:error, reason} ->
{:error, reason}
end
defmodule A.Rules.Rates do
@moduledoc """
Calculate rates
"""
require Logger
@doc """
Calculate rates to anticipate blocked statement
Formula: `rate = [(1 + rate) ^ days] - 1`
"""
@spec get_interest_rate(rate :: Decimal.t, blocked_until :: Date.t, reference_date :: Date.t) :: {:ok, Float.t} | {:error, term}
def get_interest_rate(%Decimal{} = rate, %Date{} = blocked_until, %Date{} = reference_date) do
Logger.debug("[#{__MODULE__}] Calculating interest rate with rate: #{inspect rate}")
Logger.debug("[#{__MODULE__}] Calculating interest rate with blocked until: #{inspect blocked_until}")
Logger.debug("[#{__MODULE__}] Calculating interest rate with reference date: #{inspect reference_date}")
case Date.diff(blocked_until, reference_date) do
days when days < 0 ->
{:error, "Can't get rate for D#{inspect days}"}
0 ->
{:error, "Can't get rate for D+0"}
days when days >= 1 ->
Logger.debug("[#{__MODULE__}] Generated D+#{inspect days}")
interest_rate =
rate
|> Decimal.to_float()
|> Kernel.+(1)
|> :math.pow(days)
|> Kernel.-(1)
Logger.debug("[#{__MODULE__}] Calculated interest rate: #{inspect interest_rate}")
{:ok, interest_rate}
end
end
@doc """
Calculate rates to anticipate blocked statement and return liquid amount based on formula
Formula: `liquid_amount = amount / [[(1 + rate) ^ days] - 1] + 1]`
"""
@spec get_liquid_amount(amount :: pos_integer(), rate :: Decimal.t, blocked_until :: Date.t, reference_date :: Date.t) :: {:ok, pos_integer()} | {:error, term}
def get_liquid_amount(amount, %Decimal{} = rate, %Date{} = blocked_until, %Date{} = reference_date) when is_integer(amount) do
case get_interest_rate(rate, blocked_until, reference_date) do
{:ok, interest_rate} ->
Logger.debug("[#{__MODULE__}] Calculating liquid amount with amount: #{inspect amount}")
interest_rate =
interest_rate
|> Kernel.+(1)
Logger.debug("[#{__MODULE__}] Interest rate: #{inspect interest_rate}")
liquid_amount =
amount
|> Kernel./(interest_rate)
|> round()
Logger.debug("[#{__MODULE__}] Calculated Liquid amount: #{inspect liquid_amount}")
{:ok, liquid_amount}
{:error, reason} ->
{:error, reason}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment