summaryrefslogtreecommitdiffstats
path: root/lib/convert.ml
blob: 5afc95e5b6084cb810d7d2c8f38ee9037b2def90 (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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
open Prelude
open Ledger
open Result.Let_syntax

let virt_checking_acc = [ "Unfiled"; "Checking" ]
let virt_savings_acc = [ "Unfiled"; "Savings" ]
let virt_counterparty = [ "Unfiled"; "Counterparty" ]

(* TODO: clean up *)
type convert_err = Nonpositive_amount | Other of Tx.error

let cents n = Amount (Money.of_z n)

let tx_from_current_acc euc_id (Ingcsv.Tx (base, spec)) =
  if Z.(lt base.amount ~$0) then Error Nonpositive_amount
  else
    Result.map_error ~f:(fun e -> Other e)
    @@
    match spec with
    | Payment_terminal_payment details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~credit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~debit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Account_tag) base.account
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (String_label Card_seq_no_tag) details.card_sequence_no
              |> add (String_label Terminal_tag) details.terminal
              |> add (String_label Transaction_tag) details.transaction
              |> add Timestamp_label details.timestamp
              |>
              if details.google_pay then add (Unit_label Google_pay_tag) ()
              else Fn.id)
    | Payment_terminal_cashback details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Account_tag) base.account
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (String_label Card_seq_no_tag) details.card_sequence_no
              |> add (String_label Terminal_tag) details.terminal
              |> add (String_label Transaction_tag) details.transaction
              |> add Timestamp_label details.timestamp)
    | Online_banking_credit details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Account_tag) base.account
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (Iban_label Counterparty_iban_tag)
                   details.counterparty_iban
              |> add (String_label Desc_tag) details.description
              |> add Timestamp_label details.timestamp)
    | Online_banking_debit details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Account_tag) base.account
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (Iban_label Counterparty_iban_tag)
                   details.counterparty_iban
              |> add (String_label Desc_tag) details.description)
    | Recurrent_direct_debit details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Account_tag) base.account
              |> add (Iban_label Counterparty_iban_tag)
                   details.counterparty_iban
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (String_label Desc_tag) details.description
              |> add (String_label Reference_tag) details.reference
              |> add (String_label Mandate_id_tag) details.mandate_id
              |> add (String_label Creditor_id_tag) details.creditor_id
              |>
              match details.other_party with
              | None -> Fn.id
              | Some other_party ->
                  add (String_label Other_party_tag) other_party)
    | Rounding_savings_deposit details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Unit_label Auto_round_savings_tag) ()
              |> add (String_label Savings_account_tag) details.savings_account)
    | Deposit details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Counterparty_iban_tag)
                   details.counterparty_iban
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (String_label Desc_tag) details.description
              |> add (String_label Reference_tag) details.reference)
    | Ideal_debit details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Counterparty_iban_tag)
                   details.counterparty_iban
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (String_label Desc_tag) details.description
              |> add (String_label Reference_tag) details.reference
              |> add Timestamp_label details.timestamp)
    | Batch_payment details ->
        Tx.make ~cleared:(Some base.date) ~commodity_id:euc_id
          ~debit:
            (Account_id_map.singleton virt_counterparty @@ cents base.amount)
          ~credit:
            (Account_id_map.singleton virt_checking_acc @@ cents base.amount)
          ~labels:
            Labels.(
              empty
              |> add (Iban_label Counterparty_iban_tag)
                   details.counterparty_iban
              |> add (String_label Counterparty_name_tag)
                   details.counterparty_name
              |> add (String_label Desc_tag) details.description
              |> add (String_label Reference_tag) details.reference)

let ba_from_current_acc (Ingcsv.Tx (base, _)) =
  {
    account = virt_checking_acc;
    amount = Money.of_z base.resulting_balance;
    labels = Labels.(empty |> add (Iban_label Account_tag) base.account);
  }

let les_from_current_acc euc_id tx =
  let%map tx' = tx_from_current_acc euc_id tx in
  let ba = ba_from_current_acc tx in
  [ Bal_assert_item ba; Tx_item tx' ]