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 WIR Bank PDF-Importer to support VIAC Invest transactions #4512

Merged
merged 1 commit into from
Feb 7, 2025
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.
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,29 @@
PDFBox Version: 3.0.3
Portfolio Performance Version: 0.74.1.qualifier
System: win32 | x86_64 | 21.0.5+11-LTS | Eclipse Adoptium
-----------------------------------------
VIAC Invest AG
Strasse 1
1111 Stadt
E-Mail [email protected]
Telefon 0000 00 00 00
www.viac.ch
Vertrag 1.111.111.111
Portfolio 1.111.111.111.11
Herr
Vorname Nachname
Strasse 1
1111 Stadt
Stadt, 09.01.2025
Börsenabrechnung - Zeichnung VIAC Equity North America Sustainable
Wir haben für Sie folgenden Auftrag ausgeführt:
Order: Zeichnung
16.839 Anteile VIAC Equity North America Sustainable
ISIN: CH1336969030
Kurs: CHF 101.53
Betrag CHF 1'709.70
Verrechneter Betrag: Valuta 09.01.2025 CHF 1'709.70
S. E. & O.
Freundliche Grüsse
VIAC Invest AG
Anzeige ohne Unterschrift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
PDFBox Version: 3.0.3
Portfolio Performance Version: 0.74.1.qualifier
System: win32 | x86_64 | 21.0.5+11-LTS | Eclipse Adoptium
-----------------------------------------
VIAC Invest AG
Strasse 1
1111 Stadt
E-Mail [email protected]
Telefon 0000 00 00 00
www.viac.ch
Vertrag 1.111.111.111
Portfolio 1.111.111.111.11
Herr
Vorname Nachname
Strasse 1
1111 Stadt
Stadt, 16.01.2025
Börsenabrechnung - Rücknahme VIAC Equity North America Sustainable
Wir haben für Sie folgenden Auftrag ausgeführt:
Order: Rücknahme
0.181 Anteile VIAC Equity North America Sustainable
ISIN: CH1336969030
Kurs: CHF 99.82
Betrag CHF 18.10
Verrechneter Betrag: Valuta 16.01.2025 CHF 18.10
S. E. & O.
Freundliche Grüsse
VIAC Invest AG
Anzeige ohne Unterschrift
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,52 @@ public void testWertpapierKauf11WithSecurityInCHF()
}))));
}

@Test
public void testWertpapierKauf12()
{
Client client = new Client();

WirBankPDFExtractor extractor = new WirBankPDFExtractor(client);

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

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

assertThat(errors, empty());
assertThat(results.size(), is(2));
new AssertImportActions().check(results, "CHF");

// check security
Security security = results.stream().filter(SecurityItem.class::isInstance).findFirst()
.orElseThrow(IllegalArgumentException::new).getSecurity();
assertThat(security.getIsin(), is("CH1336969030"));
assertNull(security.getWkn());
assertNull(security.getTickerSymbol());
assertThat(security.getName(), is("VIAC Equity North America Sustainable"));
assertThat(security.getCurrencyCode(), is("CHF"));

// 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("2025-01-09T00:00")));
assertThat(entry.getPortfolioTransaction().getShares(), is(Values.Share.factorize(16.839)));
assertThat(entry.getSource(), is("Kauf12_ViacInvest.txt"));
assertNull(entry.getNote());

assertThat(entry.getPortfolioTransaction().getMonetaryAmount(),
is(Money.of("CHF", Values.Amount.factorize(1709.70))));
assertThat(entry.getPortfolioTransaction().getGrossValue(),
is(Money.of("CHF", Values.Amount.factorize(1709.70))));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.TAX),
is(Money.of("CHF", Values.Amount.factorize(0.00))));
assertThat(entry.getPortfolioTransaction().getUnitSum(Unit.Type.FEE),
is(Money.of("CHF", Values.Amount.factorize(0.00))));
}

@Test
public void testInterest01()
{
Expand Down Expand Up @@ -1983,6 +2029,36 @@ public void testWertpapierVerkauf04()
hasTaxes("CHF", 0.00), hasFees("CHF", 0.00))));
}

