+
+ NewTransactionModel.Item head = viewModel.getItem(0);
+ head.ensureType(NewTransactionModel.ItemType.generalData);
+ final String transactionDescription =
+ extractStringFromMatches(m, patternHeader.getTransactionDescriptionMatchGroup(),
+ patternHeader.getTransactionDescription());
+ head.setDescription(transactionDescription);
+ Logger.debug("pattern", "Setting transaction description to " + transactionDescription);
+ final String transactionComment =
+ extractStringFromMatches(m, patternHeader.getTransactionCommentMatchGroup(),
+ patternHeader.getTransactionComment());
+ head.setTransactionComment(transactionComment);
+ Logger.debug("pattern", "Setting transaction comment to " + transactionComment);
+ head.setDate(transactionDate);
+ listAdapter.notifyItemChanged(0);
+
+ DB.get()
+ .getPatternDAO()
+ .getPatternWithAccounts(patternHeader.getId())
+ .observe(getViewLifecycleOwner(), entry -> {
+ int rowIndex = 0;
+ final boolean accountsInInitialState = viewModel.accountsInInitialState();
+ for (PatternAccount acc : entry.accounts) {
+ rowIndex++;
+
+ String accountName = extractStringFromMatches(m, acc.getAccountNameMatchGroup(),
+ acc.getAccountName());
+ String accountComment =
+ extractStringFromMatches(m, acc.getAccountCommentMatchGroup(),
+ acc.getAccountComment());
+ Float amount =
+ extractFloatFromMatches(m, acc.getAmountMatchGroup(), acc.getAmount());
+ if (amount != null && acc.getNegateAmount() != null && acc.getNegateAmount())
+ amount = -amount;
+
+ if (accountsInInitialState) {
+ NewTransactionModel.Item item = viewModel.getItem(rowIndex);
+ if (item == null) {
+ Logger.debug("pattern", String.format(Locale.US,
+ "Adding new account item [%s][c:%s][a:%s]", accountName,
+ accountComment, amount));
+ final LedgerTransactionAccount ledgerAccount =
+ new LedgerTransactionAccount(accountName);
+ ledgerAccount.setComment(accountComment);
+ if (amount != null)
+ ledgerAccount.setAmount(amount);
+ // TODO currency
+ viewModel.addAccount(ledgerAccount);
+ listAdapter.notifyItemInserted(viewModel.items.size() - 1);
+ }
+ else {
+ Logger.debug("pattern", String.format(Locale.US,
+ "Stamping account item #%d [%s][c:%s][a:%s]", rowIndex,
+ accountName, accountComment, amount));
+
+ item.setAccountName(accountName);
+ item.setComment(accountComment);
+ if (amount != null)
+ item.getAccount()
+ .setAmount(amount);
+
+ listAdapter.notifyItemChanged(rowIndex);
+ }
+ }
+ else {
+ final LedgerTransactionAccount transactionAccount =
+ new LedgerTransactionAccount(accountName);
+ transactionAccount.setComment(accountComment);
+ if (amount != null)
+ transactionAccount.setAmount(amount);
+ // TODO currency
+ Logger.debug("pattern", String.format(Locale.US,
+ "Adding trailing account item [%s][c:%s][a:%s]", accountName,
+ accountComment, amount));
+
+ viewModel.addAccount(transactionAccount);
+ listAdapter.notifyItemInserted(viewModel.items.size() - 1);
+ }
+ }
+
+ listAdapter.checkTransactionSubmittable();
+ });
+ }
+ private int extractIntFromMatches(Matcher m, Integer group, Integer literal) {
+ if (literal != null)
+ return literal;
+
+ if (group != null) {
+ int grp = group;
+ if (grp > 0 & grp <= m.groupCount())
+ try {
+ return Integer.parseInt(m.group(grp));
+ }
+ catch (NumberFormatException e) {
+ Snackbar.make(requireView(),
+ "Error extracting transaction date: " + e.getMessage(),
+ BaseTransientBottomBar.LENGTH_INDEFINITE)
+ .show();
+ }
+ }
+
+ return 0;
+ }
+ private String extractStringFromMatches(Matcher m, Integer group, String literal) {
+ if (literal != null)
+ return literal;
+
+ if (group != null) {
+ int grp = group;
+ if (grp > 0 & grp <= m.groupCount())
+ return m.group(grp);
+ }
+
+ return null;
+ }
+ private Float extractFloatFromMatches(Matcher m, Integer group, Float literal) {
+ if (literal != null)
+ return literal;
+
+ if (group != null) {
+ int grp = group;
+ if (grp > 0 & grp <= m.groupCount())
+ try {
+ return Float.valueOf(m.group(grp));
+ }
+ catch (NumberFormatException e) {
+ Snackbar.make(requireView(),
+ "Error extracting transaction amount: " + e.getMessage(),
+ BaseTransientBottomBar.LENGTH_INDEFINITE)
+ .show();
+ }
+ }
+
+ return null;