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

Fix Quirion dividend import in USD #3475

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
```
PDFBox Version: 1.8.17
Portfolio Performance Version: 0.64.4
-----------------------------------------
Erträgnisabrechnung
Referenz-Nr 12345858
Datum 28.07.2023
Depot 1234567800
Muster, Hans
Frau
Hans Muster
Straße 2
12345 Berlin
Seite 1 von 2
Für aus Ihrem Depot fällig gewordene Erträgnisse erteilen wir nachstehende Abrechnung:
Wertpapierbezeichnung iShsIII-MSCI EM Sm.Cap U.ETF Registered Shares o.N.
ISIN IE00B3F81G20
WKN A0RGER
Verwahrart Wertpapierrechnung
Lagerland Irland
Nominal/Stück 1,9983 ST
Währung USD
Zahlungszeitraum 01.07.2023 - 30.06.2024
Ausschüttung USD 0,7849 pro Anteil
Ex-Tag 13.07.2023
Zahlungstag 26.07.2023
Betrag USD 1,57
Kapitalertragsteuer USD 0,00
Solidaritätszuschlag USD 0,00
Kirchensteuer USD 0,00
Ausmachender Betrag USD 1,57
Devisenkurs EUR/USD 1,110890
Ausmachender Betrag EUR 1,41
Der Abrechnungsbetrag wird mit Valuta 26.07.2023 über Ihr Konto 1234567800 EUR gebucht.
Gebietsansässigen Empfängern von Erträgen aus ausländischen Wertpapieren obliegt eine Meldepflicht nach §§ 67
ff. AWV (Außenwirtschaftsverordnung), wenn die Gutschrift EUR 12.500,00 übersteigt.
Keine Steuerbescheinigung!
Für weitere Fragen wenden Sie sich bitte an Ihren Kundenberater.
Diese Mitteilung wurde maschinell erstellt und wird von der Bank nicht unterschrieben.
Quirin Privatbank AG
Postfach 311105 | 10641 Berlin T +49 (0)30 890 21-300 Handelsregister: Vorstand: Karl Matthäus Schmidt
Kurfürstendamm 119 | 10711 Berlin F +49 (0)30 890 21-301 Berlin Charlottenburg, HRB 87859 Johannes Eismann
www.quirinprivatbank.de info@quirinprivatbank.de USt-IdNr.: DE195661729 Aufsichtsratsvorsitzender: Holger Timm
SECTRX2 / 62243624 / 20230728 14:36:14
Erträgnisabrechnung
Referenz-Nr 12345858
Seite 2 von 2
Steuerliche Informationen
Steuerlicher Devisenumrechnungskurs: EUR/USD 1,110890
Ausschüttungsbetrag: EUR 1,41
Steuerpflichtiger Betrag nach Teilfreistellung im Privatvermögen: EUR 1,41
Kapitalertragsteuerpflichtiger Betrag: EUR 1,41
Stand allg. Verlustverrechnungstopf vor Veränderung: EUR 0,00
Veränderung allg. Verlustverrechnungstopf: EUR 0,00
Stand allg. Verlustverrechnungstopf nach Veränderung: EUR 0,00
Stand Freistellungsauftrag vor Veränderung: EUR 16,52
Veränderung Freistellungsauftrag: EUR -1,41
Stand Freistellungsauftrag nach Veränderung: EUR 15,11
Bemessungsgrundlage für Kapitalertragsteuer: EUR 0,00
Kapitalertragsteuer: EUR 0,00
Solidaritätszuschlag: EUR 0,00
Kirchensteuer: EUR 0,00
Steuerliche Information für Veranlagungszwecke
Steuerpfl. Betrag nach Teilfreistellung im Betriebsvermögen (EStG): EUR 1,41
Steuerpfl. Betrag nach Teilfreistellung im Betriebsvermögen (KStG): EUR 1,41
Quirin Privatbank AG
Postfach 311105 | 10641 Berlin T +49 (0)30 890 21-300 Handelsregister: Vorstand: Karl Matthäus Schmidt
Kurfürstendamm 119 | 10711 Berlin F +49 (0)30 890 21-301 Berlin Charlottenburg, HRB 87859 Johannes Eismann
www.quirinprivatbank.de info@quirinprivatbank.de USt-IdNr.: DE195661729 Aufsichtsratsvorsitzender: Holger Timm
SECTRX2 / 62243624 / 20230728 14:36:14

```
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,52 @@ public void testDividende03()
assertThat(grossValueUnit.getForex(), is(Money.of(CurrencyUnit.USD, Values.Amount.factorize(163.08))));
}

@Test
public void testDividende04()
{
QuirinBankAGPDFExtractor extractor = new QuirinBankAGPDFExtractor(new Client());

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

List<Item> results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Dividende04.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("IE00B3F81G20"));
assertThat(security.getWkn(), is("A0RGER"));
assertNull(security.getTickerSymbol());
assertThat(security.getName(), is("iShsIII-MSCI EM Sm.Cap U.ETF Registered Shares o.N."));
assertThat(security.getCurrencyCode(), is(CurrencyUnit.USD));

// check dividends transaction
AccountTransaction transaction = (AccountTransaction) results.stream().filter(TransactionItem.class::isInstance)
.findFirst().orElseThrow(IllegalArgumentException::new).getSubject();

assertThat(transaction.getType(), is(AccountTransaction.Type.DIVIDENDS));

