Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify DZ/Volksbank/UnionInvest PDF-Importer #2102

Merged
merged 4 commits into from Feb 28, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -53,7 +53,7 @@ public void testWertpapierKauf1()
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("VANGUARD FTSE ALL-WORLD U.ETF"));
assertThat(security.getName(), is("VANGUARD FTSE ALL-WORLD U.ETF REGISTERED SHARES USD DIS.ON"));
assertThat(security.getIsin(), is("IE00B3RBWM25"));
assertThat(security.getWkn(), is("A1JX52"));

Expand All @@ -62,7 +62,7 @@ public void testWertpapierKauf1()
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2020-01-13T11:42")));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2020-01-13T11:42:59")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY));

Expand Down Expand Up @@ -91,7 +91,7 @@ public void testWertpapierKauf2()
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("XING SE"));
assertThat(security.getName(), is("XING SE NAMENS-AKTIEN O.N."));
assertThat(security.getIsin(), is("DE000XNG8888"));
assertThat(security.getWkn(), is("XNG888"));

Expand All @@ -100,7 +100,7 @@ public void testWertpapierKauf2()
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-06-04T18:09")));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-06-04T18:09:18")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY));

Expand Down Expand Up @@ -129,7 +129,7 @@ public void testWertpapierKauf3()
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("DAIMLER AG"));
assertThat(security.getName(), is("DAIMLER AG NAMENS-AKTIEN O.N."));
assertThat(security.getIsin(), is("DE0007100000"));
assertThat(security.getWkn(), is("710000"));

Expand All @@ -138,7 +138,7 @@ public void testWertpapierKauf3()
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2020-05-14T15:40")));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2020-05-14T15:40:55")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY));

Expand Down Expand Up @@ -167,7 +167,7 @@ public void testWertpapierKauf4()
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("NEXTERA ENERGY INC."));
assertThat(security.getName(), is("NEXTERA ENERGY INC. REGISTERED SHARES DL -,01"));
assertThat(security.getIsin(), is("US65339F1012"));
assertThat(security.getWkn(), is("A1CZ4H"));

Expand All @@ -176,7 +176,7 @@ public void testWertpapierKauf4()
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2021-01-27T16:18")));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2021-01-27T16:18:02")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY));

Expand All @@ -186,6 +186,45 @@ public void testWertpapierKauf4()
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(50)));
}

@Test
public void testWertpapierKauf5()
{
DZBankPDFExtractor extractor = new DZBankPDFExtractor(new Client());

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

List<Item> results = extractor.extract(
PDFInputFile.loadTestCase(getClass(), "DZBankWertpapierabrechnung_Kauf5.txt"), errors);

assertThat(errors, empty());
assertThat(results.size(), is(2));

Optional<Item> item;

// security
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("Aktienname TECHNOLOGIES INC. REGISTERED SHARES DL-,00001"));
assertThat(security.getIsin(), is("US90353T1007"));
assertThat(security.getWkn(), is("A2PHHG"));

item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst();

assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-07-01T18:27:57")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY));

assertThat(entry.getPortfolioTransaction().getAmount(), is(Values.Amount.factorize(8963.05)));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE),
is(Money.of("EUR", Values.Amount.factorize(9.95 + 0.10))));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(100)));
}


@Test
public void testWertpapierVerkauf1()
{
Expand All @@ -197,15 +236,15 @@ public void testWertpapierVerkauf1()
PDFInputFile.loadTestCase(getClass(), "DZBankWertpapierabrechnung_Verkauf1.txt"), errors);

assertThat(errors, empty());
assertThat(results.size(), is(2));
assertThat(results.size(), is(3));

Optional<Item> item;

// security
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("NEW WORK SE"));
assertThat(security.getName(), is("NEW WORK SE NAMENS-AKTIEN O.N."));
assertThat(security.getIsin(), is("DE000NWRK013"));
assertThat(security.getWkn(), is("NWRK01"));

Expand All @@ -214,14 +253,24 @@ public void testWertpapierVerkauf1()
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-08-13T15:16")));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-08-13T15:16:51")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL));

assertThat(entry.getPortfolioTransaction().getAmount(), is(Values.Amount.factorize(577.95)));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE),
is(Money.of("EUR", Values.Amount.factorize(10.05))));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(2)));

// check tax-refund transaction
item = results.stream().filter(i -> i instanceof TransactionItem).findFirst();
assertThat(item.isPresent(), is(true));
assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class));
AccountTransaction transaction = (AccountTransaction) item.get().getSubject();

assertThat(transaction.getType(), is(AccountTransaction.Type.TAX_REFUND));
assertThat(transaction.getMonetaryAmount(), is(Money.of("EUR", Values.Amount.factorize(29.57))));
assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2019-08-13T00:00")));
}

