# S4b etapa 2 — butonul, dialogul si verificarea la salvare Continuarea lui handoff intermediar (sters), sectiunea „S4b etapa 2". Diff-ul complet: **diff aplicat (sters)** (342 randuri adaugate, 0 sterse, un singur fisier atins: `COMUN\clase\omodificari.vc2`). **STARE: WRITE-BACK FACUT, NECOMIS.** `omodificari.vcx`/`.vct` sunt regenerate (11.08.2026 09:34), textul e cel canonic FoxBin2Prg. Nimic nu e intr-o stare periculoasa. | Verificare | Rezultat | |---|---| | compilare la regenerare (`txt2vcx.ps1`) | `P1,E0,S1,X0` — 0 erori | | fidelity check binar -> text -> octeti, in staging | trecut (`OK`) | | `git_sync.ps1` dupa write-back | **0 conversii**, 464 la zi, 0 esecuri — text si binar sincrone | | textul dupa write-back | 342 adaugari, **0 stergeri** fata de HEAD | | octeti `>0x7F` (diacritice cp1250) | 6 inainte, 6 dupa, aceleasi valori (170, 227, 254) | | clasele noi chiar in binar (`.vct`, nu in text) | `frm_sincronizare_articole` x15, `propunere_afisata` x27, `cmdSincronizeazaArticole` x3, `lblAvertisment` x2 | **Prima incercare de write-back a esuat la fidelity check** — ordonarea canonica FoxBin2Prg difera de cea scrisa de mana (intrarile `OBJECTDATA` ale header-elor de grid se genereaza singure, `ADD OBJECT`-urile se sorteaza alfabetic, `optDirectie.Click` merge dupa `Unload`). Am adoptat textul canonic din staging si am reluat — nicio pierdere de continut, diferentele erau **doar** de ordine si spatii. ## Ce contine | Piesa | Unde | |---|---| | butonul `cmdSincronizeazaArticole` (Left=350, Top=0, W=250, H=22, TabIndex=6) | `ADD OBJECT` in PAGE3 | | toggle-ul de `Enabled` pe `lArticoleReadOnly` | `frm_modific2024.Show` | | `cmdSincronizeazaArticole.Click` | `frm_modific2024` | | `AfiseazaDialogSincronizareArticole` | `frm_modific2024` | | verificarea la salvare | `frm_modific2024.inainte_de_do_termin`, imediat inainte de `RETURN m.llRet` | | clasa `frm_sincronizare_articole` (derivata din `frm_termin_renunt`) | la finalul fisierului | TabIndex 6 e liber in PAGE3 (folosite: 3, 4, 5, 20 — verificat). ## Ce am schimbat fata de patch-ul partial al agentului mort Patch-ul din diff aplicat (sters) era mai complet decat il descria predarea (avea si verificarea la salvare, in metoda corecta). Cinci corectii: **1. Lipsea `cmdSincronizeazaArticole.Click`** — butonul exista, dar nu facea nimic. Adaugat, cu aceleasi garzi ca la celelalte doua butoane din PAGE3. **2. Gridul ramanea nelegat dupa schimbarea directiei.** `ConstruiestePropunereSincronizare` face `Use In propunere_sincronizare` + `CREATE CURSOR` la fiecare apel (`ofacturare_editare.prg:584-589`), deci un grid legat la design-time de acel cursor isi pierde legatura la primul click pe radio. Solutie: gridul se leaga de **`propunere_afisata`**, un cursor cu structura identica creat o singura data in `Load` (inainte de instantierea controalelor, ca sa existe cand gridul se leaga) si doar golit + reumplut la fiecare recalcul. Nicio reasignare de `RecordSource` la runtime. **3. Declansarea la salvare era pe `Reccount(...) > 0`** — ar fi deschis dialogul la *fiecare* salvare a oricarei facturi cu articole nestocate sau in valuta, pentru ca acelea produc linii `N-A` in propunere (contract, punctele 1 si 3). Acum se numara doar `Modificare` / `Adaugare` / `Semnalare`: divergente reale. `N-A` inseamna „nu se poate compara", nu „difera", si nu mai opreste pe nimeni la salvare. **4. `Pemstatus(This.oFormArticole, ...)` fara garda de tip** — `oFormArticole` are valoarea implicita `.F.`, iar `Pemstatus` pe un logic da eroare. Adaugat `Vartype(...) == 'O'`. **5. Adaugata eticheta de avertisment** ceruta de `propunere_s4b_sincronizare.md` punctul 6 („Propunere calculata automat - verificati valorile inainte de aplicare"), plus curatarea cursorului in `Unload`. ## Verificat, nu presupus | Ce | Cum | |---|---| | `_frmbase.WindowType = 1` (dialogul e modal) | `_frm_base.vc2`, blocul `PropValue` | | `do_termin` cheama `inainte_de_do_termin()` si inchide doar pe `.T.` | `_frm_base.vc2:364-374` | | `frm_termin_renunt` are `But_termin1` + `But_renunt1` | `_frm_child.vc2:23-51` | | tiparul apelantului (`CreateObject` + `Show`, citirea lui `gnButon`) | `ofacturare_comun.vc2:4651-4656` | | clasele `_optiongrup`, `_grdrow`, `_label` exista | `_baza.vc2:435`, `_grd_base.vc2:445` | | `InputMask = (get_mask(12,gnPCANT))` e tipar real | `omodificari.vc2:12374` s.a. | | `_frm_child.vcx` nu are nevoie de `SET CLASSLIB` | precedentul `frm_modifica_articol_factura` | | toate formularele sunt pe `DataSession` implicit (1) | niciun `DataSession` in `_frm_base`/`_baza`/`omodificari` | | `SET SAFETY OFF` global (pentru `ZAP`) | `COMUN\programe\proceduri.prg:5` | | octetii cp1250 din fisier sunt neatinsi | cens `>0x7F` = 6 inainte si dupa; diff-ul are **0 stergeri** | **Netestat**: nimic nu a fost rulat. Dialogul e UI, deci nu e testabil `-A -T` (aceeasi limitare ca `frm_articol_factura`, `propunere_s4b_sincronizare.md` punctul 7). Logica pura din spate ramane acoperita de `test_s4b_sincronizare.prg` (35/0), neschimbata de aceasta livrare. ## Doua lucruri de confirmat cu Marius **A. Aplicarea la salvare ocoleste validarile deja rulate.** Daca utilizatorul apasa „Aplica" in dialogul deschis *la salvare*, `tvd` se modifica **dupa** ce validarile din `inainte_de_do_termin` (pret de achizitie, linii sterse) au trecut deja. Alternativa ar fi reluarea validarilor dupa aplicare — nu am facut-o, ca sa nu extind scopul. **B. `N-A` nu mai declanseaza dialogul la salvare** (corectia 3). E o alegere de produs facuta de mine: altfel dialogul ar aparea la fiecare salvare pe documentele in valuta. > **B — CONFIRMAT de Marius, 12.08.2026. Ramane cum e, nu se schimba nimic.** Numaratoarea de la > `omodificari.vc2:14444` sta pe `Inlist(Alltrim(actiune),'Modificare','Adaugare','Semnalare')`. > Pretul acceptat, explicit: pe liniile in valuta si pe cele nestocate o divergenta reala nu mai e > semnalata **la salvare** — se vede in schimb oricand prin butonul manual „Sincronizeaza articole", > care le arata in grid. > > **A ramane deschis** si si-a schimbat forma — vezi `progres.md`, sectiunea despre validarea de > cantitate. Plasa de siguranta pe care o propuneam initial **nu se mai face**: singura validare care > ar fi putut pica dupa „Aplica" e cea de cantitate, iar premisa ei e sub semnul intrebarii. ## Defect preexistent gasit pe drum — REPARAT (aprobat separat, 11.08.2026) `omodificari.vc2:16495`, in `frm_modific2024.pgfArticole.PAGE3.cmdAdaugaArticol.Click`: ``` IF !Used('tvd') OR !This.lAreArticoleVanzari OR Thisform.lArticoleReadOnly ``` `This` e **butonul**, nu formularul — `lAreArticoleVanzari` e proprietate a lui `frm_modific2024` (`omodificari.vc2:12987`, `:14788`, `:14795`, `:14802` o folosesc corect, toate din metode ale formularului). VFP scurtcircuiteaza `OR`: cand `tvd` exista — adica in exact cazul in care butonul e activ — primul termen e `.F.` si se evalueaza al doilea, pe buton, unde proprietatea nu exista. Nu exista metoda `Error` in `_frmbase`/`_baza`/`omodificari` care sa inghita eroarea. Concluzia: **„Adauga articol" dadea eroare la orice click real**. Suitele existente nu prind asta pentru ca apeleaza metodele formularului, nu simuleaza click-ul. **Nu era una, ci doua.** Cautarea sistematica dupa acelasi tipar (proprietati ale formularului accesate cu `This.` din metode de obiect) a mai gasit una, in aceeasi metoda, la `:16565`: ``` AddProperty(poDate, 'tip', This.nTipVanzare) ``` Ambele reparate cu `Thisform.`. In tot `frm_modific2024` nu mai exista alta: cautarea a acoperit `lArticoleReadOnly`, `lAreArticoleVanzari`, `nIdVanzare`, `nTipVanzare`, `pgfArticole`, `ActualizeazaBaraTotaluri`, `AdaugaLinieTvdDinArticol`, `calculeaza_valori_articol`, filtrata pe metode de obiect (`.Click`/`.Valid`/`.InteractiveChange`/...). Celelalte 4 folosiri ale lui `This.lAreArticoleVanzari` sunt in metode ale **formularului** (`ActualizeazaBaraTotaluri`, `Show`) si sunt corecte. Nu intra in changelog: 2.11.15 nu e inca in productie, deci e un defect al codului nelivrat. ## Changelog Paragraf nou in blocul **2.11.15** (`:nou:`), nu versiune noua — 2.11.16 a fost dat inapoi „pana la punerea in productie" (commit `09f9d47`). Descrie butonul, alegerea directiei, liniile marcate si lasate neatinse, si comparatia de la salvare cu optiunea de a salva fara sincronizare. Fisierul `changelog_roafacturare.txt` avea deja **un octet stricat in HEAD** (`EF BF BD`, un `©` transformat candva in U+FFFD, in intrarea despre „ROA Romfast SRL"). E preexistent, **nu l-am atins**; cenzul ramane 3 octeti `>0x7F` inainte si dupa editarea mea. ## Ce urmeaza 1. **Rebuild `roafacturare.exe`** din IDE si testul pe ecran. Metodele `.vcx` sunt deja compilate de `txt2vcx.ps1`; EXE-ul nu. 2. Punctele A si B de confirmat.