# `DDD.Money`
[🔗](https://github.com/blackuprise/vicander/blob/v0.1.1/lib/ddd/model/money.ex#L1)

An amount of money in one currency, as a value object.

    field :price, :money                 # shorthand for {:one, DDD.Money}

    {:ok, price} = DDD.Money.of("19.99", "EUR")
    {:ok, total} = DDD.Money.add(price, price)
    {:ok, half}  = DDD.Money.multiply(price, "0.5")

The amount is a `Decimal`, never a float. The currency is a 3-letter ISO 4217 code.
Adding or subtracting two currencies is a business error (`:currency_mismatch`); there is no
silent conversion. Money is stored as `jsonb` (`{"amount": "19.99", "currency": "EUR"}`).

# `add`

Sum of two amounts in the same currency.

    iex> {:ok, sum} = DDD.Money.add(DDD.Money.of!("1.10", "EUR"), DDD.Money.of!("2.20", "EUR"))
    iex> Decimal.to_string(sum.amount)
    "3.30"
    iex> {:error, error} = DDD.Money.add(DDD.Money.of!(1, "EUR"), DDD.Money.of!(1, "USD"))
    iex> error.code
    :currency_mismatch

# `compare`

Compare two amounts of the same currency: `{:ok, :lt | :eq | :gt}`.

# `multiply`

Multiply by a number (`Decimal`, integer, float or string).

# `negative?`

True for an amount below zero.

# `of`

```elixir
@spec of(Decimal.t() | integer() | float() | String.t(), String.t()) ::
  {:ok, struct()} | {:error, DDD.Error.t()}
```

Build money from an amount (`Decimal`, integer, float or string) and a currency.

# `of!`

Like `of/2` but returns the money or raises.

# `positive?`

True for an amount above zero.

# `round`

Round to `places` decimal places (default 2), half up.

# `subtract`

Difference of two amounts in the same currency (may be negative).

# `validate`

Run field rules, then specification invariants. Returns the sealed
struct or a `DDD.Error` listing every violation.

# `zero`

Zero in `currency`.

# `zero?`

True for an amount of exactly zero.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
