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 Vanguard PDF-Importer to support new transaction #3756

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 @@ -16,6 +16,7 @@
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasTaxes;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasTicker;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasWkn;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.sale;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.security;
import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransactions;
import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countBuySell;
Expand Down Expand Up @@ -88,7 +89,7 @@ public void testWertpapierKauf01()
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2023-02-03T11:11:17")));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(11.956954)));
assertThat(entry.getSource(), is("Kauf01.txt"));
assertThat(entry.getNote(), is("Referenznummer 12345678"));
assertThat(entry.getNote(), is("Ord.-Nr.: 9876543 | Ref.-Nr.: 12345678"));

assertThat(entry.getPortfolioTransaction().getMonetaryAmount(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(300.00))));
Expand Down Expand Up @@ -134,7 +135,7 @@ public void testWertpapierKauf02()
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2023-03-07T01:32:43")));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(2.228799)));
assertThat(entry.getSource(), is("Kauf02.txt"));
assertThat(entry.getNote(), is("Referenznummer 11001804"));
assertThat(entry.getNote(), is("Ord.-Nr.: 2586411 | Ref.-Nr.: 11001804"));

assertThat(entry.getPortfolioTransaction().getMonetaryAmount(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(300.00))));
Expand Down Expand Up @@ -180,7 +181,7 @@ public void testWertpapierKauf03()
assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2023-03-06T01:33:23")));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(5.446747)));
assertThat(entry.getSource(), is("Kauf03.txt"));
assertThat(entry.getNote(), is("Referenznummer 11001804"));
assertThat(entry.getNote(), is("Ord.-Nr.: 2586325 | Ref.-Nr.: 11001804"));

assertThat(entry.getPortfolioTransaction().getMonetaryAmount(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(200.00))));
Expand All @@ -192,6 +193,37 @@ public void testWertpapierKauf03()
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(0.00))));
}

@Test
public void testWertpapierVerkauf17()
{
VanguardGroupEuropePDFExtractor extractor = new VanguardGroupEuropePDFExtractor(new Client());

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

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

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

// check security
assertThat(results, hasItem(security( //
hasIsin("IE00BFMXYX26"), hasWkn(null), hasTicker(null), //
hasName("FDIX Vanguard FTSE Japan UCITS ETF EUR Hedged Accumulating"), //
hasCurrencyCode("EUR"))));

// check buy sell transaction
assertThat(results, hasItem(sale( //
hasDate("2024-01-18T10:30:30"), hasShares(0.444601), //
hasSource("Verkauf01.txt"), //
hasNote("Ord.-Nr.: 3403175 | Ref.-Nr.: 11001912"), //
hasAmount("EUR", 12.31), hasGrossValue("EUR", 12.60), //
hasTaxes("EUR", 0.28 + 0.01), hasFees("EUR", 0.00))));
}

