import net.ktnx.mobileledger.App;
import net.ktnx.mobileledger.err.HTTPException;
import net.ktnx.mobileledger.json.v1_15.AccountListParser;
-import net.ktnx.mobileledger.json.v1_15.ParsedBalance;
-import net.ktnx.mobileledger.json.v1_15.ParsedLedgerAccount;
import net.ktnx.mobileledger.json.v1_15.ParsedLedgerTransaction;
import net.ktnx.mobileledger.json.v1_15.TransactionListParser;
import net.ktnx.mobileledger.model.Data;
return null;
}
}
+ public MobileLedgerProfile getProfile() {
+ return profile;
+ }
@Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
throwIfCancelled();
}
}
- private @NonNull
- LedgerAccount ensureAccountExists(String accountName, HashMap<String, LedgerAccount> map,
- ArrayList<LedgerAccount> createdAccounts) {
+ @NonNull
+ public LedgerAccount ensureAccountExists(String accountName, HashMap<String, LedgerAccount> map,
+ ArrayList<LedgerAccount> createdAccounts) {
LedgerAccount acc = map.get(accountName);
if (acc != null)
createdAccounts.add(acc);
return acc;
}
+ public void addNumberOfPostings(int number) {
+ expectedPostingsCount += number;
+ }
private List<LedgerAccount> retrieveAccountList() throws IOException, HTTPException {
HttpURLConnection http = NetworkUtil.prepareConnection(profile, "accounts");
http.setAllowUserInteraction(false);
while (true) {
throwIfCancelled();
- ParsedLedgerAccount parsedAccount = parser.nextAccount();
- if (parsedAccount == null) {
+ LedgerAccount acc = parser.nextLedgerAccount(this, map);
+ if (acc == null)
break;
- }
- expectedPostingsCount += parsedAccount.getAnumpostings();
- final String accName = parsedAccount.getAname();
- LedgerAccount acc = map.get(accName);
- if (acc != null)
- throw new RuntimeException(
- String.format("Account '%s' already present", acc.getName()));
- String parentName = LedgerAccount.extractParentName(accName);
- ArrayList<LedgerAccount> createdParents = new ArrayList<>();
- LedgerAccount parent;
- if (parentName == null) {
- parent = null;
- }
- else {
- parent = ensureAccountExists(parentName, map, createdParents);
- parent.setHasSubAccounts(true);
- }
- acc = new LedgerAccount(profile, accName, parent);
list.add(acc);
- map.put(accName, acc);
-
- String lastCurrency = null;
- float lastCurrencyAmount = 0;
- for (ParsedBalance b : parsedAccount.getAibalance()) {
- throwIfCancelled();
- final String currency = b.getAcommodity();
- final float amount = b.getAquantity()
- .asFloat();
- if (currency.equals(lastCurrency)) {
- lastCurrencyAmount += amount;
- }
- else {
- if (lastCurrency != null) {
- acc.addAmount(lastCurrencyAmount, lastCurrency);
- }
- lastCurrency = currency;
- lastCurrencyAmount = amount;
- }
- }
- if (lastCurrency != null) {
- acc.addAmount(lastCurrencyAmount, lastCurrency);
- }
- for (LedgerAccount p : createdParents)
- acc.propagateAmountsTo(p);
}
throwIfCancelled();
}
Data.backgroundTaskFinished();
}
}
- private void throwIfCancelled() {
+ public void throwIfCancelled() {
if (isCancelled())
throw new OperationCanceledException(null);
}
--- /dev/null
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.json;
+
+import com.fasterxml.jackson.databind.MappingIterator;
+
+import net.ktnx.mobileledger.async.RetrieveTransactionsTask;
+import net.ktnx.mobileledger.model.LedgerAccount;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static net.ktnx.mobileledger.utils.Logger.debug;
+
+abstract public class AccountListParser {
+ protected MappingIterator<net.ktnx.mobileledger.json.ParsedLedgerAccount> iterator;
+
+ public ParsedLedgerAccount nextAccount() {
+ if (!iterator.hasNext())
+ return null;
+
+ ParsedLedgerAccount next = iterator.next();
+
+ if (next.getAname()
+ .equalsIgnoreCase("root"))
+ return nextAccount();
+
+ debug("accounts", String.format("Got account '%s' [v1.15]", next.getAname()));
+ return next;
+ }
+ public LedgerAccount nextLedgerAccount(RetrieveTransactionsTask task,
+ HashMap<String, LedgerAccount> map) {
+ ParsedLedgerAccount parsedAccount = nextAccount();
+ if (parsedAccount == null)
+ return null;
+
+ task.addNumberOfPostings(parsedAccount.getAnumpostings());
+ final String accName = parsedAccount.getAname();
+ LedgerAccount acc = map.get(accName);
+ if (acc != null)
+ throw new RuntimeException(
+ String.format("Account '%s' already present", acc.getName()));
+ String parentName = LedgerAccount.extractParentName(accName);
+ ArrayList<LedgerAccount> createdParents = new ArrayList<>();
+ LedgerAccount parent;
+ if (parentName == null) {
+ parent = null;
+ }
+ else {
+ parent = task.ensureAccountExists(parentName, map, createdParents);
+ parent.setHasSubAccounts(true);
+ }
+ acc = new LedgerAccount(task.getProfile(), accName, parent);
+ map.put(accName, acc);
+
+ String lastCurrency = null;
+ float lastCurrencyAmount = 0;
+ for (ParsedBalance b : parsedAccount.getAibalance()) {
+ task.throwIfCancelled();
+ final String currency = b.getAcommodity();
+ final float amount = b.getAquantity()
+ .asFloat();
+ if (currency.equals(lastCurrency)) {
+ lastCurrencyAmount += amount;
+ }
+ else {
+ if (lastCurrency != null) {
+ acc.addAmount(lastCurrencyAmount, lastCurrency);
+ }
+ lastCurrency = currency;
+ lastCurrencyAmount = amount;
+ }
+ }
+ if (lastCurrency != null) {
+ acc.addAmount(lastCurrencyAmount, lastCurrency);
+ }
+ for (LedgerAccount p : createdParents)
+ acc.propagateAmountsTo(p);
+
+ return acc;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.json;
+
+import androidx.annotation.NonNull;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ParsedBalance {
+ private ParsedQuantity aquantity;
+ private String acommodity;
+ public ParsedQuantity getAquantity() {
+ return aquantity;
+ }
+ public void setAquantity(ParsedQuantity aquantity) {
+ this.aquantity = aquantity;
+ }
+ @NonNull
+ public String getAcommodity() {
+ return (acommodity == null) ? "" : acommodity;
+ }
+ public void setAcommodity(String acommodity) {
+ this.acommodity = acommodity;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.json;
+
+import net.ktnx.mobileledger.json.ParsedBalance;
+
+import java.util.List;
+
+public class ParsedLedgerAccount {
+ private String aname;
+ private int anumpostings;
+ private List<ParsedBalance> aibalance;
+ public String getAname() {
+ return aname;
+ }
+ public void setAname(String aname) {
+ this.aname = aname;
+ }
+ public int getAnumpostings() {
+ return anumpostings;
+ }
+ public void setAnumpostings(int anumpostings) {
+ this.anumpostings = anumpostings;
+ }
+ public List<ParsedBalance> getAibalance() {
+ return aibalance;
+ }
+ public void setAibalance(List<ParsedBalance> aibalance) {
+ this.aibalance = aibalance;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.json;
+
+import net.ktnx.mobileledger.json.v1_15.ParsedQuantity;
+import net.ktnx.mobileledger.json.v1_15.ParsedStyle;
+
+public class ParsedPrice {
+ private String tag;
+ private Contents contents;
+ public ParsedPrice() {
+ tag = "NoPrice";
+ }
+ public Contents getContents() {
+ return contents;
+ }
+ public void setContents(Contents contents) {
+ this.contents = contents;
+ }
+ public String getTag() {
+ return tag;
+ }
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+ private static class Contents {
+ private ParsedPrice aprice;
+ private net.ktnx.mobileledger.json.v1_15.ParsedQuantity aquantity;
+ private String acommodity;
+ private boolean aismultiplier;
+ private net.ktnx.mobileledger.json.v1_15.ParsedStyle astyle;
+ public Contents() {
+ acommodity = "";
+ }
+ public ParsedPrice getAprice() {
+ return aprice;
+ }
+ public void setAprice(ParsedPrice aprice) {
+ this.aprice = aprice;
+ }
+ public net.ktnx.mobileledger.json.v1_15.ParsedQuantity getAquantity() {
+ return aquantity;
+ }
+ public void setAquantity(ParsedQuantity aquantity) {
+ this.aquantity = aquantity;
+ }
+ public String getAcommodity() {
+ return acommodity;
+ }
+ public void setAcommodity(String acommodity) {
+ this.acommodity = acommodity;
+ }
+ public boolean isAismultiplier() {
+ return aismultiplier;
+ }
+ public void setAismultiplier(boolean aismultiplier) {
+ this.aismultiplier = aismultiplier;
+ }
+ public net.ktnx.mobileledger.json.v1_15.ParsedStyle getAstyle() {
+ return astyle;
+ }
+ public void setAstyle(ParsedStyle astyle) {
+ this.astyle = astyle;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2020 Damyan Ivanov.
+ * This file is part of MoLe.
+ * MoLe is free software: you can distribute it and/or modify it
+ * under the term of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your opinion), any later version.
+ *
+ * MoLe is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License terms for details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MoLe. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package net.ktnx.mobileledger.json;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ParsedQuantity {
+ private long decimalMantissa;
+ private int decimalPlaces;
+ public ParsedQuantity() {
+ }
+ public ParsedQuantity(String input) {
+ parseString(input);
+ }
+ public long getDecimalMantissa() {
+ return decimalMantissa;
+ }
+ public void setDecimalMantissa(long decimalMantissa) {
+ this.decimalMantissa = decimalMantissa;
+ }
+ public int getDecimalPlaces() {
+ return decimalPlaces;
+ }
+ public void setDecimalPlaces(int decimalPlaces) {
+ this.decimalPlaces = decimalPlaces;
+ }
+ public float asFloat() {
+ return (float) (decimalMantissa * Math.pow(10, -decimalPlaces));
+ }
+ public void parseString(String input) {
+ int pointPos = input.indexOf('.');
+ if (pointPos >= 0) {
+ String integral = input.replace(".", "");
+ decimalMantissa = Long.parseLong(integral);
+ decimalPlaces = input.length() - pointPos - 1;
+ }
+ else {
+ decimalMantissa = Long.parseLong(input);
+ decimalPlaces = 0;
+ }
+ }
+}
package net.ktnx.mobileledger.json.v1_15;
-import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import java.io.IOException;
import java.io.InputStream;
-import static net.ktnx.mobileledger.utils.Logger.debug;
-
-public class AccountListParser {
-
- private final MappingIterator<ParsedLedgerAccount> iterator;
+public class AccountListParser extends net.ktnx.mobileledger.json.AccountListParser {
public AccountListParser(InputStream input) throws IOException {
ObjectMapper mapper = new ObjectMapper();
iterator = reader.readValues(input);
}
- public ParsedLedgerAccount nextAccount() {
- if (!iterator.hasNext()) return null;
-
- ParsedLedgerAccount next = iterator.next();
-
- if (next.getAname().equalsIgnoreCase("root")) return nextAccount();
-
- debug("accounts", String.format("Got account '%s' [v1.15]", next.getAname()));
- return next;
- }
}
package net.ktnx.mobileledger.json.v1_15;
-import androidx.annotation.NonNull;
-
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ParsedBalance {
- private ParsedQuantity aquantity;
- private String acommodity;
+public class ParsedBalance extends net.ktnx.mobileledger.json.ParsedBalance {
private ParsedStyle astyle;
public ParsedBalance() {
}
- public ParsedQuantity getAquantity() {
- return aquantity;
- }
- public void setAquantity(ParsedQuantity aquantity) {
- this.aquantity = aquantity;
- }
- @NonNull
- public String getAcommodity() {
- return (acommodity == null) ? "" : acommodity;
- }
- public void setAcommodity(String acommodity) {
- this.acommodity = acommodity;
- }
public ParsedStyle getAstyle() {
return astyle;
}
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ParsedLedgerAccount {
+public class ParsedLedgerAccount extends net.ktnx.mobileledger.json.ParsedLedgerAccount {
private List<ParsedBalance> aebalance;
- private List<ParsedBalance> aibalance;
- private String aname;
- private int anumpostings;
public ParsedLedgerAccount() {
}
- public int getAnumpostings() {
- return anumpostings;
- }
- public void setAnumpostings(int anumpostings) {
- this.anumpostings = anumpostings;
- }
public List<ParsedBalance> getAebalance() {
return aebalance;
}
public void setAebalance(List<ParsedBalance> aebalance) {
this.aebalance = aebalance;
}
- public List<ParsedBalance> getAibalance() {
- return aibalance;
- }
- public void setAibalance(List<ParsedBalance> aibalance) {
- this.aibalance = aibalance;
- }
- public String getAname() {
- return aname;
- }
- public void setAname(String aname) {
- this.aname = aname;
- }
-
}
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
-public class ParsedQuantity {
- private long decimalMantissa;
- private int decimalPlaces;
- public ParsedQuantity() {
- }
- public ParsedQuantity(String input) {
- parseString(input);
- }
- public long getDecimalMantissa() {
- return decimalMantissa;
- }
- public void setDecimalMantissa(long decimalMantissa) {
- this.decimalMantissa = decimalMantissa;
- }
- public int getDecimalPlaces() {
- return decimalPlaces;
- }
- public void setDecimalPlaces(int decimalPlaces) {
- this.decimalPlaces = decimalPlaces;
- }
- public float asFloat() {
- return (float) (decimalMantissa * Math.pow(10, -decimalPlaces));
- }
- public void parseString(String input) {
- int pointPos = input.indexOf('.');
- if (pointPos >= 0) {
- String integral = input.replace(".", "");
- decimalMantissa = Long.parseLong(integral);
- decimalPlaces = input.length() - pointPos - 1;
- }
- else {
- decimalMantissa = Long.parseLong(input);
- decimalPlaces = 0;
- }
- }
+public class ParsedQuantity extends net.ktnx.mobileledger.json.ParsedQuantity {
}