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

10 KiB

Investigatie: discount pe articol (linie de factura) — ROAFACTURARE

Intrebare: discountul pe articol e azi doar procentual, sau exista si discount in valoare absoluta pe unitate / pe linie?

1. Model de date — DISCOUNT / DISCOUNT_UNITAR

Concluzie: Exista deja o coloana de discount in valoare absoluta pe unitate (DISCOUNT_UNITAR) pe VANZARI_DETALII (si pe VANZARI_DETALII_TEMP, tabela de lucru din care se compune factura), pe langa discountul de document VANZARI.DISCOUNT (valoare absoluta rezultata dintr-un procent aplicat la baza, nu procent stocat). Exista si un flag boolean VANZARI.DISCOUNT_EVIDENTIAT.

Dovezi:

  • Tip coloana: alter table VANZARI_DETALII modify discount_unitar NUMBER(22,6); / alter table VANZARI_DETALII_TEMP modify discount_unitar NUMBER(22,6); / alter table CRM_POLITICI_PRET_ART modify discount_unitar NUMBER(22,6); — D:\ROA\DATABASE\SCRIPTURI_CLAR\2024\06\ff_2024_06_13_02_COMUN_FACTURARE.sql:3,9,16. Precizia (22,6) e cea folosita la coloane de pret/valoare, nu la procente.
  • Exista si la nivel de politica de pret (CRM_POLITICI_PRET_ART.DISCOUNT_UNITAR), deci discountul unitar poate proveni din politica de pret a clientului, nu doar tastat pe linie.
  • Coloana e folosita direct ca scadere din pret: A.PRET - NVL(A.DISCOUNT_UNITAR, 0) AS PRET — D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql:3315,3500.
  • Document-level: v.discount as disc_fara_tva / v.discount_evidentiat — D:\ROA\DATABASE\SCRIPTURI_CLAR\2011\08\ff_2011_08_30_02_FACTURARE.sql:36-42,251-252,267,291. Discountul document e o valoare (lei/valuta), calculata din procent tastat de operator x baza (vezi punctul 3), nu un procent stocat pe VANZARI.

2. VFP — grid-uri de linii factura (frm_facturare_articole si frm_facturare_articole2)

Concluzie: Ambele forme au coloane de grid pentru discountul unitar in valoare absoluta, cu etichete explicite "Discount unitar cu TVA" / "Discount unitar in valuta fara TVA". In frm_facturare_articole (forma standard) aceste coloane sunt read-only in grid (afisare, nu editare directa pe linie); in frm_facturare_articole2 (forma "noua", optionala) sunt editabile si exista in plus o coloana de procent pe linie ("Procent discount", legata de campul procdisc).

Dovezi:

  • frm_facturare_articole: Column5.ControlSource = "discountctva", Column5.Name = "cDiscountCTva", Column5.ReadOnly = .T. si Column9.ControlSource = "vdiscountftva", Column9.Name = "cVdiscountftva" (fara ReadOnly, deci editabil implicit) — D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare.vc2:12311-12317, 12340-12345. Header-e: Caption = "Discount unitar cu TVA" (:12409), Caption = "Discount unitar in valuta fara TVA" (:12546).
  • frm_facturare_articole2: Column5.Name = "cDiscountCTva", Column5.ReadOnly = .F. (:16656-16657), Column9.Name = "cVdiscountftva", Column9.ReadOnly = .F. (:16687-16688), plus Column14.ControlSource = "procdisc", Column14.Name = "cProcentDiscount", Column14.Format = "RK", Column14.InputMask = "99 999.99", Column14.ReadOnly = .F. (:16720-16727), header Caption = "Procent discount" (:16934-16940).
  • Vizibilitate conditionata: nu de poDate.tip direct, ci de poDate.in_valuta — If poDate.in_valuta = 0 ... RemoveObject([cVdiscountftva]) ... Else ... RemoveObject([cDiscountctva]) — ofacturare.vc2:15269-15278 (pattern analog si la :19065 pentru frm_facturare_articole2).
  • frm_facturare_articole2 e optionala, activata prin gnFacturareNou = 1 cu un dialog Da/Nu ("Facturare noua (DA) sau standard (NU)?") — COMUN\programe\ofacturare.prg:87-93, instantiata la :929 (lcObject = [frm_facturare_articole2]).

