Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.removal;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.sale;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.security;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.taxRefund;
import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransactions;
import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransfers;
import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countBuySell;
Expand Down Expand Up @@ -2915,4 +2916,27 @@ public void testGiroKontoauszug10()
assertThat(results, hasItem(deposit(hasDate("2025-10-15"), hasAmount("EUR", 600.00), //
hasSource("GiroKontoauszug10.txt"), hasNote("Überweisung von Dr. ICcCbCKba zlKgUWI NwzaZJPVb"))));
}

@Test
public void testGiroKontoauszug11()
{
var extractor = new DeutscheBankPDFExtractor(new Client());

List<Exception> errors = new ArrayList<>();

var results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "GiroKontoauszug11.txt"), errors);

assertThat(errors, empty());
assertThat(countSecurities(results), is(0L));
assertThat(countBuySell(results), is(0L));
assertThat(countAccountTransactions(results), is(1L));
assertThat(countAccountTransfers(results), is(0L));
assertThat(countItemsWithFailureMessage(results), is(0L));
assertThat(results.size(), is(1));
new AssertImportActions().check(results, "EUR");

// assert transaction
assertThat(results, hasItem(taxRefund(hasDate("2025-08-25"), hasAmount("EUR", 34.30), //
hasSource("GiroKontoauszug11.txt"), hasNote("Steuererstattung"))));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
PDFBox Version: 3.0.6
Portfolio Performance Version: 0.80.5.qualifier
System: linux | x86_64 | 21.0.8+9-LTS | Eclipse Adoptium
-----------------------------------------
Deutsche Bank AG
Filiale
Bankhausen
Bank-Platz 1
Herrn 11111 Bankhausen
Max Mustermann Frau Birgit Bankfrau
Musterstr 1 A Telefon (111) 1111-1111
11111 Bankhausen
24h-Kundenservice (069) 910-10000
29. August 2025
Kontoauszug
Kontoinhaber: Max Mustermann
Auszug Seite von IBAN Alter Saldo
1 1 1 DE12 3456 7890 1234 5678 01 EUR + 0,00
Buchung Valuta Vorgang Soll Haben
25.08. 25.08. Verwendungszweck/ Kundenreferenz + 34,30
2025 2025 Buchung Steuererstattung 2025 zu:
WP1224776431 01569286887 KESt: 32,51 EUR
SolZ: 1,79 EUR WKN: A0GLU5 TURKEY 06/36
Filialnummer Kontonummer Neuer Saldo
100 1234567 01 EUR + 34,30
BIC (SWIFT)
DEUTDEDBHAM
Wichtige Hinweise
Bitte erheben Sie Einwendungen gegen einzelne Buchungen unverzüglich. Schecks, Wechsel und sonstige Lastschriften schreiben wir unter dem Vorbehalt
des Eingangs gut. Der angegebene Kontostand berücksichtigt nicht die Wertstellung der Buchungen (siehe oben unter "Valuta").
Somit können bei Verfügungen1)
möglicherweise Zinsen für die Inanspruchnahme einer eingeräumten oder geduldeten Kontoüberziehung anfallen.
Die abgerechneten Leistungen sind als Bank- oder Finanzdienstleistungen von der Umsatzsteuer befreit, sofern Umsatzsteuer nicht gesondert
ausgewiesen ist. Umsatzsteuer ID Nr.: Deutsche Bank AG, 60262 Frankfurt DE114103379
Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetzes entschädigungsfähig. Nähere Informationen können dem "Informationsbogen
für den Einleger" entnommen werden.
1) Der Begriff umfasst unter anderem die relevanten Zahlungskontendienste "Bargeldauszahlung" und "Überweisung".
0000000003 / 06600800 / 20250830
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,13 @@ private void addDividendeTransaction()

private void addAccountStatementTransaction()
{
final var type = new DocumentType("Kontoauszug vom", //
final var type = new DocumentType("Kontoauszug", //
builder -> builder //
.section("currency") //
.match("^.*[\\d]{4} [\\d]{4} [\\d]{4} [\\d]{4} [\\d]{2} .*(?<currency>[A-Z]{3}) [\\-|\\+] [\\.,\\d]+.*$")
.assign((ctx, v) -> ctx.put("currency", asCurrencyCode(v.get("currency"))))

.section("year") //
.section("year").optional() //
.match("^Kontoauszug vom [\\d]{2}\\.[\\d]{2}\\.(?<year>[\\d]{4}) bis [\\d]{2}\\.[\\d]{2}\\.[\\d]{4}.*$")
.assign(Map::putAll));

Expand Down Expand Up @@ -471,8 +471,8 @@ private void addAccountStatementTransaction()
// 2025 2025 Dr. kQEbfBPDq ZgltrGG wBPgFcQwn
// @formatter:on
section -> section //
.attributes("date", "note", "type", "amount", "note1") //
.documentContext("currency", "year") //
.attributes("date", "note", "type", "amount", "year", "note1") //
.documentContext("currency") //
.match("^[\\d]{2}\\.[\\d]{2}\\. (?<date>[\\d]{2}\\.[\\d]{2}\\.) " //
+ "(SEPA )?" //
+ "(?<note>(Dauerauftrag" //
Expand All @@ -484,7 +484,7 @@ private void addAccountStatementTransaction()
+ "|Verwendungszweck\\/ Kundenreferenz" //
+ "|.bertrag \\(.berweisung\\) von) " //
+ "(?<type>(\\-|\\+)) (?<amount>[\\.,\\d]+)$")
.match("^[\\d]{4} [\\d]{4} (?<note1>.*)$") //
.match("^[\\d]{4} (?<year>[\\d]{4}) (Buchung )?(?<note1>.*)$") //
.assign((t, v) -> {
// @formatter:off
// Is type --> "-" change from DEPOSIT to REMOVAL
Expand All @@ -502,6 +502,16 @@ private void addAccountStatementTransaction()
if (v.get("note").startsWith("Verwendungszweck"))
v.put("note", "");

if (v.get("note1").contains("Steuererstattung"))
{
// @formatter:off
// Change from DEPOSIT to TAX_REFUND
// @formatter:on
t.setType(AccountTransaction.Type.TAX_REFUND);

v.put("note", "Steuererstattung");
}

t.setDateTime(asDate(v.get("date") + v.get("year")));
t.setCurrencyCode(v.get("currency"));
t.setAmount(asAmount(v.get("amount")));
Expand Down Expand Up @@ -571,6 +581,16 @@ private void addAccountStatementTransaction()
if (v.get("note").startsWith("Verwendungszweck"))
v.put("note", "");

if (v.get("note1").contains("Steuererstattung"))
{
// @formatter:off
// Change from DEPOSIT to TAX_REFUND
// @formatter:on
t.setType(AccountTransaction.Type.TAX_REFUND);

v.put("note", "Steuererstattung");
}

t.setDateTime(asDate(v.get("date") + v.get("year")));
t.setCurrencyCode(v.get("currency"));
t.setAmount(asAmount(v.get("amount")));
Expand Down