Files
roafacturare/docs/cercetare/s2_factureaza_unificare.md
Marius Mutu d9f5ca4226 docs: planurile, proiectarile si rapoartele de lucru intra in versionare
Folderul docs\ era pana acum in afara oricarui control de versiuni - nici git,
nici SVN - desi contine planurile pe puncte, proiectarile si rapoartele de
cercetare pe care se sprijina modificarile din cod. O stergere acolo era
definitiva.

Fisierele intermediare (handoff-uri intre sesiuni, diff-uri deja aplicate) au
fost sterse inainte, nu versionate: ce era durabil in ele a intrat in antetele
fisierelor de test la care se refereau.

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

23 KiB

S2 — Proiectare: o singura procedura factureaza

Cercetare read-only pentru povestea S2 din docs\plan_13_unificare_formular_facturare.md. Niciun fisier de cod atins, git_sync.ps1 nerulat, niciun write-back, niciun commit.

Verdict

Se poate unifica, si e mai simplu decat pare. factureaza2 nu e o a doua implementare funcţională care trebuie fuzionata cu grija — e un fork din 08.06.2017 la care s-a dezactivat execuţia interogarii de articole (lnSucces = 1 hardcodat, goExecutor.oExecute niciodata apelat) si mai multe blocuri intregi sunt inchise cu If .F.. Are exact un singur apelant in tot codul (ofacturare.prg:90, din interiorul lui factureaza insusi, in spatele unui AMESSAGEBOX de confirmare) si zero utilizatori reali dincolo de acel switch de test. Riscul de regresie e mic pentru ca nu exista nimic funcţional de pierdut in factureaza2 — obstacolul principal nu e tehnic, e ca formularul spre care duce (frm_facturare_articole2) e tot un prototip neterminat (Init de 92 de linii, nu completeaza antetul), deci unificarea proceduri lor nu face formularul nou utilizabil — doar elimina duplicarea de cod. Asta ramane treaba lui S3.


1. Inventarul celor doua proceduri

Ambele sunt proceduri globale (nu metode de clasa) in COMUN\programe\ofacturare.prg, incarcat via SET PROCEDURE ... ADDITIVE din Programe\roafacturare.prg. Nu exista omonime — verificat cu Get-ChildItem -Recurse *.prg | Select-String '^\s*(PROCEDURE|FUNCTION)\s+factureaza2?\b' pe tot ROAFACTURARE si cu Grep pe .vc2 din COMUN: un singur rezultat pentru fiecare nume.

factureaza factureaza2
Locatie COMUN\programe\ofacturare.prg:81-577 (497 linii) COMUN\programe\ofacturare.prg:583-1081 (499 linii)
Parametri LPARAMETERS tnTip, toFactura (:82) — toFactura = obiect, pentru copiere/modificare LPARAMETERS tnTip (:584) — fara al doilea parametru
Apelanti ~20+ puncte de intrare reale (sectiunea 3) unul singur: ofacturare.prg:90, din factureaza

ofacturare.prg in sine e cod comun al intregii suite: exista o copie identica-la-origine in COMUN\programe\ofacturare.prg a fiecarui produs ROA verificat (ROACONT, ROAGEST, ROACONTRACTE, ROAAUTO, ROAACNPRO, ROAIMOB, plus alte ~30 produse) — fiecare cu propriile factureaza/factureaza2 la linii apropiate (de regula :76-77 sau :87-88 pentru comutatorul gnFacturareNou, dupa versiune). Nu exista in COMUNROA (biblioteca partajata separata) — e sincronizat manual intre produse ca fisier COMUN, nu ca livrabil COMUNROA.

2. Diff-ul semantic

Comparatie linie-cu-linie, cu citate ofacturare.prg:linie. Sase din cele noua diferente listate in sectiunea A a planului se confirma exact; una e imprecisa; una lipseste din plan.

Ce face factureaza si nu face factureaza2

