Files
roafacturare/docs/cercetare/rec_s4b_document_test.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

14 KiB

S4b - documente reale cu divergenta (pentru testarea pe ecran a dialogului nou)

Cercetare read-only pe MARIUSM_AUTO. Niciun INSERT/UPDATE/DELETE, niciun COMMIT. Doar SELECT prin goExecutor.oExecute si apeluri directe la ConstruiestePropunereSincronizare('RUL_SURSA') (COMUN\programe\ofacturare_editare.prg:572), fara UI, fara scriere in tvd/trul reale (cursoare in memorie, aruncate dupa fiecare document). Niciun proces vfp9.exe ramas viu la finalul cercetarii (verificat cu tasklist, inainte si dupa fiecare rulare).

Metoda

  1. Prefiltru SQL aproximativ (nu verdictul final - doar ca sa nu testez document cu document toata baza), doua interogari peste vanzari/vrul_tot/vvanzari_articole (sters=0, neproforma):
    • candidati A: id_articol prezent doar in rulaj sau doar in articolele facturii (seturi diferite, MINUS in ambele sensuri) - candidati pentru Adaugare/Semnalare.
    • candidati B: articole comune la care cantitatea agregata difera (SUM(cant + IIF(id_tip_rulaj<>3,cante,0)) din vrul_tot, sters exclus, vs SUM(cantitate) din vvanzari_articole, sters exclus) - candidati pentru Modificare.
    • Reunite fara duplicate: 286 documente candidat din toata istoria bazei.
  2. Verdictul real: pentru fiecare din cei 286 candidati, incarcare completa a documentului exact ca in fluxul de editare (IncarcaCursoareModificareNota -> IncarcaVanzareDinNota -> IncarcaArticoleFactura), apoi apel direct ConstruiestePropunereSincronizare('RUL_SURSA') si citirea cursorului rezultat. Toti cei 286 candidati au fost testati (nu doar un esantion).
  3. Sweep suplimentar, exhaustiv, fara prefiltru, pe toate documentele din luna/anul curent (gnAn/gnLuna = 2026/8) care au rulaje - 5 documente in total - ca sa acopar si un eventual caz "doar diferenta de pret, cantitate si set de articole identice", pe care prefiltrul de mai sus nu-l prinde daca articolul respectiv e singurul din document. Confirmare: aceleasi 2 documente gasite si de acest sweep exhaustiv (fara documente noi ratate de prefiltru in luna curenta).

Comanda de reprodus (scripturile raman in scratchpad, nu in proiect):

"C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T "<script>.prg"

Scripturi si loguri (in scratchpad-ul acestei sesiuni, nu in docs/): rec_s4b_finder.prg / rec_s4b_finder_log.txt (cei 286 candidati, toata istoria), rec_s4b_finder_luna_curenta.prg / _log.txt (sweep exhaustiv luna curenta), rec_s4b_finder_idfix.prg / _log.txt (diagnostic id_articol, mai jos).

Rezultat

Din 286 candidati testati cu functia reala, 21 de documente produc cel putin o linie Modificare/Adaugare. Niciunul din cele 21 nu combina Modificare si Adaugare si Semnalare in acelasi document - cel mai bogat caz gasit are Modificare + doua/trei linii N-A (context, nu aplicabile). Zero documente cu Semnalare-efectiv-in-cursor au aparut printre cele 21 (Semnalare cere articol prezent doar in tvd, stocat - in datele astea, articolele "doar in tvd" gasite erau toate nestocate, deci cad pe N-A inaintea verificarii de Semnalare).

Foarte important pentru testarea pe ecran: fluxul real de editare (do_editare_factura / afisjurcom.do_modifica) accepta la editare doar documente din luna/anul curent al sesiunii (garda (an*12+luna) = (gnAn*12+gnLuna), verificata in test_s8_matrice_surse.prg). Azi (11.08.2026), gnAn/gnLuna = 2026/8. Din cele 21 documente cu Modificare/Adaugare, doar 2 sunt in luna curenta - restul de 19 nu se pot deschide acum prin formularul real (ar trebui alt gnAn/gnLuna de sesiune sau alta data de sistem ca sa fie editabile).

