]> git.ktnx.net Git - mobile-ledger.git/blobdiff - app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java
JSON transaction parser: detect file-order stream and disable the early termination...
[mobile-ledger.git] / app / src / main / java / net / ktnx / mobileledger / async / RetrieveTransactionsTask.java
index 6a2700f36480c870d1fedc01517107c785bf2d83..ea648c17d3b376fb12edae9d9cd938688210e70a 100644 (file)
@@ -414,9 +414,26 @@ public class RetrieveTransactionsTask
                     else acc.removeAmounts();
 
                     profile.storeAccount(db, acc);
-                    for (ParsedBalance b : parsedAccount.getAebalance()) {
-                        profile.storeAccountValue(db, acc.getName(), b.getAcommodity(),
-                                b.getAquantity().asFloat());
+                    String lastCurrency = null;
+                    float lastCurrencyAmount = 0;
+                    for (ParsedBalance b : parsedAccount.getAibalance()) {
+                        final String currency = b.getAcommodity();
+                        final float amount = b.getAquantity().asFloat();
+                        if (currency.equals(lastCurrency)) lastCurrencyAmount += amount;
+                        else {
+                            if (lastCurrency != null) {
+                                profile.storeAccountValue(db, acc.getName(), lastCurrency,
+                                        lastCurrencyAmount);
+                                acc.addAmount(lastCurrencyAmount, lastCurrency);
+                            }
+                            lastCurrency = currency;
+                            lastCurrencyAmount = amount;
+                        }
+                    }
+                    if (lastCurrency != null) {
+                        profile.storeAccountValue(db, acc.getName(), lastCurrency,
+                                lastCurrencyAmount);
+                        acc.addAmount(lastCurrencyAmount, lastCurrency);
                     }
 
                     if (acc.isVisible(accountList)) accountList.add(acc);
@@ -475,17 +492,42 @@ public class RetrieveTransactionsTask
 
                 int processedTransactionCount = 0;
 
+                DetectedTransactionOrder transactionOrder = DetectedTransactionOrder.UNKNOWN;
+                int orderAccumulator = 0;
+                int lastTransactionId = 0;
+
                 while (true) {
                     throwIfCancelled();
                     ParsedLedgerTransaction parsedTransaction = parser.nextTransaction();
                     throwIfCancelled();
                     if (parsedTransaction == null) break;
+
                     LedgerTransaction transaction = parsedTransaction.asLedgerTransaction();
+                    if (transaction.getId() > lastTransactionId) orderAccumulator++;
+                    else orderAccumulator--;
+                    lastTransactionId = transaction.getId();
+                    if (transactionOrder == DetectedTransactionOrder.UNKNOWN) {
+                        if (orderAccumulator > 30) {
+                            transactionOrder = DetectedTransactionOrder.FILE;
+                            Log.d("rtt", String.format(
+                                    "Detected native file order after %d transactions (factor %d)",
+                                    processedTransactionCount, orderAccumulator));
+                        }
+                        else if (orderAccumulator < -30) {
+                            transactionOrder = DetectedTransactionOrder.REVERSE_CHRONOLOGICAL;
+                            Log.d("rtt", String.format(
+                                    "Detected reverse chronological order after %d transactions (factor %d)",
+                                    processedTransactionCount, orderAccumulator));
+                        }
+                    }
+
                     if (transaction.existsInDb(db)) {
                         profile.markTransactionAsPresent(db, transaction);
                         matchedTransactionsCount++;
 
-                        if (matchedTransactionsCount == MATCHING_TRANSACTIONS_LIMIT) {
+                        if ((transactionOrder == DetectedTransactionOrder.REVERSE_CHRONOLOGICAL) &&
+                            (matchedTransactionsCount == MATCHING_TRANSACTIONS_LIMIT))
+                        {
                             profile.markTransactionsBeforeTransactionAsPresent(db, transaction);
                             progress.setTotal(progress.getProgress());
                             publishProgress(progress);
@@ -521,6 +563,8 @@ public class RetrieveTransactionsTask
 
         return true;
     }
+
+    ;
     @SuppressLint("DefaultLocale")
     @Override
     protected String doInBackground(Void... params) {
@@ -561,6 +605,7 @@ public class RetrieveTransactionsTask
     private void throwIfCancelled() {
         if (isCancelled()) throw new OperationCanceledException(null);
     }
+    enum DetectedTransactionOrder {UNKNOWN, REVERSE_CHRONOLOGICAL, FILE}
 
     private enum ParserState {
         EXPECTING_ACCOUNT, EXPECTING_ACCOUNT_AMOUNT, EXPECTING_JOURNAL, EXPECTING_TRANSACTION,