summaryrefslogtreecommitdiffstats
path: root/app/Import/Ing/Convert.hs
blob: 712c8a4c53377e3ae623bac5bd7a4169c728dcea (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
module Import.Ing.Convert where

import Control.Monad (when)
import Data.Decimal
import Data.Dependent.Map
import Data.Dependent.Sum ((==>))
import Data.Functor.Identity
import Data.Iban qualified as Iban
import Data.Ledger as L
import Data.Map qualified as M
import Data.Text qualified as T
import Import.Ing.CurrentAccountCsv as C
import Import.Ing.SavingsAccountCsv as S

virtCheckingAccount :: Iban.Iban -> L.AccountId
virtCheckingAccount iban = AccountId ["Unfiled", "Asset", "Current", "Checking", "Iban", Iban.toText iban]

virtCounterparty :: T.Text -> L.AccountId
virtCounterparty name = AccountId ["Unfiled", "Expenses", "Counterparty", "Name", name]

toCents :: Decimal -> Either String L.Money
toCents m
  | f == 0 =
      return (L.Money m')
  | otherwise =
      Left "Cannot convert to whole cents: amount of money is more specific"
  where
    (m', f) = properFraction (m * 100)

condUnitLabel :: UnitTag -> Bool -> L.Labels
condUnitLabel _ False = empty
condUnitLabel t True = singleton (UnitLabel t) (Identity ())

fromCurrentAccountTx :: CommodityId -> C.Tx -> Either String L.Tx
fromCurrentAccountTx eucId (C.Tx base spec) = do
  let acc = virtCheckingAccount base.account
  when (base.amount < 0) $
    Left "Transaction amount may not be lower than zero"
  amount <- L.Amount <$> toCents base.amount
  case spec of
    PaymentTerminalPayment
      { counterpartyName,
        cardSequenceNo,
        timestamp,
        transaction,
        terminal,
        googlePay
      } ->
        return $
          L.Tx
            { cleared = Just base.date,
              commodityId = eucId,
              credit = M.singleton acc amount,
              debit = M.singleton (virtCounterparty counterpartyName) amount,
              labels =
                fromList
                  [ IbanLabel AccountTag ==> base.account,
                    TextLabel CardSeqNoTag ==> cardSequenceNo,
                    TextLabel TerminalTag ==> terminal,
                    TextLabel TransactionTag ==> transaction,
                    TimestampLabel ==> timestamp
                  ]
                  `union` condUnitLabel GooglePayTag googlePay
            }
    PaymentTerminalCashback
      { counterpartyName,
        cardSequenceNo,
        timestamp,
        transaction,
        terminal
      } ->
        return $
          L.Tx
            { cleared = Just base.date,
              commodityId = eucId,
              debit = M.singleton acc amount,
              credit = M.singleton (virtCounterparty counterpartyName) amount,
              labels =
                fromList
                  [ IbanLabel AccountTag ==> base.account,
                    TextLabel CardSeqNoTag ==> cardSequenceNo,
                    TextLabel TerminalTag ==> terminal,
                    TextLabel TransactionTag ==> transaction,
                    TimestampLabel ==> timestamp
                  ]
            }
    OnlineBankingCredit
      { counterpartyName,
        counterpartyIban,
        description,
        timestamp
      } ->
        return $
          L.Tx
            { cleared = Just base.date,
              commodityId = eucId,
              debit = M.singleton acc amount,
              credit = M.singleton (virtCounterparty counterpartyName) amount,
              labels =
                fromList
                  [ IbanLabel AccountTag ==> base.account,
                    IbanLabel CounterpartyIbanTag ==> counterpartyIban,
                    TextLabel DescTag ==> description,
                    TimestampLabel ==> timestamp
                  ]
            }
    OnlineBankingDebit
      { counterpartyName,
        counterpartyIban,
        description,
        mtimestamp
      } ->
        return $
          L.Tx
            { cleared = Just base.date,
              commodityId = eucId,
              debit = M.singleton (virtCounterparty counterpartyName) amount,
              credit = M.singleton acc amount,
              labels =
                fromList
                  [ IbanLabel AccountTag ==> base.account,
                    IbanLabel CounterpartyIbanTag ==> counterpartyIban,
                    TextLabel DescTag ==> description
                  ]
                  `union` (maybe empty (singleton TimestampLabel . Identity) mtimestamp)
            }