anaf-sync 0.6.0 — facturile `unknown` se pot repara acum
Versiunea aceasta a ajuns pe PyPI, dar nu a primit niciodată o pagină de
release și nici programe descărcabile: pasul care le construiește a picat pe
Windows, după publicare — a doua oară după 0.5.0, din alt motiv. Pagina de față
e scrisă retroactiv, ca tag-ul să nu rămână fără una. Versiunea de folosit
este 0.6.1,
care aduce tot ce e mai jos plus o remediere pentru aplicația de pe Windows.
Fișierele atașate sunt doar pachetele Python, identice cu cele publicate pe
PyPI. Programele descărcabile pentru desktop nu au existat niciodată pentru
versiunea aceasta; sunt în 0.6.1.
O factură arhivată cu câmpurile goale nu mai rămâne așa pentru totdeauna:
datele se recalculează din ZIP-ul deja salvat, iar factura se poate muta din
folderul unknown pe calea dată de șablon — local, fără autentificare și
fără limita de 60 de zile. În fereastra Facturi, fiecare factură are pentru
asta un buton propriu. /
A new anaf-sync reprocess re-derives an archived message's catalog fields —
and, with --move, its path — from the ZIP already on disk, so a document
anafpy could not read at download time is repairable by a later build,
offline and unconstrained by ANAF's window. The Facturi window offers the
same repair per invoice.
Îmbunătățiri
Facturile care apar cu unknown se pot repara. Se poate întâmpla ca
descărcarea să reușească, dar citirea XML-ului să nu: ANAF acceptă un document
pe care versiunea instalată de anafpy nu îl poate încă interpreta. Factura
se arhivează oricum — ZIP-ul semnat e scopul — dar tot ce se deduce din XML se
prăbușește în unknown: numărul, data, partenerul și valoarea din fereastra
Facturi, plus calea pe disc, care devine un folder unknown.
Până acum nu exista cale de întoarcere. Evidența nu revizitează niciodată un
mesaj deja arhivat — regula care garantează că nimic nu se descarcă de două
ori — iar după 60 de zile nici măcar sync --redownload nu mai ajunge la el.
Rândul rămânea greșit definitiv, oricât de mult ar fi învățat anafpy între
timp să citească.
Dovada nu s-a pierdut însă niciodată: XML-ul facturii stă permanent în ZIP-ul
arhivat. Exact pe asta se bazează și repararea PDF-urilor din 0.5.1, doar că
acum se aplică datelor și căii, nu randării:
anaf-sync reprocess --dry-run # arată ce s-ar corecta
anaf-sync reprocess # recitește ZIP-urile și corectează catalogul
anaf-sync reprocess --move --dry-run # și unde s-ar muta fișierele
anaf-sync reprocess --move # le mută pe calea dată de șablonFără --move se schimbă doar ce se vede în aplicație; fișierele rămân exact
unde sunt. Cu --move se recalculează și calea din șablon, se mută acolo toate
fișierele facturii și se șterge folderul unknown rămas gol. Dacă o factură
tot nu poate fi citită, comanda o numără separat, pe unreadable: atunci
merită raportată, iar o versiune mai nouă de anafpy plus încă o rulare a
aceleiași comenzi rezolvă restul.
Comanda nu cere autentificare și nu atinge rețeaua deloc, deci o arhivă veche
de ani se repară la fel de bine ca una de azi.
Un buton pentru fiecare factură, în fereastra Facturi. Panoul din dreapta
are acum „Recitește din arhivă” — aceeași operație, pentru o singură
factură. Pe rândurile cărora le lipsesc toate datele apare evidențiat, sub o
explicație a motivului: descărcarea a reușit, doar citirea nu, iar originalul
semnat e intact pe disc. Pe celelalte rânduri rămâne discret, ca să poți
re-așeza o factură după ce schimbi șablonul, fără să reorganizezi toată arhiva.
Facturile catalogate cu backfill au butonul dezactivat, cu motivul în tooltip:
sunt foldere pe care anaf-sync nu le administrează, așa că nu le rescrie
fișierele.
reprocess --move e și modul corect de a reorganiza arhiva după ce schimbi
template. Rearanjează local fișierele deja descărcate, spre deosebire de
sync --redownload, care poate aduce din nou doar ce se mai află în fereastra
de 60 de zile. Rulează întâi cu --dry-run, ca să vezi câte fișiere s-ar muta.
Internal
- What a re-projection may not invent.
message_typeandcreated_at
(data_creare, which the delay flag reads) come only from ANAF's listing,
which is long gone by the time anything is reprocessed — so the stored row
keeps them, along withcif,direction,saved_atand the message id.
Re-deriving them asNonewould silently turn "unknown delay" into "on
time".context.project_archivedis the third door onto the module's single
parse, carrying exactly those facts back in. request_idrefuses the move. It is the one path variable with no home
in any artifact, so a template referencing it errors up front rather than
renderingunknownover paths that already hold the real value. The catalog
refresh has no such dependency and still runs.- Moves are planned before they are applied. An occupied destination
refuses that message (its catalog is still refreshed); a destination whose
source is gone is recognised as a move a previous run already made; and the
file the pass re-read the message from moves last, so an interrupted run
resumes. Files land before the row does — a crash between them leaves a
stale pointer with every byte intact, where the reverse would point the row
at files that never arrived. SyncRunneris nowCliRunner, with one in-flight guard across every
subcommand the tray spawns. Two tray-spawned children would meet at the sync
lock and the second would die on it, so the UI does not offer the second
click.ARTIFACT_SUFFIXESmoves toconfig, shared bybackfilland
reprocessinstead of copied.
⚠️ Verificare. Comanda are teste peste facturi UBL reale (recitire,
mutare, mutare întreruptă și reluată, destinație ocupată, arhive fără ZIP) și
a fost rulată cap-coadă pe o arhivă de probă: factura a ieșit dinunknown,
folderul gol a dispărut, catalogul s-a completat și a doua rulare nu a mai
avut ce face. Nu a fost însă rulată pe o arhivă reală de producție — dacă
--movese poartă altfel pe un volum de sute de facturi, spune. Rulează
întâi--dry-run, și ai oricând ZIP-urile semnate ca sursă de adevăr.
⚠️ 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.5.1...v0.6.0