Packages
ex_money
0.2.0
6.1.1
6.1.0
6.0.0
6.0.0-rc.0
5.24.2
5.24.1
5.24.0
retired
5.23.0
5.22.0
5.21.0
5.20.0
5.19.2
5.19.1
5.19.0
5.18.0
5.17.2
5.17.1
5.17.0
5.16.1
5.16.0
5.15.4
5.15.3
5.15.2
5.15.1
5.15.0
5.14.1
5.13.0
5.12.4
5.12.3
5.12.2
5.12.1
5.12.0
5.11.0
5.10.0
5.9.0
5.8.0
5.7.4
5.7.3
5.7.2
5.7.1
5.7.0
5.6.0
5.5.5
5.5.4
5.5.3
5.5.2
5.5.1
5.5.0
5.4.1
5.4.0
5.4.0-rc.0
5.3.2
5.3.1
5.3.0
5.2.1
5.2.0
5.1.0
5.0.2
5.0.1
5.0.0
retired
4.4.3
4.4.2
retired
4.4.1
4.4.0
4.3.0
4.2.2
4.2.1
4.2.0
4.1.0
4.0.0
3.4.4
3.4.3
3.4.2
3.4.1
3.4.0
3.3.1
3.3.0
3.2.4
3.2.3
3.2.2
3.2.1
3.2.0
3.1.0
3.0.0
2.12.2
2.12.1
retired
2.12.0
retired
2.11.0
2.10.0
2.9.1
2.9.0
2.8.0
2.7.3
2.7.2
2.7.1
2.7.0
2.6.1
2.6.0
2.5.0
2.4.0
2.3.0
2.2.2
2.2.1
2.2.0
2.1.0
2.1.0-rc.1
retired
2.1.0-rc.0
retired
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
1.1.3
1.1.2
1.1.1
retired
1.1.0
1.0.0
1.0.0-rc.0
retired
0.9.0
retired
0.8.5
retired
0.8.4
retired
0.8.3
retired
0.8.2
retired
0.8.1
retired
0.8.0
retired
0.7.0
retired
0.6.2
retired
0.6.1
retired
0.6.0
retired
0.5.3
retired
0.5.2
retired
0.5.1
retired
0.5.0
retired
0.4.3
retired
0.4.2
retired
0.4.1
retired
0.4.0
retired
0.3.0
retired
0.2.0
retired
0.1.7
retired
0.1.6
retired
0.1.5
retired
0.1.4
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
0.0.16
retired
0.0.15
retired
0.0.14
retired
0.0.13
retired
0.0.12
retired
0.0.11
retired
0.0.10
retired
0.0.9
retired
0.0.7
retired
0.0.6
retired
0.0.5
retired
0.0.4
retired
0.0.3
retired
0.0.2
retired
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
Current section
Files
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
* `to_currency` is a valid currency code into which the `money` is converted
* `rates` is a `Map` of currency rates where the map key is an upcase
atom and the value is a Decimal conversion factor. The default is the
latest available exchange rates returned from `Money.ExchangeRates.latest_rates()`
## Examples
Money.to_currency(Money.new(:USD, 100), :AUD, %{USD: Decimal.new(1), AUD: Decimal.new(0.7345)})
{:ok, #Money<:AUD, 73.4500>}
iex> Money.to_currency Money.new(:USD, 100) , :AUDD, %{USD: Decimal.new(1), AUD: Decimal.new(0.7345)}
{:error, {Cldr.UnknownCurrencyError, "Currency :AUDD is not known"}}
iex> Money.to_currency Money.new(:USD, 100) , :CHF, %{USD: Decimal.new(1), AUD: Decimal.new(0.7345)}
{:error, "No exchange rate is available for currency :CHF"}
"""
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{currency: currency} = money, to_currency, %{} = rates)
when is_atom(to_currency) or is_binary(to_currency) do
with {:ok, to_code} <- Money.validate_currency_code(to_currency) do
if currency == to_code, do: money, else: to_currency(money, to_currency, {:ok, rates})
else
{:error, _} = error -> error
end
end
def to_currency(%Money{currency: currency, amount: amount}, to_currency, {:ok, rates})
when is_atom(to_currency) or is_binary(to_currency) do
with {:ok, code} <- Money.validate_currency_code(to_currency),
{:ok, base_rate} <- get_rate(currency, rates),
{:ok, conversion_rate} <- get_rate(to_currency, rates) do
converted_amount =
amount
|> Decimal.div(base_rate)
|> Decimal.mult(conversion_rate)
{:ok, Money.new(to_currency, converted_amount)}
else
{:error, _} = error -> error
end
end
def to_currency(%Money{currency: currency, amount: amount}, to_currency, error) do
error
end
@doc """
Convert `money` from one currency to another and raises on error
## Examples
iex> Money.to_currency! Money.new(:USD, 100) , :AUD, %{USD: Decimal.new(1), AUD: Decimal.new(0.7345)}
#Money<:AUD, 73.4500>
Money.to_currency! Money.new(:USD, 100) , :ZZZ, %{USD: Decimal.new(1), AUD: Decimal.new(0.7345)}
** (Cldr.UnknownCurrencyError) Currency :ZZZ is not known
"""
def to_currency!(%Money{} = money, currency) do
money
|> to_currency(currency)
|> do_to_currency!
end
def to_currency!(%Money{} = money, currency, rates) do
money
|> to_currency(currency, rates)
|> do_to_currency!
end
defp do_to_currency!(result) do
case result do
{:ok, converted} -> converted
{:error, {exception, reason}} -> raise exception, reason
{:error, reason} -> raise ArgumentError, reason
end
end
defp get_rate(currency, rates) do
if rate = rates[currency] do
{:ok, rate}
else
{:error, "No exchange rate is available for currency #{inspect currency}"}
end
end
end
end
end