Ce factureaza factureaza2
Tipurile 51 (ROAACNPRO), 52 (contract factura fiscala valuta) rutate la FACTURA Inlist(tnTip,45,48,49,**51,52**) la :192 si :222 Inlist(tnTip,45,48,49) la :674 si :700 — 51/52 lipsesc, ar cadea in Otherwise -> AVIZ
Ramura llCopiere/toFactura (copiere/modificare factura) declarata :102, populata :111, folosita la completarea datelor (:200-206), la construirea interogarii (Case m.llCopiere -> cursor_retur_document, :267-268), si la adaugarea articolelor din lista de preturi peste cele copiate (:454-474) absenta complet — nicio declarare a llCopiere, niciun tratament al lui toFactura
Deschiderea frm_date_factura/frm_date_aviz activa, cu toFactura transmis constructorului (:229-235) inchisa cu If .F. (:707-711)
Filtrul RORTC pe jtva_coloane AND !'RORTC'$UPPER(coloana_jv) la ambele ramuri (:243, :245) absent (:715, :717)
Executia interogarii de articole lnSucces = goExecutor.oExecute(lcSqlCursor, lcCursor) (:311) inchisa cu If .F. (:823-826); imediat dupa, lnSucces = 1 hardcodat (:827) — cursorul SQL construit la :748-822 nu ruleaza niciodata
Verificarea "nu exista articole" activa (:324-328) inchisa cu If .F. (:838) — combinata cu lnSucces=1 de mai sus, ramura merge mereu pe calea "am articole", indiferent de continut
Zeroizarea gestionabil pe proforma IF poDate.eProforma = 1 ... UPDATE (lcCursor) SET gestionabil = 0 (:333-336) absenta — eProforma nu apare nicaieri in factureaza2 (verificat cu grep pe tot fisierul)
crspolitici / crscontracte (populare combo-uri) necondiţionate (:420-440) ambele inchise cu If .F. (:956-968, :969-980)
GetInstitutiePublica poDate.institutie_publica = GetInstitutiePublica(...) (:509) absenta
codnc8/codcpv pe fiecare linie Replace codnc8 WITH ..., codcpv WITH ... in Scan (:516-517), pe langa codmatc doar codmatc (:1027) — codnc8/codcpv lipsesc
GetSoldClient + poDate.sold_lei/sold_valuta inainte de listare prezent, in ramura non-bon-fiscal (:530-533) absent — ramura echivalenta (:1040-1041) sare direct la listeaza_ofacturare()
Formularul de articole frm_facturare_articole (:395) frm_facturare_articole2 (:929) — singura diferenta functionala reala care justifica existenta lui factureaza2

Corectii fata de sectiunea A a planului

  • "verifica_numar(16, ...) pentru chitanta" — planul GRESESTE. E prezent identic in ambele: factureaza:502-504 si factureaza2:1018-1020 (If poDate.incasat <> 0 ... poGeneratorNumere.verifica_numar(16, poDate.nr_incasare) Endif). Nu lipseste din factureaza2.
  • "cursor_avize cu tip 23" — planul e imprecis. Nu exista nicio asociere cursor_avize/tip 23 in niciuna din cele doua proceduri (cursor_avize trateaza doar tnTip = 4, identic in ambele, :294-295 / :774-775). Ce difera real pentru tipul 23: in factureaza, tipul 23 e prins in Case Inlist(tnTip,1,22,5,29,7,10,**23**) -> cursor_preturi (:279-282); in factureaza2, 23 nu e in acea lista (:758, doar 1,22,5,29,7,10) si cade in schimb in Case Inlist(tnTip,**23**,41) -> cursor_gestiune (:776-778). E o rutare complet diferita pentru acelasi tip de document, nu o simpla lipsa — de adaugat explicit la lista din sectiunea A.
  • Nementionat in plan — tipul 52 lipseste si din Do Case de contract: factureaza Case Inlist(tnTip,2,26,6,**52**) (:283) vs factureaza2 Case Inlist(tnTip,2,26,6) (:762) — aceeasi lipsa a tipului 52 ca la nIdTipDoc, dar intr-un loc separat din cod; tipul 24 (aviz de retur) lipseste similar din Case Inlist(tnTip,8,9,**24**) (:306) vs Case Inlist(tnTip,8,9) (:819).

Ce fac amandoua identic (verificat, nu presupus)

Structura comentariilor lnIdSet/pnTipFacturare, bucla Do While lnRaspuns = 6, apelul actualizeaza_optiuni_program(), crearea poDate/poGeneratorNumere, alegerea frm_date_factura / frm_date_aviz_lucrare / frm_date_aviz pentru antet (desi in factureaza2 deschiderea propriu-zisa e dezactivata), tratarea tnTip=30 (aviz din NIR, inclusiv bucla Scatter/Insert Into crsfactura identica caracter-cu-caracter), verifica_numar(16,...), dezalocarea celor trei numere (nIdTipDoc, 16, 3/26) la abandon, si intreaga bucla finala de AMESSAGEBOX "Doriti sa continuati" + CloneObj/poDate.Reset().

Ce face factureaza2 si nu face factureaza

