Skip to content

Commit

Permalink
Enhancement of Arkea Direct Bank pdf import to support more cases (#4534
Browse files Browse the repository at this point in the history
)

 - Allows duplicate ')' at the end of ISIN
 - Quantity and date can be on the same line
 - Get security currency from amount instead of earlier from a data which
   is not always present

Closes #4534
  • Loading branch information
mikaelpeltier committed Feb 22, 2025
1 parent 6b30007 commit e19ba0f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,37 @@ public void testDividende01()
hasTaxes("EUR", 0.00), hasFees("EUR", 0.00))));
}

@Test
public void testDividende02()
{
ArkeaDirectBankPDFExtractor extractor = new ArkeaDirectBankPDFExtractor(new Client());

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

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

assertThat(errors, empty());
assertThat(countSecurities(results), is(1L));
assertThat(countBuySell(results), is(0L));
assertThat(countAccountTransactions(results), is(1L));
assertThat(results.size(), is(2));
new AssertImportActions().check(results, "EUR");

// check security
assertThat(results, hasItem(security( //
hasIsin("FR0010208488"), hasWkn(null), hasTicker(null), //
hasName("ENGIE"), //
hasCurrencyCode("EUR"))));

// check dividends transaction
assertThat(results, hasItem(dividend( //
hasDate("2023-04-28T00:00"), hasShares(100.00), //
hasSource("Dividende02.txt"), //
hasNote(null), //
hasAmount("EUR", 140.00), hasGrossValue("EUR", 140.00), //
hasTaxes("EUR", 0.00), hasFees("EUR", 0.00))));
}

@Test
public void testSteuern01()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
PDFBox Version: 3.0.3 != 1.8.17
Portfolio Performance Version: 0.74.0
System: win32 | x86_64 | 21.0.5+11-LTS | Azul Systems, Inc.
-----------------------------------------
AVIS D'ENCAISSEMENT COUPON M dsGVeLG FRKVnW
Au 3 mai 2023 2 DVr EEUs DUawl eKPcrLWnt
38496 nwvXi DJr CGUWSxu
VOTRE COMPTE PEA N° 974973262593 M TwQPOZG yKeVZN
Objet : Encaissement de coupons
Monsieur,
Nous avons le plaisir de vous informer que nous avons procédé à l'encaissement des coupons suivants pour votre compte :
Date Opération Détail opération Débit Crédit
n ACTION ENGIE (FR0010208488))
28/04/2023 Quantité 100
Prélèvement fiscal 0,00 €
Prélèvements sociaux 0,00 €
Montant Net 140,00 € 140,00 €
Veuillez agréer, Monsieur, l'expression de nos salutations distinguées.
Le Service OST.
Duplicata Internet
Page 1/1
Fortuneo est une marque commerciale d'Arkéa Direct Bank. Arkéa Direct Bank, Société Anonyme à Directoire et Conseil de Surveillance
au capital de 89 198 952 euros. RCS Nanterre 384 288 890. Siège social : Tour Ariane - 5, place de la Pyramide 92088 Paris La Défense.
Courtier en assurance n°ORIAS 07 008 441. Adresse postale : Fortuneo - Service Clients - TSA41707 - 35917 RENNES CEDEX 9.
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ private void addDividendeTransaction()

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

Block firstRelevantLine = new Block("^AVIS D.ENCAISSEMENT COUPON$");
Block firstRelevantLine = new Block("^AVIS D.ENCAISSEMENT COUPON.*$");
type.addBlock(firstRelevantLine);
firstRelevantLine.set(pdfTransaction);

Expand All @@ -127,34 +127,43 @@ private void addDividendeTransaction()
})

// @formatter:off
// Supported patterns are:
// n ACTION ORANGE (FR0000133308)
// Montant unitaire 0,30 €
// n ACTION ENGIE (FR0010208488))
// @formatter:on
.section("name", "isin", "currency") //
.match("^.* ACTION (?<name>.*) \\((?<isin>[A-Z]{2}[A-Z0-9]{9}[0-9])\\)$") //
.match("^Montant unitaire [\\,\\d\\s]+ (?<currency>\\p{Sc})$") //
.assign((t, v) -> t.setSecurity(getOrCreateSecurity(v)))

// @formatter:off
// Quantité 450
// @formatter:on
.section("shares") //
.match("^Quantit. (?<shares>[\\,\\d\\s]+)$") //
.assign((t, v) -> t.setShares(asShares(v.get("shares"))))

// @formatter:off
// 04/12/2023
// @formatter:on
.section("date") //
.match("^(?<date>[\\d]{2}\\/[\\d]{2}\\/[\\d]{4})$") //
.assign((t, v) -> t.setDateTime(asDate(v.get("date"))))

.section("name", "isin") //
.match("^.* ACTION (?<name>.*) \\((?<isin>[A-Z]{2}[A-Z0-9]{9}[0-9])\\)*$") //
.assign((t, v) -> t.setSecurity(getOrCreateSecurity(v))) //
.oneOf( //
// @formatter:off
// 28/04/2023 Quantité 100
// @formatter:on
section -> section.attributes("date", "shares") //
.match("^(?<date>[\\d]{2}\\/[\\d]{2}\\/[\\d]{4}) Quantit. (?<shares>[\\,\\d\\s]+)$") //
.assign((t, v) -> {
t.setShares(asShares(v.get("shares")));
t.setDateTime(asDate(v.get("date")));
}),
// @formatter:off
// Quantité 450
// 04/12/2023
// @formatter:on
section -> section.attributes("date", "shares") //
.match("^Quantit. (?<shares>[\\,\\d\\s]+)$") //
.match("^(?<date>[\\d]{2}\\/[\\d]{2}\\/[\\d]{4})$") //
.assign((t, v) -> {
t.setShares(asShares(v.get("shares")));
t.setDateTime(asDate(v.get("date")));
}))
// @formatter:off
// Supported patterns are:
// Montant Net 135,00 €
// Montant Net 140,00 € 140,00 €
// @formatter:on
.section("amount", "currency") //
.match("^Montant Net (?<amount>[\\,\\d\\s]+) (?<currency>\\p{Sc})$") //
.match("^Montant Net (?<amount>[\\,\\d\\s]+) (?<currency>\\p{Sc}).*$") //
.assign((t, v) -> {
t.getSecurity().setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setAmount(asAmount(v.get("amount")));
})
Expand Down

0 comments on commit e19ba0f

Please sign in to comment.