@Test
public void testWertpapierVerkauf05()
{
WirBankPDFExtractor extractor = new WirBankPDFExtractor(new Client());

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

List<Item> results = extractor.extract(PDFInputFile.loadTestCase(getClass(), "Verkauf05_ViacInvest.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, "CHF");

// check security
assertThat(results, hasItem(security( //
hasIsin("CH1336969030"), hasWkn(null), hasTicker(null), //
hasName("VIAC Equity North America Sustainable"), //
hasCurrencyCode("CHF"))));

// check buy sell transaction
assertThat(results, hasItem(sale( //
hasDate("2025-01-16T00:00"), hasShares(0.181), //
hasSource("Verkauf05_ViacInvest.txt"), hasNote(null), //
hasAmount("CHF", 18.10), hasGrossValue("CHF", 18.10), //
hasTaxes("CHF", 0.00), hasFees("CHF", 0.00))));
}

@Test
public void testWertpapierVerkauf04WithSecurityInCHF()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public WirBankPDFExtractor(Client client)

addBankIdentifier("WIR Bank");
addBankIdentifier("Banque WIR");
addBankIdentifier("VIAC Invest AG");

addDepositTransaction();
addBuySellTransaction();
Expand Down Expand Up @@ -86,13 +87,13 @@ private void addDepositTransaction()
private void addBuySellTransaction()
{
DocumentType type = new DocumentType("(B.rsenabrechnung|Exchange Settlement|Op.ration de bourse) " //
+ "\\- (Kauf|Verkauf|Buy|Sell|Achat|Vente)");
+ "\\- (Kauf|Zeichnung|Verkauf|R.cknahme|Buy|Sell|Achat|Vente)");
this.addDocumentTyp(type);

Transaction<BuySellEntry> pdfTransaction = new Transaction<>();

Block firstRelevantLine = new Block("^(B.rsenabrechnung|Exchange Settlement|Op.ration de bourse) " //
+ "\\- (Kauf|Verkauf|Buy|Sell|Achat|Vente).*$");
+ "\\- (Kauf|Zeichnung|Verkauf|R.cknahme|Buy|Sell|Achat|Vente).*$");
type.addBlock(firstRelevantLine);
firstRelevantLine.set(pdfTransaction);

Expand All @@ -107,9 +108,10 @@ private void addBuySellTransaction()
// Is type --> "Verkauf" change from BUY to SELL
.section("type").optional() //
.match("^(B.rsenabrechnung|Exchange Settlement|Op.ration de bourse) " //
+ "\\- (?<type>(Kauf|Verkauf|Buy|Sell|Achat|Vente)).*$") //
+ "\\- (?<type>(Kauf|Zeichnung|Verkauf|R.cknahme|Buy|Sell|Achat|Vente)).*$") //
.assign((t, v) -> {
if ("Verkauf".equals(v.get("type")) //
|| "Rücknahme".equals(v.get("type")) //
|| "Sell".equals(v.get("type")) //
|| "Vente".equals(v.get("type")))
t.setType(PortfolioTransaction.Type.SELL);
Expand All @@ -122,7 +124,7 @@ private void addBuySellTransaction()
// Kurs: USD 262.51
// @formatter:on
.section("isin", "name", "currency") //
.find("(Order|Ordre): (Kauf|Verkauf|Buy|Sell|Achat|Vente)") //
.find("(Order|Ordre): (Kauf|Zeichnung|Verkauf|R.cknahme|Buy|Sell|Achat|Vente)") //
.match("^[\\.,\\d]+ (Anteile|Qty|Ant|units|Qt.|Quantit.|parts|actions)?(?<name>.*)$") //
.match("^ISIN: (?<isin>[A-Z]{2}[A-Z0-9]{9}[0-9])$") //
.match("^(Kurs|Price|Cours): (?<currency>[\\w]{3}) .*$") //
Expand All @@ -133,7 +135,7 @@ private void addBuySellTransaction()
// 0.027 units Swisscanto Pacific ex Japan
// @formatter:on
.section("shares") //
.find("(Order|Ordre): (Kauf|Verkauf|Buy|Sell|Achat|Vente)") //
.find("(Order|Ordre): (Kauf|Zeichnung|Verkauf|R.cknahme|Buy|Sell|Achat|Vente)") //
.match("^(?<shares>[\\.,\\d]+) (Anteile|Qty|Ant|units|Qt.|Quantit.|parts|actions)?(?<name>.*)$") //
.assign((t, v) -> t.setShares(asShares(v.get("shares"))))

Expand All @@ -148,7 +150,7 @@ private void addBuySellTransaction()
// Verrechneter Betrag: Valuta 05.07.2018 CHF 360.43
// @formatter:on
.section("amount", "currency") //
.match("^(Verrechneter Betrag: Valuta|Charged amount: Value date|Montant comptabilis.: Valeur) .* (?<currency>[\\w]{3}) (?<amount>[\\.,'\\d]+)$") //
.match("^(Verrechneter Betrag: Valuta|Charged amount: Value date|Montant comptabilis.: Valeur) .* (?<currency>[\\w]{3}) (?<amount>[\\.,'\\d]+).*$") //
.assign((t, v) -> {
t.setAmount(asAmount(v.get("amount")));
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
Expand Down