Skip to content

Commit

Permalink
Modify Fidelity International PDF-Importer to support new transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
Nirus2000 authored and buchen committed Dec 30, 2023
1 parent 0de5dfc commit 5ca873f
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,37 @@
@SuppressWarnings("nls")
public class FidelityInternationalPDFExtractorTest
{
@Test
public void testSecurityBuy01()
{
FidelityInternationalPDFExtractor extractor = new FidelityInternationalPDFExtractor(new Client());

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

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

// check security
assertThat(results, hasItem(security( //
hasIsin(null), hasWkn("31620M106"), hasTicker("FIS"), //
hasName("FIDELITY NATL"), //
hasCurrencyCode("USD"))));

// check buy sell transaction
assertThat(results, hasItem(purchase( //
hasDate("2023-12-08T00:00"), hasShares(7.5146), //
hasSource("SecurityBuy01.txt"), //
hasNote("Ref. No. 23342-0D6SVL"), //
hasAmount("USD", 442.83), hasGrossValue("USD", 442.83), //
hasTaxes("USD", 0.00), hasFees("USD", 0.00))));
}

@Test
public void testSecuritySale01()
{
Expand Down Expand Up @@ -69,6 +100,37 @@ public void testSecuritySale01()
hasTaxes("USD", 0.00), hasFees("USD", 0.13))));
}

@Test
public void testSecuritySale02()
{
FidelityInternationalPDFExtractor extractor = new FidelityInternationalPDFExtractor(new Client());

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

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

// check security
assertThat(results, hasItem(security( //
hasIsin(null), hasWkn("31620M106"), hasTicker("FIS"), //
hasName("FIDELITY NATL"), //
hasCurrencyCode("USD"))));

// check buy sell transaction
assertThat(results, hasItem(sale( //
hasDate("2022-07-19T00:00"), hasShares(30), //
hasSource("SecuritySale02.txt"), //
hasNote("Ref. No. 33107-zz91lf"), //
hasAmount("USD", 2887.43), hasGrossValue("USD", 2887.50), //
hasTaxes("USD", 0.00), hasFees("USD", 0.07))));
}

@Test
public void testTradeConfirmation01()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
PDFBox Version: 1.8.17
Portfolio Performance Version: 0.66.2
-----------------------------------------
FIDELITY NATIONAL INFORMATION
SERVICES
PARTICIPANT NO.
U98299884
90035485
NIK HEMMERYCKX
XjlaqpRajgteel 88 FIDELITY STOCK PLAN SERVICES, LLC
ANTWERPEN P.O. BOX 770001
BELGIUM 2000 CINCINNATI, OH 45277-0003
TELEPHONE NUMBER:(800) 544-0275
REF # 23342-0D6SVL
CUSTOMER NO. PARTICIPANT ID. TYPE REG.REP. TRADE DATE SETTLEMENT DATE TRANS NO. CUSIP NO. ORIG.
U98299884 1 000 12-08-23 12-12-23 0D6SVL 31620M106
Confirmation of purchase made through your
FIS ESPP on DEC/08/2023. PURCHASE INFORMATION
Offering period: JAN/01/2023 - DEC/31/2023 Market Value at Purchase¹ $442.83
Accumulated Contributions* $442.83
YOU PURCHASED 7.5146 AT $58.9290 PURCHASE PRICE Gain² $0.00
SECURITY DESCRIPTION SYMBOL: FIS EXPLANATION OF PROCEEDS
FIDELITY NATL
The shares you have acquired are subject to a "Restriction Period" in accordance with Total Gain $0.00
your company's stock plan rules. Please see your plan documents for more
information. Provided below are the dates for when the restriction on these shares will
be removed. Share Proceeds** 7.5146
Sale Availability: 06/05/2024
Transfer Availability: 06/05/2024
PLEASE RETAIN THIS STATEMENT FOR YOUR RECORDS
* Accumulated Contributions are the amount of money contributed to your Plan that is
used toward the purchase of company stock.
** Shares will be held by Fidelity Stock Plan Services on your behalf in the SPS
Participant Trust.
¹ Market Value is determined under your Plan rules.
² Please consult your tax advisor regarding tax treatment in your jurisdiction.
PAGE 1 OF 1 Recordkeeping and administrative services for your company's equity compensation plans are
provided by your company and its service providers.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
PDFBox Version: 1.8.17
Portfolio Performance Version: 0.66.2
-----------------------------------------
PARTICIPANT NO.
U98299884
90017770
NIK HEMMERYCKX
flBJHBJAntgwOx 84
ANTWERPEN
BELGIUM 2000 FIDELITY STOCK PLAN SERVICES, LLC
P.O. BOX 770001
CINCINNATI, OH 45277-0003
TELEPHONE NUMBER:(800) 544-0275
REF # 33107-zz91lf
CUSTOMER NO. PARTICIPANT ID. TYPE REG.REP. TRADE DATE SETTLEMENT DATE TRANS NO. CUSIP NO. ORIG.
U98299884 1 WI# 07-19-22 07-21-22 KS51HX 31620M106
YOU SOLD 30 AT 96.2500
EXPLANATION OF PROCEEDS
SECURITY DESCRIPTION SYMBOL: FIS Sale Proceeds $2,887.50
FIDELITY NATL
DETAILS: Total Fees $0.07
Sale Date: JUL/19/2022
Proceeds Available: JUL/21/2022
Plan Type: COMPANY STOCK PLAN
Net Cash Proceeds¹ -$2,887.43
PLEASE RETAIN THIS STATEMENT FOR YOUR RECORDS
¹ Your proceeds will be held by Fidelity in your trust. Please contact Fidelity Stock Plan Services to request a distribution.
PAGE 1 OF 1 Recordkeeping and administrative services for your company's equity compensation plans are
provided by your company and its service providers.
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public String getLabel()

