sync SVN r18026

This commit is contained in:
2026-08-20 22:44:52 +03:00
parent ca3c5d7eea
commit 5b52cb3999
9 changed files with 1481 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
<!-- <!--
19/08/2026 20/08/2026
ROAFACTURARE - 2.11.15 ROAFACTURARE - 2.11.15
:nou: :nou:
@@ -7,11 +7,23 @@ ROAFACTURARE - 2.11.15
Pe linia de articol se poate alege explicatia TVA. Lista propune doar explicatiile cu cota TVA a liniei, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa. Pe linia de articol se poate alege explicatia TVA. Lista propune doar explicatiile cu cota TVA a liniei, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa.
Lista de facturi, butonul de modificare a explicatiei articolului: se poate alege acum si explicatia TVA. Lista propune doar explicatiile cu aceeasi cota de TVA ca linia facturii, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa. Valorile facturii raman neschimbate - nu se recalculeaza cota si nici totalurile documentului.
:modificare: :modificare:
Totalul notelor din bara de jos se actualizeaza imediat dupa modificarea sumei de pe randul de nota, nu doar la editarea articolelor. Totalul notelor din bara de jos se actualizeaza imediat dupa modificarea sumei de pe randul de nota, nu doar la editarea articolelor.
Fereastra de sincronizare articole - rulaje: coloanele arata acum ce valoare se inlocuieste si de unde se preia cea noua, in loc de "vechi" si "nou" explicate separat. Fereastra de sincronizare articole - rulaje: coloanele arata acum ce valoare se inlocuieste si de unde se preia cea noua, in loc de "vechi" si "nou" explicate separat.
Sincronizarea articole - rulaje porneste doar din butonul de pe pagina Articole. Nu mai apare automat la salvarea notei.
Sincronizarea articole - rulaje completeaza pe randul de rulaj si pretul fara TVA, si TVA-ul unitar - pana acum se actualizau doar cantitatea si pretul cu TVA.
Editare factura, pagina Articole: seria, lotul si explicatia se tasteaza direct in grid, iar articolul, gestiunea, valuta, explicatia TVA si codul de taxa SAF-T se aleg prin dublu clic pe celula. Culorile arata la ce foloseste fiecare coloana: alb - se tasteaza direct, verde - se alege dintr-o lista, gri - nu se poate edita.
Editare factura, pagina Articole: pretul si pretul cu TVA se afiseaza cu numarul de zecimale stabilit pentru preturile de vanzare, nu cu cel pentru preturile de achizitie.
Optiunea de meniu prin care se deschide editarea se numeste acum "Editare factura (note, rulaje, articole)".
:eroare: :eroare:
S-a corectat o eroare la descarcarea articolelor importate din eFactura, care aveau pret de achizitie cu 4 zecimale. S-a corectat o eroare la descarcarea articolelor importate din eFactura, care aveau pret de achizitie cu 4 zecimale.

218
docs/brief_r6_punct6_vfp.md Normal file
View File

@@ -0,0 +1,218 @@
# Brief de implementare — runda 6, punctul 6, partea VFP
Explicatia TVA in dialogul de modificare a articolului din `frm_facturi`. Proiectarea completa:
`docs\propunere_runda6_punct6_plsql.md`, sectiunea "Ce ramane de facut in VFP". Acest brief e
executabil: contine liniile exacte, valorile exacte si ce s-a verificat deja.
## Interdictii (citeste-le inainte de orice)
- **NU rula `git_sync.ps1`, `roa_sync.bat`, `svn update`, `svn commit`, `git commit`, `git push`.**
- **NU atinge alt fisier** in afara de `COMUN\clase\ofacturare_comun.vc2` (+ binarul lui prin
write-back) si `docs\raport_r6_punct6_vfp.md` (raportul tau).
- **NU modifica PL/SQL** — pachetul e deja aplicat pe `MARIUSM_AUTO` si verificat.
- **NU schimba `Text1.ReadOnly` nicaieri**, nu atinge grid-ul de articole, nu atinge `omodificari.vc2`.
- Esti **singurul scriitor** pe `ofacturare_comun.vc2`. Daca gasesti modificari necomise pe el la
start, opreste-te si raporteaza.
## Starea de plecare
- `svn`/`git` curate, r18025. Textele `.??2` sunt la zi (git_sync: 0 convertite, 463 la zi).
- Oracle: `MARIUSM_AUTO.PACK_FACTURARE` are deja semnatura noua, verificata pe sursa vie:
```
PROCEDURE modifica_explicatie_articol(V_ID_VANZARE_DET IN NUMBER,
V_EXPLICATIE IN VARCHAR2,
V_ID_UTIL IN NUMBER,
V_TAXCODE IN NUMBER DEFAULT NULL,
V_ID_JTVA_COLOANA IN NUMBER DEFAULT NULL);
```
Al 5-lea parametru lipsa/NULL => ramura veche (se scriu doar `EXPLICATIE` si `TAXCODE`).
## Fapte verificate pe cod — nu le re-investiga
1. `crsDetalii` (`oproceduri_facturare.prg:382-400`) are: `id_vanzare`, `id_vanzare_det`,
`proc_tvav`, `id_jtva_coloana`, `jtva_coloana`, `taxcode`, `taxname`, `sters`, `explicatie`.
**Nu are `data_act` si nu are `id_part`.**
2. `crsfacturi` (`oproceduri_facturare.prg:339-360`) are `data_act`, `id_part`, `id_vanzare`.
Randul curent din `crsfacturi` **este** antetul liniei editate: `crsDetalii` se filtreaza pe
`id_vanzare=` al randului curent din `crsfacturi` (`ofacturare_comun.vc2:3621-3623`).
3. `proc_tvav` e **multiplicator** (1.19), `cota_tva` din `vjtva_coloane` e **procent** (19).
Cota liniei = `Round((Nvl(poRec.proc_tvav,0) - 1) * 100, 2)`.
4. Filtrul de explicatii e cel din `caut_explicatie_tva` (`ocautare.prg:3193, 3220`):
`id_jtva_coloana > 0` + `cota_tva = <cota>`, pe view-ul `vjtva_coloane`.
**Nu** folosi `update_jtva_coloane` — acela adauga restrictii pe `afisat` si pe `cote_tva` de
an/luna curenta, care nu sunt in proiectarea aprobata.
5. `GetTaxCodeIdPart` (`oproceduri_comune.prg:6059-6125`) e apelabila din `frm_facturi`, isi
gestioneaza singura cursorul `jtva_coloane`, si **returneaza `.NULL.` daca `gl406` e `.F.`**
(`:6086-6088`) — de aceea apelul se face doar sub garda `gl406`, altfel ar sterge `taxcode`-ul.
6. `tlNeexigibil` = `.F.` (parametru **omis**). Confirmat, nu presupus: calea de emitere a
facturii foloseste `GetTaxCode(gnAn, gnLuna, ldDataAct, lnIdJtva, .F.)` cu ultimii trei
parametri impliciti (`ofacturare.vc2:2529` si `:3101`), iar pe jurnal de vanzari (`jv`)
`GetTaxCodeIdPart` degenereaza exact in acel apel (ramura `llJC` e `.F.`, `:6098-6110`).
Deci butonul produce acelasi `taxcode` pe care l-ar produce emiterea.
7. `n50`/`n100` = `.F.` (parametri omisi), ca in `ointroduceri.vc2:11488`.
## Modificarile — fisier `COMUN\clase\ofacturare_comun.vc2`
Ruleaza intai `vfp_symbols.ps1 -Where` ca sa confirmi domeniul fiecarei metode inainte sa editezi;
numerele de linie de mai jos sunt de la starea r18025 si se pot deplasa dupa prima editare.
### M1 — `frm_facturi.do_modifica_explicatie` (~`:4642-4659`)
Dupa `Scatter Name poRec Memo` si inainte de `If poRec.sters = 0`, ataseaza antetul pe `poRec`
(vezi faptul 1 si 2 — campurile nu exista pe `crsDetalii`):
```foxpro
AddProperty(poRec, 'data_act', crsfacturi.data_act)
AddProperty(poRec, 'id_part', Nvl(crsfacturi.id_part, 0))
```
Restul metodei ramane neschimbat (`update_saft_taxtable()` ramane unde e).
### M2 — layout `frm_modifica_articol_factura` (~`:5131`)
Randul existent cu `cbo_saft` coboara, iar deasupra lui intra randul nou de explicatie TVA.
Valori exacte:
| obiect | proprietate | din | in |
|---|---|---|---|
| `frm_modifica_articol_factura` | `Height` | 370 | **431** |
| `_shape3` | `Top` | 323 | **384** |
| `cbo_saft` | `Top` | 329 | **390** |
| `lbSaft` | `Top` | 332 | **393** |
Obiecte noi (toate in `*<PropValue>` / `ADD OBJECT`, plus linii `*< OBJECTDATA ... >` in blocul de
ZOrder de la inceputul clasei):
- `_shape4` AS `_shape` OF `_baza.vcx` — `BackStyle=0, Left=13, Top=323, Height=58, Width=348`
- `lbExplTva` AS `_label` OF `_baza.vcx` — `Caption="Explicatie TVA", Left=24, Top=332`
(diacriticele: vezi sectiunea de encoding mai jos; textul afisat corect e `Explicație TVA`)
- `cbo_expl_tva` AS `_cbbase` OF `_cb_base.vcx` — modelat dupa `cbo_saft`:
`BoundColumn=3, BoundTo=.T., ColumnCount=2, ColumnWidths="400,60", Height=24, Left=110,`
`Top=329, Width=238, RowSourceType=3`.
**`ControlSource` ramane gol** (nu legam direct de `poRec.id_jtva_coloana` — valoarea aleasa se
preia in `InteractiveChange`, ca sa putem distinge "userul a atins combo-ul" de "n-a atins").
`RowSource` se construieste in `Init` (vezi M3), nu se scrie in `ADD OBJECT`.
- `lbExplTvaInfo` AS `_label` OF `_baza.vcx` — `Caption="", Left=24, Top=355, Width=324,`
`Height=20, WordWrap=.T., ForeColor=RGB(128,0,0), Visible=.F.`
Proprietate noua de formular: `nidjtvaales`.
**Obligatoriu si intrarea `*p: nidjtvaales` in `*<DefinedPropArrayMethod>`, nu doar valoarea in
`*<PropValue>`** — fara `*p:` valoarea trece fidelity-check-ul, ajunge in binar, dar VFP nu
materializeaza proprietatea si orice acces cade cu eroarea 1734. Valoare initiala: `nidjtvaales = 0`.
### M3 — `frm_modifica_articol_factura.Init`
La finalul metodei `Init` existente (dupa blocul care citeste `citeste_lungcampexplart`), adauga
popularea combo-ului. Comportamentul cerut de proiectare, in trei ramuri:
```foxpro
Local lnCota, lcSqlTva, lcCursorTva
Thisform.nidjtvaales = 0
If Isnull(poRec.proc_tvav) Or Nvl(poRec.proc_tvav, 0) = 0
Thisform.cbo_expl_tva.Enabled = .F.
Thisform.lbExplTvaInfo.Caption = [Cota de TVA a acestei linii nu este cunoscuta; explicatia TVA nu poate fi modificata prin acest buton.]
Thisform.lbExplTvaInfo.Visible = .T.
Return
Endif
lnCota = Round((poRec.proc_tvav - 1) * 100, 2)
lcCursorTva = [crsExplTvaArt]
lcSqlTva = [select id_jtva_coloana, denumire, cota_tva from vjtva_coloane where id_jtva_coloana > 0 ] + ;
[and cota_tva = ] + Alltrim(Str(lnCota, 10, 2)) + [ order by denumire]
If goExecutor.oExecuta(lcSqlTva, lcCursorTva) And Reccount(lcCursorTva) > 0
Thisform.cbo_expl_tva.RowSource = [select denumire, cota_tva, id_jtva_coloana from ] + lcCursorTva + [ into cursor crsExplTvaCbo]
Thisform.cbo_expl_tva.Requery()
Thisform.cbo_expl_tva.Value = Nvl(poRec.id_jtva_coloana, 0)
Else
Thisform.cbo_expl_tva.Enabled = .F.
Thisform.lbExplTvaInfo.Caption = [Nu exista nicio explicatie TVA activa cu aceeasi cota ca linia facturata (cota: ] + ;
Alltrim(Str(lnCota, 10, 2)) + [ %).]
Thisform.lbExplTvaInfo.Visible = .T.
Endif
```
Note de implementare, nu le sari:
- `Alltrim(Str(lnCota,10,2))` produce `19.00`; comparatia cu `cota_tva` (NUMBER(10,0)) e corecta
in Oracle. Nu formata cu virgula.
- daca `Init` are `Return` propriu / `NODEFAULT`, verifica sa nu scurtcircuitezi codul existent.
- inchide cursorul `crsExplTvaArt` in `Destroy` daca ramane deschis (`If Used(...) : Use In ...`).
- textul mesajelor **fara diacritice** (asa sunt scrise si celelalte mesaje din aceasta clasa,
ex. `:4635`) — evita complet problema de encoding pe siruri noi.
### M4 — `cbo_expl_tva.InteractiveChange` (metoda noua)
```foxpro
PROCEDURE cbo_expl_tva.InteractiveChange
Local lnIdJtva
lnIdJtva = Nvl(This.Value, 0)
If lnIdJtva <= 0
Return
Endif
Thisform.nidjtvaales = lnIdJtva
poRec.id_jtva_coloana = lnIdJtva
If Type('gl406') = 'L' And m.gl406
poRec.taxcode = GetTaxCodeIdPart(m.gnAn, m.gnLuna, poRec.data_act, m.lnIdJtva, poRec.id_part)
Thisform.cbo_saft.Refresh()
Endif
ENDPROC
```
### M5 — `inainte_de_do_termin` (~`:5227-5235`)
Al 5-lea parametru pozitional, **literal, nu bind** — ca sa poata fi `null` curat cand userul n-a
atins combo-ul (atunci procedura ramane pe ramura veche):
```foxpro
Local lcParamJtva
lcParamJtva = Iif(Vartype(Thisform.nidjtvaales) = 'N' And Thisform.nidjtvaales > 0, ;
Alltrim(Str(Thisform.nidjtvaales)), [null])
lcSql = [begin pack_facturare.modifica_explicatie_articol(] + Alltrim(Str(poRec.id_vanzare_det)) + [,] + ;
['] + Nvl(Alltrim(OracleSpecialCharacters(poRec.explicatie)),'') + [',?gnIdUtil,?poRec.taxcode,] + lcParamJtva + [); end;]
llReturn = goExecutor.oExecuta(lcSql)
```
Restul metodei (confirmarea `amessagebox`, `Return llReturn`) ramane neschimbat. Erorile
`FACT-026..029` ies deja vizibil prin `goExecutor.oExecuta` — nu adauga cod de afisare.
### M6 — refresh dupa salvare
**Nimic de facut.** `Thisform.actualizeaza_grid2()` din `do_modifica_explicatie` (`:4654`) e
suficient: headerul nu se schimba, totalurile nu se recalculeaza.
## Encoding — capcana platita deja
Fisierele `.vc2` din acest arbore au diacriticele in **cp1250, nu cp1252**. Tool-ul `Edit` le
transforma in U+FFFD si strica textul din alte proprietati.
- **numara octetii > 0x7F inainte si dupa fiecare editare** — trebuie sa iasa acelasi numar;
- daca s-au stricat, repara cu encoding `28591`;
- pentru sirurile **noi** pe care le scrii tu: **fara diacritice**, deci problema nu apare de la
tine — dar poate aparea de la o rescriere a fisierului.
## Write-back si verificare
1. `txt2vcx.ps1 ... -AllowComun` — se ruleaza **direct, fara aprobare** (regula lui Marius).
2. Fidelity-check: FoxBin2Prg **nu pastreaza ordinea textuala** pentru `ADD OBJECT` multiple si
proprietati custom, si sorteaza cu `_` **dupa** litere. Daca primul write-back da FAIL pe
ordine: **adopta ca sursa textul regenerat din `<staging>\verify\*.vc2`**, nu incerca sa
ghicesti ordinea corecta.
3. **`mtime` nu dovedeste sincronizarea text/binar** — `txt2vcx.ps1` rescrie mtime-ul textului.
Dovada ceruta: reconverteste binarul intr-un cache temporar si fa `diff` cu textul din arbore;
raporteaza numarul de linii diferenta (trebuie 0).
## Ce raportezi
Scrie **pe disc**, la `D:\ROA\ROAFACTURARE\docs\raport_r6_punct6_vfp.md`, si raspunde in chat doar
cu `GATA` + calea. In raport:
- inventarul modificarilor cu `fisier:linie` (dupa write-back, deci pe numerotarea finala);
- confirmarea explicita ca write-back-ul e facut si **numarul de linii diferenta** la reconversie;
- numarul de octeti > 0x7F inainte si dupa;
- ce n-ai putut face si de ce;
- **nu comite nimic**; nu rula sincronizari.
Daca te apropii de ~200-250k tokens de context, opreste-te la o stare consistenta pe disc, scrie
raportul cu ce ai facut si ce ramane, si anunta — nu continua.

