Skip to content

anaf-sync 0.6.0 — facturile `unknown` se pot repara acum

Choose a tag to compare

@robert-malai robert-malai released this 31 Jul 08:34

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 șablon

Fă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_type and created_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 with cif, direction, saved_at and the message id.
    Re-deriving them as None would silently turn "unknown delay" into "on
    time". context.project_archived is the third door onto the module's single
    parse, carrying exactly those facts back in.
  • request_id refuses the move. It is the one path variable with no home
    in any artifact, so a template referencing it errors up front rather than
    rendering unknown over 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.
  • SyncRunner is now CliRunner, 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_SUFFIXES moves to config, shared by backfill and
    reprocess instead 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 din unknown,
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ă
--move se 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