private void addBuySellTransaction()
{
DocumentType type = new DocumentType("YOU SOLD");
DocumentType type = new DocumentType("YOU (PURCHASED|SOLD)");
this.addDocumentTyp(type);

Transaction<BuySellEntry> pdfTransaction = new Transaction<>();
Expand All @@ -62,52 +62,91 @@ private void addBuySellTransaction()

// Is type --> "SOLD" change from BUY to SELL
.section("type").optional() //
.match("^YOU (?<type>SOLD) [\\.,\\d]+.*$") //
.match("^YOU (?<type>(PURCHASED|SOLD)) [\\.,\\d]+.*$") //
.assign((t, v) -> {
if ("SOLD".equals(v.get("type")))
t.setType(PortfolioTransaction.Type.SELL);
})

// @formatter:off
// I00123456 1 WI# 12-12-23 12-14-23 K9T1Q9 11135F101
// SECURITY DESCRIPTION SYMBOL: AAPL Sale Proceeds $2,423.54
// APPLE INC
// @formatter:off
.section("wkn", "tickerSymbol", "currency", "name") //
.match("^.* [\\d]{2}\\-[\\d]{2}\\-[\\d]{2} [\\d]{2}\\-[\\d]{2}\\-[\\d]{2} [\\w]+ (?<wkn>[A-Z0-9]+)$") //
.match("^SECURITY DESCRIPTION SYMBOL: (?<tickerSymbol>[A-Z]{2,}) .* (?<currency>\\p{Sc})[\\.,\\d]+$") //
.match("^(?<name>.*)$") //
.assign((t, v) -> t.setSecurity(getOrCreateSecurity(v)))
.oneOf( //
// @formatter:off
// U98299884 1 000 12-08-23 12-12-23 0D6SVL 31620M106
// YOU PURCHASED 7.5146 AT $58.9290 PURCHASE PRICE Gain² $0.00
// SECURITY DESCRIPTION SYMBOL: FIS EXPLANATION OF PROCEEDS
// FIDELITY NATL
// @formatter:on
section -> section //
.attributes("wkn", "tickerSymbol", "currency", "name") //
.match("^.* [\\d]{2}\\-[\\d]{2}\\-[\\d]{2} [\\d]{2}\\-[\\d]{2}\\-[\\d]{2} [\\w]+ (?<wkn>[A-Z0-9]+)$") //
.match("^YOU PURCHASED [\\.,\\d]+ AT (?<currency>\\p{Sc})[\\.,\\d]+.*$") //
.match("^SECURITY DESCRIPTION SYMBOL: (?<tickerSymbol>[A-Z]{2,}) .*$") //
.match("^(?<name>.*)$") //
.assign((t, v) -> t.setSecurity(getOrCreateSecurity(v))),
// @formatter:off
// I00123456 1 WI# 12-12-23 12-14-23 K9T1Q9 11135F101
// YOU SOLD 14 AT 173.1100
// SECURITY DESCRIPTION SYMBOL: AAPL Sale Proceeds $2,423.54
// APPLE INC
// @formatter:on
section -> section //
.attributes("wkn", "tickerSymbol", "currency", "name") //
.match("^.* [\\d]{2}\\-[\\d]{2}\\-[\\d]{2} [\\d]{2}\\-[\\d]{2}\\-[\\d]{2} [\\w]+ (?<wkn>[A-Z0-9]+)$") //
.match("^YOU SOLD [\\.,\\d]+.*$") //
.match("^SECURITY DESCRIPTION SYMBOL: (?<tickerSymbol>[A-Z]{2,}) .* (?<currency>\\p{Sc})[\\.,\\d]+$") //
.match("^(?<name>.*)$") //
.assign((t, v) -> t.setSecurity(getOrCreateSecurity(v))))

// @formatter:off
// Sale Date: DEC/12/2023
// @formatter:on
.section("date") //
.match("^Sale Date: (?<date>[\\w]{3}\\/[\\d]{2}\\/[\\d]{4})$") //
.assign((t, v) -> t.setDate(asDate(v.get("date"))))
.oneOf( //
// @formatter:off
// Sale Date: DEC/12/2023
// @formatter:on
section -> section //
.attributes("date") //
.match("^Sale Date: (?<date>[\\w]{3}\\/[\\d]{2}\\/[\\d]{4})$") //
.assign((t, v) -> t.setDate(asDate(v.get("date")))),
// @formatter:off
// FIS ESPP on DEC/08/2023. PURCHASE INFORMATION
// @formatter:on
section -> section //
.attributes("date") //
.match("^.* (?<date>[\\w]{3}\\/[\\d]{2}\\/[\\d]{4})\\. PURCHASE INFORMATION$") //
.assign((t, v) -> t.setDate(asDate(v.get("date")))))

// @formatter:off
// YOU SOLD 14 AT 173.1100
// YOU PURCHASED 7.5146 AT $58.9290 PURCHASE PRICE Gain² $0.00
// @formatter:on
.section("shares") //
.match("^YOU SOLD (?<shares>[\\.,\\d]+).*$") //
.match("^YOU (PURCHASED|SOLD) (?<shares>[\\.,\\d]+).*$") //
.assign((t, v) -> t.setShares(asShares(v.get("shares"))))

// @formatter:off
// Net Cash Proceeds¹ -$2,423.41
// @formatter:on
.section("currency", "amount") //
.match("^Net Cash Proceeds.* \\-(?<currency>\\p{Sc})(?<amount>[\\.,\\d]+)$") //
.assign((t, v) -> {
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setAmount(asAmount(v.get("amount")));
})
.oneOf( //
// @formatter:off
// Net Cash Proceeds¹ -$2,423.41
// @formatter:on
section -> section //
.attributes("currency", "amount") //
.match("^Net Cash Proceeds.* \\-(?<currency>\\p{Sc})(?<amount>[\\.,\\d]+)$") //
.assign((t, v) -> {
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setAmount(asAmount(v.get("amount")));
}),
// @formatter:off
// Accumulated Contributions* $442.83
// @formatter:on
section -> section //
.attributes("currency", "amount") //
.match("^Accumulated Contributions.* (?<currency>\\p{Sc})(?<amount>[\\.,\\d]+)$") //
.assign((t, v) -> {
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setAmount(asAmount(v.get("amount")));
}))

// @formatter:off
// REF # 23346-K9T1Q9
// @formatter:on
.section("note").optional() //
.match("^REF # (?<note>[A-Z0-9]+\\-[A-Z0-9]+)$") //
.match("^REF # (?<note>[\\w]+\\-[\\w]+)$") //
.assign((t, v) -> t.setNote("Ref. No. " + v.get("note")))

.wrap(BuySellEntryItem::new);
Expand Down Expand Up @@ -227,14 +266,14 @@ private void addSummaryStatementBuySellTransaction()
// 20123-1XXXXX 1* WK# 01-04-21 01-06-21 46428Q109 20123-XXXXX
// @formatter:on
.section("note").optional() //
.match("^(?<note>[A-Z0-9]+\\-[A-Z0-9]+) .*$") //
.match("^(?<note>[\\w]+\\-[\\w]+) .*$") //
.assign((t, v) -> t.setNote("Ref. No. " + v.get("note")))

// @formatter:off
// 20123-1XXXXX 1* WK# 01-04-21 01-06-21 46428Q109 20123-XXXXX
// @formatter:on
.section("note").optional() //
.match("^[A-Z0-9]+\\-[A-Z0-9]+ .* (?<note>[A-Z0-9]+\\-[A-Z0-9]+)$") //
.match("^[\\w]+\\-[\\w]+ .* (?<note>[\\w]+\\-[\\w]+)$") //
.assign((t, v) -> t.setNote(concatenate(t.getNote(), v.get("note"), " | Ord. No. ")))

.wrap(BuySellEntryItem::new);
Expand Down

0 comments on commit 5ca873f

Please sign in to comment.