Name NLB uploads, delete statements, and stop importing on upload
Four changes to statement handling in the web app, made together and touching the same upload and statements-list code. Name NLB uploads by statement date. parser.Namer is an optional interface, like Warner, through which a parser names its statements; nlb reads the "Datum izpiska" from the izpisek header and names it izpisek_YYYY_MM_DD, lowercase, extension included -- ported from the rename_izpiski.py it replaces. Uploads are staged as dotfiles, invisible to import, so the parser can read them; two downloads of one statement then meet under one name and the second is recognised as already there, while a different statement of the same date is numbered _2 as the script did. Only uploads are named: source_files records statements by path, so renaming a file already in a folder would orphan its rows. Delete a statement from the statements list. The file is removed from disk for good -- the page says so before it asks -- and store.ForgetSourceFile drops its transactions and their transfer rows. A row two overlapping statements share is stored once, under the file imported first, so it goes too; the account's other statements forget their checksums and show as changed until the next Import re-reads them and restores it. A file already gone from disk can be forgotten. Upload and delete no longer import. Importing stays the user's call, made with the Import button, so a batch can be put together and looked over first. Delete still re-pairs transfers, which reads no statement. Show rows and new rows per statement. The list read "0" for a file whose rows an earlier, overlapping statement already held, which looked like a file that failed to parse. source_files now records how many transactions each statement holds, and the list reads "3 rows · 0 new". This adds a column the code reads, so an index built by an earlier version fails with "no such column: s.rows": delete index.db and import again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,8 +102,7 @@ money config # which data root is in use, and why
|
||||
|
||||
An account folder appears in the app only once its statements have been
|
||||
imported — creating an `account.toml` is not enough on its own. Run
|
||||
`money import` (or press Import in the web app) after adding one, or add its
|
||||
first statements from the Accounts screen, which imports them as it saves them.
|
||||
`money import` (or press Import in the web app) after adding one.
|
||||
|
||||
`--uniq` turns `ls` into a list of patterns still to write rather than a list of
|
||||
rows to read: one line per distinct description, since fifty visits to the same
|
||||
@@ -178,21 +177,35 @@ folder, with what the index made of it:
|
||||
| `•` not imported | new since the last import — or an import tried and failed, in which case the error is in the import report |
|
||||
| `✗` gone from disk | imported once, then removed; its transactions stay in the index only until it is rebuilt |
|
||||
|
||||
**Added** is how many transactions the file brought in. Statements that overlap
|
||||
share rows, and a shared row counts towards whichever file was imported first,
|
||||
so a later statement covering the same days can add fewer rows than it holds.
|
||||
**Transactions** reads like `3 rows · 0 new`: how many transactions the file
|
||||
holds, then how many of them it was the first to bring in. Statements that
|
||||
overlap share rows, and a shared row is stored once, under whichever file was
|
||||
imported first — so a later statement covering the same days shows fewer new
|
||||
rows than it holds, down to `0 new` when an earlier one already had them all.
|
||||
That is deduplication working, not a file that failed to parse.
|
||||
|
||||
Click a file name to open it. PDFs and CSVs open in the browser; anything else
|
||||
downloads. Only files import would read are listed or served — not
|
||||
`account.toml`, dotfiles, or anything outside an account's `include` patterns.
|
||||
|
||||
**Delete** removes a statement from disk for good — there is no copy kept
|
||||
and no undo, so keep the bank's original if you might want it back. Its
|
||||
transactions leave the index, and transfers that used them lose their pairing:
|
||||
the other leg shows as unpaired, which is the truth once one side is gone.
|
||||
Deleting does not import. A row that an overlapping statement also contains goes
|
||||
too, for now: the account's other statements are marked *changed*, and the next
|
||||
**Import** re-reads them and puts it back. For a file already gone from disk the
|
||||
button says **Forget** and only clears the index.
|
||||
|
||||
### Adding statements from the browser
|
||||
|
||||
The Accounts screen (`1`) has an **Add statements** panel: pick the account,
|
||||
drop files on it (or click to choose them) and press **Upload and import**. The
|
||||
files are saved into that account's folder, exactly where you would have copied
|
||||
them by hand, and then imported — the folder stays the source of truth, so
|
||||
deleting `index.db` and re-importing still gets everything back.
|
||||
drop files on it (or click to choose them) and press **Upload**. The files are
|
||||
saved into that account's folder, exactly where you would have copied them by
|
||||
hand — the folder stays the source of truth, so deleting `index.db` and
|
||||
re-importing still gets everything back. Uploading does not import: the files
|
||||
wait on the statements list as *not imported* until you press **Import**, so you
|
||||
can put a batch together and look it over first.
|
||||
|
||||
An upload never replaces a statement. A file whose name is already in the folder
|
||||
is skipped if its contents are identical and refused if they differ; rename it
|
||||
@@ -202,6 +215,16 @@ too, and a batch with one bad file writes none of them. The folder itself must
|
||||
already exist with an `account.toml`: an upload adds statements to an account,
|
||||
it does not create one.
|
||||
|
||||
Some banks name their downloads unhelpfully, so a parser may name the statement
|
||||
instead. An NLB izpisek is saved as `izpisek_YYYY_MM_DD.pdf` after the *Datum
|
||||
izpiska* in its header — lowercase throughout, extension included — so the
|
||||
folder sorts by date and the status line says what each file became. Downloading
|
||||
the same statement twice then lands on the same name and is recognised as
|
||||
already there; a different statement with the same date (a reissue) is numbered
|
||||
`_2`, `_3` rather than refused. A statement with no date it can find keeps its
|
||||
own name. Only uploads are named — files already in a folder are never renamed,
|
||||
since the index records them by path.
|
||||
|
||||
### Keys
|
||||
|
||||
| Key | Action |
|
||||
@@ -654,7 +677,7 @@ nothing else to configure — `parser` names one of these and that is all.
|
||||
|
||||
| `parser` | Statement | Notes |
|
||||
| --- | --- | --- |
|
||||
| `nlb` | NLB izpisek PDF | Wrapped descriptions are folded in from continuation lines, and the IBAN column is appended to the description. |
|
||||
| `nlb` | NLB izpisek PDF | Wrapped descriptions are folded in from continuation lines, and the IBAN column is appended to the description. Uploads are saved as `izpisek_YYYY_MM_DD.pdf` after the statement date. |
|
||||
| `traderepublic` | Trade Republic PDF | Handles both the single-line and the stacked layout by measuring column positions. |
|
||||
| `revolut` | `account-statement*.csv` | Skips non-COMPLETED rows, folds the fee into the amount. |
|
||||
|
||||
|
||||
Reference in New Issue
Block a user