Money v3.2.1 Money View Source

Money implements a set of functions to store, retrieve, convert and perform arithmetic on a Money.t type that is composed of a currency code and a decimal currency amount.

Money is very opinionated in the interests of serving as a dependable library that can underpin accounting and financial applications.

This opinion expressed by ensuring that:

  1. Money must always have both a amount and a currency code.

  2. The currency code must always be valid.

  3. Money arithmetic can only be performed when both operands are of the same currency.

  4. Money amounts are represented as a Decimal.

  5. Money is serialised to the database as a custom Postgres composite type that includes both the amount and the currency. Therefore for Ecto serialization Postgres is assumed as the data store. Serialization is entirely optional and Ecto is not a package dependency.

  6. All arithmetic functions work in fixed point decimal. No rounding occurs automatically (unless expressly called out for a function).

  7. Explicit rounding obeys the rounding rules for a given currency. The rounding rules are defined by the Unicode consortium in its CLDR repository as implemented by the hex package ex_cldr. These rules define the number of fractional digits for a currency and the rounding increment where appropriate.

Link to this section Summary

Types

t()

Money is composed of an atom representation of an ISO4217 currency code and a Decimal representation of an amount

Functions

Add two Money values

Add two Money values and raise on error

Compares two Money values numerically. If the first number is greater than the second :gt is returned, if less than :lt is returned, if both numbers are equal :eq is returned

Compares two Money values numerically and raises on error

Compares two Money values numerically. If the first number is greater than the second #Integer<1> is returned, if less than Integer<-1> is returned. Otherwise, if both numbers are equal Integer<0> is returned

Compares two Money values numerically and raises on error

Returns the effective cross-rate to convert from one currency to another

Returns the effective cross-rate to convert from one currency to another

Divide a Money value by a number

Divide a Money value by a number and raise on error

Returns a boolean indicating if two Money values are equal

Returns a %Money{} struct from a currency code and a float amount, or an error tuple of the form {:error, {exception, message}}

Returns a %Money{} struct from a currency code and a float amount, or raises an exception if the currency code is invalid

Convert an integer representation of money into a Money struct

Multiply a Money value by a number

Multiply a Money value by a number and raise on error

Returns a %Money{} struct from a currency code and a currency amount or an error tuple of the form {:error, {exception, message}}

Returns a %Money{} struct from a currency code and a currency amount. Raises an exception if the current code is invalid

Parse a string and return a Money.t or an error

Calls Decimal.reduce/1 on the given Money.t()

Round a Money value into the acceptable range for the requested currency

Split a Money value into a number of parts maintaining the currency's precision and rounding and ensuring that the parts sum to the original amount

Subtract one Money value struct from another

Subtract one Money value struct from another and raise on error

Convert money from one currency to another and raises on error

Returns the amount part of a Money type as a Decimal

Returns a tuple comprising the currency code, integer amount, exponent and remainder

Returns a formatted string representation of a Money{}

Returns a formatted string representation of a Money{} or raises if there is an error

Return a zero amount Money.t in the given currency

Link to this section Types

Link to this type

currency_code() View Source
currency_code() :: atom() | String.t()

Link to this type

t() View Source
t() :: %Money{amount: Decimal.t(), currency: atom()}

Money is composed of an atom representation of an ISO4217 currency code and a Decimal representation of an amount.

Link to this section Functions

Link to this function

add(money1, money2) View Source
add(money_1 :: Money.t(), money_2 :: Money.t()) ::
  {:ok, Money.t()} | {:error, {Exception.t(), String.t()}}

Add two Money values.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • {:ok, money} or

  • {:error, reason}

Example

iex> Money.add Money.new(:USD, 200), Money.new(:USD, 100)
{:ok, Money.new(:USD, 300)}

iex> Money.add Money.new(:USD, 200), Money.new(:AUD, 100)
{:error, {ArgumentError, "Cannot add monies with different currencies. " <>
  "Received :USD and :AUD."}}