Cele 2 documente editabile ACUM (luna curenta, 2026/8)

#1 - id_vanzare=1050, cod=1140895, tip=1, id_fact=8009660, an/luna=2026/8 (cel mai bogat dintre cele doua - 2 linii in propunere)

id_articol denumire codmat cant_veche cant_noua pret_vechi pret_nou actiune motiv
3598545102 ACOPERIRE STILP B IVECO IV93900901 2 0 121.0100 0 Modificare
315554536 ACOPERIRE FAR VOLVO FH12 11.00003 1 2 302.5000 302.5000 N-A Mai multe randuri RUL active pe acelasi articol, verificati manual

#2 - id_vanzare=1052, cod=1140921, tip=22 (aviz), id_fact=8009677, an/luna=2026/8

id_articol denumire codmat cant_veche cant_noua pret_vechi pret_nou actiune motiv
3598545102 ACOPERIRE STILP B IVECO IV93900901 1 0 23.1100 0 Modificare

Constatare suplimentara, verificata pe date - overflow id_articol pe articolul IV93900901

id_articol real (din nom_articole, verificat cu select id_articol from nom_articole where codmat = 'IV93900901') = 3598545102 - depaseste limita reprezentabila de campul id_articol I (Integer VFP, 4 octeti, max 2147483647) din cursorul propunere_sincronizare (CREATE CURSOR propunere_sincronizare (id_articol I, ...), ofacturare_editare.prg:587). Verificat direct: STR(id_articol,15) pe randul citit din propunere_sincronizare dupa ConstruiestePropunereSincronizare tot arata markerul de depasire VFP (***************), nu valoarea - deci valoarea stocata in cursor e trunchiata/deja corupta, nu doar o problema de afisare in scriptul meu de logare (am verificat cu doua latimi diferite, 15 si 20, acelasi rezultat).

