# Plan #7 — pret cu TVA editabil pe linie de articol Sursa: `COMUN\docs\todos.txt` punctul 7. Ordine de executie: **al doilea**, dupa #8. Stare: propunere, neinceput. ## Problema raportata Factura iese 99.99 lei dar utilizatorul are nevoie de exact 100.00 lei cu TVA. Politica de preturi e pe "preturi fara TVA", calculul porneste de la pretul fara TVA, TVA-ul se rotunjeste si nu poate fi ajustat. Varianta aleasa de Marius: utilizatorul modifica `pret_cu_tva` la nivel de articol, la introducerea facturii si ulterior la editare. ## Descoperirea care schimba dimensiunea lucrarii Cerinta initiala presupunea o coloana noua salvata in `VANZARI_DETALII`, cu migrare si atingerea tuturor locurilor de calcul. **Nu e necesar.** Instalatia exista deja, integral: 1. `VANZARI_DETALII.PRET_CU_TVA` exista deja, ca **flag NUMBER(1) per linie** (0 = `PRET` e fara TVA, 1 = `PRET` e cu TVA inclus). Confirmat prin uz: `ff_2026_07_27_01_FACTURARE.sql:25,43`. 2. `PACK_FACTURARE.adauga_articol_factura` primeste deja flagul ca parametru, `V_PRETURI_CU_TVA_TEMP` (`ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql:540`) — deci VFP il trimite deja per articol, la adaugarea pe factura. 3. Toate functiile de calcul ramifica deja pe el (`V_PRET_CU_TVA` / `V_PRET_ARE_TVA` in `calculeaza_total_fara_tva` / `_tva` / `_cu_tva` si variantele `_fact`, `:15638-15949`). 4. Listarea si relistarea in VFP ramifica deja pe el, in `COMUN\programe\ofacturare_comun.prg:1816-1880` (`prelucreaza_facturacrs`) — lantul de `IIF( pret_cu_tva = 1, ..., ...)` care produce `pretctva`, `discountctva` si valorile pe linie. Ce lipseste e **exclusiv partea de UI**: pe formularul de introducere articole nu exista coloana pentru flag, deci utilizatorul nu il poate schimba per linie. Cautare pe `pret_cu_tva` in `COMUN\clase\ofacturare.vc2` (formularele `frm_facturare_articole` si `frm_facturare_articole2`): **zero rezultate**. Singurul checkbox `cPret_cu_tva` gasit e in alt grid, `Clase\ofundal_facturare.vc2:696-699`. Concluzie: **fara DDL, fara migrare de date, fara modificari in view-uri sau in pachetul Oracle.** Lucrarea e VFP-only, pe formularul de articole. ## Consecinta pentru rotunjire Cu flagul pe 1, utilizatorul tasteaza direct pretul cu TVA (ex. 100.00), iar pretul fara TVA se deriva. Totalul facturii devine exact suma preturilor tastate — exact cazul din todo. De stiut: exista deja un mecanism ascuns de absorbtie a diferentelor de rotunjire, dar **doar contabil**. `PACK_FACTURARE.verifica_total_document` (`:16009-16188`) compara totalul asteptat cu suma din notele contabile si, la diferenta, insereaza automat o linie de corectie in `ACT_TEMP` (`:16086-16188`). Nu apare pe factura si nu se vede in `VANZARI_DETALII`. Nu se atinge in acest plan, dar explica de ce pana acum diferenta "disparea" fara ca utilizatorul sa o poata controla. ## Capcana de duplicare `do_scrie_factura` exista in **doua clase aproape identice** in `COMUN\clase\ofacturare.vc2`: `frm_facturare_articole` (`:13981-14339`) si `frm_facturare_articole2` (`:18004-18331`). Orice modificare de comportament trebuie facuta in ambele, altfel un flux ramane in urma. Prima story stabileste care dintre ele e folosita pe ce tipuri de factura. ## Stories ### S1 — Stabilirea formularului si a fluxului real Determina care dintre `frm_facturare_articole` / `frm_facturare_articole2` se deschide pentru fiecare tip de sursa (lista de preturi, comanda, contract, aviz) si de unde vine flagul azi in cursorul de articole (`PACK_FACTURARE.cursor_preturi`, spec `:335`, body `:2121`). Confirma valoarea implicita propagata din politica de pret. *Gata cand:* e notat in `docs\progres.md` ce formular acopera ce tip, si care e sursa implicita a flagului. *Blocheaza:* S2. ### S2 — Coloana `pret_cu_tva` in gridul de articole Adauga in grid o coloana checkbox pentru flag, editabila per linie. Respecta `COMUN\docs\conventie_ux_formulare.md` (pozitionare, ordine de taburi) si, daca formularul are 2+ griduri, `COMUN\docs\capcana_grid_controlsource.md`. Editare pe versiunile text `.vc2` + write-back, cu regulile de encoding cp1252 din `COMUN\docs\conventie_encoding_cp1252.md`. *Gata cand:* coloana apare si se poate bifa/debifa, in ambele clase. ### S3 — Recalcularea afisata la schimbarea flagului La bifare/debifare, valorile de pe linie si totalul facturii se recalculeaza imediat, folosind aceeasi ramificare ca `prelucreaza_facturacrs` (`ofacturare_comun.prg:1816-1880`), ca listarea sa dea identic cu ce vede utilizatorul pe ecran. *Gata cand:* bifarea unei linii schimba totalul afisat coerent, fara reincarcarea formularului. *Depinde de:* S2. ### S4 — Pretul editabil in modul "cu TVA" Cu flagul pe 1, campul de pret accepta pretul cu TVA tastat de utilizator si il trimite ca atare la `adauga_articol_factura` prin `V_PRETURI_CU_TVA_TEMP = 1`. Verifica precizia de rotunjire folosita (`gnPPretV`, `gnPc` — vezi `ofacturare_comun.prg:1817-1821`). *Gata cand:* o factura cu o singura linie, pret 100.00 cu TVA, cantitate 1, da total exact 100.00. *Depinde de:* S2. ### S5 — Test pe fluxul real Test headless conform `COMUN\docs\depanare_testare_vfp.md`, plus verificare UI conform `COMUN\docs\testare-ui-vfp.md`. Cazuri: cota standard si cota redusa; cu si fara discount unitar (ramura `discount_evidentiat` din `calculeaza_total_tva_fact`, `:15899-15949`); doua linii cu flaguri diferite pe aceeasi factura. *Gata cand:* toate cazurile dau acelasi rezultat la introducere, la listarea initiala si la relistare. *Depinde de:* S3, S4. ### S6 — Editarea ulterioara a flagului Modificarea flagului pe o factura deja emisa **nu intra aici** — depinde de mecanismul de editare din planul #6, pentru ca schimbarea afecteaza sumele si deci notele contabile. Story-ul se rezuma la a nota dependenta si a lasa punctul de extensie curat. *Gata cand:* dependenta e consemnata in `plan_06_editare_factura.md`. ### S7 — Diff, review, changelog Diff ca fisier in `docs\`, commit doar dupa aprobare. Changelog `:nou:` sau `:modificare:`, 1-3 fraze non-tehnice, bump pe seria 2.11.x. ## Riscuri - Flagul exista deja pe linii istorice; expunerea lui in UI nu schimba date vechi, dar face vizibile eventuale inconsistente deja prezente. De privit inainte de livrare cate linii au flagul diferit de valoarea implicita a politicii. - Rotunjirea per unitate se face in `PACK_SESIUNE.calculeaza_pret_*`, pachet care **nu a fost gasit** in arhiva de migrari cautata. Daca S4 arata diferente de rotunjire, e nevoie de o cautare dedicata dupa `create or replace package pack_sesiune` in `D:\ROA\DATABASE\SCRIPTURI_CLAR`. - Duplicarea `frm_facturare_articole` / `_articole2` e sursa clasica de "merge pe un flux, nu si pe celalalt". ## Varianta respinsa Denormalizarea completa (salvarea TVA unitar si a valorii TVA pe linie, cu recitire in toate view-urile si rapoartele) — minimum 6 zone distincte: DDL cu migrare de date istorice, ~4 proceduri in `PACK_FACTURARE`, 3-4 view-uri (`fact_vrap_fact_articole`, `fact_vrap_articole_vandute`, `fact_vfacturi`, `fact_vfacturi2`), raportul dinamic din `COMUN\programe\oproceduri_rapoarte_fact.prg:581-590`, gridul si rapoartele `.frx`. Nu se justifica atat timp cat flagul per linie rezolva cazul real.