Add two Money values and raise on error.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • {:ok, money} or

  • raises an exception

Examples

iex> Money.add! Money.new(:USD, 200), Money.new(:USD, 100)
#Money<:USD, 300>

Money.add! Money.new(:USD, 200), Money.new(:CAD, 500)
** (ArgumentError) Cannot add two %Money{} with different currencies. Received :USD and :CAD.
Link to this function

cmp(money1, money2) View Source
cmp(money_1 :: Money.t(), money_2 :: Money.t()) ::
  :gt | :eq | :lt | {:error, {Exception.t(), String.t()}}

Compares two Money values numerically. If the first number is greater than the second :gt is returned, if less than :lt is returned, if both numbers are equal :eq is returned.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • :gt | :eq | :lt or

  • {:error, {Exception.t, String.t}}

Examples

iex> Money.cmp Money.new(:USD, 200), Money.new(:USD, 100)
:gt

iex> Money.cmp Money.new(:USD, 200), Money.new(:USD, 200)
:eq

iex> Money.cmp Money.new(:USD, 200), Money.new(:USD, 500)
:lt

iex> Money.cmp Money.new(:USD, 200), Money.new(:CAD, 500)
{:error,
 {ArgumentError,
  "Cannot compare monies with different currencies. Received :USD and :CAD."}}

Compares two Money values numerically and raises on error.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • :gt | :eq | :lt or

  • raises an exception

Examples

Money.cmp! Money.new(:USD, 200), Money.new(:CAD, 500)
** (ArgumentError) Cannot compare monies with different currencies. Received :USD and :CAD.
Link to this function

compare(money1, money2) View Source
compare(money_1 :: Money.t(), money_2 :: Money.t()) ::
  -1 | 0 | 1 | {:error, {Exception.t(), String.t()}}

Compares two Money values numerically. If the first number is greater than the second #Integer<1> is returned, if less than Integer<-1> is returned. Otherwise, if both numbers are equal Integer<0> is returned.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • -1 | 0 | 1 or

  • {:error, {Exception.t, String.t}}

Examples

iex> Money.compare Money.new(:USD, 200), Money.new(:USD, 100)
1

iex> Money.compare Money.new(:USD, 200), Money.new(:USD, 200)
0

iex> Money.compare Money.new(:USD, 200), Money.new(:USD, 500)
-1

iex> Money.compare Money.new(:USD, 200), Money.new(:CAD, 500)
{:error,
 {ArgumentError,
  "Cannot compare monies with different currencies. Received :USD and :CAD."}}
Link to this function

compare!(money_1, money_2) View Source

Compares two Money values numerically and raises on error.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • -1 | 0 | 1 or

  • raises an exception

Examples

Money.compare! Money.new(:USD, 200), Money.new(:CAD, 500)
** (ArgumentError) Cannot compare monies with different currencies. Received :USD and :CAD.
Link to this function

cross_rate(from, to, rates \\ Money.ExchangeRates.latest_rates()) View Source
cross_rate(
  Money.t() | currency_code(),
  currency_code(),
  Money.ExchangeRates.t() | {:ok, Money.ExchangeRates.t()}
) :: {:ok, Decimal.t()} | {:error, {Exception.t(), String.t()}}

Returns the effective cross-rate to convert from one currency to another.

Arguments

  • from is any Money.t struct returned by Cldr.Currency.new/2 or a valid currency code

  • 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 upcased atom or string and the value is a Decimal conversion factor. The default is the latest available exchange rates returned from Money.ExchangeRates.latest_rates()

Examples