@Test
public void testDividende01()
{
Expand Down
@@ -0,0 +1,52 @@
PDFBox Version: 1.8.17
Portfolio Performance Version: 0.67.1
-----------------------------------------
So erreichen Sie uns:
Web: www.de.vanguard
Telefon: (030) 3119 6465
E-Mail: kundenservice@vanguard.com
Herr
pmlQQF LkxbHKD
jesJ-rudS. 847 Außerdem können Sie uns eine
11678 IHKmfnz Nachricht aus dem Postfach
Ihres Benutzerkontos
schreiben.
Wertpapierabrechnung: Verkauf
Depotnummer: 6226170
Am 18.01.2024 haben wir für Sie folgende Transaktion ausgeführt:
Wertpapierbezeichnung FDIX Vanguard FTSE Japan UCITS ETF EUR Hedged
Accumulating
ISIN IE00BFMXYX26
Lagerland Luxemburg
Nominal / Stück 0,444601
Währung EUR
Ordernummer 3403175
Handelsplatz Xetra
Kurs (Stückpreis) EUR 28,3350
Auftragsdatum / -zeit 18.01.2024 um 10:30:25 Uhr
Ausführungstag / -zeit 18.01.2024 um 10:30:30 Uhr
Kurswert EUR 12,60
Kapitalertragsteuer EUR 0,28
Solidaritätszuschlag EUR 0,01
EUR 12,31
Abrechnungskonto DE61760300800210815700
Referenznummer 11001912
Valutadatum (Buchungsdatum) 22.01.2024
Vanguard Group Europe GmbH Postanschrift: Geschäftsführung: Rechtsform: Gesellschaft mit
Kurfürstendamm 21 Kurfürstendamm 21 Sebastian Külps beschränkter Haftung
10719 Berlin 10719 Berlin Julia Maschkow Sitz: Berlin
kundenservice@vanguard.com 030 31196465 Vorsitzender des Aufsichtsrats: Amtsgericht: Charlottenburg, Berlin
www.de.vanguard Sean Hagerty HRB Nr. 222205 Umsatzsteuer-ID-Nr.
DE336773878
Kundenname: Herr InhrDU TKUSJbC Seite 2 von 2
Depotnummer: 7381584
Steuerliche Informationen - Wertpapierabrechnung
Veräußerungsgewinn /-Verlust EUR 1,62
Zu berücksichtigende Teilfreistellung EUR 0,49
Steuerpfl. Betrag nach Teilfreistellung EUR 1,13
Bemessungsgrundlage für Kapitalertragsteuer EUR 1,13
Kapitalertragsteuer EUR -0,28
Solidaritätszuschlag EUR -0,01
Kirchensteuer EUR 0,00
Bitte beachten Sie, dass dieser Beleg keine Steuerbescheinigung darstellt. Dieser Beleg ist
maschinell erstellt und wird nicht unterschrieben.
@@ -1,6 +1,7 @@
package name.abuchen.portfolio.datatransfer.pdf;

import static name.abuchen.portfolio.datatransfer.ExtractorUtils.checkAndSetGrossUnit;
import static name.abuchen.portfolio.util.TextUtil.concatenate;
import static name.abuchen.portfolio.util.TextUtil.trim;

import name.abuchen.portfolio.datatransfer.ExtrExchangeRate;
Expand Down Expand Up @@ -34,21 +35,29 @@ public String getLabel()

private void addBuySellTransaction()
{
DocumentType type = new DocumentType("Wertpapierabrechnung: Kauf");
DocumentType type = new DocumentType("Wertpapierabrechnung: (Kauf|Verkauf)");
this.addDocumentTyp(type);

Transaction<BuySellEntry> pdfTransaction = new Transaction<>();

Block firstRelevantLine = new Block("^Wertpapierabrechnung: Kauf$");
Block firstRelevantLine = new Block("^Wertpapierabrechnung: (Kauf|Verkauf)$");
type.addBlock(firstRelevantLine);
firstRelevantLine.set(pdfTransaction);

pdfTransaction //

.subject(() -> {
BuySellEntry entry = new BuySellEntry();
entry.setType(PortfolioTransaction.Type.BUY);
return entry;
BuySellEntry portfolioTransaction = new BuySellEntry();
portfolioTransaction.setType(PortfolioTransaction.Type.BUY);
return portfolioTransaction;
})

// Is type --> "Verkauf" change from BUY to SELL
.section("type").optional() //
.match("^Wertpapierabrechnung: (?<type>(Kauf|Verkauf)).*$") //
.assign((t, v) -> {
if ("Verkauf".equals(v.get("type")))
t.setType(PortfolioTransaction.Type.SELL);
})

// @formatter:off
Expand Down Expand Up @@ -109,14 +118,23 @@ private void addBuySellTransaction()
t.setAmount(asAmount(v.get("amount")));
}))

// @formatter:off
// Ordernummer 3403175
// @formatter:on
.section("note") //
.match("^Ordernummer (?<note>.*)$") //
.assign((t, v) -> t.setNote("Ord.-Nr.: " + trim(v.get("note"))))

// @formatter:off
// Referenznummer 12345678
// @formatter:on
.section("note").optional() //
.match("^(?<note>Referenznummer .*)$") //
.assign((t, v) -> t.setNote(trim(v.get("note"))))
.match("^Referenznummer (?<note>.*)$") //
.assign((t, v) -> t.setNote(concatenate(t.getNote(), "Ref.-Nr.: " + trim(v.get("note")), " | ")))

.wrap(BuySellEntryItem::new);

addTaxesSectionsTransaction(pdfTransaction, type);
}

private void addDividendTransaction()
Expand All @@ -133,9 +151,9 @@ private void addDividendTransaction()
pdfTransaction //

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

// @formatter:off
Expand Down Expand Up @@ -217,23 +235,25 @@ private <T extends Transaction<?>> void addTaxesSectionsTransaction(T transactio

// @formatter:off
// Kapitalertragsteuer EUR -5,78
// Kapitalertragsteuer EUR 0,28
// @formatter:on
.section("currency", "tax").optional() //
.match("^Kapitalertrag(s)?steuer (?<currency>[\\w]{3}) \\-(?<tax>[\\.,\\d]+)$") //
.match("^Kapitalertrags(s)?teuer (?<currency>[\\w]{3}) (\\-)?(?<tax>[\\.,\\d]+)$") //
.assign((t, v) -> processTaxEntries(t, v, type))

// @formatter:off
// Solidaritätszuschlag EUR -0,31
// Solidaritätszuschlag EUR 0,01
// @formatter:on
.section("currency", "tax").optional() //
.match("^Solidarit.tszuschlag (?<currency>[\\w]{3}) \\-(?<tax>[\\.,\\d]+)$") //
.match("^Solidarit.tszuschlag (?<currency>[\\w]{3}) (\\-)?(?<tax>[\\.,\\d]+)$") //
.assign((t, v) -> processTaxEntries(t, v, type))

// @formatter:off
// Kirchensteuer EUR 0,00
// @formatter:on
.section("currency", "tax").optional() //
.match("^Kirchensteuer (?<currency>[\\w]{3}) \\-(?<tax>[\\.,\\d]+)$") //
.match("^Kirchensteuer (?<currency>[\\w]{3}) (\\-)?(?<tax>[\\.,\\d]+)$") //
.assign((t, v) -> processTaxEntries(t, v, type));
}
}