diff --git a/.gitignore b/.gitignore index ff64370..5fd1f6a 100644 --- a/.gitignore +++ b/.gitignore @@ -104,5 +104,6 @@ roacont_ref.FPT # --- COMUN este gestionat separat, prin propriul sau git (romfast/comun.git) --- COMUN/ -docs/diff_runda*.patch +docs/diff_*.patch .gstack/ +docs/local/ diff --git a/Clase/ovanzcump.vc2 b/Clase/ovanzcump.vc2 index bb021ab..1767c88 100644 --- a/Clase/ovanzcump.vc2 +++ b/Clase/ovanzcump.vc2 @@ -20865,7 +20865,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - SET STEP ON lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -21063,7 +21062,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -21274,7 +21272,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -21485,7 +21482,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -22921,7 +22917,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - SET STEP ON lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -23119,7 +23114,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -23330,7 +23324,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -23541,7 +23534,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -25155,7 +25147,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - SET STEP ON lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -25353,7 +25344,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -25564,7 +25554,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -25775,7 +25764,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -25997,7 +25985,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -26221,7 +26208,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -26425,7 +26411,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -26631,7 +26616,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -26835,7 +26819,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -28466,7 +28449,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - SET STEP ON lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -28664,7 +28646,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -28875,7 +28856,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -29086,7 +29066,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -29308,7 +29287,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -29532,7 +29510,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -29736,7 +29713,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -29942,7 +29918,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -30146,7 +30121,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx" Set Date To Ymd Set Mark To '-' - Set Step On lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumeDeclarant = lcNumePrenumeDeclarant lcPrenumeDeclarant = "" @@ -38862,7 +38836,6 @@ DEFINE CLASS frm_regcump2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx" *!* Delete From cListRCTemp Where Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') Not In ; *!* (Select Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') From cListRC WHERE !EMPTY(NVL(denumire,'')) ) *!* Endif - SET STEP ON WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT *** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE) TEXT to m.lcSql textmerge noshow @@ -42642,14 +42615,14 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" from vjc2010 where an = <> and luna = <> - and (RO11nt <> 0 or RO21nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0) + and (RO11nt <> 0 or RO21nt <> 0 or ro20nt <> 0 or ro24nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0) and tva_incasare = 1) group by id_fact, cont) ip on jc.id_fact = ip.id_fact where jc.an = <> and jc.luna = <> and jc.tva_incasare = 1 - and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0) + and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro20nt <> 0 or jc.ro24nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0) and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0 ENDTEXT @@ -43155,7 +43128,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" lcWhere = Alltrim(Substr(m.lcWhere, m.lnPos + 11)) Endif Endif - SET STEP ON Do Case Case m.lnTipJurnal = 1 pcSubtitlu = "Achizitii de bunuri si prestari de sevicii taxabile din tara" @@ -43452,7 +43424,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" *!* Delete From cListRCTemp Where Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') Not In ; *!* (Select Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') From cListRC WHERE !EMPTY(NVL(denumire,'')) ) *!* Endif - SET STEP ON WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT *** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE) TEXT to m.lcSql textmerge noshow @@ -43467,7 +43438,7 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" LEFT Join JTVA_COLOANE J2 On J.id_jtva_coloana = J2.id_tva left join nom_fdoc fdoc on a.id_fdoc = fdoc.id_fdoc where a.an = ?m.gnAn and a.luna = ?m.gnLuna and a.sters = 0 and a.scd = '4426' And a.scc = '4428' And Nvl(a.id_jtva_coloana, 0) <> 0 - and jc.an = ?m.gnAn and jc.luna = ?m.gnLuna and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0) + and jc.an = ?m.gnAn and jc.luna = ?m.gnLuna and (jc.RO11nt <> 0 or jc.RO21nt <> 0 or jc.ro20nt <> 0 or jc.ro24nt <> 0 or jc.ro19nt <> 0 or jc.ro9nt <> 0 or jc.ro5nt <> 0) ORDER BY a.cod, J2.COLOANA_JC ENDTEXT @@ -44214,7 +44185,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" *!* 25.08.2014 *!* marius.mutu *!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0 - SET STEP ON Local lcXMLFacturi If !(luna_inchisa Or m.glEMama) Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO09NB+RO05NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO09NT+RO05NT) as soldn, ; @@ -50170,7 +50140,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx" ENDPROC PROCEDURE do_excel - SET STEP ON do export_excel_grid WITH thisform._grdbase1,"dataact, nract", "", this.lb_titlu_alb_b121.caption IN proceduri_excel.prg return @@ -50521,7 +50490,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx" update_jtva_coloane('JV') *** SELECTEZ FACTURILE CU TVA_INCASARE CU TOTAL BAZA, TVA, BAZAN, TVAN - SET STEP ON Select r.cod, r.id_fact, r.tip, r.denumire, r.nract, r.SERIE_ACT, r.dataact, r.COD_FISCAL, Space(10) As COD_TVA, Space(100) As EXPLICATIE_TVA, r.TOTCTVA, r.TOTFTVATAX, r.TOTTVATAX, TVA_INCASARE, ; (RO24B + RO20B + RO19B + RO9B + RO5B + CESCDD1 + CESCDD2 + CEOPTR + FODD + FOFDD + CESVDD + CESVFDD + CESVFS + ROTI + WRN + WRSCDD + WRSCFDD) As BAZA, ; (RO24T + RO20T + RO19T + RO9T + RO5T) As TVA, ; @@ -51396,7 +51364,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx" *!* 25.08.2014 *!* marius.mutu *!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0 - SET STEP ON Local lcXMLFacturi If !(luna_inchisa Or m.glEMama) Select *, (RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ; @@ -53816,8 +53783,8 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" select jv.id_fact, ip.cont, nvl(ip.sold, 0) as soldf, - (RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as soldn, - nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as solddif, + (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as soldn, + nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as solddif, jv.denumire, jv.nract, jv.serie_act, @@ -53830,6 +53797,10 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" jv.RO11nt, jv.RO21nb, jv.RO21nt, + jv.RO20nb, + jv.RO20nt, + jv.RO24nb, + jv.RO24nt, jv.ro19nb, jv.ro19nt, jv.ro9nb, @@ -53849,15 +53820,15 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" from vjv2010 where an = <> and luna = <> - and (RO11nt <> 0 or RO21nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0) + and (RO11nt <> 0 or RO21nt <> 0 or ro20nt <> 0 or ro24nt <> 0 or ro19nt <> 0 or ro9nt <> 0 or ro5nt <> 0) and tva_incasare = 1) group by id_fact, cont) ip on jv.id_fact = ip.id_fact where jv.an = <> and jv.luna = <> and jv.tva_incasare = 1 - and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0) - and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0 + and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro20nt <> 0 or jv.ro24nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0) + and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0 ENDTEXT llSucces = goExecutor.oExecuta(m.lcSql, "crsSoldDif") @@ -53888,7 +53859,6 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" ENDPROC PROCEDURE do_excel - SET STEP ON do export_excel_grid WITH thisform._grdbase1,"dataact, nract", "", this.lb_titlu_alb_b121.caption IN proceduri_excel.prg return @@ -54377,7 +54347,7 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" LEFT Join JTVA_COLOANE J2 On J.id_jtva_coloana = J2.id_tva left join nom_fdoc fdoc on a.id_fdoc = fdoc.id_fdoc where a.an = ?m.gnAn and a.luna = ?m.gnLuna and a.sters = 0 and a.scd = '4428' And a.scc = '4427' And Nvl(a.id_jtva_coloana, 0) <> 0 - and jv.an = ?m.gnAn and jv.luna = ?m.gnLuna and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0) + and jv.an = ?m.gnAn and jv.luna = ?m.gnLuna and (jv.RO11nt <> 0 or jv.RO21nt <> 0 or jv.ro20nt <> 0 or jv.ro24nt <> 0 or jv.ro19nt <> 0 or jv.ro9nt <> 0 or jv.ro5nt <> 0) order by a.cod, J2.COLOANA_JC ENDTEXT @@ -55063,7 +55033,6 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx" *!* 25.08.2014 *!* marius.mutu *!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0 - SET STEP ON Local lcXMLFacturi If !(luna_inchisa Or m.glEMama) Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ; diff --git a/Programe/oproceduri_inchidere.prg b/Programe/oproceduri_inchidere.prg index a439d2b..038c4ed 100644 --- a/Programe/oproceduri_inchidere.prg +++ b/Programe/oproceduri_inchidere.prg @@ -771,7 +771,7 @@ Procedure inchidere_tva_sold Local lnIdSet, lnNrAct, lnProcTVA, lnRecords, lnSucces, lnSuma, loAct Local lnCota, lnCotaTVA, lnSuma24, lnSuma5, lnSuma9, lnSumaT Local lnSuma24T, lnSuma5T, lnSuma9T, lnSumaNT, lcMesaj -SET STEP ON + Local lnSuma11, lnSuma19, lnSuma20, lnSuma21, lnSuma11T, lnSuma19T, lnSuma20T, lnSuma21T lcJurnal = Upper(Alltrim(m.tcJurnal)) && JC/JV If m.lcJurnal = 'JC' && Jurnal Cumparari lcSCD = '4426' @@ -788,7 +788,6 @@ SET STEP ON lcMesaj = '' lnIdSet = 99999 && nota fara predefinire lnBut = lans(m.lnIdSet) - Set Step On If m.lnBut = 1 Select actactan Scatter Name loAct @@ -799,8 +798,18 @@ SET STEP ON lnNrAct = crsTVAIncasareTemp.nract lnIdFact = crsTVAIncasareTemp.id_fact lnSumaT = soldn - lnSuma21 = soldn21 - lnSuma11 = soldn11 + lnSuma21 = 0 + lnSuma11 = 0 + lnSuma21T = 0 + lnSuma11T = 0 + If Type('crsTVAIncasareTemp.soldn21') = 'N' + lnSuma21 = crsTVAIncasareTemp.soldn21 + lnSuma11 = crsTVAIncasareTemp.soldn11 + Endif + If Type('crsTVAIncasareTemp.ro21nt') = 'N' + lnSuma21T = crsTVAIncasareTemp.ro21nt + lnSuma11T = crsTVAIncasareTemp.ro11nt + Endif lnSuma24 = soldn24 lnSuma20 = soldn20 @@ -809,16 +818,12 @@ SET STEP ON lnSuma5 = soldn5 If m.lcJurnal = 'JC' && Jurnal Cumparari - lnSuma21T = ro21nt - lnSuma11T = ro11nt lnSuma24T = ro24nt lnSuma20T = ro20nt lnSuma19T = ro19nt lnSuma9T = ro09nt lnSuma5T = ro05nt ELSE - lnSuma21T = ro21nt - lnSuma11T = ro11nt lnSuma24T = ro24nt lnSuma20T = ro20nt lnSuma19T = ro19nt @@ -830,7 +835,7 @@ SET STEP ON lnSuma = m.lnSumaT lnCotaTVA = 0.00 If m.lnSumaT = 0 - lnSuma = Iif(m.lnCota = 1, m.lnSuma24, Iif(m.lnCota = 2, m.lnSuma20, Iif(m.lnCota = 3, m.lnSuma19, Iif(m.lnCota = 4, m.lnSuma9, Iif(m.lnCota = 5, m.lnSuma5, Iif(m.lnCota = 21, m.lnSuma21, m.lnSuma11)))))) + lnSuma = Iif(m.lnCota = 1, m.lnSuma24, Iif(m.lnCota = 2, m.lnSuma20, Iif(m.lnCota = 3, m.lnSuma19, Iif(m.lnCota = 4, m.lnSuma9, Iif(m.lnCota = 5, m.lnSuma5, Iif(m.lnCota = 6, m.lnSuma21, m.lnSuma11)))))) lnCotaTVA = Iif(m.lnCota = 1, 1.24, Iif(m.lnCota = 2, 1.20, Iif(m.lnCota = 3, 1.19, Iif(m.lnCota = 4, 1.09, Iif(m.lnCota = 5, 1.05, Iif(m.lnCota = 6, 1.21, 1.11)))))) Endif diff --git a/changelog_roacont.txt b/changelog_roacont.txt index 5f89c83..3f048cc 100644 --- a/changelog_roacont.txt +++ b/changelog_roacont.txt @@ -1,7 +1,28 @@ diff --git a/docs/design-alegere-partener-anaf.md b/docs/design-alegere-partener-anaf.md deleted file mode 100644 index 5682349..0000000 --- a/docs/design-alegere-partener-anaf.md +++ /dev/null @@ -1,941 +0,0 @@ - -# Design: Asistenta alegere partener corect la introducere (verificare ANAF automata) - -Generat de /office-hours pe 24.07.2026 -Branch: main (implementarea va merge pe claude/) -Repo: romfast/roacont (mirror git al SVN ^/ROACONT/Trunk) -Status: APPROVED (24.07.2026, D7) -Mode: Startup (intraprenoriat — produs intern ROA) - -## Problema - -La introducerea facturilor de achizitie/vanzare (si la incasari/plati) utilizatorul -alege partenerul dintr-un dialog de cautare. Cand un partener isi schimba calitatea -de platitor TVA, conventia ROA cere ALT partener (alt `nom_parteneri.id_par`) cu -acelasi nume si cod fiscal cu/fara RO; cel vechi se marcheaza de regula INACTIV. -Probleme concrete: - -1. Utilizatorul nu are nicio informatie, la selectie, despre situatia ANAF curenta - a partenerului (platitor TVA sau nu, activ/radiat) — statutul se poate schimba - oricand, chiar daca partenerul nu are inca o "pereche". -2. Perechea inactiva e complet invizibila (filtru hardcodat `STERS=0 AND INACTIV=0`), - deci la o noua schimbare de calitate utilizatorul creeaza al TREILEA duplicat in - loc sa reactiveze partenerul vechi. -3. Alegerea gresita din pereche rupe imperecherea plati/incasari cu facturi - (aceeasi cheie `id_part`), producand solduri fantoma pe doi parteneri. -4. Importurile (eFactura, extrase) compara codul fiscal doar cu UPPER+ALLTRIM, - deci `RO12345` si `12345` sunt terti diferiti — fabrica de duplicate noi. - -## Evidenta cererii - -- Situatie recurenta la clientii ROACONT: parteneri care comuta calitatea de - platitor TVA de mai multe ori; utilizatori care aleg din greseala membrul gresit - al perechii; corectii manuale costisitoare la imperecherea plati-facturi. -- Butonul de verificare ANAF exista deja in nomenclator si e folosit — dar e in alt - flux decat introducerea, unde se ia de fapt decizia. - -## Status quo (fluxul actual, mapat in cod) - -- Nucleu selectie: `CautPartenerContabilitate()` — `COMUN\programe\ocautare.prg:56` - (SELECT `ID_PART, DENUMIRE, COD_FISCAL` din `NOM_PARTENERI`, filtru inactivi - `:117-121`), varianta casa/banca `caut_parteneri()` `:161` (param `tlInactiv` - `:175-177`), selectie multipla `caut_parteneri_xml()` `:199`. -- Dialog: `cauta_alfa_form(_plus)` — `COMUN\clase\cauta_alfa_forms.vc2` (do_cauta, - do_alege, do_adauga/buton Nou). -- Puncte de apel: note contabile/facturi (`Clase\ointroduceri_cont.vc2`, - `verific_partener` :1542/:4769 → `do_cauta_partener` :921/:3848), casa/banca - (`COMUN\clase\ocasabanca.vc2:1788,1823`), stornare - (`Ferestre\frm_stornare_plinc.sc2:368`), importuri - (`frm_import_extrase_banca.sc2`, `frm_import_note_a4200.sc2`, - `oproceduri_import.prg:364/:746`). -- Verificare ANAF existenta: clasa `VerificareANAF` cu - `ANAF_SincronWebService_PlatitorTva` — `COMUN\programe\validare.prg:1552,1603` - (endpoint v9 `PlatitorTvaRest`, loturi max 100 CUI, pauza 1s; intoarce `scpTVA`, - `statusInactivi`, `statusTvaIncasare`, denumire/adresa); buton `but_verifica` - (`COMUN\clase\cmd_butoane.vc2:427`) doar pe nomenclator/formular verificare. -- Statutul TVA NU e stocat pe partener: se deduce din prefixul `RO` al - `COD_FISCAL` (ex. `saft_d406.prg:1066`). Rezultatele verificarii merg doar in - istoric (`pack_parteneri.save_istoric_cod_fiscal`, `validare.prg:757`). - -## Utilizator tinta si pana cea mai ingusta - -Operatorul de contabilitate care introduce zilnic facturi si incasari/plati. -Pana cea mai ingusta: in momentul alegerii partenerului, sa i se spuna automat -"ANAF zice altceva decat codul fiscal al partenerului ales" si sa i se ofere -perechea corecta (inclusiv cea inactiva) sau crearea unui partener nou. - -## Constrangeri - -- 80/20: modificari minime cu efect maxim; fara refactorizari; fara schimbare de - schema Oracle (fara coloana "platitor TVA" pe `nom_parteneri`). -- VFP9 legacy, fara teste automate; comentarii in cod max o linie `*!*`. -- Conventia ROA ramane: partener nou la schimbare de calitate TVA; regula se - documenteaza (nu era scrisa nicaieri pana la acest document). -- Fara commit (git/SVN) fara review pe diff in `docs/`. - -## Premise agreate - -1. Modelul de date ramane neschimbat; statutul TVA se deduce din prefixul RO. -2. (revizuita) Durerea are DOUA surse: lipsa de vizibilitate la selectie SI - duplicatele nascute la import din compararea nenormalizata a codului fiscal. -3. Punctul de interventie cu efect maxim e nucleul de selectie din `ocautare.prg` - (+ dialogul `cauta_alfa_form`), mostenit de toate punctele de apel. -4. (decizie utilizator, D5) Verificarea ANAF se face AUTOMAT la fiecare alegere de - partener, nu doar cand exista pereche — statutul se poate schimba intre timp. - -## Perspectiva cross-model (subagent independent) - -- Steelman: dialogul de selectie devine "ghid de decizie" — o singura interventie - in nucleu, mostenita de toate formularele, fara schimbare de model de date. -- Insight-cheie: criteriul de "partener corect" nu e doar ANAF, ci SI "pe ce - id_part sunt documentele existente" → fereastra de decizie afiseaza data - ultimului document per membru al perechii. -- Premisa contestata (acceptata): duplicatele se nasc si la import → fixul de - potrivire normalizata intra in pachet. -- Idee laterala retinuta ca transa viitoare: raport pasiv de discordante - "prefix RO vs ultimul istoric ANAF" peste datele deja colectate. - -## Abordari considerate - -### A: Doar buton manual "Verificare ANAF" in dialogul de selectie -Refolosire `but_verifica`; zero latenta automata. Respinsa ca insuficienta: -protectia depinde de disciplina utilizatorului. - -### B (ALEASA): Verificare ANAF automata la alegere + fereastra de decizie + fix import -Detalii mai jos. Completeness 9/10 pe durerea descrisa. - -### C: B + raport pasiv discordante ANAF din istoric -Amanata ca transa separata (depinde de cat de des ruleaza clientii verificarea in -lot; decuplata de hot path — se poate adauga oricand). - -## Abordarea recomandata (aprobata: B) - -Interventie intr-un singur punct comun + doua completari mici: - -1. **Functie noua** `VerificaPartenerLaSelectie(toPartener)` in - `COMUN\programe\ocautare.prg`, apelata din `CautPartenerContabilitate()` - **inainte de blocul `ADAUGA_CORESP_TIP_PART` (`ocautare.prg:148-150`)** — daca - utilizatorul comuta pe pereche, corespondentele tip-partener se adauga pe - id_part-ul FINAL, nu pe cel initial. Acopera note/facturi, stornare, importuri - fara sa atinga cele ~10 puncte de apel. - - **Contract**: functia primeste si poate REESCRIE obiectul de retur - (`id_part`, `nume/denumire`, `cod_fiscal`, `tip`); daca `loCauta` e NULL/gol - (utilizatorul a renuntat la cautare), verificarea se sare complet. - - **Politica de activare (decizie eng review D1, apelanti triati in cod)**: - hibrid explicit. `CautPartenerContabilitate`: hook ON implicit (apelantii - sunt fluxuri de introducere), cu opt-out DOAR la `orap_terti.prg:1019` - (raport). `caut_parteneri`: hook OFF implicit, activat EXPLICIT (parametru - nou `tlVerificaANAF`) la cele 4 puncte de introducere: `ocasabanca.vc2` - (:1823), `frm_import_extrase_banca.sc2` (:2211, :2616), - `ointroduceri_cont.vc2` (:9665, :9704). Fluxurile de consultare (fisa - cont `fisa_cont_noua.sc2:459`, `orap_trezorerie.prg:31/:229`, - `orap_terti.prg:826/:1794/:1986`) raman NEATINSE, fara nicio modificare. - - Apel ANAF pentru CUI-ul partenerului ales: **wrapper nou single-CUI** peste - `VerificareANAF` (functia de lot `ANAF_SincronWebService_PlatitorTva` e - construita pentru loturi de 100 cu logging intens — nu se cheama direct in - hot path); timeout-ul se seteaza pe obiectul WinHTTP cu `SetTimeouts`. - - **Cache pe sesiune** — proprietate pe un obiect global existent (ex. - `goApp`) sau colectie publica declarata in `roacont.prg`, cheie = CUI - normalizat (fara RO), valoare = rezultat+timestamp; se goleste la - schimbarea firmei. Un CUI verificat o data pe sesiune nu mai genereaza - apel — limiteaza si presiunea pe serviciul ANAF (mai multi operatori - simultan raman fiecare cu 1 apel/CUI/sesiune). - - **Degradare tacuta**: fara internet / ANAF cazut / timeout ⇒ comportament - identic cu azi (fara mesaje de eroare in hot path). - - **Guard obligatoriu de mediu partajat**: `ocautare.prg` e inclus si de alte - produse ROA — hook-ul verifica intai existenta clasei - (`TYPE("goApp")`/`ALINES`+`SET("PROCEDURE")` sau `try CREATEOBJECT` cu - fallback) si degradeaza tacut daca `validare.prg`/`VerificareANAF` nu sunt - incarcate in acel produs. Fara guard, orice selectie de partener din - produsele-frate ar crapa la runtime. - - **Excluderi**: persoane fizice (TIP_PERSOANA=2 / CNP 13 cifre), coduri - nenumerice dupa eliminarea RO, parteneri externi (COD_TARA<>RO). -2. **La discordanta** (ANAF `scpTVA` ≠ prefixul RO al partenerului ales, sau - `statusInactivi` = inactiv/radiat) — fereastra compacta de decizie - (**forma noua mica in `COMUN\ferestre\`**, pe stilul dialogurilor existente; - nu AMESSAGEBOX — are grid cu membrii perechii si 3-4 butoane): - - Cauta perechea dupa CUI normalizat (fara RO), **INCLUSIV INACTIV=1** - (interogare Oracle ieftina; filtrul gridului principal NU se schimba). - - Afiseaza toti membrii: ID, denumire, cod fiscal, activ/inactiv, - **data ultimului document** per `id_part` (MAX peste jurnal cumparari, - jurnal vanzari si casa/banca — lista exacta a tabelelor se confirma la - implementare; atentie la lipsa indexului pe `id_part` pe baze mari — se - ruleaza DOAR in fereastra de discordanta, nu in hot path). - - Actiuni: (a) alege perechea concordanta cu ANAF; (b) **swap ghidat** cu - confirmare: reactiveaza perechea + inactiveaza partenerul curent (evita al - treilea duplicat); dupa swap se face **refresh pe cursorul de selectie** - (cel vechi dispare, cel reactivat apare); (c) fara pereche: propune buton - "Nou" cu CUI-ul corect precompletat; (d) continua oricum (utilizatorul - decide, nimic blocant). - - **Guvernarea swap-ului (decizie CEO review D2)**: swap-ul se executa prin - calea EXISTENTA de modificare nomenclator (`nom_parteneri_modifica` / - pachetul Oracle aferent), NU prin UPDATE ad-hoc in ocautare.prg — o - singura cale de scriere in nom_parteneri. Gating cu dreptul EXISTENT de - modificare nomenclator parteneri (`verifica_drepturi`): fara drept, - butonul de swap e dezactivat cu tooltip explicativ, dar perechea poate fi - in continuare ALEASA. - - **Kill-switch (decizie CEO review D4)**: optiune noua in `settings.ini`, - sectiunea `[anaf]`, `verificare_selectie=1` implicit (citita cu `getini`). - Cu 0, verificarea automata la selectie e oprita complet (comportament - identic cu azi) — rollback chirurgical per statie/client fara downgrade - de exe. - - Concordanta ⇒ nicio fereastra, flux identic cu azi. -3. **Fix import** (`Programe\oproceduri_import.prg`, potrivirea - `GetPartenerByCodFiscal` :449 / dedup :4479-4495, citare verificata): cand - potrivirea exacta esueaza, se incearca potrivirea pe CUI normalizat (fara - RO); la gasire NU se alege automat — se cere confirmare ("exista partener cu - acelasi CUI fara/cu RO — folosesti acela sau creezi unul nou?"). - **Pe loturi** (zip eFactura): confirmarile NU se pun una cate una in mijlocul - importului — discordantele se colecteaza si se prezinta o singura data, la - final, intr-o lista cu optiune per rand + "aplica la toate". Opreste fabrica - de duplicate fara sa blocheze importul. -4. **Optional** (redundant partial cu verificarea automata — se taie daca - diff-ul creste): buton `but_verifica` si in `cauta_alfa_form`, pentru - verificare manuala INAINTE de alegere. - -### Ce NU facem (explicit) -- Nu adaugam coloana TVA / data verificare pe `nom_parteneri`. -- Nu facem merge/reasignare de documente intre id_part-uri. -- Nu schimbam filtrul `STERS=0 AND INACTIV=0` al gridului de selectie. -- Nu blocam alegerea: toate avertismentele sunt informative, cu "continua oricum". - -## Intrebari deschise - -1. ~~Drepturile swap~~ — REZOLVAT (CEO review D2): dreptul existent de - modificare nomenclator parteneri; executie prin calea existenta de - modificare, nu UPDATE ad-hoc. -2. TTL cache: pe sesiune (propus) sau pe zi (persistat)? Propunerea: sesiune. -3. `caut_parteneri_xml` (selectie multipla) intra in scope sau ramane pe fluxul - vechi? Propunerea: ramane pe fluxul vechi (volum mare de CUI-uri per apel). -4. Latenta reala ANAF in orele de varf — de masurat inainte de a decide timeout-ul. -5. ~~Sursa `tip` la comutare~~ — REZOLVAT (eng review D2): la comutarea pe - pereche, `tip` se recalculeaza pentru id-ul perechii cu acelasi criteriu ca - in SELECT-ul gridului (apartenenta la `coresp_tip_part` pentru tipurile - contului); hook-ul fiind inainte de blocul `ocautare.prg:148-150`, blocul - existent adauga natural corespondenta lipsa pe id-ul FINAL. Nota de - implementare: wrapper-ul single-CUI sta in `validare.prg`, langa clasa - `VerificareANAF` (coeziune). - -## Criterii de succes - -- La alegerea unui partener discordant cu ANAF, utilizatorul vede fereastra de - decizie intr-un timp acceptabil (tinta orientativa <3s; pragul final se - fixeaza dupa masuratorile de latenta din Tema) si poate ajunge la perechea - inactiva fara sa iasa din fluxul de introducere. -- Zero regresie de viteza cand ANAF nu raspunde (degradare tacuta). -- Importul eFactura nu mai creeaza partener nou fara confirmare cand exista - pereche pe CUI normalizat. -- Niciun duplicat nou "al treilea" la clientii-pilot dupa o luna de folosire. - -## Plan de distributie - -Livrare in `roacont.exe` prin fluxul existent: build din VFP IDE (`roacont.PJX`), -revizie in `pj2`, intrare in `changelog_roacont.txt` (tag `:nou:`), commit SVN de -catre Marius dupa aprobarea diff-ului. Nu necesita migrare Oracle (fara DDL). - -## Dependinte - -- Serviciul ANAF `PlatitorTvaRest v9` (deja folosit in verificarea din nomenclator). -- `COMUN\programe\validare.prg` si `ocautare.prg` sunt partajate cu alte produse - ROA care le includ — de verificat la implementare cine mai apeleaza - `caut_parteneri`/`CautPartenerContabilitate` din alte produse (blast radius - COMUN vs COMUNROA). - -## Anexa: harta erorilor, edge-case-uri si teste (CEO review D3) - -### Harta erorilor (regula-cheie: verificarea esueaza TACUT, swap-ul esueaza ZGOMOTOS) - -| Cale | Ce poate merge prost | Actiune | Utilizatorul vede | -|---|---|---|---| -| Apel ANAF (wrapper) | timeout / DNS / HTTP 5xx / 429 | degradare tacuta + UN log pe sesiune (nu per apel) | ~~nimic (flux ca azi)~~ — REVIZUIT REVIZIA 5: banda gri "ANAF nu a raspuns - verificare sarita" in toate cazurile (timeout/DNS/conexiune refuzata SI HTTP 5xx/429); doar timeout/DNS/conexiune refuzata (`FARA_RASPUNS`) deschide intrerupatorul, vezi REVIZIA 5 pt. 5 | -| Raspuns ANAF | JSON malformat / ~~CUI negasit~~ / refuz | tratat ca "fara informatie" → degradare tacuta | nimic — REVIZUIT REVIZIA 5: 404 cu `notFound` continand chiar CUI-ul cerut nu mai e "fara informatie", da verdict rosu "Cod fiscal inexistent la ANAF" (vezi REVIZIA 5 pt. 4) | -| Query pereche Oracle | eroare goExecutor | degradare tacuta + log | nimic | -| MAX(data doc) per id_part | lent / eroare | fereastra se deschide FARA coloana "ultim doc" | fereastra fara acea coloana | -| Swap (via nom_parteneri_modifica) | eroare Oracle / lock / drept lipsa | mesaj de EROARE vizibil; partenerul ramane neschimbat | AMESSAGEBOX cu cauza | -| Anulare fereastra (ESC/inchidere) | — | selectia ORIGINALA ramane valabila | revine in formular cu partenerul ales initial | -| Dublu-click / reintrare | apel dublu in curs | guard de reintrare (flag "verificare in curs") — implementat REVIZIA 5 (`lVerificareInCurs`, vezi REVIZIA 5 pt. 8), nu doar cerut | un singur apel, o singura fereastra | - -### Ordinea operatiilor (performanta) -1. Alege partener → 2. cache lookup CUI → 3. apel ANAF (doar daca nu e in -cache) → 4. concordant ⇒ STOP (zero query suplimentar pe selectiile normale) -→ 5. DOAR la discordanta: query pereche pe CUI normalizat (inclusiv inactivi) -+ MAX(data doc) per membru → 6. fereastra de decizie. - -### Reguli de implementare -- **`NormalizeazaCUI()`** — functie UNICA in COMUN (strip RO doar daca restul - e numeric, UPPER, fara spatii), folosita de wrapper, de query-ul de pereche - si de fixul de import. Fara logica duplicata in 3 locuri. -- **Indicator vizual**: wait cursor + text scurt "Verificare ANAF..." pe durata - apelului (hot path-ul devine perceptibil doar cand chiar se apeleaza ANAF). -- **Logging**: fiecare discordanta gasita se logheaza in `goLog` (CUI, id_part - ales, ce a zis ANAF, ce a decis utilizatorul) — diagnosticabil ulterior. -- **Kill-switch**: `settings.ini [anaf] verificare_selectie=0` dezactiveaza - complet hook-ul (verificat la intrare in functie, inainte de orice). - -### Lista de teste (manual / harness headless — test_init_env_auto) -1. Partener concordant (RO + ANAF platitor) → niciun mesaj, flux identic. -2. Discordant cu pereche ACTIVA → fereastra, alegerea perechii scrie id-ul corect. -3. Discordant cu pereche INACTIVA → fereastra o arata; swap reactiveaza/inactiveaza - + refresh cursor; fara drept de nomenclator → buton dezactivat, alegerea merge. -4. Discordant FARA pereche → propunere "Nou" cu CUI precompletat. -5. ~~Fara internet / ANAF cazut → zero mesaje, flux identic cu azi, un log.~~ - REVIZUIT REVIZIA 5: Fara internet / ANAF cazut → banda gri "ANAF nu a - raspuns - verificare sarita" (nu zero mesaje), niciun dialog modal, flux - fara blocare; log pe tranzitie de stare, nu per apel (vezi REVIZIA 5 pt. 1-2). -6. Persoana fizica (CNP) / partener extern (COD_TARA<>RO) / CUI gol → skip total. -7. Import lot eFactura cu discordante → confirmarile apar O DATA la final, - "aplica la toate" functioneaza, niciun partener creat fara confirmare. -8. Dublu-click rapid pe rand → un singur apel ANAF, o singura fereastra. -9. Kill-switch 0 → comportament identic cu versiunea anterioara. -10. Cache: al doilea document pe acelasi partener in aceeasi sesiune → zero - apel ANAF nou. -11. REGRESIE (eng review D1): fisa de cont si rapoartele terti/trezorerie NU - declanseaza verificarea ANAF — comportament identic cu versiunea anterioara. - -## Specificatia vizuala a ferestrei de decizie (design review D2-D3) - -``` -+--- Verificare partener ANAF ------------------------------------+ -| ANAF: NEPLATITOR TVA (din 01.03.2026). Partenerul ales are | -| codul fiscal RO12345678 — nu corespunde. | <- verdictul, PRIMUL -+------------------------------------------------------------------+ -| ID | Denumire | Cod fiscal | Stare | Ultim document | -| 1234 | FIRMA SRL | RO12345678 | Activ | 15.06.2026 | <- alegerea initiala -|>5678 | FIRMA SRL | 12345678 | INACTIV | 20.02.2026 | <- PERECHEA, preselectata -+------------------------------------------------------------------+ -| [Alege selectat] [Reactiveaza+inactiveaza] [Nou] [Continua] | -+------------------------------------------------------------------+ -``` - -- **Ierarhie**: 1) verdictul intr-o propozitie (status ANAF + data + de ce nu - corespunde), 2) gridul cu toti membrii, randul CONCORDANT cu ANAF preselectat, - 3) butoanele. Ton utilitar, fara alarmism — o singura decizie pe ecran. -- **Tastatura (decizie D2)**: Enter = alege randul selectat (preselectat: - perechea concordanta); sageti = schimba selectia; ESC = pastreaza alegerea - originala (inchide fara nicio actiune); swap DOAR pe butonul dedicat, cu - confirmare suplimentara — niciodata pe Enter. Hotkey-uri pe butoane (VFP \<). -- **Conventii existente refolosite**: randul INACTIV colorat gri - RGB(225,225,225) + tooltip — aceeasi conventie pe care utilizatorii o stiu - din cauta_alfa_form ("partenerii de alt tip sunt colorati gri", - ocautare.prg:136-137); butoane din cmd_butoane.vcx; erori prin AMESSAGEBOX; - fereastra pe clasele de baza cont2000 (stil identic cu dialogurile existente). -- **Starea "fara pereche"**: fereastra FARA grid — doar verdictul + butoanele - [Nou (CUI precompletat)] si [Continua]; Enter = Continua (aici NU exista - alternativa corecta de preselectat, deci implicitul ramane conservator). -- **Butonul de swap fara drept de nomenclator**: dezactivat (nu ascuns), cu - tooltip "Necesita drept de modificare nomenclator parteneri". -- **Indicator in dialogul de selectie**: pe durata apelului ANAF — wait cursor - + WAIT WINDOW "Verificare ANAF..." NOWAIT, sters imediat dupa raspuns; - vizibil doar cand apelul chiar are loc (cache miss). - -## Regula de lucru documentata (nota ceruta — nu era scrisa nicaieri) - -**Conventie ROA — schimbarea calitatii de platitor TVA a unui partener:** -1. NU se modifica codul fiscal al partenerului existent (istoricul documentelor - ramane legat de `id_part`-ul vechi si de statutul TVA de la acea data). -2. Se foloseste ALT partener cu acelasi nume si codul fiscal cu/fara RO dupa noua - calitate. Daca perechea EXISTA deja (chiar inactiva), se REACTIVEAZA aceea — - nu se creeaza al treilea duplicat. -3. De regula, membrul care nu mai corespunde se marcheaza INACTIV ca sa nu mai - apara la introducere. Daca ambii raman activi (situatii tranzitorii), - utilizatorul alege dupa situatia ANAF si dupa documentul introdus. -4. La incasari/plati se alege ACELASI `id_part` ca pe facturile pe care le - stinge — altfel imperecherea plati-facturi se rupe. - -(La implementare, acest text se muta/copiaza si in `COMUN\docs\` daca vrem sa fie -vizibil si celorlalte produse ROA.) - -## Tema (assignment) - -Inainte de implementare, ruleaza pe o baza reala de client doua masuratori: -1. `SELECT` de numarare: cate grupuri de CUI normalizat (fara RO) au >1 partener - si cati dintre ei au membri inactivi — dimensioneaza problema reala. -2. 10 apeluri ANAF `PlatitorTvaRest` la ore diferite — masoara latenta reala - pentru alegerea timeout-ului. -Rezultatele decid timeout-ul si daca fereastra de decizie are nevoie de -pre-incarcare asincrona. - -## Ce am observat la felul in care gandesti - -- Ai respins ambele extreme si ai corectat exact pe mecanism: "chiar daca nu - exista o pereche, tot trebuie facuta verificarea automata pe ANAF, pentru ca - intre timp partenerul isi poate fi schimbat calitatea" — ai vazut ca riscul e - in timp, nu in structura datelor. -- Ai adus singur cazul-limita care omoara solutiile naive: "partenerul anterior - este marcat inactiv... si exista situatii in care isi schimba calitatea de mai - multe ori" — perechea invizibila din cauza filtrului INACTIV=0. -- "80/20 minim de modificari cu maxim de efecte" — ai cerut explicit constrangerea - de cost inainte de solutii, nu dupa. - -## GSTACK REVIEW REPORT - -| Review | Trigger | Why | Runs | Status | Findings | -|--------|---------|-----|------|--------|----------| -| CEO Review | `/plan-ceo-review` | Scope & strategy | 1 | CLEAR | mode: HOLD_SCOPE, 3 constatari decise (swap guvernat, anexa spec, kill-switch), 0 critical gaps | -| Codex Review | `/codex review` | Independent 2nd opinion | 0 | — | sarit (2 verificari independente rulate azi la office-hours) | -| Eng Review | `/plan-eng-review` | Architecture & tests (required) | 1 | CLEAR | 2 issues (politica hook hibrid D1, recalc tip D2), 13/13 cai cu test, 0 critical gaps | -| Design Review | `/plan-design-review` | UI/UX gaps | 1 | CLEAR | score: 5/10 → 9/10, 3 decizii (focus, Enter=perechea, spec vizuala) | -| DX Review | `/plan-devex-review` | Developer experience gaps | 0 | — | n/a (nu e produs developer-facing) | - -- **UNRESOLVED:** 0 — toate deciziile CEO (D1-D6), eng (D1-D2) si design (D1-D3) au raspuns. -- **VERDICT:** CEO + ENG + DESIGN CLEARED — planul e complet, gata de implementare pe branch claude/partener-anaf. - ---- - -## REVIZIA 2 (25.07.2026) — V2': verdict ANAF in formularul de cautare - -Status: APPROVED (25.07.2026, feedback live Marius + D1a/D2 confirmate). -Aceasta revizie INLOCUIESTE sectiunile "fereastra de decizie" si "Specificatia -vizuala a ferestrei de decizie" din designul initial. Restul (hook, wrapper -single-CUI, NormalizeazaCUI, cache, kill-switch, excluderi, degradare tacuta, -fix import, politica de activare pe apelanti) RAMANE VALABIL. - -### Motivatia (test live 25.07, ROMFAST 1879855) - -Fereastra de decizie implementata in rundele 1-8 s-a dovedit confuza in uz real: -1. Utilizatorul nu intelege de ce a aparut fereastra; mesajul de sus e insuficient - (fara numele partenerului, fara ce inseamna verdictul, fara ce are de facut). -2. Gridul arata TOT grupul de CUI, inclusiv membrii cu aceeasi problema — nu ghideaza. -3. Butonul Inactiveaza/Activeaza cere o operatiune de nomenclator ambigua (pe care - rand? in pereche cu cine?) in mijlocul fluxului de introducere. -4. Verificarea ANAF e invizibila cand totul corespunde (WAIT WINDOW NOWAIT dispare - la orice miscare de mouse) — utilizatorul nu stie ca protectia exista. -5. Butonul "Nou" din fereastra dubleaza butonul Nou al cautarii. - -### Solutia revizuita - -**1. Label ANAF in `cauta_alfa_form` (COMUN\clase\cauta_alfa_forms.vc2)** — -verdictul pentru RANDUL CURENT din grid, vizibil INAINTE de alegere: - -``` -+--- Cautare partener --------------------------------------------+ -| Cautare: ROMFAST_ [Nou] | -| | Denumire | Cod fiscal | ... || -| |>ROMFAST CONSTANTA SRL | 1879855 | || -| ANAF: PLATITOR TVA — codul 1879855 (fara RO) NU corespunde. | <- label -+------------------------------------------------------------------+ -``` - -Starile labelului (texte finale, spec Marius 25.07): -- gol — persoana fizica / partener extern / CUI nenumeric / kill-switch 0; -- ~~eroare-timeout ANAF (degradare tacuta)~~ — REVIZUIT REVIZIA 5: la lipsa - raspunsului HTTP labelul nu mai ramane gol, arata gri "ANAF nu a raspuns - - verificare sarita" (vezi REVIZIA 5 pt. 1); -- "Verificare ANAF..." — pe durata apelului (persistent, nu WAIT WINDOW); -- concordant (VERDE): "ANAF: Platitor TVA (RO1879855 FAGA SRL)" — cod fiscal + - denumirea ANAF; -- discordant (ROSU, bold): "(!) ANAF: Platitor TVA (1879855 ROMFAST CONSTANTA - SRL) » detalii" — marcaj (!) si sageata » (chr 187, cp1252) care indica - apasarea pentru detalii; cursor mana pe label (clickabil). - -Declansare: `AfterRowColChange` reporneste un timer debounce (~400ms); apelul se -face doar daca utilizatorul ramane pe rand (cache per CUI pe sesiune → un singur -apel real per partener). Navigarea rapida nu declanseaza nimic. - -Blast radius: label + timer + proprietate de activare intra in clasa comuna, dar -INERTE implicit (proprietate .F.); se activeaza doar din cautarile de parteneri -cu verificare ANAF (tlVerificaANAF / CautPartenerContabilitate), cu guard-urile -existente pentru produsele-frate. Celelalte nomenclatoare nu vad nicio diferenta. - -**2. Dublu-click pe label** → AMESSAGEBOX cu detaliile complete: nume + cod ales, -verdict ANAF, codul fiscal corect, perechea existenta (cautata pe CUI normalizat, -INCLUSIV inactiva) sau indrumarea catre butonul Nou al cautarii daca nu exista. - -**3. La alegerea unui partener discordant (D1a)** — plasa de siguranta: apare -automat dialogul de decizie (formularul de cautare ramane deschis). Format -final (spec Marius, 25.07) — lista numerotata + butoane care spun exact ce aleg: - -``` -1. ROMFAST CONSTANTA SRL (CUI: 1879855, ID: 108) ANAF: PLATITOR TVA -2. FAGA SRL (CUI: RO1879855, ID: 200140) inactiv - - [Alege FAGA SRL] [Alege ROMFAST CONSTANTA SRL] [Renunta] -``` - -- Butonul perechii alege perechea; butonul alesului pastreaza alegerea; - Renunta (si ESC) = ramai in cautare. Fara linie de mapare Da/Nu. -- Fara pereche: randul 1 + "Nu exista partener cu CUI RO1879855 (il puteti - crea cu butonul Nou)." — butoane [Continua] [Renunta]. -- Mai multi candidati: lista numerotata a candidatilor + "Alegeti manual." — - buton unic, ramai in cautare. -- Implementare: AMESSAGEBOX nu suporta etichete custom pe butoane — dialogul e - o clasa mica `DEFINE CLASS ... AS Form` definita IN COD in ocautare.prg - (fara .scx, fara binar), 2-3 butoane cu Caption dinamic (denumiri trunchiate - rezonabil). Detaliile de la dublu-click pe label folosesc acelasi format - numerotat, pur informativ. - -**FARA activare/reactivare (decizie Marius, 25.07)**: alegerea unei perechi -inactive doar FOLOSESTE acel id_part pe document — partenerul ramane inactiv, -"inactiv" apare pur informativ. Motivatie: pe incasari/plati utilizatorul vrea -partenerul cu facturile/soldul, indiferent de TVA; nu toti utilizatorii au -drepturi de modificare nomenclator; orice operatiune de nomenclator in fluxul -de introducere incurca. Activarea/inactivarea raman exclusiv operatiuni -manuale in nomenclatorul de parteneri. - -**4. Alegere rapida (D2)**: daca utilizatorul alege inainte ca timerul sa fi -verificat randul, verificarea se face PE LOC la selectie (alegerile rapide nu -ocolesc protectia). - -### Ce se ELIMINA din implementarea rundelor 1-8 - -- `COMUN\ferestre\frm_verif_partener_anaf` (.sc2/.scx/.sct) — fereastra dispare. -- But_swap / ActualizeazaCaptionSwap / apelul `PACK_PARTENERI.MODIFICA_INACTIV`. -- Migrarea `ff_2026_07_24_01_COMUN_PACK_PARTENERI.sql` — NU se mai ruleaza pe - productie; `versiune_db.txt` revine la valoarea anterioara. (Procedura ramane - aplicata pe schema de test — inofensiva, se poate drop-ui separat.) -- Deschiderea ferestrei din hook (`Do Form ... frm_verif_partener_anaf`). - -### Ce se PASTREAZA neschimbat - -`NormalizeazaCUI`, wrapper single-CUI `ANAF_VerificaCuiSingle`, cache-ul pe -sesiune + golirea la schimbarea firmei, kill-switch `[anaf] verificare_selectie`, -excluderile (PF/extern/nenumeric), degradarea tacuta, fixul de import -(oproceduri_import.prg), politica de activare pe apelanti (tlVerificaANAF, -opt-out orap_terti), regula de lucru documentata, harta erorilor (mai putin -randul de swap — eliminat). - -### Teste afectate - -Suita `COMUN\utile\Teste\partener_anaf\` se rescrie pe noul flux: label (stari, -debounce, dublu-click), D1a (cele 3 butoane), D2 (alegere rapida), reactivare -single-row, regresie nomenclatoare non-partener (label inert). - ---- - -## REVIZIA 3 (25.07.2026) — verdict la data documentului + texte finale - -Status: APPROVED (25.07.2026, feedback live Marius pe screenshot-ul din productie). -Aceasta revizie ajusteaza doar textele si adauga data documentului; restul REVIZIEI 2 -ramane valabil. - -### 1. Textul labelului - -Denumirea si codul fiscal afisate sunt cele de la ANAF (nu cele ale randului ales), -in ordinea NUME apoi COD, plus data la care s-a cerut starea: - -- concordant (verde): `ANAF: Platitor TVA (ROMFAST SRL RO1879855) la 15.06.2026` -- discordant (rosu, bold): `(!) ANAF: Platitor TVA (ROMFAST SRL RO1879855) la 15.06.2026 >> click detalii` - -Sageata `»` (Chr(187)) se inlocuieste cu `>>` ASCII (fara risc de encoding cp1252), -iar textul devine `click detalii`. Marcajul `(!)` se pastreaza la discordanta. - -### 2. Dialogurile (detalii la dublu-click + confirmarea la alegere) - -Format aerisit, cu antet comun (metodele `AntetDialog` / `ListaCorecti` din -`anaf_verif_cautare`): - -``` -ROMFAST CONSTANTA SRL (CUI: 1879855, ID: 108) - -! ANAF: Platitor TVA (ROMFAST SRL, RO1879855) la 15.06.2026 - -Parteneri ROA cu CUI RO1879855: - 1. ABSOLUT SRL (ID: 598) inactiv - 2. ROMFAST S.R.L. (ID: 614) -``` - -- lista contine DOAR partenerii cu codul fiscal corect (fara cel deja ales), - ordonati alfabetic (`ORDER BY UPPER(DENUMIRE)` in `ANAF_CautaPereche`); -- fara candidati: `Nu exista partener cu CUI RO1879855 (il puteti crea cu butonul Nou).`; -- la alegere, ultimul rand ramane maparea butoanelor: - `Da = alege 1. Nu = pastreaza selectia Abandon = inapoi la cautare`. - -### 3. Starea ANAF la data documentului - -Serviciul `PlatitorTvaRest v9` primea deja o data (era `Date()`); acum primeste data -documentului, cand exista: - -- `ANAF_VerificaCuiSingle(tcCui, tdData)` si `ANAF_StarePartener(tcCodFiscal, tdData)`; - data goala/lipsa => data curenta (comportament identic cu inainte); -- cheia de cache pe sesiune devine `CUI + data` (acelasi CUI la doua date = doua apeluri); -- transport: cheia de hash `dDataDoc` pentru `CautPartenerContabilitate`, parametrul 7 - `tdDataDoc` pentru `caut_parteneri`; proprietatea `dDataDoc` pe `anaf_verif_cautare`; -- sursele datei in apelanti: `poAct.dataact` (introduceri note/facturi, - `ointroduceri_cont.vc2`: `do_cauta_partener` x2, gridurile de partener din - `frm_note`/`frm_note2007`, `frm_plati_impozite`) si `poDate.dataact` (facturare, - `ofacturare.vc2`: `do_cauta_client`, `do_cauta_furnizor`); toate cu guard `Type(...)='D'`. - -### 4. Casa/banca — verificare scoasa - -Punctul activat in runda 1 (`ocasabanca.vc2`, `Ck_bancasa.InteractiveChange`) NU e -introducere de document: e checkbox-ul de filtrare care alege casa/banca proprie -(`filtru = ' AND id_bancasa = ...'`), fara data de document. Verificarea ANAF se -dezactiveaza acolo (revenire la apelul fara `tlVerificaANAF`). - -### 5. Comentarii in cod - -Regula de lucru confirmata de Marius (25.07): fara comentarii in corpul codului; o -singura linie scurta in antetul fisierului, fara autor "claude". Comentariile inline -adaugate in rundele 1-11 pentru aceasta functionalitate se elimina. - -### 6. Import din extras de cont — corectie de abordare (decizie Marius, 25.07) - -La importul din extras e vorba de PLATI/INCASARI, nu de facturi: statutul ANAF -(platitor/neplatitor) nu ajuta cu nimic acolo. Singurul criteriu care conteaza e -"partenerul pe care stau facturile", pentru ca `GetDocumentByContPartenerAct` -(`COMUN\programe\oproceduri_comune.prg:6942`) cauta documentul strict pe `id_part` -(`ireg_parteneri`, an/luna curente), iar `GetPartenerByCodFiscal` (`:6557`) -normalizeaza CUI-ul si ia orbeste `MAX(id_part)` din grup. - -Prin urmare: -- verificarea ANAF se scoate din formularul de import extrase (cele doua pickere - manuale de partener din configurari); -- confirmarea pe loturi pentru discordantele de CUI (adaugata in runda 1) se - ELIMINA — importul nu mai intreaba nimic; -- cand exista mai multi parteneri cu acelasi CUI normalizat, alegerea se face - dupa documente, nu dupa `MAX(id_part)`: - 1. daca linia de extras are numar de document si optiunea "Asociaza facturi" e - bifata, documentul se cauta pe TOTI membrii grupului, iar nota merge pe - partenerul pe care s-a gasit factura (se muta si `id_partd`/`id_partc`); - 2. altfel, se alege membrul cu documente in perioada curenta (`ireg_parteneri`, - numar de randuri, la egalitate soldul cel mai mare in modul); - 3. daca niciun membru nu are documente, ramane alegerea de azi. -- la initializare facturi din balanta (`CompleteazaParteneriROA`) confirmarea per - partener se elimina: se foloseste tacut partenerul existent cu acelasi CUI - normalizat, iar cursorul de parteneri primeste coloana normalizata calculata o - singura data (fara `Locate` cu apel de functie per partener). - ---- - -## REVIZIA 4 (26.07.2026) — verificare neintruziva la alegerea partenerului - -Status: APROBATA CU MODIFICARI dupa review /autoplan (26.07.2026, 3 lentile: -CEO / design / inginerie, Codex indisponibil pe masina). Aceasta revizie -inlocuieste punctul 3 al REVIZIEI 2 ("La alegerea unui partener discordant") -si punctul 2 al REVIZIEI 3 (maparea butoanelor la alegere). - -Motivatia (Marius, 26.07): formularul de avertizare de la alegerea partenerului -e intruziv si confuz, mai ales pe incasari/plati, unde partenerul NU e o alegere -libera — e determinat de facturile de imperecheat, iar o propunere de schimbare -a partenerului exact in acel punct sparge imperecherea (`GetDocumentByContPartenerAct` -cauta documentul strict pe `id_part`). - -### Decizii de poarta (review /autoplan, 26.07) - -| # | Decizie | Continut | -|---|---|---| -| D1 / UC1 | **Marcajul colorat pe toate randurile NU intra in aceasta transa** | Implicit ramane nivelul 1 (verdict pe randul curent). Ghidarea o preia, in Detalii, semnul "are documente in perioada" pe fiecare candidat. Marcajul in grid devine transa separata, dupa masuratori (vezi "Transa viitoare") | -| UC2 | **Polaritate inversata** | `CautPartenerContabilitate` devine OFF implicit + opt-in explicit `lVerificaANAF=>1` pe 8 apeluri. Simetric cu `caut_parteneri` | -| UC3 | **Detalii ramane AMESSAGEBOX** | Fara formular nou definit in cod. Optiunea per utilizator se comuta dintr-un punct de meniu, dupa modelul `RC_REGCUMP_LISTARE_BUG` | - -### 1. Ce se scoate din calea de alegere - -`VerificaAlegere` (`ocautare.prg:428`) nu mai deschide nimic pe comportamentul -implicit: cand nivelul de confirmare e 0 face `Return .T.` imediat, fara apel -sincron la ANAF. - -La nivelul 3 (opt-in) comportamentul ramane exact cel de azi: verificare sincrona -+ `Amessagebox(...,3+48)` cu lista numerotata + `aInputBox` pentru varianta. -ATENTIE (eroare factuala corectata): clasa `anaf_dialog` **nu exista** — a fost -eliminata la runda 11, iar confirmarea de azi e AMESSAGEBOX. Nicio parte a acestei -revizii nu se sprijina pe ea. - -Chiar cand nu se afiseaza nimic, alegerea unui partener discordant **se logheaza** -in `goLog` (CUI, `id_part` ales, verdict) — e singura sursa de date despre -frecventa reala a problemei, si conditia de intrare pentru transa viitoare. - -### 2. Detalii (click pe label) — decizia, la cererea utilizatorului - -Ramane `AMESSAGEBOX`, cu formatul din REVIZIA 3, plus doua schimbari: - -1. **Discriminatorul pe documente** langa fiecare candidat — criteriul care conteaza - efectiv la imperechere, nu statutul TVA: - ``` - ROMFAST CONSTANTA SRL (CUI: 1879855, ID: 108) - - ! ANAF: Platitor TVA (ROMFAST SRL, RO1879855) la 15.06.2026 - - Parteneri ROA cu CUI RO1879855: - 1. ABSOLUT SRL (ID: 598) inactiv - 2. ROMFAST S.R.L. (ID: 614) are documente in perioada - ``` - Sursa: `ireg_parteneri` pe anul/luna curente, un singur SELECT, **doar la - deschiderea Detalii** (niciodata in calea de navigare prin grid). -2. **Alegerea variantei se face de aici** (butoanele AMESSAGEBOX + `aInputBox` - cand sunt mai multi candidati), adica exact mecanismul existent, mutat de pe - calea impusa pe calea ceruta de utilizator. Foloseste `poANAFInlocuire` + - `AplicaInlocuirePartenerANAF`, cu guardul obligatoriu de la punctul 5 (C2). - -Detalii se deschide si cand `oStare` e `.Null.` (ANAF picat, cod fiscal invalid): -afiseaza antetul si o linie explicita ("ANAF nu a raspuns — verificarea a fost -sarita"), nu returneaza mut ca azi (`ocautare.prg:411`). - -Labelul devine clickabil pe ambele stari (verde si rosu) si primeste **F4** ca -echivalent de tastatura (utilizatorii lucreaza fara mouse); textul labelului spune -`F4 = detalii`. Codul de tasta pentru F4 se confirma la implementare — ramura -`OTHERWISE` din `cauta_alfa_forms.vc2:715` nu intra in conflict cu redirectarea -literelor catre caseta de cautare. - -### 3. Cascada de optiuni — o singura scara - -O singura optiune, `RC_ANAF_VERIF_SELECTIE`, cu valori cumulative: - -| Valoare | Comportament | -|---|---| -| 0 | oprit (nicio verificare) | -| **1** | **verdict pe randul curent (implicit)** | -| 2 | rezervat pentru marcajul in grid (transa viitoare) | -| 3 | verdict + confirmare la alegerea unui partener discordant (opt-in) | - -Rezolvare, prima valoare gasita castiga: -1. `settings.ini [anaf] verificare_selectie` — **doar kill-switch pe valoarea 0**, - nu sursa de nivel (altfel bifa/optiunea utilizatorului devine silentios - inoperanta si nimeni nu poate explica de ce); -2. `citeste_optiune_utilizator('RC_ANAF_VERIF_SELECTIE')` — per utilizator; -3. `citeste_optiune('RC_ANAF_VERIF_SELECTIE')` — per firma; -4. hardcodat: 1. - -Comutarea per utilizator: punct de meniu, dupa modelul `RC_REGCUMP_LISTARE_BUG` -(citeste valoarea, arata starea, scrie noua valoare cu `scrie_optiune_utilizator`). -Etichete fara ambiguitate: `Arata starea ANAF in cautarea de partener` / -`Intreaba la alegerea unui partener discordant`. - -Seed-ul per firma se amana: cascada cade oricum pe implicitul hardcodat, iar un -INSERT in `optiuni` e citit de COMUN in toate produsele — nu e "discoverabilitate", -e comutator suite-wide. - -### 4. Politica de activare (inversata, UC2) - -`CautPartenerContabilitate` (`ocautare.prg:507`) devine **OFF implicit**, cu opt-in -explicit `lVerificaANAF=>1`. Motivul, verificat: exista ~68 de apelanti, dintre care -lista de opt-out acoperea ~20, toti din ROACONT; ar fi ramas ON prin omisiune -`COMUN\clase\baza.vc2:10400` (clasa de baza UI, deci toate produsele), -`orapoarte_cont.vc2:3843` (filtru de raport), `ofacturare.vc2:20946` ("Alegeti Banca"), -`:20957` ("casa in lei"), `:19441` (Agenti), `:7160/:7997/:9257` (Responsabili), -`:13793/:17826` (Partener rezervare), plus `oinventar`, `omodificari`, -`onomenclatoare`, `ferestre_cere_date`, `ooperatii_comune.prg`. `ROAGEST` si -`ROAAUTO` incarca `validare.prg` (`roagest.prg:234`, `roaauto.prg:198`), deci toate -guardurile existente trec si la ele. - -**Lista ON (singurele locuri cu `lVerificaANAF=>1`):** -- `Clase\ointroduceri_cont.vc2` — `do_cauta_partener` (x2, `:921`, `:3850`); -- `Clase\ointroduceri_cont.vc2` — gridurile de partener din `frm_note` (`:7096`, `:7120`) - si `frm_note2007` (`:8943`, `:8984`); -- `COMUN\clase\ofacturare.vc2` — `do_cauta_client`, `do_cauta_furnizor`. - -Parametrul `lNuVerificaANAF` dispare. Consecinta de curatat: dupa inversare, niciun -apelant nu mai trimite `tlVerificaANAF` la `caut_parteneri` — se decide explicit daca -parametrii `tlVerificaANAF`/`tdDataDoc` si ramura ANAF din `caut_parteneri` -(`ocautare.prg:625`) raman sau se scot ca ei cod mort. - -### 5. Reguli obligatorii de implementare (constatari verificate in cod) - -| # | Regula | Ancoraj | -|---|---|---| -| C2 | `AplicaInlocuirePartenerANAF` se apeleaza **doar cand `gnButon = 1`**; `poANAFInlocuire` se reseteaza la intrarea in Detalii si pe ramura de abandon. Altfel: utilizatorul alege varianta in Detalii, apoi anuleaza cautarea, iar `Scatter ... Blank` (`cauta_alfa.prg:243`) + guardul slab `Type('toPartener.id_part')='N'` fac ca apelantul sa primeasca totusi partenerul — pe incasari rupe imperecherea | `ocautare.prg:165`, `:609`, `:666` | -| C3 | `do_termin` pe formularul de cautare se apeleaza **dupa** ce AMESSAGEBOX-ul a returnat, niciodata din interiorul unui dialog modal copil (`do_termin` face `this.Release`) | `_frm_base.vc2:363-371` | -| H2 | Eroarea de SELECT din `ANAF_CautaPereche` nu mai are voie sa apara ca "Nu exista partener cu CUI ... (il puteti crea cu butonul Nou)" — asta indruma activ spre al treilea duplicat. `ListaCorecti` primeste un parametru de eroare; la eroare mesajul devine "Nu s-a putut citi lista de parteneri" si sugestia "Nou" dispare. Cursorul se inchide si pe ramura de eroare | `ocautare.prg:154-157`, `:389-405`, `:423`, `:455` | -| H6 | Cascada se citeste **o singura data**, la intrarea in `CautPartenerContabilitate`/`caut_parteneri`, cu `lcSel = Select()` / `Select(m.lcSel)` in jur. Niciodata din `Activeaza`, `VerificaRand` sau dintr-un handler de UI. `citeste_optiune_utilizator` **nu restaureaza** zona de lucru, iar `scrie_optiune_utilizator` da AMESSAGEBOX la eroare si face `TABLEUPDATE` in afara ramurii de succes | `oinit_optiuni.prg:731-740`, `:770-778` | -| H7 | Cascada testeaza `!Empty(Alltrim(valoare))` pe fiecare nivel. Patternul existent `Int(Val(Nvl(citeste_optiune_utilizator(...), '0')))` mapeaza absent -> 0 = OPRIT si ar opri verificarea la primul nivel gol | `Clase\ovanzcump.vc2` (pattern), `oinit_optiuni.prg:730`, `:808` | -| M9 | Citirea `getini` iese de pe calea per-rand: azi `ANAF_StarePartener` o face la fiecare verificare, cu `FOPEN`/scan/`FCLOSE` pe `DIRGEN\settings.ini`, care e de regula pe share de retea. Kill-switch-ul se citeste odata cu cascada | `ocautare.prg:59`, `ini.prg:288`, `roacont.prg:441` | -| M2 | Se foloseste `This.oForm.crs_cursor`, nu `_GRID1.RecordSource`: `SAVE_GRID` goleste `RecordSource` pe toata durata repopularii, care include un round-trip Oracle | `oproceduri_comune.prg:1387`, `ocautare.prg:303`, `:414`, `:443` | -| M5 | Valorile de cascada cache-uite pe sesiune se invalideaza la schimbarea firmei sau a utilizatorului (ca si cache-ul ANAF) | — | -| A2 | Guard suplimentar `'OINIT_OPTIUNI' $ Upper(Set('Procedure'))` inainte de orice apel la cascada: `ROACASA` incarca `ocautare` fara `oinit_optiuni` | `ocautare.prg:63` (modelul existent) | -| B1 | Bug in codul de azi: `VerificaRand` iese pe `Reccount = 0` fara sa goleasca labelul, deci verdictul precedent ramane pe ecran atribuit unei liste goale | `ocautare.prg:304-306` | -| B2 | Spec vs implementare: `SeteazaLabel` forteaza `FontBold = .F.`, desi REVIZIA 2/3 cere discordanta in rosu **bold**. Se aliniaza (bold la discordanta) | `ocautare.prg:353` | -| B3 | `Anchor` al labelului devine 14 (Left+Bottom+Right) — cu 6 textul se taie la redimensionare; labelul urca deasupra `cmd_select` (invizibil pe fluxul de partener), fara sa mai creasca inaltimea formei | `cauta_alfa_forms.vc2:47`, `:269-279`, `ocautare.prg:245-257` | -| B4 | Denumirea ANAF se trunchiaza la ~24 caractere in label (cea completa apare in Detalii): textul discordant la lungime maxima depaseste 2 randuri de Arial 10 in ~487x30px si se taie fara elipsa | `ocautare.prg:367` | -| B5 | `SET STEP ON` viu la `validare.prg:1841` (preexistent, nu din aceasta lucrare) — in IDE deschide debuggerul. De scos | `validare.prg:1841` | - -Wrapperul batch ANAF **nu se scrie** in aceasta transa: fara marcaj in grid nu are -consumator (YAGNI). - -### 6. Ce se pastreaza neschimbat - -Textele si culorile labelului (REVIZIA 3 pt. 1, cu corectia B2), starea la data -documentului (REVIZIA 3 pt. 3), `dDataDoc`/`tdDataDoc`, `NormalizeazaCUI`, -`ANAF_VerificaCuiSingle`, cache-ul pe sesiune + golirea la schimbarea firmei, -excluderile (PF/extern/nenumeric), degradarea tacuta, `ANAF_CautaPereche`, -`AplicaInlocuirePartenerANAF`, fixul de import (REVIZIA 3 pt. 6), regula "fara -comentarii in corpul codului" (REVIZIA 3 pt. 5), hook-ul generic din `cauta_alfa.prg` -si cele 8 linii din `cauta_alfa_forms.vc2`. - -### 7. Teste (toate fezabile in harnessul headless) - -1. Cascada: ini `0` bate tot; utilizator bate firma; firma bate hardcodatul; - **absent != 0** (H7); lipsa `crsOptiuni`/`crsOptiuniUtilizator`/`goExecutor`. -2. Nivel 1 (implicit): label prezent; `VerificaAlegere` nu deschide nimic si **nu - face niciun apel HTTP** la alegere (contorul de apeluri exista deja in suita). -3. Nivel 0: `poVerifAlegere` neinstantiat, zero apeluri, label absent. -4. Nivel 3: dialogul existent, cele 3 rezultate — testele actuale, rulate cu - optiunea pe 3. -5. **C2 (testul cel mai important, lipsa azi):** `poANAFInlocuire` setat + `gnButon = 2` - (Renunta) => obiectul returnat ramane blank, `id_part = 0`. -6. H2: `ANAF_CautaPereche` esuat (mock pe `goExecutor`) => mesaj de eroare, fara - sugestia "Nou". -7. Detalii cu `oStare` `.Null.` => se deschide, cu linia explicativa. -8. Discriminatorul "are documente in perioada" (mock pe `goExecutor`, cu si fara randuri). -9. Bug-ul B1: cautare fara rezultate => labelul se goleste. -10. Zona de lucru: `Alias()` identic inainte si dupa citirea/scrierea optiunilor (H6). -11. Punctul de meniu scrie valoarea corecta si are efect imediat (`M6`: la trecerea - pe 0 se opreste si timerul si se goleste labelul pe cautarea deschisa). -12. Regresie: apelantii care NU au `lVerificaANAF=>1` nu instantiaza `poVerifAlegere`. - -### 8. Transa viitoare — marcaj in grid (nivelul 2), cu conditii de intrare - -Nu se implementeaza pana nu exista, in aceasta ordine: -1. **Masuratori** (Tema din planul initial, inca nefacuta): latenta reala a unui apel - ANAF la ore diferite; comportamentul la rafale (30 loturi de 20 CUI la interval - scurt — de la al catelea vine 429); numarul real de perechi de CUI duplicat la un - client real. -2. **Date din loguri**: cate discordante apar efectiv la pilot si in ce flux. - -Cerinte tehnice de respectat atunci (toate verificate acum, ca sa nu se piarda): - -| # | Cerinta | -|---|---| -| UC1 | Criteriul de colorare corect pe trezorerie e "are documente in perioada" (SELECT local), nu statutul ANAF: pe o incasare, verdele dupa ANAF indruma spre partenerul fara facturi | -| D-F2 | `DynamicForeColor` e **invizibil pe randul selectat** (`_baza.vc2:200-201`: highlight bleumarin cu text alb). Semnalul are nevoie de al doilea canal: `DynamicFontBold`, care supravietuieste highlight-ului. Verde+bold pentru randul confirmat, restul normal; rosul dispare de pe randuri (are 3 sensuri distincte: prefix gresit, radiat la ANAF, CIF invalid) | -| C4 | Un singur `anaf_timer` cu doua consumatoare = nedeterminism: `do_cauta` face `Go Top` + `SetFocus` dupa `actualizeaza_grid1`, deci `AfterRowColChange` rearmeaza acelasi timer. Necesar: doua flag-uri (sau doua timere) + flag de suprimare `lInBatch`, `GO` pe `Recno()` salvat, colectarea CUI-urilor fara `SELECT-SQL` pe cursorul legat de grid | -| H1 | CUI-urile din `notfound` sunt inserate ca randuri blank (`scpTVA = .F.`, denumire goala) — fara filtru `!Empty(denumire)` orice partener cu prefix RO negasit la ANAF ar aparea marcat gresit | `validare.prg:1984-1996` | -| H4 | `Collection.GetKey` e supraincarcat: cu argument numeric intoarce cheia de la index, nu indexul. Cheile se construiesc string: `'P' + Transform(id_part)`, si `Item()` doar dupa `GetKey(...) <> 0` | -| H5 | Expresia `Dynamic*` se evalueaza in context de pictare: referinta necalificata (`ANAF_CuloareRand(id_part)`), corp intreg in `TRY/CATCH` cu `Return Rgb(0,0,0)`, `Nvl(id_part,0)` (randul `` de pe ramura `lAllInList` are `id_part` blank), zero apeluri care schimba zona de lucru. O eroare aici se repeta la fiecare repaint | -| H8 | Curatarea binding-ului pe metoda: `Unbindevents(form, 'actualizeaza_grid1', This, 'DupaGrid')` cu 4 argumente — varianta cu 1 argument sterge si `BINDEVENT(Thisform,"lAles",...)` din `Init` si rupe selectia multipla | -| H9 | Codul ROA impune >= 1s intre interogarile ANAF (`validare.prg:1777`, `INKEY(1)`); un debounce de 400ms il incalca. Necesare: interval minim global pe sesiune + circuit-breaker la 3 esecuri + log per cod HTTP distinct (azi `gvANAF_EroareLogataSesiune` amuteste toata sesiunea dupa prima eroare, iar 429/5xx sunt indistinguibile de "fara informatie"). Nota REVIZIA 5: intrerupatorul livrat acolo e pe timp (10 minute dupa un singur esec FARA_RASPUNS), mecanism diferit — contorul de 3 esecuri si logul per cod HTTP raman cerinta deschisa, neacoperita, pentru nivelul 2 | -| M1 | Delegatul `DupaGrid` trebuie sa aiba semnatura metodei delegate (`Lparameters pcFiltru`), altfel eroare 1229 | -| M7 | Codul fiscal invalid nu are stare in schema de culori — se decide explicit sau se documenteaza omisiunea | -| Test | Partile netestabile in harnessul actual: ordinea actiunilor sub timer, reentranta pe cursorul gridului, culorile efectiv randate. Daca intra, intra cu risc de regresie permanent | -| Invariant | Intreg mecanismul depinde de `PRIVATE poVerifAlegere`/`poANAFInlocuire` vizibile prin domeniu dinamic, ceea ce functioneaza doar pentru ca formularul de cautare e `WindowType = 1` (modal). Orice trecere la modeless rupe atribuirea **fara eroare** | - ---- - -## REVIZIA 5 (27.07.2026) — reparatie 404 + intrerupator de disponibilitate ANAF - -Status: APROBATA (27.07.2026, plan `docs\plan-reparatie-anaf-404-breaker.md`, T1-T8). -Aceasta revizie nu schimba fereastra sau textele labelului (raman cele din REVIZIA 3, -cu corectia B2 din REVIZIA 4); corecteaza contractul dintre wrapper-ul ANAF -(`COMUN\programe\validare.prg`) si consumatorul lui (`COMUN\programe\ocautare.prg`) -si adauga o a treia stare de banda pentru cand serviciul ANAF nu raspunde. - -### Motivatia - -Doua simptome constatate pe ecran: (1) `RO123456789` — cod valid ca cifra de -control dar inexistent la ANAF, banda arata promptul gri generic in loc de -"inexistent la ANAF"; (2) `FANALEX OIL MARKET S.R.L.` scris in campul cod fiscal — -banda tace complet. Plus un al treilea defect gasit la analiza: serviciul cazut sau -supraincarcat poate bloca interfata pana la cateva zeci de secunde per rand, pentru -ca garda existenta din jurul `SetTimeouts` nu se aplica pe obiectul COM folosit. - -### 1. Regula "esec tacit" revizuita pentru banda - -Regula veche (REVIZIA 2, "Starile labelului"): orice eroare/timeout ANAF lasa -labelul gol, identic cu starea "nimic de verificat". Regula noua: "esec tacit" -ramane valabila pentru dialogurile modale (fara AMESSAGEBOX la esec, ca azi), dar -banda de stare VORBESTE: - -- lipsa de raspuns HTTP (`FARA_RASPUNS`), raspuns HTTP primit dar neinteles - (`RASPUNS_NEINTELES`, punctul 5) sau apel sarit fiindca serviciul e deja in - starea CAZUT/SE TESTEAZA (punctul 3) → acelasi text de banda gri, in toate - trei situatiile: **"ANAF nu a raspuns - verificare sarita"**, distincta de - promptul gri generic (persoana fizica / partener extern / CUI nenumeric / - kill-switch 0); -- ce difera intre `FARA_RASPUNS` si `RASPUNS_NEINTELES` e DOAR intrerupatorul: - `FARA_RASPUNS` il deschide (stare CAZUT); `RASPUNS_NEINTELES` schimba banda la - fel, dar nu deschide intrerupatorul si nu intra in cache; -- 404 cu `notFound` continand chiar CUI-ul cerut → verdict rosu "Cod fiscal - inexistent la ANAF" (punctul 4), nu mai e tratat ca "fara informatie". - -### 2. Testul 5 actualizat - -Testul 5 din "Lista de teste" (mai sus) trece de la "zero mesaje" la banda care -vorbeste explicit la lipsa raspunsului; vezi textul revizuit la pozitia lui in -lista. Regresiile de pastrat verzi: celelalte 10 teste ale listei plus cele 30 de -scenarii existente in suita headless (`test_verif_partener_anaf_v2_ui.ps1`). - -### 3. Starea serviciului ANAF pe sesiune - -Patru stari, tinute pe sesiune (nu per CUI), cu intrerupator de 10 minute: - -``` - +-------------+ - pornire sesiune ---->| NECUNOSCUT | - +------+------+ - deschidere formular | (sonda pleaca asincron) - v - +-------------+ sonda / verificare reala OK - | SE TESTEAZA+-------------------------------> +-----+ - +------+------+ | VIU | - | sonda esuata +--+--+ - v | - +-------------+ <--------------------------------+ - | CAZUT (10') | apel real esuat (FARA_RASPUNS) - +------+------+ - | au trecut 10 minute + se deschide un formular - +--> SE TESTEAZA (sonda noua, tot asincron) -``` - -- **NECUNOSCUT / CAZUT expirat** → la deschiderea formularului de cautare pleaca o - sonda asincrona (acelasi constructor de cerere ca verificarea normala), fara sa - blocheze interfata. -- **SE TESTEAZA** → randul care cere verdict NU face apel propriu; asteapta - raspunsul sondei (banda: "ANAF: se verifica ..."), interogat neblocant de - timerul de debounce existent (400ms). Sonda are propriul termen de viata; daca - expira fara raspuns, starea trece direct pe CAZUT. -- **VIU** → verificari sincrone normale, fara sonda. -- **CAZUT** → zero apeluri catre ANAF pentru randul curent, banda gri "ANAF nu a - raspuns - verificare sarita". -- La tranzitia CAZUT/NECUNOSCUT → VIU, `nIdPart` se invalideaza, ca sa se - re-evalueze randul curent (altfel ramane pe verdictul dinaintea revenirii). -- La nivelul 3 (confirmare la alegere, opt-in): in starile CAZUT si SE TESTEAZA - verificarea sincrona de la alegere se sare, iar alegerea trece fara blocare. - -### 4. Contractul 404 - -Corpul raspunsului ANAF se citeste si pe status 404, nu doar pe 200. Verdictul -"Cod fiscal inexistent la ANAF" se da **doar** cand `notFound` din raspuns contine -chiar CUI-ul cerut — niciun alt corp neinteles nu mai produce acest verdict; ramura -veche care trata orice corp diferit de "gasit" ca "inexistent" se elimina. - -### 5. Clasa de esec a wrapper-ului - -`ANAF_VerificaCuiSingle` primeste un parametru suplimentar, prin referinta, cu -clasa esecului. `ANAF_StarePartener` o preia si o expune mai departe apelantului, -tot prin referinta: - -| Valoare | Cand | Banda | Intrerupator | -|---|---|---|---| -| `''` | apel reusit (obiect intors) sau verdict "inexistent" valid | verdict normal (verde/rosu) | nimic | -| `FARA_RASPUNS` | niciun raspuns HTTP: exceptie la deschiderea/trimiterea cererii, timeout, DNS, conexiune refuzata | gri "ANAF nu a raspuns - verificare sarita" | **singura** valoare care il deschide (stare CAZUT) | -| `RASPUNS_NEINTELES` | raspuns HTTP primit dar corpul nu se poate interpreta: status neasteptat, corp gol, JSON neparsabil, `notFound` fara CUI-ul cerut, 429, 500 | acelasi gri "ANAF nu a raspuns - verificare sarita" | nu il deschide, nu intra in cache | - -Apelul fara acest parametru ramane valabil (parametru optional) — apelantii -existenti nu se schimba. - -### 6. Cache doar pe verdicte pozitive - -Verdictul `'NEGASIT'` si esecurile nu se mai tin in cache toata sesiunea. Cache-ul -pe sesiune (cheie CUI+data, vezi REVIZIA 3 pt. 3) ramane doar pentru verdicte -pozitive (platitor/neplatitor gasit la ANAF). Rolul de "nu bate ANAF de doua ori -pentru acelasi caz esuat" il preia intrerupatorul de la punctul 3, nu cache-ul — -altfel un verdict negativ dintr-un serviciu picat sau degenerat ar ramane lipit pe -CUI pana la schimbarea firmei. - -### 7. Cod normalizat cu litere in campul cod fiscal - -Cand codul din campul cod fiscal contine litere dupa normalizare (cazul -`FANALEX OIL MARKET S.R.L.` scris acolo din greseala) → banda gri "nu se poate -verifica la ANAF", nu tacere ca azi. `VALIDARE_CIF` nu se modifica in aceasta -transa (ramane folosita neschimbata in restul suitei — D406, import, facturare); -tara partenerului nu intra in aceasta transa — punctul D (`cod_tara` in cursorul -de cautare) ramane amanat, ca in "Ce NU facem" mai sus. - -### 8. Guard de reintrare implementat - -Guard-ul de reintrare (flag "verificare in curs") cerut deja in harta erorilor de -mai sus e implementat in aceasta transa ca `lVerificareInCurs`, nu doar specificat: -fara el, timerele VFP care trag si in timpul unui `AMESSAGEBOX`/`WaitForResponse` -pot intrerupe secventa "verifica cheia → apel → adauga in cache" si arunca eroare -la a doua inserare pe aceeasi cheie. - -### 9. Ce se pastreaza neschimbat - -Textele si culorile labelului (REVIZIA 3 pt. 1, cu corectia B2), starea la data -documentului (REVIZIA 3 pt. 3), `NormalizeazaCUI`, cache-ul pe sesiune + golirea la -schimbarea firmei (cu restrangerea de la pct. 6), excluderile (PF/extern/ -nenumeric — extinse acum cu banda gri de la pct. 7 in loc de tacere), -degradarea tacuta pentru `RASPUNS_NEINTELES` (niciun AMESSAGEBOX, nicio acuzatie, -nicio scriere in cache, intrerupatorul neatins — dar banda vorbeste, ca la pct. 1), -`ANAF_CautaPereche`, -`AplicaInlocuirePartenerANAF`, fixul de import, cascada de optiuni -`RC_ANAF_VERIF_SELECTIE` (REVIZIA 4 pt. 3), politica de activare pe apelanti -(REVIZIA 4 pt. 4). diff --git a/versiune_db.txt b/versiune_db.txt index b97754b..387c852 100644 --- a/versiune_db.txt +++ b/versiune_db.txt @@ -1 +1 @@ -2026_07_26_02 \ No newline at end of file +2026_07_28_01 \ No newline at end of file