Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EBFMe75MwdnDQk3qhp1YB2
9.4 KiB
Date de test - NNIR editabil in Registru Jurnal
Baza: MARIUSM_AUTO@ROA_CENTRAL (test, nu productie). Verificare: verif_nnir_cod.sql in acest
folder (sqlplus ... @verif_nnir_cod.sql <cod>).
| Caz | COD | AN | LUNA | ID_SET | NNIR curent | ACT randuri | RUL randuri | RUL_OBINV randuri |
|---|---|---|---|---|---|---|---|---|
| NIR/achizitie (principal) | 1140841 | 2026 | 7 | 209 | 3 | 7 (doar 1 cu nnir=3, restul 0) | 1 (nnir=3) | 0 |
| Obiecte de inventar | 1140835 | 2026 | 6 | 211 | 2026060001 | 1 | 0 | 2 (nnir=2026060001) |
| Fara rulaje | 1140848 | 2026 | 7 | 209 | 124 | 2 (ambele nnir=124) | 0 | 0 |
| Nota de inventar (blocare) | 1140716 | 2026 | 3 | 90101 | 2026030004 | 1 | 1 (nnir=2026030004) | 0 |
Note:
- ACT e pe linii (nu pe antet) - la COD 1140841 doar linia efectiv legata de rulaj are NNIR-ul
real, restul liniilor documentului au NNIR=0. Sincronizarea (
WHERE Nvl(nnir,0) = vechi) trebuie sa lase liniile cu 0 neatinse. - Nu exista nicio nota cu
id_set=90101sau cu rulaje inRUL_OBINVin luna curenta de lucru (AN=2026, LUNA=7) - alese din perioade anterioare. Editarea reala prinafisjurcom.do_modificae limitata la luna curenta (comun.vc2:2265-2268); testul instantiazafrm_modific2024direct (catest_repro_cnrcrt_footer.prg), cu cursoare construite pe AN/LUNA propriu notei, ocolind acel filtru - la fel ca precedentul deja acceptat inachizitie_import.
Stare implementare (livrata, 03.08.2026)
COMUN\clase\omodificari.vc2 (frm_modific2024):
Grid1.ColumnCount = 44,Column44.ControlSource = "nnir"(la runtime apare calificat automat de VFP cu aliasul cursorului:tact.nnir),ReadOnly = .F.- confirmat prin instantiere reala (nu doar citire de sursa).PROCEDURE sincronizeaza_nnir(tnNnirVechi, tnNnirNou)(omodificari.vc2:13762) - update petact/trul/trul_obinvundeNvl(nnir,0) = vechi, cu revenire pe recno. Propaga si valoarea 0 (stergerea NNIR) - nu exista gardaEMPTYpe valoarea noua.- Legare pe coloana:
Grid1.Column44.Text1.Whenretine valoarea veche inthisform.nnnirvechi;Grid1.Column44.Text1.LostFocusapeleazasincronizeaza_nnirsiThisform.Grid1.Refresh()Valida fost eliminat (la textbox valoarea nu ajunge in ControlSource decat DUPA ce Valid returneaza .T., deci nu propaga). Testul declanseazaLostFocus.
- Blocarea pentru
id_set = 90101(nota de inventar): inInit(omodificari.vc2:13654) SI reimpusa inGrid1.AfterRowColChange(14289-14292), dupaSetAll("ReadOnly", ...)- fara a doua,SetAllanuleaza blocarea la prima navigare in grid. ColumnOrder = 7in clasa, plus repozitionare la runtime inShow(), dupagridextra1.setup()(13729-13738) - preferintele de grid salvate per utilizator impingeau coloana noua la coada (veziCOMUN\docs\capcana_grid_preferinte_utilizator.md). Pozitia NU e o asertiune stabila intre masini; asertat tare in test:ControlSource = "nnir",ReadOnly(.F. normal / .T. pe id_set 90101), propagarea valorii.
Cerinte de mediu descoperite la construirea harness-ului (deja tratate in scripturile livrate)
COMUN\utile\Teste\test_init_env_auto.prg(generic) e de fapt specific ROACONT (gcAppPath, classlib-uri si proceduri hardcodateD:\ROA\ROACONT\) - inutilizabil pentru ROAGEST. S-a scrisCOMUN\utile\Teste\test_init_env_auto_roagest.prg, cu SET PATH/CLASSLIB/PROCEDURE reconstruite dinPrograme\roagest.prg.gcUserNametrebuie setat explicit inainte deoptiuni_firma(oinit_optiuni.prg) - altfelSCRIE_OPTIUNI(gcUserName)da "Operator/operand type mismatch" (PUBLIC nedeclarat ramane logic .F.).gcUserNamee schema/userul de conectare Oracle (Programe\roagest.prg:560,575)SCRIE_OPTIUNIil foloseste direct infrom <gcUserName>.optiuni, deci trebuiegcUserName = m.gcS, NU un nume de persoana (ex. 'MARIUS M' da ORA-00907, identificator invalid- incercare gresita initiala). Numele de persoana e
gcUserNameApp(variabila separata).
frm_modific2024faceSeek(..,'crsJtvaTemp','id_jtva')in ControlSource-ul coloanei de explicatie TVA a rulajelor (Column63) - evaluat la CONSTRUCTIA formularului. Fara cursorul deschis,CREATEOBJECT('frm_modific2024',...)pica cu "File 'crsjtvatemp.dbf' does not exist". Fix:update_jtva_coloane('', 'crsJtvaTemp', 6)(inCOMUN\programe\updateserver.prg:553) inainte de instantiere - construieste direct cursorul cu indexul cerut, fara pasii intermediari folositi de exemplul ROACONT (update_jtva_coloana/crsExplicatiiTVATemp, care oricum nu exista in ROAGEST).- Mock-ul
amessageboxtrebuie incarcat INAINTE detest_init_env_auto_roagest.prg(nu doar dupa, cum sugereaza exemplele dinachizitie_import) -optiuni_firmapoate afisa un dialog real dacaSCRIE_OPTIUNIraporteaza eroare, inainte sa apuce sa se incarce mock-ul "la coada". - La citirea unei coloane de grid prin ControlSource dintr-un cursor legat ca RecordSource, VFP
calificat automat campul simplu cu aliasul (
nnir->tact.nnir) - comparatiile exacte== 'NNIR'trebuie sa accepte si forma calificata. - Coloanele de grid nu sunt garantat numite
Column<N>- unele auNamecustom (ex.cAlespe pozitia 41 in acest grid); accesul dinamic la coloana trebuie facut prin colectiaGrid1.Columns(i), nu prin constructia textuala a numelui"column" + TRANSFORM(i). frm_modific2024.Grid1.AfterRowColChangeare propria logica de blocare pe sucursala (SetAll ReadOnly pe toate coloanele dacaNvl(gnIdSucursala,0) <> Nvl(tAct.id_sucursala,0)) - independenta de blocarea 90101, se declanseaza automat la pozitionare in grid. COD 1140835 (cazul obiecte de inventar) areid_sucursaladiferit de sesiunea de test (gnIdSucursala = NULL), deci Column44 ieseReadOnly=.T.in acest scenariu - nu e o eroare, e comportament existent, neplanificat de NNIR; sincronizarea tot functioneaza (apelul e direct, nu prin UI).- Termin reatribuie COD nou:
afisjurcom.do_modifica(comun.vc2:2444-2487) cheamaoscrie_in_fisierede DOUA ori - intai(2,.T.,llRul)(STERGE, marcheazasters=1pe COD-ul ORIGINAL, dinactactanneatins de editare), apoi(0,.T.,llRul)(SCRIE varianta editata sub COD nou, generat depack_contafin, sub AN/LUNA de sesiune curenta - nu pastreaza COD-ul/AN/LUNA notei editate). Verificarea si curatenia testului se fac dupa NNIR (marcaj distinct), nu dupa COD, si readuc nota originala lasters=0dupa test (pasul STERGE o dezactiveaza altfel permanent). - Salvarea reala cere tranzactie manuala explicita:
SQLSetProp(gnHandle,'Transactions',2)inainte de blocul STERGE+SCRIE+finalizeaza, apoiSQLCOMMIT(gnHandle)/SQLROLLBACK+SQLSetProp(...,1)dupa - echivalentul direct althisform.do_deschide_tranzactie()/do_inchide_tranzactie()dinafisjurcom(_frm_base.vc2:252-305, mostenite, apelate pe formularul de jurnal - nu pefrm_modific2024, deci invizibile la o privire doar pe clasa notei). Fara acest wrapping,oscrie_in_fisiere/finalizeaza_modificare_notaraporteaza succes dar nu se vede nimic persistat, nici in aceeasi sesiune.
Capcana: .FXP stale ascunde scenariile noi
VFP nu recompileaza .prg-ul daca exista un .FXP mai vechi - ruleaza tacut versiunea veche a
scriptului. Simptom: suita raporteaza PASS-uri corecte, dar scenariile adaugate dupa ultima
compilare nu apar deloc in log (verifica numarul de assert-uri, nu doar 0 FAIL). Sterge
.FXP-ul inainte de fiecare rulare.
Capcana: dialog modal "Enter the value for " in loc de eroare catchabila
O variabila memorie lipsa/umbrita folosita ca ?param intr-un SQL pass-through (SQLEXEC/
goExecutor.oExecuta) NU da o eroare VFP catchabila (ON ERROR) - deschide dialogul nativ
"View Parameter" ("Enter the value for "), MODAL, care blocheaza tot procesul headless la
nesfarsit si nu lasa nimic in log (spre deosebire de un REPLACE/expresie cu aceeasi variabila
lipsa, care DA eroare catchabila - vezi cazul gnIdUtil scapat o data ca PRIVATE neasignat).
Simptom: proces vfp9.exe care nu mai raspunde, fara .ERR, fara linie noua in log.
Remediu: garda explicita inainte de orice rulare care ajunge la cod ce foloseste ?param -
verifica TYPE(<nume>) == 'U' pe toate variabilele relevante (nu doar cele proprii testului, ci
si cele din codul apelat: oscrie_in_fisiere, pack_contafin/pack_sesiune, oinit_optiuni.prg)
si opreste testul cu FAIL clar in log daca lipseste ceva, inainte sa ajunga la SQLEXEC. Implementat
in test_nnir_sincronizare.prg (NnirGardaVariabile, apelata imediat dupa init mediu). TYPE()
returneaza 'X' (nu 'U') pentru NULL - o valoare NULL e un bind valid, doar variabila absenta
e problema.
Rezultat test complet (03.08.2026, pe binarul livrat)
33 PASS, 0 FAIL pe cele 6 scenarii: NIR, obiecte de inventar si nota fara rulaje (toate cu
salvare reala prin Termin + verificare in Oracle), blocare id_set=90101, NNIR -> 0, si blocare
id_set=90101 pe sucursala curenta. Baza de test verificata dupa rulare: cele 4 note originale
(1140841, 1140835, 1140848, 1140716) raman intacte (NNIR si sters la valorile initiale); notele
noi create de Termin (COD reatribuit) au fost marcate sters=1 de curatenia din test.
Scenariul 6 (INVENTAR2) exista pentru ca scenariul 4 ruleaza pe o nota din ALTA sucursala, unde
AfterRowColChange blocheaza oricum tot gridul - trecea din motivul gresit. Scenariul 6 aliniaza
gnIdSucursala la nota (llReadOnly iese .F.) si asertesteaza si ca restul coloanelor raman
editabile, altfel blocarea NNIR nu dovedeste nimic.