Skip to content
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
6 changes: 6 additions & 0 deletions .claude/rules/pdfextractors.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ PDF importers extract transactions from bank and broker PDF statements.
- Consistency in coding style between all extractors is more important than nice code.
- Add comment-blocks with `@formatter:off` and `@formatter:on` before each section-block showing the format that is handled there.

## Regular Expressions

Beside general good practices for regular expressions, keep in mind:
* all special characters in the PDF document (`äöüÄÖÜß` as well as e.g. circumflex or similar) should be matched by a `.` (dot) because the PDF to text conversion can create different results
* the special characters `$^{[(|)]}*+?\` in the PDF document are to be escaped

## Conventions

**DocumentType declaration** — always `final`:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasAmount;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasCurrencyCode;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasDate;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasExDate;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasFees;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasForexGrossValue;
import static name.abuchen.portfolio.datatransfer.ExtractorMatchers.hasGrossValue;
Expand Down Expand Up @@ -286,7 +287,7 @@ public void testDividendos01()

// check dividend transaction
assertThat(results, hasItem(dividend( //
hasDate("2025-05-28T00:00"), hasShares(33.00), //
hasDate("2025-05-28T00:00"), hasExDate(null), hasShares(33.00), //
hasSource("Dividendos01.txt"), //
hasAmount("EUR", 3.57), hasGrossValue("EUR", 7.83), //
hasTaxes("EUR", 2.44), hasFees("EUR", 1.82))));
Expand Down Expand Up @@ -319,7 +320,7 @@ public void testDividendos02()

// check dividend transaction
assertThat(results, hasItem(dividend( //
hasDate("2025-06-16T00:00"), hasShares(6.00), //
hasDate("2025-06-16T00:00"), hasExDate(null), hasShares(6.00), //
hasSource("Dividendos02.txt"), //
hasAmount("EUR", 0.00), hasGrossValue("EUR", 1.08), //
hasForexGrossValue("USD", 1.26), //
Expand Down Expand Up @@ -353,7 +354,7 @@ public void testDividende02WithSecurityInEUR()

// check dividends transaction
assertThat(results, hasItem(dividend( //
hasDate("2025-06-16T00:00"), hasShares(6.00), //
hasDate("2025-06-16T00:00"), hasExDate(null), hasShares(6.00), //
hasSource("Dividendos02.txt"), //
hasAmount("EUR", 0.00), hasGrossValue("EUR", 1.08), //
hasTaxes("EUR", 0.33), hasFees("EUR", 0.75), //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private void addBuySellTransaction_Format01()
// @formatter:on
.section("fxGross", "termCurrency", "baseCurrency", "exchangeRate") //
.match("^Cambio divisa (?<exchangeRate>[\\.,\\d]+) (?<termCurrency>[A-Z]{3})\\/(?<baseCurrency>[A-Z]{3})$") //
.match("^S/títulos [A-Z]{3}[\\s]{1,}[\\d]+[\\s]{1,}[\\.,\\d]+[\\s]{1,}(\\-)?(?<fxGross>[\\.,\\d]+)$") //
.match("^S\\/t.tulos [A-Z]{3}[\\s]{1,}[\\d]+[\\s]{1,}[\\.,\\d]+[\\s]{1,}(\\-)?(?<fxGross>[\\.,\\d]+)$") //
.assign((t, v) -> {
var rate = asExchangeRate(v);
type.getCurrentContext().putType(rate);
Expand All @@ -142,8 +142,7 @@ private void addBuySellTransaction_Format02()

var pdfTransaction = new Transaction<BuySellEntry>();

var firstRelevantLine = new Block(
"^CARTA DE AVISO POR OPERACIONES DE FONDOS (SUSCRIPCI.N|REEMBOLSO) EN EFECTIVO$");
var firstRelevantLine = new Block("^CARTA DE AVISO POR OPERACIONES DE FONDOS (SUSCRIPCI.N|REEMBOLSO) EN EFECTIVO$");
type.addBlock(firstRelevantLine);
firstRelevantLine.set(pdfTransaction);

Expand Down Expand Up @@ -191,7 +190,7 @@ private void addBuySellTransaction_Format02()
// @formatter:on
.section("amount", "currency") //
.find("CONCEPTO DIVISA PRECIO IMPORTE") //
.match("^(SUSCRIPCIÓN|REEMBOLSO) EFECTIVO (?<currency>[A-Z]{3}) [\\.,\\d]+ (?<amount>[\\.,\\d]+)$") //
.match("^(SUSCRIPCI.N|REEMBOLSO) EFECTIVO (?<currency>[A-Z]{3}) [\\.,\\d]+ (?<amount>[\\.,\\d]+)$") //
.assign((t, v) -> {
t.setCurrencyCode(asCurrencyCode(v.get("currency")));
t.setAmount(asAmount(v.get("amount")));
Expand Down
Loading