Consecinta verificata in cod (nu doar presupusa): AplicaSincronizareArticole citeste lnIdArticol = id_articol direct din propunere_sincronizare (linia 790) si il foloseste in AplicaModificareTvd/AplicaAdaugareTvd/AplicaModificareTrul pentru LOCATE FOR id_articol = m.tnIdArticol pe tvd/trul (liniile 836, 874, 910) - cursoare unde id_articol vine direct din Oracle, deci pastreaza valoarea reala (3598545102). Cu valoarea din campul I deja trunchiata, LOCATE nu are cum sa gaseasca randul corect pe acest articol. Ambele documente editabile acum (#1 si #2 de mai sus) au randul lor de Modificare exact pe acest articol - deci propunerea s-ar afisa corect in dialogul nou, dar AplicaSincronizareArticole ar putea sa nu scrie efectiv modificarea pe acest rand quand se apasa "Aplica". Nu am testat efectiv AplicaSincronizareArticole pe date reale (ar fi scriere, chiar daca doar in cursor in memorie, si nu era ceruta cercetarea de aplicare) - constatarea e din citirea codului + valoarea reala confirmata din Oracle, nu din rulare.

Alte documente cu Modificare/Adaugare, NU editabile acum (alta luna/an) - pentru context

Cele mai "curate" (fara efectul de trunchiere de mai sus, sau cu cantitate neschimbata si doar pretul diferit intre doua valori nenule - nu artefact de zero):

id_vanzare=943, cod=1140122, tip=-3, id_fact=8007141, an/luna=2022/4 - singurul document din cele 21 cu Adaugare (nu Modificare):

id_articol denumire codmat cant_veche cant_noua pret_vechi pret_nou actiune motiv
(overflow, vezi mai sus) ADAPTOR SATACADU1 0 1 0 0 Adaugare

id_vanzare=631, cod=1138622, tip=3, id_fact=8001320, an/luna=2014/1 - singurul caz din toata cautarea cu Modificare "curata": cantitate neschimbata (1->1), doar pretul difera intre doua valori nenule:

id_articol denumire codmat cant_veche cant_noua pret_vechi pret_nou actiune motiv
(overflow, vezi mai sus) ACOPERIRE STILP B IVECO IV93900901 1 1 24.9200 112.1600 Modificare
315554536 ACOPERIRE FAR VOLVO FH12 11.00003 10 20 124 558 N-A Mai multe randuri RUL active pe acelasi articol, verificati manual

id_vanzare=953, cod=1140144, tip=23, id_fact=8007201, an/luna=2022/5 si id_vanzare=887, cod=1139941, tip=23, id_fact=8006845, an/luna=2021/12 - alt tipar de Modificare curata pe cantitate (neschimbata), doar pretul difera (articol "COCA COLA 0.33L", fara overflow de id_articol):

document id_articol cant_veche cant_noua pret_vechi pret_nou actiune
953 (overflow diferit, neverificat individual) 1 1 11.9000 0 Modificare
887 (overflow diferit, neverificat individual) 1 1 3.5100 0 Modificare

Restul de 14 documente (id_vanzare 976, 937, 793, 682, 681, 1006, 985, 905, 881, 695, 686, 685, 1013, 1014) urmeaza acelasi tipar predominant: un singur articol RUL cu un rand id_tip_rulaj=3 (diferenta de pret) al carui cant propriu e 0 - agregarea E.3 exclude cante pentru randurile tip 3, deci cant_articol/val_articol ies 0, iar propunerea arata "Modificare, cantitate/pret -> 0". E un rezultat corect al formulei documentate (nu o eroare de interogare), dar nu e un exemplu "tipic" de sincronizare cantitate/pret - lista completa, cu toate liniile, e in rec_s4b_finder_log.txt (liniile cu GASIT).

Ce nu am gasit / limite ale cautarii

  • Zero documente cu Modificare + Adaugare in acelasi document, din cei 286 candidati testati (acoperire 100% pe cele doua euristici de prefiltru).
  • Zero documente cu actiune efectiv Semnalare in cursorul rezultat, din aceiasi 286.
  • Prefiltrul SQL (candidati A/B) nu garanteaza acoperire completa: un document la care UN SINGUR articol difera doar prin pret (cantitate identica) si care e si singurul articol divergent din acel document (fara alt articol cu set/cantitate diferita in acelasi document care sa-l fi adus in lista de candidati) ar fi ratat de ambele euristici. Nu am facut un scan exhaustiv pe pret peste toata istoria (ar fi insemnat sute de mii de documente testate cu functia reala, cost prea mare pentru scopul cercetarii) - doar pe luna curenta (5 documente, exhaustiv, fara ratari).
  • Nu am testat AplicaSincronizareArticole (scrierea efectiva in tvd/trul in memorie) pe niciun document real - cercetarea ceruta a fost doar pentru ConstruiestePropunereSincronizare.

Verificari de siguranta

  • Toate interogarile au fost SELECT prin goExecutor.oExecute; niciun INSERT/UPDATE/DELETE, niciun goExecutor.oExecuta (DML) apelat in aceasta cercetare.
  • Niciun COMMIT/ROLLBACK - nicio tranzactie deschisa (nu s-a apelat MyDeschideTranzactie).
  • Niciun formular deschis, nicio tasta/click injectat.
  • tasklist verificat inainte si dupa fiecare rulare vfp9.exe -A -T: zero procese vfp9.exe ramase vii la finalul cercetarii.

Precizia coloanelor identificator

Interogare ALL_TAB_COLUMNS, read-only, pe coloanele identificator din cursoarele de editare a facturii. Script: rec_s4b_precizie_coloane.prg, log: rec_s4b_precizie_coloane_log.txt.

tabela/view coloana tip Oracle precizie/scala
VVANZARI_ARTICOLE ID_VANZARE / ID_VANZARE_DET / ID_ARTICOL / ID_JTVA_COLOANA / ID_VALUTA / ID_VANZARE_SET NUMBER 10/0
VVANZARI_ARTICOLE ID_GESTIUNE NUMBER 20/0
VVANZARI_ARTICOLE TAXCODE NUMBER 6/0
VVANZARI_ARTICOLE STERS NUMBER 1/0
NOM_ARTICOLE ID_ARTICOL NUMBER 20/0
VRUL_TOT ID_ARTICOL / ID_TIP_RULAJ / ID_VALUTA NUMBER 10/0
VANZARI_DETALII ID_VANZARE (MARIUSM_AUTO) / ID_VANZARE_DET / ID_ARTICOL / ID_JTVA_COLOANA / ID_VALUTA / ID_VANZARE_SET NUMBER 10/0
VANZARI_DETALII ID_VANZARE (schema ACN) NUMBER 20/0 (alta schema, acelasi nume de tabela)
VANZARI_DETALII ID_GESTIUNE NUMBER 20/0

Valoare maxima efectiva in date + randuri care depasesc 2147483647 (max VFP I, Integer 4 octeti):

coloana max efectiv randuri > 2147483647 total randuri
NOM_ARTICOLE.ID_ARTICOL 4294511702 5795 6457 (89.8%)
VRUL_TOT.ID_ARTICOL 4294511700 6432 10293 (62.5%)
VANZARI_DETALII.ID_VANZARE_DET 1609 0 1362
VANZARI_DETALII.ID_VANZARE 1060 0 1362

Concluzie factuala: id_articol e afectat masiv (nu e un caz izolat) - aproape 9 din 10 articole din NOM_ARTICOLE si peste 6 din 10 randuri din VRUL_TOT au id_articol peste limita unui camp VFP I. Valorile maxime (4294511700-4294511702) sunt foarte aproape de 2^32 (4294967296), consistent cu un id generat in intervalul unsigned pe 32 de biti, nu cu o secventa Oracle standard. Precizia declarata in Oracle (NUMBER(10) sau NUMBER(20)) e suficienta pentru aceste valori - problema e strict de partea VFP (campul I), nu de precizia coloanei Oracle. id_vanzare/id_vanzare_det, in schimb, sunt mici (sub 2000) in datele curente si nu au niciun rand peste limita - nu inseamna insa ca schema le limiteaza (ambele sunt tot NUMBER(10)/NUMBER(20) dupa schema, fara CHECK constraint vizibil aici care sa impuna un plafon sub 2^31).

Restul campurilor I din tvd

Cursorul tvd (CreeazaCursorArticoleGol, ofacturare_editare.prg:276) mai declara I (Integer VFP, 4 octeti, max 2147483647) pe: id_gestiune, id_valuta, id_jtva_coloana, taxcode, sters, id_vanzare_set (plus id_vanzare/id_vanzare_det, deja verificate mai sus - fara depasiri). Toate cele 6 coloane cerute exista in VVANZARI_ARTICOLE sub numele exact. Script: rec_s4b_restul_campuri_i.prg, log: rec_s4b_restul_campuri_i_log.txt.

coloana sursa max efectiv randuri > 2147483647
ID_GESTIUNE VVANZARI_ARTICOLE (facturi existente) 23 0 din 1362
ID_GESTIUNE NOM_GESTIUNI (nomenclator complet, NUMBER(5,0)) 29 0 din 28
ID_VALUTA VVANZARI_ARTICOLE 3 0 din 1362
ID_JTVA_COLOANA VVANZARI_ARTICOLE 188 0 din 1362
ID_VANZARE_SET VVANZARI_ARTICOLE 4 0 din 1362
TAXCODE VVANZARI_ARTICOLE 310354 0 din 1362
STERS VVANZARI_ARTICOLE 1 0 din 1362

Raspuns la intrebare: nu, niciunul din aceste 6 campuri nu are, azi, vreo valoare peste 2147483647, si niciunul nu e nici macar apropiat de limita (cel mai mare, TAXCODE, e la 310354 - de ~6900 de ori sub prag). Spre deosebire de id_articol (NUMBER(10)/NUMBER(20) cu valori reale pana la ~4.29 miliarde), id_gestiune are un plafon de schema explicit jos: NOM_GESTIUNI.ID_GESTIUNE e declarata NUMBER(5,0) - max teoretic posibil 99999, cu 4-5 ordine de marime sub limita I. Nu exista un risc plauzibil pe termen scurt pentru niciunul din aceste 6 campuri; id_articol ramane singurul camp I din tvd cu depasire reala confirmata in date.