Money.cross_rate(Money.new(:USD, 100), :AUD, %{USD: Decimal.new(1), AUD: Decimal.new("0.7345")})
{:ok, #Decimal<0.7345>}

Money.cross_rate Money.new(:USD, 100), :ZZZ, %{USD: Decimal.new(1), AUD: Decimal.new(0.7345)}
** (Cldr.UnknownCurrencyError) Currency :ZZZ is not known
Link to this function

cross_rate!(from, to_currency, rates \\ Money.ExchangeRates.latest_rates()) View Source

Returns the effective cross-rate to convert from one currency to another.

Arguments

  • from is any Money.t struct returned by Cldr.Currency.new/2 or a valid currency code

  • 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 upcased atom or string and the value is a Decimal conversion factor. The default is the latest available exchange rates returned from Money.ExchangeRates.latest_rates()

Examples

iex> Money.cross_rate!(Money.new(:USD, 100), :AUD, %{USD: Decimal.new(1), AUD: Decimal.new("0.7345")})
#Decimal<0.7345>

iex> Money.cross_rate!(:USD, :AUD, %{USD: Decimal.new(1), AUD: Decimal.new("0.7345")})
#Decimal<0.7345>

Money.cross_rate Money.new(:USD, 100), :ZZZ, %{USD: Decimal.new(1), AUD: Decimal.new("0.7345")}
** (Cldr.UnknownCurrencyError) Currency :ZZZ is not known
Link to this function

div(money, number) View Source
div(Money.t(), Cldr.Math.number_or_decimal()) ::
  {:ok, Money.t()} | {:error, {Exception.t(), String.t()}}

Divide a Money value by a number.

Options

  • money is any valid Money.t types returned by Money.new/2

  • number is an integer, float or Decimal.t

Note that dividing one %Money{} by another is not supported.

Returns

  • {:ok, money} or

  • {:error, reason}

Example

iex> Money.div Money.new(:USD, 200), 2
{:ok, Money.new(:USD, 100)}

iex> Money.div(Money.new(:USD, 200), "xx")
{:error, {ArgumentError, "Cannot divide money by \"xx\""}}

Divide a Money value by a number and raise on error.

Options

  • money is any valid Money.t types returned by Money.new/2

  • number is an integer, float or Decimal.t

Returns

  • a Money.t struct or

  • raises an exception

Examples

iex> Money.div Money.new(:USD, 200), 2
{:ok, Money.new(:USD, 100)}

Money.div(Money.new(:USD, 200), "xx")
** (ArgumentError) "Cannot divide money by \"xx\""]}}
Link to this function

equal?(arg1, arg2) View Source
equal?(money_1 :: Money.t(), money_2 :: Money.t()) :: boolean()

Returns a boolean indicating if two Money values are equal

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • true or false

Example

iex> Money.equal? Money.new(:USD, 200), Money.new(:USD, 200)
true

iex> Money.equal? Money.new(:USD, 200), Money.new(:USD, 100)
false
Link to this function

from_float(currency_code, amount) View Source
from_float(float() | currency_code(), float() | currency_code()) ::
  Money.t() | {:error, {Exception.t(), String.t()}}

Returns a %Money{} struct from a currency code and a float amount, or an error tuple of the form {:error, {exception, message}}.

Floats are fraught with danger in computer arithmetic due to the unexpected loss of precision during rounding. The IEEE754 standard indicates that a number with a precision of 16 digits should round-trip convert without loss of fidelity. This function supports numbers with a precision up to 15 digits and will error if the provided amount is outside that range.

Note that Money cannot detect lack of precision or rounding errors introduced upstream. This function therefore should be used with great care and its use should be considered potentially harmful.

Arguments

  • currency_code is an ISO4217 three-character upcased binary or atom

  • amount is a float

Examples

iex> Money.from_float 1.23456, :USD
#Money<:USD, 1.23456>

iex> Money.from_float 1.234567890987656, :USD
{:error,
  {Money.InvalidAmountError,
    "The precision of the float 1.234567890987656 is " <>
    "greater than 15 which could lead to unexpected results. " <>
    "Reduce the precision or call Money.new/2 with a Decimal or String amount"}}
Link to this function

from_float!(currency_code, amount) View Source
from_float!(currency_code(), float()) :: Money.t() | no_return()

Returns a %Money{} struct from a currency code and a float amount, or raises an exception if the currency code is invalid.