@Test
Expand All @@ -243,7 +292,7 @@ public void testWertpapierVerkauf2()
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("BAYER AG"));
assertThat(security.getName(), is("BAYER AG NAMENS-AKTIEN O.N."));
assertThat(security.getIsin(), is("DE000BAY0017"));
assertThat(security.getWkn(), is("BAY001"));

Expand All @@ -252,7 +301,7 @@ public void testWertpapierVerkauf2()
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-09-26T09:04")));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2019-09-26T09:04:37")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL));

Expand All @@ -263,6 +312,91 @@ public void testWertpapierVerkauf2()
is(Money.of("EUR", Values.Amount.factorize(37.97))));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(30)));
}

@Test
public void testWertpapierVerkauf3()
{
DZBankPDFExtractor extractor = new DZBankPDFExtractor(new Client());

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

List<Item> results = extractor.extract(
PDFInputFile.loadTestCase(getClass(), "DZBankWertpapierabrechnung_Verkauf3.txt"), errors);

assertThat(errors, empty());
assertThat(results.size(), is(2));

Optional<Item> item;

// security
item = results.stream().filter(i -> i instanceof SecurityItem).findFirst();

Security security = ((SecurityItem) item.orElseThrow(IllegalArgumentException::new)).getSecurity();
assertThat(security.getName(), is("NETFLIX INC. REGISTERED SHARES DL -,001"));
assertThat(security.getIsin(), is("US64110L1061"));
assertThat(security.getWkn(), is("552484"));

item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst();

assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2021-02-09T19:48:50")));
assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL));

assertThat(entry.getPortfolioTransaction().getAmount(), is(Values.Amount.factorize(442.29)));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE),
is(Money.of("EUR", Values.Amount.factorize(9.95 + 0.10))));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.TAX),
is(Money.of("EUR", Values.Amount.factorize(10.01))));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(1)));
}

@Test
public void testWertpapierVerkauf4()
{
DZBankPDFExtractor extractor = new DZBankPDFExtractor(new Client());

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

List<Item> results = extractor.extract(
PDFInputFile.loadTestCase(getClass(), "DZBankWertpapierabrechnung_Verkauf4.txt"), errors);

assertThat(errors, empty());
assertThat(results.size(), is(3));

// check security
Security security = results.stream().filter(i -> i instanceof SecurityItem).findFirst()
.orElseThrow(IllegalArgumentException::new).getSecurity();
assertThat(security.getIsin(), is("US29786A1060"));
assertThat(security.getWkn(), is("A14P98"));
assertThat(security.getName(), is("ETSY INC. REGISTERED SHARES DL -,001"));

// check buy sell transaction
Optional<Item> item = results.stream().filter(i -> i instanceof BuySellEntryItem).findFirst();
assertThat(item.orElseThrow(IllegalArgumentException::new).getSubject(), instanceOf(BuySellEntry.class));
BuySellEntry entry = (BuySellEntry) item.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.SELL));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.SELL));

assertThat(entry.getPortfolioTransaction().getAmount(), is(Values.Amount.factorize(805.45)));
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2021-01-27T15:52:15")));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(5)));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE),
is(Money.of("EUR", Values.Amount.factorize(9.95 + 0.10))));

// check tax-refund transaction
item = results.stream().filter(i -> i instanceof TransactionItem).findFirst();
assertThat(item.isPresent(), is(true));
assertThat(item.get().getSubject(), instanceOf(AccountTransaction.class));
AccountTransaction transaction = (AccountTransaction) item.get().getSubject();

assertThat(transaction.getType(), is(AccountTransaction.Type.TAX_REFUND));
assertThat(transaction.getMonetaryAmount(), is(Money.of("EUR", Values.Amount.factorize(26.23))));
assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2021-01-27T00:00")));
}

@Test
public void testAusschuettung1()
Expand Down
@@ -0,0 +1,39 @@
PDF Author: ''
PDFBox Version: 1.8.16
-----------------------------------------

Volksbank · Postfach 100111 · 01234 Ortschaft
Depotnummer
2872248800
Kundennummer 20826520
Max Mustermann
Auftragsnummer 746825/42.00
Max Mustermann Datum 01.01.2019
MWohnstraße 4 Rechnungsnummer W03227-0000007905/38
01234 Ortschaft Steuernummer 37513578292
Onlinedepot

