Packages

Money functions for operations on and localization of a money data type with support for ISO 4217 currencies and ISO 24165 digial tokens (crypto currencies).

Retired package: Deprecated

Current section

Files

Jump to
ex_money lib money conversion.ex
Raw

lib/money/conversion.ex

defmodule Money.Currency.Conversion do
@moduledoc false
defmacro __using__(_opts) do
quote location: :keep do
alias Cldr.Currency
@doc """
Convert `money` from one currency to another.
* `money` is a %Money{} struct
* `currency` is a valid currency code. An exception is raised if the
currency code is invalid or if there is no known exchange rate.
* `rates` is a `Map` of currency rates where the map key is an upcase
atom and the value is a decimal convertion factor. The default is the
latest available exchange rates from [Open Exchange Rates](http://openexchangerates.org)
`to_currency` converts one money amount to another currency via a map of
currency conversion values.
##Example
#> Money.to_currency Money.new(:USD, 100), :AUD
"""
def to_currency(money, to_currency, rates \\ Money.ExchangeRates.latest_rates())
def to_currency(%Money{currency: currency} = money, to_currency, rates)
when currency == to_currency do
money
end
def to_currency(%Money{} = money, to_currency, %{} = rates)
when is_atom(to_currency) do
to_currency(money, to_currency, {:ok, rates })
end
def to_currency(%Money{currency: currency, amount: amount}, to_currency, {:ok, rates})
when is_atom(to_currency) do
validate_currency_code!(to_currency)
validate_rate_exists!(to_currency, rates)
base_rate = rates[currency]
conversion_rate = rates[to_currency]
converted_amount = amount
|> Decimal.div(base_rate)
|> Decimal.mult(conversion_rate)
Money.new(converted_amount, to_currency)
end
def to_currency(%Money{currency: currency, amount: amount}, to_currency, :error) do
:error
end
defp validate_rate_exists!(currency, rates) do
if is_nil(rates[currency]) do
raise Money.ExchangeRateError, "No exchange rate is available for currency #{inspect currency}"
end
end
end
end
end