Files
gomag-vending/docs/relink-facturi-manuale.md
Claude Agent ccc6a933fa feat(scripts): line-level residual check in relink_manual_invoices
Linking the VANZARI header (ID_COMANDA) makes the app dashboard show an
order facturat, but ROA decides facturat at the LINE level
(PACK_FACTURARE.cursor_comanda matches invoiced qty on ID_ARTICOL + exact
PRET). When a manual invoice represented lines differently than the order
(e.g. per-VAT-rate discounts consolidated into one 0%-TVA line), the order
stays nefacturat in ROA despite the header link.

Add order_line_residual(): predicts the residual before --apply (via
extra_idv) and re-verifies after linking. Warns in the plan, the summary
counter, and post-apply when an order will still show nefacturat. The
script never touches COMENZI_ELEMENTE — those need a manual line fix.

Surfaced by orders 5419/5423 (web 492710430/492710513) on 2026-06-26.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 09:46:59 +00:00

6.4 KiB
Raw Permalink Blame History

Reconciliere facturi manuale ROA ↔ comenzi GoMag

Script: scripts/relink_manual_invoices.py Launcher Windows: scripts/relink_manual_invoices.bat

Cand se foloseste

Cand Oracle pool / sync-ul a fost cazut (ex. dupa o pana de curent la VENDING) si operatorul a emis facturi manual direct in ROA in acel interval. Dupa ce aplicatia revine, importeaza aceleasi comenzi web in COMENZI, dar factura manuala nu se leaga de comanda → comanda ramane nefacturata in ROA si in dashboard, desi factura exista.

Semnal: in dashboard apar comenzi „nefacturate" pentru clienti care au fost de fapt facturati, iar in VANZARI exista facturi cu ID_COMANDA IS NULL.

Cauza tehnica

Flux VANZARI.ID_COMANDA COMENZI.COMANDA_EXTERNA
Normal (app) setat (leaga factura de comanda) nr comanda GoMag
Manual (operator, in downtime) NULL

Dashboard-ul / cache-ul SQLite marcheaza o comanda „Facturat" doar daca exista VANZARI ... WHERE id_comanda = <comanda> AND sters = 0 (vezi invoice_service.check_invoices_for_orders). Factura manuala cu ID_COMANDA NULL nu e niciodata gasita → comanda apare nefacturata.

ID_FACT (documentul fiscal) si COMENZI.COMANDA_EXTERNA sunt deja completate; singura piesa lipsa e legatura VANZARI → COMANDA.

⚠️ Facturi de depozit (walk-in) — NU se ating

Operatorul emite zilnic si facturi manuale legitime din depozit (~20+/zi), fara nicio comanda online in spate. Acestea au tot ID_COMANDA NULL, dar nu trebuie legate de nimic. De aceea matching-ul e conservator: orice nu e o potrivire 1:1 sigura e raportat, niciodata legat automat.

Cum potriveste

Pentru fiecare factura orfana (VANZARI.ID_COMANDA NULL, sters=0, in fereastra --days) cauta o comanda GoMag nefacturata (in SQLite, cu id_comanda setat) cu:

  1. Total identic (TOTAL_CU_TVAorder_total, toleranta 0.01 lei), apoi
  2. acelasi partener (ID_PART = id_partener) SAU
  3. nume potrivit (token-overlap, tolereaza SRL/SC si ordinea cuvintelor) — acopera cazul in care operatorul a creat un partener duplicat la facturare.

Verifica si ca acea comanda e activa in ROA (sters=0) si nu are deja factura (anti-dubla-facturare).

Clasificare (in raport)

Eticheta Ce inseamna Actiune
LINK potrivire 1:1 sigura leaga (la --apply)
SKIP_NOMATCH nicio comanda online cu acel total factura de depozit — lasata neatinsa
SKIP_AMBIGUOUS mai multe comenzi plauzibile, sau total potrivit dar partener+nume diferit raportat pentru verificare manuala
SKIP_ALREADY comanda nu mai e activa / are deja factura sarit

La aplicare: UPDATE VANZARI SET ID_COMANDA = <comanda> + populeaza orders.factura_* in SQLite, exact ca aplicatia (update_order_invoice).

