- private void startNewPatternActivity(String scanned) {
- Intent intent = new Intent(requireContext(), TemplatesActivity.class);
- Bundle args = new Bundle();
- args.putString(TemplatesActivity.ARG_ADD_TEMPLATE, scanned);
- requireContext().startActivity(intent, args);
- }
- private void alertNoPatternMatch(String scanned) {
- MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext());
- builder.setCancelable(true)
- .setMessage(R.string.no_pattern_matches)
- .setPositiveButton(R.string.add_button,
- (dialog, which) -> startNewPatternActivity(scanned))
- .create()
- .show();
- }
- protected void onQrScanned(String text) {
- Logger.debug("qr", String.format("Got QR scan result [%s]", text));
-
- if (Misc.emptyIsNull(text) == null)
- return;
-
- LiveData<List<TemplateHeader>> allPatterns = DB.get()
- .getPatternDAO()
- .getPatterns();
- allPatterns.observe(getViewLifecycleOwner(), patternHeaders -> {
- ArrayList<TemplateHeader> matchingPatterns = new ArrayList<>();
-
- for (TemplateHeader ph : patternHeaders) {
- String patternSource = ph.getRegularExpression();
- if (Misc.emptyIsNull(patternSource) == null)
- continue;
- try {
- Pattern pattern = Pattern.compile(patternSource);
- Matcher matcher = pattern.matcher(text);
- if (!matcher.matches())
- continue;
-
- Logger.debug("pattern",
- String.format("Pattern '%s' [%s] matches '%s'", ph.getName(),
- patternSource, text));
- matchingPatterns.add(ph);
- }
- catch (ParcelFormatException e) {
- // ignored
- Logger.debug("pattern",
- String.format("Error compiling regular expression '%s'", patternSource),
- e);
- }
- }
-
- if (matchingPatterns.isEmpty())
- alertNoPatternMatch(text);
- else if (matchingPatterns.size() == 1)
- applyPattern(matchingPatterns.get(0), text);
- else
- choosePattern(matchingPatterns, text);
- });
- }
- private void choosePattern(ArrayList<TemplateHeader> matchingPatterns, String matchedText) {
- final String patternNameColumn = "name";
- AbstractCursor cursor = new AbstractCursor() {
- @Override
- public int getCount() {
- return matchingPatterns.size();
- }
- @Override
- public String[] getColumnNames() {
- return new String[]{"_id", patternNameColumn};
- }
- @Override
- public String getString(int column) {
- if (column == 0)
- return String.valueOf(getPosition());
- return matchingPatterns.get(getPosition())
- .getName();
- }
- @Override
- public short getShort(int column) {
- if (column == 0)
- return (short) getPosition();
- return -1;
- }
- @Override
- public int getInt(int column) {
- return getShort(column);
- }
- @Override
- public long getLong(int column) {
- return getShort(column);
- }
- @Override
- public float getFloat(int column) {
- return getShort(column);
- }
- @Override
- public double getDouble(int column) {
- return getShort(column);
- }
- @Override
- public boolean isNull(int column) {
- return false;
- }
- @Override
- public int getColumnCount() {
- return 2;
- }
- };
-
- 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);
- dialog.dismiss();
- })
- .create()
- .show();
- }
- private void applyPattern(TemplateHeader 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 (TemplateAccount 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;
- }