- int maxTransactionId = Progress.INDETERMINATE;
- success = false;
- try {
- HttpURLConnection http =
- NetworkUtil.prepare_connection(params[0].getBackendPref(), "journal");
- http.setAllowUserInteraction(false);
- publishProgress(progress);
- TransactionListFragment ctx = getContext();
- if (ctx == null) return null;
- try (SQLiteDatabase db = MLDB.getWritableDatabase()) {
- try (InputStream resp = http.getInputStream()) {
- if (http.getResponseCode() != 200) throw new IOException(
- String.format("HTTP error %d", http.getResponseCode()));
- db.beginTransaction();
- try {
- db.execSQL("UPDATE transactions set keep=0");
-
- int state = ParserState.EXPECTING_JOURNAL;
- String line;
- BufferedReader buf =
- new BufferedReader(new InputStreamReader(resp, "UTF-8"));
-
- int processedTransactionCount = 0;
- int transactionId = 0;
- int matchedTransactionsCount = 0;
- LedgerTransaction transaction = null;
- LINES:
- while ((line = buf.readLine()) != null) {
- if (isCancelled()) break;
- Matcher m;
- //L(String.format("State is %d", state));
- switch (state) {
- case ParserState.EXPECTING_JOURNAL:
- if (!line.isEmpty() && (line.charAt(0) == ' ')) continue;
- if (line.equals("<h2>General Journal</h2>")) {
- state = ParserState.EXPECTING_TRANSACTION;
- L("→ expecting transaction");
- }
- break;
- case ParserState.EXPECTING_TRANSACTION:
- if (!line.isEmpty() && (line.charAt(0) == ' ')) continue;
- m = transactionStartPattern.matcher(line);
- if (m.find()) {
- transactionId = Integer.valueOf(m.group(1));
- state = ParserState.EXPECTING_TRANSACTION_DESCRIPTION;
- L(String.format(
- "found transaction %d → expecting " + "description",
- transactionId));
- progress.setProgress(++processedTransactionCount);
- if (maxTransactionId < transactionId)
- maxTransactionId = transactionId;
- if ((progress.getTotal() == Progress.INDETERMINATE) ||
- (progress.getTotal() < transactionId))
- progress.setTotal(transactionId);
- publishProgress(progress);
- }
- m = endPattern.matcher(line);
- if (m.find()) {
- L("--- transaction list complete ---");
- success = true;
- break LINES;
- }
- break;
- case ParserState.EXPECTING_TRANSACTION_DESCRIPTION:
- if (!line.isEmpty() && (line.charAt(0) == ' ')) continue;
- m = transactionDescriptionPattern.matcher(line);
- if (m.find()) {
- if (transactionId == 0)
- throw new TransactionParserException(
- "Transaction Id is 0 while expecting " +
- "description");
-
- transaction =
- new LedgerTransaction(transactionId, m.group(1),
- m.group(2));
- state = ParserState.EXPECTING_TRANSACTION_DETAILS;
- L(String.format("transaction %d created for %s (%s) →" +
- " expecting details", transactionId,
- m.group(1), m.group(2)));
- }
- break;
- case ParserState.EXPECTING_TRANSACTION_DETAILS:
- if (line.isEmpty()) {
- // transaction data collected
- if (transaction.existsInDb(db)) {
- db.execSQL("UPDATE transactions SET keep = 1 WHERE id" +
- "=?", new Integer[]{transaction.getId()});
- matchedTransactionsCount++;
-
- if (matchedTransactionsCount == 100) {
- db.execSQL("UPDATE transactions SET keep=1 WHERE " +
- "id < ?",
- new Integer[]{transaction.getId()});
- success = true;
- progress.setTotal(progress.getProgress());
- publishProgress(progress);
- break LINES;
- }
- }
- else {
- db.execSQL("DELETE from transactions WHERE id=?",
- new Integer[]{transaction.getId()});
- db.execSQL("DELETE from transaction_accounts WHERE " +
- "transaction_id=?",
- new Integer[]{transaction.getId()});
- transaction.insertInto(db);
- matchedTransactionsCount = 0;
- progress.setTotal(maxTransactionId);
- }
-
- state = ParserState.EXPECTING_TRANSACTION;
- L(String.format(
- "transaction %s saved → expecting " + "transaction",
- transaction.getId()));
+ progress.setState(ProgressState.FINISHED);
+ onProgressUpdate(progress);
+ }
+ private void retrieveTransactionListLegacy(List<LedgerAccount> accounts,
+ List<LedgerTransaction> transactions)
+ throws IOException, HTTPException {
+ Progress progress = Progress.indeterminate();
+ progress.setState(ProgressState.RUNNING);
+ progress.setTotal(expectedPostingsCount);
+ int maxTransactionId = -1;
+ HashMap<String, LedgerAccount> map = new HashMap<>();
+ LedgerAccount lastAccount = null;
+ ArrayList<LedgerAccount> syntheticAccounts = new ArrayList<>();
+
+ HttpURLConnection http = NetworkUtil.prepareConnection(profile, "journal");
+ http.setAllowUserInteraction(false);
+ publishProgress(progress);
+ if (http.getResponseCode() != 200)
+ throw new HTTPException(http.getResponseCode(), http.getResponseMessage());
+
+ try (InputStream resp = http.getInputStream()) {
+ if (http.getResponseCode() != 200)
+ throw new IOException(String.format("HTTP error %d", http.getResponseCode()));
+
+ int matchedTransactionsCount = 0;
+
+ ParserState state = ParserState.EXPECTING_ACCOUNT;
+ String line;
+ BufferedReader buf =
+ new BufferedReader(new InputStreamReader(resp, StandardCharsets.UTF_8));
+
+ int processedTransactionCount = 0;
+ int transactionId = 0;
+ LedgerTransaction transaction = null;
+ LINES:
+ while ((line = buf.readLine()) != null) {
+ throwIfCancelled();
+ Matcher m;
+ m = reComment.matcher(line);
+ if (m.find()) {
+ // TODO: comments are ignored for now
+// Log.v("transaction-parser", "Ignoring comment");
+ continue;
+ }
+ //L(String.format("State is %d", updating));
+ switch (state) {
+ case EXPECTING_ACCOUNT:
+ if (line.equals("<h2>General Journal</h2>")) {
+ state = ParserState.EXPECTING_TRANSACTION;
+ L("→ expecting transaction");
+ continue;
+ }
+ m = reAccountName.matcher(line);
+ if (m.find()) {
+ String acct_encoded = m.group(1);
+ String accName = URLDecoder.decode(acct_encoded, "UTF-8");
+ accName = accName.replace("\"", "");
+ L(String.format("found account: %s", accName));
+
+ lastAccount = map.get(accName);
+ if (lastAccount != null) {
+ L(String.format("ignoring duplicate account '%s'", accName));
+ continue;
+ }
+ String parentAccountName = LedgerAccount.extractParentName(accName);
+ LedgerAccount parentAccount;
+ if (parentAccountName != null) {
+ parentAccount = ensureAccountExists(parentAccountName, map,
+ syntheticAccounts);
+ }
+ else {
+ parentAccount = null;
+ }
+ lastAccount = new LedgerAccount(accName, parentAccount);
+
+ accounts.add(lastAccount);
+ map.put(accName, lastAccount);
+
+ state = ParserState.EXPECTING_ACCOUNT_AMOUNT;
+ L("→ expecting account amount");
+ }
+ break;
+
+ case EXPECTING_ACCOUNT_AMOUNT:
+ m = reAccountValue.matcher(line);
+ boolean match_found = false;
+ while (m.find()) {
+ throwIfCancelled();
+
+ match_found = true;
+ String value = Objects.requireNonNull(m.group(1));
+ String currency = m.group(2);
+ if (currency == null)
+ currency = "";
+
+ {
+ Matcher tmpM = reDecimalComma.matcher(value);
+ if (tmpM.find()) {
+ value = value.replace(".", "");
+ value = value.replace(',', '.');
+ }
+
+ tmpM = reDecimalPoint.matcher(value);
+ if (tmpM.find()) {
+ value = value.replace(",", "");
+ value = value.replace(" ", "");
+ }
+ }
+ L("curr=" + currency + ", value=" + value);
+ final float val = Float.parseFloat(value);
+ lastAccount.addAmount(val, currency);
+ for (LedgerAccount syn : syntheticAccounts) {
+ L(String.format(Locale.ENGLISH, "propagating %s %1.2f to %s",
+ currency, val, syn.getName()));
+ syn.addAmount(val, currency);
+ }
+ }
+
+ if (match_found) {
+ syntheticAccounts.clear();
+ state = ParserState.EXPECTING_ACCOUNT;
+ L("→ expecting account");
+ }
+
+ break;
+
+ case EXPECTING_TRANSACTION:
+ if (!line.isEmpty() && (line.charAt(0) == ' '))
+ continue;
+ m = reTransactionStart.matcher(line);
+ if (m.find()) {
+ transactionId = Integer.parseInt(Objects.requireNonNull(m.group(1)));
+ state = ParserState.EXPECTING_TRANSACTION_DESCRIPTION;
+ L(String.format(Locale.ENGLISH,
+ "found transaction %d → expecting description", transactionId));
+ progress.setProgress(++processedTransactionCount);
+ if (maxTransactionId < transactionId)
+ maxTransactionId = transactionId;
+ if ((progress.isIndeterminate()) ||
+ (progress.getTotal() < transactionId))
+ progress.setTotal(transactionId);
+ publishProgress(progress);
+ }
+ m = reEnd.matcher(line);
+ if (m.find()) {
+ L("--- transaction value complete ---");
+ break LINES;
+ }
+ break;
+
+ case EXPECTING_TRANSACTION_DESCRIPTION:
+ if (!line.isEmpty() && (line.charAt(0) == ' '))
+ continue;
+ m = reTransactionDescription.matcher(line);
+ if (m.find()) {
+ if (transactionId == 0)
+ throw new TransactionParserException(
+ "Transaction Id is 0 while expecting description");
+
+ String date = Objects.requireNonNull(m.group(1));
+ try {
+ int equalsIndex = date.indexOf('=');
+ if (equalsIndex >= 0)
+ date = date.substring(equalsIndex + 1);
+ transaction =
+ new LedgerTransaction(transactionId, date, m.group(2));
+ }
+ catch (ParseException e) {
+ throw new TransactionParserException(
+ String.format("Error parsing date '%s'", date));
+ }
+ state = ParserState.EXPECTING_TRANSACTION_DETAILS;
+ L(String.format(Locale.ENGLISH,
+ "transaction %d created for %s (%s) →" + " expecting details",
+ transactionId, date, m.group(2)));
+ }
+ break;
+
+ case EXPECTING_TRANSACTION_DETAILS:
+ if (line.isEmpty()) {
+ // transaction data collected
+
+ transaction.finishLoading();
+ transactions.add(transaction);
+
+ state = ParserState.EXPECTING_TRANSACTION;
+ L(String.format("transaction %s parsed → expecting transaction",
+ transaction.getLedgerId()));