From 5daa349abe844608e69c7cba8cdd403fadd8719e Mon Sep 17 00:00:00 2001 From: Oliver Fueckert Date: Fri, 17 Jan 2025 12:36:00 +0100 Subject: [PATCH] Add Vorabpauschale and test to MerkurPrivatBankPDFExtractor --- .../MerkurPrivatBankPDFExtractorTest.java | 33 +++++++++++ .../pdf/merkurprivatbank/Vorabpauschale01.txt | 47 +++++++++++++++ .../pdf/MerkurPrivatBankPDFExtractor.java | 58 +++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/Vorabpauschale01.txt diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/MerkurPrivatBankPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/MerkurPrivatBankPDFExtractorTest.java index aebe50d11b..0a88fe1d9e 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/MerkurPrivatBankPDFExtractorTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/MerkurPrivatBankPDFExtractorTest.java @@ -17,6 +17,7 @@ import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasWkn; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.removal; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.security; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.taxes; import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransactions; import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countBuySell; import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countSecurities; @@ -334,4 +335,36 @@ public void testKontoauszug02() hasSource("Kontoauszug02.txt"), hasNote("Neuanlage")))); } + + @Test + public void testVorabpauschale01() + { + MerkurPrivatBankPDFExtractor extractor = new MerkurPrivatBankPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Vorabpauschale01.txt"), errors); + + assertThat(errors, empty()); + assertThat(countSecurities(results), is(1L)); + assertThat(countBuySell(results), is(0L)); + assertThat(countAccountTransactions(results), is(1L)); + assertThat(results.size(), is(2)); + new AssertImportActions().check(results, CurrencyUnit.EUR); + + // check security + assertThat(results, hasItem(security( // + hasIsin("IE00BZ02LR44"), hasWkn("A2AQST"), hasTicker(null), // + hasName("XTR.(IE)-MSCI WORLD ESG REGISTERED SHARES 1C O.N."), // + hasCurrencyCode("EUR")))); + + // check taxes transaction + assertThat(results, hasItem(taxes( // + hasDate("2025-01-03T00:00"), hasShares(8300.2084), // + hasSource("Vorabpauschale01.txt"), // + hasNote("Abrechnungsnr. 82937342032"), // + hasAmount("EUR", 437.75), hasGrossValue("EUR", 437.75), // + hasTaxes("EUR", 0.00), hasFees("EUR", 0.00)))); + } + } diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/Vorabpauschale01.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/Vorabpauschale01.txt new file mode 100644 index 0000000000..83455cfadc --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/merkurprivatbank/Vorabpauschale01.txt @@ -0,0 +1,47 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.73.0 +System: macosx | aarch64 | 21.0.5+11-LTS | Azul Systems, Inc. +----------------------------------------- +Am Marktplatz 10 · 97762 Hammelburg Seite 1 +Depotnummer + 89540578 + Kundennummer 511351085 +lijfcJ iVzTo luueLtE + Abrechnungsnr. 82937342032 +xsoLyF nCbJw lmACnsX Datum 14.01.2025 +YlAGWBokB. 7 Ihr Berater Herr HIs ufsYRtIIzIS +49057 SOvStiuQ Telefon +53 089 882649-13 + + + +Vorabpauschale Investmentfonds +Nominale Wertpapierbezeichnung ISIN (WKN) +Stück 8.300,2084 XTR.(IE)-MSCI WORLD ESG IE00BZ02LR44 (A2AQST) +REGISTERED SHARES 1C O.N. +Zahlbarkeitstag 02.01.2025 Vorabpauschale pro St. 0,523967800 EUR +Bestandsstichtag 31.12.2024 mit Teilfreistellung (Aktien- +Ex-Tag 02.01.2025 fonds) 0,366777460 EUR +Geschäftsjahr 01.01.2024 - 31.12.2024 Herkunftsland Irland +Steuerpflichtige Vorabpauschale 2.371,03+ EUR +davon steuerfreier Anteil wg. Teilfreistellung 711,31- EUR +Kapitalertragsteuerpfl. Ertrag nach Teilfreistellung 1.659,72+ EUR +Berechnungsgrundlage für die Kapitalertragsteuer 1.659,72+ EUR +Kapitalertragsteuer 25 % auf 1.659,72 EUR 414,93- EUR +Solidaritätszuschlag 5,5 % auf 414,93 EUR 22,82- EUR +Ausmachender Betrag 437,75- EUR +Lagerstelle CBFI (601617 / 67268) +Den Betrag buchen wir mit Wertstellung 03.01.2025 zu Lasten des Kontos 4648427 (IBAN Ry64 7013 1917 2554 3073 02), +BLZ 188 214 00 (BIC SljYdFa2K09). +Keine Steuerbescheinigung. +Nachrichtlich die Übersicht Ihrer Verrechnungs- und Steuertopfsalden zum Zeitpunkt der Erstellung der Abrechnung. +Verrechnungstöpfe 2025 ohne Vorjahressaldo Berechnungsgrundlage +der gezahlten Steuern +Euro Aktien Sonstige Sparer- anrechenbare Aktien und Sonstige +Pauschbetrag Quellensteuer +Vorher 0,00 0,00 0,00 0,00 00002,54 +Ertrag 0,00 0,00 0,00 0,00 0.659,72 +Nachher 0,00 0,00 0,00 0,00 00.222,26 +Bitte ggf. Rückseite beachten. +6175.99990221.0005662ER99 +``` \ No newline at end of file diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MerkurPrivatBankPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MerkurPrivatBankPDFExtractor.java index fe60b68cf7..fb9a9ad579 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MerkurPrivatBankPDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MerkurPrivatBankPDFExtractor.java @@ -2,6 +2,7 @@ import static name.abuchen.portfolio.util.TextUtil.trim; +import name.abuchen.portfolio.Messages; import name.abuchen.portfolio.datatransfer.pdf.PDFParser.Block; import name.abuchen.portfolio.datatransfer.pdf.PDFParser.DocumentType; import name.abuchen.portfolio.datatransfer.pdf.PDFParser.Transaction; @@ -25,6 +26,7 @@ public MerkurPrivatBankPDFExtractor(Client client) addBuySellTransaction(); addDividendeTransaction(); addAccountStatementTransaction(); + addAdvanceTaxTransaction(); } @Override @@ -240,6 +242,62 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); } + private void addAdvanceTaxTransaction() + { + final DocumentType type = new DocumentType("Vorabpauschale Investmentfonds"); + this.addDocumentTyp(type); + + Transaction pdfTransaction = new Transaction<>(); + + Block firstRelevantLine = new Block("^.*Abrechnungsnr.*$", "^Keine Steuerbescheinigung.*$"); + type.addBlock(firstRelevantLine); + firstRelevantLine.set(pdfTransaction); + + pdfTransaction // + + .subject(() -> { + AccountTransaction accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.TAXES); + return accountTransaction; + }) + + .section("name", "isin", "wkn", "nameContinued", "currency") // + .find("Nominale Wertpapierbezeichnung ISIN \\(WKN\\)") // + .match("^St.ck (?[\\.,\\d]+) (?.*) (?[A-Z]{2}[A-Z0-9]{9}[0-9]) \\((?.*)\\)$") // + .match("^(?.*)$") // + .match("^.* Vorabpauschale pro St\\. [\\.,\\d]+ (?[\\w]{3})$") // + .assign((t, v) -> t.setSecurity(getOrCreateSecurity(v))) + + .section("shares") // + .find("Nominale Wertpapierbezeichnung ISIN \\(WKN\\)") // + .match("^St.ck (?[\\.,\\d]+) .*$") // + .assign((t, v) -> t.setShares(asShares(v.get("shares")))) + + .section("date") // + .match("^Den Betrag buchen wir mit Wertstellung (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}).*$") // + .assign((t, v) -> t.setDateTime(asDate(v.get("date")))) + + .section("currency", "amount") // + .match("^Ausmachender Betrag (?[\\.,\\d]+)\\- (?[\\w]{3})$") // + .assign((t, v) -> { + t.setCurrencyCode(asCurrencyCode(v.get("currency"))); + t.setAmount(asAmount(v.get("amount"))); + }) + + .section("note").optional() // + .match("^.*(?Abrechnungsnr\\. [\\d]+).*$") // + .assign((t, v) -> t.setNote(trim(v.get("note")))) + + .wrap(t -> { + TransactionItem item = new TransactionItem(t); + + if (t.getCurrencyCode() != null && t.getAmount() == 0) + item.setFailureMessage(Messages.MsgErrorTransactionTypeNotSupported); + + return item; + }); + } + private > void addTaxesSectionsTransaction(T transaction, DocumentType type) { transaction //