Wertpapier Abrechnung Kauf
Nominale Wertpapierbezeichnung ISIN (WKN)
Stück 100 Aktienname TECHNOLOGIES INC. US90353T1007 (A2PHHG)
REGISTERED SHARES DL-,00001
Handels-/Ausführungsplatz Tradegate (gemäß Weisung)
Börsensegment XGAT
Limit-Order
Limit 39,60 EUR
Schlusstag/-Zeit 01.07.2019 18:27:57 Auftraggeber Max Mustermann
Ausführungskurs 39,53 EUR Auftragserteilung/ -ort Online-Banking
Girosammelverw. mehrere Sammelurkunden - kein Stückeausdruck -
Kurswert 8.751,00- EUR
Provision 9,95- EUR
Übertragungs-/Liefergebühr 0,10- EUR
Ausmachender Betrag 8.963,05- EUR

Den Gegenwert buchen wir mit Valuta 03.07.2019 zu Lasten des Kontos 3078256012
(IBAN DE27 8509 0000 5571 2612 00), BLZ 82070000 (BIC GENODEF8HH).
Die Wertpapiere schreiben wir Ihrem Depotkonto gut.
Sofern keine Umsatzsteuer ausgewiesen ist, handelt es sich um eine umsatzsteuerbefreite Finanzdienstleistung.

.
Dieses Dokument wurde maschinell erstellt und wird nicht unterschrieben.
5282.07912203.0500081O607
@@ -0,0 +1,63 @@
PDF Autor: ''
PDFBox Version: 1.8.16
-----------------------------------------

Volksbank Dresden eG · Postfach 100555 · 01075 Dresden Seite 1 von 2
Depotnummer
3002278500
Kundennummer 81222500
Max Muster
Auftragsnummer 680489/62.00
Max Muster Datum 09.02.2021
Straße-Str. 16 Rechnungsnummer W03202-0000002647/21
012345 Stadt Steuernummer 20253585232
Onlinedepot

Wertpapier Abrechnung Verkauf
Nominale Wertpapierbezeichnung ISIN (WKN)
Stück 1 NETFLIX INC. US64110L1061 (552484)
REGISTERED SHARES DL -,001
Handels-/Ausführungsplatz Tradegate (gemäß Weisung)
Börsensegment XGAT
Limit-Order
Limit 462,00 EUR
Schlusstag/-Zeit 09.02.2021 19:48:50 Auftraggeber Max Muster
Ausführungskurs 462,35 EUR Auftragserteilung/ -ort Online-Banking
Girosammelverw. mehrere Sammelurkunden - kein Stückeausdruck -
Kurswert 462,35 EUR
Provision 9,95- EUR
Übertragungs-/Liefergebühr 0,10- EUR
Ermittlung steuerrelevante Erträge
Veräußerungsgewinn 37,93 EUR
Berechnungsgrundlage für die Kapitalertragsteuer 37,93 EUR

Steuerberechnung
Kapitalertragsteuer 25,00% auf 37,93 EUR 9,49- EUR
Solidaritätszuschlag 5,50% auf 9,49 EUR 0,52- EUR
Ausmachender Betrag 442,29 EUR

Den Gegenwert buchen wir mit Valuta 11.02.2021 zu Gunsten des Kontos 5472271080
(IBAN DE27 8709 0000 7032 2570 00), BLZ 85090000 (BIC GENODEF1DRS).
Die Wertpapiere entnehmen wir Ihrem Depotkonto.
Sofern keine Umsatzsteuer ausgewiesen ist, handelt es sich um eine umsatzsteuerbefreite Finanzdienstleistung.
7202.02092110.0000031OR07
Seite 2 von 2
Depotnummer 5072458900
Kundennummer 53728539
Auftragsnummer 682489/62.00
Datum 09.02.2021

Nachrichtlich die Übersicht Ihrer Verrechnungs- und Steuertopfsalden zum Zeitpunkt der Erstellung der Abrechnung.
Verlustverrechnungstöpfe 2021 Berechnungsgrundlage
der gezahlten Steuern
Euro Aktien Sonstige Sparer- anrechenbare Aktien und Sonstige
Pauschbetrag Quellensteuer
Vorher 0,00 0,00 0,00 0,00 2.465,61
Verkauf 0,00 0,00 0,00 0,00 37,93
Nachher 0,00 0,00 0,00 0,00 2.503,54
Berücksichtigte Anschaffungsgeschäfte (alle ermittelten Beträge in EUR)
Geschäft Auftragsnr. Ausführ.-tag Whr./St. Nennwert/Stück AS-Kosten Erlös ant. Ergebnis
Kauf 6441497200 19.01.2021 Stück 1,0000 414,37- 452,30 37,93 (D)
Summe aller Erträge nach Differenzmethode und/oder Ersatzbemessungsgrundlage 37,93
Dieses Dokument wurde maschinell erstellt und wird nicht unterschrieben.
7202.02092110.0000032OR07