From ebcb8508704b882cbd9c692920ce760fb1c6ed28 Mon Sep 17 00:00:00 2001 From: Alexander Ott <45203494+Nirus2000@users.noreply.github.com> Date: Mon, 30 Dec 2024 09:05:43 +0100 Subject: [PATCH] Modify DKB PDF-Importer to support new transaction (#4430) Closes #4427 --- .../pdf/dkb/DkbPDFExtractorTest.java | 34 +++++++++ .../pdf/dkb/KreditKontoauszug07.txt | 75 +++++++++++++++++++ .../datatransfer/pdf/DkbPDFExtractor.java | 29 +++---- 3 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/KreditKontoauszug07.txt diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/DkbPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/DkbPDFExtractorTest.java index f0abdf7ddb..0bf55939be 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/DkbPDFExtractorTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/DkbPDFExtractorTest.java @@ -5164,4 +5164,38 @@ public void testKreditKontoauszug06() assertThat(transaction.getSource(), is("KreditKontoauszug06.txt")); assertThat(transaction.getNote(), is("ZAHLUNG6")); } + + @Test + public void testKreditKontoauszug07() + { + DkbPDFExtractor extractor = new DkbPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "KreditKontoauszug07.txt"), + errors); + + assertThat(errors, empty()); + assertThat(countSecurities(results), is(0L)); + assertThat(countBuySell(results), is(0L)); + assertThat(countAccountTransactions(results), is(4L)); + assertThat(results.size(), is(4)); + new AssertImportActions().check(results, CurrencyUnit.EUR); + + // assert transaction + assertThat(results, hasItem(deposit(hasDate("2024-11-29"), hasAmount("EUR", 392.31), // + hasSource("KreditKontoauszug07.txt"), hasNote("Lastschrift")))); + + // assert transaction + assertThat(results, hasItem(removal(hasDate("2024-11-29"), hasAmount("EUR", 500.00), // + hasSource("KreditKontoauszug07.txt"), hasNote("PAYPAL *abc, 35314369001")))); + + // assert transaction + assertThat(results, hasItem(removal(hasDate("2024-12-23"), hasAmount("EUR", 134.47), // + hasSource("KreditKontoauszug07.txt"), hasNote("PAYPAL *abc, 35314369001")))); + + // assert transaction + assertThat(results, hasItem(removal(hasDate("2024-12-27"), hasAmount("EUR", 500.00), // + hasSource("KreditKontoauszug07.txt"), hasNote("PAYPAL *abc, 35314369001")))); + } } diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/KreditKontoauszug07.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/KreditKontoauszug07.txt new file mode 100644 index 0000000000..0efaee81a4 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dkb/KreditKontoauszug07.txt @@ -0,0 +1,75 @@ +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +14460 Potsdam Kontaktdaten +Adresse Lufthansa Miles & More Credit Card Service +Postfach 2620 + 94016 Passau +Telefon: 069 - 667 888 666 +Fax: 069 - 667 888 930 +E-Mail: service@lufthansacard.de +Herrn +Xxx Yyyy +Wohnstraße 1 +12345 Irgendwo +Abrechnungsnummer: 21234567 +Ihre Abrechnung vom 28.11.2024 bis 27.12.2024 Abrechnungsdatum: 27. Dezember 2024 +Miles & More Credit Card: 5310 11XX XXXX 1234 +Seite 1 von 2 Servicekarten-Nr.: 212345678901238 +Karteninhaber: Xxx Yyyy +Datum Datum Angabe des Unternehmens / Währung Betrag Kurs Betrag in +Beleg Buchung Verwendungszweck EUR +28.11.24 Saldo letzte Abrechnung 392,31 - +28.11.24 29.11.24 Lastschrift 392,31 + +28.11.24 29.11.24 PAYPAL *abc, 35314369001 500,00 - + Prämienmeilen +250 +20.12.24 23.12.24 PAYPAL *abc, 35314369001 134,47 - + Prämienmeilen +67 +22.12.24 27.12.24 PAYPAL *abc, 35314369001 500,00 - + Prämienmeilen +250 +Neuer Saldo 1.134,47 - +Bitte prüfen Sie diese Abrechnung auf ihre Richtigkeit. Eventuelle Reklamationen müssen umgehend nach Zugang dieser Abrechnung bei +der DKB AG eingereicht werden. Nutzen Sie dazu einfach den Reklamationsservice in Ihrem Online-Kartenkonto auf der Seite +"Kartenumsätze". +Den fälligen Betrag ziehen wir zum Zahlungstermin per Hinweis: +Lastschrift von Ihrem Konto Nr. XXXX XX12 34, BLZ 120 300 00 Alle Zinsen und Entgelte finden Sie jederzeit +ein. im Preis- und Leistungsverzeichnis der DKB AG auf +miles-and-more-kreditkarte.com/download. +Der monatliche Verfügungsrahmen Ihrer Lufthansa Senator +Credit Card beträgt 10.000 EUR. +Information zu Ihrem Miles & More Programm +Die mit dem Meilenzeichen gekennzeichneten Umsätze sind meilenfähig. +Die aus dieser Abrechnung resultierende Gutschrift von 567 Prämienmeilen wird auf Ihrem nächsten Miles & More Kontoauszug +ausgewiesen. +Für Umsätze mit dem Überweisungsservice erhalten Sie 1 Meile pro 1 Euro Umsatz. +Für Ihre Umsätze in einem Lufthansa WorldShop erhalten Sie insgesamt je 2 € Umsatz dauerhaft 5 Prämienmeilen (3 Meilen davon sind +in der zuvor genannten Meilensumme enthalten und 2 Meilen sind in Ihrem Miles & More Konto ersichtlich). +Kartenausgebende Bank: Korrespondenzadresse: Vorstand: Vorsitzender des Handelsregister: Umsatzsteuer- +Deutsche Kreditbank AG Postfach 2620 Dr. Sven Deglow (Vorsitzender), Aufsichtsrates: Amtsgericht Identifikationsnummer: +Taubenstr. 7-9 94016 Passau Tilo Hacke, Jan Walther, Stephan Winkelmeier Berlin-Charlottenburg DE 137 17 87 46 +10117 Berlin Arnulf Keese, Kristina Trink HRB: 34165 B +14460 Potsdam Kontaktdaten +Adresse Lufthansa Miles & More Credit Card Service +Postfach 2620 + 94016 Passau +Telefon: 069 - 667 888 666 +Fax: 069 - 667 888 930 +E-Mail: service@lufthansacard.de +Herrn +Xxx Yyyy +Wohnstraße 1 +12345 Irgendwo +Abrechnungsnummer: 21234567 +Ihre Abrechnung vom 28.11.2024 bis 27.12.2024 Abrechnungsdatum: 27. Dezember 2024 +Miles & More Credit Card: 5310 11XX XXXX 1234 +Seite 2 von 2 Servicekarten-Nr.: 212345678901238 +Karteninhaber: Xxx Yyyy +Haben Sie Prämienmeilen mit MilesPay eingelöst, wird der Eurobetrag, der dem gewählten Meilenwert entspricht, Ihrem Kreditkartenkonto +innerhalb von 2 bis 3 Werktagen wieder gutgeschrieben. Diese Rückbuchung erscheint als „MilesPay Gutschrift“ auf Ihrer +Kreditkartenabrechnung. +Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetzes entschädigungsfähig. Nähere Informationen entnehmen Sie +dem Informationsbogen für Einleger, den Sie auf miles-and-more-kreditkarte.com/download finden. +Kartenausgebende Bank: Korrespondenzadresse: Vorstand: Vorsitzender des Handelsregister: Umsatzsteuer- +Deutsche Kreditbank AG Postfach 2620 Dr. Sven Deglow (Vorsitzender), Aufsichtsrates: Amtsgericht Identifikationsnummer: +Taubenstr. 7-9 94016 Passau Tilo Hacke, Jan Walther, Stephan Winkelmeier Berlin-Charlottenburg DE 137 17 87 46 +10117 Berlin Arnulf Keese, Kristina Trink HRB: 34165 B diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DkbPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DkbPDFExtractor.java index 7ec2b40ce8..68487d52f9 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DkbPDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DkbPDFExtractor.java @@ -1225,14 +1225,15 @@ private void addCreditcardStatementTransaction() documentContext -> documentContext // // @formatter:off // DKB-VISA-Card beträgt 100 EUR. Soweit auf dem Umsatzsteuernummer: DE137178746 + // Credit Card beträgt 10.000 EUR. // @formatter:on .section("currency") // - .match("^DKB\\-VISA\\-Card betr.gt [\\.,\\d]+ (?[\\w]{3})\\. .*$") // + .match("^.*Card betr.gt [\\.,\\d]+ (?[\\w]{3})\\..*$") // .assign((ctx, v) -> ctx.put("currency", asCurrencyCode(v.get("currency"))))); this.addDocumentTyp(type); - Block depositBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2}(?! Habenzins).* [\\.,\\d]+\\+$"); + Block depositBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2}(?! Habenzins).* [\\.,\\d]+([\\s])?\\+$"); type.addBlock(depositBlock); depositBlock.set(new Transaction() @@ -1248,7 +1249,7 @@ private void addCreditcardStatementTransaction() .documentContext("currency") // .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) " // + "(?Ausgleich Kreditkarte gem\\. Abrechnung) v\\. " // - + "(?[\\.,\\d]+)\\+$") // + + "(?[\\.,\\d]+)([\\s])?\\+$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1261,7 +1262,7 @@ private void addCreditcardStatementTransaction() .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2})" // + "(?(?! Habenzins).*) " // + "[\\w]{3} [\\.,\\d]+ [\\.,\\d]+ " // - + "(?[\\.,\\d]+)\\+$") // + + "(?[\\.,\\d]+)([\\s])?\\+$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1282,7 +1283,7 @@ private void addCreditcardStatementTransaction() .documentContext("currency") // .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2})" // + "(?(?! Habenzins).*) " // - + "(?[\\.,\\d]+)\\+$") // + + "(?[\\.,\\d]+)([\\s])?\\+$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1301,7 +1302,7 @@ private void addCreditcardStatementTransaction() .wrap(TransactionItem::new)); - Block interestBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2} Habenzins auf [\\d]+ Tage [\\.,\\d]+\\+$"); + Block interestBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2} Habenzins auf [\\d]+ Tage [\\.,\\d]+([\\s])?\\+$"); type.addBlock(interestBlock); interestBlock.set(new Transaction() @@ -1315,7 +1316,7 @@ private void addCreditcardStatementTransaction() .documentContext("currency") // .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) " // + "(?Habenzins auf [\\d]+ Tage) " // - + "(?[\\.,\\d]+)\\+$") // + + "(?[\\.,\\d]+)([\\s])?\\+$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1325,7 +1326,7 @@ private void addCreditcardStatementTransaction() .wrap(TransactionItem::new)); - Block taxesBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) Abgeltungsteuer [\\.,\\d]+ \\-$"); + Block taxesBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) Abgeltungsteuer [\\.,\\d]+([\\s])?\\-$"); type.addBlock(taxesBlock); taxesBlock.set(new Transaction() @@ -1339,7 +1340,7 @@ private void addCreditcardStatementTransaction() .documentContext("currency") // .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) " // + "(?Abgeltungsteuer) " // - + "(?[\\.,\\d]+) \\-$") // + + "(?[\\.,\\d]+)([\\s])?\\-$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1349,7 +1350,7 @@ private void addCreditcardStatementTransaction() .wrap(TransactionItem::new)); - Block removalBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2}(?! (Abgeltungsteuer|Kartenpreis|PIN\\-Geb.hr)).* [\\.,\\d]+ \\-$"); + Block removalBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2}(?! (Abgeltungsteuer|Kartenpreis|PIN\\-Geb.hr)).* [\\.,\\d]+([\\s])?\\-$"); type.addBlock(removalBlock); removalBlock.set(new Transaction() @@ -1367,7 +1368,7 @@ private void addCreditcardStatementTransaction() .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2})" // + "(?(?! (Abgeltungsteuer|Kartenpreis|PIN\\-Geb.hr)).*) " // + "[\\w]{3} [\\.,\\d]+ [\\.,\\d]+ " // - + "(?[\\.,\\d]+) \\-$") // + + "(?[\\.,\\d]+)([\\s])?\\-$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1389,7 +1390,7 @@ private void addCreditcardStatementTransaction() .documentContext("currency") // .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2})" // + "(?(?! (Abgeltungsteuer|Kartenpreis|PIN\\-Geb.hr)).*) " // - + "(?[\\.,\\d]+) \\-$") // + + "(?[\\.,\\d]+)([\\s])?\\-$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); @@ -1408,7 +1409,7 @@ private void addCreditcardStatementTransaction() .wrap(TransactionItem::new)); - Block feeBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (Kartenpreis|PIN\\-Geb.hr) [\\.,\\d]+ \\-$"); + Block feeBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} [\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (Kartenpreis|PIN\\-Geb.hr) [\\.,\\d]+([\\s])?\\-$"); type.addBlock(feeBlock); feeBlock.set(new Transaction() @@ -1421,7 +1422,7 @@ private void addCreditcardStatementTransaction() .section("date", "note", "amount") // .documentContext("currency") // .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{2} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) " // - + "(?(Kartenpreis|PIN\\-Geb.hr)) (?[\\.,\\d]+) \\-$") // + + "(?(Kartenpreis|PIN\\-Geb.hr)) (?[\\.,\\d]+)([\\s])?\\-$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount")));