anaf-sync 0.3.0 — the invoices ANAF will never list again
Facturile mai vechi de 60 de zile intră în arhivă cu anaf-sync backfill, iar
anaf-sync init cere de-acum CIF-ul. / A new command for invoices past ANAF's
retention window, one changed command signature, and two archiving fixes.
What's new
anaf-sync backfill <folder> catalogs invoices already on disk. ANAF lists
a message for 60 days and never again, so an operator adopting anaf-sync has
years of invoices the API is structurally incapable of showing it — and an
archive whose database is lost cannot be rebuilt from ANAF either. Both are the
same job: read the ZIPs off disk and catalog what they say. Number, date,
partner, total and currency all reconstruct from the document itself, and the
direction (received or sent) is deduced from the CIFs inside it; invoices
between two other firms are skipped and counted. --dry-run reports what would
be cataloged and writes nothing.
The command only reads: nothing is downloaded, moved or renamed, and files
stay exactly where they are. Two fields exist only in ANAF's listing and cannot
be recovered — the message type and the date the invoice reached SPV — so the
"declared late" check has nothing to stand on for backfilled rows. For the same
reason those rows never suppress a download: an invoice cataloged this way
that is still inside the 60-day window will be fetched from ANAF anyway, under
its real message id. A duplicate costs one file; a false skip loses an invoice
for good.
Point it at the folder in [output] directory to rebuild a lost catalog —
rows already present are left untouched, since a real ANAF id beats anything
inferable from disk. Re-running is safe: the second pass updates the same rows
rather than duplicating them.
Changed — action required
anaf-sync init now takes the CIF as an argument. anaf-sync init on its
own used to write a config carrying a 12345678 placeholder — a config that
cannot sync until it is hand-edited is one you can forget to edit, and the
failure surfaces on the first scheduled run, silently. It is now
anaf-sync init 12345678, repeatable for several firms
(anaf-sync init 12345678 87654321), with the RO prefix optional and
stripped. One CIF writes cif = "...", several write cifs = [...], each with
the other form shown as a hint. A malformed CIF is rejected before anything
touches the filesystem, so a bad run leaves no half-written file.
Scripts and documentation that call bare anaf-sync init need the argument
added. Existing config files are unaffected.
Fixes
Artifact suffixes are appended instead of replacing the last dot-segment.
Path.with_suffix replaces a trailing dot-segment rather than adding one, so a
Romanian legal form arriving as … S.R.L was filed as … S.R.zip — a letter
short. Four of ten invoices in a real archive were affected, and a template
ending in {number} fared worse: FCT.1001 became FCT.zip. Nothing was ever
lost — the database stores the un-mangled base and every reader re-applied the
same operation — but the names on disk were wrong, and two invoices differing
only past the last dot would have collapsed onto one file.
Files written by earlier versions keep their truncated names; new invoices are
filed correctly from now on. Re-running sync --redownload re-files anything
still inside the 60-day window under the corrected name.
A message where no artifact could be written is now a failure, not a silent
success. Every artifact writer may decline a message, and the engine used to
record the message as archived with an empty artifact list — the run exited 0,
and because archived records are permanent, it was never retried. The default
["zip", "pdf"] hides this, since the ZIP always writes; a pdf-only archive
does not, and ANAF's rendering service answers HTTP 200 with a JSON error
payload instead of PDF bytes when it refuses a document. Past 60 days that
invoice was unrecoverable. It is now reported as a per-message failure naming
the configured artifacts, visible in anaf-sync status and retried on the next
run while the window is still open.
Docs
The README gained a section on what is saved per invoice and why the zip
should stay in artifacts: it is the signed original every other artifact
derives from, and the derivation is one-way. The PDF is what you read; the ZIP
is what you keep.
Internal
- Dependency floor raised to anafpy 0.6.1.
- The tray's private copy of the suffix logic is gone — it now calls the shared
template.artifact_path, so the two can no longer drift.
⚠️ The bundles are unsigned — no macOS notarization, no Windows
Authenticode. First run triggers the usual OS warning; use the
right-click-open workaround documented in the README. The CLI on PyPI
(pip install anaf-sync) is unaffected.
Full changelog: v0.2.4...v0.3.0