diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/DABPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/DABPDFExtractorTest.java index bb017d5c95..31f6ff3c68 100644 --- a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/DABPDFExtractorTest.java +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/DABPDFExtractorTest.java @@ -1,7 +1,9 @@ package name.abuchen.portfolio.datatransfer.pdf.dab; 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.fee; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasAmount; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasCurrencyCode; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasDate; @@ -18,6 +20,8 @@ import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasWkn; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.inboundDelivery; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.outboundDelivery; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.purchase; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.removal; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.sale; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.security; import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.taxRefund; @@ -799,6 +803,37 @@ public void testWertpapierKauf13() is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(10.00)))); } + @Test + public void testWertpapierKauf14() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kauf14.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("IE00BCBJG560"), hasWkn(null), hasTicker(null), // + hasName("SPDR MSCI Wrld Small Cap U.ETF Registered Shares o.N."), // + hasCurrencyCode("EUR")))); + + // check buy sell transaction + assertThat(results, hasItem(purchase( // + hasDate("2024-08-29T12:59:00"), hasShares(0.0425), // + hasSource("Kauf14.txt"), // + hasNote("Abrechnungs-Nr. 92328727"), // + hasAmount("EUR", 4.13), hasGrossValue("EUR", 4.13), // + hasTaxes("EUR", 0.00), hasFees("EUR", 0.00)))); + } + @Test public void testWertpapierVerkauf01() { @@ -1702,6 +1737,37 @@ public void testWertpapierVerkauf13() hasTaxes("EUR", 100.00 + 10.00 + 10.00), hasFees("EUR", 0.00)))); } + @Test + public void testWertpapierVerkauf14() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Verkauf14.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("IE00BL25JM42"), hasWkn(null), hasTicker(null), // + hasName("Xtr.(IE) - MSCI World Value Registered Shares 1C USD o.N."), // + hasCurrencyCode("EUR")))); + + // check buy sell transaction + assertThat(results, hasItem(sale( // + hasDate("2024-11-07T16:00"), hasShares(0.2741), // + hasSource("Verkauf14.txt"), // + hasNote("Abrechnungs-Nr. 64518224"), // + hasAmount("EUR", 11.60), hasGrossValue("EUR", 11.67), // + hasTaxes("EUR", 0.07), hasFees("EUR", 0.00)))); + } + @Test public void testMultipleWertpapierKaufVerkauf01() { @@ -3648,4 +3714,138 @@ public void testKontoumsaetze07() assertThat(transaction.getSource(), is("Kontoumsaetze07.txt")); assertThat(transaction.getNote(), is("Porto")); } + + @Test + public void testKontoumsaetze08() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoumsaetze08.txt"), errors); + + assertThat(errors, empty()); + 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); + + // assert transaction + assertThat(results, hasItem(deposit(hasDate("2024-08-28"), hasAmount("EUR", 26.59), // + hasSource("Kontoumsaetze08.txt"), hasNote("vermögenswirksame Leistung")))); + } + + @Test + public void testKontoumsaetze09() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoumsaetze09.txt"), errors); + + assertThat(errors, empty()); + 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); + + // assert transaction + assertThat(results, hasItem(withFailureMessage( // + Messages.MsgErrorTransactionAlternativeDocumentRequired, // + fee( // + hasDate("2024-10-09"), // + hasSource("Kontoumsaetze09.txt"), // + hasNote("Ginmon Gebuehrenrechnung September 2024"), // + hasAmount("EUR", 0.02))))); + } + + @Test + public void testKontoumsaetze10() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoumsaetze10.txt"), errors); + + assertThat(errors, empty()); + 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); + + // assert transaction + assertThat(results, hasItem(removal(hasDate("2024-11-11"), hasAmount("EUR", 50.00), // + hasSource("Kontoumsaetze10.txt"), hasNote("SEPA-Überweisung")))); + } + + @Test + public void testKontoumsaetze11() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoumsaetze11.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("IE00B52MJY50"), hasWkn(null), hasTicker(null), // + hasName(null), // + hasCurrencyCode("EUR")))); + + // assert transaction + assertThat(results, hasItem(withFailureMessage( // + Messages.MsgErrorTransactionAlternativeDocumentRequired, // + sale( // + hasDate("2024-11-11"), hasShares(0.003), // + hasSource("Kontoumsaetze11.txt"), // + hasNote(null), // + hasAmount("EUR", 0.49), hasGrossValue("EUR", 0.49), // + hasTaxes("EUR", 0.00), hasFees("EUR", 0.00))))); + } + + @Test + public void testKontoumsaetze12() + { + DABPDFExtractor extractor = new DABPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kontoumsaetze12.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("IE00BL25JM42"), hasWkn(null), hasTicker(null), // + hasName(null), // + hasCurrencyCode("EUR")))); + + // assert transaction + assertThat(results, hasItem(withFailureMessage( // + Messages.MsgErrorTransactionAlternativeDocumentRequired, // + purchase(// + hasDate("2024-10-01"), hasShares(0.15), // + hasSource("Kontoumsaetze12.txt"), // + hasNote(null), // + hasAmount("EUR", 6.26), hasGrossValue("EUR", 6.26), // + hasTaxes("EUR", 0.00), hasFees("EUR", 0.00))))); + } } diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kauf14.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kauf14.txt new file mode 100644 index 0000000000..9d133b65ea --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kauf14.txt @@ -0,0 +1,50 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +BELEGDRUCK=J +ORIGINAL=1 +FAXVERSAND=N +EMAILVERSAND=N +DEPOTNUMMER=0000000000 +Wertpapierabrechnung DEPOTUNTERBEZEICHNUNG= +VERSANDARTENSCHLUESSEL=DRUCK +ADRESSZEILE1=Herr +Kauf ADRESSZEILE2=Vorname Nachname +Kommissionsgeschäft ADRESSZEILE3=Straße 1 +ADRESSZEILE4=12345 Ort +Depot-Nr. Abrechnungs-Nr. ADRESSZEILE5= +0000000000 92328727 / 29.08.2024 ADRESSZEILE6= +BELEGNUMMER=11349 +Herr SEITENNUMMER=1 +Vorname Nachname STEUERERSTATTUNG=N +Straße 1 Depotinhaber +12345 Ort Vorname Nachname +München, 29.08.2024 +Wir haben für Sie gekauft +Gattungsbezeichnung ISIN +SPDR MSCI Wrld Small Cap U.ETF Registered Shares o.N. IE00BCBJG560 +Nominal Kurs +STK 0,0425 EUR 97,1400 +Handelstag 29.08.2024 Kurswert EUR 4,13- +Handelszeit 12:59* +Börse Tradegate/EDG +Verwahrart Wertpapierrechnung +Lagerland Irland +Wert Konto-Nr. Betrag zu Ihren Lasten +02.09.2024 0000000000 EUR 4,13 +Die Höhe des von der KVG festgelegten Ausgabeauf- bzw. Rücknahmeabschlages sowie die jährlich zu zahlende Ver- +waltungsvergütung und die Gesamtkostenquote sind dem Verkaufsprospekt bzw. den Vertragsbedingungen zu entnehmen. +Aggregierte Order ggf. zum Mischkurs. +* Die angegebene Zeit entspricht den Angaben der Handelspartner gemäß der lokalen Zeit in Deutschland (Mitteleuropäische Zeit bzw. Mitteleuropäische Sommerzeit). +Widerrufsbelehrung für den Erwerb von Anteilen oder Aktien eines offenen Investmentvermögens: Ist der Käufer von Anteilen oder Aktien eines offenen Investmentvermögens +durch mündliche Verhandlungen außerhalb der ständigen Geschäftsräume desjenigen, der die Anteile oder Aktien verkauft oder den Verkauf vermittelt hat, dazu bestimmt worden, +eine auf den Kauf gerichtete Willenserklärung abzugeben, so ist er an diese Erklärung nur gebunden, wenn er sie nicht innerhalb einer Frist von zwei Wochen bei der +Verwaltungsgesellschaft oder einem Repräsentanten im Sinne des § 319 KAGB schriftlich widerruft. +Dieser Beleg wird maschinell erstellt und daher nicht unterschrieben. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens +> 75009 Paris > Frankreich > Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre > Directeur Général: Jean-Laurent Bonnafé +3.19/ABREABHNHANDKF/GABAUFTL/011349/290824/210432 + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze08.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze08.txt new file mode 100644 index 0000000000..42f8230012 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze08.txt @@ -0,0 +1,31 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +Kontoauszug DAB Verrechnungskonto Kontonummer: 0000000000 KOPIE +BLZ: 701 204 00 +IBAN: DE00000000000000000000 +BIC (SWIFT-Code): DABBDEMMXXX +Vorname Nachname +Letzter Auszug Nr. 000 vom 00.00.0000 +Umsatzzeitraum +Ginmon Vermögensverwaltung GmbH 28.08.2024 - 28.08.2024 Seite 1/1 +Mainzer Landstr. 33a +60329 Frankfurt Auszug Nr. 001 +28.08.2024 +Buchung Valuta Buchungsinformation Soll Haben +00.00. Alter Kontostand: EUR 0,00+ +28.08. 28.08. vermögenswirksame Leistung 26,59+ +Company where VL is payed from 000/UVXY VL +Nachname, Vo. +28.08. Neuer Kontostand: EUR 26,59+ +Hinweis +Der Kontostand /Saldo kann auch noch nicht wertgestellte Beträge enthalten, über die bis zur Wertstellung noch nicht ohne Abzug von Sollzinsen +verfügt werden kann. +Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetztes entschädigungsfähig. Nähere Informationen können dem +„Informationsbogen für den Einleger“ entnommen werden. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE 191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens, +75009 Paris, Frankreich, Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre, Directeur Général: Jean-Laurent Bonnafé + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze09.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze09.txt new file mode 100644 index 0000000000..b6f0aba3ff --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze09.txt @@ -0,0 +1,34 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +Kontoauszug DAB Verrechnungskonto Kontonummer: 0000000000 KOPIE +BLZ: 701 204 00 +IBAN: DE00000000000000000000 +BIC (SWIFT-Code): DABBDEMMXXX +Vorname Nachname +Letzter Auszug Nr. 004 vom 27.09.2024 +Umsatzzeitraum +Ginmon Vermögensverwaltung GmbH 28.09.2024 - 09.10.2024 Seite 1/1 +Mainzer Landstr. 33a +60329 Frankfurt Auszug Nr. 005 +09.10.2024 +Buchung Valuta Buchungsinformation Soll Haben +27.09. Alter Kontostand: EUR 0,60+ +09.10. 09.10. Verwalterpreis 0,02- +Ginmon Gebuehrenrechnung September 2024 End to End- +ID:SEPA-EINZUG +IBAN: DE62701204003335687004 +BIC: DABBDEMMXXX +Empfänger: Ginmon Vermoegensverwaltung GmbH +09.10. Neuer Kontostand: EUR 0,58+ +Hinweis +Der Kontostand /Saldo kann auch noch nicht wertgestellte Beträge enthalten, über die bis zur Wertstellung noch nicht ohne Abzug von Sollzinsen +verfügt werden kann. +Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetztes entschädigungsfähig. Nähere Informationen können dem +„Informationsbogen für den Einleger“ entnommen werden. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE 191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens, +75009 Paris, Frankreich, Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre, Directeur Général: Jean-Laurent Bonnafé + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze10.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze10.txt new file mode 100644 index 0000000000..ed4e8c586c --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze10.txt @@ -0,0 +1,34 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +Kontoauszug DAB Verrechnungskonto Kontonummer: 0000000000 KOPIE +BLZ: 701 204 00 +IBAN: DE00000000000000000000 +BIC (SWIFT-Code): DABBDEMMXXX +Vorname Nachname +Letzter Auszug Nr. 009 vom 08.11.2024 +Umsatzzeitraum +Ginmon Vermögensverwaltung GmbH 09.11.2024 - 11.11.2024 Seite 1/1 +Mainzer Landstr. 33a +60329 Frankfurt Auszug Nr. 010 +11.11.2024 +Buchung Valuta Buchungsinformation Soll Haben +08.11. Alter Kontostand: EUR 50,32+ +11.11. 11.11. SEPA-Überweisung 50,00- +AGKRGWWWRHABNBNBOZSPCR Ginmon End to End- +ID:DAB/B3/480606009/2024-11-11 +IBAN: DE00000000000000000000 +BIC: BICXXXXX001 +Empfänger: Vorname Nachname +11.11. Neuer Kontostand: EUR 0,32+ +Hinweis +Der Kontostand /Saldo kann auch noch nicht wertgestellte Beträge enthalten, über die bis zur Wertstellung noch nicht ohne Abzug von Sollzinsen +verfügt werden kann. +Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetztes entschädigungsfähig. Nähere Informationen können dem +„Informationsbogen für den Einleger“ entnommen werden. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE 191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens, +75009 Paris, Frankreich, Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre, Directeur Général: Jean-Laurent Bonnafé + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze11.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze11.txt new file mode 100644 index 0000000000..3d530a0deb --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze11.txt @@ -0,0 +1,30 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +Kontoauszug DAB Verrechnungskonto Kontonummer: 0000000000 KOPIE +BLZ: 701 204 00 +IBAN: DE00000000000000000000 +BIC (SWIFT-Code): DABBDEMMXXX +Vorname Nachname +Letzter Auszug Nr. 007 vom 29.10.2024 +Umsatzzeitraum +Ginmon Vermögensverwaltung GmbH 30.10.2024 - 07.11.2024 +dstr. 33a Seite 1/1Mainzer Lan +60329 Frankfurt Auszug Nr. 008 +07.11.2024 +Buchung Valuta Buchungsinformation Soll Haben +29.10. Alter Kontostand: EUR 1,24+ +07.11. 11.11. Wertpapierverkauf 0,49+ +VKF A2061191320241107 IE00B52MJY50* 0,003 +07.11. Neuer Kontostand: EUR 50,36+ +Hinweis +Der Kontostand /Saldo kann auch noch nicht wertgestellte Beträge enthalten, über die bis zur Wertstellung noch nicht ohne Abzug von Sollzinsen +verfügt werden kann. +Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetztes entschädigungsfähig. Nähere Informationen können dem +„Informationsbogen für den Einleger“ entnommen werden. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE 191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens, +75009 Paris, Frankreich, Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre, Directeur Général: Jean-Laurent Bonnafé + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze12.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze12.txt new file mode 100644 index 0000000000..9331e61b93 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Kontoumsaetze12.txt @@ -0,0 +1,30 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.3.qualifier +----------------------------------------- +Kontoauszug DAB Verrechnungskonto Kontonummer: 0000000000 KOPIE +BLZ: 701 204 00 +IBAN: DE00000000000000000000 +BIC (SWIFT-Code): DABBDEMMXXX +Vorname Nachname +Letzter Auszug Nr. 003 vom 26.09.2024 +Umsatzzeitraum +Ginmon Vermögensverwaltung GmbH 27.09.2024 - 27.09.2024 +dstr. 33a Seite 1/1Mainzer Lan +60329 Frankfurt Auszug Nr. 004 +27.09.2024 +Buchung Valuta Buchungsinformation Soll Haben +26.09. Alter Kontostand: EUR 27,30+ +27.09. 01.10. Wertpapierkauf 6,26- +KAUF A6239874820240927 IE00BL25JM42* 0,150 +27.09. Neuer Kontostand: EUR 0,60+ +Hinweis +Der Kontostand /Saldo kann auch noch nicht wertgestellte Beträge enthalten, über die bis zur Wertstellung noch nicht ohne Abzug von Sollzinsen +verfügt werden kann. +Guthaben sind als Einlagen nach Maßgabe des Einlagensicherungsgesetztes entschädigungsfähig. Nähere Informationen können dem +„Informationsbogen für den Einleger“ entnommen werden. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE 191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens, +75009 Paris, Frankreich, Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre, Directeur Général: Jean-Laurent Bonnafé + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Verkauf14.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Verkauf14.txt new file mode 100644 index 0000000000..36aebc89ce --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/dab/Verkauf14.txt @@ -0,0 +1,89 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +BELEGDRUCK=J +ORIGINAL=1 +FAXVERSAND=N +EMAILVERSAND=N +DEPOTNUMMER=0000000000 +Wertpapierabrechnung DEPOTUNTERBEZEICHNUNG= +VERSANDARTENSCHLUESSEL=DRUCK +ADRESSZEILE1=Herr +Verkauf ADRESSZEILE2=Vorname Nachname +Kommissionsgeschäft ADRESSZEILE3=Straße 1 +ADRESSZEILE4=12345 Ort +Depot-Nr. Abrechnungs-Nr. ADRESSZEILE5= +0000000000 64518224 / 07.11.2024 ADRESSZEILE6= +BELEGNUMMER=8907 +Herr SEITENNUMMER=1 +Vorname Nachname STEUERERSTATTUNG=N +Straße 1 Depotinhaber +12345 Ort Vorname Nachname +München, 07.11.2024 +Wir haben für Sie verkauft +Gattungsbezeichnung ISIN +Xtr.(IE) - MSCI World Value Registered Shares 1C USD o.N. IE00BL25JM42 +Nominal Kurs +STK 0,2741 EUR 42,5700 +Handelstag 07.11.2024 Kurswert EUR 11,67 +Handelszeit 16:00* Kapitalertragsteuer EUR 0,06- +Börse Tradegate/EDG Solidaritätszuschlag EUR 0,01- +Verwahrart Wertpapierrechnung +Lagerland Irland +Wert Konto-Nr. Betrag zu Ihren Gunsten +11.11.2024 0000000000 EUR 11,60 +Hinweise zur steuerlichen Verrechnung: vorher aktuell +Gesamtveräußerungsergebnis vor Anwendung einer TFQ EUR 0,33 +Veräußerungsgewinn Fonds EUR 0,23 +Aktienverlusttopf EUR 0,00 0,00 +allgemeiner Verlusttopf EUR 0,00 0,00 +Quellensteuertopf EUR 0,00 0,00 +zu versteuern EUR 0,23 +im laufenden Jahr einbehaltene Kapitalertragsteuer EUR 0,22 +im laufenden Jahr einbehaltener Solidaritätszuschlag EUR 0,01 +Kapitalertragsteuer, Solidaritätszuschlag und ggf. Kirchensteuer nach gemeldetem Kirchensteuersatz verrechnet mit dem +Finanzamt Frankfurt am Main, Steuernummer 014/220/15370. +Die Höhe des von der KVG festgelegten Ausgabeauf- bzw. Rücknahmeabschlages sowie die jährlich zu zahlende Ver- +waltungsvergütung und die Gesamtkostenquote sind dem Verkaufsprospekt bzw. den Vertragsbedingungen zu entnehmen. +Es folgt Seite 2 +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens +> 75009 Paris > Frankreich > Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre > Directeur Général: Jean-Laurent Bonnafé +3.19/ABREABHNHANDVK/POC1618/008907/071124/210753 +BELEGDRUCK=J +ORIGINAL=1 +FAXVERSAND=N +Depot-Nr. Abrechnungs-Nr. Seite-Nr. EMAILVERSAND=N +00000000000 64518224 2 DEPOTNUMMER=00000000000 +DEPOTUNTERBEZEICHNUNG= +VERSANDARTENSCHLUESSEL=DRUCK +ADRESSZEILE1=Herr +ADRESSZEILE2=Vorname Nachname +Fondsart: Aktienfonds (§ 2 Abs. 6 InvStG) ADRESSZEILE3=Straße 1 +Angewendete Teilfreistellungsquote: 30% ADRESSZEILE4=12345 Ort +Im Steuerabzugsverfahren werden generell - auch bei betrieblichen Anlegern - die Teilfreistellungsquoten (TFQ) für ADRESSZEILE5= +Privatanleger herangezogen. ADRESSZEILE6= +BELEGNUMMER=8907 +SEITENNUMMER=2 +Höhe der Teilfreistellung Privatanleger Betriebliche Anleger(natürliche Person) Körperschaft STEUERERSTATTUNG=N +Aktienfonds 30% 60% 80% +Mischfonds 15% 30% 40% +Immobilienfonds 60% 60% 60% +Immobilienfonds mit +überwiegend 80% 80% 80% +Auslandsimmobilien +Sonstiger Investmentfonds 0% 0% 0% +Aggregierte Order ggf. zum Mischkurs. +* Die angegebene Zeit entspricht den Angaben der Handelspartner gemäß der lokalen Zeit in Deutschland (Mitteleuropäische Zeit bzw. Mitteleuropäische Sommerzeit). +Widerrufsbelehrung für den Erwerb von Anteilen oder Aktien eines offenen Investmentvermögens: Ist der Käufer von Anteilen oder Aktien eines offenen Investmentvermögens +durch mündliche Verhandlungen außerhalb der ständigen Geschäftsräume desjenigen, der die Anteile oder Aktien verkauft oder den Verkauf vermittelt hat, dazu bestimmt worden, +eine auf den Kauf gerichtete Willenserklärung abzugeben, so ist er an diese Erklärung nur gebunden, wenn er sie nicht innerhalb einer Frist von zwei Wochen bei der +Verwaltungsgesellschaft oder einem Repräsentanten im Sinne des § 319 KAGB schriftlich widerruft. +Dieser Beleg wird maschinell erstellt und daher nicht unterschrieben. +BNP Paribas S.A. Niederlassung Deutschland > Standort: München > Landsberger Straße 300 > 80687 München > Postadresse: DAB BNP Paribas > Postfach 2547 > +90011 Nürnberg > Sitz: Nürnberg HRB Nürnberg 31129 > USt.-Ident-Nr.: DE191528929 > Sitz der Hauptniederlassung der BNP Paribas S.A.: 16, boulevard des Italiens +> 75009 Paris > Frankreich > Registergericht: R.C.S. Paris 662 042 449 > Président du Conseil d‘Administration: Jean Lemierre > Directeur Général: Jean-Laurent Bonnafé +3.19/ABREABHNHANDVK/POC1618/008907/071124/210753 + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/ginmon/FeeInvoice01.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/ginmon/FeeInvoice01.txt new file mode 100644 index 0000000000..539c212171 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/ginmon/FeeInvoice01.txt @@ -0,0 +1,41 @@ +``` +PDFBox Version: 1.8.17 +Portfolio Performance Version: 0.72.2 +----------------------------------------- +Ginmon Vermögensverwaltung GmbH, Mainzer Landstraße 33a, 60329 Frankfurt am Main +Herr +Vorname Nachname +Straße 1 +12345 Ort +Deutschland +Rechnungsdatum / Invoice date: 31.10.2024 +Rechnungsnummer /Invoice no: 00000002024101 +Kundennummer /Customer ID: GM0000000 +Gebührenabrechnung Oktober +Invoice October +Zeitraum vom 01.10.2024 – 31.10.2024 +Period of 01.10.2024 – 31.10.2024 +Position Berechungsbasis Gebühr Betrag +Calculation Fee Amount +Grundgebühr 57.60 € 0.7500% p.a. 0.04 € +Base fee (Ø AuM in 31 Tagen / days) +Discount 0.00 € +Depotführung inklusive 0.00 € +Handling charge included +Transaktionskosten inklusive 0.00 € +Transaction fees included +MwSt. inkl. von 19% 0.01 € +VAT included of 19% +Rechnungsbetrag 0.04 € +Total amount +Der ausstehende Betrag wird in den kommenden Tagen automatisch aus Ihrem Ginmon Konto +entnommen. Sie müssen hierfür nichts weiter unternehmen. +The amount will automatically be deducted from your Ginmon account within the upcoming days. There +is no further action required on your side. +Ginmon GmbH Geschäftssitz Bankverbindung +Ginmon Vermögensverwaltung Geschäftsführer: Lars Reiner IBAN: DE66 7012 0400 2569 4200 09 +Mainzer Landstraße 33a Amtsgericht: Frankfurt am Main BIC: DABBDEMMXXX +60329 Frankfurt am Main HRB 102248 / HRB 107290 DAB BNP Paribas +service@ginmon.de USt-IdNr. DE298791666 + +``` \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/ginmon/GinmonPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/ginmon/GinmonPDFExtractorTest.java new file mode 100644 index 0000000000..c874d7567f --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/ginmon/GinmonPDFExtractorTest.java @@ -0,0 +1,51 @@ +package name.abuchen.portfolio.datatransfer.pdf.ginmon; + +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.fee; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasAmount; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasDate; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasNote; +import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasSource; +import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countAccountTransactions; +import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countBuySell; +import static name.abuchen.portfolio.datatransfer.ExtractorTestUtilities.countSecurities; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsEmptyCollection.empty; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import name.abuchen.portfolio.datatransfer.Extractor.Item; +import name.abuchen.portfolio.datatransfer.actions.AssertImportActions; +import name.abuchen.portfolio.datatransfer.pdf.GinmonPDFExtractor; +import name.abuchen.portfolio.datatransfer.pdf.PDFInputFile; +import name.abuchen.portfolio.model.Client; +import name.abuchen.portfolio.money.CurrencyUnit; + +@SuppressWarnings("nls") +public class GinmonPDFExtractorTest +{ + @Test + public void testFeeInvoice01() + { + GinmonPDFExtractor extractor = new GinmonPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "FeeInvoice01.txt"), errors); + + assertThat(errors, empty()); + 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); + + // assert transaction + assertThat(results, hasItem(fee(hasDate("2024-10-31"), hasAmount("EUR", 0.04), // + hasSource("FeeInvoice01.txt"), hasNote("R.-Nr.: 00000002024101 | 01.10.2024 – 31.10.2024")))); + } +} diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DABPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DABPDFExtractor.java index 7ea4089075..845d043edf 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DABPDFExtractor.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/DABPDFExtractor.java @@ -157,6 +157,21 @@ private void addBuySellTransaction() v.put("name", v.get("name") + " " + v.get("name1")); t.setSecurity(getOrCreateSecurity(v)); + }), + // @formatter:off + // SPDR MSCI Wrld Small Cap U.ETF Registered Shares o.N. IE00BCBJG560 + // Nominal Kurs + // STK 0,0425 EUR 97,1400 + // @formatter:on + section -> section // + .attributes("name", "isin", "currency") // + .match("^(?.*) (?[A-Z]{2}[A-Z0-9]{9}[0-9]).*$") // + .find("Nominal Kurs") // + .match("^STK (?[\\.,\\d]+) (?[\\w]{3}) [\\.,\\d]+$") // + .assign((t, v) -> { + t.setSecurity(getOrCreateSecurity(v)); + t.setShares(asShares(v.get("shares"))); + t.setDate(asDate(v.get("date"), v.get("time"))); })) // @formatter:off @@ -1026,7 +1041,7 @@ private void addBuySellTaxReturnBlock(DocumentType type) private void addAccountStatementTransaction() { - final DocumentType type = new DocumentType("(Verm.gensbericht|Verm.gensstatus)", // + final DocumentType type = new DocumentType("(Verm.gensbericht|Verm.gensstatus|Kontoauszug)", // documentContext -> documentContext // .oneOf( // // @formatter:off @@ -1043,7 +1058,22 @@ private void addAccountStatementTransaction() .attributes("currency") // .match("^Referenzw.hrung (?.*)$") // .assign((ctx, v) -> { - if ("Euro".equals(trim(v.get("currency")))) ctx.put("currency", "EUR"); + if ("Euro".equals(trim(v.get("currency")))) + ctx.put("currency", "EUR"); + }), + // @formatter:off + // 28.08.2024 + // Buchung Valuta Buchungsinformation Soll Haben + // 00.00. Alter Kontostand: EUR 0,00+ + // @formatter:on + section -> section // + .attributes("year", "currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\.(?[\\d]{4})$") // + .find("Buchung Valuta Buchungsinformation Soll Haben") // + .match("^[\\d]{2}\\.[\\d]{2}\\. Alter Kontostand: (?[\\w]{3}) [\\.,\\d]+\\+$") // + .assign((ctx, v) -> { + ctx.put("year", v.get("year")); + ctx.put("currency", asCurrencyCode(v.get("currency"))); }))); this.addDocumentTyp(type); @@ -1074,6 +1104,55 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); + // @formatter:off + // 23.09.2022 23.09.2022 SEPA-Überweisung Anlage 2.000,00 EUR + // @formatter:on + Block depositBlock_Format02 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} SEPA\\-.berweisung .* [\\.,\\d]+ [\\w]{3}$"); + type.addBlock(depositBlock_Format02); + depositBlock_Format02.set(new Transaction() + + .subject(() -> { + AccountTransaction accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.DEPOSIT); + return accountTransaction; + }) + + .section("date", "note", "amount", "currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) (?SEPA\\-.berweisung) .* (?[\\.,\\d]+) (?[\\w]{3})$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date"))); + t.setAmount(asAmount(v.get("amount"))); + t.setCurrencyCode(asCurrencyCode(v.get("currency"))); + t.setNote(v.get("note")); + }) + + .wrap(TransactionItem::new)); + + // @formatter:off + // 28.08. 28.08. vermögenswirksame Leistung 26,59+ + // @formatter:on + Block depositBlock_Format03 = new Block("^[\\d]{2}\\.[\\d]{2}\\. [\\d]{2}\\.[\\d]{2}\\. verm.genswirksame Leistung [\\.,\\d]+\\+$"); + type.addBlock(depositBlock_Format03); + depositBlock_Format03.set(new Transaction() + + .subject(() -> { + AccountTransaction accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.DEPOSIT); + return accountTransaction; + }) + + .section("date", "note", "amount") // + .documentContext("year", "currency") // + .match("^([\\d]{2}\\.[\\d]{2}\\.) (?[\\d]{2}\\.[\\d]{2}\\.) (?verm.genswirksame Leistung) (?[\\.,\\d]+)\\+$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date") + v.get("year"))); + t.setCurrencyCode(v.get("currency")); + t.setAmount(asAmount(v.get("amount"))); + t.setNote(v.get("note")); + }) + + .wrap(TransactionItem::new)); + // @formatter:off // SEPA-Überweisung MUSTERMANN, MAX 05.07.19 15.000,00 // no minus sign! // SEPA-Dauerauftrag MUSTERMANN, MAX 15.07.19 300,00 // no minus sign! @@ -1100,6 +1179,55 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); + // @formatter:off + // 23.09.2022 23.09.2022 SEPA-Überweisung Entsparen -2.000,00 EUR + // @formatter:on + Block removalBlock_Format02 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} SEPA\\-.berweisung .* -[\\.,\\d]+ [\\w]{3}$"); + type.addBlock(removalBlock_Format02); + removalBlock_Format02.set(new Transaction() + + .subject(() -> { + AccountTransaction accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.REMOVAL); + return accountTransaction; + }) + + .section("date", "note", "amount", "currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) (?SEPA\\-.berweisung) .* -(?[\\.,\\d]+) (?[\\w]{3})$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date"))); + t.setAmount(asAmount(v.get("amount"))); + t.setCurrencyCode(asCurrencyCode(v.get("currency"))); + t.setNote(v.get("note")); + }) + + .wrap(TransactionItem::new)); + + // @formatter:off + // 11.11. 11.11. SEPA-Überweisung 50,00- + // @formatter:on + Block removalBlock_Format03 = new Block("^[\\d]{2}\\.[\\d]{2}\\. [\\d]{2}\\.[\\d]{2}\\. SEPA\\-.berweisung [\\.,\\d]+\\-$"); + type.addBlock(removalBlock_Format03); + removalBlock_Format03.set(new Transaction() + + .subject(() -> { + AccountTransaction accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.REMOVAL); + return accountTransaction; + }) + + .section("note", "date", "amount") // + .documentContext("year", "currency") // + .match("^[\\d]{2}\\.[\\d]{2}\\. (?[\\d]{2}\\.[\\d]{2}\\.) (?SEPA\\-.berweisung) (?[\\.,\\d]+)\\-$") // + .assign((t, v) -> { + t.setDateTime(asDate(v.get("date") + v.get("year"))); + t.setCurrencyCode(v.get("currency")); + t.setAmount(asAmount(v.get("amount"))); + t.setNote(v.get("note")); + }) + + .wrap(TransactionItem::new)); + // @formatter:off // Belastung Porto 05.04.16 0,70 // no minus sign! // @formatter:on @@ -1126,52 +1254,67 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); // @formatter:off - // 23.09.2022 23.09.2022 SEPA-Überweisung Anlage 2.000,00 EUR + // SEPA-Lastschrift Lastschrift Managementgebühr 29.06.20 53,02 // @formatter:on - Block depositBlock_Format02 = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} SEPA\\-.berweisung .* [\\.,\\d]+ [\\w]{3}$"); - type.addBlock(depositBlock_Format02); - depositBlock_Format02.set(new Transaction() + Block feesBlock_Format02 = new Block("^SEPA\\-Lastschrift Lastschrift Managementgeb.hr .*$"); + type.addBlock(feesBlock_Format02); + feesBlock_Format02.set(new Transaction() .subject(() -> { AccountTransaction accountTransaction = new AccountTransaction(); - accountTransaction.setType(AccountTransaction.Type.DEPOSIT); + accountTransaction.setType(AccountTransaction.Type.FEES); return accountTransaction; }) - .section("note", "date", "amount", "currency") // - .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) (?SEPA\\-.berweisung) .* (?[\\.,\\d]+) (?[\\w]{3})$") // + .section("note", "date", "amount") // + .documentContext("currency") // + .match("^SEPA\\-Lastschrift Lastschrift (?Managementgeb.hr) (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) (?[\\.,\\d]+)$") // .assign((t, v) -> { t.setDateTime(asDate(v.get("date"))); t.setAmount(asAmount(v.get("amount"))); - t.setCurrencyCode(asCurrencyCode(v.get("currency"))); + t.setCurrencyCode(v.get("currency")); t.setNote(v.get("note")); }) .wrap(TransactionItem::new)); // @formatter:off - // 23.09.2022 23.09.2022 SEPA-Überweisung Entsparen -2.000,00 EUR + // 09.10. 09.10. Verwalterpreis 0,02- + // Ginmon Gebuehrenrechnung September 2024 End to End- // @formatter:on - Block removalBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} [\\d]{2}\\.[\\d]{2}\\.[\\d]{4} SEPA\\-.berweisung .* -[\\.,\\d]+ [\\w]{3}$"); - type.addBlock(removalBlock); - removalBlock.set(new Transaction() + Block feeBlock_Format03 = new Block("^[\\d]{2}\\.[\\d]{2}\\. [\\d]{2}\\.[\\d]{2}\\. Verwalterpreis [\\.,\\d]+\\-$"); + type.addBlock(feeBlock_Format03); + feeBlock_Format03.setMaxSize(2); + feeBlock_Format03.set(new Transaction() .subject(() -> { AccountTransaction accountTransaction = new AccountTransaction(); - accountTransaction.setType(AccountTransaction.Type.REMOVAL); + accountTransaction.setType(AccountTransaction.Type.FEES); return accountTransaction; }) - .section("note", "date", "amount", "currency") // - .match("^[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4}) (?SEPA\\-.berweisung) .* -(?[\\.,\\d]+) (?[\\w]{3})$") // + .section("amount", "date", "note") // + .documentContext("currency", "year") // + .match("^[\\d]{2}\\.[\\d]{2}\\. (?[\\d]{2}\\.[\\d]{2}\\.) Verwalterpreis (?[\\.,\\d]+)\\-$") // + .match("^(?.*) End to End\\-") // .assign((t, v) -> { - t.setDateTime(asDate(v.get("date"))); + t.setDateTime(asDate(v.get("date") + v.get("year"))); + t.setCurrencyCode(v.get("currency")); t.setAmount(asAmount(v.get("amount"))); - t.setCurrencyCode(asCurrencyCode(v.get("currency"))); t.setNote(v.get("note")); + + if (v.get("note").startsWith("Ginmon Gebuehrenrechnung")) + v.getTransactionContext().put(FAILURE, Messages.MsgErrorTransactionAlternativeDocumentRequired); }) - .wrap(TransactionItem::new)); + .wrap((t, ctx) -> { + TransactionItem item = new TransactionItem(t); + + if (ctx.getString(FAILURE) != null) + item.setFailureMessage(ctx.getString(FAILURE)); + + return item; + })); // @formatter:off // 23.09.2022 23.09.2022 Sollzinsen -100,00 EUR @@ -1198,29 +1341,47 @@ private void addAccountStatementTransaction() .wrap(TransactionItem::new)); // @formatter:off - // SEPA-Lastschrift Lastschrift Managementgebühr 29.06.20 53,02 + // 07.11. 11.11. Wertpapierverkauf 0,49+ + // VKF A2061191320241107 IE00B52MJY50* 0,003 + // + // 27.09. 01.10. Wertpapierkauf 6,26- + // KAUF A6239874820240927 IE00BL25JM42* 0,150 // @formatter:on - Block feesBlock = new Block("^SEPA\\-Lastschrift Lastschrift Managementgeb.hr .*$"); - type.addBlock(feesBlock); - feesBlock.set(new Transaction() + Block BuySellBlock = new Block("^[\\d]{2}\\.[\\d]{2}\\. [\\d]{2}\\.[\\d]{2}\\. (Wertpapierverkauf|Wertpapierkauf) [\\.,\\d]+[\\+\\-]$"); + type.addBlock(BuySellBlock); + BuySellBlock.set(new Transaction() .subject(() -> { - AccountTransaction accountTransaction = new AccountTransaction(); - accountTransaction.setType(AccountTransaction.Type.FEES); - return accountTransaction; + BuySellEntry portfolioTransaction = new BuySellEntry(); + portfolioTransaction.setType(PortfolioTransaction.Type.BUY); + return portfolioTransaction; }) - .section("note", "date", "amount") // - .documentContext("currency") // - .match("^SEPA\\-Lastschrift Lastschrift (?Managementgeb.hr) (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{2}) (?[\\.,\\d]+)$") // + .section("amount", "date", "isin", "shares", "type") // + .documentContext("currency", "year") // + .match("^[\\d]{2}\\.[\\d]{2}\\. (?[\\d]{2}\\.[\\d]{2}\\.) (?Wertpapierverkauf|Wertpapierkauf) (?[\\.,\\d]+)[\\+\\-]$") // + .match("^.* (?[A-Z]{2}[A-Z0-9]{9}[0-9])\\*[\\s]{1,}(?[\\.,\\d]+)$") // .assign((t, v) -> { - t.setDateTime(asDate(v.get("date"))); - t.setAmount(asAmount(v.get("amount"))); + if ("Wertpapierverkauf".equals(v.get("type"))) + t.setType(PortfolioTransaction.Type.SELL); + + t.setSecurity(getOrCreateSecurity(v)); + + t.setDate(asDate(v.get("date") + v.get("year"))); t.setCurrencyCode(v.get("currency")); - t.setNote(v.get("note")); + t.setShares(asShares(v.get("shares"))); + t.setAmount(asAmount(v.get("amount"))); + v.getTransactionContext().put(FAILURE, Messages.MsgErrorTransactionAlternativeDocumentRequired); }) - .wrap(TransactionItem::new)); + .wrap((t, ctx) -> { + BuySellEntryItem item = new BuySellEntryItem(t); + + if (ctx.getString(FAILURE) != null) + item.setFailureMessage(ctx.getString(FAILURE)); + + return item; + })); } private > void addTaxesSectionsTransaction(T transaction, DocumentType type) @@ -1425,4 +1586,5 @@ private > void addFeesSectionsTransaction(T transaction .match("^.*[\\s]{1,}Transaktionsentgelt (?[\\w]{3}) (?[\\.,\\d]+)\\-$") // .assign((t, v) -> processFeeEntries(t, v, type)); } + } \ No newline at end of file diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/GinmonPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/GinmonPDFExtractor.java new file mode 100644 index 0000000000..afbfa33d5d --- /dev/null +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/GinmonPDFExtractor.java @@ -0,0 +1,97 @@ +package name.abuchen.portfolio.datatransfer.pdf; + +import static name.abuchen.portfolio.util.TextUtil.concatenate; +import static name.abuchen.portfolio.util.TextUtil.trim; + +import name.abuchen.portfolio.datatransfer.ExtractorUtils; +import name.abuchen.portfolio.datatransfer.pdf.PDFParser.Block; +import name.abuchen.portfolio.datatransfer.pdf.PDFParser.DocumentType; +import name.abuchen.portfolio.datatransfer.pdf.PDFParser.Transaction; +import name.abuchen.portfolio.model.AccountTransaction; +import name.abuchen.portfolio.model.Client; +import name.abuchen.portfolio.money.Values; + +@SuppressWarnings("nls") +public class GinmonPDFExtractor extends AbstractPDFExtractor +{ + public GinmonPDFExtractor(Client client) + { + super(client); + + addBankIdentifier("Ginmon Vermögensverwaltung GmbH"); + + addNonImportableTransaction(); + } + + @Override + public String getLabel() + { + return "Ginmon Vermögensverwaltung GmbH"; + } + + private void addNonImportableTransaction() + { + final DocumentType type = new DocumentType("Geb.hrenabrechnung", "Kontoauszug"); + this.addDocumentTyp(type); + + Transaction pdfTransaction = new Transaction<>(); + + Block firstRelevantLine = new Block("^Rechnungsdatum.*$"); + type.addBlock(firstRelevantLine); + firstRelevantLine.set(pdfTransaction); + + pdfTransaction // + + .subject(() -> { + AccountTransaction accountTransaction = new AccountTransaction(); + accountTransaction.setType(AccountTransaction.Type.FEES); + return accountTransaction; + }) + + // @formatter:off + // Rechnungsbetrag 0.04 € + // @formatter:on + .section("amount", "currency") // + .match("^Rechnungsbetrag (?[\\.,\\d]+) (?\\p{Sc})$") // + .assign((t, v) -> { + t.setCurrencyCode(asCurrencyCode(v.get("currency"))); + t.setAmount(asAmount(v.get("amount"))); + }) + + // @formatter:off + // Rechnungsdatum / Invoice date: 31.10.2024 + // @formatter:on + .section("date") // + .match("^Rechnungsdatum / Invoice date: (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4})$") // + .assign((t, v) -> t.setDateTime(asDate(v.get("date")))) + + // @formatter:off + // Rechnungsnummer /Invoice no: 00000002024101 + // @formatter:on + .section("note").optional() // + .match("^Rechnungsnummer.*: (?.*)$") // + .assign((t, v) -> t.setNote("R.-Nr.: " + trim(v.get("note")))) + + // @formatter:off + // Zeitraum vom 01.10.2024 – 31.10.2024 + // @formatter:on + .section("note").optional() // + .match("^Zeitraum vom (?[\\d]{2}\\.[\\d]{2}\\.[\\d]{4} \\– [\\d]{2}\\.[\\d]{2}\\.[\\d]{4})$") // + .assign((t, v) -> t.setNote(concatenate(t.getNote(), trim(v.get("note")), " | "))) + + .wrap((t, ctx) -> { + TransactionItem item = new TransactionItem(t); + + if (ctx.getString(FAILURE) != null) + item.setFailureMessage(ctx.getString(FAILURE)); + + return item; + }); + } + + @Override + protected long asAmount(String value) + { + return ExtractorUtils.convertToNumberLong(value, Values.Amount, "en", "US"); + } +} diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFImportAssistant.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFImportAssistant.java index 2338afb139..c4763e8942 100644 --- a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFImportAssistant.java +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/PDFImportAssistant.java @@ -73,6 +73,7 @@ public PDFImportAssistant(Client client, List files) extractors.add(new FinTechGroupBankPDFExtractor(client)); extractors.add(new FirstradeSecuritiesIncPDFExtractor(client)); extractors.add(new GenoBrokerPDFExtractor(client)); + extractors.add(new GinmonPDFExtractor(client)); extractors.add(new GladbacherBankAGPDFExtractor(client)); extractors.add(new HargreavesLansdownPlcExtractor(client)); extractors.add(new HelloBankPDFExtractor(client));