]> git.ktnx.net Git - mobile-ledger-staging.git/blob - app/src/main/java/net/ktnx/mobileledger/json/AccountListParser.java
a step towards API-independent JSON parsing of accounts
[mobile-ledger-staging.git] / app / src / main / java / net / ktnx / mobileledger / json / AccountListParser.java
1 /*
2  * Copyright © 2020 Damyan Ivanov.
3  * This file is part of MoLe.
4  * MoLe is free software: you can distribute it and/or modify it
5  * under the term of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your opinion), any later version.
8  *
9  * MoLe is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License terms for details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
16  */
17
18 package net.ktnx.mobileledger.json;
19
20 import com.fasterxml.jackson.databind.MappingIterator;
21
22 import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
23 import net.ktnx.mobileledger.model.LedgerAccount;
24
25 import java.util.ArrayList;
26 import java.util.HashMap;
27
28 import static net.ktnx.mobileledger.utils.Logger.debug;
29
30 abstract public class AccountListParser {
31     protected MappingIterator<net.ktnx.mobileledger.json.ParsedLedgerAccount> iterator;
32
33     public ParsedLedgerAccount nextAccount() {
34         if (!iterator.hasNext())
35             return null;
36
37         ParsedLedgerAccount next = iterator.next();
38
39         if (next.getAname()
40                 .equalsIgnoreCase("root"))
41             return nextAccount();
42
43         debug("accounts", String.format("Got account '%s' [v1.15]", next.getAname()));
44         return next;
45     }
46     public LedgerAccount nextLedgerAccount(RetrieveTransactionsTask task,
47                                            HashMap<String, LedgerAccount> map) {
48         ParsedLedgerAccount parsedAccount = nextAccount();
49         if (parsedAccount == null)
50             return null;
51
52         task.addNumberOfPostings(parsedAccount.getAnumpostings());
53         final String accName = parsedAccount.getAname();
54         LedgerAccount acc = map.get(accName);
55         if (acc != null)
56             throw new RuntimeException(
57                     String.format("Account '%s' already present", acc.getName()));
58         String parentName = LedgerAccount.extractParentName(accName);
59         ArrayList<LedgerAccount> createdParents = new ArrayList<>();
60         LedgerAccount parent;
61         if (parentName == null) {
62             parent = null;
63         }
64         else {
65             parent = task.ensureAccountExists(parentName, map, createdParents);
66             parent.setHasSubAccounts(true);
67         }
68         acc = new LedgerAccount(task.getProfile(), accName, parent);
69         map.put(accName, acc);
70
71         String lastCurrency = null;
72         float lastCurrencyAmount = 0;
73         for (ParsedBalance b : parsedAccount.getAibalance()) {
74             task.throwIfCancelled();
75             final String currency = b.getAcommodity();
76             final float amount = b.getAquantity()
77                                   .asFloat();
78             if (currency.equals(lastCurrency)) {
79                 lastCurrencyAmount += amount;
80             }
81             else {
82                 if (lastCurrency != null) {
83                     acc.addAmount(lastCurrencyAmount, lastCurrency);
84                 }
85                 lastCurrency = currency;
86                 lastCurrencyAmount = amount;
87             }
88         }
89         if (lastCurrency != null) {
90             acc.addAmount(lastCurrencyAmount, lastCurrency);
91         }
92         for (LedgerAccount p : createdParents)
93             acc.propagateAmountsTo(p);
94
95         return acc;
96     }
97
98 }