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>
6.4 KiB
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:
- Total identic (
TOTAL_CU_TVA≈order_total, toleranta 0.01 lei), apoi - acelasi partener (
ID_PART=id_partener) SAU - 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:07–10:25; 12 facturi manuale TIP=1 (IDV 138191–138203 → comenzi 5419–5430)
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.