See Money.from_float/2 for further information.

Note that Money cannot detect lack of precision or rounding errors introduced upstream. This function therefore should be used with great care and its use should be considered potentially harmful.

Arguments

  • currency_code is an ISO4217 three-character upcased binary or atom

  • amount is a float

Examples

iex> Money.from_float!(:USD, 1.234)
#Money<:USD, 1.234>

Money.from_float!(:USD, 1.234567890987654)
#=> ** (Money.InvalidAmountError) The precision of the float 1.234567890987654 is greater than 15 which could lead to unexpected results. Reduce the precision or call Money.new/2 with a Decimal or String amount
    (ex_money) lib/money.ex:293: Money.from_float!/2
Link to this function

from_integer(amount, currency) View Source
from_integer(integer(), currency_code()) ::
  Money.t() | {:error, Exception.t(), String.t()}

Convert an integer representation of money into a Money struct.

This is the inverse operation of Money.to_integer_exp/1. Note that the ISO definition of currency digits (subunit) is always used. This is, in some cases like the Colombian Peso (COP) different to the CLDR definition.

Options

  • integer is an integer representation of a mooney item including any decimal digits. ie. 20000 would interpreted to mean $200.00

  • currency is the currency code for the integer. The assumed decimal places is derived from the currency code.

Returns

  • A Money struct or

  • {:error, {Cldr.UnknownCurrencyError, message}}

Examples

iex> Money.from_integer(20000, :USD)
#Money<:USD, 200.00>

iex> Money.from_integer(200, :JPY)
#Money<:JPY, 200>

iex> Money.from_integer(20012, :USD)
#Money<:USD, 200.12>

iex> Money.from_integer(20012, :COP)
#Money<:COP, 200.12>
Link to this function

get_env(key, default, atom) View Source

Link to this function

known_current_currencies() View Source

Link to this function

known_historic_currencies() View Source

Link to this function

known_tender_currencies() View Source

Link to this function

mult(money, number) View Source
mult(Money.t(), Cldr.Math.number_or_decimal()) ::
  {:ok, Money.t()} | {:error, {Exception.t(), String.t()}}

Multiply a Money value by a number.

Options

  • money is any valid Money.t type returned by Money.new/2

  • number is an integer, float or Decimal.t

Note that multipling one %Money{} by another is not supported.

Returns

  • {:ok, money} or

  • {:error, reason}

Example

iex> Money.mult(Money.new(:USD, 200), 2)
{:ok, Money.new(:USD, 400)}

iex> Money.mult(Money.new(:USD, 200), "xx")
{:error, {ArgumentError, "Cannot multiply money by \"xx\""}}

Multiply a Money value by a number and raise on error.

Options

  • money is any valid Money.t types returned by Money.new/2

  • number is an integer, float or Decimal.t

Returns

  • a Money.t or

  • raises an exception

Examples

iex> Money.mult!(Money.new(:USD, 200), 2)
#Money<:USD, 400>

Money.mult!(Money.new(:USD, 200), :invalid)
** (ArgumentError) Cannot multiply money by :invalid
Link to this function

new(currency_code, amount, options \\ []) View Source
new(amount() | currency_code(), amount() | currency_code(), Keyword.t()) ::
  Money.t() | {:error, {Exception.t(), String.t()}}

Returns a %Money{} struct from a currency code and a currency amount or an error tuple of the form {:error, {exception, message}}.

Arguments

  • currency_code is an ISO4217 three-character upcased binary or atom

  • amount is an integer, string or Decimal

Options

:locale is any known locale. The locale is used to normalize any binary (String) amounts to a form that can be consumed by Decimal.new/1. This consists of removing any localised grouping characters and replacing the localised decimal separator with a ".".

Note that the currency_code and amount arguments can be supplied in either order,

Examples

iex> Money.new(:USD, 100)
#Money<:USD, 100>

iex> Money.new(100, :USD)
#Money<:USD, 100>

