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

13 KiB

Verificare discount pe linie de factura — frm_facturare_articole / VANZARI_DETALII

Investigatie read-only. Toate liniile citate au fost verificate pe fisierul text real din working copy (ofacturare.vc2, 23087 linii, ultima scriere 07.08 22:18) si pe scripturile DDL din D:\ROA\DATABASE\SCRIPTURI_CLAR. Nu s-a executat nimic pe baza de date.

1. Confirmare/infirmare afirmatii initiale

Concluzie: toate afirmatiile despre frm_facturare_articole sunt corecte, cu linii care se potrivesc exact sau aproape exact. Confirmat via vfp_symbols.ps1 -Where ca formularul frm_facturare_articole ocupa exact ofacturare.vc2:10968-15739.

Dovezi:

  • Column5.ControlSource = "discountctva", Column5.Name = "cDiscountCTva", Column5.ReadOnly = .T. — confirmat la ofacturare.vc2:12311-12317 (identic cu afirmatia).
  • Column9.ControlSource = "vdiscountftva", Column9.Name = "cVdiscountftva", fara ReadOnly — confirmat la ofacturare.vc2:12340-12345 (identic).
  • Capete de coloana: Caption = "Discount unitar cu TVA" la :12409, Caption = "Discount unitar in valuta fara TVA" la :12546 — ambele confirmate exact.
  • Excludere reciproca pe valuta la ofacturare.vc2:15269-15278:
    15269			If poDate.in_valuta = 0
    15270				Thisform.grd_factura.RemoveObject([cVpretFtva])
    15271				Thisform.grd_factura.RemoveObject([cVdiscountftva])
    15272				Thisform.grd_factura.RemoveObject([cVvaldiminuatftva])
    15273			Else
    15274				Thisform.grd_factura.RemoveObject([cPretFtva])
    15275				Thisform.grd_factura.RemoveObject([cDiscountctva])
    
    confirmat identic (linii exacte, nu doar apropiate).
  • VANZARI_DETALII.DISCOUNT_UNITAR NUMBER(22,6) — confirmat, dar cu precizare: linia corecta in ff_2024_06_13_02_COMUN_FACTURARE.sql e :3 (nu si :9/:16 cum lasa sa se inteleaga formularea initiala — acelea sunt VANZARI_DETALII_TEMP si, respectiv, CRM_POLITICI_PRET_ART, vezi punctul 4).

2. Consecinta practica pe ecran

Concluzie: pe factura in lei, coloana vizibila e "Discount unitar cu TVA" (discountctva) si e needitabila in grid (ReadOnly = .T.). Pe factura in valuta, coloana vizibila e "Discount unitar in valuta fara TVA" (vdiscountftva) si este editabila direct in grid (nicio proprietate ReadOnly setata pe coloana sau pe Text1-ul ei → mosteneste default-ul VFP, .F.).

Dovezi:

  • Ramane pe ecran: cand in_valuta = 0 se elimina cele 3 coloane "V..." (inclusiv cVdiscountftva) → ramane cDiscountCTva. Cand in_valuta <> 0 se elimina cDiscountctva (si celelalte 3 coloane fara "V") → ramane cVdiscountftva. (:15269-15278, citat mai sus).
  • Ca sa nu presupun ca lipsa lui Column9.ReadOnly inseamna implicit editabil, am verificat lantul de clase: grid-ul grd_factura e ADD OBJECT 'grd_factura' AS _grdrow (:12263), fara ReadOnly la nivel de grid intre :12263-12364; clasa _grdrow (_grd_base.vc2:445) nu seteaza ReadOnly nicaieri in propriul body, iar parintele ei _grdbase/_grid de asemenea nu (singurele 3 aparitii de ReadOnly in _grd_base.vc2 sunt in clasa separata _grdfooter, neinrudita). Deci Column9 chiar e editabila.
  • Confirmare suplimentara: in formularul frm_facturare_articole2 (prototip separat, clasa la ofacturare.vc2:15741-19355, NU formularul in productie), aceleasi doua coloane apar cu ReadOnly explicit: Column5.ReadOnly = .F. (:16657) si Column9.ReadOnly = .F. (:16688) — adica in prototip discountul e editabil in ambele monede direct din grid; in formularul real doar varianta in valuta e editabila din grid.

3. Poate operatorul introduce azi un discount pe linie, si pe ce cale

Concluzie: da, poate — dar nu prin do_calculeaza_discount de la frm_facturare_articole:13405-13424 (asta calculeaza discountul global pe toata factura, Thisform.ndiscfactron/ndiscfactval, nicio legatura cu discountctva/vdiscountftva pe linie — vezi corectia de la final). Calea reala e formularul frm_articol_factura (ofacturare.vc2:1108-2659), deschis din do_adauga_articol la adaugarea unui articol (:12873, ofrmadarticol.Show(1) doar daca !tlImplicit). Acolo exista metoda frm_articol_factura.do_calculeaza_discount (:1874-1976) legata de 3 controale editabile: Clb_procent_discount.Text_simplu1 (procent), Clb_discount_unitar.tx_suma_nat/tx_suma_val (suma in lei / valuta), Clb_discountctva.tx_suma_nat/tx_suma_val (varianta cu TVA) — toate cu handler Valid/InteractiveChange care apeleaza do_calculeaza_discount(valoare, tip) cu tip=1 procent, tip=2 lei, tip=3 valuta (:2602-2624, :2646-2649).

