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 @@ -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;
Expand All @@ -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;
Expand All @@ -33,16 +33,17 @@ public class AdvanziaBankPDFExtractorTest
@Test
public void testKontoauszug01()
{
AdvanziaBankPDFExtractor extractor = new AdvanziaBankPDFExtractor(new Client());
var extractor = new AdvanziaBankPDFExtractor(new Client());

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

List<Item> 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);

Expand Down Expand Up @@ -74,16 +75,17 @@ public void testKontoauszug01()
@Test
public void testKontoauszug02()
{
AdvanziaBankPDFExtractor extractor = new AdvanziaBankPDFExtractor(new Client());
var extractor = new AdvanziaBankPDFExtractor(new Client());

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

List<Item> 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);

Expand Down Expand Up @@ -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<Exception> 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))));
}
}
Original file line number Diff line number Diff line change
@@ -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

```
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,27 @@ 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 \\((?<currency>[\\w]{3})\\).*$") //
.match("^.*Beschreibung Betrag \\((?<currency>[A-Z]{3})\\).*$") //
.assign((ctx, v) -> ctx.put("currency", asCurrencyCode(v.get("currency")))));

this.addDocumentTyp(type);

// @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<AccountTransaction>()
var interestBlock_Format01 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} ZINSERTRAG [\\.\\d]+,[\\d]{2}.*$");
type.addBlock(interestBlock_Format01);
interestBlock_Format01.set(new Transaction<AccountTransaction>()

.subject(() -> {
AccountTransaction accountTransaction = new AccountTransaction();
var accountTransaction = new AccountTransaction();
accountTransaction.setType(AccountTransaction.Type.INTEREST);
return accountTransaction;
})
Expand All @@ -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<AccountTransaction>()

.subject(() -> {
var accountTransaction = new AccountTransaction();
accountTransaction.setType(AccountTransaction.Type.INTEREST);
return accountTransaction;
})

.section("date", "amount") //
.documentContext("currency") //
.match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?<date>[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) ZINSERTRAG (?<amount>[\\.\\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<AccountTransaction>()
var depositBlock_Format01 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} EINZAHLUNG [\\.\\d]+,[\\d]{2}.*$");
type.addBlock(depositBlock_Format01);
depositBlock_Format01.set(new Transaction<AccountTransaction>()

.subject(() -> {
AccountTransaction accountTransaction = new AccountTransaction();
var accountTransaction = new AccountTransaction();
accountTransaction.setType(AccountTransaction.Type.DEPOSIT);
return accountTransaction;
})
Expand All @@ -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<AccountTransaction>()

.subject(() -> {
var accountTransaction = new AccountTransaction();
accountTransaction.setType(AccountTransaction.Type.DEPOSIT);
return accountTransaction;
})

.section("date", "amount") //
.documentContext("currency") //
.match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?<date>[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) EINZAHLUNG (?<amount>[\\.\\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<AccountTransaction>()
var removalBlock_Format01 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} AUSZAHLUNG \\-[\\.\\d]+,[\\d]{2}.*$");
type.addBlock(removalBlock_Format01);
removalBlock_Format01.set(new Transaction<AccountTransaction>()

.subject(() -> {
AccountTransaction accountTransaction = new AccountTransaction();
var accountTransaction = new AccountTransaction();
accountTransaction.setType(AccountTransaction.Type.REMOVAL);
return accountTransaction;
})
Expand All @@ -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<AccountTransaction>()

.subject(() -> {
var accountTransaction = new AccountTransaction();
accountTransaction.setType(AccountTransaction.Type.REMOVAL);
return accountTransaction;
})

.section("date", "amount") //
.documentContext("currency") //
.match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?<date>[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) AUSZAHLUNG \\-(?<amount>[\\.\\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));
}
}