assertThat(transaction.getDateTime(), is(LocalDateTime.parse("2023-07-26T00:00")));
assertThat(transaction.getShares(), is(Values.Share.factorize(1.9983)));
assertThat(transaction.getSource(), is("Dividende04.txt"));
assertThat(transaction.getNote(), is("Referenz-Nr 12345858"));

assertThat(transaction.getMonetaryAmount(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(1.41))));
assertThat(transaction.getGrossValue(),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(1.41))));
assertThat(transaction.getUnitSum(Unit.Type.TAX),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(0.00))));
assertThat(transaction.getUnitSum(Unit.Type.FEE),
is(Money.of(CurrencyUnit.EUR, Values.Amount.factorize(0.00))));

Unit grossValueUnit = transaction.getUnit(Unit.Type.GROSS_VALUE).orElseThrow(IllegalArgumentException::new);
assertThat(grossValueUnit.getForex(), is(Money.of(CurrencyUnit.USD, Values.Amount.factorize(1.57))));
}

@Test
public void testDividende03WithSecurityInEUR()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private void addBuySellTransaction_Format01()
return null;
});

addTaxesSectionsTransaction(pdfTransaction, type);
addTaxesSectionsTransactionFormat02(pdfTransaction, type);
addFeesSectionsTransaction(pdfTransaction, type);
}

Expand Down Expand Up @@ -220,7 +220,7 @@ private void addBuySellTransaction_Format02()
return null;
});

addTaxesSectionsTransaction(pdfTransaction, type);
addTaxesSectionsTransactionFormat02(pdfTransaction, type);
addFeesSectionsTransaction(pdfTransaction, type);
}

Expand Down Expand Up @@ -267,13 +267,14 @@ private void addDividendeTransaction_Format01()
t.setAmount(asAmount(v.get("amount")));
})

// Dividenden für 01.01.2009-31.12.2009 Bruttobetrag 163,08 USD 124,50 EUR
// Devisenkurs 1,309900
// Devisenkurs EUR/USD 1,110890
.section("baseCurrency", "termCurrency", "exchangeRate", "fxGross", "fxCurrency", "gross", "currency").optional()
.match("^(Umrechnungskurs|Exchange Rate): (?<baseCurrency>[\\w]{3})\\/(?<termCurrency>[\\w]{3}) (?<exchangeRate>[\\.,\\d]+)$")
.match("^(Bruttobetrag|Gross Amount) (?<fxCurrency>[\\w]{3}) (?<fxGross>[\\.,\\d]+)$")
.match("^(Bruttobetrag|Gross Amount) (?<currency>[\\w]{3}) (?<gross>[\\.,\\d]+)$")
.match("^(Ausmachender Betrag) (?<fxCurrency>[\\w]{3}) (?<fxGross>[\\.,\\d]+)$")
.match("^(Devisenkurs) (?<baseCurrency>[\\w]{3})\\/(?<termCurrency>[\\w]{3}) (?<exchangeRate>[\\.,\\d]+)$")
.match("^Ausmachender Betrag (?<currency>[\\w]{3}) (?<gross>[\\.,\\d]+)$")
.assign((t, v) -> {
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setAmount(asAmount(v.get("gross")));
ExtrExchangeRate rate = asExchangeRate(v);
type.getCurrentContext().putType(rate);

Expand All @@ -294,7 +295,7 @@ private void addDividendeTransaction_Format01()
return null;
});

addTaxesSectionsTransaction(pdfTransaction, type);
addTaxesSectionsTransactionFormat01(pdfTransaction, type);
addFeesSectionsTransaction(pdfTransaction, type);

block.set(pdfTransaction);
Expand Down Expand Up @@ -399,7 +400,7 @@ private void addDividendeTransaction_Format02()
return null;
});

addTaxesSectionsTransaction(pdfTransaction, type);
addTaxesSectionsTransactionFormat02(pdfTransaction, type);
addFeesSectionsTransaction(pdfTransaction, type);

block.set(pdfTransaction);
Expand Down Expand Up @@ -689,7 +690,29 @@ private void addDepotStatementTransaction()
}));
}

private <T extends Transaction<?>> void addTaxesSectionsTransaction(T transaction, DocumentType type)
private <T extends Transaction<?>> void addTaxesSectionsTransactionFormat01(T transaction, DocumentType type)
{
transaction
// Kapitalertragsteuer EUR - 752,05
// Kapitalertragsteuer: EUR -73,71
.section("currency", "tax").optional()
.match("^Kapitalertragsteuer: (?<currency>[\\w]{3}) \\-(?<tax>[\\.,\\d]+)$")
.assign((t, v) -> processTaxEntries(t, v, type))

// Solidaritätszuschlag EUR - 41,36
// Solidaritätszuschlag: EUR -4,05
.section("currency", "tax").optional()
.match("^Solidarit.tszuschlag: (?<currency>[\\w]{3}) \\-(?<tax>[\\.,\\d]+)$")
.assign((t, v) -> processTaxEntries(t, v, type))

// Kirchensteuer EUR - 1,00
// Kirchensteuer EUR: -1,00
.section("currency", "tax").optional()
.match("^Kirchensteuer: (?<currency>[\\w]{3}) \\-(?<tax>[\\.,\\d]+)$")
.assign((t, v) -> processTaxEntries(t, v, type));
}

private <T extends Transaction<?>> void addTaxesSectionsTransactionFormat02(T transaction, DocumentType type)
{
transaction
// Ausl. Quellensteuer -32,62 USD -24,90 EUR
Expand Down