Lantul, cu linii:

  1. Operator tasteaza in unul din campurile de mai sus → Valid/InteractiveChange → Thisform.do_calculeaza_discount(valoare, tip) (ofacturare.vc2:2602-2649).
  2. do_calculeaza_discount (:1874-1976) scrie in obiectul poArticol: poArticol.discount_unitar, discount_unitar_val, discount_unitar_ctva, discount_unitar_ctva_val (ex. :1898-1906, :1943-1951).
  3. La revenirea in do_adauga_articol (:12813-13086), poArticol e scris in crsfactura prin Gather/Replace:
    12956			Replace id_temp With Recno(), codmat With Nvl(poArticol.codmat, Space(50)), ;
    ...
    12957				discountftva With poArticol.discount_unitar, discountctva With poArticol.discount_unitar_ctva, ;
    			vdiscountftva With Nvl(poArticol.discount_unitar_val, 0), vdiscountctva With Nvl(poArticol.discount_unitar_ctva_val, 0)
    
    (linii 12956-12957; varianta pentru selectie multipla de articole la 13003-13005).
  4. discount_unitar initial (inainte de tastare) e preluat din crsarticole (cursorul de stoc, populat inainte de deschiderea dialogului) prin do_initializeaza_articol (:13618 si urm.): toArticol.discount_unitar = Nvl(toArticol.discount_unitar, 0) (:13630) — deci daca stocul / politica de pret vine deja cu un discount populat, acela e valoarea implicita afisata in dialog, pe care operatorul o poate suprascrie.
  5. Cale suplimentara, directa: pe factura in valuta, cum cVdiscountftva e editabil in grid (punctul 2), operatorul poate scrie si direct in celula vdiscountftva din grd_factura — dar fara niciun Valid/InteractiveChange propriu definit pentru acea coloana in frm_facturare_articole (cautat explicit cVdiscountftva/cDiscountCTva in intervalul 10968-15739: singurele hit-uri sunt definitiile de coloana si RemoveObject, niciun handler de eveniment) — editarea directa in grid NU declanseaza recalcularea automata a vvaldiminuatftva/totaluri, doar modifica valoarea bruta in crsfactura.

4. Structura reala a coloanelor de discount pe VANZARI_DETALII

Concluzie: nu exista un CREATE TABLE VANZARI_DETALII in SCRIPTURI_CLAR (arhiva incepe din 2009, iar tabela exista deja atunci — coloana DISCOUNT_UNITAR era deja in uz in pachete PL/SQL din 2009, deci a fost creata inainte de arhiva). Singura coloana de discount pe VANZARI_DETALII/VANZARI_DETALII_TEMP gasita in SCRIPTURI_CLAR e DISCOUNT_UNITAR, si singura modificare de tip/precizie inregistrata e cea din 2024.

Dovezi (cronologic, tot ce am gasit cu DISCOUNT in contextul acestei tabele):

  • Nu exista niciun CREATE TABLE VANZARI_DETALII sau ALTER TABLE VANZARI_DETALII ADD DISCOUNT... in toata arhiva SCRIPTURI_CLAR (2009-2026). Cel mai vechi hit pe DISCOUNT_UNITAR legat de aceasta tabela e o declaratie de variabila V_DISCOUNT_UNITAR VANZARI_DETALII.DISCOUNT_UNITAR%TYPE in pachetul PACK_FACTURARE, prezenta deja in scripturile din 2009 (ex. 2009\9\ff_2009_09_03_01_FACTURARE_PACK_FACTURARE.sql) — coloana exista deja atunci.
  • Singura modificare de precizie gasita: ff_2024_06_13_02_COMUN_FACTURARE.sql:3 — alter table VANZARI_DETALII modify discount_unitar NUMBER(22,6); — si simetric pentru VANZARI_DETALII_TEMP la linia :9, si pentru CRM_POLITICI_PRET_ART (tabela de politici de pret) la linia :16. Deci forma finala confirmata: DISCOUNT_UNITAR NUMBER(22,6), o singura coloana de discount (valoare, nu procent), identica pe toate cele 3 tabele.
  • Nu exista alte coloane DISCOUNT%/VDISCOUNT% la nivel Oracle pe VANZARI_DETALII — cele patru campuri VFP discountftva/discountctva/vdiscountftva/vdiscountctva din crsfactura NU au corespondent 1:1 in schema Oracle; la scriere (Gather/Replace in do_adauga_articol, punctul 3) doar discount_unitar (si varianta cu TVA calculata din el) ajunge, prin campurile intermediare, la coloana unica Oracle.
  • Convenția de interogare a bazei de dezvoltare, gasita in COMUN\docs\scripturi-migrare-db.md:36-40: sursa de referinta pentru DDL e schema de dezvoltare MARIUSM_AUTO (bazata pe ROA_CENTRAL), interogata prin goExecutor, niciodata o schema de client. Nu am rulat nimic pe baza — doar raportez conventia, asa cum a cerut sarcina.