3. Calculul + discount_evidentiat

Concluzie: DISCOUNT_UNITAR se scade direct din pretul unitar fara TVA, in valuta documentului, inainte de a se aplica TVA-ul, apoi se inmulteste cu cantitatea. Flagul DISCOUNT_EVIDENTIAT schimba doar mecanismul aritmetic (scade discountul din valoarea deja calculata vs. din pretul unitar rotunjit), nu semantica — discountul ramane o valoare absoluta pe unitate in ambele ramuri. In VFP, checkbox-ul corespunzator e etichetat "Se pune in evidenta discount-ul pe articole in notele contabile si pe factura" — adica discountul e afisat separat pe document/nota contabila vs. absorbit tacit in pret.

Dovezi (FUNCTION calculeaza_total_fara_tva_fact, D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql:15794-15847):

IF V_DISCOUNT_EVIDENTIAT = 1 THEN
  V_SUMA_FARA_TVA := ROUND((ROUND(curs*PRET,...) - DIFERENTA)*CANTITATE,...)
                    - ROUND(ROUND(curs*NVL(DISCOUNT_UNITAR,0),...)*CANTITATE,...)
ELSE
  V_SUMA_FARA_TVA := ROUND((ROUND(curs*ROUND(PRET,...),...)
                    - ROUND(curs*ROUND(NVL(DISCOUNT_UNITAR,0),...),...) - DIFERENTA)*CANTITATE,...)

Aceeasi structura simetrica in calculeaza_total_tva_fact (:15899-15944). In VFP, sinteza corespunzatoare: valdiminuatftva WITH poArticol.pretftva - NVL(poArticol.discount_unitar,0) — ofacturare.vc2:13126, conversia cu-TVA: discount_unitar_ctva = discount_unitar*(proc_tvav-1) + discount_unitar — :13635-13636. Checkbox: ADD OBJECT 'ck_discountevidentiat' AS _checkbox WITH ... Caption = "Se pune in evidenta discount-ul pe articole in notele contabile si pe factura", ControlSource = "poDate.discount_evidentiat" — :11300-11305.

4. Oracle — parametrii adauga_articol_factura

Concluzie: procedura primeste discountul ca parametru numeric absolut V_DISCOUNT_UNITAR IN NUMBER si il scrie direct in VANZARI_DETALII_TEMP.DISCOUNT_UNITAR, fara nicio transformare procent->valoare. Discountul de document (VANZARI.discount) e separat, aplicat/gestionat la alt nivel (agregare pe factura, cf. do_calculeaza_discount in VFP).

Dovezi: semnatura completa PROCEDURE adauga_articol_factura(V_ID_TEMP IN NUMBER, ... V_CANTITATE IN NUMBER, V_DISCOUNT_UNITAR IN NUMBER, V_CONT IN VARCHAR2, ...) — D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\03\ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql:4972-4998, parametrul V_DISCOUNT_UNITAR la linia 4986; INSERT INTO VANZARI_DETALII_TEMP (... DISCOUNT_UNITAR ...) VALUES (... V_DISCOUNT_UNITAR ...) — :5219, 5249.

5. Discount unitar in valoare absoluta — exista deja in suita

Concluzie: Da, exista deja in toata suita ROA — nu doar "conceptual", ci implementat si cablat de la Oracle pana la grid. COMUN\clase\ofacturare.vc2 (fisierul verificat pentru ROAFACTURARE) e literalmente acelasi fisier partajat cu D:\ROA\ROAGEST\COMUN\clase\ofacturare.vc2 si D:\ROA\ROAACNPRO\COMUN\clase\ofacturare.vc2 (confirmat prin grep pe ambele arbore), la fel pack_facturare. Nu a fost nevoie de o cautare separata in alt produs — e literalmente acelasi cod, aceeasi coloana.

