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 Trade Republic PDF-Importer to support new transaction #2897

Merged
merged 1 commit into from Jul 2, 2022
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
@@ -0,0 +1,32 @@
PDFBox Version: 1.8.16
-----------------------------------------
TRADE REPUBLIC BANK GMBH KASTANIENALLEE 32 10435 BERLIN
+
+
+
+
+
WERTPAPIERABRECHNUNG
ÜBERSICHT
Market-Order Kauf am 15.02.2022, um 17:39 Uhr (Europe/Berlin) an der Lang & Schwarz Exchange.
Der Kontrahent der Transaktion ist Lang & Schwarz TradeCenter AG & Co. KG.
POSITION ANZAHL KURS BETRAG
3M Co. 7 Stk. 139,40 EUR 975,80 EUR
Registered Shares DL -,01
ISIN: US88579Y1010
GESAMT 975,80 EUR
ABRECHNUNG
POSITION BETRAG
Fremdkostenzuschlag -1,00 EUR
GESAMT -976,80 EUR
BUCHUNG
VERRECHNUNGSKONTO VALUTA BETRAG
DE123+++ 17.02.2022 -976,80 EUR
3M Co. Registered Shares DL -,01 in Girosammelverwahrung in Deutschland.
Diese Abrechnung wird maschinell erstellt und daher nicht unterschrieben.
Sofern keine Umsatzsteuer ausgewiesen ist, handelt es sich gem. § 4 Nr. 8 UStG um eine umsatzsteuerfreie
Leistung.
Trade Republic Bank GmbH www.traderepublic.com Sitz der Gesellschaft: Düsseldorf Geschäftsführer
Kastanienallee 32 service@traderepublic.com AG Düsseldorf HRB 85864 Andreas Willius
10435 Berlin USt-ID DE307510626 Karsten Müller
ABRE / 15.02.2022 / 35573379 / 9bb6-125d
Expand Up @@ -246,6 +246,48 @@ public void testKauf05()
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(1.00))));
}

@Test
public void testKauf06()
{
TradeRepublicPDFExtractor extractor = new TradeRepublicPDFExtractor(new Client());

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

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

assertThat(errors, empty());
assertThat(results.size(), is(2));
new AssertImportActions().check(results, CurrencyUnit.EUR);

// check security
Security security = results.stream().filter(SecurityItem.class::isInstance).findFirst()
.orElseThrow(IllegalArgumentException::new).getSecurity();
assertThat(security.getIsin(), is("US88579Y1010"));
assertThat(security.getName(), is("3M Co. Registered Shares DL -,01"));
assertThat(security.getCurrencyCode(), is(CurrencyUnit.EUR));

// check buy sell transaction
BuySellEntry entry = (BuySellEntry) results.stream().filter(BuySellEntryItem.class::isInstance).findFirst()
.orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(entry.getPortfolioTransaction().getType(), is(PortfolioTransaction.Type.BUY));
assertThat(entry.getAccountTransaction().getType(), is(AccountTransaction.Type.BUY));

assertThat(entry.getPortfolioTransaction().getDateTime(), is(LocalDateTime.parse("2022-02-15T17:39")));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(7)));
assertThat(entry.getSource(), is("Kauf06.txt"));
assertNull(entry.getNote());

assertThat(entry.getPortfolioTransaction().getMonetaryAmount(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(976.80))));
assertThat(entry.getPortfolioTransaction().getGrossValue(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(975.80))));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.TAX),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(0.00))));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(1.00))));
}

