Files
roafacturare/docs/cercetare/rec_s5_discount_valuta.md
Marius Mutu b5a7108f34 docs: cercetarile comune trec in COMUN, reziduul #6 dispare, progres.md la zi
Curatenie ceruta dupa inchiderea lui #6. Folderul cercetare\ NU se putea sterge
in bloc: plan_13 se sprijina pe el cu 85 de trimiteri, deci e baza de dovezi a
planului aflat in lucru. Impartirea:

- 14 cercetari trans-proiect trec in COMUN\docs\cercetare\ - valuta si curs,
  TVA/VANZARI, consumatorii VANZARI din toata suita, integrarile #10/#11/#12,
  watchdog VFP, proiectarea Oracle a lui S5, view-ul VVANZARI_ARTICOLE. Nu sunt
  ale ROAFACTURARE, iar #10/#11/#12 se reiau chiar din ele.
- 20 de rapoarte de executie ale lui #6, nereferite de nimic viu, sterse.
- 91 raman, neatinse.

Trimiterile catre handoff-urile si diff-urile intermediare deja desfiintate au
fost curatate peste tot (39 de fisiere): 50 catre handoff-uri, 37 catre diff-uri
aplicate, plus caile celor mutate in COMUN. Zero trimiteri rupte ramase.

progres.md preia rolul de predare: ce ramane din #6 (cele sase documente
parazite, cele doua esecuri reale din S8 pe factura din aviz), cifrele de test
citite din log, si cele doua capcane de mediu platite - .FXP vechi executat in
locul .prg-ului, si GETFONT() care atarna un formular instantiat fara goApp.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SN8snvkk94KuhWwoXUUey3
2026-08-11 22:31:42 +03:00

11 KiB

S5 — parametrul de discount si documentele in valuta. Rezultat

Inchide cele doua goluri declarate de docs\cercetare\rec_s5_scriere_reala.md, sectiunea „Ce NU acopera testul". Suita: COMUN\utile\Teste\editare_factura\test_s5_discount_valuta.prg. Log: COMUN\utile\Teste\editare_factura\test_s5_discount_valuta_log.txt (rulare 10.08.2026, 00:05:16-00:05:21). Diff: diff aplicat (sters).

Rezultat

46 PASS / 0 FAIL, numarate din log. Zero linii EROARE, ultima linie e done, deci rularea a ajuns la capat. Starea finala e verificata independent prin sqlplus, nu din logul testului.

VERDICTUL pe NULL: PASTREAZA. Nu zeroeaza.

Dovedit pe date, in doua contexte diferite, prin patru apeluri succesive in aceeasi tranzactie, cu citirea starii necomise intre ele (log, blocul A):

Apel VANZARI.DISCOUNT DISCOUNT_TVA TOTAL_FARA_TVA TOTAL_TVA TOTAL_CU_TVA
stare initiala 0 0 747.96 157.06 905.02
recalculeaza_totaluri_vanzari(1049, NULL) 0 0 747.96 157.06 905.02
recalculeaza_totaluri_vanzari(1049, 12.5) 12.50 2.63 735.46 154.43 889.89
recalculeaza_totaluri_vanzari(1049, NULL) 12.50 2.63 735.46 154.43 889.89
recalculeaza_totaluri_vanzari(1049, 0) 0 0 747.96 157.06 905.02

Randul al patrulea e verdictul: NULL peste un discount de 12.50 il lasa 12.50, si lasa toate totalurile neschimbate pana la a patra zecimala (asertia A3 compara exact, cu toleranta 0.0001, nu aproximativ). Randul al cincilea arata contrastul: 0 explicit chiar zeroeaza — deci cele doua valori nu se confunda in implementare.

Acelasi verdict, repetat pe calea de valuta (blocul B, id_vanzare = 1037): discount 10 -> NULL -> discount ramane 10, ftva/tva/valval/tvaval neschimbate.

Codul si datele concorda

ff_2026_08_09_01_COMUN_PACK_FACTURARE.sql:16043-16046:

SELECT NVL(V_DISCOUNT, discount), in_valuta, NVL(discount_evidentiat, 0)
  INTO lnDiscountFactura, lnInValuta, lnDiscountEvidentiat
  FROM vanzari
 WHERE id_vanzare = V_ID_VANZARE;

NVL(V_DISCOUNT, discount) — parametrul nul cade pe valoarea din tabela, iar UPDATE-ul final (:16215) scrie inapoi discount = lnDiscountFactura. Citirea corpului si comportamentul pe date spun acelasi lucru. Nu am gasit nicio divergenta si niciun defect in procedura.

Cum se comporta o valoare nenula

Document in RON (in_valuta = 0): discountul se scade ca atare din baza fara TVA, iar TVA-ul lui se scade din TVA. Cu PPRETV = 2 si cota maxima 1.21 pe liniile active:

total_fara_tva = 747.96 - 12.50            = 735.46
discount_tva   = ROUND(12.50 * 0.21, 2)    =   2.63
total_tva      = 157.06 -  2.63            = 154.43
total_cu_tva   = 735.46 + 154.43           = 889.89

VALOARE_ACHIZITIE ramane 263.31 — nu depinde de discount, verificat explicit (A2).

Document in valuta (in_valuta = 1): discountul e exprimat in valuta. In RON se scade convertit prin cursul documentului, in valuta se scade brut — ramura decode(in_valuta, 1, ROUND(curs * discount / multiplicator, PPRETV), discount) (:16073-16092). Pe id_vanzare = 1037 (id_valuta = 2, curs = 5.2688, multiplicator = 1), cu discount 10:

discount in RON = ROUND(5.2688 * 10 / 1, 2) = 52.69
total_fara_tva  = 1053.76 - 52.69           = 1001.07
total_tva       =  221.29 - ROUND(52.69 * 0.21, 2) = 221.29 - 11.06 = 210.23
valval          =  200 - 10                 =  190.00
discount_tva    = ROUND(10 * 0.21, 2)       =    2.10   (TVA-ul discountului, in VALUTA)
tvaval          =   42 -  2.10              =   39.90
totval          =  190 + 39.90              =  229.90

Toate cele sapte valori au fost calculate in test din starea de plecare si comparate cu ce a scris procedura. ID_VALUTA, CURS si MULTIPLICATOR raman 2 / 5.2688 / 1 dupa recalcul.

De consemnat, pentru cine citeste coloanele: DISCOUNT_TVA retine DISC_TVA_VAL, adica TVA-ul discountului in valuta (2.10), nu in RON (11.06) — pe documentele in RON cele doua coincid, pe cele in valuta nu. Nu e defect, scrie_in_vanzari face la fel; e doar neevident din nume.

Documentele in valuta EXISTA. Premisa contrara era gresita.

