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
This commit is contained in:
106
docs/cercetare/rec_garda_idset.md
Normal file
106
docs/cercetare/rec_garda_idset.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Cercetare: garda "id_set distincte in nota" din `do_editare_factura` vs discount editabil (#6)
|
||||
|
||||
Sursa: export proaspat `PACK_FACTURARE.pck` din `MARIUSM_AUTO@ROA_CENTRAL` (facut in aceasta
|
||||
sesiune, 08.08.2026), plus `SELECT text FROM user_views WHERE view_name = 'VACT_TOT'` pe aceeasi
|
||||
schema. Cod verificat: `COMUN\clase\ofacturare_comun.vc2`, metoda `do_editare_factura`.
|
||||
|
||||
## 1. Ce scrie `scrie_discount` si unde ajunge
|
||||
|
||||
`PACK_FACTURARE.scrie_discount` (pck:12859-13057): la intrare face
|
||||
`pack_facturare.nid_set := pack_facturare.nid_set + 5` (:12901), scrie randul `DISCOUNT` in
|
||||
`ACT_TEMP` cu `ID_SET = pack_facturare.nid_set` (deci +5), cheama `scrie_tva` (tot cu acelasi
|
||||
`nid_set` +5, deci si randul `TVA DISCOUNT` primeste +5) daca `V_CU_TVA = 1`, apoi **restaureaza**
|
||||
`pack_facturare.nid_set` la valoarea veche (:13054) inainte de a reveni la apelant. Deci exact
|
||||
randurile `DISCOUNT`/`TVA DISCOUNT` (si numai ele) ies cu `id_set` +5 fata de restul notei -
|
||||
confirmat pe cod, nu doar pe progres.md anterior.
|
||||
|
||||
`ACT_TEMP` se copiaza in `ACT` la commit-ul tranzactiei (mecanism comun, neschimbat). `vact_tot`
|
||||
(`user_views`, verificat direct) e un JOIN simplu peste `ACT`, cu `A.ID_SET` expus **neschimbat, ca
|
||||
atare** - nu exista nicio normalizare/filtrare de `id_set` in view. Deci orice factura ale carei
|
||||
randuri `ACT` au 2 `id_set` diferite le arata identic si `vact_tot`, si `actactan` (incarcat din
|
||||
`vact_tot` in `IncarcaCursoareModificareNota`, `COMUN\programe\ofacturare_editare.prg:53`, cu
|
||||
`ORDER BY id_act`).
|
||||
|
||||
**Descoperire suplimentara, relevanta pentru corectitudinea codului (nu doar garda)**: randurile
|
||||
`DISCOUNT`/`TVA DISCOUNT` scriu `ID_FACT = -1` (variabila locala `V_ID_FACT` initializata `-1` si
|
||||
niciodata reasignata in nicio ramura a `CASE`-ului din `scrie_discount`) si nu populeaza deloc
|
||||
`ID_FACTD` (coloana absenta din lista INSERT) - deci raman `NULL`. Un `Go Top` orb pe `actactan`
|
||||
poate ateriza pe un rand de discount si prelua `id_fact = -1` / `id_factd = NULL` in loc de valorile
|
||||
reale ale documentului, daca acel rand s-ar intampla sa fie primul in ordinea `id_act`. Cu codul
|
||||
actual randurile de discount se scriu mereu DUPA liniile de marfa (vezi pct. 2), deci `id_act` le
|
||||
pune ultimele si `Go Top` "merge" din intamplare - dar nu e o garantie de contract, e o coincidenta
|
||||
de ordine de scriere.
|
||||
|
||||
## 2. Cand se cheama `scrie_discount`
|
||||
|
||||
Confirmat 3 cai de apel la nivel de **document** (parametrul `V_DISCOUNT_FACTURA`, discountul de pe
|
||||
`VANZARI.DISCOUNT`), toate cu tiparul identic "`IF V_DISCOUNT_FACTURA <> 0 THEN scrie_discount(...)`"
|
||||
dupa bucla de linii:
|
||||
- `scrie_factura2` (pck:6009-6212, discount la :6992-7006) - calea facturii emise **direct** (nu din
|
||||
aviz), ex. `frm_facturare_articole`;
|
||||
- `scrie_factura_avize` (pck:6648-7076, discount la :6985-7007) - facturare din aviz;
|
||||
- (acelasi tipar exista si la nivel de **linie**, gardat de `pack_facturare.ndiscount_evidentiat = 1
|
||||
AND discount_unitar <> 0`, in `scrie_factura_avize` :6919-6935, `contabilizeaza_articol` :7496,
|
||||
`contabilizeaza_rata` :7594 - discount pe linie individuala, nu pe document, dar acelasi mecanism
|
||||
`id_set+5`).
|
||||
|
||||
Deci **orice factura emisa cu codul curent, cu discount de document nenul (`VANZARI.DISCOUNT <>
|
||||
0`), sau cu discount evidentiat pe cel putin o linie, iese cu 2 `id_set` distincte in `ACT`/
|
||||
`vact_tot`**. Nu e un caz marginal - e calea normala pentru orice factura cu discount.
|
||||
|
||||
Pe `MARIUSM_AUTO` (date de test): 3 facturi cu `VANZARI.DISCOUNT <> 0`, 0 cu >1 `id_set` distinct in
|
||||
`ACT` pe acelasi `cod` - verificat din nou in aceasta sesiune, acelasi rezultat ca la runda 2. Astea
|
||||
sunt cele 3 randuri vechi 2008/2014 mentionate deja in `progres.md`, scrise cu o versiune de pachet
|
||||
de dinainte de introducerea offset-ului `+5` (mecanism care, judecand dupa comentariile din cod,
|
||||
tine de o reforma ulterioara a contabilizarii discountului). Nu exista nicio factura in datele de
|
||||
test emisa cu discount **prin codul curent** - de-asta "0 cazuri in date" nu contrazice cazul
|
||||
posibil prin cod, doar arata ca setul de date nu-l acopera.
|
||||
|
||||
## 3. Verdict asupra garzii: **trebuia inlocuita, si a fost**
|
||||
|
||||
Garda originala (`lnIdSetDistinct > 1` => refuza editarea) ar fi respins editarea a exact clasa de
|
||||
facturi pe care decizia 17 (`docs\progres.md`, discountul de document editabil in #6) trebuie sa o
|
||||
acopere. Confirmat pe cod la pct. 1-2, nu doar pe date.
|
||||
|
||||
**Schimbare aplicata** in `do_editare_factura` (`COMUN\clase\ofacturare_comun.vc2:3781-3805`):
|
||||
in loc sa numere doar `id_set` distincte si sa refuze la >1, acum:
|
||||
- daca exista un singur `id_set` - neschimbat, editare admisa (comportamentul de dinainte de runda
|
||||
2);
|
||||
- daca exista exact 2 `id_set` distincte **si diferenta e exact 5** (relatia exacta scrisa de
|
||||
`scrie_discount`) - editare admisa, cu `id_set` **principal = cel mic** (liniile de marfa/servicii,
|
||||
nu randurile de discount) transmis catre `frm_modific2024` si folosit pentru `Locate For id_set =
|
||||
lnIdSet` (in loc de `Go Top` orb) la citirea `id_fact`/`id_factd` - evita exact capcana de la
|
||||
pct. 1 (a lua `id_fact=-1` de pe un rand de discount);
|
||||
- orice alta combinatie (>2 `id_set` distincte, sau exact 2 dar fara relatia +5) - refuza editarea,
|
||||
cu acelasi mesaj ca inainte; ramane un semnal real ca nota nu e "o factura curata" editabila pe
|
||||
aceasta cale.
|
||||
|
||||
`frm_modific2024` (`omodificari.vc2`) sustine asta structural: `Init(tnIdSet, ...)` seteaza
|
||||
`This.nid_set` dintr-un SINGUR parametru (folosit pentru predefinire/validari, `:5204-5251`), dar
|
||||
coloana `id_set` din grid e needitabila (`Column25.ReadOnly = .T.`) si update-ul de completare
|
||||
`UPDATE tact SET id_set = This.nid_set WHERE EMPTY(NVL(id_set,0))` (`:13365`) **nu suprascrie**
|
||||
randurile care au deja `id_set` populat - deci un cursor cu randuri mixte (principal + principal+5)
|
||||
trece nemodificat prin formular, atata timp cat `id_set`-ul "de referinta" transmis la `Init` e cel
|
||||
principal.
|
||||
|
||||
## Fisiere atinse
|
||||
|
||||
- `COMUN\clase\ofacturare_comun.vc2` (+ write-back `.vcx`/`.vct`, `txt2vcx.ps1 -AllowComun`,
|
||||
fidelity check OK) - garda inlocuita, `Go Top` -> `Locate For id_set = lnIdSet`.
|
||||
- `COMUN\utile\Teste\editare_factura\test_incarca_cursoare.prg` - `verifica_garda_idset_distinct`
|
||||
inlocuita cu `verifica_garda_idset`, care reproduce exact mecanica noii garzi pe 4 cursoare
|
||||
sintetice (1 id_set / 2 id_set +5 / 2 id_set fara relatia +5 / 3 id_set) - toate 4 + cele 2
|
||||
cazuri de regresie (`cod=1140888`, `cod=1140885`) au dat rezultatul asteptat la rulare headless
|
||||
(`vfp9.exe -A -T`).
|
||||
- Patch: `docs\diff_runda3_garda_idset.patch` (netrimis la commit, asteapta review).
|
||||
- Baseline: `COMUN\clase\ofacturare_comun.vc2.pre_runda3.bak`.
|
||||
|
||||
## Netestat
|
||||
|
||||
- Fluxul real UI (`frm_modific2024` deschis pe o factura cu discount de document) - nu exista
|
||||
candidat in datele de test (0 facturi cu discount emise prin codul curent, cf. pct. 2). Verificat
|
||||
doar prin harness fara UI, pe cursoare sintetice care reproduc exact forma datelor descrise de
|
||||
cod.
|
||||
- Write-back-ul real (`OSCRIE_IN_FISIERE` + `finalizeaza_modificare_nota`) pe un asemenea caz -
|
||||
neatins, la fel ca in rundele anterioare (evitat deliberat, nu scrie in schema de dev intr-un test
|
||||
automat).
|
||||
Reference in New Issue
Block a user