defmodule ISO20022.Camt053.Balance do
@moduledoc """
A balance entry from `<Bal>`.
## Balance types
| Atom | ISO code | Description |
|------|----------|-------------|
| `:opening_booked` | `OPBD` | Opening booked balance (mandatory) |
| `:closing_booked` | `CLBD` | Closing booked balance (mandatory) |
| `:closing_available` | `CLAV` | Closing available balance |
| `:interim_booked` | `ITBD` | Interim booked balance |
| `:interim_available` | `ITAV` | Interim available balance |
| `:forward_available` | `FWAV` | Forward available balance |
| `{:other, code}` | any | Unrecognised type code |
`amount` is always a positive `Decimal`. The sign of the balance is expressed via
`credit_debit`: `:credit` for a positive/credit balance, `:debit` for an
overdraft/negative balance.
"""
@type balance_type ::
:opening_booked
| :closing_booked
| :closing_available
| :interim_booked
| :interim_available
| :forward_available
| {:other, String.t()}
@type credit_debit :: :credit | :debit
@type t :: %__MODULE__{
type: balance_type(),
amount: Decimal.t(),
currency: String.t(),
credit_debit: credit_debit(),
date: Date.t()
}
defstruct [:type, :amount, :currency, :credit_debit, :date]
@doc """
Parses an ISO 20022 balance type code string into an atom.
"""
@spec parse_type(String.t()) :: balance_type()
def parse_type("OPBD"), do: :opening_booked
def parse_type("CLBD"), do: :closing_booked
def parse_type("CLAV"), do: :closing_available
def parse_type("ITBD"), do: :interim_booked
def parse_type("ITAV"), do: :interim_available
def parse_type("FWAV"), do: :forward_available
def parse_type(code), do: {:other, code}
end