Files
comun/docs/cercetare/rec_consumatori_vanzari.md
Marius Mutu 09ddeabb1c docs: cercetarile trans-proiect din ROAFACTURARE trec in COMUN
Paisprezece rapoarte care nu erau ale ROAFACTURARE traiau in docs\cercetare\ al
acelui proiect: valuta si curs in ofacturare, TVA calculat vs salvat plus
denormalizarea VANZARI, inventarul consumatorilor VANZARI din toata suita ROA,
integrarile de contracte/politici/nomenclator (#10, #11, #12), watchdog-ul VFP
de testare, proiectarea Oracle a scrierii din S5 si view-ul VVANZARI_ARTICOLE.

Motivul mutarii, nu doar al pastrarii: planurile #10, #11 si #12 sunt amanate,
iar indexul lor spune explicit ca se reiau din aceste rapoarte - deci sunt punct
de plecare, nu istoric. Iar tinta lor e COMUN plus ROAPRETURI/ROACONTRACTE.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-11 22:31:53 +03:00

15 KiB

Inventar consumatori VANZARI.AVIZE/CURS/ID_VALUTA/MULTIPLICATOR in suita ROA

Cercetare STRICT de citire (fara modificari de cod, fara DDL, fara conexiuni DB, fara rulare de conversii noi vcx2txt.ps1/git_sync.ps1) — masoara riscul de comportament schimbat dupa corectiile S4 (AVIZE, WHERE lipsa) si S8/curs (garda nin_valuta) aplicate in PACK_FACTURARE (vezi rec_s4_aplicare.md). Executata cu 3 subagenti in paralel: (a) ROAFACTURARE+COMUN, (b) cele 8 produse cu cache text deja generat, (c) restul suitei (~56 directoare).

RISC REAL

1. Referinta la aviz dispare de pe factura retiparita (tip=4). COMUN\programe\oproceduri_facturare.prg (listeaza_formular, ~:1125/:1189/:1265) si dublura ei COMUN\clase\ofacturare_comun.vc2 (frm_facturi.do_listeaza_formular, ~:4103/:4204) — cod partajat, prezent in tot ecosistemul ROA*. Construiesc crsFacturaListare din FACT_VFACTURI2 (coloana altele = alias pentru vanzari.avize cand tip in (4,24,8,9)), apoi poDate.descriere = Alltrim(altele) specific pentru tip=4 ("factura din aviz"). poDate.descriere ajunge pe formularul tiparit ca referinta "nr. aviz" (layout exact in .frx, neconvertit — vezi gap mai jos). Ce se schimba: la retiparirea/relistarea unei facturi tip=4 mai vechi, unde vanzari.avize era populat gresit inainte (smearat de UPDATE-ul fara WHERE) si acum e gol pentru majoritatea facturilor, referinta la aviz dispare vizibil de pe document. E in calea de reprint, nu de emitere — deci afecteaza utilizatorul la orice reeditare/retiparire ulterioara corectiei.

2. Nota "Curs: X RON/valuta" pe factura electronica/PDF, generata fara verificare in_valuta. xmlefactura.prg (COMUN partajat, cod identic — verificat prin hash — in ROAEFACTURA, ROASITFIN, ROACONIMPORT, ROAPRINT, ROAPRODUCTIE, ROACONT/OUTPUT, si prezent si in ROAFACTURARE/COMUN):

IF !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
    lcTextAditional = ... + "Curs: " + ALLTRIM(STR(loDate.curs,10,4)) + " RON/" + ... loDate.cValuta ...
ENDIF

Conditia verifica doar curs nenul, nu si loDate.in_valuta (spre deosebire de blocul de cateva linii mai jos, DocumentCurrencyCode, care testeaza corect in_valuta=1). Inainte, facturile in LEI aveau deja curs populat gresit (bug), deci nota aparea eronat, dar cu o valoare "plauzibila". Ce se schimba: dupa corectie, curs=1 pe facturile in lei — !EMPTY(1) tot trece, deci nota tot apare, dar acum arata constant "Curs: 1.0000 RON/" cu sufix de valuta gol (id_valuta=0). Vizibil pe fiecare factura/aviz in lei exportata ca e-factura sau tiparita, in toate produsele de mai sus.

RISC POSIBIL

  1. ofacturare_comun.vc2:4156-4157 (si dublura oproceduri_facturare.prg:1225-1226): dupa blocul If poDate.in_valuta = 1 ... Else ... Endif, poDate.Curs/poDate.multiplicator sunt suprascrise necondiționat din valorile citite din view. Calculul de discount e corect protejat de in_valuta=1, dar nu s-a putut confirma daca FRX-ul (neconvertit) afiseaza aceste campuri necondiționat de in_valuta. De verificat in layout-ul tiparit.
  2. vizualizare_facturi2 (oproceduri_facturare.prg:431-479): grid-ul de cautare/listare facturi expune coloanele altele, curs, multiplicator, valuta, id_valuta, nume_val direct din FACT_VFACTURI2. Nu s-a putut confirma legarea la ControlSource in .scx (neconvertit) — daca vreuna e legata vizibil intr-un grid, utilizatorii ar vedea coloane goale/"1" unde inainte vedeau valori (gresite).
  3. ROAACNPRO Programe\proceduri_acnpro.prg:1180-1229, calcul_penalitati (calea activa): Select v.Curs, v.id_Valuta ... left join vnom_valute vl on v.id_valuta = vl.id_valuta From vanzari v, afisat probabil intr-un grid de review inainte de generarea facturilor de penalizare. Calculul numeric al penalitatii NU foloseste curs (confirmat), deci fara risc de calcul; ramane risc de afisare: id_valuta=0 ar putea sa nu se potriveasca in left join vnom_valute (tabela de valute proprie ACNPRO, distincta de NOM_VALUTE), lasand coloana valuta goala. Nu s-a putut confirma daca vnom_valute are un rand pentru id_valuta=0 (spre deosebire de NOM_VALUTE, unde existenta randului id_valuta=0 a fost deja confirmata in rec_s4_aplicare.md, punctul 3 din sectiunea S8/curs — deci pentru view-urile FACT_VFACTURI* din COMUN acest risc e deja exclus, ramane specific tabelei proprii ACNPRO).
  4. ROAAUTO Programe\oproceduri_devize.prg:1486-1532, relisteaza_factura_deviz: citeste curs/multiplicator/altele din fact_vfacturi la reafisarea unei facturi, dar cursorul se inchide imediat fara ca valorile sa fie propagate mai departe — risc redus, de reverificat doar daca un apelant viitor se bazeaza pe acelasi cursor.
  5. CONTAFIN2ORA\VFP2ORA\Programe\acn.prg:~1247-1319 (unealta de migrare, nu produs curent de vanzare): scrie direct curs/id_valuta/multiplicator in INSERT INTO VANZARI + MERGE INTO VANZARI_CURSURI, cu propria regula de zero-ing independenta de PACK_FACTURARE — probabil neafectata functional, dar merita o verificare separata daca unealta mai e folosita activ.

FARA RISC (rezumat, nu enumerate)

  • ROAFACTURARE+COMUN: restul celor ~930 potriviri brute pentru AVIZE/CURS/ID_VALUTA/ MULTIPLICATOR/ALTELE — module NIR/import, balante/parteneri/compensari, salarii, curs valutar BNR, sau citiri deja corect protejate de in_valuta/tip_valuta (ofacturare.prg::listeaza_ofacturare la emitere, ofacturare_stoc.prg, anaf_efactura.prg cu decode(in_valuta,1,curs,1), makexmlfacturaelectronica.prg cu garda mmoneda<>"RON"). Niciun hit .avize (acces direct de camp) in afara celor doua raportate mai sus.
  • ROACONT: Programe\saft_d406.prg (declaratia fiscala D406, oSalesInvoices) — foloseste DECODE(v.in_valuta, 0, 0, ...) explicit, output SAF-T neschimbat de corectie. Restul hit-urilor pe tabele proprii (ireg_parteneri, act, rul) sau text necorelat.
  • ROAACNPRO (restul), ROACONTRACTE, ROAGEST, ROAIMOB, ROAREGISTRATURA, ROASTART: zero hit relevant legat de VANZARI in afara COMUN (verificat, nu doar negasit).
  • ~40 de produse din restul suitei (ROAEFACTURA si variante, ROASITFIN, ROAPRINT, ROACONIMPORT, ROAPRODUCTIE, ROAHOTEL si variante, ROASAL, ROAMANAGER, ROADECL, ROAPRETURI, ROABAZA, ROAAPROV, ROADEVIZE, etc.): hit-uri pe "AVIZE" = conceptul de business "aviz de expeditie" (tip document), nu coloana; hit-uri "CURS"/"ID_VALUTA" pe alte tabele proprii sau in oDateFactura (populate de apelant, protejate de in_valuta). COMUNROA (depozitul central) contine doar scripturi de deployment, fara logica de facturare.

Rezumat acoperire

  • ROAFACTURARE + COMUN local: acoperire completa .prg + .vc2/.sc2 via vfp_symbols.ps1 -CodeOnly (index deja construit). Gap: 207 .frx si 30 .mnx fara .fr2/.mn2 in cache — layout-ul efectiv tiparit (unde poDate.descriere/Curs/cValuta chiar apar pe hartie) nu e verificabil fara conversie (interzisa in acest task). Riscurile REAL #1/#2 si POSIBIL #3/#4 depind partial de acest layout.
  • 8 produse cu cache text existent (ROAACNPRO, ROAAUTO, ROACONT, ROACONTRACTE, ROAGEST, ROAIMOB, ROAREGISTRATURA, ROASTART): acoperire completa .prg + .vc2/.sc2 via vfp_symbols.ps1 -CodeOnly. Gap: proprietati/metadata (ControlSource de grid legat direct de o coloana, fara linie de cod explicita) nu apar in -CodeOnly — dar un asemenea caz s-ar clasifica oricum FARA RISC (simpla afisare).
  • Restul suitei (~56 directoare, inclusiv COMUNROA): acoperire doar pe fisierele .prg (text simplu, nu necesita conversie); zero cache text pentru .vcx/.scxniciun cod din clase/formulare compilate al acestor produse nu a fost verificat, conform interdictiei de a genera cache nou. ~35 produse identificate ca in afara domeniului (unelte/infrastructura: SSH, server, telefonie, criptare, declaratii D1xx/D3xx/D406 etc.) fara nicio potrivire pe termenii cautati.
  • Nicio conexiune la baza de date folosita; cifrele despre distributia datelor (ex. randul id_valuta=0 din NOM_VALUTE) sunt preluate din rec_s4_aplicare.md, deja documentate.

Concluzie

Doua locuri cu risc real confirmat, ambele in codul COMUN partajat (deci efect cross-project): disparitia referintei la aviz de pe facturile tip=4 retiparite, si textul "Curs: 1.0000 RON/" afisat gresit pe nota facturii electronice/PDF pentru facturile in lei. Restul e risc posibil, dependent de layout-uri .frx/.scx neconvertite (gap de acoperire cunoscut, nu absenta de risc). Nu s-a gasit niciun consumator cu risc real de calcul (sume/discounturi) — toate caile de calcul verificate sunt deja protejate corect de in_valuta.


Corectie aplicata — riscul REAL #2 (nota "Curs:" din xmlefactura.prg)

Modificare de cod, ceruta explicit de team-lead dupa livrarea inventarului de mai sus. Domeniu: doar D:\ROA\ROAFACTURARE\COMUN\programe\xmlefactura.prg. Nicio alta copie din suita nu a fost atinsa.

Ce s-a schimbat

Linia 374 (acum singura diferenta fata de fisierul dinainte de editare):

-		IF !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
+		IF loDate.in_valuta = 1 AND !EMPTY(NVL(loDate.curs,0)) AND ATC('curs', m.lcTextAditional) = 0
 			lcTextAditional = m.lcTextAditional + Iif(!Empty(m.lcTextAditional), ' # ', '') +  "Curs: " + ...
 		ENDIF

Garda adaugata (loDate.in_valuta = 1 AND) e preluata identic din modelul deja corect din acelasi fisier, la 9 linii mai jos (acum :385, era :384): If loDate.in_valuta = 1 / oinvoice.lastchild.Text = m.mmoneda, folosit pentru DocumentCurrencyCode. Nicio forma noua inventata. Fara comentarii adaugate (regula 2, rezolvari de erori). Diff complet: D:\ROA\ROAFACTURARE\docs\diff_xmlefactura_garda_valuta.patch.

Verificare pe cazuri (dupa modificare)

  1. Factura in lei (in_valuta=0), curs=1 (comportamentul nou, generalizat, al facturilor in lei dupa corectia PACK_FACTURARE): inainte, !EMPTY(NVL(1,0))=.T. -> nota aparea cu "Curs: 1.0000 RON/" (valuta goala). Acum, loDate.in_valuta = 1 e .F. -> intreg AND-ul e fals -> nota NU se mai adauga. Singurul caz care isi schimba comportamentul (cel vizat).
  2. Factura in valuta reala (in_valuta=1), curs populat normal: loDate.in_valuta = 1 e .T., restul conditiei neschimbat -> nota apare identic ca inainte. Neschimbat.
  3. Factura veche cu curs NULL (orice in_valuta): NVL(NULL,0)=0 -> !EMPTY(0)=.F. -> conditia era deja falsa inainte de garda si ramane falsa (garda adaugata doar restrange in plus cazul in_valuta=0, nu schimba nimic pe ramura curs NULL). Neschimbat.

Confirmat: doar cazul 1 (facturi in lei cu curs efectiv nenul) isi schimba comportamentul, exact riscul identificat.

Verificare encoding (byte-level)

Fisierul contine octeti cp1252 >=0x80 (0xEE = "î", la liniile 1203 si 1330 — "puteti încarca prin SPV"), deci risc de corupere la scriere cu tool care nu pastreaza octetii nativ. Editare facuta cu perl in mod raw (s/.../.../ ), nu cu Edit/Write:

  • Backup pre-editare: xmlefactura.prg.pre_runda.bak (md5 e800c71bd08e6c472b6fe912437f37f8, 62093 octeti).
  • Dupa editare: md5 c9c9f4774346b2e62bfe9c12ea02dfb3, 62118 octeti (+25 = exact lungimea textului loDate.in_valuta = 1 AND inserat).
  • Comparatie linie-cu-linie (raw bytes) intre backup si fisierul editat: 1364 linii in ambele, o singura linie diferita (374) — restul fisierului byte-identic.
  • Octetii 0xEE de la liniile 1203/1330 confirmati neschimbati dupa editare.
  • Scanare pentru markeri de corupere (EF BF BD = U+FFFD reincodat): zero potriviri.

Encoding intact, nicio corupere.

Copii identice/asemanatoare in suita — corectie fata de raportul initial

Raportul initial (sectiunea RISC REAL #2) afirma ca fisierul e "identic prin hash" in ROAEFACTURA, ROASITFIN, ROACONIMPORT, ROAPRINT, ROAPRODUCTIE si ROACONT/OUTPUT — verificare hash directa acum (md5 pe tot arborele D:\ROA, exclus DATABASE) arata ca afirmatia era partial gresita: doar ROACONIMPORT si ROAPRINT sunt byte-identice intre ele; restul au fiecare continut propriu, divergent de ROAFACTURARE. Ce e adevarat si ramane valabil: toate contin acelasi tipar de cod vulnerabil (linia cu conditia fara garda pe in_valuta), verificat cu grep, o singura aparitie in fiecare fisier.

Grup A — fisier byte-identic cu ROAFACTURARE/COMUN INAINTE de editarea de azi (md5 e800c71bd08e6c472b6fe912437f37f8, deci acelasi patch de o linie de la :374 se aplica identic, byte cu byte, in toate): ROAACNPRO, ROAAUTO, ROACONT, ROACONTRACTE, ROADEF, ROAGEST, ROAIMOB, ROAREGISTRATURA, ROARES, ROASTART — cale D:\ROA\<PRODUS>\COMUN\programe\xmlefactura.prg. (In plus, acelasi hash apare si in foldere de backup istoric fara relevanta: _backup_comun_conflicts\*, _backup_roaimob_comun_conflict\* — nu sunt copii vii.)

Grup B — fisier divergent (alt continut/alte linii in rest), dar cu ACELASI tipar vulnerabil (conditie identica textual, gasita o singura data per fisier, doar la alt numar de linie):

Produs Cale md5 Linia conditiei
OUTPUT/ROACONT D:\ROA\OUTPUT\ROACONT\COMUN\programe\xmlefactura.prg 504dc24e771f6d66e4f028d1347671a8 350
ROACONIMPORT D:\ROA\ROACONIMPORT\COMUN\programe\xmlefactura.prg fa1e389839109ae46da1ef815e102259 356
ROAEFACTURA D:\ROA\ROAEFACTURA\COMUN\programe\xmlefactura.prg 200442ad86e180c2484c96367ac9514a 356
ROAPRINT D:\ROA\ROAPRINT\COMUN\programe\xmlefactura.prg fa1e389839109ae46da1ef815e102259 356
ROAPRODUCTIE D:\ROA\ROAPRODUCTIE\COMUN\programe\xmlefactura.prg b71c1d9284d8ee78d02429b04c968a35 326
ROASITFIN D:\ROA\ROASITFIN\COMUN\programe\xmlefactura.prg 47bb2e49770713b396e855e8af0ae2ea 356

Grup C — NU are acest bloc de cod deloc (verificat, nu doar negasit — nu construiesc nota de curs valutar in e-factura): ROADECL, ROAMANAGER, ROAPRETURI, ROASAL. Fara risc, fara propagare necesara.

Fisierul modificat azi: doar D:\ROA\ROAFACTURARE\COMUN\programe\xmlefactura.prg (md5 nou c9c9f4774346b2e62bfe9c12ea02dfb3). Toate celelalte 16 cai listate mai sus (Grup A + Grup B) raman NEATINSE, cu bug-ul inca prezent — propagarea e decizie de proces a lui Marius, nu s-a facut aici.

Livrabile

  • Modificare: D:\ROA\ROAFACTURARE\COMUN\programe\xmlefactura.prg (linia 374, +garda in_valuta).
  • Patch de review: D:\ROA\ROAFACTURARE\docs\diff_xmlefactura_garda_valuta.patch.
  • Backup pre-editare (ramas pe disc, netracked): xmlefactura.prg.pre_runda.bak in acelasi folder.
  • Aceasta sectiune.

Fara commit git/svn — asteapta aprobarea patch-ului.