+ @Override
+ public double getDouble(int column) {
+ return -1;
+ }
+ @Override
+ public boolean isNull(int column) {
+ return false;
+ }
+ };
+
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
+ builder.setCancelable(true)
+ .setTitle(R.string.choose_pattern_to_apply)
+ .setSingleChoiceItems(cursor, -1, patternNameColumn,
+ (dialog, which) -> applyPattern(matchingPatterns.get(which), matchedText))
+ .create()
+ .show();
+ }
+ private void applyPattern(PatternHeader patternHeader, String text) {
+ Pattern pattern = Pattern.compile(patternHeader.getRegularExpression());
+
+ Matcher m = pattern.matcher(text);
+
+ if (!m.matches()) {
+ Snackbar.make(requireView(), R.string.pattern_does_not_match,
+ BaseTransientBottomBar.LENGTH_INDEFINITE)
+ .show();
+ return;
+ }
+
+ SimpleDate transactionDate;
+ {
+ int day = extractIntFromMatches(m, patternHeader.getDateDayMatchGroup(),
+ patternHeader.getDateDay());
+ int month = extractIntFromMatches(m, patternHeader.getDateMonthMatchGroup(),
+ patternHeader.getDateMonth());
+ int year = extractIntFromMatches(m, patternHeader.getDateYearMatchGroup(),
+ patternHeader.getDateYear());
+
+ SimpleDate today = SimpleDate.today();
+ if (year <= 0)
+ year = today.year;
+ if (month <= 0)
+ month = today.month;
+ if (day <= 0)
+ day = today.day;
+
+ transactionDate = new SimpleDate(year, month, day);
+
+ Logger.debug("pattern", "setting transaction date to " + transactionDate);
+ }
+
+ 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();
+ }
+ }