Un singur lucru: verificari defensive suplimentare de tip la iesirea timpurie (pnButon = 2):

IF TYPE('poDate.nr_incasare') = 'N'
    poDate.nr_incasare = 0
ENDIF
IF TYPE('poDate.incasat') = 'N'
    poDate.incasat = 0
ENDIF

(factureaza2:727-732) — factureaza face resetarea echivalenta necondiţionat, dar mai tarziu, in ramura de succes (:546-547), nu pe calea de abandon. Diferenta e cosmetica, nu comportamentala pe fluxul normal.

3. Toti apelantii

Cautare in tot arborele D:\ROA (fiecare produs + COMUN-ul lui + COMUNROA), cu capcana "Grep nu vede COMUN" tratata explicit (path dat direct pe fiecare COMUN, nu doar pe radacina produsului — altfel cautarea sare tacut peste el, per gitignore-ul fiecarui produs).

Niciun produs verificat (ROACONT, ROAGEST, ROAAUTO, ROAACNPRO, ROAIMOB) nu apeleaza factureaza direct din cod propriu — nici in COMUN, nici in partea specifica produsului. Singura urma in COMUN-urile lor e propria copie a ofacturare.prg/oproceduri_facturare.prg (definitia, nu un apel). Confirma independent observatia din coresp_cont_venchelt.md ca ROAACNPRO nu trece prin acest flux (foloseste pack_acn.salveaza_regdoc, nu contabilizeaza_articol). Exceptia: ROACONTRACTE, care are un apel real, specific produsului, la wrapper-ul facturare_contracte.

Apelanti directi ai factureaza(N)

Apelant Produs Parametri Tip document
Meniuri\politica.mn2:12 ROAFACTURARE factureaza(1) lista de preturi, lei
Meniuri\politica.mn2:15 ROAFACTURARE factureaza(8) retur factura lei
Meniuri\politica.mn2:18 ROAFACTURARE factureaza(45) restaurant
Meniuri\politica.mn2:26 ROAFACTURARE factureaza(49) marfa custodie fara descarcare K
Meniuri\politica.mn2:29 ROAFACTURARE factureaza(48) marfa custodie cu descarcare K
Meniuri\politica.mn2:37 ROAFACTURARE factureaza(5) lista de preturi, valuta (invoice)
Meniuri\politica.mn2:40 ROAFACTURARE factureaza(7) credit note
Meniuri\politica.mn2:43 ROAFACTURARE factureaza(10) factura fiscala valuta
Meniuri\politica.mn2:46 ROAFACTURARE factureaza(9) retur factura valuta
Meniuri\contracte.mn2:12 ROAFACTURARE factureaza(2) contract, lei
Meniuri\contracte.mn2:15 ROAFACTURARE factureaza(6) contract, valuta
Meniuri\contracte.mn2:18 ROAFACTURARE factureaza(52) contract, factura fiscala valuta

Apelanti prin COMUN\programe\oproceduri_facturare.prg (dispecer comun, un wrapper per grup de tipuri)

Wrapper (oproceduri_facturare.prg) -> factureaza(N) Apelat din
facturare_contracte(tcTip) (:119-136) factureaza(2)/factureaza(6)/factureaza(52) dupa tcTip ROAFACTURARE\Clase\ofundal_facturare.vc2:890-894, ROAFACTURARE\Ferestre\fundal.sc2:924, ROACONTRACTE\Clase\ferestre_contracte.vc2:1542-1546 (produs diferit, apel real)
facturare_comenzi() (:139-141) factureaza(3) COMUN\clase\ocomenzi.vc2:1580-1596, metoda do_factura — SCATTER NAME goComanda MEMO inainte de apel
facturare_avize() (:144-146) factureaza(4) ROAFACTURARE\Clase\ofundal_facturare.vc2:905, ROAFACTURARE\Ferestre\fundal.sc2:932
copiere_factura(toFactura) (:150-153) factureaza(toFactura.Tip, toFactura) COMUN\clase\ofacturare_comun.vc2:3710 — fisierul de perimetrul #6, doar citit, neatins
facturare_lista_de_preturi() (:114-116) Do politica.mpr -> popup-ul din politica.mn2 (vezi tabelul de mai sus) ROAFACTURARE\Clase\ofundal_facturare.vc2:883, ROAFACTURARE\Ferestre\fundal.sc2:920
emitere_aviz_clienti(tnTip) (:198-228) factureaza(21/22/26/24) dupa tnTip=1/2/3/7; tnTip=4,5,6 -> initializeaza_vanzare_din_stoc, nu factureaza ROAFACTURARE\Meniuri\aviz_clienti.mn2:21,47,51,55,59,63,67
emitere_aviz_clienti_debitori(tnTip) (:230-243) factureaza(28/29) dupa tnTip=1/2 ROAFACTURARE\Meniuri\aviz_clienti_debitori.mn2:22,26
emitere_aviz_clienti_custodie(tnTip) (:244-259) factureaza(42/47) dupa tnTip=1/2; tnTip=3 -> initializeaza_vanzare_din_stoc ROAFACTURARE\Meniuri\aviz_clienti_custodie.mn2:30,34,38
emitere_aviz_transfer(tnTip) (:261-280) factureaza(25/23/27/30/41) dupa tnTip=1..5 ROAFACTURARE\Meniuri\aviz_subunitati.mn2:36,40,44,48,52

