X-Git-Url: https://git.ktnx.net/?p=mobile-ledger.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fasync%2FRetrieveTransactionsTask.java;h=8d98dc63c89e920ce1128df939f0ee014b33805b;hp=ea648c17d3b376fb12edae9d9cd938688210e70a;hb=23b8360d4f884bbdb20cc2de1825486ef42f37d6;hpb=0996c57ac91f80b69373dc287469a56259a57e03 diff --git a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java index ea648c17..8d98dc63 100644 --- a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java +++ b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java @@ -50,14 +50,17 @@ import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.ArrayList; import java.util.HashMap; +import java.util.Locale; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static net.ktnx.mobileledger.utils.Logger.debug; + public class RetrieveTransactionsTask extends AsyncTask { - private static final int MATCHING_TRANSACTIONS_LIMIT = 50; + private static final int MATCHING_TRANSACTIONS_LIMIT = 150; private static final Pattern reComment = Pattern.compile("^\\s*;"); private static final Pattern reTransactionStart = Pattern.compile("([\\d.-]+)"); @@ -76,7 +79,7 @@ public class RetrieveTransactionsTask this.contextRef = contextRef; } private static void L(String msg) { - //Log.d("transaction-parser", msg); + //debug("transaction-parser", msg); } @Override protected void onProgressUpdate(Progress... values) { @@ -112,6 +115,7 @@ public class RetrieveTransactionsTask int maxTransactionId = Progress.INDETERMINATE; ArrayList accountList = new ArrayList<>(); HashMap accountNames = new HashMap<>(); + HashMap syntheticAccounts = new HashMap<>(); LedgerAccount lastAccount = null, prevAccount = null; boolean onlyStarred = Data.optShowOnlyStarred.get(); @@ -186,6 +190,9 @@ public class RetrieveTransactionsTask .setHasSubAccounts(prevAccount.isParentOf(lastAccount)); // make sure the parent account(s) are present, // synthesising them if necessary + // this happens when the (missing-in-HTML) parent account has + // only one child so we create a synthetic parent account record, + // copying the amounts when child's amounts are parsed String parentName = lastAccount.getParentName(); if (parentName != null) { Stack toAppend = new Stack<>(); @@ -195,16 +202,24 @@ public class RetrieveTransactionsTask parentName = new LedgerAccount(parentName).getParentName(); } + syntheticAccounts.clear(); while (!toAppend.isEmpty()) { String aName = toAppend.pop(); - LedgerAccount acc = new LedgerAccount(aName); - acc.setHiddenByStar(lastAccount.isHiddenByStar()); + LedgerAccount acc = profile.tryLoadAccount(db, aName); + if (acc == null) { + acc = new LedgerAccount(aName); + acc.setHiddenByStar(lastAccount.isHiddenByStar()); + acc.setExpanded(!lastAccount.hasSubAccounts() || + lastAccount.isExpanded()); + } acc.setHasSubAccounts(true); + acc.removeAmounts(); // filled below when amounts are parsed if ((!onlyStarred || !acc.isHiddenByStar()) && acc.isVisible(accountList)) accountList.add(acc); L(String.format("gap-filling with %s", aName)); accountNames.put(aName, null); profile.storeAccount(db, acc); + syntheticAccounts.put(aName, acc); } } @@ -230,9 +245,14 @@ public class RetrieveTransactionsTask if (currency == null) currency = ""; value = value.replace(',', '.'); L("curr=" + currency + ", value=" + value); + final float val = Float.parseFloat(value); profile.storeAccountValue(db, lastAccount.getName(), currency, - Float.valueOf(value)); - lastAccount.addAmount(Float.parseFloat(value), currency); + val); + lastAccount.addAmount(val, currency); + for (LedgerAccount syn : syntheticAccounts.values()) { + syn.addAmount(val, currency); + profile.storeAccountValue(db, syn.getName(), currency, val); + } } if (match_found) { @@ -248,7 +268,8 @@ public class RetrieveTransactionsTask if (m.find()) { transactionId = Integer.valueOf(m.group(1)); state = ParserState.EXPECTING_TRANSACTION_DESCRIPTION; - L(String.format("found transaction %d → expecting description", + L(String.format(Locale.ENGLISH, + "found transaction %d → expecting description", transactionId)); progress.setProgress(++processedTransactionCount); if (maxTransactionId < transactionId) @@ -285,9 +306,9 @@ public class RetrieveTransactionsTask return String.format("Error parsing date '%s'", date); } state = ParserState.EXPECTING_TRANSACTION_DETAILS; - L(String.format("transaction %d created for %s (%s) →" + - " expecting details", transactionId, date, - m.group(2))); + L(String.format(Locale.ENGLISH, + "transaction %d created for %s (%s) →" + + " expecting details", transactionId, date, m.group(2))); } break; @@ -338,8 +359,8 @@ public class RetrieveTransactionsTask transaction.addAccount( new LedgerTransactionAccount(acc_name, Float.valueOf(amount), currency)); - L(String.format("%d: %s = %s", transaction.getId(), - acc_name, amount)); + L(String.format(Locale.ENGLISH, "%d: %s = %s", + transaction.getId(), acc_name, amount)); } else throw new IllegalStateException(String.format( "Can't parse transaction %d " + "details: %s", @@ -509,13 +530,14 @@ public class RetrieveTransactionsTask if (transactionOrder == DetectedTransactionOrder.UNKNOWN) { if (orderAccumulator > 30) { transactionOrder = DetectedTransactionOrder.FILE; - Log.d("rtt", String.format( + debug("rtt", String.format(Locale.ENGLISH, "Detected native file order after %d transactions (factor %d)", processedTransactionCount, orderAccumulator)); + progress.setTotal(Data.transactions.size()); } else if (orderAccumulator < -30) { transactionOrder = DetectedTransactionOrder.REVERSE_CHRONOLOGICAL; - Log.d("rtt", String.format( + debug("rtt", String.format(Locale.ENGLISH, "Detected reverse chronological order after %d transactions (factor %d)", processedTransactionCount, orderAccumulator)); } @@ -542,8 +564,10 @@ public class RetrieveTransactionsTask progress.setTotal(maxTransactionId); } - if ((progress.getTotal() == Progress.INDETERMINATE) || - (progress.getTotal() < transaction.getId())) + + if ((transactionOrder != DetectedTransactionOrder.UNKNOWN) && + ((progress.getTotal() == Progress.INDETERMINATE) || + (progress.getTotal() < transaction.getId()))) progress.setTotal(transaction.getId()); progress.setProgress(++processedTransactionCount); @@ -564,12 +588,11 @@ public class RetrieveTransactionsTask return true; } - ; @SuppressLint("DefaultLocale") @Override protected String doInBackground(Void... params) { MobileLedgerProfile profile = Data.profile.get(); - Data.backgroundTaskCount.incrementAndGet(); + Data.backgroundTaskStarted(); try { if (!retrieveAccountList(profile) || !retrieveTransactionList(profile)) return retrieveTransactionListLegacy(profile); @@ -596,7 +619,7 @@ public class RetrieveTransactionsTask return "Operation cancelled"; } finally { - Data.backgroundTaskCount.decrementAndGet(); + Data.backgroundTaskFinished(); } } private MainActivity getContext() {