Dovezi: discount_unitar/discountunitar apare identic in D:\ROA\ROAGEST\COMUN\clase\ofacturare.vc2, D:\ROA\ROAGEST\COMUN\clase\ofacturare_comun.vc2, D:\ROA\ROAGEST\COMUN\programe\ofacturare*.prg, D:\ROA\ROAACNPRO\COMUN\clase\ofacturare.vc2 si D:\ROA\ROAACNPRO\COMUN\clase\ofacturare_comun.vc2; SQL-uri de discount identice (ex. v.discount as disc_fara_tva) gasite si in D:\ROA\DATABASE\SCRIPTURI_CLAR\2021\02\ff_2021_02_03_01_VANZARI.sql:19-20,259-260,409-410, 481-482,612.

6. Ce ar presupune un discount unitar in valoare absoluta — inventar (nu solutie, doar puncte de atins)

  • Coloana tabela: deja exista (VANZARI_DETALII.DISCOUNT_UNITAR, NUMBER(22,6), plus pe VANZARI_DETALII_TEMP si CRM_POLITICI_PRET_ART) — nimic de adaugat.
  • Parametru Oracle: deja exista (adauga_articol_factura(... V_DISCOUNT_UNITAR ...), ff_2026_03_23_04_COMUN_PACK_FACTURARE.sql:4986) — nimic de adaugat.
  • Coloana grid: deja exista in ambele forme (cDiscountCTva/cVdiscountftva); in frm_facturare_articole (forma standard, majoritara) e read-only — de decis daca se face editabila pe linie sau ramane doar afisaj derivat din politica de pret / discountul procentual de pe factura.
  • Intrare pentru operator: in forma standard nu s-a gasit un punct unde operatorul tasteaza manual discount_unitar per linie la adaugarea articolului — pare alimentat din CRM_POLITICI_PRET_ART.DISCOUNT_UNITAR (politica de pret a clientului) sau din redistribuirea discountului procentual de pe factura (do_calculeaza_discount, ofacturare.vc2:13405-13424). De clarificat fluxul exact inainte de a proiecta un input nou.
  • Recalcul: formulele Oracle (calculeaza_total_fara_tva_fact/calculeaza_total_tva_fact) deja trateaza DISCOUNT_UNITAR ca valoare absoluta — nimic de schimbat aritmetic daca se reutilizeaza calea existenta.
  • Rapoarte .frx: nu s-a verificat daca discountul unitar apare pe rapoartele tiparite de factura — necunoscut, de verificat separat.
  • eFactura / SAF-T: nu s-a verificat daca discount_unitar e mapat in XML-ul UBL/eFactura sau in declaratia SAF-T — necunoscut, de verificat separat (fisierele COMUN_EFACTURA*.sql / COMUN_SAFT*.sql contin "discount" dar nu au fost citite).

Raspuns scurt la intrebare

Nu doar procentual: discountul pe articol exista deja si ca valoare absoluta pe unitate (DISCOUNT_UNITAR, NUMBER(22,6)), implementat capat la capat — coloana Oracle pe VANZARI_DETALII/VANZARI_DETALII_TEMP, parametru in pack_facturare.adauga_articol_factura, formule de calcul care scad direct din pret, si coloane de grid in VFP cu eticheta explicita "Discount unitar cu TVA"/"...in valuta fara TVA". Discountul de document (VANZARI.discount) ramane procentual-la-origine (tastat ca procent, stocat ca valoare calculata). Ce nu e clar e daca operatorul poate tasta liber discountul unitar pe linie in forma standard (frm_facturare_articole, unde coloana e read-only) — in forma "noua" optionala (frm_facturare_articole2, gnFacturareNou=1) e editabila si are si un procent-pe-linie separat.

Necunoscute ramase

  • Sursa exacta a valorii discount_unitar la adaugarea unui articol in forma standard (politica de pret vs. redistribuire din discountul procentual de pe factura) — nu s-a urmarit tot lantul do_adauga/crsgestarticol.
  • Daca discount_unitar apare pe rapoartele .frx tiparite.
  • Daca discount_unitar e transmis in eFactura (UBL) sau SAF-T.
  • Cat de folosita e efectiv frm_facturare_articole2 in productie (e optionala, per sesiune, cu prompt).