Total: ~33 puncte de intrare reale in cod pentru factureaza, doar unul pentru factureaza2 (ofacturare.prg:90, in interiorul lui factureaza, gatit de gnFacturareNou=1 + confirmare DA la AMESSAGEBOX).

4. Rolul lui gnFacturareNou

Nu e un comutator de productie — e un switch de dezvoltator, fara nicio persistenta.

  • Declarat: nicaieri. Cautare exhaustiva (gnFacturareNou, tot D:\ROA, extensii .prg/.vc2/.sc2/.mn2) — singura aparitie e exact linia care il citeste (ofacturare.prg:88, sau liniile echivalente in fiecare copie de produs). Nu exista intr-un ecran de optiuni, nu e coloana intr-un tabel de configurare (spre deosebire de gnScadereStoc, gl406 etc., citite din oinit_optiuni.prg).
  • Citit: o singura data, ofacturare.prg:88 — If Type('gnFacturareNou') = 'N' And m.gnFacturareNou = 1.
  • Valoare implicita: inexistenta ca variabila -> Type() intoarce 'U' (Undefined), deci conditia e falsa implicit. Devine .T. doar daca cineva a facut manual, in sesiunea VFP curenta (de regula din fereastra de comenzi a IDE-ului), gnFacturareNou = 1.
  • Cine il seteaza: nimeni, in cod. E gandit sa fie setat manual de un dezvoltator care vrea sa testeze prototipul.
  • Confirma sau infirma ca e comutator intre proceduri, nu intre formulare? Azi, chiar intre proceduri — factureaza:88-93 face Return factureaza2(m.tnTip) dupa raspunsul DA la dialog, adica sare complet in cealalta procedura, cu tot ce lipseste din ea (sectiunea 2). Planul (S2, linia 1423) vrea sa-l transforme in comutator intre formulare, in interiorul unei singure proceduri — schimbare corecta, pentru ca azi dubleaza cod, nu doar UI.

5. Proiectarea unificarii

Semnatura

Neschimbata la aceasta poveste: factureaza(tnTip, toFactura). Parametrul de sursa explicit (comanda/contract) e treaba lui S3c, care depinde de S2 si il trateaza separat — nu se amesteca aici (planul insusi spune "Atinge cod comun intregii suite — nu se face impreuna cu alta modificare").

Ramificarea interna

Nu e nevoie de o rescriere — factureaza de azi e deja versiunea completa si functionala. Interventia e chirurgicala:

  1. Muta verificarea gnFacturareNou de la inceputul procedurii (azi :88-93, unde face Return factureaza2(...)) la punctul unde se alege lcObject pentru formularul de articole (azi :395 in factureaza, ramura corespunzatoare celei din factureaza2:929):
    Case tnTip = 27
        lcObject = [frm_avizare_lucrare]
    Otherwise
        lcObject = IIF(m.llFacturareNoua, [frm_facturare_articole2], [frm_facturare_articole])
    Endcase
    
    unde llFacturareNoua e calculat o singura data, la fel ca azi (Type('gnFacturareNou')='N' And gnFacturareNou=1, urmat de acelasi AMESSAGEBOX DA/NU), dar fara Return in alta procedura — doar seteaza flagul si continua executia normala.
  2. Tot restul ramane identic — cursorul de articole, eProforma, codmatc/codnc8/codcpv, GetInstitutiePublica, GetSoldClient, filtrul RORTC, rutarea tipurilor 51/52/23/24, ramura llCopiere/toFactura — pentru ca acestea nu au nicio legatura cu care formular de articole se deschide. factureaza2 nu avea o varianta "corecta, dar diferita" a acestor blocuri — pur si simplu nu le avea, pentru ca fusesera dezactivate in graba la prototipare (If .F. peste tot), nu pentru ca noul formular ar avea nevoie de alt comportament acolo.
  3. Sterge factureaza2 in intregime (:583-1082, inclusiv bannerul INCEPUT/SFARSIT).