iex> Money.new("USD", 100)
#Money<:USD, 100>

iex> Money.new("thb", 500)
#Money<:THB, 500>

iex> Money.new("EUR", Decimal.new(100))
#Money<:EUR, 100>

iex> Money.new(:EUR, "100.30")
#Money<:EUR, 100.30>

iex> Money.new(:XYZZ, 100)
{:error, {Money.UnknownCurrencyError, "The currency :XYZZ is invalid"}}

iex> Money.new("1.000,99", :EUR, locale: "de")
#Money<:EUR, 1000.99>

iex> Money.new 123.445, :USD
{:error,
 {Money.InvalidAmountError,
  "Float amounts are not supported in new/2 due to potenial " <>
  "rounding and precision issues.  If absolutely required, " <>
  "use Money.from_float/2"}}
Link to this function

new!(currency_code, amount) View Source

Returns a %Money{} struct from a currency code and a currency amount. Raises an exception if the current code is invalid.

Arguments

  • currency_code is an ISO4217 three-character upcased binary or atom

  • amount is an integer, float or Decimal

Examples

Money.new!(:XYZZ, 100)
** (Money.UnknownCurrencyError) Currency :XYZZ is not known
  (ex_money) lib/money.ex:177: Money.new!/2
Link to this function

parse(string, options \\ []) View Source
parse(String.t(), Keyword.t()) ::
  Money.t() | {:error, {Exception.t(), String.t()}}

Parse a string and return a Money.t or an error.

The string to be parsed is required to have a currency code and an amount. The currency code may be placed before the amount or after, but not both.

Parsing is strict. Additional text surrounding the currency code and amount will cause the parse to fail.

Arguments

  • string is a string to be parsed

  • options is a keyword list of options that is passed to Money.new/3

Examples

iex> Money.parse("USD 100")
#Money<:USD, 100>

iex> Money.parse "USD 100,00", locale: "de"
#Money<:USD, 100.00>

iex> Money.parse("100 USD")
#Money<:USD, 100>

iex> Money.parse("100")
{:error,
 {Money.Invalid,
  "A currency code must be specified but was not found in \"100\""}}

iex> Money.parse("USD 100 with trailing text")
{:error, {Money.Invalid, "Could not parse \"USD 100 with trailing text\"."}}

Calls Decimal.reduce/1 on the given Money.t()

This will reduce the coefficient and exponent of the decimal amount in a standard way that may aid in native comparison of %Money.t() items.

Example

iex> x = %Money{currency: :USD, amount: %Decimal{sign: 1, coef: 42, exp: 0}}
#Money<:USD, 42>
iex> y = %Money{currency: :USD, amount: %Decimal{sign: 1, coef: 4200000000, exp: -8}}
#Money<:USD, 42.00000000>
iex> x == y
false
iex> y = Money.reduce(x)
#Money<:USD, 42>
iex> x == y
true
Link to this function

round(money, opts \\ []) View Source
round(Money.t(), Keyword.t()) :: Money.t()

Round a Money value into the acceptable range for the requested currency.

Arguments

  • money is a %Money{} struct

  • opts is a keyword list of options

Options

  • :rounding_mode that defines how the number will be rounded. See Decimal.Context. The default is :half_even which is also known as "banker's rounding"

  • :currency_digits which determines the rounding increment. The valid options are :cash, :accounting and :iso. The default is :iso. The rounding increment applies to currencies such as :AUD and :CHF which have an accounting increment of 0.01 but a minimum cash increment of 0.05.

Notes

There are two kinds of rounding applied:

  1. Round to the appropriate number of fractional digits

  2. Apply an appropriate rounding increment. Most currencies round to the same precision as the number of decimal digits, but some such as :AUD and :CHF round to a minimum such as 0.05 when its a cash amount.

Examples

iex> Money.round Money.new("123.73", :CHF), currency_digits: :cash
#Money<:CHF, 123.75>

