summaryrefslogtreecommitdiffstats
path: root/lib/ledger.mli
blob: 0b8e3835ed60fc5154bace8db0084c34243da77e (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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