View File

@@ -0,0 +1,139 @@
# Brief de implementare — runda 7: sincronizarea articole-rulaje
Doua cereri ale lui Marius, 20.08.2026 (dupa proba pe ecran a rundei 6):
1. sincronizarea sa porneasca **doar din buton**, nu sa se mai arate la terminarea editarii;
2. la directia **ARTICOLE_SURSA** (articole -> rulaj) se copiaza `pretvtva`, dar **nu** si `pretv`
si `tvav`, care raman vechi.
## Interdictii (citeste-le inainte de orice)
- **NU rula `git_sync.ps1`, `roa_sync.bat`, `svn update`, `svn commit`, `svn revert`, `git commit`,
`git push`, `git stash`, `git checkout`.**
- **NU atinge `COMUN\clase\ofacturare_comun.vc2`** — are o livrare separata, verificata, necomisa.
Orice scriere acolo distruge munca altcuiva.
- **NU atinge PL/SQL**, nu te conecta la Oracle pentru scriere.
- Fisierele tale, singurele: `COMUN\clase\omodificari.vc2` (+ binarul prin write-back),
`COMUN\programe\ofacturare_editare.prg`, si raportul `docs\raport_r7_sincronizare.md`.
- Esti singurul scriitor pe ele. Daca gasesti alte modificari necomise acolo, opreste-te si raporteaza.
## M1 — sincronizarea porneste doar din buton
`COMUN\clase\omodificari.vc2`, metoda `inainte_de_do_termin` a clasei `frm_modific2024`,
blocul de la **`:14484-14494`** (numerele se deplaseaza dupa prima editare — confirma cu
`vfp_symbols.ps1 -Where`):
```foxpro
*!* al doilea punct de declansare al sincronizarii: enumerarea diferentelor la salvare, cu
*!* continuarea salvarii daca utilizatorul renunta - de aceea llRet nu se schimba aici;
*!* pe document fara linii active nu porneste: propunerea ar marca toata sursa ca "Adaugare"
IF m.llRet AND This.lAreArticoleVanzari AND !This.lArticoleReadOnly AND Used('tvd') AND m.lnLiniiActive > 0
LOCAL lcSemnaturaAcum
lcSemnaturaAcum = This.SemnaturaDivergenteSincronizare()
*!* doar divergentele aparute in sesiunea curenta deschid dialogul; N-A nu intra in semnatura
IF !Empty(m.lcSemnaturaAcum) AND !(m.lcSemnaturaAcum == This.cSemnaturaSincronizare)
This.AfiseazaDialogSincronizareArticole()
ENDIF
ENDIF
```
**Se sterge integral, cu tot cu cele patru linii de comentariu.** `RETURN m.llRet` de dupa ramane.
Nu atinge butonul `pgfArticole.PAGE3.cmdSincronizeazaArticole.Click` (`:16671`) — el ramane singura
cale de pornire.
**Nu sterge** metoda `SemnaturaDivergenteSincronizare`, proprietatea `cSemnaturaSincronizare` si
atribuirea ei de la `:14956`. Dupa aceasta stergere raman fara consumator — **semnaleaza asta in
raport**, ca decizia de curatare sa fie a lui Marius, dar nu o lua tu.
## M2 — `pretv` si `tvav` se recalculeaza la scrierea in rulaj
`COMUN\programe\ofacturare_editare.prg`, `FUNCTION AplicaModificareTrul` (**`:924`**). Azi:
```foxpro
lcCampCant = IIF(Nvl(cant,0) <> 0, 'cant', 'cante')
REPLACE (m.lcCampCant) WITH m.tnCantitateNoua, pretvtva WITH m.tnPretNouCuTva IN trul
```
Formula corecta **exista deja** si e sursa de adevar — nu inventa alta: `omodificari.vc2`,
`calculeaza_valori_rul`, ramura `pretvtva` (**`:13566-13587`**):
```foxpro
lnProcTvav = IIF(EMPTY(proc_tvav), 1, proc_tvav) - 1 && 1.19 -> 0.19
lnTVAv = ROUND(lnPretVtva * lnProcTVAv / (1 + lnProcTvav), gnPPretv)
lnPretv = lnPretvtva - lnTvav
lnValoarecTVA = ROUND(lnCantitate * lnPretvTva, gnPC)
lnValoareTVA = ROUND(lnValoarecTVA * lnProcTVAv / (1 + lnProcTvav), gnPC)
lnValoareFTva = lnValoareCtva - lnValoareTVA
REPLACE pretv, pretvtva, tvav, valoarev, valtvav, valoarevcTVA
```
Atentie la precizii, sunt **doua diferite**: `pretv`/`tvav`/`pretvtva` se rotunjesc la **`gnPPretV`**
(precizia pretului de **vanzare**), iar `valoarev`/`valtvav`/`valoarevcTVA` la **`gnPC`**.
**Nu** apela `toForm.calculeaza_valori_rul()` in locul calculului: metoda alege cursorul din
`This.pgfArticole.ActivePage` (`:13532-13533`) — `trul` doar cand pagina activa e 1. Sincronizarea
porneste de pe pagina 3, deci ar nimeri `trul_obinv`. Calculeaza in `AplicaModificareTrul`, unde
esti deja pozitionat pe randul corect din `trul`.
Ordinea conteaza: cantitatea se scrie **inainte** de a citi `cant`/`cante` pentru valori, altfel
valorile ies pe cantitatea veche.
**Include si `valoarev`, `valtvav`, `valoarevcTVA`.** Marius a numit doar `pretv` si `tvav`, dar
sincronizarea schimba si cantitatea, iar cele trei valori depind de `cantitate x pretvtva`; lasate
nescrise raman la fel de vechi ca `pretv`. E semnalat lui ca depasire fata de cerere.
Actualizeaza si comentariul-antet al lui `AplicaSincronizareArticole` (`:787-794`), care azi spune
*"ARTICOLE_SURSA scrie doar cant/pretvtva pe randul RUL deja existent"* — a devenit fals.
## Teste — obligatoriu, nu optional
Exista suite care acopera exact zona atinsa:
- `COMUN\utile\Teste\editare_factura\test_s4b_sincronizare.prg` (42 cazuri; **sectiunea C** e chiar
`AplicaSincronizareArticole` pe directia `ARTICOLE_SURSA`, care scrie in `trul`)
- `COMUN\utile\Teste\editare_factura\test_s4b_dialog.prg` (35 cazuri)
Ruleaza-le pe amandoua **dupa** modificari. Reguli platite deja, respecta-le:
- **sterge `.fxp`-ul** inainte de fiecare rulare, altfel se executa bytecode vechi;
- **o singura suita per apel** de comanda — doua rulari inlantuite in acelasi apel atarna;
- cifra se ia **numarand liniile `PASS`/`FAIL` din log**, iar dovada ca rularea a ajuns la capat e
**linia de `REZULTAT`**; fara ea rularea a fost taiata, indiferent ce zice orice raport.
(Linia de `REZULTAT` contine ea insasi cuvintele `PASS` si `FAIL` — un `Select-String` naiv
raporteaza cu unu mai mult din fiecare.)
Daca sectiunea C pica **pentru ca astepta vechiul comportament** (doar `cant`/`pretvtva`), asta e
asertiune invechita, nu regresie: actualizeaz-o si spune explicit in raport ce ai schimbat si de ce.
Daca pica altceva, **nu modifica testul** — raporteaza.
Detalii de mediu si capcane: `COMUN\docs\depanare_testare_vfp.md`, `COMUN\docs\testare-ui-vfp.md`.
## Encoding si write-back (doar pentru `.vc2`)
- `.vc2` e **CRLF pe toate liniile** si are diacriticele in **cp1250**. Numara octetii >0x7F inainte
si dupa; trebuie acelasi numar, si zero `EF BF BD`. `.prg` se editeaza normal.
- Dupa editarea `.vc2`: `txt2vcx.ps1` **imediat** (se ruleaza direct, fara aprobare):
```
powershell -ExecutionPolicy Bypass -File D:\ROA\UTIL\foxbin2prg\txt2vcx.ps1 `
-TextFile 'D:\ROA\ROAFACTURARE\COMUN\clase\omodificari.vc2' `
-ProjectRoot 'D:\ROA\ROAFACTURARE' -CacheRoot 'D:\ROA\ROAFACTURARE' -AllowComun
```
- daca fidelity-check-ul pica pe ordine, adopta textul din `<staging>\verify\`;
- **dovada de sincronizare**: reconverteste binarul intr-un cache temporar cu `vcx2txt.ps1 -Source
... -CacheRoot <temp> -Force` si fa `diff` cu textul din arbore -> **0 linii diferenta**.
`mtime` nu dovedeste nimic.
- **Inainte de write-back verifica sa nu ruleze `vfp9.exe`** (`Get-Process vfp9`) — tine binarul
blocat. Daca ruleaza, **nu-l omori**: opreste-te si anunta-ma.
## Ce raportezi
Scrie **pe disc**, la `D:\ROA\ROAFACTURARE\docs\raport_r7_sincronizare.md`, si raspunde in chat doar
cu `GATA <cale>`. In raport: inventarul cu `fisier:linie` pe numerotarea finala; confirmarea
write-back-ului cu numarul de linii diferenta la reconversie; octetii >0x7F inainte/dupa; cifrele de
test luate din log (`PASS`/`FAIL` + prezenta liniei `REZULTAT`), pe fiecare suita; ce asertiuni ai
schimbat si de ce; ce n-ai putut face.
Daca te apropii de ~200-250k tokens de context, opreste-te la o stare consistenta pe disc
(write-back facut), scrie raportul cu ce ramane, si anunta.

327
docs/diff_r6_punct6.md Normal file
View File

@@ -0,0 +1,327 @@
# Diff pentru aprobare — runda 6, punctul 6 (partea VFP) + changelog
Stare verificata inainte de livrare:
- write-back facut; text din arbore vs. text reconvertit din binar: **0 linii diferenta**, md5 identic
- octetul diacritic din `lbExplTva.Caption`, citit **din binar**: `0xFE` (cp1250, ca restul clasei)
- 13 octeti >0x7F, zero `EF BF BD`, CRLF pe toate liniile
- `PACK_FACTURARE` cu semnatura noua era deja aplicat pe `MARIUSM_AUTO` / `ROA_CENTRAL`
- proba pe ecran facuta de Marius; a rezultat o corectie de filtru (mai jos)
## Filtrul listei de explicatii TVA — verificat pe date
Prima versiune filtra doar `id_jtva_coloana > 0` + cota liniei, si arata si liniile de TVA.
Interogare read-only pe `vjtva_coloane` (`MARIUSM_AUTO`), 197 de randuri cu `id > 0`:
| `afisat` | ce sunt randurile | exemplu |
|---|---|---|
| 0 | **liniile de TVA** | `TVA LIVR. INTERN 19%` |
| 1 | **bazele** cu cota | `LIVR. INTERN 19%` |
| 2 | neimpozabile/scutite (cota 0) | `LIVR. SCUTITE FARA DREPT DE DEDUCERE` |
Filtrul devine `afisat > 0 and jv = 1`, acelasi pe care il foloseste emiterea facturii
(`ofacturare.prg:170`, `update_jtva_coloane([JV], ...)` cu `tnTip` gol).
`jv = 1` nu a fost cerut explicit, dar fara el o factura de **vanzare** primea si explicatii de
**achizitie** (`ACH. INT. 19% BUNURI VANZARE` are cota 19, deci garda `FACT-029` din PL/SQL le-ar
fi acceptat). Numarul de optiuni ramase per cota, pe datele din `MARIUSM_AUTO`:
```
cota: 0 5 9 11 19 20 21 24
tot: 24 16 36 22 40 18 22 19
afisat>0: 24 9 19 9 21 10 12 11
+ jv=1: 15 3 3 3 3 3 3 3
```
Nicio cota nu ramane cu lista goala, deci ramura "lista goala" ramane teoretica, ca la proiectare.
Restrictia pe `cote_tva` de an/luna curenta pe care o adauga `update_jtva_coloane` **nu** a fost
preluata intentionat: ar goli lista la editarea unei facturi vechi cu cota iesita din uz (24%).
## 1. `COMUN\clase\ofacturare_comun.vc2` (repo COMUN, se comite ca `.vcx` + `.vct`)
```diff
diff --git a/clase/ofacturare_comun.vc2 b/clase/ofacturare_comun.vc2
index 6f7f325..367fd89 100644
--- a/clase/ofacturare_comun.vc2
+++ b/clase/ofacturare_comun.vc2
@@ -4647,6 +4647,8 @@ DEFINE CLASS frm_facturi AS _frmbase OF "_frm_base.vcx"
Select crsDetalii
Scatter Name poRec Memo
poRec.explicatie = NVL(poRec.explicatie, ' ')
+ AddProperty(poRec, 'data_act', crsfacturi.data_act)
+ AddProperty(poRec, 'id_part', Nvl(crsfacturi.id_part, 0))
If poRec.sters = 0
ofrmmodificare = Createobject("frm_modifica_articol_factura")
ofrmmodificare.Show()
@@ -5135,9 +5137,14 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
*< OBJECTDATA: ObjPath="Ed_tx_simplu1" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="cbo_saft" UniqueID="" Timestamp="" />
*< OBJECTDATA: ObjPath="lbSaft" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="_shape4" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="lbExplTva" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="cbo_expl_tva" UniqueID="" Timestamp="" />
+ *< OBJECTDATA: ObjPath="lbExplTvaInfo" UniqueID="" Timestamp="" />
*<DefinedPropArrayMethod>
*p: nid
+ *p: nidjtvaales
*p: ntip_selectie && 0 - cautare in toti delegatii; 1 - cautare in delegatii clientului
*p: orec
*</DefinedPropArrayMethod>
@@ -5145,9 +5152,10 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
*<PropValue>
BorderStyle = 1
DoCreate = .T.
- Height = 370
+ Height = 431
Name = "frm_modifica_articol_factura"
nid = .F.
+ nidjtvaales = 0
ntip_selectie = 0
orec = .F.
Width = 376
@@ -5161,17 +5169,17 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
_shape2.ZOrderSet = 2
Lb_titlu_alb_b121.Caption = "Modific<69> explica<63>ie articol"
Lb_titlu_alb_b121.Name = "Lb_titlu_alb_b121"
- Lb_titlu_alb_b121.TabIndex = 5
+ Lb_titlu_alb_b121.TabIndex = 6
Lb_titlu_alb_b121.ZOrderSet = 3
BUT_TERMIN1.Left = 344
BUT_TERMIN1.Name = "BUT_TERMIN1"
- BUT_TERMIN1.TabIndex = 3
+ BUT_TERMIN1.TabIndex = 4
BUT_TERMIN1.Top = 1
BUT_TERMIN1.ZOrderSet = 4
Gridsort1.Name = "Gridsort1"
But_renunt1.Left = 315
But_renunt1.Name = "But_renunt1"
- But_renunt1.TabIndex = 4
+ But_renunt1.TabIndex = 5
But_renunt1.Top = 1
But_renunt1.ZOrderSet = 6
*</PropValue>
@@ -5181,11 +5189,36 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
Height = 37, ;
Left = 13, ;
Name = "_shape3", ;
- Top = 323, ;
+ Top = 384, ;
Width = 348, ;
ZOrderSet = 0
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="shape" />
+ ADD OBJECT '_shape4' AS _shape WITH ;
+ BackStyle = 0, ;
+ Height = 58, ;
+ Left = 13, ;
+ Name = "_shape4", ;
+ Top = 323, ;
+ Width = 348, ;
+ ZOrderSet = 10
+ *< END OBJECT: ClassLib="_baza.vcx" BaseClass="shape" />
+
+ ADD OBJECT 'cbo_expl_tva' AS _cbbase WITH ;
+ BoundColumn = 3, ;
+ BoundTo = .T., ;
+ ColumnCount = 2, ;
+ ColumnWidths = "400,60", ;
+ Height = 24, ;
+ Left = 110, ;
+ Name = "cbo_expl_tva", ;
+ RowSourceType = 3, ;
+ TabIndex = 2, ;
+ Top = 329, ;
+ Width = 238, ;
+ ZOrderSet = 12
+ *< END OBJECT: ClassLib="_cb_base.vcx" BaseClass="combobox" />
+
ADD OBJECT 'cbo_saft' AS _cbbase WITH ;
BoundColumn = 4, ;
BoundTo = .T., ;
@@ -5197,8 +5230,8 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
Name = "cbo_saft", ;
RowSource = "Select taxname, tip, procent_taxa, taxcode From saft_taxtable where tva = 1 order by taxcode Into Cursor crsTaxTableX", ;
RowSourceType = 3, ;
- TabIndex = 2, ;
- Top = 329, ;
+ TabIndex = 3, ;
+ Top = 390, ;
Width = 266, ;
ZOrderSet = 8
*< END OBJECT: ClassLib="_cb_base.vcx" BaseClass="combobox" />
@@ -5221,20 +5254,54 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
_lbbase1.Name = "_lbbase1"
*< END OBJECT: ClassLib="lb_tx.vcx" BaseClass="container" />
+ ADD OBJECT 'lbExplTva' AS _label WITH ;
+ Caption = "Explica<63>ie TVA", ;
+ Left = 24, ;
+ Name = "lbExplTva", ;
+ TabIndex = 8, ;
+ Top = 332, ;
+ ZOrderSet = 11
+ *< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
+
+ ADD OBJECT 'lbExplTvaInfo' AS _label WITH ;
+ Caption = "", ;
+ ForeColor = RGB(128,0,0), ;
+ Height = 20, ;
+ Left = 24, ;
+ Name = "lbExplTvaInfo", ;
+ Top = 355, ;
+ Visible = .F., ;
+ Width = 324, ;
+ WordWrap = .T., ;
+ ZOrderSet = 13
+ *< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
+
ADD OBJECT 'lbSaft' AS _label WITH ;
Caption = "Cod taxa", ;
Left = 24, ;
Name = "lbSaft", ;
- TabIndex = 6, ;
- Top = 332, ;
+ TabIndex = 7, ;
+ Top = 393, ;
ZOrderSet = 9
*< END OBJECT: ClassLib="_baza.vcx" BaseClass="label" />
+ PROCEDURE Destroy
+ If Used('crsExplTvaCbo')
+ Use In crsExplTvaCbo
+ Endif
+ If Used('crsExplTvaArt')
+ Use In crsExplTvaArt
+ Endif
+ DoDefault()
+ ENDPROC
+
PROCEDURE inainte_de_do_termin
- Local llReturn
+ Local llReturn, lcParamJtva
If amessagebox("Doriti sa salvati modificarile?",4+32,"Confirmare salvare explicatie") = 6
+ lcParamJtva = Iif(Vartype(Thisform.nidjtvaales) = 'N' And Thisform.nidjtvaales > 0, ;
+ Alltrim(Str(Thisform.nidjtvaales)), [null])
lcSql = [begin pack_facturare.modifica_explicatie_articol(] + Alltrim(Str(poRec.id_vanzare_det)) + [,] + ;
- ['] + Nvl(Alltrim(OracleSpecialCharacters(poRec.explicatie)),'') + [',?gnIdUtil,?poRec.taxcode); end;]
+ ['] + Nvl(Alltrim(OracleSpecialCharacters(poRec.explicatie)),'') + [',?gnIdUtil,?poRec.taxcode,] + lcParamJtva + [); end;]
llReturn = goExecutor.oExecuta(lcSql)
Else
llReturn = .F.
@@ -5258,6 +5325,46 @@ DEFINE CLASS frm_modifica_articol_factura AS frm_termin_renunt OF "_frm_child.vc
Endwith
Endif
+ Local lnCota, lcSqlTva, lcCursorTva
+ Thisform.nidjtvaales = 0
+
+ If Isnull(poRec.proc_tvav) Or Nvl(poRec.proc_tvav, 0) = 0
+ Thisform.cbo_expl_tva.Enabled = .F.
+ Thisform.lbExplTvaInfo.Caption = [Cota de TVA a acestei linii nu este cunoscuta; explicatia TVA nu poate fi modificata prin acest buton.]
+ Thisform.lbExplTvaInfo.Visible = .T.
+ Return
+ Endif
+
+ lnCota = Round((poRec.proc_tvav - 1) * 100, 2)
+ lcCursorTva = [crsExplTvaArt]
+ *!* afisat > 0 = doar bazele, fara liniile de TVA; jv = 1 = doar jurnalul de vanzari
+ lcSqlTva = [select id_jtva_coloana, denumire, cota_tva from vjtva_coloane where id_jtva_coloana > 0 ] + ;
+ [and afisat > 0 and jv = 1 and cota_tva = ] + Alltrim(Str(lnCota, 10, 2)) + [ order by denumire]
+ If goExecutor.oExecuta(lcSqlTva, lcCursorTva) And Reccount(lcCursorTva) > 0
+ Thisform.cbo_expl_tva.RowSource = [select denumire, cota_tva, id_jtva_coloana from ] + lcCursorTva + [ into cursor crsExplTvaCbo]
+ Thisform.cbo_expl_tva.Requery()
+ Thisform.cbo_expl_tva.Value = Nvl(poRec.id_jtva_coloana, 0)
+ Else
+ Thisform.cbo_expl_tva.Enabled = .F.
+ Thisform.lbExplTvaInfo.Caption = [Nu exista nicio explicatie TVA activa cu aceeasi cota ca linia facturata (cota: ] + ;
+ Alltrim(Str(lnCota, 10, 2)) + [ %).]
+ Thisform.lbExplTvaInfo.Visible = .T.
+ Endif
+
+ ENDPROC
+
+ PROCEDURE cbo_expl_tva.InteractiveChange
+ Local lnIdJtva
+ lnIdJtva = Nvl(This.Value, 0)
+ If lnIdJtva <= 0
+ Return
+ Endif
+ Thisform.nidjtvaales = lnIdJtva
+ poRec.id_jtva_coloana = lnIdJtva
+ If Type('gl406') = 'L' And m.gl406
+ poRec.taxcode = GetTaxCodeIdPart(m.gnAn, m.gnLuna, poRec.data_act, m.lnIdJtva, poRec.id_part)
+ Thisform.cbo_saft.Refresh()
+ Endif
ENDPROC
ENDDEFINE
```
## 2. `changelog_roafacturare.txt` (repo ROAFACTURARE)
```diff
diff --git a/changelog_roafacturare.txt b/changelog_roafacturare.txt
index ed81ecb..6c0733f 100644
--- a/changelog_roafacturare.txt
+++ b/changelog_roafacturare.txt
@@ -1,5 +1,5 @@
<!--
-19/08/2026
+20/08/2026
ROAFACTURARE - 2.11.15
:nou:
@@ -7,11 +7,19 @@ ROAFACTURARE - 2.11.15
Pe linia de articol se poate alege explicatia TVA. Lista propune doar explicatiile cu cota TVA a liniei, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa.
+ Lista de facturi, butonul de modificare a explicatiei articolului: se poate alege acum si explicatia TVA. Lista propune doar explicatiile cu aceeasi cota de TVA ca linia facturii, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa. Valorile facturii raman neschimbate - nu se recalculeaza cota si nici totalurile documentului.
+
:modificare:
Totalul notelor din bara de jos se actualizeaza imediat dupa modificarea sumei de pe randul de nota, nu doar la editarea articolelor.
Fereastra de sincronizare articole - rulaje: coloanele arata acum ce valoare se inlocuieste si de unde se preia cea noua, in loc de "vechi" si "nou" explicate separat.
+ Editare factura, pagina Articole: seria, lotul si explicatia se tasteaza direct in grid, iar articolul, gestiunea, valuta, explicatia TVA si codul de taxa SAF-T se aleg prin dublu clic pe celula. Culorile arata la ce foloseste fiecare coloana: alb - se tasteaza direct, verde - se alege dintr-o lista, gri - nu se poate edita.
+
+ Editare factura, pagina Articole: pretul si pretul cu TVA se afiseaza cu numarul de zecimale stabilit pentru preturile de vanzare, nu cu cel pentru preturile de achizitie.
+
+ Optiunea de meniu prin care se deschide editarea se numeste acum "Editare factura (note, rulaje, articole)".
+
:eroare:
S-a corectat o eroare la descarcarea articolelor importate din eFactura, care aveau pret de achizitie cu 4 zecimale.
```
## 3. `docs\progres.md` (repo ROAFACTURARE)
```diff
diff --git a/docs/progres.md b/docs/progres.md
index 52c419d..f1805d9 100644
--- a/docs/progres.md
+++ b/docs/progres.md
@@ -2309,5 +2309,20 @@ initial, apoi **respinsa** — nu se reintroduce.
- `ff_2026_08_20_01` (garda `FACT-025`, runda 5) e **deja aplicat** pe `MARIUSM_AUTO`; scriptul 02 il
contine. **Nu se re-aplica 01** — ar sterge punctul 6.
-Ramase: proba pe ecran a punctelor 1-5, aplicarea scriptului pe `MARIUSM_AUTO`, partea VFP a
-punctului 6, si intrarea de changelog pentru runda 6 (nu exista inca).
+Ramase: partea VFP a punctului 6 si intrarea de changelog pentru runda 6 (nu exista inca).
+
+**Corectie 20.08.2026, seara** — doua puncte din lista de mai sus erau deja facute:
+
+- **Proba pe ecran a punctelor 1-5**: facuta de Marius.
+- **Scriptul `ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql` era deja aplicat** pe schema
+ `MARIUSM_AUTO` de pe `ROA_CENTRAL`, contrar notei de mai sus ("NERULAT"). Dovezi, nu mtime:
+ `VERSIUNE` are randul `20.08.2026 / seq 2 / COMUN_PACK_FACTURARE`; `ALL_OBJECTS` da PACKAGE si
+ PACKAGE BODY **VALID**, `last_ddl_time` 20.08.2026 13:56:38; iar sursa vie din `ALL_SOURCE`
+ (spec + body, normalizata: fara `CREATE OR REPLACE`, fara `/`, fara antetul de comentariu si
+ fara `exec`/`commit`) e **identica cu fisierul de pe disc — 0 linii diferenta pe 16 407**.
+ Deci in Oracle sta varianta **finala** (fara recalcul), nu varianta respinsa, desi fisierul are
+ mtime 15:45, ulterior compilarii de la 13:56.
+ Concluzie de metoda: mtime-ul fisierului si nota "scriptul nu a fost rulat" din raportul de
+ livrare nu sunt surse de stare pentru ce e in Oracle. Starea se citeste din `VERSIUNE` +
+ `ALL_SOURCE`, prin diff, inainte de a re-aplica ceva.
+- Ramane valabila interdictia: **nu se re-aplica `ff_2026_08_20_01`** — ar sterge punctul 6.
```

View File

@@ -0,0 +1,250 @@
# Diff pentru aprobare — commit unic: runda 6 (punctul 6) + runda 7 (sincronizare)
Marius a cerut **un singur commit, dupa ce sunt gata toate trei lucrarile**. Toate trei sunt gata.
Acest fisier e inventarul complet al commit-ului. Rationamentul detaliat al punctului 6 (filtrul
listei de explicatii TVA, cu cifrele pe date) ramane in `docs\diff_r6_punct6.md` — nu se repeta aici.
Raportul rundei 7, inclusiv raspunsul la intrebarea de fapt, e in `docs\raport_r7_sincronizare.md`.
## Stare verificata inainte de livrare
| fisier | write-back | dovada |
|---|---|---|
| `COMUN\clase\ofacturare_comun.vc2` | facut, binar 19:59 | reconversie + diff **0 linii**, md5 identic |
| `COMUN\clase\omodificari.vc2` | facut, binar 22:20 | reconversie + diff **0 linii**, md5 `d23691466b7017380fe36099943b3208` |
| `COMUN\programe\ofacturare_editare.prg` | n/a (`.prg`) | ASCII curat, CRLF |
| `COMUN\utile\Teste\...\test_s4b_sincronizare.prg` | n/a (`.prg`) | ASCII curat, LF (ca originalul) |
Teste: `test_s4b_sincronizare` **44 PASS / 0 FAIL**, `test_s4b_dialog` **35 PASS / 0 FAIL**,
zero erori in loguri. O suita per apel, `.fxp` sters inainte de fiecare rulare.
Punctul 6 a fost probat pe ecran de Marius, de doua ori.
## Rezumat pe fisiere
Repo `COMUN`:
```
clase/ofacturare_comun.vc2 | 129 +++++++++++++++++++--
clase/omodificari.vc2 | 11 --
programe/ofacturare_editare.prg | 21 +++-
.../editare_factura/test_s4b_sincronizare.prg | 20 +++-
4 files changed, 152 insertions(+), 29 deletions(-)
```
Repo `ROAFACTURARE`:
```
M changelog_roafacturare.txt (2 randuri noi in :modificare:, blocul 2.11.15)
M docs/progres.md
?? docs/raport_r7_sincronizare.md, docs/brief_r7_sincronizare.md, docs/handoff_r6_r7_sincronizare.md,
docs/brief_r6_punct6_vfp.md, docs/raport_r6_punct6_vfp.md, docs/diff_r6_punct6.md (doar git)
```
## 1. `COMUN\clase\omodificari.vc2` — M1: sincronizarea porneste doar din buton
Se comite ca `.vcx` + `.vct`, niciodata `.vc2`.
```diff
@@ -14481,17 +14481,6 @@ DEFINE CLASS frm_modific2024 AS _frmbase OF "_frm_base.vcx"
ENDIF
SELECT (m.lnAreaTvd)
ENDIF
- *!* al doilea punct de declansare al sincronizarii: enumerarea diferentelor la salvare, cu
- *!* continuarea salvarii daca utilizatorul renunta - de aceea llRet nu se schimba aici;
- *!* pe document fara linii active nu porneste: propunerea ar marca toata sursa ca "Adaugare"
- IF m.llRet AND This.lAreArticoleVanzari AND !This.lArticoleReadOnly AND Used('tvd') AND m.lnLiniiActive > 0
- LOCAL lcSemnaturaAcum
- lcSemnaturaAcum = This.SemnaturaDivergenteSincronizare()
- *!* doar divergentele aparute in sesiunea curenta deschid dialogul; N-A nu intra in semnatura
- IF !Empty(m.lcSemnaturaAcum) AND !(m.lcSemnaturaAcum == This.cSemnaturaSincronizare)
- This.AfiseazaDialogSincronizareArticole()
- ENDIF
- ENDIF
RETURN m.llRet
```
## 2. `COMUN\programe\ofacturare_editare.prg` — M2: `pretv` si `tvav` in rulaj
```diff
@@ -789,8 +789,9 @@ ENDFUNC && ConstruiestePropunereSincronizare
*!* Modificare/Adaugare pe tvd nu se aplica, doar cele pe trul, care nu au nevoie de metode de formular)
*!* reconstruieste propunerea (ConstruiestePropunereSincronizare) si aplica tot ce nu e N-A/Semnalare,
*!* DOAR in cursoarele din memorie (tvd/trul) - niciun INSERT/UPDATE Oracle; RUL_SURSA scrie in tvd
-*!* (cantitate/pret, pastrand pret_cu_tva existent pe rand), ARTICOLE_SURSA scrie doar cant/pretvtva pe
-*!* randul RUL deja existent (niciodata rand RUL nou - lipsesc contul/gestiunea sigure din articol)
+*!* (cantitate/pret, pastrand pret_cu_tva existent pe rand), ARTICOLE_SURSA scrie cant/pretvtva si
+*!* recalculeaza pretv/tvav pe randul RUL deja existent (niciodata rand RUL nou - lipsesc contul/
+*!* gestiunea sigure din articol)
*!* retur numeric: cate linii au fost efectiv aplicate (ca apelantul sa poata reface bara de totaluri)
FUNCTION AplicaSincronizareArticole
LPARAMETERS tcDirectie, toForm
@@ -919,12 +920,15 @@ ENDFUNC && AplicaAdaugareTvd
*!* parametri: id_articol, cantitate/pret noi (pret_nou cu TVA)
*!* scrie in trul (singurul rand activ gasit pe articol - garantat unic, altfel propunerea a marcat N-A)
-*!* doar cant/cante (dupa care din ele era deja folosit pe rand) si pretvtva; nu atinge id_tip_rulaj,
-*!* conturi (scd/scc) sau alte campuri derivate (valoare/tva/etc.) - raman de recalculat de apelant daca e nevoie
+*!* cant/cante (dupa care din ele era deja folosit pe rand), apoi recalculeaza pretv/tvav/pretvtva cu
+*!* formula din calculeaza_valori_rul (ramura pretvtva); nu atinge valorile (valoarev/valtvav/
+*!* valoarevcTVA), id_tip_rulaj, conturi (scd/scc) sau valoare/tva (pretul de achizitie) - raman de
+*!* recalculat de apelant daca e nevoie
FUNCTION AplicaModificareTrul
LPARAMETERS tnIdArticol, tnCantitateNoua, tnPretNouCuTva
LOCAL lnAreaOrigine, llAplicat, lcCampCant
+ LOCAL lnPretvtva, lnProcTvav, lnTvav, lnPretv
lnAreaOrigine = Select()
llAplicat = .F.
@@ -933,7 +937,14 @@ FUNCTION AplicaModificareTrul
LOCATE FOR id_articol = m.tnIdArticol AND Nvl(sters,0) <> 1
IF Found()
lcCampCant = IIF(Nvl(cant,0) <> 0, 'cant', 'cante')
- REPLACE (m.lcCampCant) WITH m.tnCantitateNoua, pretvtva WITH m.tnPretNouCuTva IN trul
+ REPLACE (m.lcCampCant) WITH m.tnCantitateNoua IN trul
+
+ lnPretvtva = ROUND(m.tnPretNouCuTva, m.gnPPretv)
+ lnProcTvav = IIF(Empty(proc_tvav), 1, proc_tvav) - 1 && 1.19 -> 0.19
+ lnTvav = ROUND(m.lnPretvtva * m.lnProcTvav / (1 + m.lnProcTvav), m.gnPPretv)
+ lnPretv = m.lnPretvtva - m.lnTvav
+
+ REPLACE pretv WITH m.lnPretv, pretvtva WITH m.lnPretvtva, tvav WITH m.lnTvav IN trul
llAplicat = .T.
ENDIF
ENDIF
```
## 3. `COMUN\utile\Teste\editare_factura\test_s4b_sincronizare.prg` — fixture + acoperire
Cursorul `trul` din test nu avea `pretv`/`tvav`, iar harness-ul nu definea `gnPPretV`; fara ele
codul nou dadea eroare in test, nu in productie. Cazul C1 1600 adauga TVA 19% real, ca defalcarea
sa fie efectiv verificata (toate cazurile existente aveau `proc_tvav = 1`, deci `tvav` iesea 0).
```diff
@@ -38,6 +38,11 @@ IF Type('gnPC') <> 'N'
gnPC = 2
ENDIF
+IF Type('gnPPretV') <> 'N'
+ PUBLIC gnPPretV
+ gnPPretV = 4
+ENDIF
+
SET PROCEDURE TO D:\ROA\ROAFACTURARE\COMUN\programe\ofacturare_editare.prg ADDITIVE
@@ -348,22 +353,32 @@ AdaugaTvd(1400, 5, 12, 1, 1, 'ARTICOL 1400', 'COD1400', 60)
AdaugaTrul(1400, 0, 3, 9, 0, 1, '371', 1)
*!* 1500: adaugare in ARTICOLE_SURSA (doar in tvd) - nu se aplica niciodata, trul nu primeste rand nou
AdaugaTvd(1500, 1, 1, 1, 1, 'ARTICOL 1500', 'COD1500', 1)
+*!* 1600: modificare cu TVA 19% - defalcarea pretvtva -> pretv/tvav (238/2 = 119 -> 100 + 19)
+AdaugaTvd(1600, 2, 119, 1, 1, 'ARTICOL 1600', 'COD1600', 238)
+AdaugaTrul(1600, 1, 0, 100, 0, 1, '371', 1.19)
LOCAL lnReccountTrulInainte, lnAplicateC1
lnReccountTrulInainte = Reccount('trul')
lnAplicateC1 = AplicaSincronizareArticole('ARTICOLE_SURSA')
-DO asserteaza WITH 'C1 ARTICOLE_SURSA: 2 linii aplicate (modificarile 1300 si 1400; adaugarea 1500 sarita)', lnAplicateC1 == 2, TRANSFORM(lnAplicateC1)
+DO asserteaza WITH 'C1 ARTICOLE_SURSA: 3 linii aplicate (modificarile 1300, 1400 si 1600; adaugarea 1500 sarita)', lnAplicateC1 == 3, TRANSFORM(lnAplicateC1)
DO asserteaza WITH 'C1: trul nu a crescut (adaugarea 1500 nu creeaza rand RUL nou)', Reccount('trul') == m.lnReccountTrulInainte, TRANSFORM(Reccount('trul'))
SELECT trul
LOCATE FOR id_articol = 1300
DO asserteaza WITH 'C1 1300: cant (campul folosit initial) actualizat la 5, pretvtva la 12, id_tip_rulaj neatins', ;
Found() AND cant == 5 AND cante == 0 AND pretvtva == 12 AND id_tip_rulaj == 0, TRANSFORM(cant) + '/' + TRANSFORM(cante)
+DO asserteaza WITH 'C1 1300: pretv/tvav recalculate (proc_tvav = 1, deci TVA 0 si pretv = pretvtva)', ;
+ pretv == 12 AND tvav == 0, TRANSFORM(pretv) + '/' + TRANSFORM(tvav)
LOCATE FOR id_articol = 1400
DO asserteaza WITH 'C1 1400: cante (campul folosit initial) actualizat la 5, cant ramane 0', ;
Found() AND cante == 5 AND cant == 0 AND pretvtva == 12, TRANSFORM(cant) + '/' + TRANSFORM(cante)
+LOCATE FOR id_articol = 1600
+DO asserteaza WITH 'C1 1600: pretvtva 119 defalcat in pretv 100 + tvav 19, cant actualizat la 2', ;
+ Found() AND cant == 2 AND pretvtva == 119 AND pretv == 100 AND tvav == 19, ;
+ TRANSFORM(pretv) + '/' + TRANSFORM(tvav) + '/' + TRANSFORM(cant)
+
STRTOFILE('REZULTAT: ' + TRANSFORM(gnPass) + ' PASS / ' + TRANSFORM(gnFail) + ' FAIL' + CHR(13) + CHR(10), lcLog, 1)
@@ -395,7 +410,8 @@ PROCEDURE CreeazaTrulTest
Use In trul
ENDIF
CREATE CURSOR trul (id_articol N(20), denumire C(100), codmat C(30), um C(10), cant N(12,3), cante N(12,3), ;
- pretvtva N(14,4), id_tip_rulaj I, sters I, id_gestiune I, cont C(20), proc_tvav N(6,4))
+ pretv N(14,4), pretvtva N(14,4), tvav N(14,4), id_tip_rulaj I, sters I, id_gestiune I, cont C(20), ;
+ proc_tvav N(6,4))
ENDPROC
```
## 4. `changelog_roafacturare.txt`
```diff
@@ -1,5 +1,5 @@
<!--
-19/08/2026
+20/08/2026
ROAFACTURARE - 2.11.15
:nou:
@@ -7,11 +7,23 @@ ROAFACTURARE - 2.11.15
Pe linia de articol se poate alege explicatia TVA. Lista propune doar explicatiile cu cota TVA a liniei, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa.
+ Lista de facturi, butonul de modificare a explicatiei articolului: se poate alege acum si explicatia TVA. Lista propune doar explicatiile cu aceeasi cota de TVA ca linia facturii, iar codul de taxa SAF-T se completeaza automat dupa explicatia aleasa. Valorile facturii raman neschimbate - nu se recalculeaza cota si nici totalurile documentului.
+
:modificare:
Totalul notelor din bara de jos se actualizeaza imediat dupa modificarea sumei de pe randul de nota, nu doar la editarea articolelor.
Fereastra de sincronizare articole - rulaje: coloanele arata acum ce valoare se inlocuieste si de unde se preia cea noua, in loc de "vechi" si "nou" explicate separat.
+ Sincronizarea articole - rulaje porneste doar din butonul de pe pagina Articole. Nu mai apare automat la salvarea notei.
+
+ Sincronizarea articole - rulaje completeaza pe randul de rulaj si pretul fara TVA, si TVA-ul unitar - pana acum se actualizau doar cantitatea si pretul cu TVA.
+
+ Editare factura, pagina Articole: seria, lotul si explicatia se tasteaza direct in grid, iar articolul, gestiunea, valuta, explicatia TVA si codul de taxa SAF-T se aleg prin dublu clic pe celula. Culorile arata la ce foloseste fiecare coloana: alb - se tasteaza direct, verde - se alege dintr-o lista, gri - nu se poate edita.
+
+ Editare factura, pagina Articole: pretul si pretul cu TVA se afiseaza cu numarul de zecimale stabilit pentru preturile de vanzare, nu cu cel pentru preturile de achizitie.
+
+ Optiunea de meniu prin care se deschide editarea se numeste acum "Editare factura (note, rulaje, articole)".
+
:eroare:
S-a corectat o eroare la descarcarea articolelor importate din eFactura, care aveau pret de achizitie cu 4 zecimale.
```
## 5. `COMUN\clase\ofacturare_comun.vc2` — punctul 6
Neschimbat fata de livrarea precedenta, deja aprobata la proba pe ecran. Diff-ul integral si
rationamentul filtrului: `docs\diff_r6_punct6.md`, sectiunile "Filtrul listei de explicatii TVA"
si "1. `COMUN\clase\ofacturare_comun.vc2`".
## Ce se comite, in ordine
SVN (sursa de adevar), **tintit** — pe binare, niciodata pe `.vc2`/`.sc2`:
- `COMUN\clase\ofacturare_comun.vcx` + `.vct`
- `COMUN\clase\omodificari.vcx` + `.vct`
- `COMUN\programe\ofacturare_editare.prg`
- `COMUN\utile\Teste\editare_factura\test_s4b_sincronizare.prg`
- `changelog_roafacturare.txt`
- `docs\progres.md`
**Nu se comit**: `roafacturare.PJT` / `.PJX` / `.exe` — apar modificate in `svn status`, dar vin din
sesiunea de VFP a lui Marius, nu din aceasta lucrare.
Imediat dupa `svn commit` -> `roa_sync.bat`, apoi se raporteaza revizia SVN si ce a intrat pe `main`.
Fisierele noi din `docs\` sunt doar in git.
## Ce NU s-a facut, intentionat
- **`valoarev`/`valtvav`/`valoarevcTVA` nu se scriu la sincronizare** — perimetru respins explicit
de Marius. Consecinta e documentata ca defect in `docs\raport_r7_sincronizare.md`: `VALOAREV` si
`VALTVAV` ajung invechite in Oracle, `VALOAREVCTVA` nu e coloana in `RUL` si ramane invechit doar
pe ecran pana la reincarcarea notei. **Decizia de reparare e a lui Marius.**
- `SemnaturaDivergenteSincronizare` si `cSemnaturaSincronizare` au ramas fara consumator dupa M1.
Semnalate, **nesterse**, conform deciziei.

View File

@@ -0,0 +1,220 @@
# Handoff — runda 6 (punctul 6) + runda 7 (sincronizare articole-rulaje)
Scris 20.08.2026, seara. Sesiunea principala a trecut de pragul de context. **Numai stare, fara
analize noi.**
## Stare periculoasa — citeste asta prima
- **Nimic nu e comis.** Nici SVN, nici git, nici in `COMUN`. Marius a decis explicit: **un singur
commit, dupa ce sunt gata toate trei lucrarile** (punctul 6 + cele doua cereri de runda 7).
Punctul 6 e gata si probat, dar asteapta.
- `COMUN\clase\omodificari.vc2` si `COMUN\programe\ofacturare_editare.prg` erau, la scrierea acestui
fisier, **in lucru la subagentul `r7-sincronizare`**. Verifica pe disc `mtime` + `git status` in
`COMUN` inainte sa presupui ceva; nu porni un al doilea scriitor pe ele.
- `roafacturare.PJT` / `.PJX` / `.exe` apar modificate in `svn status`. **Nu sunt ale noastre** — vin
din sesiunea de VFP a lui Marius. Decizia lui: **se lasa asa**, nu se comit, nu se reverteaza.
## 1. Punctul 6 — TERMINAT, verificat, necomis
Explicatia TVA in dialogul de modificare a articolului deschis din `frm_facturi`.
**Cod, pe numerotarea finala** (`COMUN\clase\ofacturare_comun.vc2`):
| ce | unde |
|---|---|
| `data_act` + `id_part` puse pe `poRec` din antetul `crsfacturi` | `frm_facturi.do_modifica_explicatie`, `:4650-4651` |
| layout: `Height` 370->431, randul `cbo_saft` coborat, obiecte noi `_shape4` / `lbExplTva` / `cbo_expl_tva` / `lbExplTvaInfo` | `frm_modifica_articol_factura`, `:5140-5300` |
| proprietatea `nidjtvaales` (+ intrarea `*p:`, obligatorie) | `:5147`, `:5158` |
| popularea combo-ului, filtrata | `Init`, `:5328-5360` |
| filtrul SQL | `:5340-5342` |
| derivarea `taxcode` | `cbo_expl_tva.InteractiveChange` |
| al 5-lea parametru pozitional, literal `null` cand combo-ul n-a fost atins | `inainte_de_do_termin` |
| `Destroy` inchide `crsExplTvaCbo` + `crsExplTvaArt` | in aceeasi clasa |
**Write-back FACUT si dovedit** (nu prin `mtime`): reconversie binar -> text intr-un cache temporar,
`diff` **0 linii**, md5 identic. Binar la 19:59. Encoding: **13** octeti >0x7F, zero `EF BF BD`,
CRLF pe toate liniile; octetul diacritic din `lbExplTva.Caption` e **`0xFE`** (cp1250), verificat
citind din binar.
**Probat pe ecran de Marius, de doua ori** (a doua oara dupa corectia de filtru). E OK.
### Ce s-a stabilit — nu se redeschide
- **Filtrul listei**: `id_jtva_coloana > 0 AND afisat > 0 AND jv = 1 AND cota_tva = <cota liniei>`.
Verificat pe date in `vjtva_coloane` (`MARIUSM_AUTO`, 197 randuri cu `id > 0`): `afisat = 0` sunt
**liniile de TVA**, `afisat = 1` **bazele** cu cota, `afisat = 2` neimpozabilele. `jv = 1` tine
afara explicatiile de achizitie, care altfel treceau de garda `FACT-029` (au aceeasi cota).
Acelasi filtru pe care il foloseste emiterea (`ofacturare.prg:170`).
- **NU** se preia si restrictia pe `cote_tva` de an/luna curenta din `update_jtva_coloane`: ar goli
lista la editarea unei facturi vechi cu cota iesita din uz (24%).
- **`neexigibil` = `.F.`** (parametru omis), la fel `n50`/`n100`. Nu e presupunere: emiterea
foloseste `GetTaxCode(gnAn, gnLuna, ldDataAct, lnIdJtva, .F.)` cu ultimii trei impliciti
(`ofacturare.vc2:2529` si `:3101`), iar pe jurnal de vanzari `GetTaxCodeIdPart` degenereaza exact
in acel apel.
- `crsDetalii` **nu are** `data_act`/`id_part`; vin din randul curent din `crsfacturi`, care e chiar
antetul liniei editate (`ofacturare_comun.vc2:3621-3623`).
- Combo-ul **nu** are `ControlSource` — valoarea se preia in `InteractiveChange`, ca sa se poata
distinge "userul a atins combo-ul" de "nu l-a atins" (al doilea caz trimite `null` si lasa
procedura PL/SQL pe ramura veche).
- Ordinea de tab: `Ed_tx_simplu1`=1, `cbo_expl_tva`=2, `cbo_saft`=3, `BUT_TERMIN1`=4,
`But_renunt1`=5, `Lb_titlu_alb_b121`=6, `lbSaft`=7, `lbExplTva`=8.
### Oracle — nimic de facut
`ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql` **era deja aplicat** pe schema `MARIUSM_AUTO` de pe
`ROA_CENTRAL`, contrar notei "NERULAT" din rapoartele vechi. Dovezi: rand `20.08.2026 / seq 2 /
COMUN_PACK_FACTURARE` in `VERSIUNE`; PACKAGE + PACKAGE BODY **VALID**, `last_ddl_time` 13:56:38;
sursa vie din `ALL_SOURCE` identica cu fisierul de pe disc, **0 linii diferenta pe 16 407**.
**Nu se re-aplica `ff_2026_08_20_01`** — ar sterge punctul 6.
## 2bis. ACTUALIZARE 20.08.2026 20:40 - starea reala pe disc, dupa oprirea subagentului
Sesiunea subagentului `r7-sincronizare` a fost inchisa din greseala, **inainte sa scrie raport**.
`docs\raport_r7_sincronizare.md` **nu exista**. Starea de mai jos e citita direct de pe disc,
nu dintr-un raport.
### STARE PERICULOASA: text editat FARA write-back
| fisier | text | binar | concluzie |
|---|---|---|---|
| `COMUN\clase\omodificari.vc2` | **20:35** | `.vcx`/`.vct` la **14:08** | **modificarea NU exista in binar, deci nu exista in aplicatie** |
| `COMUN\programe\ofacturare_editare.prg` | 20:33 | - | `.prg`, nu are nevoie de write-back |
| `COMUN\clase\ofacturare_comun.vc2` | 19:59 | 19:59, diff 0 linii | punctul 6, sincronizat si verificat |
`vfp9.exe` **nu ruleaza** - lock-ul e liber, write-back-ul se poate face oricand.
### M1 - facut pe text, corect
Blocul "al doilea punct de declansare" a disparut din `frm_modific2024.inainte_de_do_termin`
(0 potriviri pe comentariu). `AfiseazaDialogSincronizareArticole()` mai are **un singur**
apelant, `omodificari.vc2:16665`, adica butonul. Corect. **Ramane de facut write-back-ul.**
### M2 - facut pe text, dar DEPASESTE perimetrul aprobat
`AplicaModificareTrul` (`ofacturare_editare.prg`) calculeaza si scrie acum:
`pretv`, `pretvtva`, `tvav` (cerute) **plus `valoarev`, `valtvav`, `valoarevcTVA`** - pe care
**Marius le-a respins explicit**: sincronizarea e intre cantitate si preturi, nu valori.
Subagentul a apucat sa aplice varianta initiala a brief-ului; corectia de perimetru nu a mai
ajuns la el.
**De facut in sesiunea urmatoare, in aceasta ordine:**
1. Scoate din `AplicaModificareTrul` cele trei campuri de valoare din `REPLACE` si cele trei
linii care le calculeaza (`lnValoarecTVA`, `lnValoareTVA`, `lnValoareFtva`), plus
`lnCantitate` daca ramane nefolosit. Raman `pretv`, `pretvtva`, `tvav`.
Verifica si `LOCAL`-urile declarate, si comentariul-antet al lui `AplicaSincronizareArticole`.
2. Write-back pe `omodificari.vc2` (`txt2vcx.ps1 -TextFile ... -AllowComun`), apoi **dovada prin
reconversie** cu `vcx2txt.ps1` intr-un cache temporar si `diff` - trebuie 0 linii.
3. Ruleaza cele doua suite (vezi mai jos), o suita per apel, cu `.fxp` sters inainte.
4. Raspunde la intrebarea de fapt ramasa deschisa (cine recalculeaza
`valoarev`/`valtvav`/`valoarevcTVA` dupa sincronizare) - **doar raspuns, fara reparatie**.
5. Adauga cele doua puncte in changelog, regenereaza `docs\diff_r6_punct6.md` si cere aprobarea
de commit.
Nimic nu a fost testat: **cele doua suite nu au fost rulate**.
## 2. Runda 7 — IN LUCRU la subagentul `r7-sincronizare`
Brief executabil, cu liniile si formula: `docs\brief_r7_sincronizare.md`.
Raportul lui va fi la `docs\raport_r7_sincronizare.md`.
**M1** — sincronizarea articole-rulaje porneste **doar din buton**. Se sterge blocul "al doilea
punct de declansare" din `frm_modific2024.inainte_de_do_termin`, `omodificari.vc2:14484-14494`.
Butonul `pgfArticole.PAGE3.cmdSincronizeazaArticole.Click` (`:16671`) ramane singura cale.
Dupa stergere raman **fara consumator** metoda `SemnaturaDivergenteSincronizare` (`:14840`),
proprietatea `cSemnaturaSincronizare` si atribuirea de la `:14956` — se semnaleaza, **nu** se sterg.
**M2** — `AplicaModificareTrul` (`ofacturare_editare.prg:924`) scrie azi doar `cant`/`cante` si
`pretvtva`; trebuie sa scrie **si `pretv`, si `tvav`**.
- **Perimetru corectat de Marius**: **DOAR `pretv` si `tvav`.** Versiunea initiala a brief-ului
cerea si `valoarev`/`valtvav`/`valoarevcTVA` — **respinsa**: sincronizarea e intre cantitate si
preturi, nu valori. Nu o reintroduce.
- **Intrebare de fapt inca deschisa**, ceruta subagentului, fara modificare de cod: cine recalculeaza
`valoarev`/`valtvav`/`valoarevcTVA` pe randul `trul` dupa sincronizare, inainte de scrierea in
Oracle? Trei concluzii posibile — le recalculeaza cineva / le recalculeaza salvarea / nu le
recalculeaza nimeni si ajung vechi in Oracle. In ultimul caz **se raporteaza ca defect, nu se
repara**; decide Marius.
- Formula canonica, **de reutilizat, nu de reinventat**: `omodificari.vc2`, `calculeaza_valori_rul`,
ramura `pretvtva`, `:13566-13587`. Doua precizii diferite: `gnPPretV` pentru preturi, `gnPC` pentru
valori.
- `calculeaza_valori_rul` **nu se poate apela direct** din sincronizare: isi alege cursorul din
`This.pgfArticole.ActivePage` (`:13532-13533`) si nimereste `trul` doar cand pagina activa e 1;
sincronizarea porneste de pe pagina 3, deci ar scrie in `trul_obinv`.
### Teste obligatorii pentru runda 7
`COMUN\utile\Teste\editare_factura\test_s4b_sincronizare.prg` (42 cazuri, **sectiunea C** e chiar
directia `ARTICOLE_SURSA`) si `test_s4b_dialog.prg` (35 cazuri). Reguli: sterge `.fxp`-ul inainte de
fiecare rulare; **o singura suita per apel** de comanda; cifra se ia numarand `PASS`/`FAIL` din log,
iar dovada ca rularea a ajuns la capat e **linia de `REZULTAT`** (care contine ea insasi cuvintele
`PASS` si `FAIL` — un `Select-String` naiv raporteaza cu unu mai mult din fiecare).
## 3. Changelog
`changelog_roafacturare.txt` — intrarea rundei 6 e **scrisa**, in blocul existent **2.11.15**, data
mutata la 20/08/2026. Versiunea **nu se bifurca** cat timp #6 nu e in productie (decizia lui Marius,
commit `09f9d47`).
**Ramas de adaugat**, dupa ce runda 7 e gata: sincronizarea porneste doar din buton, si copierea
`pretv`/`tvav` in rulaj.
## 4. Ce se comite, cand vine aprobarea
SVN (sursa de adevar), **tintit** — pe binare, niciodata pe `.vc2`/`.sc2`:
- `COMUN\clase\ofacturare_comun.vcx` + `.vct`
- `COMUN\clase\omodificari.vcx` + `.vct` (dupa runda 7)
- `COMUN\programe\ofacturare_editare.prg` (dupa runda 7)
- `changelog_roafacturare.txt`
- `docs\progres.md`
**Nu**: `roafacturare.PJT` / `.PJX` / `.exe`. Imediat dupa `svn commit` -> `roa_sync.bat`, si se
raporteaza revizia SVN si ce a intrat pe `main`. Fisierele noi din `docs\` sunt doar in git.
Diff-ul pentru aprobare, deja generat pentru punctul 6: `docs\diff_r6_punct6.md` (contine si
rationamentul filtrului, cu cifrele pe date). **Trebuie regenerat** dupa ce intra runda 7.
## 5. Capcane de mediu platite in aceasta sesiune
- **`python <<EOF` si `python -c "..."` nu executa nimic** prin tool-ul Bash de pe masina asta —
exit 0, zero efect, fara eroare. Scrie scriptul intr-un fisier si ruleaza-l pe cale absoluta.
Pentru `.vc2` foloseste **mod binar** (`'rb'`/`'wb'`): e CRLF peste tot si cp1250 pe diacritice.
- **`txt2vcx.ps1` are parametrul `-TextFile`, nu `-Source`** (`vcx2txt.ps1` are `-Source`). Ambele au
nevoie de `-ProjectRoot` si `-CacheRoot` date explicit pentru acest proiect.
- **Write-back-ul esueaza cat timp ruleaza `vfp9.exe`** — tine `.vcx/.vct` exclusiv. Se verifica cu
`Get-Process vfp9` **inainte**. Procesul e al lui Marius: **nu se omoara**, se cere inchiderea.
- **Un subagent poate raporta `idle` si apoi sa scrie in fisier.** S-a intamplat; era sa produca doi
scriitori pe aceeasi metoda. Verifica `mtime`/md5 pe disc inainte sa preiei un fisier, si spune-le
explicit sa nu raporteze idle cu lucru in curs.
- `svn status` cere `--depth` sau atentie la externals: `COMUN` apare ca `X` (external), iar starea
lui se vede separat.
---
## ACTUALIZARE FINALA 20.08.2026 22:40 — toate cele trei lucrari sunt gata
Pasii 1-5 din lista de mai sus sunt **executati**. Handoff-ul de mai sus ramane ca istoric; starea
curenta e cea de aici.
1. **Perimetrul M2 corectat** — `valoarev`/`valtvav`/`valoarevcTVA` scoase din `AplicaModificareTrul`,
impreuna cu `lnValoarecTVA`/`lnValoareTVA`/`lnValoareFtva`/`lnCantitate` si cu `LOCAL`-urile si
comentariile-antet ale ambelor functii. Raman `pretv`, `pretvtva`, `tvav`.
2. **Write-back pe `omodificari.vc2` FACUT si dovedit** — nu mai exista fisier editat fara binar.
Prima incercare a picat la fidelity check: subagentul lasase linia 14485 goala in loc de `\t\t`.
Restaurata. Dovada pe binarul din proiect: md5 `d23691466b7017380fe36099943b3208`, **diff 0 linii**.
3. **Ambele suite rulate**: `test_s4b_sincronizare` **44/0**, `test_s4b_dialog` **35/0**.
A fost nevoie de o corectie de fixture (`gnPPretV`, coloanele `pretv`/`tvav` in cursorul `trul`)
plus un caz nou cu TVA 19% — detalii in `docs\raport_r7_sincronizare.md`.
4. **Intrebarea de fapt: raspunsa** — nu le recalculeaza nimeni; `VALOAREV`/`VALTVAV` ajung invechite
in Oracle, `VALOAREVCTVA` nu e coloana in `RUL`. Raportat ca defect, **nereparat**.
5. **Changelog completat** (2 randuri in `:modificare:`, blocul 2.11.15) si **diff regenerat** ca
`docs\diff_r6_r7_pentru_commit.md` (inventarul intregului commit; `docs\diff_r6_punct6.md` ramane
ca rationament detaliat al punctului 6).
### Nimic nu e intr-o stare periculoasa
- Niciun fisier editat fara write-back. Nicio tranzactie deschisa. `vfp9.exe` nu ruleaza.
- **Nimic nu e comis** — nici SVN, nici git, nici in `COMUN`. Se asteapta aprobarea pe
`docs\diff_r6_r7_pentru_commit.md`, apoi `svn commit` tintit + `roa_sync.bat`.
- `roafacturare.PJT`/`.PJX`/`.exe` raman modificate din sesiunea de VFP a lui Marius: **nu se comit**.

View File

@@ -2309,5 +2309,66 @@ initial, apoi **respinsa** — nu se reintroduce.
- `ff_2026_08_20_01` (garda `FACT-025`, runda 5) e **deja aplicat** pe `MARIUSM_AUTO`; scriptul 02 il - `ff_2026_08_20_01` (garda `FACT-025`, runda 5) e **deja aplicat** pe `MARIUSM_AUTO`; scriptul 02 il
contine. **Nu se re-aplica 01** — ar sterge punctul 6. contine. **Nu se re-aplica 01** — ar sterge punctul 6.
Ramase: proba pe ecran a punctelor 1-5, aplicarea scriptului pe `MARIUSM_AUTO`, partea VFP a Ramase: partea VFP a punctului 6 si intrarea de changelog pentru runda 6 (nu exista inca).
punctului 6, si intrarea de changelog pentru runda 6 (nu exista inca).
**Corectie 20.08.2026, seara** — doua puncte din lista de mai sus erau deja facute:
- **Proba pe ecran a punctelor 1-5**: facuta de Marius.
- **Scriptul `ff_2026_08_20_02_COMUN_PACK_FACTURARE.sql` era deja aplicat** pe schema
`MARIUSM_AUTO` de pe `ROA_CENTRAL`, contrar notei de mai sus ("NERULAT"). Dovezi, nu mtime:
`VERSIUNE` are randul `20.08.2026 / seq 2 / COMUN_PACK_FACTURARE`; `ALL_OBJECTS` da PACKAGE si
PACKAGE BODY **VALID**, `last_ddl_time` 20.08.2026 13:56:38; iar sursa vie din `ALL_SOURCE`
(spec + body, normalizata: fara `CREATE OR REPLACE`, fara `/`, fara antetul de comentariu si
fara `exec`/`commit`) e **identica cu fisierul de pe disc — 0 linii diferenta pe 16 407**.
Deci in Oracle sta varianta **finala** (fara recalcul), nu varianta respinsa, desi fisierul are
mtime 15:45, ulterior compilarii de la 13:56.
Concluzie de metoda: mtime-ul fisierului si nota "scriptul nu a fost rulat" din raportul de
livrare nu sunt surse de stare pentru ce e in Oracle. Starea se citeste din `VERSIUNE` +
`ALL_SOURCE`, prin diff, inainte de a re-aplica ceva.
- Ramane valabila interdictia: **nu se re-aplica `ff_2026_08_20_01`** — ar sterge punctul 6.
## Runda 6 punctul 6 + runda 7 (sincronizare) - 20.08.2026, seara
Starea completa, cu inventar pe `fisier:linie`, ce s-a stabilit si ce e in lucru:
**`docs\handoff_r6_r7_sincronizare.md`**. Pe scurt:
- **Punctul 6 (explicatie TVA in `frm_facturi`): TERMINAT**, write-back verificat prin
reconversie (0 linii diferenta, md5 identic), probat pe ecran de Marius de doua ori.
Filtrul final al listei: `id_jtva_coloana > 0 AND afisat > 0 AND jv = 1 AND cota_tva = <cota
liniei>`. Pe date (`vjtva_coloane`, `MARIUSM_AUTO`): `afisat = 0` sunt liniile de TVA,
`afisat = 1` bazele, `afisat = 2` neimpozabilele; `jv = 1` tine afara explicatiile de
achizitie, care altfel treceau de garda `FACT-029` fiindca au aceeasi cota.
- **Runda 7, in lucru**: sincronizarea articole-rulaje porneste doar din buton (se scoate
declansarea de la salvare, `omodificari.vc2:14484-14494`), si `AplicaModificareTrul`
(`ofacturare_editare.prg:924`) scrie si `pretv`/`tvav`, nu doar `pretvtva`.
**Perimetru fixat de Marius: doar preturi, nu si `valoarev`/`valtvav`/`valoarevcTVA`** -
sincronizarea e intre cantitate si preturi. Ramane de raspuns, ca fapt, cine recalculeaza
acele valori dupa sincronizare.
- **Nimic nu e comis** - decizia lui Marius e un singur commit, dupa ce sunt gata toate trei.
- `roafacturare.PJT`/`.PJX`/`.exe` apar modificate: zgomot din sesiunea lui de VFP, se lasa asa.
### Runda 7 - terminata, 20.08.2026, 22:40
Raport complet: **`docs\raport_r7_sincronizare.md`**. Diff-ul commit-ului unic (runda 6 + runda 7):
**`docs\diff_r6_r7_pentru_commit.md`**.
- **M1 gata**: blocul de declansare de la salvare a disparut din `frm_modific2024.inainte_de_do_termin`;
`AfiseazaDialogSincronizareArticole` are un singur apelant, butonul (`omodificari.vc2:16665`).
`SemnaturaDivergenteSincronizare` + `cSemnaturaSincronizare` au ramas fara consumator - semnalate,
nesterse. Write-back facut, dovedit prin reconversie: 0 linii diferenta, md5 identic.
- **M2 gata, in perimetrul corectat**: `AplicaModificareTrul` scrie `pretv`, `pretvtva`, `tvav`.
Cele trei campuri de valoare pe care le adaugase subagentul au fost scoase.
- **Teste**: `test_s4b_sincronizare` **44/0**, `test_s4b_dialog` **35/0**. Prima rulare a dat 40/2,
din fixture, nu din cod: harness-ul nu definea `gnPPretV`, iar cursorul `trul` din test nu avea
coloanele `pretv`/`tvav` (tabela reala `RUL` le are). Adaugat si un caz cu TVA 19% real (C1 1600),
fiindca toate cazurile existente aveau `proc_tvav = 1` si `tvav` ieseau 0 orice s-ar fi scris.
- **Raspunsul la intrebarea de fapt: nu le recalculeaza nimeni.** Lantul e verbatim de la cursor
pana in Oracle - `trul` -> `RUL_TEMP` (`ofacturare_comun.vc2:3814`, doar `id_util`/`sters` se
suprascriu) -> `sql_temp_insert` -> `INSERT INTO RUL (<lista coloane>) SELECT ... FROM RUL_TEMP`
(`PACK_CONTAFIN.pck:2013`). Nici `ActualizeazaBaraTotaluri` (insumeaza doar `tvd.valoare`), nici
`finalizeaza_modificare_nota` nu ating valorile. Interogat pe `MARIUSM_AUTO`: `VALOAREV` si
`VALTVAV` **sunt** coloane in `RUL` si ajung invechite in baza; `VALOAREVCTVA` **nu e** coloana -
exista doar in cursorul Fox, calculat la incarcare, deci ramane invechit doar pe ecran.
Back-fill-ul de la reincarcare nu repara: are garda `WHERE EMPTY(NVL(...,0))`, deci prinde doar
zerourile. Raportat ca defect, **nereparat** - decide Marius.
- **Nimic nu e comis.** Se asteapta aprobarea pe `docs\diff_r6_r7_pentru_commit.md`.

View File

@@ -0,0 +1,113 @@
# Raport runda 6, punctul 6, partea VFP
## GATA — text editat, write-back facut si verificat
Implementare completa a partii VFP din punctul 6 (explicatia TVA in dialogul de modificare a
articolului din `frm_facturi`), conform `docs\brief_r6_punct6_vfp.md`, punctele M1-M5, plus
doua corectii cerute de team-lead la review (TabIndex complet, `Destroy` inchide ambele
cursoare). Scris pe binar cu succes; verificarile de mai jos confirma sincronizarea text/binar.
## Inventar modificari (numerotare finala, dupa write-back)
Fisier: `D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare_comun.vc2` (+ `ofacturare_comun.vcx`/`.vct`).
- **M1** — `frm_facturi.do_modifica_explicatie` (`:4642`): la `:4650-4651`, doua
`AddProperty(poRec, 'data_act', crsfacturi.data_act)` / `AddProperty(poRec, 'id_part',
Nvl(crsfacturi.id_part, 0))`, intre `poRec.explicatie = NVL(...)` si `If poRec.sters = 0`.
- **M2** — clasa `frm_modifica_articol_factura` (`:5132-5369`):
- Layout: `Height` 370->431 (`:5155`); `_shape3.Top` 323->384 (`:5192`); `cbo_saft.Top`
329->390 (`:5234`); `lbSaft.Top` 332->393 (`:5284`).
- `OBJECTDATA` ZOrder (`:5140-5143`): 4 linii noi — `_shape4`, `lbExplTva`, `cbo_expl_tva`,
`lbExplTvaInfo`.
- Proprietate noua `nidjtvaales`: `*p: nidjtvaales` in `*<DefinedPropArrayMethod>` (`:5147`,
intre `*p: nid` si `*p: ntip_selectie`), valoare initiala `nidjtvaales = 0` in `*<PropValue>`
(`:5158`).
- Obiecte noi (ADD OBJECT): `_shape4` (`:5197`), `cbo_expl_tva` (`:5207`, `ControlSource` gol,
`RowSource` populat in `Init`), `lbExplTva` (`:5257`, caption `Explicaţie TVA`, diacritic
cp1250 `0xFE`), `lbExplTvaInfo` (`:5266`).
- **M3** — `frm_modifica_articol_factura.Init` (`:5313-5353`): la final (dupa blocul
`citeste_lungcampexplart`), populare `cbo_expl_tva` din `vjtva_coloane` filtrat pe cota TVA a
liniei, cu cele 3 ramuri din brief (cota necunoscuta la `:5331-5336`; gasit la `:5342-5345`;
negasit la `:5346-5350`).
- **M4** — `cbo_expl_tva.InteractiveChange` (`:5355-5367`, metoda noua — override de eveniment
de baza, nu necesita `*m:`): seteaza `Thisform.nidjtvaales`, `poRec.id_jtva_coloana`, si sub
garda `gl406` recalculeaza `poRec.taxcode` prin `GetTaxCodeIdPart`.
- **M5** — `inainte_de_do_termin` (`:5298-5311`): parametrul 5 (`lcParamJtva`, `:5301-5302`)
construit literal (nu bind), `null` cand `Thisform.nidjtvaales` n-a fost atins.
- **In plus fata de M1-M5, cerut/corectat la review**:
- `PROCEDURE Destroy` (`:5288-5296`) — inchide `crsExplTvaCbo` (RowSource-ul combo-ului) si
`crsExplTvaArt` (cursorul intermediar din `Init`) daca raman deschise, apoi `DoDefault()`
(`:5295`) — lantul de curatenie mostenit din `frm_termin_renunt` (`_frm_child.vcx`) nu e
taiat; acelasi tipar (cleanup local + `DODEFAULT()`) e deja folosit in fisier la
`frm_modifica_factura.Destroy` (`:5720-5722`).
- `TabIndex`, ordine completa: `Ed_tx_simplu1`=1, `cbo_expl_tva`=2 (nou), `cbo_saft`=2->3,
`BUT_TERMIN1`=3->4, `But_renunt1`=4->5, `Lb_titlu_alb_b121`=5->6, `lbSaft`=6->7, `lbExplTva`=8
(nou); `lbExplTvaInfo` ramane fara `TabIndex` (`Visible = .F.`).
Ordinea fizica finala a metodelor in clasa: `Destroy`, `inainte_de_do_termin`, `Init`,
`cbo_expl_tva.InteractiveChange` — confirmata din textul regenerat de FoxBin2Prg la fidelity-check
(nu presupusa).
## Write-back — confirmat
`txt2vcx.ps1 -TextFile COMUN\clase\ofacturare_comun.vc2 -ProjectRoot D:\ROA\ROAFACTURARE
-CacheRoot D:\ROA\ROAFACTURARE -AllowComun`:
- Prima rulare (pe textul M1-M5, inainte de corectiile de TabIndex/`Destroy`): **ESEC pe ordine**
— exact avertismentul din brief ("FoxBin2Prg nu pastreaza ordinea textuala pentru ADD OBJECT
multiple"). Am adoptat ca sursa blocul clasei `frm_modifica_articol_factura` din
`<staging>\verify\ofacturare_comun.vc2` (ordinea canonica ADD OBJECT: `_shape3, _shape4,
cbo_expl_tva, cbo_saft, Ed_tx_simplu1, lbExplTva, lbExplTvaInfo, lbSaft`), fara sa ating nicio
alta clasa din fisier.
- Rularea finala (dupa corectiile de TabIndex + `Destroy`, cu semnal `WRITE-BACK ACUM` de la
team-lead, lock-ul lui Marius eliberat): **OK** — `1/1 fisier(e) scrise cu succes`, fara alt
esec de fidelitate.
**Dovada de sincronizare text/binar** (nu `mtime` — reconversie separata + diff):
`vcx2txt.ps1 -Source ofacturare_comun.vcx -Force` intr-un cache temporar separat, apoi
`diff` cu textul din arbore -> **0 linii diferenta**.
## Verificari encoding (inainte / dupa, pe tot parcursul)
- **Octeti > 0x7F**: 12 inainte de orice editare -> **13** dupa toate editarile si dupa
write-back (neschimbat de la corectiile de TabIndex/`Destroy` — nu ating diacritice). Singurul
octet nou e `0xFE` (diacriticul `ț` din caption-ul `lbExplTva`, `Explicaţie TVA`); zero
aparitii de `EF BF BD` (fara corupere UTF-8).
- **Octetul diacritic verificat explicit** (cerut de team-lead): `lbExplTva.Caption` (`:5258`) are
octetul `0xFE` exact in aceeasi pozitie semantica ca `Lb_titlu_alb_b121.Caption` (`:5170`,
`"Modific\xE3 explica\xFEie articol"`) din aceeasi clasa — acelasi octet `0xFE` = `ț` cp1250 in
ambele, confirmat byte-cu-byte (`od -c`) pe fisierul final, dupa write-back.
- **LF izolate** (`0x0A` fara `0x0D` inainte): 0, atat inainte cat si dupa toate editarile si dupa
write-back. Fisierul final are 7540 de linii, toate CRLF.
## Scop
`git status` in `D:\ROA\ROAFACTURARE\COMUN` (repo propriu al lui COMUN, unde `.vc2` e versionat
si `.vcx`/`.vct` sunt gitignored prin design — `git check-ignore` confirma `*.VCX`/`*.VCT` in
`.gitignore`): **doar** `clase/ofacturare_comun.vc2` modificat (117 insertii, 11 stergeri),
niciun alt fisier. Niciun PL/SQL, niciun `omodificari.vc2`, niciun grid de articole, niciun
`Text1.ReadOnly` atins — conform interdictiilor.
## Ce n-a fost facut si de ce
Nimic din scopul brief-ului a ramas nefacut. Singura abatere fata de fluxul standard a fost
timpul de asteptare intre editarea textului si write-back, cauzat de un lock legitim
(sesiunea VFP activa a lui Marius pe acelasi binar) — nu de o problema de implementare; write-back-ul
s-a facut abia dupa ce team-lead a confirmat eliberarea lock-ului si a dat semnalul explicit.
## Nu s-a comis nimic si nu s-a rulat nicio sincronizare
Nu s-a rulat `git_sync.ps1`, `roa_sync.bat`, `svn update/commit`, `git commit/push`. Nu s-a pornit
VFP, nu s-a deschis IDE-ul. Commit-ul ramane la latitudinea sesiunii principale, dupa aprobare.
## Fisiere atinse in aceasta sesiune
- `D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare_comun.vc2` — editat, write-back facut, verificat
(0 linii diferenta la reconversie).
- `D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare_comun.vcx` / `.vct` — regenerate prin write-back,
verificate byte-identic cu textul din arbore (via reconversie separata).
- `D:\ROA\ROAFACTURARE\COMUN\clase\ofacturare_comun.vc2.pre_r6p6.bak`,
`ofacturare_comun.vc2.pre_r6p6_fix2.bak` — backup-uri locale (baseline-uri intermediare),
netracked de git, de sters la curatenie (`COMUN\utile\curatenie.ps1`).
- `D:\ROA\ROAFACTURARE\docs\raport_r6_punct6_vfp.md` — acest raport.
- Niciun proces deschis, nicio tranzactie Oracle deschisa, niciun date de test consumate.

View File

@@ -0,0 +1,138 @@
# Raport runda 7 — sincronizarea articole-rulaje
Scris 20.08.2026, 22:40. Acopera M1, M2 (dupa corectia de perimetru), rularea celor doua suite si
raspunsul la intrebarea de fapt ramasa deschisa.
## M1 — sincronizarea porneste doar din buton — GATA
Blocul "al doilea punct de declansare" a fost sters din `frm_modific2024.inainte_de_do_termin`.
Metoda se termina acum la `RETURN m.llRet`, imediat dupa validarile pe `tvd`; nu mai exista niciun
apel de sincronizare pe drumul salvarii.
`AfiseazaDialogSincronizareArticole` are un **singur** apelant ramas:
`omodificari.vc2:16665`, adica butonul `pgfArticole.PAGE3.cmdSincronizeazaArticole.Click`.
Definitia metodei e la `:13184`.
**Ramase fara consumator, semnalate, NEsterse** (conform deciziei):
| membru | unde |
|---|---|
| `SemnaturaDivergenteSincronizare` (metoda) | `omodificari.vc2:14829`, declarata `*m:` la `:6820` |
| `cSemnaturaSincronizare` (proprietate) | declarata `*p:` la `:6831`, valoare initiala `:6870` |
| atribuirea care le leaga | `:14945`, in `IncarcaArticoleFactura`-ul din ramura cu articole |
Proprietatea e **scrisa o data si citita niciodata**; metoda e apelata doar ca sa alimenteze acea
scriere. Ambele sunt acum cod mort, dar functional inofensiv.
### Write-back — FACUT si dovedit
`txt2vcx.ps1 ... -AllowComun` a esuat prima data la fidelity check: subagentul rundei precedente
lasase **linia 14485 goala**, desi in original era `\t\t` (o linie de spatiere pe care stergerea
n-ar fi trebuit s-o atinga). Restaurata la `\t\t`; diff-ul fata de HEAD e acum exact blocul de 11
linii sters, nimic altceva.
Dovada pe binarul din proiect, nu pe `mtime`: reconversie `vcx2txt.ps1` intr-un cache temporar,
**md5 identic** (`d23691466b7017380fe36099943b3208`), **diff 0 linii**. Binare la 22:20:09,
text la 22:20:10. Encoding: 6 octeti >0x7F (`0xAA`, `0xE3`, `0xFE` — cp1250), zero `EF BF BD`,
CRLF pe toate cele 17 145 de linii.
## M2 — `pretv` si `tvav` in rulaj — GATA, perimetru corectat
`AplicaModificareTrul` (`COMUN\programe\ofacturare_editare.prg:926`) scrie acum:
```
REPLACE (m.lcCampCant) WITH m.tnCantitateNoua IN trul
REPLACE pretv WITH m.lnPretv, pretvtva WITH m.lnPretvtva, tvav WITH m.lnTvav IN trul
```
Cele trei campuri de valoare (`valoarev`, `valtvav`, `valoarevcTVA`) pe care subagentul apucase
sa le adauge din varianta initiala a brief-ului **au fost scoase**, impreuna cu liniile care le
calculau (`lnValoarecTVA`, `lnValoareTVA`, `lnValoareFtva`) si cu `lnCantitate`, ramas nefolosit.
`LOCAL`-urile si comentariile-antet ale ambelor functii (`AplicaModificareTrul` si
`AplicaSincronizareArticole`) au fost aduse la zi.
Formula e cea canonica din `calculeaza_valori_rul`, ramura `pretvtva` (`omodificari.vc2:13573-13575`),
cu `gnPPretV` pentru preturi — reutilizata, nu reinventata.
`.prg`, deci fara write-back. Fisierul e ASCII curat, CRLF.
## Teste — ambele suite verzi
O suita per apel, `.fxp` sters inainte de fiecare rulare.
| suita | rezultat |
|---|---|
| `test_s4b_sincronizare.prg` | **44 PASS / 0 FAIL**, zero erori in log |
| `test_s4b_dialog.prg` | **35 PASS / 0 FAIL**, zero erori in log |
### Prima rulare a picat — fixture, nu cod
`test_s4b_sincronizare` a dat initial **40 PASS / 2 FAIL**, cu erori in log:
```
EROARE 12 [APLICAMODIFICARETRUL:942] Variable 'GNPPRETV' is not found.
EROARE 12 [APLICAMODIFICARETRUL:947] Variable 'PRETV' is not found.
```
Ambele vin din harness, nu din codul de productie:
1. testul definea `gnPC`, dar **nu si `gnPPretV`** — suitele surori din `achizitie_import` il pun
la `4` (`test_adauga_factura_ui.prg:167`);
2. cursorul `trul` construit de `CreeazaTrulTest` avea `pretvtva`, dar **nu si `pretv`/`tvav`` —
campuri pe care tabela reala `RUL` le are (verificat in Oracle, vezi mai jos) si pe care
`calculeaza_valori_rul` le scrie de ani de zile.
Modificari in `COMUN\utile\Teste\editare_factura\test_s4b_sincronizare.prg`:
- `PUBLIC gnPPretV = 4` daca nu exista deja, dupa blocul identic al lui `gnPC`;
- `pretv N(14,4)` si `tvav N(14,4)` adaugate in `CREATE CURSOR trul`;
- asserturile C1 1300/1400 verifica si `pretv`/`tvav` (pe `proc_tvav = 1`, adica TVA 0);
- **caz nou C1 1600**, cu TVA 19% real, ca defalcarea sa fie efectiv acoperita:
`238 / 2 buc = 119` cu TVA -> `pretv 100 + tvav 19`. Fara el, toate cazurile din sectiunea C
aveau `proc_tvav = 1` si `tvav` ar fi iesit 0 orice s-ar fi scris in formula.
De aici cresterea 42 -> 44 de cazuri.
## Intrebarea de fapt: cine recalculeaza `valoarev`/`valtvav`/`valoarevcTVA` dupa sincronizare?
**Nimeni.** A treia concluzie din cele trei posibile. Se raporteaza ca defect, **nu s-a reparat**.
Lantul complet, verificat cap-coada:
| pas | unde | ce face cu cele trei campuri |
|---|---|---|
| incarcare nota | `ofacturare_editare.prg:96-104` | `valoarev`/`valtvav` vin din `vrul_tot`, completate **doar daca sunt goale** (`WHERE EMPTY(NVL(...,0))`); `valoarevcTVA` e calculat **o singura data**, `valoarev + valtvav AS valoarevctva`, la construirea `RUL_TEMP` -> `trul` |
| sincronizare | `ofacturare_editare.prg:947` | scrie `cant`/`cante`, `pretv`, `pretvtva`, `tvav`. **Nu le atinge** |
| dupa "Aplica" | `omodificari.vc2:17097` | `ActualizeazaBaraTotaluri()` + refresh grid. Bara **doar insumeaza `tvd.valoare`** (`:13009`) — nu atinge `trul` |
| salvare, pas 1 | `omodificari.vc2:14379` | `inainte_de_do_termin` pune doar `id_set` pe `trul` si valideaza `tvd` |
| salvare, pas 2 | `ofacturare_comun.vc2:3812-3814` | `Select * From trul Into Cursor RUL_TEMP`, apoi `Replace All id_util..., sters With 0`. **Copie verbatim** |
| salvare, pas 3 | `oscrie_in_fisiere.prg:131` | `sql_temp_insert('rul_temp','RUL_TEMP')` — bulk insert, fara calcul |
| salvare, pas 4 | `PACK_CONTAFIN.pck:2013` | `INSERT INTO <schema>.RUL (<lista>) SELECT <lista> FROM RUL_TEMP`, lista fiind coloanele reale ale lui `RUL` (`LISTA_CAMPURI`, `:3287`). **Fara recalcul** |
| post-procesare | `PACK_CONTAFIN.pck:8601` | `finalizeaza_modificare_nota` renumeroteaza `cod`, atinge `atasamente_vanzari`/`nom_lucrari`. **Nimic pe valori** |
### Ce ajunge efectiv gresit in Oracle
Interogat pe `MARIUSM_AUTO` / `ROA_CENTRAL`, coloanele reale ale tabelei `RUL`:
```
CANT, CANTE, PRETV, PRETVTVA, TVAV, VALOAREV, VALTVAV (7 din 8 cerute)
```
`VALOAREVCTVA` **nu e coloana in `RUL`**. Exista doar in cursorul Fox, calculat la incarcare
pentru grid si pentru bara de totaluri (`csumcolumns`) — nu se salveaza nicaieri.
Deci, concret:
- **`VALOAREV` si `VALTVAV` ajung invechite in Oracle.** Dupa sincronizare, cantitatea si pretul
de pe rand sunt cele noi, iar cele doua valori raman cele dinainte. La o reincarcare ulterioara
a notei nu se repara singure: back-fill-ul de la incarcare are garda `WHERE EMPTY(NVL(...,0))`,
deci prinde doar valorile zero, nu si pe cele nenule dar gresite.
- **`VALOAREVCTVA` nu ajunge in Oracle deloc**, dar ramane invechit **in ecran** pana la
reincarcarea notei: gridul de rulaje si bara de totaluri arata suma veche.
Iesirea manuala exista: daca utilizatorul atinge randul de rulaj in gridul de pe pagina 1,
`calculeaza_valori_rul` recalculeaza toate cele sase campuri deodata (`omodificari.vc2:13587`).
Sincronizarea insa porneste de pe pagina 3 si nu poate apela acea metoda direct — isi alege
cursorul din `pgfArticole.ActivePage` (`:13532-13533`) si ar scrie in `trul_obinv`.
**Decizia daca se repara si cum e a lui Marius.** Nu s-a atins nimic.