iex> Money.round Money.new("123.7456", :CHF)
#Money<:CHF, 123.75>

Money.round Money.new("123.7456", :JPY)
#Money<:JPY, 124>

Split a Money value into a number of parts maintaining the currency's precision and rounding and ensuring that the parts sum to the original amount.

Options

  • money is a %Money{} struct

  • parts is an integer number of parts into which the money is split

Returns a tuple {dividend, remainder} as the function result derived as follows:

  1. Round the money amount to the required currency precision using Money.round/1

  2. Divide the result of step 1 by the integer divisor

  3. Round the result of the division to the precision of the currency using Money.round/1

  4. Return two numbers: the result of the division and any remainder that could not be applied given the precision of the currency.

Examples

Money.split Money.new(123.5, :JPY), 3
{¥41, ¥1}

Money.split Money.new(123.4, :JPY), 3
{¥41, ¥0}

Money.split Money.new(123.7, :USD), 9
{$13.74, $0.04}
Link to this function

sub(money1, money2) View Source
sub(money_1 :: Money.t(), money_2 :: Money.t()) ::
  {:ok, Money.t()} | {:error, {Exception.t(), String.t()}}

Subtract one Money value struct from another.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • {:ok, money} or

  • {:error, reason}

Example

iex> Money.sub Money.new(:USD, 200), Money.new(:USD, 100)
{:ok, Money.new(:USD, 100)}
Link to this function

sub!(a, b) View Source
sub!(money_1 :: Money.t(), money_2 :: Money.t()) :: Money.t() | none()

Subtract one Money value struct from another and raise on error.

Returns either {:ok, money} or {:error, reason}.

Options

  • money_1 and money_2 are any valid Money.t types returned by Money.new/2

Returns

  • a Money.t struct or

  • raises an exception

Examples

iex> Money.sub! Money.new(:USD, 200), Money.new(:USD, 100)
#Money<:USD, 100>

Money.sub! Money.new(:USD, 200), Money.new(:CAD, 500)
** (ArgumentError) Cannot subtract monies with different currencies. Received :USD and :CAD.
Link to this function

to_currency(money, to_currency, rates \\ Money.ExchangeRates.latest_rates()) View Source
to_currency(
  Money.t(),
  currency_code(),
  Money.ExchangeRates.t()
  | {:ok, Money.ExchangeRates.t()}
  | {:error, {Exception.t(), String.t()}}
) :: {:ok, Money.t()} | {:error, {Exception.t(), String.t()}}

Convert money from one currency to another.

