diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DeutscheBankPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DeutscheBankPDFExtractor.java index 5ad713d84a..edc27fed46 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DeutscheBankPDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DeutscheBankPDFExtractor.java @@ -387,6 +387,7 @@ private void addAccountStatementTransaction() }) .section("date", "note", "sign", "amount", "note1") // + .documentContext("currency", "year") .match("^[\\d]{2}\\.[\\d]{2}\\. (?[\\d]{2}\\.[\\d]{2}\\.) " // + "(SEPA )?" // + "(?(Dauerauftrag" // @@ -399,7 +400,6 @@ private void addAccountStatementTransaction() + "(?(\\-|\\+)) (?[\\.,\\d]+)$") .match("^(?.*)$") // .assign((t, v) -> { - Map context = type.getCurrentContext(); // Is sign --> "-" change from DEPOSIT to REMOVAL if ("-".equals(v.get("sign"))) t.setType(AccountTransaction.Type.REMOVAL); @@ -414,8 +414,8 @@ private void addAccountStatementTransaction() if (v.get("note").startsWith("Verwendungszweck")) v.put("note", ""); - t.setDateTime(asDate(v.get("date") + context.get("year"))); - t.setCurrencyCode(context.get("currency")); + t.setDateTime(asDate(v.get("date") + v.get("year"))); + t.setCurrencyCode(v.get("currency")); t.setAmount(asAmount(v.get("amount"))); t.setNote(v.get("note")); @@ -447,7 +447,7 @@ private void addAccountStatementTransaction() if (t.getCurrencyCode() != null && t.getAmount() == 0) item.setFailureMessage(Messages.MsgErrorTransactionTypeNotSupported); - if (Boolean.valueOf(type.getCurrentContext().getBoolean("skipTransaction"))) + if (type.getCurrentContext().getBoolean("skipTransaction")) return null; // If we have multiple entries in the document, diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFParser.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFParser.java index 8a6dab429e..96b7acab64 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFParser.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFParser.java @@ -105,7 +105,7 @@ public void parse(String filename, List items, String text) parseContext(context, lines); for (Block block : blocks) - block.parse(filename, items, lines); + block.parse(filename, context, items, lines); } /** @@ -160,7 +160,7 @@ public void set(Transaction transaction) this.transaction = transaction; } - public void parse(String filename, List items, String[] lines) + public void parse(String filename, DocumentContext documentContext, List items, String[] lines) { List blocks = new ArrayList<>(); @@ -193,7 +193,7 @@ public void parse(String filename, List items, String[] lines) endLine = Math.min(endLine, startLine + maxSize - 1); } - transaction.parse(filename, items, lines, startLine, endLine); + transaction.parse(filename, documentContext, items, lines, startLine, endLine); } } @@ -268,7 +268,8 @@ private final Transaction internalOneOf(boolean isOptional, sections.add(new Section(this, null) { @Override - public void parse(String filename, String[] lines, int lineNo, int lineNoEnd, TypedMap ctx, T target) + public void parse(String filename, DocumentContext documentContext, String[] lines, int lineNo, + int lineNoEnd, TypedMap ctx, T target) { List errors = new ArrayList<>(); @@ -276,7 +277,7 @@ public void parse(String filename, String[] lines, int lineNo, int lineNoEnd, Ty { try { - section.parse(filename, lines, lineNo, lineNoEnd, ctx, target); + section.parse(filename, documentContext, lines, lineNo, lineNoEnd, ctx, target); // if parsing was successful, then return return; @@ -315,14 +316,15 @@ public Transaction wrap(BiFunction wrapper) return this; } - public void parse(String filename, List items, String[] lines, int lineNoStart, int lineNoEnd) + public void parse(String filename, DocumentContext documentContext, List items, String[] lines, + int lineNoStart, int lineNoEnd) { TypedMap txContext = new TypedMap(); T target = supplier.get(); for (Section section : sections) - section.parse(filename, lines, lineNoStart, lineNoEnd, txContext, target); + section.parse(filename, documentContext, lines, lineNoStart, lineNoEnd, txContext, target); for (Consumer conclude : concludes) conclude.accept(target); @@ -457,7 +459,11 @@ public Set> entrySet() private boolean isOptional = false; private boolean isMultipleTimes = false; private Transaction transaction; + /** attributes extracted from regular pattern */ private String[] attributes; + /** attributes mixed in from the document context */ + private String[] documentAttributes; + private List pattern = new ArrayList<>(); private BiConsumer assignment; @@ -473,6 +479,12 @@ public Section attributes(String... attributes) return this; } + public Section documentContext(String... documentAttributes) + { + this.documentAttributes = documentAttributes; + return this; + } + public Section optional() { this.isOptional = true; @@ -503,7 +515,8 @@ public Transaction assign(BiConsumer assignment) return transaction; } - public void parse(String filename, String[] lines, int lineNo, int lineNoEnd, TypedMap txContext, T target) + public void parse(String filename, DocumentContext documentContext, String[] lines, int lineNo, int lineNoEnd, + TypedMap txContext, T target) { if (assignment == null) throw new IllegalArgumentException("Assignment function missing"); //$NON-NLS-1$ @@ -533,6 +546,22 @@ public void parse(String filename, String[] lines, int lineNo, int lineNoEnd, Ty Messages.MsgErrorMissingValueMatches, values.keySet().toString(), Arrays.toString(attributes), filename, lineNo + 1, lineNoEnd + 1)); + // enrich extracted values with context values + if (documentAttributes != null) + { + for (String attribute : documentAttributes) + { + if (!documentContext.containsKey(attribute)) + { + throw new IllegalArgumentException(MessageFormat.format( + Messages.MsgErrorMissingValueMatches, values.keySet().toString(), + attribute, filename, lineNo + 1, lineNoEnd + 1)); + } + + values.put(attribute, documentContext.get(attribute)); + } + } + assignment.accept(target, new ParsedData(values, lineNo, lineNoEnd, filename, txContext)); // if there might be multiple occurrences that match,