diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/AdvanziaBankPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/AdvanziaBankPDFExtractorTest.java index a33b09f8cd..4aa99004f4 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/AdvanziaBankPDFExtractorTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/AdvanziaBankPDFExtractorTest.java @@ -8,6 +8,7 @@ import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.interest; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.removal; import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransactions; +import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransfers; import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countBuySell; import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countSecurities; import static org.hamcrest.CoreMatchers.is; @@ -20,7 +21,6 @@ import org.junit.Test; -import name.abuchen.portfolio.datatransfer.Extractor.Item; import name.abuchen.portfolio.datatransfer.actions.AssertImportActions; import name.abuchen.portfolio.datatransfer.pdf.AdvanziaBankPDFExtractor; import name.abuchen.portfolio.datatransfer.pdf.PDFInputFile; @@ -33,16 +33,17 @@ public class AdvanziaBankPDFExtractorTest @Test public void testKontoauszug01() { - AdvanziaBankPDFExtractor extractor = new AdvanziaBankPDFExtractor(new Client()); + var extractor = new AdvanziaBankPDFExtractor(new Client()); List errors = new ArrayList<>(); - List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoauszug01.txt"), errors); + var results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoauszug01.txt"), errors); assertThat(errors, empty()); assertThat(countSecurities(results), is(0L)); assertThat(countBuySell(results), is(0L)); assertThat(countAccountTransactions(results), is(6L)); + assertThat(countAccountTransfers(results), is(0L)); assertThat(results.size(), is(6)); new AssertImportActions().check(results, CurrencyUnit.EUR); @@ -74,16 +75,17 @@ public void testKontoauszug01() @Test public void testKontoauszug02() { - AdvanziaBankPDFExtractor extractor = new AdvanziaBankPDFExtractor(new Client()); + var extractor = new AdvanziaBankPDFExtractor(new Client()); List errors = new ArrayList<>(); - List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoauszug02.txt"), errors); + var results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoauszug02.txt"), errors); assertThat(errors, empty()); assertThat(countSecurities(results), is(0L)); assertThat(countBuySell(results), is(0L)); assertThat(countAccountTransactions(results), is(6L)); + assertThat(countAccountTransfers(results), is(0L)); assertThat(results.size(), is(6)); new AssertImportActions().check(results, CurrencyUnit.EUR); @@ -111,4 +113,38 @@ public void testKontoauszug02() assertThat(results, hasItem(interest(hasDate("2024-05-31"), hasAmount("EUR", 308.76), // hasSource("Kontoauszug02.txt"), hasNote(null)))); } + + @Test + public void testKontoauszug03() + { + var extractor = new AdvanziaBankPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + var results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoauszug03.txt"), errors); + + assertThat(errors, empty()); + assertThat(countSecurities(results), is(0L)); + assertThat(countBuySell(results), is(0L)); + assertThat(countAccountTransactions(results), is(4L)); + assertThat(countAccountTransfers(results), is(0L)); + assertThat(results.size(), is(4)); + new AssertImportActions().check(results, CurrencyUnit.EUR); + + // assert transaction + assertThat(results, hasItem(deposit(hasDate("2025-07-04"), hasAmount("EUR", 190.00), // + hasSource("Kontoauszug03.txt"), hasNote(null)))); + + // assert transaction + assertThat(results, hasItem(deposit(hasDate("2025-07-04"), hasAmount("EUR", 562.00), // + hasSource("Kontoauszug03.txt"), hasNote(null)))); + + // assert transaction + assertThat(results, hasItem(removal(hasDate("2025-07-28"), hasAmount("EUR", 340.00), // + hasSource("Kontoauszug03.txt"), hasNote(null)))); + + // assert transaction + assertThat(results, hasItem(interest(hasDate("2025-07-31"), hasAmount("EUR", 123.66), // + hasSource("Kontoauszug03.txt"), hasNote(null)))); + } } diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/Kontoauszug03.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/Kontoauszug03.txt new file mode 100644 index 0000000000..b3daa9e107 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/advanziabank/Kontoauszug03.txt @@ -0,0 +1,33 @@ +``` +PDFBox Version: 3.0.5 +Portfolio Performance Version: 0.80.4.qualifier +System: win32 | x86_64 | 21.0.8+9-LTS | Azul Systems, Inc. +----------------------------------------- +Munsbach, 4. August 2025 +Kontoauszug Advanziakonto: 132189116 +Valutadatum Buchungstag Beschreibung Betrag (EUR) +01.07.2025 ALTER SALDO 82.536,92 +03.07.2025 04.07.2025 EINZAHLUNG 190,00 +03.07.2025 04.07.2025 EINZAHLUNG 562,00 +28.07.2025 28.07.2025 AUSZAHLUNG -340,00 +31.07.2025 31.07.2025 ZINSERTRAG 123,66 +31.07.2025 NEUER SALDO 83.072,58 +Der aktuelle Zinssatz auf Ihrem Advanziakonto beträgt 1,51 % p.a. effektiv (1,5000 % nom.). +Überweisen Sie bitte unter folgenden Angaben: +Begünstigter: Ihr Vor- und Nachname +Kreditinstitut: Advanzia Bank S.A. +IBAN: LU933441321651966167 – BIC: ADVZLULL +Verwendungszweck: 4895657002494 +Im Allgemeinen sind alle Einleger durch das Luxemburger Einlagensicherungssystem abgesichert. Für bestimmte +Einlagen gelten Ausnahmen, die auf der Webseite des Fonds de garantie des dépôts (FGDL) aufgeführt sind. Auf +Anfrage teilt die Advanzia Bank S.A. Ihnen ebenfalls mit, ob bestimmte Produkte unter die Sicherung fallen oder +nicht. +Die Jahreszinsbescheinigung finden Sie im Kundenportal unter der Rubrik "Auszüge". +Bitte beachten Sie, dass unser telefonischer Kundenservice am 15. August 2025 vorübergehend nicht erreichbar +ist. +Advanzia Bank S.A. +Gesetzliche Vertreter: Nishant Fafalia, Kaj Larsen, Patrick Thilges 14, rue Gabriel Lippmann L-5365 Munsbach +Luxembourg +RCS Lux: B 109 476 VAT: LU 93621979 advanziakonto.com + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/AdvanziaBankPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/AdvanziaBankPDFExtractor.java index e5825c8ee9..75ed286dfe 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/AdvanziaBankPDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/AdvanziaBankPDFExtractor.java @@ -27,13 +27,14 @@ public String getLabel() private void addAccountStatementTransaction() { - final DocumentType type = new DocumentType("Kontoauszug Advanziakonto", // + final var type = new DocumentType("Kontoauszug Advanziakonto", // documentContext -> documentContext // // @formatter:off // Datum Beschreibung Betrag (EUR) + // Valutadatum Buchungstag Beschreibung Betrag (EUR) // @formatter:on .section("currency") // - .match("^Datum Beschreibung Betrag \\((?[\\w]{3})\\).*$") // + .match("^.*Beschreibung Betrag \\((?[A-Z]{3})\\).*$") // .assign((ctx, v) -> ctx.put("currency", asCurrencyCode(v.get("currency"))))); this.addDocumentTyp(type); @@ -41,12 +42,12 @@ private void addAccountStatementTransaction() // @formatter:off // 30.06.2023 ZINSERTRAG 47,11 // @formatter:on - Block interestBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} ZINSERTRAG [\\.\\d]+,[\\d]{2}.*$"); - type.addBlock(interestBlock); - interestBlock.set(new Transaction() + var interestBlock_Format01 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} ZINSERTRAG [\\.\\d]+,[\\d]{2}.*$"); + type.addBlock(interestBlock_Format01); + interestBlock_Format01.set(new Transaction() .subject(() -> { - AccountTransaction accountTransaction = new AccountTransaction(); + var accountTransaction = new AccountTransaction(); accountTransaction.setType(AccountTransaction.Type.INTEREST); return accountTransaction; }) @@ -62,15 +63,39 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); + // @formatter:off + // 31.07.2025 31.07.2025 ZINSERTRAG 123,66 + // @formatter:on + var interestBlock_Format02 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} ZINSERTRAG [\\.\\d]+,[\\d]{2}.*$"); + type.addBlock(interestBlock_Format02); + interestBlock_Format02.set(new Transaction() + + .subject(() -> { + var accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.INTEREST); + return accountTransaction; + }) + + .section("date", "amount") // + .documentContext("currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) ZINSERTRAG (?[\\.\\d]+,[\\d]{2}).*$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date"))); + t.setAmount(asAmount(v.get("amount"))); + t.setCurrencyCode(v.get("currency")); + }) + + .wrap(TransactionItem::new)); + // @formatter:off // 14.06.2023 EINZAHLUNG 100,00 // @formatter:on - Block depositBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} EINZAHLUNG [\\.\\d]+,[\\d]{2}.*$"); - type.addBlock(depositBlock); - depositBlock.set(new Transaction() + var depositBlock_Format01 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} EINZAHLUNG [\\.\\d]+,[\\d]{2}.*$"); + type.addBlock(depositBlock_Format01); + depositBlock_Format01.set(new Transaction() .subject(() -> { - AccountTransaction accountTransaction = new AccountTransaction(); + var accountTransaction = new AccountTransaction(); accountTransaction.setType(AccountTransaction.Type.DEPOSIT); return accountTransaction; }) @@ -86,15 +111,39 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); + // @formatter:off + // 03.07.2025 04.07.2025 EINZAHLUNG 190,00 + // @formatter:on + var depositBlock_Format02 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} EINZAHLUNG [\\.\\d]+,[\\d]{2}.*$"); + type.addBlock(depositBlock_Format02); + depositBlock_Format02.set(new Transaction() + + .subject(() -> { + var accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.DEPOSIT); + return accountTransaction; + }) + + .section("date", "amount") // + .documentContext("currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) EINZAHLUNG (?[\\.\\d]+,[\\d]{2}).*$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date"))); + t.setAmount(asAmount(v.get("amount"))); + t.setCurrencyCode(v.get("currency")); + }) + + .wrap(TransactionItem::new)); + // @formatter:off // 15.06.2023 AUSZAHLUNG -100,00 // @formatter:on - Block removalBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} AUSZAHLUNG \\-[\\.\\d]+,[\\d]{2}.*$"); - type.addBlock(removalBlock); - removalBlock.set(new Transaction() + var removalBlock_Format01 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} AUSZAHLUNG \\-[\\.\\d]+,[\\d]{2}.*$"); + type.addBlock(removalBlock_Format01); + removalBlock_Format01.set(new Transaction() .subject(() -> { - AccountTransaction accountTransaction = new AccountTransaction(); + var accountTransaction = new AccountTransaction(); accountTransaction.setType(AccountTransaction.Type.REMOVAL); return accountTransaction; }) @@ -108,6 +157,30 @@ private void addAccountStatementTransaction() t.setCurrencyCode(v.get("currency")); }) + .wrap(TransactionItem::new)); + + // @formatter:off + // 28.07.2025 28.07.2025 AUSZAHLUNG -340,00 + // @formatter:on + var removalBlock_Format02 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} AUSZAHLUNG \\-[\\.\\d]+,[\\d]{2}.*$"); + type.addBlock(removalBlock_Format02); + removalBlock_Format02.set(new Transaction() + + .subject(() -> { + var accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.REMOVAL); + return accountTransaction; + }) + + .section("date", "amount") // + .documentContext("currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) AUSZAHLUNG \\-(?[\\.\\d]+,[\\d]{2}).*$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date"))); + t.setAmount(asAmount(v.get("amount"))); + t.setCurrencyCode(v.get("currency")); + }) + .wrap(TransactionItem::new)); } }