5. Coloana de procent de discount pe VANZARI_DETALII / campul procdisc

Concluzie: nu exista o coloana de procent de discount pe VANZARI_DETALII (doar DISCOUNT_UNITAR, o valoare absoluta). Campul procdisc din frm_facturare_articole2 e doar un camp de lucru in grid, fara nicio scriere in cursorul local si fara corespondent Oracle — practic un camp scaffolded si neconectat.

Dovezi:

  • Cautare DISCOUNT+PROCENT/PROC in ff_2024_06_13_02_COMUN_FACTURARE.sql (scriptul care fixeaza forma finala a coloanelor de discount): nicio potrivire — confirma ca nu exista un "procent discount" ca si coloana pe VANZARI_DETALII.
  • procdisc apare o singura data in tot ofacturare.vc2: Column14.ControlSource = "procdisc" la :16721, in interiorul clasei frm_facturare_articole2 (15741-19355 — prototip, nu formularul in productie).
  • Nicio instructiune Gather/Replace ... procdisc With ... in tot fisierul (cautat pe tot ofacturare.vc2) — camp fara sursa de populare in cod.
  • Toate celelalte aparitii de "procdisc" din fisier sunt de fapt variabila de memorie gnMemProcDisc ("memorare procent discount" — o optiune de aplicatie care controleaza daca procentul de discount tastat se retine intre articole, :2299, :2441, :12835 etc.), fara legatura cu campul de cursor procdisc.
  • Cautare PROCDISC in SCRIPTURI_CLAR: doar 2 hit-uri, ambele in scripturi din 2015 pentru tabela de optiuni firma (co_2015_12_09_01_OPTIUNI.sql, ff_2015_12_09_01_OPTIUNI.sql) — legate de aceeasi optiune gnMemProcDisc, nu de VANZARI_DETALII.

Ce era gresit in afirmatiile de mai sus

  • Formularea "linia 3, 9, 16" pentru coloana Oracle DISCOUNT_UNITAR grupa laolalta 3 tabele diferite (VANZARI_DETALII la :3, VANZARI_DETALII_TEMP la :9, CRM_POLITICI_PRET_ART la :16) ca si cum ar fi acelasi lucru repetat de 3 ori — corect ca valoare (toate devin NUMBER(22,6)), dar sunt 3 tabele distincte, nu 3 confirmari ale aceleiasi coloane.
  • Cea mai importanta corectie: linia indicata pentru "de unde se scrie discountctva/vdiscountftva — din do_calculeaza_discount (ofacturare.vc2:13405-13424)" trimite la metoda gresita. frm_facturare_articole.do_calculeaza_discount de la acea linie calculeaza discountul global pe factura (Thisform.ndiscfactron/ndiscfactval), nu discountul pe linie. Metoda care chiar calculeaza discount_unitar/discount_unitar_ctva (sursa reala pentru discountctva si vdiscountftva) e frm_articol_factura.do_calculeaza_discount, o metoda cu acelasi nume dar in alta clasa, la ofacturare.vc2:1874-1976. Cele doua metode au nume identic dar apartin la doua clase diferite din acelasi fisier — o capcana reala de grep fara indexul de simboluri.

Necunoscute ramase

  • Nu am verificat daca crsarticole (cursorul de stoc din care pleaca poArticol.discount_unitar la do_initializeaza_articol:13630) e populat vreodata cu un discount nenul direct dintr-o interogare de politica de pret (CRM_POLITICI_PRET_ART) inainte de a ajunge in dialogul frm_articol_factura — am gasit doar ca acea tabela are aceeasi coloana discount_unitar (NUMBER(22,6)), nu am urmarit interogarea SQL efectiva care umple crsarticole/crsartselectate (cod probabil in Programe/, in afara ofacturare.vc2, netrasat din lipsa de timp alocat).
  • Nu am confirmat pe date reale (Oracle) daca exista astazi randuri cu DISCOUNT_UNITAR populat pe VANZARI_DETALII provenind din editarea directa in grid pe factura in valuta (punctul 2/3, ultimul paragraf) — doar am aratat ca acea cale exista in cod, fara handler de recalcul.
  • Nu am cautat daca frm_facturare_articole2 (prototipul) e instantiat undeva in productie sau e cu adevarat mort/nefolosit — task-ul l-a framat deja ca "prototip" si am pastrat presupunerea.