Ordinea, ca suita sa nu fie stricata niciun moment

Riscul de "moment in care suita e stricata" e mic aici, spre deosebire de S3c — pentru ca factureaza2 nu are alt apelant decat el insusi prin factureaza. Ordinea propusa:

  1. Muta logica de selectie a lui lcObject (pasul 1 de mai sus) inainte de a sterge factureaza2 — la acest punct, codul are temporar ambele cai active (comutatorul nou + factureaza2 inca existent, dar orfan). Se poate testa manual ca gnFacturareNou=1 deschide frm_facturare_articole2 din interiorul lui factureaza, cu restul comportamentului corect (spre deosebire de azi, unde deschiderea prin factureaza2 sare peste eProforma, codnc8 etc.)
  2. Abia dupa verificare, sterge factureaza2 — pasul e sigur pentru ca nu mai are niciun apelant (linia 90, singurul, a fost deja inlocuita la pasul 1).
  3. Un singur fisier se schimba: COMUN\programe\ofacturare.prg. Niciun apelant din tabelul de la punctul 3 nu are nevoie de nicio modificare — toti cheama factureaza(N) cu aceeasi semnatura, niciunul nu cheama factureaza2 direct.
  4. ROACONTRACTE nu necesita nicio schimbare la aceasta poveste — apelul lui la facturare_contracte -> factureaza(2/6/52) nu atinge factureaza2 deloc.

6. Riscurile de regresie

  • Cel mai probabil sa se rupa: ramura llCopiere/toFactura, pentru ca e cea mai complexa bucata de logica prezenta doar in factureaza (cursor_retur_document, apoi suprapunerea cu cursor_preturi pentru a permite adaugarea de articole noi peste cele copiate, :454-474). Nu are nicio acoperire azi in factureaza2 de comparat — deci orice greseala de copy-paste la mutarea liniei lcObject risca sa rupa exact aceasta ramura, nu partea "noua". Testat manual din copiere_factura (ofacturare_comun.vc2:3710) inainte si dupa.
  • Al doilea cel mai probabil: rutarea tipurilor 23/24/51/52, pentru ca azi cad in Do Case-uri diferite intre cele doua proceduri (sectiunea 2) — o gresala de aliniere la stergerea lui factureaza2 nu ar afecta functional (pentru ca acele Do Case-uri raman neatinse, doar duplicate disparute), dar merita o trecere vizuala pe fiecare tip listat la punctul 3 dupa modificare.
  • ROACONTRACTE — singurul apelant real din alt produs. Nu poate fi testat din arborele de lucru ROAFACTURARE — cere un build/rulare separata a ROACONTRACTE, cu propriul ofacturare.prg sincronizat manual (nu e acelasi fisier fizic, e o copie). Verificarea "gata" trebuie sa includa explicit macar un test manual pe ROACONTRACTE, tip contract-factura, nu doar pe ROAFACTURARE.
  • frm_facturare_articole2 insusi ramane netestabil functional la aceasta poveste — Init-ul lui nu completeaza antetul (S1), deci deschiderea cu gnFacturareNou=1 va arata un formular cu campuri goale la fel ca azi. Nu e o regresie introdusa de S2, dar e o asteptare de gestionat: S2 nu face frm_facturare_articole2 utilizabil, doar elimina procedura duplicata din spatele lui.
  • Nimic din asta e testabil headless — toate cele ~33 puncte de intrare sunt declansate din meniuri/formulare UI (ON SELECTION BAR, DO ... IN ... din metode de clic), iar rezultatul se verifica prin ACT/VANZARI/RUL in Oracle sau vizual pe formular. Testarea de dupa modificare trebuie sa fie manuala, minim pe: o factura lista de preturi lei (tip 1), un aviz din comanda (tip 21), o factura din contract lei (tip 2, din ROACONTRACTE daca fezabil), o copiere de factura (toFactura populat), si — cu gnFacturareNou=1 setat manual — confirmarea ca frm_facturare_articole2 se deschide fara eroare (nu neaparat ca arata corect, asta e S3).

7. Criteriul de "gata", rescris si verificabil