⚠ Verificare reziduu de linie (legatura header nu e mereu suficienta)

Aplicatia / dashboard-ul marcheaza o comanda „Facturat" doar dupa legatura header (VANZARI.ID_COMANDA). ROA insa verifica la nivel de linie: in PACK_FACTURARE.cursor_comanda, cantitatea facturata se potriveste cu comanda pe ID_ARTICOL + PRET exact, iar o linie e „de facturat" cand SIGN(CANTITATE) * (CANTITATE NVL(facturat,0)) > 0.

Daca factura manuala a reprezentat liniile altfel decat comanda — tipic discounturi comasate (ex. discounturile pe cote de TVA 11%/21% puse intr-o singura linie la 0% TVA) — preturile nu se mai potrivesc, deci ROA arata comanda tot nefacturata desi headerul e legat si dashboard-ul o vede facturata.

Scriptul prezice acest reziduu inainte de --apply (functia order_line_residual, simuland factura ce urmeaza a fi legata) si il re-verifica dupa legare. Cand exista, afiseaza !! ATENTIE ... cu liniile reziduale (ART / cantitate comanda / pret / facturat) si un contor in rezumat. Scriptul NU atinge COMENZI_ELEMENTE — aceste cazuri se corecteaza manual in ROA (aliniezi liniile comenzii la factura, ex. comasezi liniile de discount ca in factura, pastrand valoarea totala).

Utilizare

Ruleaza pe serverul de productie VENDING (are nevoie de Oracle prod + api/data/import.db prod). Foloseste app.config.settings (deci .env-ul prod).

REM din C:\gomag-vending\scripts
relink_manual_invoices.bat                  REM dry-run, ultimele 3 zile (NU modifica)
relink_manual_invoices.bat --apply          REM aplica, cu confirmare
relink_manual_invoices.bat --apply --yes    REM aplica fara confirmare
relink_manual_invoices.bat --days 7         REM alta fereastra

Dublu-click pe .bat = dry-run. .bat-ul seteaza mediul Oracle thick-mode (TNS_ADMIN + PATH instant client) ca start.bat.

Direct cu Python (echivalent):

set TNS_ADMIN=C:\roa\instantclient_11_2_0_2
set PATH=C:\app\Server\product\18.0.0\dbhomeXE\bin;%PATH%
C:\gomag-vending\venv\Scripts\python.exe scripts\relink_manual_invoices.py --apply

Din containerul de dev, peste SSH:

scp -P 22122 scripts/relink_manual_invoices.* gomag@79.119.86.134:C:/gomag-vending/scripts/
ssh -p 22122 gomag@79.119.86.134 'cmd /c "C:\gomag-vending\scripts\relink_manual_invoices.bat --days 3 < nul"'

Workflow recomandat: intai dry-run → verifica lista LINK si SKIP_AMBIGUOUS → apoi --apply. Cazurile SKIP_AMBIGUOUS se rezolva manual in ROA.

Istoric

Codifica reconcilierea din 2026-06-26 (pana de curent la VENDING): pool cazut ~09:0710:25; 12 facturi manuale TIP=1 (IDV 138191138203 → comenzi 54195430) legate; 3 facturi de depozit corect excluse (CRISS VENDING, COFEE SEVEN TO GO, PANDELE MIOARA); 2 parteneri duplicati semnalati (CERBU, MILITARU).

Follow-up 2026-06-26 (reziduu de linie): 2 din cele 12 comenzi (5419/web 492710430, 5423/web 492710513) au ramas nefacturate in ROA desi headerul era legat — factura manuala comasase cele 2 linii de discount (ART 2077, split pe TVA 11%/21%) intr-una la 0% TVA, deci nu se potriveau pe ID_ARTICOL+PRET. Reparate manual prin alinierea liniilor comenzii la factura (comasare in COMENZI_ELEMENTE, valoare discount pastrata). De aici provine verificarea de reziduu de linie adaugata in script.

Vezi si: oracle-schema-notes.md (tabele COMENZI/VANZARI), sectiunea „Facturi & Cache" din README.