diff options
Diffstat (limited to 'app/Import/Ing/Convert.hs')
-rw-r--r-- | app/Import/Ing/Convert.hs | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/app/Import/Ing/Convert.hs b/app/Import/Ing/Convert.hs new file mode 100644 index 0000000..712c8a4 --- /dev/null +++ b/app/Import/Ing/Convert.hs | |||
@@ -0,0 +1,126 @@ | |||
1 | module Import.Ing.Convert where | ||
2 | |||
3 | import Control.Monad (when) | ||
4 | import Data.Decimal | ||
5 | import Data.Dependent.Map | ||
6 | import Data.Dependent.Sum ((==>)) | ||
7 | import Data.Functor.Identity | ||
8 | import Data.Iban qualified as Iban | ||
9 | import Data.Ledger as L | ||
10 | import Data.Map qualified as M | ||
11 | import Data.Text qualified as T | ||
12 | import Import.Ing.CurrentAccountCsv as C | ||
13 | import Import.Ing.SavingsAccountCsv as S | ||
14 | |||
15 | virtCheckingAccount :: Iban.Iban -> L.AccountId | ||
16 | virtCheckingAccount iban = AccountId ["Unfiled", "Asset", "Current", "Checking", "Iban", Iban.toText iban] | ||
17 | |||
18 | virtCounterparty :: T.Text -> L.AccountId | ||
19 | virtCounterparty name = AccountId ["Unfiled", "Expenses", "Counterparty", "Name", name] | ||
20 | |||
21 | toCents :: Decimal -> Either String L.Money | ||
22 | toCents m | ||
23 | | f == 0 = | ||
24 | return (L.Money m') | ||
25 | | otherwise = | ||
26 | Left "Cannot convert to whole cents: amount of money is more specific" | ||
27 | where | ||
28 | (m', f) = properFraction (m * 100) | ||
29 | |||
30 | condUnitLabel :: UnitTag -> Bool -> L.Labels | ||
31 | condUnitLabel _ False = empty | ||
32 | condUnitLabel t True = singleton (UnitLabel t) (Identity ()) | ||
33 | |||
34 | fromCurrentAccountTx :: CommodityId -> C.Tx -> Either String L.Tx | ||
35 | fromCurrentAccountTx eucId (C.Tx base spec) = do | ||
36 | let acc = virtCheckingAccount base.account | ||
37 | when (base.amount < 0) $ | ||
38 | Left "Transaction amount may not be lower than zero" | ||
39 | amount <- L.Amount <$> toCents base.amount | ||
40 | case spec of | ||
41 | PaymentTerminalPayment | ||
42 | { counterpartyName, | ||
43 | cardSequenceNo, | ||
44 | timestamp, | ||
45 | transaction, | ||
46 | terminal, | ||
47 | googlePay | ||
48 | } -> | ||
49 | return $ | ||
50 | L.Tx | ||
51 | { cleared = Just base.date, | ||
52 | commodityId = eucId, | ||
53 | credit = M.singleton acc amount, | ||
54 | debit = M.singleton (virtCounterparty counterpartyName) amount, | ||
55 | labels = | ||
56 | fromList | ||
57 | [ IbanLabel AccountTag ==> base.account, | ||
58 | TextLabel CardSeqNoTag ==> cardSequenceNo, | ||
59 | TextLabel TerminalTag ==> terminal, | ||
60 | TextLabel TransactionTag ==> transaction, | ||
61 | TimestampLabel ==> timestamp | ||
62 | ] | ||
63 | `union` condUnitLabel GooglePayTag googlePay | ||
64 | } | ||
65 | PaymentTerminalCashback | ||
66 | { counterpartyName, | ||
67 | cardSequenceNo, | ||
68 | timestamp, | ||
69 | transaction, | ||
70 | terminal | ||
71 | } -> | ||
72 | return $ | ||
73 | L.Tx | ||
74 | { cleared = Just base.date, | ||
75 | commodityId = eucId, | ||
76 | debit = M.singleton acc amount, | ||
77 | credit = M.singleton (virtCounterparty counterpartyName) amount, | ||
78 | labels = | ||
79 | fromList | ||
80 | [ IbanLabel AccountTag ==> base.account, | ||
81 | TextLabel CardSeqNoTag ==> cardSequenceNo, | ||
82 | TextLabel TerminalTag ==> terminal, | ||
83 | TextLabel TransactionTag ==> transaction, | ||
84 | TimestampLabel ==> timestamp | ||
85 | ] | ||
86 | } | ||
87 | OnlineBankingCredit | ||
88 | { counterpartyName, | ||
89 | counterpartyIban, | ||
90 | description, | ||
91 | timestamp | ||
92 | } -> | ||
93 | return $ | ||
94 | L.Tx | ||
95 | { cleared = Just base.date, | ||
96 | commodityId = eucId, | ||
97 | debit = M.singleton acc amount, | ||
98 | credit = M.singleton (virtCounterparty counterpartyName) amount, | ||
99 | labels = | ||
100 | fromList | ||
101 | [ IbanLabel AccountTag ==> base.account, | ||
102 | IbanLabel CounterpartyIbanTag ==> counterpartyIban, | ||
103 | TextLabel DescTag ==> description, | ||
104 | TimestampLabel ==> timestamp | ||
105 | ] | ||
106 | } | ||
107 | OnlineBankingDebit | ||
108 | { counterpartyName, | ||
109 | counterpartyIban, | ||
110 | description, | ||
111 | mtimestamp | ||
112 | } -> | ||
113 | return $ | ||
114 | L.Tx | ||
115 | { cleared = Just base.date, | ||
116 | commodityId = eucId, | ||
117 | debit = M.singleton (virtCounterparty counterpartyName) amount, | ||
118 | credit = M.singleton acc amount, | ||
119 | labels = | ||
120 | fromList | ||
121 | [ IbanLabel AccountTag ==> base.account, | ||
122 | IbanLabel CounterpartyIbanTag ==> counterpartyIban, | ||
123 | TextLabel DescTag ==> description | ||
124 | ] | ||
125 | `union` (maybe empty (singleton TimestampLabel . Identity) mtimestamp) | ||
126 | } | ||