Planul spune azi: "factureaza2 nu mai exista, iar comutatorul alege formularul, nu procedura." Rescris, verificabil fara ambiguitate:

  1. Structural (verificabil cu o comanda, fara sa citesti codul):
    Get-ChildItem -Recurse 'D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare.prg' |
      Select-String -Pattern '^\s*(PROCEDURE|FUNCTION)\s+factureaza2\b'
    
    trebuie sa intoarca zero rezultate.
    Select-String -Path 'D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare.prg' -Pattern 'gnFacturareNou'
    
    trebuie sa intoarca exact o aparitie, situata in interiorul lui factureaza, la punctul unde se alege lcObject (nu inainte de constructia lui poDate, ca azi).
  2. Comportamental, testat manual, fara gnFacturareNou setat (calea implicita, majoritatea utilizatorilor): cele patru documente listate la sectiunea 6 (factura lista de preturi, aviz din comanda, factura din contract, copiere factura) produc aceleasi randuri in ACT/VANZARI/RUL ca inainte de modificare.
  3. Comportamental, cu gnFacturareNou = 1 setat manual si DA la dialog: se deschide frm_facturare_articole2 (nu frm_facturare_articole), fara eroare la deschidere, cu eProforma/codnc8/codcpv/GetInstitutiePublica/GetSoldClient/filtrul RORTC/rutarea 51-52-23-24 toate active identic cu calea implicita (spre deosebire de azi, cand gnFacturareNou=1 le sarea pe toate).
  4. ROACONTRACTE: minim un test manual de facturare din contract, dupa sincronizarea ofacturare.prg in acel produs, confirma acelasi rezultat ca inainte.

Ce nu s-a putut stabili si de ce

  • Cine activeaza popup-urile politica.mn2/contracte.mn2 (nivelul chiar deasupra apelurilor directe la factureaza(N)) nu a fost trasat pana la butonul/grid-ul exact — nu era necesar pentru diff-ul procedurilor sau pentru tabelul de apelanti (punctul de interes e apelul la factureaza, nu inca un nivel de indirectare deasupra), dar daca implementarea muta si aceste meniuri, merita o trecere separata.
  • Daca alte produse (ROAGEST, ROAAUTO, ROAACNPRO, ROAIMOB, ROACONT) au propriul lor oproceduri_facturare.prg/ocomenzi.vc2 invocat din cod specific produsului, dincolo de ce am cautat — cautarea a acoperit exact numele factureaza/factureaza2 si cei noua wrapperi din oproceduri_facturare.prg; nu a acoperit eventuale cai complet diferite catre acelasi fisier (de exemplu un meniu .mn2 specific unui alt produs care ar chema un wrapper cu alt nume). Pentru aceste cinci produse, cautarea directa (factureaza(, cei noua wrapperi) a dat zero rezultate in codul specific produsului — suficient pentru concluzia "nu apeleaza azi", dar nu e o dovada negativa absoluta de "nu ar putea apela niciodata prin alt canal".
  • Testarea reala pe ROACONTRACTE nu a fost efectuata (read-only, fara rulare de cod) — doar confirmata existenta apelului in sursa (ferestre_contracte.vc2:1542-1546).
  • Diferenta minora de text intre mesajele "Luna inchisa" ale celor doua proceduri (factureaza:105 vs factureaza2:594, un caracter diacritic afisat diferit la citire) nu a fost investigata mai departe — pare artefact de encoding la citire (cp1250 in fisier), nu o diferenta de continut intentionata; oricum dispare odata cu stergerea lui factureaza2.

Bug-uri semnalate, nereparate

  • factureaza2 e, in forma actuala, non-functional dincolo de deschiderea formularului de antet dezactivata — chiar daca cineva ar apela azi acest cod pe o cale ipotetica ocolind factureaza, executia interogarii SQL e dezactivata (lnSucces = 1 hardcodat la :827, fara goExecutor.oExecute) si verificarea "nu exista articole" e dezactivata (:838) — codul ar merge mereu pe ramura de succes cu un cursor crsarticole nepopulat de aceasta rulare (posibil ramas dintr-un apel anterior, cu alt tnTip). Nu se repara aici — S2 il sterge oricum, deci bug-ul dispare odata cu procedura, nu prin fix separat.
  • Niciun bug nou gasit in COMUN\clase\ofacturare_comun.vc2 sau COMUN\programe\ofacturare_editare.prg (perimetrul #6) — singura atingere a acestor fisiere in aceasta cercetare a fost citirea liniei copiere_factura din ofacturare_comun.vc2:3710, care nu are nimic suspect.