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

353 lines
21 KiB
Markdown

# Plan #6 — editarea unei facturi emise, netrimisa inca in eFactura
Sursa: `COMUN\docs\todos.txt` punctul 6.
Ordine de executie: **al treilea**, dupa #8 si #7.
> **Stare: IN LUCRU.** S1-S6 gata, S5 comis in git pe 10.08.2026. Ramase: **S4b** partial (actiunea
> de sincronizare), **S7** neatins, **S8** partial, **S9** partial. Starea la zi si ordinea
> recomandata: **`docs\handoff_punct6_dupa_s5.md`**. Deciziile 38-41, care **corecteaza S5 fata de
> ce scrie mai jos**: `docs\handoff_s5.md`.
## Cerinta si directia aleasa
Factura emisa trebuie sa poata fi corectata cat timp nu a plecat in eFactura
(`anaf_efactura.id_fact`). Problema: notele contabile si rulajele se genereaza complicat la emitere,
iar editarea de azi nu le sincronizeaza.
**Varianta respinsa: regenerarea prin re-emitere.** Emiterea face verificari de stoc si alte
protectii dependente de tipul documentului (lista de preturi, comanda, contract, retur, invoice); la
regenerare acestea ar esua pe date care intre timp s-au schimbat.
**Varianta aleasa: editare directa in `frm_modific2024`**, extins cu partea de
`vanzari`/`vanzari_detalii`, ca sa nu se duplice un formular de editare de note si rulaje.
### Doua puncte de intrare, o singura implementare (decizie Marius, 06.08.2026)
Editarea unei facturi de vanzare trebuie sa fie posibila **si din ROACONT > registru jurnal >
modificare**, adica exact prin procedura existenta de editare de note contabile / rulaje — nu doar
dintr-o actiune noua in formularul de facturi din ROAFACTURARE.
Consecinta pentru arhitectura: lucrarea **nu** e "cod apelant nou in ROAFACTURARE", ci
**extinderea clasei comune `frm_modific2024` + a partii server-side**, de unde ambele puncte de
intrare o primesc automat. Cazul "documentul curent e o factura de vanzare" se detecteaza in
formular, nu in apelant.
### `ID_FACT` nu se schimba — by design
`id_fact` se genereaza la introducerea documentului, din `nract` + `dataact`, si **ramane acelasi la
modificarea notelor contabile**; se schimba doar `cod`-ul setului de note/rulaje. Legatura initiala
cu `ACT`/`RUL` era `vanzari.cod`, dar intre timp s-a adaugat si perechea
`vanzari.id_fact` / `act.id_fact` / `rul.id_fact` / `documente.id_doc`, folosita de alte
functionalitati.
Deci `VANZARI.ID_FACT` **ramane neatins** la editare, iar realinierea priveste exclusiv `cod`-ul.
Orice ipoteza de rescriere a lui `id_fact` e gresita si a fost scoasa din plan.
## Ce s-a stabilit din cod
### Formularul exista deja si e direct utilizabil
`frm_modific2024` e o **clasa `.vcx`** (nu `.scx` monolitic), definita in
`COMUN\clase\omodificari.vc2` (clasa incepe la `:6375`, metodele proprii `:12200-15319`). E deja in
COMUN-ul ROAFACTURARE, deci **nu trebuie portata nimic**: `COMUN\clase` e deja in `SET CLASSLIB` /
`SET PROCEDURE`, iar clasa foloseste doar globale standard (`gnAn`, `gnLuna`, `goExecutor`, `gcs`,
`gnIdUtil`, `glLunaInchisa`), toate setate de `Programe\roafacturare.prg`.
Formularul editeaza **doar cursoare in memorie**; `do_termin` (mostenit din `_frmbase`) nu scrie
nimic, doar seteaza `gnButon=1` si inchide. Scrierea e treaba codului apelant.
Acelasi formular e si "modificare registru jurnal" — apelat din `afisjurcom.do_modifica`
(`comun.vc2:2222-2563`). Fluxul e deja documentat in
`D:\ROA\ROAGEST\COMUN\docs\flux-modificare-stergere-nota-jurnal.md`, verificat linie cu linie.
### Scrierea in ACT/RUL: o singura cale posibila
**Nu exista niciun `UPDATE`/`DELETE` direct pe `ACT` sau `RUL` in tot codul VFP** (cautat explicit).
Singura cale: cursoare -> `ACT_TEMP`/`RUL_TEMP` (INSERT-uri in `oscrie_in_fisiere.prg:127-136`,
`:272-274`) -> `PACK_CONTAFIN.init_scriere_act_rul_local` / `final_scriere_act_rul_local`.
Editarea **nu suprascrie randul vechi**: il marcheaza `STERS = 1` si scrie un document nou, cu `cod`
nou. Comportament intentionat, nu efect secundar.
### Sincronizarea cu VANZARI exista deja partial — si aici e lucrarea
`pack_contafin.finalizeaza_modificare_nota` (`COMUN\docs\PACK_CONTAFIN.pck:8601-8651`) apeleaza deja
`pack_facturare.actualizeaza_vanzari(cod_vechi, cod_nou)` cand `cod`-ul exista in `vanzari`
(iar `finalizeaza_stergere_nota` apeleaza `sterge_din_vanzari`).
Dar `actualizeaza_vanzari` (`ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql:15951-15961`) face **exclusiv**
realinierea legaturii:
```sql
UPDATE VANZARI_DETALII SET STERS = 0
WHERE ID_VANZARE IN (SELECT ID_VANZARE FROM VANZARI WHERE COD = V_COD_VECHI);
UPDATE VANZARI SET COD = V_COD_NOU, STERS = 0 WHERE COD = V_COD_VECHI;
```
Nu recalculeaza sume, nu atinge cantitati/preturi din `VANZARI_DETALII`, nu reactualizeaza totalurile
denormalizate din `VANZARI` (`total_fara_tva`, `total_tva`, `total_cu_tva`, `valoare_achizitie`,
`discount_tva`). Comentariul din cod (`:15954`) anticipeaza chiar aceasta extensie: *"de modificat in
caz ca il las sa stearga manual inregistrari din VANZARI_DETALII"*.
**Deci: azi, o editare de nota rescrie corect contabilitatea si pastreaza legatura cu factura, dar
lasa sumele facturii la valorile vechi.** Exact divergenta pe care o descrie cerinta.
### Calea de scriere in VANZARI_DETALII (stabilit 08.08.2026)
Detaliu complet: `docs\cercetare\rec_cale_vanzari_detalii.md`.
La **emitere**, liniile nu se scriu din VFP in `VANZARI_DETALII`. VFP cheama, per linie din
`crsfactura`, `pack_facturare.adauga_articol_factura` (`ofacturare.vc2:14069-14091`), care insereaza
in `VANZARI_DETALII_TEMP`; trecerea in tabela reala o face `scrie_in_vanzari`, cu un
`INSERT ... SELECT FROM VANZARI_DETALII_TEMP`, potrivit pe `(id_comanda, numar_act)`.
**`adauga_articol_factura` nu e reutilizabila la editare**: ramifica pe `pack_facturare.ntip`
(stare de sesiune) si **re-deriva pretul, TVA-ul si valuta din documentul-sursa** (comanda, aviz,
contract). La o factura deja emisa nu exista document-sursa de re-derivat, iar valorile editate de
utilizator ar fi suprascrise. `VANZARI_DETALII_TEMP` e GTT `ON COMMIT DELETE ROWS`, deci si
umplerea, si consumul ar trebui sa stea in aceeasi tranzactie.
**Calea aleasa pentru #6: scriere directa in `VANZARI_DETALII`**, fara sa treaca prin TEMP —
`UPDATE` tintit pe `ID_VANZARE_DET` pentru linii modificate, `STERS = 1` pentru linii scoase,
`INSERT` pentru linii adaugate. Modelul exista deja: `modifica_explicatie_articol`. `ID_VANZARE_DET`
vine automat dintr-un trigger `BEFORE INSERT` pe `SEQ_VANZARI_DETALII`, deci un `INSERT` de
oriunde primeste cheia corect.
Alternativa (refolosirea TEMP) ar fi cerut fie atingerea lui `adauga_articol_factura` /
`scrie_in_vanzari` — cod critic de emitere — fie duplicarea lor, adica exact tiparul care a produs
problema reparata la #8.
**Stergerea unei singure linii nu exista azi**: `sterge_factura` / `sterge_proforma` marcheaza
`STERS = 1` pe toate liniile documentului deodata. E functionalitate noua pentru #6.
### Punctul de agatare si garda existenta
- Sablonul arhitectural cel mai apropiat e `frm_facturi.do_sterge`
(`COMUN\clase\ofacturare_comun.vc2:4503-4719`): incarca cursoarele pe `cod`, porneste tranzactie
manuala, ruleaza `oscrie_in_fisiere`, apoi `pack_contafin.finalizeaza_stergere_nota`. Se cloneaza
acesta, **nu** `do_modifica` (care doar deschide un formular de metadate).
- Garda "nu edita daca a plecat in eFactura" exista deja, dar **in `do_modifica`, nu in
`do_sterge`** (`ofacturare_comun.vc2:4426-4430`: `select count(*) from anaf_efactura where
id_fact = ...` + `poRec.sters = 0 AND NVL(pnEFactura,0) = 0`). Azi e o simpla conditie de `If`
care deschide sau nu dialogul; pentru editare trebuie sa devina un `Return` cu mesaj, ca
celelalte garzi, si sa fie extrasa in `COMUN\programe\` ca sa fie apelabila si din `afisjurcom`,
care nu o are deloc.
- Gating-ul de drepturi pe `frm_facturi` **nu** e prin `nid_cw`, ci prin `This.lactiv3` / `lactiv4` +
tokeni in globala `gcAcces`. (Difera de `ofundal_facturare`, unde se foloseste `nid_cw` — de nu
confundat cu planurile #11/#10.)
## Stories
### S1 — Actiunea noua pe formularul de facturi (punctul de intrare din ROAFACTURARE)
Al doilea punct de intrare, ROACONT > registru jurnal > modificare, exista deja si nu are nevoie de
actiune noua — dar garzile de mai jos trebuie sa fie in formular sau in codul comun, ca sa se aplice
si acolo, nu doar in ROAFACTURARE.
Cloneaza structura din `do_sterge` (`ofacturare_comun.vc2:4503-4719`) intr-o actiune noua de editare:
garda eFactura + `sters=0` (refolosita din `:4428-4432`), plus garzile pe care `do_modifica` nu le are
azi dar `do_sterge` le are si care devin obligatorii cand se ating sumele: **luna inchisa**
(`glLunaInchisa`, `:4518-4520`), **luna curenta** (`:4543-4546`) si **referinte de incasari/plati**
(`ReferinteDocumenteNota`, `:4565-4569`).
Drepturi: **sub tokenul "3" existent** (decizia din 08.08.2026) — butonul nou se adauga in
`cbuton3` alaturi de `but_modifica1`/`But_modifica2`, si actiunea trece prin `This.lactiv3`. Fara
token nou, fara interventie in tabelele de drepturi.
*Gata cand:* actiunea apare, e vizibila doar cu drept, si refuza corect facturile trimise in
eFactura, sterse, din luna inchisa sau referentiate.
### S2 — Incarcarea cursoarelor notei
Dupa modelul `afisjurcom.do_modifica` (`comun.vc2:2222-2563`): incarca `vact_tot` / `vrul_tot` /
`vrul_obinv_tot` in cursoarele `tact` / `trul` / `trul_obinv`, filtrate pe `cod` + `an` + `luna`
(acelasi filtru ca la stergere).
*Gata cand:* pentru o factura data se incarca exact randurile ei de nota si de rulaj.
*Depinde de:* S1.
### S3 — Deschiderea `frm_modific2024` pe factura
Instantiaza clasa din `COMUN\clase\omodificari.vc2` cu cursoarele din S2. Cod apelant ~40 de linii,
fara modificari in clasa.
*Gata cand:* formularul se deschide din ROAFACTURARE si arata nota facturii; `gnButon=1` la
confirmare.
*Depinde de:* S2.
### S4 — Pagina noua de articole factura in `frm_modific2024`
Editarea randului din `vanzari` si a randurilor din `vanzari_detalii` intra **in acelasi formular**,
pe o pagina noua a pageframe-ului existent, dupa modelul paginilor de rulaje.
**Scop complet (decizia lui Marius, 08.08.2026)**: linii **sterse, adaugate si modificate**
(articol, cantitate, pret, flagul `pret_cu_tva` — vezi planul #7), plus **discountul de document**
(`VANZARI.DISCOUNT`) pe zona de antet.
**Fara plafon de cantitate si fara verificare de stoc.** Corectia unei facturi emise e
raspunderea utilizatorului; formularul nu-l opreste. Asta inchide intrebarea lasata deschisa de #7
(de unde vine plafonul cand cursorul de stoc din formularul de compunere nu exista) — raspunsul e
ca nu mai e nevoie de plafon. In schimb, obligatia se muta pe **helpere si verificari**, vezi S4b:
totaluri calculate, propuneri de sincronizare si semnalarea necorelarilor cu notele si rulajele.
**Drepturi**: sub tokenul "3" existent (modificare). Fara token nou.
**Liniile din seturi** se trateaza ca orice alta linie — fara ramura speciala in formular si fara
blocarea facturilor care le contin. Consecinta pentru S5: agregarea din `scrie_in_vanzari` are
ramura proprie pe `VANZARI_SETURI_TEMP`, deci recalculul trebuie sa acopere si liniile de set,
altfel totalurile diverg tacut exact pe facturile cu seturi.
Ancora concreta: `pgfArticole` din `omodificari.vc2` are azi
`PAGE1.Caption = "Rulaje materii prime, materiale, marfuri, obiecte inventar (303)"` cu `grdRulaje` si
`PAGE2.Caption = "Rulaje obiecte inventar in folosinta (8039)"` cu `grdRulajeObinv` (`:8598-8601`).
Se adauga `PAGE3` cu un grid de articole legat de cursorul de `vanzari_detalii`, plus zona de antet
pentru randul din `vanzari`.
Pagina se afiseaza **doar cand documentul curent are rand in `vanzari`**; altfel formularul arata
exact ca azi. Asta e conditia ca registrul jurnal din ROACONT/ROAGEST sa nu se schimbe pentru
documentele care nu sunt facturi.
Respecta `COMUN\docs\conventie_ux_formulare.md` si, pentru 3 griduri,
`COMUN\docs\capcana_grid_controlsource.md`. Clasa e in `COMUN\`, deci schimbarea e **cross-project**.
*Gata cand:* pagina apare pe o factura de vanzare deschisa din ambele puncte de intrare, si lipseste
pe un document care nu e factura.
*Depinde de:* S3.
### S4b — Helpere, totaluri si verificari de corelatie, **explicit, niciodata silentios**
Cerinta lui Marius: preturile si cantitatile din rulaje si cele din articolele facturii se pot
desincroniza la editare, iar programul **nu** are voie sa le alinieze pe tacute. Trebuie sa arate
utilizatorului ce nu se potriveste si sa **propuna** sincronizarea, ca actiune constienta.
Odata cu decizia din 08.08.2026 (S4 fara plafon si fara verificare de stoc), **S4b devine partea
grea a lui #6**: singura plasa de siguranta a utilizatorului. Nu mai e un adaos peste S4, ci
conditia care face editarea libera acceptabila. Acopera si liniile **adaugate sau sterse**, nu doar
valorile modificate.
Continut:
- **Totaluri de control vizibile in formular**, pe trei surse: suma din `RUL`, suma din
`VANZARI_DETALII` si suma din `ACT`. Cand cele trei nu coincid, diferenta se vede, nu se ascunde.
- **Indicator de stare a sincronizarii** (label/culoare), nu doar un mesaj la salvare.
- **Actiune explicita de sincronizare**, cu enumerarea liniilor care s-ar modifica si a valorilor
vechi/noi inainte de aplicare.
- Sincronizarea nu se declanseaza automat la `do_termin`.
Directia sincronizarii (rulajul e sursa sau articolul e sursa) se stabileste la implementare, dar
alegerea trebuie sa fie a utilizatorului, nu implicita.
*Gata cand:* o editare care desincronizeaza cele trei surse produce un indicator vizibil si o
propunere enumerata, iar refuzul propunerii lasa datele nemodificate.
*Depinde de:* S4.
### S5 — Scrierea sumelor editate in VANZARI (partea Oracle)
**Procedura sora noua** (ex. `recalculeaza_totaluri_vanzari`), apelata din
`finalizeaza_modificare_nota` dupa `actualizeaza_vanzari` — **nu** extinderea in-place a lui
`actualizeaza_vanzari`. Motivul: `actualizeaza_vanzari` ruleaza azi la ORICE editare de nota al
carei `cod` exista in `VANZARI`, inclusiv din registrul jurnal ROAGEST/ROACONT pe editari care nu
ating sumele; recalculul in-place ar propaga riscul in toata suita. Detaliu si sursa curenta:
`docs\cercetare\rec_s5_oracle_vanzari.md`.
Refoloseste acelasi calcul ca `scrie_in_vanzari` — nu o formula paralela, altfel cele doua cai
diverg exact ca in problema de la #8. Partea per-linie e **deja extrasa** in
`calculeaza_total_fara_tva_fact` / `calculeaza_total_tva_fact`, care ramifica deja pe
`PRET_CU_TVA`; de extras ramane doar blocul de **agregare**, parametrizat pe sursa
(`VANZARI_DETALII_TEMP` la emitere, `VANZARI_DETALII` la editare).
Doua constrangeri gasite la cercetare:
- **`SERIE_INCASAT` / `NR_INCASAT` / `SUMA_INCASAT` / `TIP_INCASAT` nu se recalculeaza.** Vin din
stare de sesiune specifica emiterii unei facturi-cu-incasare si n-au sursa persistenta; o copiere
naiva a intregului `UPDATE` din `scrie_in_vanzari` le-ar pune `NULL` la fiecare editare, rupand
legatura cu incasarea. Se scriu doar cele 11 coloane de totaluri/curs.
- **`VALVAL` / `TVAVAL` / `TOTVAL`** (totaluri in valuta) intra in recalcul, desi planul initial nu
le enumera: sunt in acelasi bloc de agregare, costa zero in plus si altfel raman incoerente pe
documentele in valuta.
**Discountul de document e editabil** (decizia din 08.08.2026), deci intra ca valoare noua in
recalcul, nu se citeste ca invariant din `VANZARI.DISCOUNT`.
Script de migrare conform `COMUN\docs\scripturi-migrare-db.md`: CRLF, idempotent, nivel Oracle 10.2,
`versiune_db.txt` actualizat.
*Gata cand:* dupa o editare de cantitate, `total_fara_tva`/`total_tva`/`total_cu_tva` din `VANZARI`
corespund sumei liniilor.
*Depinde de:* S4.
### S6 — Legaturile care depind de `cod`
Editarea scrie un document nou cu `cod` nou, iar `actualizeaza_vanzari` realiniaza `VANZARI.COD`.
`VANZARI.ID_FACT` **nu se schimba** (by design — vezi mai sus), deci tot ce se leaga prin `id_fact` /
`id_doc` ramane valid: `anaf_efactura`, `documente`, si perechile `act.id_fact` / `rul.id_fact`.
**Inchis pe cod la 08.08.2026** (`docs\cercetare\rec_s5_oracle_vanzari.md`, sectiunea C): toate
legaturile trec prin `ID_FACT` (`ACT.id_factd`/`id_factc`, `DOCUMENTE.ID_DOC`,
`ANAF_EFACTURA.ID_FACT`) sau prin `ID_VANZARE` (`vanzari_coresp`, `marcheaza_facturat`), niciodata
prin `cod`. `actualizeaza_vanzari` rescrie doar `COD` pe acelasi rand — `ID_VANZARE` nu se schimba
niciodata. `ReferinteDocumenteNota` e o garda pre-editare, nu o legatura persistenta. **Fara lucru
suplimentar**; ramane doar confirmarea pe fluxul real, in S8.
*Depinde de:* S5.
### S7 — Rotunjirea la reeditare
`verifica_total_document` (`:16009-16188`) insereaza automat o linie de corectie in `ACT_TEMP` cand
totalul difera de suma din note. La editare se aplica din nou — de confirmat ca nu se acumuleaza
corectii succesive la editari repetate.
*Gata cand:* trei editari consecutive nu lasa trei linii de corectie.
*Depinde de:* S5.
### S8 — Test pe fluxul real, din ambele puncte de intrare
Test headless (`COMUN\docs\depanare_testare_vfp.md`) + UI (`COMUN\docs\testare-ui-vfp.md`), pe cate un
caz din fiecare tip de sursa: lista de preturi, comanda, contract, aviz. Fiecare caz rulat **de doua
ori**: o data pornit din formularul de facturi (ROAFACTURARE), o data din registru jurnal (ROACONT).
Verifica: nota veche `STERS=1`, nota noua corecta, `id_fact` neschimbat, `vanzari`/`vanzari_detalii`
sincronizate, totalurile denormalizate corecte, rulajele refacute, totalurile de control din S4b
concordante, si ca **nu** s-au declansat verificarile de stoc de la emitere.
Al treilea caz obligatoriu: un document care **nu** e factura, deschis din registru jurnal — pagina
de articole nu apare si comportamentul e identic cu cel de azi.
*Depinde de:* S6, S7.
### S9 — Diff, review, changelog, documentatie
Diff ca fisier in `docs\`, commit dupa aprobare, in doua repo-uri (ROAFACTURARE si COMUN). Changelog
`:nou:`. Propune actualizarea `flux-modificare-stergere-nota-jurnal.md` cu ramura de facturi.
## Riscuri
- **Cel mai mare**: `omodificari.vc2` e in COMUN si serveste si registrul jurnal din ROAGEST/ROACONT.
O regresie acolo e mai grava decat lipsa functionalitatii aici. S4 trebuie sa pastreze modul "doar
nota" complet neschimbat.
- Modelul "sterge + scrie document nou cu cod nou" inseamna ca o factura editata isi schimba `cod`-ul
— orice raport sau integrare care tine minte `cod`-ul vechi il pierde. S6 exista tocmai pentru asta.
- Fara garzile de luna inchisa / luna curenta / referinte (azi absente pe `do_modifica`), editarea de
sume ar putea modifica o perioada deja raportata. Sunt obligatorii, nu optionale.
- Interactiunea cu #7: daca flagul `pret_cu_tva` devine editabil pe linie, editarea ulterioara trebuie
sa il trateze la fel ca introducerea.
## Dependente
- **#7** — S4 include editarea flagului `pret_cu_tva` pe linie; se face dupa ce #7 stabileste
comportamentul la introducere.
- **#8** — S5 refoloseste calculul totalurilor din `scrie_in_vanzari`, care se atinge in #8.
### Ce preda #7 catre S6 (consemnat 07.08.2026, decizia lui Marius)
Din #7 s-a livrat editarea flagului `pret_cu_tva` **doar** pe factura in curs de compunere
(inainte de salvare), prin `frm_facturare_articole.do_modifica` (buton `But_modifica1` +
dublu-clic pe `grd_factura`), care redeschide dialogul `frm_articol_factura`. Detaliu complet:
`docs\cercetare\rec_s2b_aplicare.md`.
Editarea aceluiasi flag pe o factura **deja salvata** a fost mutata explicit in #6, prin decizia
lui Marius din 07.08.2026. Motivul, exact: butonul existent din `frm_facturi` (`But_modifica2` ->
`do_modifica_explicatie`, **nu** `do_modifica`) deschide `frm_modifica_articol_factura`, care
editeaza doar `explicatie` si `taxcode` — doua campuri care nu ating nicio suma
(`pack_facturare.modifica_explicatie_articol` e un `UPDATE` de doua coloane). Cealalta actiune,
`do_modifica`, deschide `frm_modifica_factura` (antet: ruta, delegat, agent, serie/numar, date) —
tot fara sume.
Flagul `pret_cu_tva` e de alta natura: schimbarea lui reimparte baza si TVA-ul pe linie, deci
muta totalurile denormalizate din `VANZARI` si notele contabile — exact problema de fond a
punctului 6.
#7 lasa mostenire un model gata facut si verificat pentru partea de UI a acestei editari:
maparea de intrare `crsfactura` -> `poArticol` (`AddProperty`/`RemoveProperty` pe 7 perechi de
nume) si drumul invers (`Gather`+`Replace`), documentate in `docs\cercetare\rec_s2b_aplicare.md`.
Deci S4 nu trebuie sa reproiecteze dialogul, ci sa rezolve partea de persistenta/recalcul in
Oracle (vezi S5).
Limitarea `ncantitatemax` din #7 a fost eliminata tot in #7, prin decizia lui Marius din
07.08.2026: `do_modifica` recalculeaza plafonul din cursorul de stoc in loc sa il fixeze pe
cantitatea curenta a liniei, reconstituind cantitatea disponibila de dinainte ca linia curenta sa
o fi consumat. Mecanismul, pe scurt: regasire dupa `id_c` in `crsarticole`/`crsarticole1` (alegerea
cursorului dupa `opt_facturare`), apoi reversul decrementarii pe care `do_adauga_articol` a
aplicat-o deja — `cantitate + poArticol.cantitate` la tipurile de document cu verificare de stoc,
`cantitate - poArticol.cantitate` la retur; fallback pe cantitatea liniei daca randul nu mai e in
cursor. Detaliu complet: `docs\cercetare\rec_s2c_ncantitatemax.md`.
**Inchis pe 08.08.2026**: intrebarea era de unde vine plafonul de cantitate la o factura deja
salvata, unde cursorul de stoc (`crsarticole`/`crsarticole1`) poate sa nu existe. Decizia lui
Marius: **#6 nu are plafon si nu verifica stocul** — corectia unei facturi emise e raspunderea
utilizatorului. Nu e nevoie de interogare de stoc proprie. Efortul se muta in S4b (helpere,
totaluri, verificari de corelatie cu `ACT` si `RUL`).