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
107 lines
7.0 KiB
Markdown
107 lines
7.0 KiB
Markdown
# 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).
|