Nota anterioara („nu exista in schema un document descoperibil simultan cu articole si in valuta reala") nu se confirma. In MARIUSM_AUTO:

  • 28 de randuri VANZARI cu IN_VALUTA = 1;
  • 25 dintre ele au cel putin o linie activa in VANZARI_DETALII;
  • 8 au si ID_VALUTA / CURS / MULTIPLICATOR completate si rand in VANZARI_CURSURI: id_vanzare 329, 627, 678, 859, 864, 947, 952, 1037.

Celelalte 17 sunt degenerate (ID_VALUTA si CURS nule pe cap), deci nu sunt cazuri de test bune.

Ales: id_vanzare = 1037, cod = 1140730, din 07.05.2026, o linie activa (det = 1565, cantitate 1, pret 200 in valuta, pret_cu_tva = 0, proc_tvav = 1.21, pret_achizitie = 100), totaluri persistate 1053.76 / 221.29 / 1275.05 in RON si 200 / 42 / 242 in valuta.

Recalculul reproduce exact starea persistata a acestui document, si in RON si in valuta (asertiile B1). Asta e proba directa ca agregarea din procedura — inclusiv conversia prin VANZARI_CURSURI — e corecta pe un document in valuta emis pe cale normala, nu doar pe unul simulat in VFP. Golul lasat de test_adauga_linie_valuta.prg (care suprascria tvanz manual) e inchis pe partea de Oracle.

Ce NU se poate acoperi pe documentele in valuta

Niciunul dintre cele 8 nu e din luna curenta (cel mai recent e din 05.2026, restul din 2009-2022), iar garda din do_editare_factura cere data_act in luna de lucru. Deci lantul complet de editare nu poate fi rulat pe un document in valuta — pe date exista doar recalculul Oracle, care e insa exact partea despre care nu se stia nimic. Documentul fiind arhiva, blocul B se inchide cu ROLLBACK: 1037 e verificat prin sqlplus dupa test si e neatins.

Lantul real de salvare cu discount nenul (blocul C)

Singurul bloc care comite. Documentul 1049 a primit discount 12.5 prin chiar procedura testata (commit), apoi a trecut prin lantul complet de editare fara nicio modificare de linii:

recalculeaza_totaluri_vanzari(1049, 12.5)   -- COMMIT, pregatire
  IncarcaVanzareDinNota -> tvanz.discount = 12.5000       <- proba C2
MyDeschideTranzactie()
  OSCRIE_IN_FISIERE(2, .T., .T.)  => 1
  OSCRIE_IN_FISIERE(0, .T., .T.)  => 1
  pack_contafin.finalizeaza_modificare_nota => 1
    [in tranzactie] cod 1140897 -> 1140898, discount INCA 12.50   <- proba C3
  ScrieArticoleFacturaEditate(1049) => 1
MyInchideTranzactie(1)                       -- COMMIT
  [dupa commit] discount 12.50, ftva 735.46, tva 154.43, ctva 889.89   <- proba C5
recalculeaza_totaluri_vanzari(1049, 0)      -- COMMIT, restaurare

Trei lucruri pe care doar acest bloc le stabileste:

  1. tvanz.discount chiar aduce discountul din VANZARI. IncarcaVanzareNota (ofacturare_editare.prg:177) selecteaza v.discount direct din VANZARI, iar helperul citeste de acolo (:485-486). Daca cursorul l-ar fi adus 0, salvarea ar fi sters discountul documentului — exact riscul din briefing. Nu se intampla.
  2. finalizeaza_modificare_nota nu atinge DISCOUNT. Citit in tranzactie, dupa realinierea COD-ului: 1140897 -> 1140898, discount inca 12.50. Concorda cu corpul lui actualizeaza_vanzari (:16012-16022), care scrie doar VANZARI_DETALII.STERS, VANZARI.COD si VANZARI.STERS.
  3. Discountul supravietuieste unei salvari complete, cu totalurile recalculate coerent (735.46 + 154.43 = 889.89).

NULL nu ajunge azi in procedura pe calea VFP decat daca VANZARI.DISCOUNT e NULL in baza — helperul trimite NULL doar la Isnull(discount) (:546), altfel trimite valoarea. Pe 1049 discountul e 0, nu NULL, deci calea reala trimite mereu o valoare. Ramura NULL a helperului nu e atinsa de acest test; contractul procedurii pe NULL este insa dovedit direct (blocurile A si B).

Verificarea independenta prin sqlplus (dupa test, cu procesul VFP terminat)

MARIUSM_AUTO/…@ROA_CENTRAL:

1049: cod=1140898 sters=0 in_valuta=0 discount=0 discount_tva=0 val_ach=263.31
      ftva=747.96 tva=157.06 ctva=905.02 valval=747.96 tvaval=157.06 totval=905.02
linii 1049: det=1581 sters=0 cant=2 pret=302.51 pret_ach=10
            det=1582 sters=1 cant=1 pret=121.30 pret_ach=0
            det=1583 sters=0 cant=1 pret=150.00 pret_ach=10
            det=1588 sters=0 cant=3 pret=50.00  pret_ach=77.77
1037: cod=1140730 sters=0 in_valuta=1 discount=0 discount_tva=0 val_ach=100
      ftva=1053.76 tva=221.29 ctva=1275.05 valval=200 tvaval=42 totval=242
      id_valuta=2 curs=5.2688 multiplicator=1        -- NEATINS
1050: cod=1140895 discount=0 total_cu_tva=1924.59    -- NEATINS
vact_tot 08.2026: cod=1140897 randuri=10 sterse=10 | cod=1140898 randuri=10 sterse=0
v$transaction pe MARIUSM_AUTO: 0 randuri

1049 e exact in starea de dinaintea acestui test pe toate coloanele de valoare — singura schimbare e COD. Structura liniilor e neschimbata (aceleasi 3 active, 1582 ramane stearsa din testul precedent).

Date de test consumate

  • Un singur cod realocat: 1140897 -> 1140898 pe id_vanzare = 1049. Cine reia testul citeste cod-ul curent din VANZARI, nu-l presupune.
  • Nimic altceva. Zero linii adaugate sau sterse, zero valori de totaluri lasate schimbate, DISCOUNT restaurat la 0. Blocurile A si B nu consuma nimic (ROLLBACK).
  • id_vanzare = 1050 si id_vanzare = 1037 sunt neatinse, verificat prin sqlplus.

Ce NU acopera nici acest test

  • Liniile din seturi (id_vanzare_set nenul) — niciunul dintre documentele folosite nu are asa ceva, deci ramura union all din agregare (:16178-16209), care ia totalurile din capul de set, ramane neatinsa. Neschimbat fata de raportul precedent.
  • Lantul complet de editare pe un document in valuta — imposibil azi: niciun document in valuta nu e din luna curenta (vezi mai sus). Doar recalculul Oracle e acoperit.
  • Ramura NULL a helperului (ofacturare_editare.prg:546) — cere VANZARI.DISCOUNT NULL in baza, ceea ce nu s-a fabricat.
  • discount_evidentiat = 1 — toate documentele folosite au 0; ramura care distribuie discountul pe linii nu e atinsa.
  • Cele cinci validari din inainte_de_do_termin, frm_modific2024, al doilea punct de intrare (comun.vc2:2491) si calea de ROLLBACK la esec partial raman neacoperite, ca inainte.

Igiena la iesire

Zero tranzactii deschise (v$transaction, 0 randuri), zero procese vfp9.exe (tasklist), zero commituri git sau SVN. Niciun fisier de productie atins: singurul fisier nou este suita de test. PACK_FACTURARE, omodificari.vc2, ofacturare_comun.vc2, comun.vc2, ofacturare_editare.prg si COMUN\clase\ofacturare.vc2 sunt neatinse.