Arguments

  • money is any Money.t struct returned by Cldr.Currency.new/2

  • 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 upcased atom or string 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.from_float(0.7345)})
{:ok, #Money<:AUD, 73.4500>}

Money.to_currency(Money.new("USD", 100), "AUD", %{"USD" => Decimal.new(1), "AUD" => Decimal.from_float(0.7345)})
{:ok, #Money<:AUD, 73.4500>}

iex> Money.to_currency Money.new(:USD, 100), :AUDD, %{USD: Decimal.new(1), AUD: Decimal.from_float(0.7345)}
{:error, {Cldr.UnknownCurrencyError, "The currency :AUDD is invalid"}}

iex> Money.to_currency Money.new(:USD, 100), :CHF, %{USD: Decimal.new(1), AUD: Decimal.from_float(0.7345)}
{:error, {Money.ExchangeRateError, "No exchange rate is available for currency :CHF"}}
Link to this function

to_currency!(money, to_currency, rates \\ Money.ExchangeRates.latest_rates()) View Source
to_currency!(
  Money.t(),
  currency_code(),
  Money.ExchangeRates.t()
  | {:ok, Money.ExchangeRates.t()}
  | {:error, {Exception.t(), String.t()}}
) :: Money.t() | no_return()

Convert money from one currency to another and raises on error

Arguments

  • money is any Money.t struct returned by Cldr.Currency.new/2

  • 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 upcased atom or string and the value is a Decimal conversion factor. The default is the latest available exchange rates returned from Money.ExchangeRates.latest_rates()

Examples

iex> Money.to_currency! Money.new(:USD, 100), :AUD, %{USD: Decimal.new(1), AUD: Decimal.from_float(0.7345)}
#Money<:AUD, 73.4500>

iex> Money.to_currency! Money.new("USD", 100), "AUD", %{"USD" => Decimal.new(1), "AUD" => Decimal.from_float(0.7345)}
#Money<:AUD, 73.4500>

Money.to_currency! Money.new(:USD, 100), :ZZZ, %{USD: Decimal.new(1), AUD: Decimal.from_float(0.7345)}
** (Cldr.UnknownCurrencyError) Currency :ZZZ is not known
Link to this function

to_decimal(money) View Source
to_decimal(money :: Money.t()) :: Decimal.t()

Returns the amount part of a Money type as a Decimal

Options

  • money is any valid Money.t type returned by Money.new/2

Returns

  • a Decimal.t

Example

iex> m = Money.new("USD", 100)
iex> Money.to_decimal(m)
#Decimal<100>
Link to this function

to_integer_exp(money, opts \\ []) View Source

Returns a tuple comprising the currency code, integer amount, exponent and remainder

Some services require submission of money items as an integer with an implied exponent that is appropriate to the currency.

Rather than return only the integer, Money.to_integer_exp returns the currency code, integer, exponent and remainder. The remainder is included because to return an integer money with an implied exponent the Money has to be rounded potentially leaving a remainder.

Options

Notes

  • Since the returned integer is expected to have the implied fractional digits the Money needs to be rounded which is what this function does.

Example

iex> m = Money.new(:USD, "200.012356")
#Money<:USD, 200.012356>
iex> Money.to_integer_exp(m)
{:USD, 20001, -2, Money.new(:USD, "0.002356")}

iex> m = Money.new(:USD, "200.00")
#Money<:USD, 200.00>
iex> Money.to_integer_exp(m)
{:USD, 20000, -2, Money.new(:USD, "0.00")}
Link to this function

to_string(money, options \\ []) View Source

Returns a formatted string representation of a Money{}.

Formatting is performed according to the rules defined by CLDR. See Cldr.Number.to_string/2 for formatting options. The default is to format as a currency which applies the appropriate rounding and fractional digits for the currency.

Options

  • money_1 is any valid Money.t type returned by Money.new/2

Returns

  • {:ok, string} or

  • {:error, reason}

Examples

iex> Money.to_string Money.new(:USD, 1234)
{:ok, "$1,234.00"}

iex> Money.to_string Money.new(:JPY, 1234)
{:ok, "¥1,234"}

iex> Money.to_string Money.new(:THB, 1234)
{:ok, "THB 1,234.00"}

iex> Money.to_string Money.new(:USD, 1234), format: :long
{:ok, "1,234 US dollars"}
Link to this function

to_string!(money, options \\ []) View Source

Returns a formatted string representation of a Money{} or raises if there is an error.

Formatting is performed according to the rules defined by CLDR. See Cldr.Number.to_string!/2 for formatting options. The default is to format as a currency which applies the appropriate rounding and fractional digits for the currency.

Examples

iex> Money.to_string! Money.new(:USD, 1234)
"$1,234.00"

iex> Money.to_string! Money.new(:JPY, 1234)
"¥1,234"

iex> Money.to_string! Money.new(:THB, 1234)
"THB 1,234.00"

iex> Money.to_string! Money.new(:USD, 1234), format: :long
"1,234 US dollars"
Link to this function

validate_currency(currency_code) View Source

Return a zero amount Money.t in the given currency

Example

iex> Money.zero(:USD)
#Money<:USD, 0>

iex> money = Money.new(:USD, 200)
iex> Money.zero(money)
#Money<:USD, 0>

iex> Money.zero :ZZZ
{:error, {Cldr.UnknownCurrencyError, "The currency :ZZZ is invalid"}}