@Test
public void testAchat01()
{
Expand Down
Expand Up @@ -142,9 +142,10 @@ private void addBuySellTransaction()
.match("^Sparplanausf.hrung .* (?<date>([\\d]{2}\\.[\\d]{2}\\.[\\d]{4}|[\\d]{4}\\-[\\d]{2}\\-[\\d]{2})) .*$")
.assign((t, v) -> t.setDate(asDate(v.get("date"))))
,
/***
* This is for the reinvestment of dividends
*/

// This is for the reinvestment of
// dividends

// DE40110101001234567890 06.08.2021 0,44 GBP
section -> section
.attributes("date")
Expand All @@ -155,6 +156,9 @@ private void addBuySellTransaction()
// If the type of transaction is "SELL" and the amount
// is negative, then the gross amount set. Fees are
// processed in a separate transaction.

// GESAMT 1.395,60 EUR
// GESAMT -1.396,60 EUR
.section("negative").optional()
.match("GESAMT (\\-)?[\\.,\\d]+ [\\w]{3}")
.match("GESAMT (?<negative>\\-)[\\.,\\d]+ [\\w]{3}")
Expand All @@ -169,10 +173,10 @@ private void addBuySellTransaction()
// - one for gross
// - one for the net value
// we pick the second
//
// @formatter:on

// GESAMT 1.825,60 EUR
// GESAMT 1.792,29 EUR
// @formatter:on
section -> section
.attributes("amount", "currency", "gross", "grossCurrency")
.match("^(GESAMT|TOTAL) (\\-)?(?<gross>[\\.,\\d]+) (?<grossCurrency>[\\w]{3})$")
Expand All @@ -190,14 +194,12 @@ private void addBuySellTransaction()
}
})
,
// @formatter:off
// In case there is no tax,
// only one line with "GESAMT"
// exists and we need to grab data from that line
//

// GESAMT 1.792,29 EUR
// TOTAL 20,00 EUR
// @formatter:on
section -> section
.attributes("amount", "currency")
.match("^(GESAMT|TOTAL) (\\-)?(?<amount>[\\.,\\d]+) (?<currency>[\\w]{3})$")
Expand Down Expand Up @@ -407,10 +409,10 @@ private void addDividendeTransaction()
// - one for gross
// - one for the net value
// we pick the second
//
// @formatter:on

// GESAMT 3,83 EUR
// GESAMT 2,83 EUR
// @formatter:on
section -> section
.attributes("amount", "currency")
.match("^GESAMT [\\.,\\d]+ [\\w]{3}$")
Expand Down Expand Up @@ -551,7 +553,7 @@ private void addDeliveryInOutBoundTransaction()
Pattern pTransactionPosition = Pattern.compile("^(?<transactionPosition>[\\d]) (Barausgleich|Kurswert) (\\-)?[\\.,\\d]+ [\\w]{3}$");
context.put("skipTransaction", Boolean.FALSE.toString());
context.put("transactionPosition", "0");
// read the current context here

for (String line : lines)
{
Matcher m = pDate.matcher(line);
Expand Down Expand Up @@ -715,7 +717,7 @@ private void addAccountStatementTransaction()
{
DocumentType type = new DocumentType("KONTOAUSZUG", (context, lines) -> {
Pattern currency = Pattern.compile("BUCHUNGSTAG / BUCHUNGSTEXT BETRAG IN (?<currency>[\\w]{3})");
// read the current context here

for (String line : lines)
{
Matcher m = currency.matcher(line);
Expand Down Expand Up @@ -1010,11 +1012,14 @@ private void addSellWithNegativeAmountTransaction()
.match("^((Limit|Stop-Market|Market)-Order )?(Kauf|Verkauf) .* (?<date>([\\d]{2}\\.[\\d]{2}\\.[\\d]{4}|[\\d]{4}\\-[\\d]{2}\\-[\\d]{2})), um (?<time>[\\d]{2}:[\\d]{2}) .*$")
.assign((t, v) -> t.setDateTime(asDate(v.get("date"), v.get("time"))))

// GESAMT 0,34 EUR
// GESAMT -0,66 EUR
.section("negative").optional()
.match("^GESAMT [\\.,\\d]+ [\\w]{3}$")
.match("^GESAMT (?<negative>\\-)[\\.,\\d]+ [\\w]{3}$")
.assign((t, v) -> type.getCurrentContext().put("negative", "X"))

// GESAMT -0,66 EUR
.section("negative").optional()
.match("^GESAMT (?<negative>\\-)[\\.,\\d]+ [\\w]{3}$")
.assign((t, v) -> {
Expand Down