open Prelude (* type account_type = Asset | Equity | Liability | Expense | Income [@@deriving compare, sexp]*) type tx_type = | Interest_tx | Online_banking_tx | Recurrent_direct_tx | Payment_terminal_tx | Cash_payment_tx | Atm_tx | Auto_save_rounding_tx | Batch_tx | Direct_debit_tx | Periodic_tx type iban_tag = Account_tag | Counterparty_iban_tag [@@deriving compare, sexp] type unit_tag = Filed_tag | Google_pay_tag | Auto_round_savings_tag [@@deriving compare, sexp] type string_tag = | Desc_tag | User_tag | Counterparty_name_tag | Reference_tag | Mandate_id_tag | Creditor_id_tag | Other_party_tag | Transaction_tag | Terminal_tag | Card_seq_no_tag | Savings_account_tag [@@deriving compare, sexp] module Label : sig type 'a t = | Iban_label : iban_tag -> Iban.t t | String_label : string_tag -> string t | Timestamp_label : Time_ns.t t | Unit_label : unit_tag -> unit t val int_to_cmp : int -> ('a, 'a) Dmap.cmp val compare : 'a1 'a2. 'a1 t -> 'a2 t -> ('a1, 'a2) Dmap.cmp end module Labels : sig include Dmap.S with type 'a key = 'a Label.t val sexp_of_binding : binding -> Sexp.t val binding_of_sexp : Sexp.t -> binding include Sexpable.S with type t := t end module Money : sig type t val equal : t -> t -> bool val compare : t -> t -> int val of_bigint : Bigint.t -> t val to_bigint : t -> Bigint.t val ( + ) : t -> t -> t val ( - ) : t -> t -> t val ( = ) : t -> t -> bool val ( ~$ ) : int -> t val sexp_of_t : t -> Sexp.t end type commodity_id = string (* TODO: consider making this UUID *) [@@deriving equal, compare, sexp] type scalar = | Amount of Money.t | Rate of { in_primary_commodity : Money.t; rate : Bigdecimal.t } [@@deriving equal, compare, sexp_of] module Account_id : sig type t = string list [@@deriving sexp, compare] end type account = { id : Account_id.t; description : string list; commodity_id : commodity_id; balance : Money.t; } [@@deriving sexp_of] type bal_assert = { account : Account_id.t; amount : Money.t; labels : Labels.t; } [@@deriving sexp_of] module Account_id_map : Map.S with type Key.t = Account_id.t module Debit_credit : sig type t = Debit | Credit [@@deriving string, sexp_of] val opposite : t -> t end module Tx : sig (* Private because we only want to allow constructing balanced transactions. *) type t = private { cleared : Date.t option; commodity_id : commodity_id; entries : (Debit_credit.t * scalar * Money.t option) Account_id_map.t; labels : Labels.t; } type error = Unbalanced val make : cleared:Date.t option -> commodity_id:commodity_id -> entries:(Debit_credit.t * scalar * Money.t option) Account_id_map.t -> labels:Labels.t -> (t, error) result val sexp_of_t : t -> Sexp.t end type item = Tx_item of Tx.t | Bal_assert_item of bal_assert [@@deriving sexp_of] type t [@@deriving sexp_of] val make : item list -> t