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

215 lines
14 KiB
Markdown

# 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.