diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/Dividende10.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/Dividende10.txt new file mode 100644 index 0000000000..76a6e6d86c --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/Dividende10.txt @@ -0,0 +1,70 @@ +PDFBox Version: 1.8.16 +Portfolio Performance Version: 0.60.0 +----------------------------------------- + da + + +Raiffeisenbank Region Amstetten eGen +Raiffeisenplatz 1, 3300 Amstetten + b +BLZ: 32025 UID: ATU16111800 + + +a +a +Abrechnung Ereignis a +11111111 - 16.08.2021 a +Depot-Nr.: 11.111.111 +DI Max Muster DI Max Muster +Maxstra 20 +1234 Cirty 059/551 +ciqwapqwn +Wir haben für Sie am 16.08.2021 unten angeführtes Geschäft abgerechnet: +Geschäftsart: Ertrag +7,01 Stk +Titel: AT0000A1TW21 RAIFF.-EMERGINGMARKETS-AKTIEN RZ(A) +MITEIGENTUMSANTEILE - Ausschüttung +Fondsgesellschaft: Raiffeisen Kapitalanlageges. m.b.H. +Ertrag: 1,19 EUR +Verwahrart: SV +Positionsdaten: Loco: AT Österreich +Bruttobetrag: 8,34 EUR +Auslands-KESt: -2,15 EUR +KESt: -0,60 EUR +Zu Gunsten IBAN AT62 3202 1111 1111 1111 5,59 EUR +Valuta 16.08.2021 +KESt wird mit dem Finanzamt für Großbetriebe abgerechnet. +KESt pro Fondsanteil 0,085 EUR für Neubestand +Auslands-KESt pro Fondsanteil 0,3066 EUR für Neubestand +Extag: 16.08.2021 +17.08.2021 1 / 2 +Irrtum vorbehalten +Dieser Beleg trägt keine Unterschrift. +Raiffeisenbank Region Amstetten eGen +Raiffeisenplatz 1, 3300 Amstetten + b +BLZ: 32025 UID: ATU16311100 +a +a +Abrechnung Ereignis a +11111111 - 16.08.2021 a +Depot-Nr.: 11.111.111 +DI Max Muster +059/551 +fasfasa +Ausgangssituation: +KESt-Neubestand mit Anschaffungskosten nach dem gleitenden +Durchschnittsverfahren § 27a Abs. 4 Zi 3 EStG 7,01 Stk +steuerlicher Anschaffungswert: 743,86 EUR +KESt-Neubestand mit Anschaffungskosten nach dem gleitenden +Durchschnittsverfahren § 27a Abs. 4 Zi 3 EStG 7,01 Stk +ausschüttungsgleicher Ertrag: 12,01 EUR +Anschaffungswertreduzierender Betrag: 8,34 EUR +steuerlicher Anschaffungswert: 743,86 EUR +Bestand nach Buchung: +KESt-Neubestand mit Anschaffungskosten nach dem gleitenden +Durchschnittsverfahren § 27a Abs. 4 Zi 3 EStG 7,01 Stk +steuerlicher Anschaffungswert: 747,53 EUR +17.08.2021 2 / 2 +Irrtum vorbehalten +Dieser Beleg trägt keine Unterschrift. \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/RaiffeisenbankgruppePDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/RaiffeisenbankgruppePDFExtractorTest.java index 4fb321f0af..cced89b305 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/RaiffeisenbankgruppePDFExtractorTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/raiffeisenbankgruppe/RaiffeisenbankgruppePDFExtractorTest.java @@ -9,6 +9,7 @@ import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.junit.Assert.assertNull; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.check; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.deposit; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.dividend; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasAmount; @@ -1136,6 +1137,72 @@ public void testDividende09() hasTaxes("EUR", (0.86 / 1.0897) + 9.29 + 0.29), hasFees("EUR", 1.45 + 3.00)))); } + @Test + public void testDividende09WithSecurityInEUR() + { + Security security = new Security("iSh.DJ U.S.Select Div.U.ETF DE Inhaber-Anteile", CurrencyUnit.EUR); + security.setIsin("DE000A0D8Q49"); + + Client client = new Client(); + client.addSecurity(security); + + RaiffeisenBankgruppePDFExtractor extractor = new RaiffeisenBankgruppePDFExtractor(client); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Dividende09.txt"), errors); + + assertThat(countSecurities(results), is(0L)); + assertThat(countBuySell(results), is(0L)); + assertThat(countAccountTransactions(results), is(1L)); + assertThat(results.size(), is(1)); + new AssertImportActions().check(results, CurrencyUnit.EUR); + + // check dividends transaction + assertThat(results, hasItem(dividend( // + hasDate("2020-04-15T00:00"), hasShares(221), // + hasSource("Dividende09.txt"), hasNote(null), // + hasAmount("EUR", 82.99), hasGrossValue("EUR", 97.81), // + hasTaxes("EUR", (0.86 / 1.0897) + 9.29 + 0.29), hasFees("EUR", 1.45 + 3.00), // + check(tx -> { + CheckCurrenciesAction c = new CheckCurrenciesAction(); + Account account = new Account(); + account.setCurrencyCode(CurrencyUnit.EUR); + Status s = c.process((AccountTransaction) tx, account); + assertThat(s, is(Status.OK_STATUS)); + })))); + } + + @Test + public void testDividende10() + { + RaiffeisenBankgruppePDFExtractor extractor = new RaiffeisenBankgruppePDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Dividende10.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("AT0000A1TW21"), hasWkn(null), hasTicker(null), // + hasName("RAIFF.-EMERGINGMARKETS-AKTIEN RZ(A) MITEIGENTUMSANTEILE"), // + hasCurrencyCode("EUR")))); + + // check dividends transaction + assertThat(results, hasItem(dividend( // + hasDate("2021-08-16T00:00"), hasShares(7.01), // + hasSource("Dividende10.txt"), hasNote(null), // + hasAmount("EUR", 5.59), hasGrossValue("EUR", 8.34), // + hasTaxes("EUR", 2.15 + 0.60), hasFees("EUR", 0.00)))); + } + @Test public void testKontoauszug01() { diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/RaiffeisenBankgruppePDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/RaiffeisenBankgruppePDFExtractor.java index 9c03503415..2498d5061f 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/RaiffeisenBankgruppePDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/RaiffeisenBankgruppePDFExtractor.java @@ -264,6 +264,25 @@ private void addDividendeTransaction() pdfTransaction .oneOf( + // @formatter:off + // Titel: AT0000A1TW21 RAIFF.-EMERGINGMARKETS-AKTIEN RZ(A) + // MITEIGENTUMSANTEILE - Ausschüttung + // Ertrag: 1,19 EUR + // @formatter:on + section -> section + .attributes("isin", "name", "name1", "currency") + .match("^Titel: (?[A-Z]{2}[A-Z0-9]{9}[0-9]) (?.*)$") + .match("^(?.*) \\- Aussch.ttung$") + .match("^(Dividende|Ertrag): [\\.,\\d]+ (?[\\w]{3})$") + .assign((t, v) -> { + if (!v.get("name1").startsWith("Dividende:") + || !v.get("name1").startsWith("Ertrag:") + || !v.get("name1").startsWith("Fondsgesellschaft:")) + v.put("name", trim(v.get("name")) + " " + trim(v.get("name1"))); + + t.setSecurity(getOrCreateSecurity(v)); + }) + , // @formatter:off // Titel: DE000BAY0017 Bayer AG // Namens-Aktien o.N. @@ -375,15 +394,15 @@ private void addDividendeTransaction() // Dividendengutschrift 68,00 USD 59,86+ EUR // @formatter:on section -> section - .attributes("baseCurrency", "termCurrency", "exchangeRate", "fxGross", "fxCurrency", "gross", "currency") + .attributes("baseCurrency", "termCurrency", "exchangeRate", "fxGross", "gross") .match("^Devisenkurs (?[\\w]{3}) \\/ (?[\\w]{3}) ([\\s]+)?(?[\\.,\\d]+)$") - .match("^Dividendengutschrift (?[\\.,\\d]+) (?[\\w]{3}) (?[\\.,\\d]+)\\+ (?[\\w]{3})$") + .match("^Dividendengutschrift (?[\\.,\\d]+) [\\w]{3} (?[\\.,\\d]+)\\+ [\\w]{3}$") .assign((t, v) -> { ExtrExchangeRate rate = asExchangeRate(v); type.getCurrentContext().putType(rate); - Money gross = Money.of(asCurrencyCode(v.get("currency")), asAmount(v.get("gross"))); - Money fxGross = Money.of(asCurrencyCode(v.get("fxCurrency")), asAmount(v.get("fxGross"))); + Money gross = Money.of(rate.getBaseCurrency(), asAmount(v.get("gross"))); + Money fxGross = Money.of(rate.getTermCurrency(), asAmount(v.get("fxGross"))); checkAndSetGrossUnit(gross, fxGross, t, type.getCurrentContext()); }) @@ -393,18 +412,15 @@ private void addDividendeTransaction() // Devisenkurs: 1,0856 (13.01.2023) 109,37 EUR // @formatter:on section -> section - .attributes("fxGross", "fxCurrency", "exchangeRate", "currency") - .match("^Bruttoertrag: (?[\\.,\\d]+) (?[\\w]{3}).*$") - .match("^Devisenkurs: (?[\\.,\\d]+) \\([\\d]{2}\\.[\\d]{2}\\.[\\d]{4}\\) [\\.,\\d]+ (?[\\w]{3}).*$") + .attributes("fxGross", "termCurrency", "exchangeRate", "baseCurrency") + .match("^Bruttoertrag: (?[\\.,\\d]+) (?[\\w]{3}).*$") + .match("^Devisenkurs: (?[\\.,\\d]+) \\([\\d]{2}\\.[\\d]{2}\\.[\\d]{4}\\) [\\.,\\d]+ (?[\\w]{3}).*$") .assign((t, v) -> { - v.put("baseCurrency", asCurrencyCode(v.get("currency"))); - v.put("termCurrency", asCurrencyCode(v.get("fxCurrency"))); - ExtrExchangeRate rate = asExchangeRate(v); type.getCurrentContext().putType(rate); - Money fxGross = Money.of(asCurrencyCode(v.get("fxCurrency")), asAmount(v.get("fxGross"))); - Money gross = rate.convert(asCurrencyCode(v.get("currency")), fxGross); + Money fxGross = Money.of(rate.getTermCurrency(), asAmount(v.get("fxGross"))); + Money gross = rate.convert(rate.getBaseCurrency(), fxGross); checkAndSetGrossUnit(gross, fxGross, t, type.getCurrentContext()); }) @@ -1028,7 +1044,7 @@ private > void addFeesSectionsTransaction(T transaction .assign((t, v) -> processFeeEntries(t, v, type)) // @formatter:off - // Zahlungsverkehr-Transaktionsgebühr: -3,00 EUR + // Zahlungsverkehr-Transaktionsgebühr: -3,00 EUR // @formatter:on .section("fee", "currency").optional() .match("^Zahlungsverkehr\\-Transaktionsgeb.hr: \\-(?[\\.,\\d]+) (?[\\w]{3}).*$")