diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/mlpbank/Kauf01.txt b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/mlpbank/Kauf01.txt new file mode 100644 index 0000000000..b3c3011fd0 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/mlpbank/Kauf01.txt @@ -0,0 +1,33 @@ +PDF Autor: '' +PDFBox Version: 1.8.16 +----------------------------------------- +MLP Banking AG · Alte Heerstraße 40 · 69168 Wiesloch +Depotnummer 8505679654 +Kundennummer 9999999 +Max Mustermann +Auftragsnummer 638328/07.00 +Max Mustermann Datum 18.01.2021 +Musterstraße 10 Rechnungsnummer W00866-0000233255/21 +11111 Musterstadt Umsatzsteuer-ID DE143449824 +Vermögensdepot +0016 +Wertpapier Abrechnung Kauf +Auftrag vom 12.01.2021 10:34:30 Uhr +Nominale Wertpapierbezeichnung ISIN (WKN) +Stück 4,929 SAUREN GLOBAL BALANCED LU0106280836 (930920) +INHABER-ANTEILE A O.N +Handels-/Ausführungsplatz Außerbörslich (gemäß Weisung) +Schlusstag 14.01.2021 +Ausführungskurs 20,29 EUR +Girosammelverw. mehrere Sammelurkunden - kein Stückeausdruck - +Kurswert 100,01- EUR +Ausmachender Betrag 100,01- EUR +Ausgabeaufschlag pro Anteil 5,00 % +Den Gegenwert buchen wir mit Valuta 18.01.2021 zu Lasten des Kontos 505679278 (IBAN DE10 6723 0000 0505 6792 78), +BLZ 67230000 (BIC MLPBDE61XXX). +Die Wertpapiere schreiben wir Ihrem Depotkonto gut. +Sofern keine Umsatzsteuer ausgewiesen ist, handelt es sich um eine umsatzsteuerbefreite Finanzdienstleistung. +Ihr Ausgabeaufschlag betraegt: +0,00 EUR (0,000 Prozent) +Dieses Dokument wurde maschinell erstellt und wird nicht unterschrieben. +0866.01182114.0015226OR07 \ No newline at end of file diff --git a/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/mlpbank/mlpbankPDFExtractorTest.java b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/mlpbank/mlpbankPDFExtractorTest.java new file mode 100644 index 0000000000..1bbe37ef48 --- /dev/null +++ b/name.abuchen.portfolio.tests/src/name/abuchen/portfolio/datatransfer/pdf/mlpbank/mlpbankPDFExtractorTest.java @@ -0,0 +1,66 @@ +package name.abuchen.portfolio.datatransfer.pdf.mlpbank; + +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsEmptyCollection.empty; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.junit.Test; + +import name.abuchen.portfolio.datatransfer.Extractor.BuySellEntryItem; +import name.abuchen.portfolio.datatransfer.Extractor.Item; +import name.abuchen.portfolio.datatransfer.Extractor.SecurityItem; +import name.abuchen.portfolio.datatransfer.pdf.MLPBankingAGPDFExtractor; +import name.abuchen.portfolio.datatransfer.pdf.PDFInputFile; +import name.abuchen.portfolio.model.AccountTransaction; +import name.abuchen.portfolio.model.BuySellEntry; +import name.abuchen.portfolio.model.Client; +import name.abuchen.portfolio.model.PortfolioTransaction; +import name.abuchen.portfolio.model.Security; +import name.abuchen.portfolio.model.Transaction.Unit; +import name.abuchen.portfolio.money.Money; +import name.abuchen.portfolio.money.Values; + +@SuppressWarnings("nls") +public class mlpbankPDFExtractorTest +{ + + @Test + public void testWertpapierKauf01() + { + MLPBankingAGPDFExtractor extractor = new MLPBankingAGPDFExtractor(new Client()); + + List errors = new ArrayList<>(); + + List results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Kauf01.txt"), errors); + + assertThat(errors, empty()); + assertThat(results.size(), is(2)); + + // check security + Security security = results.stream().filter(i -> i instanceof SecurityItem).findFirst() + .orElseThrow(IllegalArgumentException::new).getSecurity(); + assertThat(security.getIsin(), is("LU0106280836")); + assertThat(security.getWkn(), is("930920")); + assertThat(security.getName(), is("SAUREN GLOBAL BALANCED INHABER-ANTEILE A O.N")); + + // check buy sell transaction + Optional 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.BUY)); + assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY)); + + assertThat(entry.getPortfolioTransaction().getAmount(), is(Values.Amount.factorize(100.01))); + assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2021-01-14T00:00"))); + assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(4.929))); + assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE), + is(Money.of("EUR", Values.Amount.factorize(0.00)))); + } +} diff --git a/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MLPBankingAGPDFExtractor.java b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MLPBankingAGPDFExtractor.java new file mode 100644 index 0000000000..bf0571fb1c --- /dev/null +++ b/name.abuchen.portfolio/src/name/abuchen/portfolio/datatransfer/pdf/MLPBankingAGPDFExtractor.java @@ -0,0 +1,88 @@ +package name.abuchen.portfolio.datatransfer.pdf; + +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.BuySellEntry; +import name.abuchen.portfolio.model.Client; +import name.abuchen.portfolio.model.PortfolioTransaction; +import name.abuchen.portfolio.model.Transaction.Unit; +import name.abuchen.portfolio.money.Money; + +@SuppressWarnings("nls") +public class MLPBankingAGPDFExtractor extends AbstractPDFExtractor +{ + public MLPBankingAGPDFExtractor(Client client) + { + super(client); + + addBankIdentifier("MLP Banking AG"); //$NON-NLS-1$ + + addBuySellTransaction(); + } + + @Override + public String getPDFAuthor() + { + return "MLP Banking AG"; //$NON-NLS-1$ + } + + @Override + public String getLabel() + { + return "MLP Banking AG"; //$NON-NLS-1$ + } + + private void addBuySellTransaction() + { + DocumentType newType = new DocumentType(".*Abrechnung Kauf.*"); + this.addDocumentTyp(newType); + + Transaction pdfTransaction = new Transaction<>(); + pdfTransaction.subject(() -> { + BuySellEntry entry = new BuySellEntry(); + entry.setType(PortfolioTransaction.Type.BUY); + return entry; + }); + + Block firstRelevantLine = new Block(".*Abrechnung Kauf.*"); + newType.addBlock(firstRelevantLine); + firstRelevantLine.set(pdfTransaction); + + pdfTransaction + // Stück 4,929 SAUREN GLOBAL BALANCED LU0106280836 (930920) + // INHABER-ANTEILE A O.N + .section("isin", "wkn", "name", "shares", "nameContinued") + .match("^(Stück) (?[\\d.,]+) (?.*) (?[\\w]{12}.*) (\\((?.*)\\).*)") + .match("(?.*)") + .assign((t, v) -> { + t.setSecurity(getOrCreateSecurity(v)); + t.setShares(asShares(v.get("shares"))); + }) + + // Schlusstag 14.01.2021 + .section("date") + .match("^(Schlusstag) (?\\d+.\\d+.\\d{4}+).*") + .assign((t, v) -> { + t.setDate(asDate(v.get("date"))); + }) + + // Ausmachender Betrag 100,01- EUR + .section("currency", "amount") + .match("^(Ausmachender Betrag) (?[\\d.]+,\\d+)[?(-|\\+)] (?\\w{3}+)") + .assign((t, v) -> { + t.setAmount(asAmount(v.get("amount"))); + t.setCurrencyCode(v.get("currency")); + }) + + // Ihr Ausgabeaufschlag betraegt: + // 0,00 EUR (0,000 Prozent) + .section("fee", "currency") + .match("^(?[\\d.-]+,\\d+) (?[\\w]{3}) \\([\\d.-]+,\\d+ \\w+\\)$") + .assign((t, v) -> t.getPortfolioTransaction() + .addUnit(new Unit(Unit.Type.FEE, + Money.of(asCurrencyCode(v.get("currency")), + asAmount(v.get("fee")))))) + .wrap(BuySellEntryItem::new); + } +} 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 2a2a2a111c..d20b72feb5 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 @@ -50,6 +50,7 @@ public PDFImportAssistant(Client client, List files) extractors.add(new HelloBankPDFExtractor(client)); extractors.add(new INGDiBaExtractor(client)); extractors.add(new JustTradePDFExtractor(client)); + extractors.add(new MLPBankingAGPDFExtractor(client)); extractors.add(new OnvistaPDFExtractor(client)); extractors.add(new PostfinancePDFExtractor(client)); extractors.add(new QuirionPDFExtractor(client));