diff --git a/.gitignore b/.gitignore index 83d2178..5fd1f6a 100644 --- a/.gitignore +++ b/.gitignore @@ -104,6 +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 f0d1e1f..3f048cc 100644 --- a/changelog_roacont.txt +++ b/changelog_roacont.txt @@ -1,25 +1,27 @@ - - - -# 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/docs/handoff_transa1.md b/docs/handoff_transa1.md deleted file mode 100644 index 327e4b6..0000000 --- a/docs/handoff_transa1.md +++ /dev/null @@ -1,87 +0,0 @@ -# Handoff Transa 1 (L1 + L2) — ocautare.prg + validare.prg - -Data: 27.07.2026. Patch: `docs/diff_runda1_transa1.patch`. Backup-uri: `*.pre_runda1.bak` -in `COMUN/programe/`. Fara comit (git/svn), fara `git add`. - -## L1 — perioada TVA - -- `validare.prg` header (dupa ultima intrare 27.07.2026): intrare noua cumulativa. -- `validare.prg:1663 ANAF_VerdictDinCursor`: 4 proprietati noi pe `loResult` - (`dInceputScpTVA`, `dSfarsitScpTVA`, `dAnulareScpTVA`, `cMesajScpTVA`), citite din - cursor INAINTE de `Use In` — linii neschimbate fata de plan (1657→1663 dupa insertia - headerului, offset normal). -- `validare.prg` `ParseJsonANAFv8` (~2074-2086): log explicit (nu in CATCH) pentru fiecare - din cele 3 campuri de data, cand sirul sursa e nevid dar `CTOD` a intors gol. -- `ocautare.prg` header: intrare noua cumulativa (L1; L2 nu are comentariu, e corectie). -- `ocautare.prg:145-153 ANAF_StarePartener`: propaga cele 4 proprietati in `loOut`, citire - garda cu `Pemstatus(loRezANAF, '', 5)`; daca lipsesc (validare.prg vechi la alte - produse ROA), `loOut` primeste oricum proprietatea cu valoare goala — asa TextAnaf/Detalii - n-au nevoie de Pemstatus la randul lor. -- `TextStare` (nou parametru `tcPerioada`) + `SufixPerioadaTVA` (functie noua) + `TextAnaf` - (foloseste cele doua) — implementeaza tabelul de conditii si formele exacte din plan - (precedenta pe `dAnulareScpTVA`, apoi range daca ambele date, apoi `din data`; sufixul - `' la data documentului'` dispare cand perioada apare). -- `TextPerioadaTVA` (functie noua) + `Detalii`: bloc cu perioada completa (etichete distincte) - + mesajul ANAF integral, inserat dupa `AntetDialog(...)` in AMBELE ramuri unde `oStare` - nu e null (cazul concordant si cel discordant/lista de candidati) — deci apare si in cazul - concordant, cum cere planul. - -## L2 — CNP la 13 cifre - -- `EvalueazaRand:600(vechi)`: `This.cClasaEsec = ''` → `'COD_INVALID'` (fara comentariu). -- `ANAF_StarePartener`: parametru nou `tnTipPersoana` (adaugat la finalul listei, ca sa nu - mut pozitiile parametrilor `@`); conditia de la `:82` devine - `Len(m.lcCui) = 13 And !(Vartype(m.tnTipPersoana) = 'N' And m.tnTipPersoana = 1)`, seteaza - `tcClasaEsec = 'CNP'` inainte de `Return .Null.`. Singurul apel din tot codul e in - `EvalueazaRand` (verificat cu grep in D:\ROA\ROACONT) — actualizat sa paseze - `m.lnTipPersoana` (deja calculat la linia anterioara, nimic nou de calculat). - **Corectie runda 2** (semnalata de team-lead la review): forma initiala - `m.tnTipPersoana <> 1` compara direct cu 1, ceea ce arunca eroare VFP 107 - ("Operator/operand type mismatch") daca `ANAF_StarePartener` e chemata cu vechea - semnatura de 6 parametri (`tnTipPersoana` nepasat = `.F.` logic, `.F. <> 1` = mismatch - tip) — risc real, pentru ca fisierul e cod partajat COMUN si alte produse ROA il pot - chema fara noul parametru. Forma cu `Vartype(...) = 'N' And ... = 1` e sigura indiferent - daca parametrul e pasat sau nu si pastreaza compatibilitatea inapoi (apelant vechi -> se - comporta ca azi, sare ANAF pe 13 cifre). -- `EvalueazaRand`: ramura noua `Case Isnull(m.loStare) And m.lcClasaEsec == 'CNP'` inaintea - lui `Case Isnull(m.loStare)`, banda neutra `'Persoana fizica - CNP corect'`. -- `Detalii`, Iif imbricat: doua ramuri noi, `CNP` si `COD_INVALID`, exact textul din plan. -- Ramurile marcate INACCESIBILE in plan (CNP invalid sub clasa noua, CUI valid/invalid sub - FARA_RASPUNS) NU au fost implementate, cum cere planul. - -## Verificari facute - -- cp1252: toate editarile au fost facute INTAI, verificare byte-level DUPA. `ocautare.prg` - a avut 3 linii corupte (`0xBA` → `EF BF BD`) dupa editari (caracterul `ș` din - "mașina"/"și"/"tranșa", niciuna dintre ele atinsa intentionat) — reparate cu - `s/\xEF\xBF\xBD/\xBA/g` (sigur, pentru ca toate cele 3 corupte erau confirmat `0xBA` in - backup si in `svn cat`, verificat byte-cu-byte cu `xxd`+`md5sum`, nu doar vizual — atentie, - terminalul afiseaza `0xBA` si `EF BF BD` identic vizual, verificarea trebuie facuta pe - octeti, nu pe ce se vede). Dupa reparare: 0 aparitii `EF BF BD` in ambele fisiere, numar de - linii cu octeti >=0x80 identic intre fisierul curent si `svn cat` (3 in ocautare.prg, 0 in - validare.prg), continut confirmat identic prin md5sum pe liniile respective. -- Comentarii: doar in antet, cate o intrare cumulativa per fisier (L1); L2 fara comentariu. -- Patch (`docs/diff_runda1_transa1.patch`) recitit — contine doar modificarile de mai sus, - fara cele 3 linii cu diacritice (au disparut din diff dupa reparare, semn ca sunt - byte-identice cu baseline-ul). - -## Ce n-am putut verifica - -- Nu am rulat headless VFP (`vfp9.exe -A -T`) pe aceste functii — modificarile ating clase - UI (`anaf_verif_cautare`, mesaje `Amessagebox`) greu de testat fara IDE/formular; recomand - testare manuala in VFP conform planului de test insotitor. -- N-am gasit alti apelanti ai `ANAF_StarePartener` in afara de `ocautare.prg` insusi (grep pe - tot `D:\ROA\ROACONT`), deci parametrul nou `tnTipPersoana` nu are alti calleri de actualizat - — dar n-am verificat si in `D:\ROA\COMUNROA` sau alte produse ROA in afara acestui working - copy. - -## Capcane intalnite - -- Editarea cu Edit tool a corupt caractere cp1252 in TOT fisierul `ocautare.prg` la fiecare - scriere, exact cum avertizeaza `conventie_encoding_cp1252.md` — dar comparatia vizuala in - terminal ("liniile arata la fel") a fost INSELATOARE: `0xBA` si `EF BF BD` (3 octeti) se - afiseaza identic ca `�` in terminal. Un prim test cu `perl -ne 'print "$." if /[\x80-\xFF]/'` - a raportat "acelasi numar de linii, acelasi continut vizual" si a fost gresit interpretat ca - "nicio corupere" — abia comparatia cu `xxd`+`md5sum` a scos la iveala diferenta reala. - Concluzie pentru viitor: verificarea corecta e strict pe secventa de octeti `EF BF BD` - (`perl -ne 'print "$." if /\xEF\xBF\xBD/'`), nu pe prezenta oricarui octet >=0x80. diff --git a/docs/handoff_transa2.md b/docs/handoff_transa2.md deleted file mode 100644 index cad89ed..0000000 --- a/docs/handoff_transa2.md +++ /dev/null @@ -1,51 +0,0 @@ -# Handoff TRANSA 2 (L4) — borderou eFactura, taxare inversa - -Data: 28.07.2026. Status: implementat si validat pe schema dev, NEAPLICAT pe view-urile reale. - -## Ce am scris - -1. `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\07\ff_2026_07_28_01_COMUN_EFACTURA.sql` (nou, CRLF): - `create or replace view` pentru `anaf_vefactura_primit` (coloana `jtva_ti` = suma celor 13 - termeni `TI*`/`XX*TIT` de pe `jc2007`, printr-un singur `CROSS APPLY` care intoarce si - `jtotctva` si `jtva_ti` odata — un singur scan, nu doi subselecti) si `anaf_vefactura_trimis` - (`jtva_ti` = `0` constant, `jtotctva` neschimbat). La final: `alter view ... compile` pe cele - doua DETALIU + verificare `user_objects.status='INVALID'` care arunca eroare daca ramane ceva - invalid. `versiune_db.txt`: `2026_07_26_02` -> `2026_07_28_01`. -2. `COMUN\programe\import_efactura.prg`: sonda `user_tab_columns` pe `lcTabel` (`goExecutor.oExecuta`, - tipar deja folosit in fisier la `cGestiuni`/`cUMISO`/`cUM`) inainte de a construi `lcSelect`; - `lcExprDiferenta` ia una din doua forme (cu/fara `jtva_ti`), injectata prin `<>` - in `TEXTMERGE`. `lcSchema` neatins (numar de coloane identic). Antet actualizat cu intrare noua - `*!* 28.07.2026 / marius.mutu`. - -## Ce am validat pe baza (`MARIUSM_AUTO@ROA_CENTRAL`, doar SELECT + view-uri temporare) - -Am creat `zz_test_jtva_primit`/`zz_test_jtva_trimis` cu EXACT corpul din script, verificat, apoi -`DROP VIEW` pe amandoua (confirmat: `no rows selected` la interogarea finala pe `user_objects`). - -- Ambele compileaza (`STATUS = VALID`). -- `zz_test_jtva_primit`: 487 randuri (coincide cu ce raporta handoff-ul conditiilor); 459 pe trimis. -- Cele 8 randuri cu `id_fact` completat: `jtotctva` neschimbat fata de azi, `jtva_ti = 0` pe toate - (niciuna nu e taxare inversa — coincide cu constatarea din `handoff_transa2_conditii.md`). -- Pe trimis: `jtva_ti` e `0` pe toate randurile, niciodata NULL. -- Testul aritmetic direct pe cazul sintetic din handoff (`jc2007.id_fact=8007136`, - `an=2022 luna=4 dataact=30-APR-22 nract=222 id_part=614`): `totctva=119`, `jtva_ti_expr=19` — - exact valorile asteptate (confirma ca `diferenta` ar deveni `100-(119-19)=0`). -- Sonda `user_tab_columns` gaseste `JTVA_TI` pe ambele view-uri de test — confirma ca tehnica - folosita in `import_efactura.prg` functioneaza identic pe view ca pe tabela. - -NU am rulat `create or replace view` pe view-urile reale si nu am atins `jc2007`/`jv2007`. - -## Ce ramane de facut de om - -- Aplicarea scriptului pe schema clientului, INAINTE de deploy-ul exe-ului (ordinea ceruta de plan). -- Verificarea finala pe o factura REALA de taxare inversa importata din eFactura — schema dev nu are - niciuna (confirmat deja in `handoff_transa2_conditii.md`); mecanismul e demonstrat doar numeric. -- Review + aprobare `docs\diff_runda1_transa2.patch` inainte de orice commit (SVN sau git). -- Curatenie dupa aprobare: `import_efactura.prg.pre_runda1.bak` si patch-ul se sterg (nu se comit). - -## Fisiere - -- Backup: `D:\ROA\ROACONT\COMUN\programe\import_efactura.prg.pre_runda1.bak` -- Patch: `D:\ROA\ROACONT\docs\diff_runda1_transa2.patch` -- Script nou: `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\07\ff_2026_07_28_01_COMUN_EFACTURA.sql` -- `D:\ROA\ROACONT\versiune_db.txt`: `2026_07_28_01` diff --git a/docs/handoff_transa2_conditii.md b/docs/handoff_transa2_conditii.md deleted file mode 100644 index 95e6501..0000000 --- a/docs/handoff_transa2_conditii.md +++ /dev/null @@ -1,189 +0,0 @@ -# TRANSA 2 (L4) — inchidere conditii de intrare — verificare Oracle - -Data: 27.07.2026. Conexiune: `MARIUSM_AUTO@ROA_CENTRAL` (schema dev), read-only, doar SELECT. -Fisiere sursa salvate: `docs/local/view_anaf_vefactura_primit.sql`, `docs/local/view_anaf_vefactura_trimis.sql`. - -## VERDICT GENERAL - -- **A — INCHISA.** Definitiile curente extrase din `USER_VIEWS.TEXT`. -- **B — INCHISA PARTIAL.** Mecanismul e confirmat pe date, dar NU dintr-o factura venita real din import eFactura (nu exista in schema dev). Demonstrat pe cel mai apropiat caz din `jc2007`. -- **C — INCHISA, cu recomandare concreta.** Forma subselectului unic e mai jos. -- **D — INCHISA.** Sonda recomandata: `user_tab_columns`. - -**CONTRAZICE PLANUL (cel mai important gasit):** lista canonica de 10 coloane din plan -(`TI21T, TI11T, TI19T, TI09T, TI24T, TI20T, XX21TIT, XX11TIT, XX19TIT, XX9TIT`) **nu compileaza -direct pe `JC2007`**. `TI19T` si `TI09T` NU exista ca si coloane pe tabela — vezi B mai jos. - ---- - -## A. Definitiile curente ale view-urilor - -Extrase din `USER_VIEWS.TEXT` (nu din arhiva CLAR), salvate integral in: -- `docs/local/view_anaf_vefactura_primit.sql` -- `docs/local/view_anaf_vefactura_trimis.sql` - -Confirmari: -- `anaf_vefactura_primit.jtotctva` = subselect corelat pe `jc2007 j` + `left join nom_parteneri p`, - cheie de potrivire an/luna/dataact + `REGEXP_SUBSTR(a.xnumar_act, '\d+[^[:digit:]]*$') LIKE '%'||TO_CHAR(j.nract)||'%'` - + `REGEXP_REPLACE(p.cod_fiscal,'[^[:digit:]]','') = a.cod_fiscal_emitent`. Exact cum descrie planul. -- `anaf_vefactura_trimis.jtotctva` = acelasi tipar dar pe **`jv2007`** (nu `jc2007`), cheie pe - `cod_fiscal_beneficiar`, filtru `a.factura_emisa = 1`. Confirma ca planul are dreptate sa puna - `jtva_ti = 0` constant la trimis: la vanzari nu exista familia `TI*`/`XX*TIT` (verificat — acele - coloane sunt specifice achizitiilor, nu apar in `jv2007`, nu a fost nevoie sa fie recalculate). - -**Views DETALIU** — exista amandoua, construite peste view-urile de baza prin `id_efactura`/`id`: -- `ANAF_VEFACTURA_PRIMIT_DETALIU` (VALID) — `SELECT f.* (coloane specifice), d.* FROM anaf_vefactura_primit f JOIN anaf_efactura_detalii d ON f.id = d.id_efactura`. -- `ANAF_VEFACTURA_TRIMIS_DETALIU` (VALID) — identic, pe `anaf_vefactura_trimis`. -- Bonus gasit: exista si `ANAF_VEFACTURA_EMIS_DETALIU`, dar e **INVALID** azi (preexistent, nelegat - de L4 — de semnalat, nu de reparat aici). - -Important pentru scriptul de migrare: niciuna din cele doua DETALIU nu selecteaza `jtotctva` sau -orice coloana noua din view-ul de baza (`f.*` explicit enumerat, fara `jtotctva`/`jtva_ti`) — deci -adaugarea `jtva_ti` in view-urile de baza **nu le afecteaza structural**, doar le invalideaza -temporar (dependinta VFP) pana la recompilare automata pe urmatoarea referire. Se pastreaza -verificarea de obiecte invalide ceruta de plan la finalul scriptului. - ---- - -## B. Trasare cap-coada — CONTRAZICE PLANUL pe lista de coloane - -### Ce s-a confirmat - -- `ProcentTva2IdJtva` (gasita real in `COMUN\programe\oproceduri_comune.prg:5836`, NU in - `anaf_efactura.vc2` cum spune planul — functia e apelata acolo la `:12093`/`:12636`, dar - **definita** in `oproceduri_comune.prg`) confirma exact id-urile din plan pentru taxare inversa - pe JC: 21%->216, 11%->218, 19%->141, 9%->145 (`:5864-5871`). -- `oproceduri_decont.prg:8670` (citat corect de plan) e o expresie SQL, dar **din view-ul - `VJC2025`**, nu direct pe `jc2007`. Am extras `USER_VIEWS.TEXT` pentru `VJC2025`: acolo - `ti19t` si `ti09t` sunt ALIASURI calculate — `SUM(a.ti19bct + a.ti19bvt + a.ti19bft) as ti19t`, - `SUM(a.ti09bvt + a.ti09bft) as ti09t` — NU coloane fizice. - -### Verificare directa pe `JC2007` (`USER_TAB_COLUMNS`) - -Din cele 10 coloane canonice din plan, gasite pe tabela **8/10**: - -| Coloana plan | Exista pe JC2007? | -|---|---| -| TI21T, TI11T, TI24T, TI20T | DA (coloane simple) | -| XX21TIT, XX11TIT, XX19TIT, XX9TIT | DA (coloane simple) | -| **TI19T** | **NU** — pe tabela exista in schimb `TI19BCT`, `TI19BVT`, `TI19BFT` (3 subcoloane) | -| **TI09T** | **NU** — pe tabela exista in schimb `TI09BVT`, `TI09BFT` (2 subcoloane, fara varianta `BC`) | - -Un `create or replace view` care scrie `nvl(j.TI19T,0)+nvl(j.TI09T,0)` direct pe `jc2007 j` **nu -compileaza** — `ORA-00904`. Lista corecta de termeni pentru `jc2007` (13 termeni, nu 10): - -``` -NVL(j.TI21T,0)+NVL(j.TI11T,0)+NVL(j.TI24T,0)+NVL(j.TI20T,0) -+ NVL(j.TI19BCT,0)+NVL(j.TI19BVT,0)+NVL(j.TI19BFT,0) -+ NVL(j.TI09BVT,0)+NVL(j.TI09BFT,0) -+ NVL(j.XX21TIT,0)+NVL(j.XX11TIT,0)+NVL(j.XX19TIT,0)+NVL(j.XX9TIT,0) -``` - -### Factura reala cu taxare inversa — NU exista una venita din import eFactura in schema dev - -- `anaf_efactura` (schema `MARIUSM_AUTO`): 487 randuri primite, doar **8** au `id_fact` completat - (legatura catre `jc2007`/`act`). Niciunul dintre acele 8 `id_fact` se suprapune cu vreun rand din - `jc2007` care are coloane `TI*`/`XX*TIT` nenule (31 randuri in toata schema, toate din test/demo, - ani 2007-2022, fara `id_fact` legat de `anaf_efactura`). Interogarea de join explicit - (`jc2007 j JOIN anaf_efactura a ON a.id_fact = j.id_fact WHERE a.factura_emisa=0 AND `) - a intors **0 randuri**. -- Cele 6 randuri din `anaf_vefactura_primit` cu `id_fact` legat au `total_cu_tva = jtotctva` - (diferenta 0) — niciuna dintre ele nu e taxare inversa, deci nu demonstreaza mecanismul. - -**Cel mai apropiat caz gasit** (nu vine din eFactura, e din `jc2007` direct — demonstreaza doar -aritmetica pe care view-ul o va aplica): - -``` -an=2022 luna=4 dataact=30-APR-22 nract=222 id_part=614 id_fact=8007136 -ti19bft=19 totctva=119 -``` - -Daca acest rand ar fi venit dintr-un import eFactura cu linie `AE` (TVA XML = 0), XML-ul ar fi -avut `total_cu_tva = 100` (119 - 19 taxare inversa), in timp ce `jtotctva` (= `SUM(totctva)`) tot -ar da `119`. Cu view-ul curent: `diferenta = total_cu_tva - jtotctva = 100 - 119 = -19` (fals -pozitiv, exact cat e TVA de taxare inversa). Cu `jtva_ti` adaugat: `diferenta = total_cu_tva - -(jtotctva - jtva_ti) = 100 - (119 - 19) = 0`. Mecanismul se confirma numeric, dar **pe un caz -sintetic, nu pe o factura reala din import eFactura** — schema dev nu are asa ceva. De consemnat -in nota de release: verificare finala pe date reale ramane de facut la prima factura de taxare -inversa importata dupa aplicarea scriptului (sau pe schema de productie/testare cu date reale, -daca exista acces). - ---- - -## C. Verdict performanta — forma subselectului unic - -Confirmat: `jtotctva` e deja un subselect scalar corelat cu `REGEXP_SUBSTR`/`REGEXP_REPLACE` in -`WHERE`, neindexabil. Recomandare: `CROSS APPLY` (Oracle 12c+, disponibil pe 19c) in loc de doi -subselecti scalari separati — un singur scan per rand din urma, ambele sume calculate odata: - -```sql -SELECT ..., - jt.jtotctva, - jt.jtva_ti - FROM anaf_efactura a - CROSS APPLY ( - SELECT SUM(j.totctva) AS jtotctva, - SUM(NVL(j.TI21T,0)+NVL(j.TI11T,0)+NVL(j.TI24T,0)+NVL(j.TI20T,0) - +NVL(j.TI19BCT,0)+NVL(j.TI19BVT,0)+NVL(j.TI19BFT,0) - +NVL(j.TI09BVT,0)+NVL(j.TI09BFT,0) - +NVL(j.XX21TIT,0)+NVL(j.XX11TIT,0)+NVL(j.XX19TIT,0)+NVL(j.XX9TIT,0)) AS jtva_ti - FROM jc2007 j - LEFT JOIN nom_parteneri p ON j.id_part = p.id_part - WHERE j.an = EXTRACT(YEAR FROM a.xdata_act) - AND j.luna = EXTRACT(MONTH FROM a.xdata_act) - AND j.dataact = a.xdata_act - AND REGEXP_SUBSTR(a.xnumar_act, '\d+[^[:digit:]]*$') LIKE '%' || TO_CHAR(j.nract) || '%' - AND REGEXP_REPLACE(p.cod_fiscal, '[^[:digit:]]', '') = a.cod_fiscal_emitent - ) jt - WHERE a.factura_emisa = 0 -``` - -Motiv pentru `CROSS APPLY` (nu doi subselecti separati): pastreaza exact semantica actuala — fiind -un `SUM(...)` fara `GROUP BY`, subquery-ul `APPLY` intoarce mereu exact un rand (NULL pe ambele -sume cand nu exista potrivire), identic cu comportamentul scalar-subquery de azi. Nu necesita -restructurarea restului view-ului (multe coloane scalare + `detalii` tip `M`/CLOB, imposibil de -pus curat intr-un `GROUP BY` la nivel de view fara alte modificari). Nu e scriptul de migrare final -— doar forma recomandata, de validat de cine scrie scriptul. - -Pe `anaf_vefactura_trimis`: `jtva_ti` ramane `0` constant (fara subselect), deci nu exista cost -suplimentar acolo — planul are dreptate aici, nimic de schimbat. - ---- - -## D. Sonda de coloana - -Confirmat azi (inainte de migrare): -```sql -SELECT jtva_ti FROM anaf_vefactura_primit WHERE 1=2; --- ORA-00904: "JTVA_TI": invalid identifier -``` - -**Recomandare: `USER_TAB_COLUMNS`**, nu `TRY` pe `SELECT`: - -```sql -SELECT COUNT(*) FROM user_tab_columns - WHERE table_name = 'ANAF_VEFACTURA_PRIMIT' AND column_name = 'JTVA_TI'; -``` - -Motive: -- Confirmat ca views apar normal in `USER_TAB_COLUMNS` (40 coloane gasite pentru - `ANAF_VEFACTURA_PRIMIT`), deci interogarea functioneaza identic pe view ca pe tabela. -- E o interogare de dictionar, fara sa declanseze parsarea/executia interogarii principale — in VFP - nu necesita un bloc `TRY/CATCH` in jurul unui `SELECT` care ar putea arunca o eroare ANAF pe - conexiunea Oracle reala (goExecutor), doar un `SELECT ... FROM user_tab_columns`, mai usor de - facut robust si de logat separat daca lipseste catalogul. -- Cost neglijabil (interogare pe dictionar, nu pe date), rulata o singura data la deschiderea - ferestrei, nu per rand. - ---- - -## Alte observatii utile pentru cine scrie scriptul de migrare - -- `TI09` nu are deloc varianta `BC` (doar `BV`/`BF`) — asimetric fata de `TI19` care are toate 3 - (`BC`/`BV`/`BF`). Nu e o eroare, tabela chiar arata asa; scriptul trebuie sa scrie exact - `TI09BVT + TI09BFT` (2 termeni), nu 3. -- `XX9TIT`/`XX9TIB` (fara zero la 9) sunt corecte, exista pe tabela — confirmat, la fel cum zice - planul. -- `ANAF_VEFACTURA_EMIS_DETALIU` e INVALID in schema dev azi, independent de L4 — de mentionat catre - echipa daca cineva verifica obiecte invalide global, ca sa nu fie confundat cu o stricare produsa - de scriptul L4. diff --git a/docs/handoff_transa3_conditii.md b/docs/handoff_transa3_conditii.md deleted file mode 100644 index c052c5a..0000000 --- a/docs/handoff_transa3_conditii.md +++ /dev/null @@ -1,185 +0,0 @@ -# Handoff — TRANSA 3, verificare conditii de intrare (agent read-only) - -Verificare pe cod + Oracle (schema `MARIUSM_AUTO`, alias `ROA_CENTRAL`), 27.07.2026. -Referinta: `docs\plan-anaf-tva-efactura-4-lucrari.md`, sectiunea "TRANSA 3 — L3" (330-497) -si "Ce ramane neverificat" (571-581). Niciun DDL/DML rulat, doar `SELECT`. Niciun commit. - ---- - -## A. Cotele 21%/11% in `pack_contab` — **INCHIS** - -Sursa exportata: `docs\local\PACK_CONTAB.pck` (`ALL_SOURCE`, `MARIUSM_AUTO`, PACKAGE + PACKAGE BODY, -451 linii). - -- `defalca_tva_incasare` (`.pck:60-79`) nu contine el insusi nicio lista de cote — deleaga integral - la `creeaza_note_tva_incasare` (`.pck:69`). -- `creeaza_note_tva_incasare` (`.pck:121-415`) foloseste `DECODE(A.ID_JTVA_COLOANA, ...)` cu id-urile - 211/215 pentru JC (`RO21NB/RO21NT`, `RO11NB/RO11NT`, `.pck:255-257, 288-289`) si 38/42 pentru JV - (`.pck:270-272, 303-304`), alaturi de 171/179/189/173 (24/20/19/9) si default 5%. Antetul pachetului - are comentariul `08.08.2025 / creeaza_note_tva_incasare TVA 21%, 11%` (`.pck:56-58`), care confirma - data introducerii. -- `cauta_facturaTVAEx` (`.pck:417-448`) filtreaza explicit `RO21NT <> 0 OR RO11NT <> 0 OR RO19NT <> 0 - OR RO9NT <> 0 OR RO5NT <> 0` (`.pck:433, 446`). - -**Observatie in afara scopului A** (nu blocheaza conditia de intrare, dar de retinut): filtrul din -`cauta_facturaTVAEx` omite `RO24NT`/`RO20NT` — o factura cu TVA neexigibil DOAR pe cota 24% sau 20% -nu apare in lista cautata manual. E preexistent, nu introdus de suportul 21/11, si e alt buton -(`cauta_facturaTVAEx` alimenteaza calea "Otherwise" din `do_adauga_tva_exigibil`, nu calea L3). - -**VERDICT: cotele 21%/11% sunt tratate integral in ambele proceduri. Conditia de intrare e inchisa.** - ---- - -## B. Formula de sold neexigibil — **INCHIS PARTIAL, CONTRAZICE PLANUL pe sursa datelor** - -Confirmat pe `ALL_TAB_COLUMNS` (`MARIUSM_AUTO`): toate cele 14 coloane din lista corecta -(`RO24NB/NT, RO20NB/NT, RO21NB/NT, RO11NB/NT, RO19NB/NT, RO9NB/NT, RO5NB/NT`) exista, cu acelasi nume, -in **ambele** `JC2007` si `JV2007` (NUMBER(18,4)). `ID_FACT` exista in ambele (NUMBER(20)). - -**CONTRAZICE PLANUL:** coloana `TVA_INCASARE` **nu exista** in `JC2007` nici in `JV2007` — nu e -"de confirmat", e absenta confirmata. `TVA_INCASARE` traieste pe `DOCUMENTE` (header-ul facturii, -`ID_DOC` = `id_fact`, cf. `pack_contab.creeaza_note_tva_incasare`: `select nract from documente where -id_doc = tnIdFact`), plus pe view-urile `VJC2025`/`VJV2025` care deja o aduc alaturi de toate cele 14 -coloane de cota (verificat pe `ALL_TAB_COLUMNS`) — acelasi view pe care `cauta_facturaTVAEx` il -foloseste deja (`vjv2025`/`vjc2025`, `.pck:430, 443`). - -O interogare literala "peste jc2007 + jv2007" cu filtru `tva_incasare = 1`, asa cum e formulat in -plan la Pasul 3, ar da eroare Oracle (coloana inexistenta). Recomandare: interogarea sa foloseasca -`VJC2025`/`VJV2025` (deja au `AN`, `LUNA`, `ID_FACT`, toate cele 14 coloane, `TVA_INCASARE`) in loc de -`JC2007`/`JV2007` brute — consecvent cu precedentul din acelasi pachet (`cauta_facturaTVAEx`), sau -alternativ un JOIN explicit `jc2007/jv2007` -> `documente` pe `id_doc = id_fact`. - -Interogare-draft testata pe date reale (VJC2025/VJV2025, fara restrictie an/luna, deci scanare completa -ca sa vada volumul maxim): - -```sql -select id_fact from vjc2025 - where tva_incasare = 1 - and (ro24nb+ro24nt+ro20nb+ro20nt+ro21nb+ro21nt+ro11nb+ro11nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt) <> 0 -union -select id_fact from vjv2025 - where tva_incasare = 1 - and (ro24nb+ro24nt+ro20nb+ro20nt+ro21nb+ro21nt+ro11nb+ro11nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt) <> 0; -``` - -Rezultate (fara filtrul de an/luna, deci acesta e volumul-plafon, nu volumul unei singure salvari): -5711 randuri in `VJC2025`, 15506 in `VJV2025`, care se filtreaza la interogarea reala pe `an`/`luna` -curente plus intersectia locala cu `tact`. `ID_FACT` nu e niciodata null pe niciuna din cele doua -(`count(*) where tva_incasare=1 and id_fact is null` = 0 pe amandoua). - -**VERDICT: coloanele de cota si `id_fact` sunt confirmate pe `JC2007`/`JV2007` (lista corecta e -completa acolo). `tva_incasare` NU e acolo — planul trebuie corectat sa citeasca din `VJC2025`/ -`VJV2025` (sau JOIN cu `DOCUMENTE`), altfel Pasul 3 pica la implementare cu eroare Oracle de coloana -inexistenta.** - ---- - -## C. `defalca_tva_incasare` poate intoarce zero randuri sau `id_fact` problematic — **INCHIS, cu -intarire fata de plan** - -Din sursa (`.pck:121-415`): cursorul returnat de `creeaza_note_tva_incasare` seteaza mereu -`id_fact = tnIdFact` (parametrul de intrare, literal — `.pck:169`) — deci `id_fact` NU poate fi NULL -in cursor decat daca parametrul insusi era NULL, ceea ce VFP nu trimite (`Str()` pe un numeric). -**Zero randuri e insa posibil**: filtrul final `WHERE A1.ID_JTVA_COLOANA IS NOT NULL AND SIGN(V_SUMA) -* A1.totctva > SIGN(V_SUMA) * A1.DIF` (`.pck:412-413`) poate exclude toate liniile. - -Codul VFP care insereaza din cursor (`omodificari.vc2:12400-12422`, -`Insert Into &tcCursorAct(...) ... FROM (lcCursorDefTVA) a`) nu are protectie explicita pe 0 randuri — -un `INSERT INTO ... SELECT` dintr-un cursor gol insereaza tacut 0 randuri, fara eroare. Confirma -citatul din plan (`oproceduri_inchidere.prg:843-848`, alta cale de apel, meniu -> `inchidere_tva_sold`, -care TRATEAZA explicit `Reccount(lcCursorDefTVA) = 0`). - -**Gasit in plus, mai relevant decat citatul din plan pentru drumul L3:** pe drumul -`do_adauga_tva_exigibil` (butonul chiar din spatele avertizarii L3), exista un caz concret si usor de -reprodus in care `tnIdFact` trimis catre Oracle e **santinela `-5`**, nu id-ul real: - -``` -omodificari.vc2:12547-12552 (Case !Empty(perechec) And Left(scd,1)='5') - loadd.id_fact = Iif(m.loadd.id_factc > 0, m.loadd.id_factc, -5) - ... - llCalculeazaNoteTVA = m.llCalculeazaTVAEx -``` -si simetric la `:12555-12561` pentru `id_factd`. Daca `llCalculeazaNoteTVA` e adevarat (bifat -`chkTVAEX`), linia asta ajunge la `Thisform.creeaza_note_tva_incasare('tact', m.loadd, m.lnSuma)` -(`:12601`), care citeste `lnIdFact = toRec.id_fact` (`:12378`) — posibil `-5` — si il trimite direct -la `pack_contab.defalca_tva_incasare(-5, ...)` (`:12385-12389`). Nicio factura nu are `id_fact = -5`, -deci cursorul Oracle vine garantat gol pe acest drum, de fiecare data cand id_factc/id_factd nu era -deja completat. - -**VERDICT: da, zero randuri e un caz real si reproductibil pe insusi drumul pe care il declanseaza -butonul din dialogul L3 ("Adauga acum"), nu doar pe calea de meniu citata in plan. Flagul anti-bucla -de la Pasul 5 e strict necesar — confirmarea e mai tare decat presupunea planul.** `id_fact` NULL nu -e posibil prin acest pachet (mereu = parametrul trimis); riscul real e parametrul insusi fiind -santinela, nu NULL. - ---- - -## D. Kill-switch: unde se pune — **CONTRAZICE PLANUL pe mecanism** - -Planul (Pasul 0.5) presupune "Optiune in `Optiuni_FIRMA`/`Optiuni_PROGRAM`" — DBF-urile locale din -`D:\ROA\ROACONT\DATE\` (`Optiuni_FIRMA.dbf`, `Optiuni_PROGRAM.dbf`, `Optiuni_LOCAL.dbf` — exista pe -disc, confirmat). **`RC_ANAF_VERIF_SELECTIE` NU foloseste aceste DBF-uri.** Mecanismul real, verificat -in cod: - -- Functia care citeste nivelul: `ANAF_NivelVerificare` (`COMUN\programe\ocautare.prg:242-276`). -- Kill-switch propriu-zis, verificat PRIMUL: fisier `.ini`, nu DBF — - `getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')`; doar valoarea explicita `'0'` opreste - (`ocautare.prg:247-249`). Absenta cheii NU opreste nimic (cascada continua). -- Optiune per-utilizator/per-firma: cursoarele `crsOptiuniUtilizator`/`crsOptiuni`, incarcate din - Oracle la pornire — tabelele Oracle `optiuni_util` / `optiuni` (`actualizeaza_optiuni_utilizator` / - `actualizeaza_optiuni`, `oinit_optiuni.prg:709-722, 784-798`), citite prin - `citeste_optiune_utilizator` / `citeste_optiune` (`oinit_optiuni.prg:725-742, 802-823`; apel efectiv - la `ocautare.prg:264-266`). Cache pe sesiune intr-o `Collection` (`goCacheANAF_Nivel`, - `ocautare.prg:253-259`), cheia fiind schema + utilizator. -- Scriere: `scrie_optiune_utilizator` cheama `PACK_SESIUNE.SetOptiuneUtilizator` (`oinit_optiuni.prg: - 764`) — deci store-ul de adevar e Oracle, nu DBF local. -- Aparitia in UI: intrare de meniu, nu ecran de optiuni cu DBF — - `ON SELECTION BAR 3 OF optiuniuti DO ANAF_ComutaVerificare IN ocautare.prg` - (`Meniuri\CONT2000.MPR:210`), care cheama `ANAF_ComutaVerificare` (`ocautare.prg:324-382`) — un - toggle interactiv (citeste valoarea curenta, cere valoarea noua), nu un formular cu campuri DBF. - -**VERDICT: modelul real de urmat pentru kill-switch-ul L3 e Oracle (`optiuni`/`optiuni_util` + -`citeste_optiune`/`citeste_optiune_utilizator` + cache in Collection) plus, daca se vrea si oprire -per-masina, INI-ul (`getini(gcGeneralIniFile, ...)`) — NU `Optiuni_FIRMA`/`Optiuni_PROGRAM.dbf` din -`DATE\`. Planul trebuie corectat inainte de Pasul 0.5.** - ---- - -## E. Acoperirea drumurilor de instantiere — **INCHIS, lista din plan e completa** - -Cautare `rg --no-ignore` in tot `D:\ROA\ROACONT` (inclusiv `COMUN\`) dupa -`Createobject([frm_modific2007]...)` / `Createobject([frm_modific2024]...)`. Rezultat (excluzand -`.BAK`, fisiere de test, si documentul de plan insusi): **exact aceleasi 14 situri** din listă: -`ocont2003.prg:416,1230,1679,2141`; `oproceduri_incasari.prg:299`; `frm_import_extrase_banca.sc2:1652`; -`anaf_efactura.vc2:12733,12940`; `frm_initializare_facturi_balanta.sc2:1803`; `comun.vc2:2436`; -`oproceduri_inchidere.prg:719,902,1007,1438`; `frm_import_note_a4200.sc2:1651`; -`frm_import_note_facturi_clienti.sc2:895`; `ooperatii_comune.prg:1137`. Nimic lipsa. - -(Gasit in plus, dar nu conteaza pentru acoperirea de productie: `COMUN\utile\Teste\ -achizitie_import\test_repro_cnrcrt_footer.prg:82` — harness de test, nu drum de productie.) - -**Verificare bucla** (subagent, citire directa a codului din jurul fiecarui `Createobject`): din cele -14 situri, **niciunul altul** nu instantiaza formularul intr-o bucla activa — toate `SCAN`/`FOR` din -procedurile respective se incheie inainte de linia cu `Createobject`. Singura exceptie sintactica: -`oproceduri_inchidere.prg:719` e in interiorul unui `Do While`, dar urmat imediat de un `Exit` -necondiționat dupa `loForm.Show(1)` — functional tot instantiere unica, nu bucla reala. - -**VERDICT: candidatii pentru flagul de lot (Pasul 0.6) raman exact cei trei numiti in plan — -`anaf_efactura.vc2:12733`, `:12940`, `comun.vc2:2436`. Nu mai sunt altii.** - ---- - -## Ce ramane neverificat (in afara scopului A-E, de mentionat) - -- Comportamentul `goExecutor` la timeout/conexiune cazuta — nu a fost testat (ar necesita simularea - unei conexiuni cazute); contractul de cod (`lnSucces < 0` la esec, in toate apelurile vazute) e - vizibil, dar nu a fost validat prin scenariu de esec real. -- Volumul real de linii pe un decont de curier/procesator la clienti — nu exista date de productie - disponibile in schema de dev (`MARIUSM_AUTO`) ca sa fie masurat; ramane pe baza estimarii din plan. - ---- - -## Fisiere generate - -- `docs\local\PACK_CONTAB.pck` — export sursa `pack_contab` (PACKAGE + PACKAGE BODY), 451 linii, - `ALL_SOURCE` din `MARIUSM_AUTO`. diff --git a/docs/handoff_transa3_deschise.md b/docs/handoff_transa3_deschise.md deleted file mode 100644 index 3b5cbc8..0000000 --- a/docs/handoff_transa3_deschise.md +++ /dev/null @@ -1,182 +0,0 @@ -# TRANSA 3 (L3) — cele doua puncte ramase din "Ce ramane neverificat" - -Data: 27.07.2026. Read-only (Oracle: doar SELECT; cod: doar citire). Nimic modificat, nimic comis. -Nu ating `docs\handoff_transa3_conditii.md` (al colegului T3-cond). - -## VERDICT GENERAL - -- **Punctul 1 (goExecutor la timeout/conexiune cazuta) — CONTRAZICE PLANUL.** Comportamentul implicit - NU e "se sare, cu linie in goLog": pe conexiune cazuta apare mereu un dialog modal blocant, care la - Cancel face `QUIT` (inchide toata aplicatia). Pattern-ul defensiv cerut de plan **nu are niciun - precedent** azi in codebase — trebuie construit, nu copiat. -- **Punctul 2 (linii pe decont) — RAMAS DESCHIS pe cifra exacta**, dar decizia arhitecturala a - planului (fara lista `IN(...)`) ramane intemeiata independent de cifra. Schema dev nu are volum - reprezentativ pentru batch-uri reale de extras/decont. - ---- - -## Punctul 1 — comportamentul `goExecutor` la timeout / conexiune cazuta - -Sursa reala (cautata cu `rg --no-ignore`... de fapt Grep a gasit-o direct, COMUN nu era exclus in -aceasta sesiune): clasa `oexecutor` e definita in `COMUN\programe\oproceduri_comune.prg:69-547` -(NU in `anaf_efactura.vc2` — de acolo doar se apeleaza). Instantiata o singura data: -`goExecutor = Createobject("oExecutor")`, `Programe\roacont.prg:588`. - -### Ce intoarce `oExecute()` la esec - -Functie normala, **nu arunca eroare VFP**. `SQLExec()` esuat intoarce direct `< 0`, prins de codul -existent — niciun `THROW`/`ERROR()` implicat. Return: `CT_INSUCCES` (`= -1`, -`COMUN\include\comun.h:10`) daca `lnSucces < 1`, altfel `CT_SUCCES` (`= 1`) -(`oproceduri_comune.prg:496`, `Return Iif(lnSucces >= 1, CT_SUCCES, CT_INSUCCES)`). -Cursorul de iesire nu se creeaza pe esec (Use-ul din urma nu ruleaza). - -`oExecuta()` (wrapper cu litera mica, folosit in ~jumatate din apeluri) doar impacheteaza -`oExecute()` si adauga necontitionat `amessagebox(This.oPrelucrareEroare(), 16, "Eroare")` pe orice -esec (`:149-152`) — **indiferent de parametri**. Diferenta fata de `oExecute()` (raw) e semnificativa -pentru L3. - -### Urca eroarea la `ErrorHandler` global? NU, direct — DAR - -Nu urca la `ON ERROR` (nu e o exceptie VFP). Insa exista un dialog modal **necontitionat de -`tlShowError`**, la eroare ODBC (`lnEroare1 = 1526`) cu cod de eroare in lista -`12152, 3113, 3114, 12560, 4068, 28, 12` (`oproceduri_comune.prg:383`) — **exact codurile de -conexiune cazuta/protocol** (3114 = NOT CONNECTED TO ORACLE, 3113 = end-of-file on communication -channel, 12560 = protocol adapter error): - -``` -lnRaspuns = amessagebox('Eroare de conectare.' + ... + 'Doriti reconectare?', 4 + 32, 'Eroare') -``` - -(`:390`) — apare **mereu** cand `llReconnect = .T.`, chiar daca apelantul a lasat toti parametrii -default. Daca utilizatorul raspunde "Nu" (`lnRaspuns <> 6`): `Quit` + `Retry` (`:412-413`) — -**inchide toata aplicatia**, nu doar sare peste verificare. - -`llReconnect` e recalculat **la fiecare apel**, ignorand orice setare anterioara pe obiect -(`:220-224`): -``` -If SQLGetprop(lnHandle, "Transactions") = 2 && TRANZACTIE MANUALA - This.lReconnect = .F. -Else - This.lReconnect = .T. && cazul normal, in afara unei tranzactii manuale -Endif -``` -si apoi, daca apelul are sub 8 parametri (cazul general in tot codebase-ul), `llReconnect` preia -`This.lReconnect` — deci **.T. implicit** pentru orice verificare in afara unei tranzactii manuale. -Singurul mod de a opri acest modal e sa dai explicit al 8-lea parametru (`tlReconnect = .F.`) la -apel — vezi mai jos, nu exista niciun apel asa in tot codebase-ul. - -**CONTRAZICE PLANUL:** cerinta "orice esec (... conexiune cazuta ...) -> se sare, cu linie in -`goLog`. Niciodata tacut... Esecul nu blocheaza salvarea" (plan, `:445-448`) **nu e comportamentul -implicit** pentru exact acest caz (conexiune cazuta). E opusul: un dialog modal blocant, care poate -opri toata aplicatia. Pentru orice ALTA eroare (SQL gresit, tabela inexistenta — `ORA-00942`, -coloana lipsa — `ORA-00904`), comportamentul implicit CHIAR e "se sare, log, fara dialog" — -`llShowError` e `.F.` implicit si acel dialog nu e conditionat decat de el. Deci planul are dreptate -pentru clasa generala de erori, dar nu pentru "conexiune cazuta" — exact cazul numit explicit in -text. - -`goLog.Log(...)` SE cheama pe toate drumurile de esec (`:368-370`, `:384-387`, `:422-424`) — de -partea asta planul are dreptate necontitionat, indiferent de tipul erorii. - -In plus, pe orice esec (`lnSucces < 0`), independent de parametri, codul posteaza automat eroarea la -endpoint-ul de erori (`goMyXMLHTTP.postError(...)`, `:463-471`) — un apel HTTP sincron in plus pe -drumul de salvare, la fiecare esec, inclusiv la cele care ar trebui "sarite silentios". - -### Timeout configurat? - -Nu exista niciun `SQLSETPROP` cu `QueryTimeout`/`ConnectTimeout`/`WaitTime` pe handle-ul Oracle, -nicaieri in `oExecutor`/`oConn` (`oproceduri_comune.prg:662-731`, `Connect` foloseste doar -`Sqlstringconnect(lcString)` cu `dsn=...;Uid=...;Pwd=...`, fara parametri de timeout). Singurul -`ConnectTimeout` gasit in tot fisierul (`:4105-4118`) e pentru verificarea HTTP de update-uri, fara -legatura cu conexiunea Oracle. **Concluzie: un query care ramane agatat (nu eroare, ci hang) nu are -niciun timeout care sa-l intrerupa — ar bloca formularul la nesfarsit**, ceva ce nici planul, nici -codul actual nu adreseaza. De consemnat separat, dincolo de "esec" (eroare) — un hang nu e un esec, -e o blocare fara iesire. - -### Tiparul de apel defensiv "corect" deja folosit in codebase — NU EXISTA - -Am cautat toate apelurile `oExecute(`/`oExecuta(` din COMUN si Programe (peste 150) — **niciunul nu -trece de 2 parametri** (`tcSql`, `tcCursor`). Nimeni nu foloseste vreodata parametrii 6-8 -(`tlShowError`, `tlQuitOnError`, `tlReconnect`) explicit. Deci pattern-ul "cheama cu -`tlReconnect = .F.` ca sa eviti dialogul de reconectare" **nu are niciun precedent** — L3 ar fi -PRIMUL loc din codebase care il foloseste. - -Cel mai apropiat precedent (nu perfect, dar cel mai aproape de "se sare fara dialog"): -- `oproceduri_inchidere.prg:1297`: `goExecutor.oExecuta(lcSql, "imob_conturi")` urmat doar de - `If m.llSucces ... Endif` — la esec nu se face nimic in plus (dar `oExecuta` tot arata singura - `amessagebox` interna, deci nu e cu adevarat silentios). -- Pattern mai bun de citat ca baza (foloseste `oExecute`, nu wrapper-ul `oExecuta`): - `COMUN\clase\baza.vc2:1807`, `lnSucces = goExecutor.oExecute(lcSql,lcCursor)`, fara parametri - suplimentari — la 2 parametri, `llShowError`/`llQuitOnError` raman `.F.` (fara dialog pe erori - generice), dar `llReconnect` tot devine `.T.` implicit, deci tot apare dialogul de reconectare pe - conexiune cazuta. - -**Recomandare pentru L3** (nu e sarcina mea sa implementez, doar de raportat ca gasire): interogarea -noua trebuie sa apeleze `goExecutor.oExecute(...)` (NU `oExecuta`, care are mesaj propriu -necontitionat), cu toti cei 8 parametri, ultimul (`tlReconnect`) explicit `.F.`, si verificarea -proprie a rezultatului fara niciun `amessagebox` propriu — un tipar care azi nu exista nicaieri in -cod si trebuie scris de la zero, nu copiat. - ---- - -## Punctul 2 — numarul real de linii pe un decont de curier/procesator - -### Ce s-a verificat despre sursa datelor - -Confirmat din cod (`Programe\oproceduri_import.prg:100-264`): importul de extrase/deconturi e -**strict pe fisier local** (`Getfile()` la `:138`, parsat client-side in cursoare VFP -`C_IMPORT_TEMP` -> `cActTemp`). Oracle NU pastreaza niciun tabel de staging cu "lot de import" si -numar de linii — abia dupa validare, liniile devin note (`ACT`/`ACTACTAN`) si se salveaza individual. -Deci **nu exista in Oracle o coloana/tabela care sa raspunda direct la intrebare** — a trebuit -reconstruita indirect. - -`nom_fdoc`: `id_fdoc = 40` = `EXTRAS CON` (extras cont), `id_fdoc = 33` = `DECONT` (decont -curier/procesator). - -### Reconstructie indirecta (proxy, nu masuratoare directa) - -`ACT` nu are o coloana de "id lot" — am grupat notele salvate prin apropierea `DATAORA` (momentul -efectiv al salvarii, cu ora), pe acelasi `id_util`, cu prag de 10 minute intre randuri consecutive ca -limita de lot. E o aproximare (poate sparge/uni loturi reale), nu o masuratoare exacta din aplicatie. - -**Rezultate (schema `MARIUSM_AUTO`, dev):** -- `DECONT` (id_fdoc=33): **doar 2 randuri in toata baza**, un singur lot de 2 linii (25.06.2026). - Date insuficiente pentru orice concluzie. -- `EXTRAS CON` (id_fdoc=40): 222 randuri, pe 32 zile distincte, din 19.01.2008 pana in 29.05.2026 — - 40 loturi estimate. **min 1, max 70, medie 5.6, percentila 95 ≈ 10 linii/lot.** - -**CONTRAZICE PLANUL, cu rezerva explicita de mai jos:** cifra afirmata in plan ("un extras obisnuit -are 300-2000 linii/luna") e cu un ordin de marime peste orice lot gasit in aceasta schema (maximul -absolut observat e 70). - -**De ce nu extrapolez asta la "planul gresit pe cifra":** `MARIUSM_AUTO` e schema de dezvoltare a lui -Marius (confirmat in `COMUN\docs\oracle_export.md`), nu un client real cu volum de productie. Loturile -gasite arata a teste punctuale facute de-a lungul anilor (o inserare la cateva luni sau ani), nu -activitate de contabilitate lunara reala pe un cont bancar activ. **Schema dev NU are date -reprezentative pentru volumul real al unui client — nu pot confirma sau infirma cifra 300-2000 pe -aceasta baza.** Ramane RAMAS DESCHIS strict pe cifra exacta. - -**Corroborare slaba, doar indicativa:** fisierul-sablon real din `Alte\Extras_de_cont_11634808MT -940.txt` (extras MT940 pentru o singura zi, un singur cont) are 11 linii de tranzactie (`:61:`) pentru -acea zi. Extrapolat naiv la ~20-22 zile lucratoare/luna ar da ~220-240 linii/luna pentru un cont de -activitate medie — aproape de capatul de jos al intervalului din plan (300), dar e un singur esantion -de o zi, pentru o singura firma, nu o distributie. - -### Ce ramane solid, indiferent de cifra exacta - -Decizia arhitecturala a planului de la Pasul 3 ("fara lista `IN(...)`", `:421-431`) **nu depinde** -de cifra 300-2000 ca sa fie corecta: o interogare unica, de lungime fixa, cu intersectia facuta local -in VFP, elimina o clasa intreaga de eroare (`ORA-01795`, prag 1000) **indiferent daca lotul real are -10 sau 2000 de linii** — nu exista un prag sub care revenirea la `IN(...)` ar fi de preferat, pentru -ca varianta cu interogare unica nu are dezavantaj de cost fata de o lista `IN` mica. Deci verdictul -practic: **decizia ramane intemeiata**, chiar daca premisa numerica citata in text nu e verificata -(si, pe aceasta schema, pare supraestimata). - ---- - -## Alte observatii utile - -- `oExecuta()` (wrapper) vs `oExecute()` (raw): distinctia conteaza mult pentru L3 si nu era - evidenta din plan. `oExecuta` are propriul `amessagebox` necontitionat pe esec — pentru cerinta - "niciodata dialog, doar log", trebuie folosit `oExecute`, nu `oExecuta`. -- `oPrelucrareEroare()` (folosit de mesajele proprii de eroare) nu a fost citit in detaliu — nu era - necesar pentru cele doua puncte cerute. diff --git a/docs/plan-anaf-tva-efactura-4-lucrari.md b/docs/plan-anaf-tva-efactura-4-lucrari.md deleted file mode 100644 index c4d8ee5..0000000 --- a/docs/plan-anaf-tva-efactura-4-lucrari.md +++ /dev/null @@ -1,714 +0,0 @@ -# Plan: 4 lucrari ROACONT (ANAF perioada TVA, validare CNP, avertizare exigibilizare, borderou eFactura) - -Data: 27.07.2026. Autor livrare: marius.mutu. -Versiune consolidata dupa runda 2 de review si poarta de decizie. **Aceasta e versiunea de -executat** — incorporeaza toate deciziile. Istoricul review-ului e in Anexa, la final, si nu -contine nimic de implementat. - -Plan de test insotitor: -`~/.gstack/projects/ROACONT/mmari-main-eng-review-test-plan-20260727-194744.md` - -## Livrare in TREI TRANSE separate - -Cele 4 lucrari nu au nicio dependenta functionala intre ele, dar au clase de risc si povesti de -retragere incompatibile. Impachetate impreuna, o retragere pentru L3 ar lua cu ea si view-ul deja -aplicat in schema clientului. - -| Transa | Continut | Blast radius | Retragere | Blocata de | -|---|---|---|---|---| -| 1 | L1 + L2 | 2 fisiere `.prg` in COMUN | un pas | nimic — se poate incepe | -| 2 | L4 | script DB + o expresie in client | doi pasi coordonati | 2 conditii de intrare | -| 3 | L3 | drumul de salvare al notelor, toata suita ROA | un pas, dar afecteaza tot | 1 conditie de intrare | - -Fiecare transa se inchide in SVN inainte de a incepe urmatoarea. - ---- - -# TRANSA 1 — L1 + L2 - -Ambele in `COMUN\programe\ocautare.prg` + `COMUN\programe\validare.prg`. Lane secvential: L1 apoi L2. -Fara DB, fara drum de salvare. Reversibil prin revenire la binarul anterior. - -## L1 — de cand este platitor / neplatitor de TVA - -### Problema - -Verificarea ANAF de la alegerea partenerului spune doar starea la data documentului -("ANAF: platitor TVA la 27.07.2026"). Pentru un cod fiscal care si-a schimbat atributul, -utilizatorul nu vede DE CAND s-a schimbat. - -### Ce exista deja (verificat, nu se construieste) - -- `ParseJsonANAFv8` (`validare.prg:2001-2114`) pune DEJA in cursor toate campurile necesare: - `data_inceput_ScpTVA`, `data_sfarsit_ScpTVA`, `data_anul_imp_ScpTVA`, `mesaj_ScpTVA` - (citite din `inregistrare_scop_tva.perioade_tva[1]`, liniile 2060-2072). -- Cele trei coloane de data sunt DEJA de tip `D` in `CREATE CURSOR` (`validare.prg:2012`). - Nu e nevoie de normalizare, doar de garda pe gol. -- Informatia se pierde in `ANAF_VerdictDinCursor` (`validare.prg:1657-1689`), care ia din cursor - doar `cui`, `scpTVA`, `statusInactivi`, `denumire`, `mesaj` (`:1670-1675`). -- Cache-ul de sesiune `goCacheANAF_Sesiune` pastreaza **obiectul intreg** (`ocautare.prg:127` - `.Add(m.loRezANAF, ...)`, `:130` `.Item(...)`). Proprietatile noi supravietuiesc. Nu se modifica. -- `lDiscordanta` exista deja: `ocautare.prg:143`, - `(loRezANAF.scpTVA <> loOut.lAreRO) Or loRezANAF.statusInactivi`. Banda se ramifica deja pe ea - la `:651`. Nu se scrie detectie noua. - -Lucrarea e strict propagare + afisare. Nu se schimba apelul HTTP, nu se face al doilea apel. - -### Modificari - -**1. `validare.prg`, `ANAF_VerdictDinCursor` (~1657-1689)** - -Pe obiectul rezultat se adauga patru proprietati, toate citite din cursorul deja parsat: - -- `dInceputScpTVA`, `dSfarsitScpTVA`, `dAnulareScpTVA` — din coloanele de tip `D`, cu `Nvl` si - garda pe gol. -- `cMesajScpTVA` — din coloana **`mesaj_ScpTVA`** (`C(244)`), NU din `mesaj`. - - Motiv: `validare.prg:2012` declara `mesaj_ScpTVA C(244)` dar `mesaj V(100)`, iar `:2109` face - `loDate.mesaj = loDate.mesaj_ScpTVA` urmat de `Insert Into` la `:2112` — VFP taie tacut la 100 - din 244 de caractere. Proprietatea `mesaj` deja expusa contine mesajul ANAF trunchiat la 41%. - -Toate patru se citesc **aici**: cursorul se inchide la `:1683` si nu mai exista alta ocazie. - -**2. `ocautare.prg`, `ANAF_StarePartener`, blocul de verdict (`136-145`)** - -Propaga cele patru proprietati in `loOut`. - -Citirea se face cu `Pemstatus(loRezANAF, 'dInceputScpTVA', 5)` **aici, la `:140-145`** — nu in -`TextAnaf`. `ocautare.prg` e incarcat si de produse ROA care pot avea un `validare.prg` mai vechi -(garda existenta la `:63-66`); citirea neprotejata ar arunca eroare in acest bloc, inainte sa se -ajunga vreodata la `TextAnaf`. - -**3. `ocautare.prg`, `TextAnaf` (`683-695`) — cand si unde apare data** - -Data de perioada apare in banda **doar pe trei conditii**. In rest banda ramane identica cu azi, -iar perioada completa se vede in F4. - -| Conditie | Data in banda | -|---|---| -| `lDiscordanta` = .T. (ROA difera de ANAF, sau partener inactiv) | DA | -| `dAnulareScpTVA` nevid (anulare din oficiu) | DA | -| `dSfarsitScpTVA` < `Date()` (perioada s-a incheiat deja) | DA | -| rest (cazul normal, concordant) | NU | - -**Regula de pozitionare, obligatorie:** data se lipeste **imediat dupa starea de TVA, inaintea -oricarui segment `, Inactiv`**. - -`TextStare` (`ocautare.prg:680`) produce `Platitor TVA, Inactiv`. Forma gresita -`ANAF: Platitor TVA, Inactiv din 01.03.2019` afirma ca partenerul e inactiv din 2019, cand de fapt -aceea e data de inceput a perioadei de TVA. Cum `lDiscordanta` include `statusInactivi`, cazul -inactiv e chiar unul dintre cele aduse in banda — deci regula nu e optionala. - -Forme corecte: - -``` -ANAF: Platitor TVA din 01.03.2019, Inactiv (DENUMIRE... RO12345678) (F4 = detalii) -ANAF: Platitor TVA din 01.03.2019 (DENUMIRE... RO12345678) (F4 = detalii) -ANAF: Platitor TVA 01.03.2019 - 31.03.2026 (DENUMIRE... RO12345678) (F4 = detalii) -ANAF: Neplatitor TVA din 12.03.2026 (DENUMIRE... 12345678) (F4 = detalii) -ANAF: Neplatitor TVA, anulat din 12.03.2026 (DENUMIRE... 12345678) (F4 = detalii) -``` - -Precedenta cand ambele date sunt nevide: pe `dAnulareScpTVA` — anularea din oficiu e informatia -mai grava, iar `anulat` e cuvantul pe care contabilul il cauta. Cele doua date NU se contopesc: -`data_sfarsit_ScpTVA` (incetarea inregistrarii) si `data_anul_imp_ScpTVA` (anulare din oficiu) au -consecinte diferite asupra dreptului de deducere. - -Cand perioada apare in banda, data documentului redundanta (`' la ' + Dtoc(toStare.dData)`) se -scoate din text, ca sa nu rezulte doua date cu doua prepozitii alaturate. - -Banda are voie 2-3 randuri: `lb_anaf` are `WordWrap = .T.`, `Height = 46`, -`Width = toForm.Width - 20` (`ocautare.prg:472-476`). Riscul real nu e latimea, ci ca un sufix de -lungime variabila muta punctul de wrap si `(F4 = detalii)` sare intre randuri la derularea cu -sagetile. Regula de mai sus il reduce mult: ~95% din randuri pastreaza banda de azi. - -**4. `ocautare.prg`, `Detalii` (`787-873`)** - -Bloc nou in dialog, dupa starea curenta: perioada de inregistrare in scopuri de TVA (inceput / -sfarsit / anulare, cele nevide, cu etichete distincte) si, daca `cMesajScpTVA` e nevid, mesajul -textual primit de la ANAF, **integral**. - -Perioada apare in F4 **intotdeauna** cand ANAF a trimis-o, inclusiv in cazul concordant in care -banda nu o arata. - -**5. `validare.prg` (`2064-2072`) — logul pe parsare esuata** - -Se logheaza cazul in care `perioade_tva[1]` exista, sirul sursa e nevid, dar data parsata e goala. - -Conditia se scrie **explicit**, NU in `CATCH`: `CTOD` nu arunca exceptie pe format necunoscut, ci -intoarce data goala. `CATCH`-ul de la `:2070` prinde doar erori de acces la `perioade_tva[1]`, deci -un log pus acolo nu s-ar declansa niciodata pe cazul pentru care a fost cerut. - -(Parsarea e corecta cat timp ANAF trimite `YYYY-MM-DD`, sub `Set Date To YMD` de la `:2023`, -restaurat in `Finally` la `:2131`.) - -### Limita de acceptat - -ANAF v9 intoarce O SINGURA perioada — cea care acopera data interogata. Textul afisat descrie -perioada relevanta pentru data documentului, nu tot istoricul. - ---- - -## L2 — validare CNP la codurile de 13 cifre - -### Problema (bug raportat) - -`ARGHIR MARIA (CUI: 2540324131210, ID: 149) ANAF nu a raspuns - verificarea a fost sarita.` - -Mesajul e fals. `ANAF_StarePartener` (`ocautare.prg:82-84`) intoarce `.Null.` pentru codurile de -13 cifre FARA a seta `tcClasaEsec`. CNP-ul din exemplu este VALID. - -Localizarea exacta a defectului: -- BANDA nu acuza ANAF: `.Null.` cu clasa goala cade pe `Case Isnull(m.loStare)` (`:648-650`) -> - promptul neutru. Nu e gresit, dar nu spune nimic. -- DIALOGUL F4 e singurul care minte: `Detalii`, `:799-804`, ultima ramura a `Iif`-ului imbricat - (`:803`) -> 'ANAF nu a raspuns - verificarea a fost sarita.' -- `VerificaAlegere` (`:875+`) intoarce `.T.` tacut pe `oStare` nul — acolo nu e nimic de reparat. - -Defectul e mai larg decat cazul raportat: `EvalueazaRand` sterge explicit clasa de esec cand codul -e invalid (`:600`, `This.cClasaEsec = ''`). Deci pentru ORICE cod fiscal invalid, banda spune corect -"CNP invalid" / "CIF invalid", dar F4 afiseaza tot 'ANAF nu a raspuns'. Cazul raportat e una din -doua instante ale aceluiasi defect. - -### Ce exista deja (verificat) - -- Validarea locala RULEAZA DEJA: `EvalueazaRand` apeleaza `ANAF_ValidareCod` la `:594` si iese - devreme pe orice rezultat nevid (`595-604`), INAINTE de apelul ANAF. Deci "CNP invalid (...)" si - "CIF invalid (...)" se afiseaza deja azi. Nu se scrie validare noua. -- Consecinta: un cod care pica validarea nu ajunge niciodata pe drumul ANAF. Ramurile - "CNP invalid" sub clasa noua si "CUI valid/invalid" sub `FARA_RASPUNS` sunt INACCESIBILE prin - constructie si NU se implementeaza. -- `ANAF_ValidareCod` (`:208-227`) decide CNP vs CIF cu prioritate pe `tip_persoana`, altfel lungime 13. -- `VALIDARE_CNP` (`validare.prg:1296-1312`), `VALIDARE_CIF` (`validare.prg:1225-1294`). -- Clasa noua `COD_INVALID` urmeaza tiparul existent `COD_NENUMERIC` de la `ocautare.prg:643-646`. - -### Modificari - -1. `ocautare.prg`, `EvalueazaRand` (`:600`): `This.cClasaEsec = 'COD_INVALID'` in loc de `''`. -2. `ocautare.prg`, `ANAF_StarePartener` (`82-84`): seteaza `tcClasaEsec = 'CNP'` inainte de - `Return .Null.` -3. `ocautare.prg`, `ANAF_StarePartener`: primeste in plus `tnTipPersoana`, iar conditia de la `:82` - devine `Len(m.lcCui) = 13 And m.lnTipPersoana <> 1`. - - Motiv: `:82` decide "persoana fizica" doar pe lungime, ignorand `tip_persoana`, in timp ce - `ANAF_ValidareCod` (`:222`) decide invers, cu prioritate pe `tip_persoana`. Divergenta e mascata - azi pentru ca banda cade pe promptul neutru si nu afirma nimic. L2 pune acolo - "Persoana fizica - CNP corect", deci pentru un partener extern cu cod numeric de 13 cifre - aplicatia ar **afirma pe ecran** ceva fals, unde azi tace. Cauza e preexistenta, consecinta - vizibila ar fi introdusa de L2. -4. `ocautare.prg`, `EvalueazaRand` (`636-657`): ramura noua inaintea lui `Case Isnull(m.loStare)`, - pe clasa `'CNP'` — banda arata `Persoana fizica - CNP corect`, culoare NEUTRA - (`SeteazaLabel(..., .F., .T.)`), nu verde. - - De ce nu verde: verdele si formularea scurta stau in acelasi loc si in aceeasi culoare cu - confirmarea reala de la ANAF. O cifra de control nu este o verificare la ANAF. -5. `ocautare.prg`, `Detalii` (`799-804`): doua ramuri noi in `Iif`-ul imbricat: - - `'CNP'` -> `Persoana fizica - CNP corect.` - - `'COD_INVALID'` -> `Cod fiscal invalid - nu s-a interogat ANAF. Corectati codul in fisa partenerului.` - -Informativ, fara blocare si fara dialog de confirmare — cascada `RC_ANAF_VERIF_SELECTIE` ramane -neatinsa. - ---- - -# TRANSA 2 — L4: borderou eFactura, taxare inversa - -Nu se incepe inainte ca transa 1 sa fie in SVN. - -### Problema - -In borderoul eFactura, facturile primite cu taxare inversa apar gri (diferenta fata de registrul de -cumparari). In XML-ul eFactura taxarea inversa are TVA 0 (`ClassifiedTaxCategory/ID = 'AE'`), dar in -contabilitate se inregistreaza `4426 = 4427`, deci `jc2007.totctva` contine si acest TVA. Diferenta -rezultata e exact TVA-ul de taxare inversa si nu e o eroare reala. - -Importul face deja corectia inversa la generarea notelor (`anaf_efactura.vc2:12096-12106`), dar -numai `IF thisform.lPrimite`. - -### Decizie - -Corectia se face din datele contabile REALE, prin view-ul Oracle — nu prin recalcul cu cota -standard (care ar da gresit pe facturi mai vechi la 19%). Scope: DOAR facturi primite. - -**Coloana vizibila in grid NU se face.** Se livreaza doar corectia interna a expresiei `diferenta`. - -### Conditii de intrare (ambele obligatorii inainte de a scrie scriptul) - -1. **Trasare cap-coada** a unei facturi reale: linie XML cu `ClassifiedTaxCategory/ID = 'AE'` -> - `id_jtva_coloana` -> coloana din `jc2007`. Se confirma pe date ca acolo sta suma. -2. **Definitia curenta a lui `anaf_vefactura_trimis` se ia din `USER_VIEWS.TEXT` din schema tinta**, - nu din arhiva CLAR. - - Motiv: scriptul-model `2025\06\ff_2025_06_16_02_COMUN_EFACTURA.sql` redefineste NUMAI - `anaf_vefactura_primit` (`:3-53`). Corpul lui `anaf_vefactura_trimis` e in alt fisier, mai vechi - (`2024\08\ff_2024_08_22_01_COMUN_EFACTURA.sql:63-112`); cele doua au divergat cu ~10 luni si - exista 10 scripturi in arhiva care il redefinesc. Cine il rescrie "dupa model" luand fisierul - gresit revine tacut la o versiune veche a view-ului. - -### Modificari - -**1. Script de migrare nou**, in `D:\ROA\DATABASE\SCRIPTURI_CLAR\2026\07\` - -`create or replace view` pentru AMBELE view-uri, cu o coloana noua `jtva_ti`: - -- `anaf_vefactura_primit`: `jtva_ti` = suma coloanelor de TVA de taxare inversa din `jc2007`, cu - EXACT aceeasi potrivire ca cea folosita azi pentru `jtotctva` (an/luna/dataact/regexp pe numar act - si cod fiscal emitent). -- `anaf_vefactura_trimis`: `jtva_ti` = constanta `0`. La facturi emise nu se inregistreaza nota - contabila de TVA pentru taxare inversa, deci `diferenta` de acolo ramane identica cu azi. - - Coloana e obligatorie in AMBELE: `import_efactura.prg:40` foloseste `FROM <>`, un - singur SELECT pentru ambele view-uri (`lcTabel` setat la `:27`). Fara ea, borderoul de facturi - TRIMISE crapa cu ORA-00904. - -**Lista de coloane** — CORECTATA 28.07.2026, verificata pe `USER_TAB_COLUMNS`. - -Expresia din `Programe\oproceduri_decont.prg:8670` NU se poate copia: e scrisa peste view-ul -`VJC2025` (`FROM VJC2025 J`, `:8677`), nu peste tabela. In acel view `ti19t` si `ti09t` sunt -ALIASURI calculate (`SUM(ti19bct+ti19bvt+ti19bft) as ti19t`, `SUM(ti09bvt+ti09bft) as ti09t`). -**Pe `jc2007` coloanele `TI19T` si `TI09T` nu exista.** Un `create or replace view` care le -foloseste direct pica cu `ORA-00904` — si, cum acelasi script redefineste si -`anaf_vefactura_trimis`, ar rupe borderoul pe AMBELE sensuri. - -Lista corecta pe `jc2007` are **13 termeni**, nu 10 (`TI09` nu are varianta `BC`, asimetric fata -de `TI19`): - -``` -NVL(j.TI21T,0)+NVL(j.TI11T,0)+NVL(j.TI24T,0)+NVL(j.TI20T,0) -+ NVL(j.TI19BCT,0)+NVL(j.TI19BVT,0)+NVL(j.TI19BFT,0) -+ NVL(j.TI09BVT,0)+NVL(j.TI09BFT,0) -+ NVL(j.XX21TIT,0)+NVL(j.XX11TIT,0)+NVL(j.XX19TIT,0)+NVL(j.XX9TIT,0) -``` - -Familia NU este `XX*TI*` singura. Importul eFactura trece prin `ProcentTva2IdJtva` -(definita in `COMUN\programe\oproceduri_comune.prg:5836`, doar apelata din -`anaf_efactura.vc2:12093`), care pentru cumparari cu taxare inversa da id-urile 216/218/141/145; -in `jtva_coloane`, 216 = 'TX. INV. 21%' -> `TI21B` (pereche 217 = `TI21T`), 218 = 'TX. INV. 11%' -> -`TI11B` (219 = `TI11T`). Coloanele `XX*TIT` sunt achizitii NON-CE, pe care importul eFactura nu le -scrie. Toate confirmate ca existente in `jc2007`: `TI21T`=217, `TI11T`=219 -(`2026\03\ff_2026_03_09_02_COMUN_PACK_CONTAFIN_10G_ROMCONSTRUCT.pck:4991-4993`), `XX19TIB`=192, -`XX19TIT`=193 (`2026\01\PACK_CONTAFIN_ROMCONSTRUCT...pck:4891-4892`). - -**Performanta:** `jtotctva` e deja un subselect corelat peste `jc2007` cu `REGEXP_SUBSTR` + -`REGEXP_REPLACE` in `WHERE` — neindexabil, scanare per rand. Un al doilea subselect identic pentru -`jtva_ti` ar dubla exact acest cost. Se scrie **un singur subselect care intoarce ambele sume**. - -Se pastreaza `EXEC pack_migrare.UpdateVersiune(...)` + `COMMIT`. Fisierul se scrie cu **CRLF**. -Se bumpeaza `versiune_db.txt`. Scriptul se incheie cu o verificare de obiecte invalide: view-urile -`anaf_vefactura_primit_detaliu` si `anaf_vefactura_trimis_detaliu` -(`2024\08\ff_2024_08_28_02_COMUN_EFACTURA.sql:84`, `:122`) sunt construite peste cele doua si se -recompileaza automat, dar invaliditatea trebuie sa nu treaca neobservata. - -**2. `COMUN\programe\import_efactura.prg` — o singura expresie** - -Linia `:36`: - -``` -NVL(total_cu_tva,0.00) - (NVL(jtotctva,0.00) - NVL(jtva_ti,0.00)) as diferenta -``` - -**`lcSchema` (`:31-33`) NU se modifica.** `jtva_ti` apare doar ca termen intr-o expresie, nu ca -coloana de iesire, deci numarul de coloane al cursorului ramane acelasi. `lcSchema` e o schema -**pozitionala** imperecheata cu `lcSelect` in `gencursor` (`:50`); orice coloana noua de iesire ar -cere modificarea ambelor, iar modificarea uneia singure ar strica intreg borderoul. - -**3. Degradare gratioasa la lipsa coloanei** - -Inainte de a construi `lcSelect`, se testeaza o data existenta coloanei (`SELECT jtva_ti FROM ... -WHERE 1=2` intr-un `TRY`, sau interogare pe `user_tab_columns`) si se construieste `lcSelect` cu sau -fara termenul `jtva_ti`. - -Motiv: exe-ul ajunge la client prin update automat, iar migrarea CLAR ruleaza pe alta cadenta. Fara -sonda, prima combinatie gresita da ORA-00904 si borderoul nu se deschide deloc, nici primite nici -trimise. Cu sonda, ordinea de livrare devine optimizare, nu conditie de functionare. - -Ordinea recomandata ramane: **scriptul se aplica INAINTE de build** — de scris in nota de release. - -**4. Ce NU se atinge** - -Colorarea ramane pe `diferenta <> 0` (`anaf_efactura.vc2:6020-6041` Page2 si `12790-12817` -`frm_import_efactura`) — se corecteaza doar sursa numarului. NU se inventeaza o a treia culoare: -randurile cu taxare inversa nu sunt de investigat, sunt corecte prin constructie, iar falsurile -pozitive omoara marcajul de exceptie. NU se ating Page1 / Page3 si filtrul `chkDiferente` -(`anaf_efactura.vc2:5347-5349`) — sunt facturi emise. Nu se editeaza niciun binar `.vcx`. - -### Limita cunoscuta, de consemnat - -O taxare inversa inregistrata la cota GRESITA face ca diferenta sa se anuleze reciproc si randul sa -devina alb. Fara coloana in grid nu mai exista nicio parghie vizuala pentru acest caz. E pretul -deciziei de a nu adauga coloana si trebuie sa fie scris, nu descoperit. - ---- - -# TRANSA 3 — L3: avertizare de exigibilizare TVA la salvarea notelor - -Ultima, singura. Nu se incepe inainte ca transele 1 si 2 sa fie in SVN. - -### Scopul lucrarii — ca sa nu se citeasca gresit - -Singura modificare de cod e in `COMUN\clase\omodificari.vc2`, in `inainte_de_do_termin` al celor -doua clase de formular de note: `frm_modific2007` (`:5001`) si `frm_modific2024` (`:13131`). - -**NU** se modifica `oproceduri_inchidere.prg`. **NU** se modifica `do_adauga_tva_exigibil`. -**NU** se genereaza nimic automat in afara butonului din dialog. - -`oproceduri_inchidere.prg` apare mai jos doar ca drum de test: exigibilizarea din meniu deschide -chiar `frm_modific2007` (`:902`, `Createobject([frm_modific2007], ...)`, cu titlul -'Exigibilizare TVA Incasare'), deci avertizarea se declanseaza si acolo fara ca cineva sa fi atins -acel fisier. - -### Conditie de intrare - -Cotele 21% si 11% in `pack_contab.defalca_tva_incasare` si `pack_contab.cauta_facturaTVAEx`. -Partial inchisa: exista suport 21%/11% in `2025\08\ff_2025_08_08_02_COMUN__PACK_CONTAB.sql` -(comentariu "creeaza_note_tva_incasare TVA 21%, 11%"). De confirmat pe date. - -### Ce exista deja (verificat) - -- `Command5` -> `Thisform.do_adauga_tva_exigibil()` (`omodificari.vc2:13776-13778`). - Captionul DIFERA intre clase: `:2643` = "Adauga nota TVA devenit exigibil" (`frm_modific2007`), - `:6923` = "Adauga TVA exigibilizat" (`frm_modific2024`). -- `do_adauga_tva_exigibil` (`:12483+`) lucreaza pe conditia - `ales and (scc = '4428' or scd = '4428' or id_factd > 0 or id_factc > 0)` (`:12509`). - **Nu contine nicio lista de cote** — lucreaza pe liniile notei si pe `proc_tva`, si deleaga - defalcarea Oracle-ului. Deci e agnostic la cota si functioneaza la 21%. -- `cmdSelect.Click` = "Selecteaza tot" (`:13640-13658`) — face doar `Replace All ales With .T.` -- Precedent identic ca forma in acelasi hook: avertizarea 4426-4428 (`:13165-13176`), cu - `amessagebox(..., 4+32, ...)` si `Return .F.` -- `tact` poarta `tipnota`, `id_fact`, `id_factd`, `id_factc`, `ales`, `id_act`. Cursorul e construit - de fiecare apelant, nu de `omodificari.vc2`. Codul insusi nu are incredere ca `tipnota` exista: - `:4752` si `:12847` folosesc `If TYPE('tact.tipnota') = 'N' AND ...` -- `Return .F.` din `inainte_de_do_termin` opreste salvarea: apelantul din `_frm_base.vc2` - (`PROCEDURE do_termin`) nu face Release/Hide si **nu seteaza `buton`/`gnButon`**, iar toti - apelantii testeaza `If buton = 1` inainte de a scrie. Nicio subclasa a celor doua clase nu exista - in arbore, deci niciun override nu poate sari peste hook. - -### Modificari — algoritm - -**Pasul 0 — pozitionare in hook.** Verificarea se aseaza sub acelasi `IF m.llRet` ca avertizarea -existenta (`:13165`) si **dupa** `SELECT tact` / `SET FILTER TO` de la inceputul procedurii -(`:5001-5005`, `:13131-13135`). Altfel apare peste dialogul de eroare de la -`verificare_note_contabile`, sau filtrul gridului ii ascunde randuri. - -Ordinea dialogurilor la o singura apasare de Salvare: `verificare_note_contabile` -> avertizarea -4426-4428 -> avertizarea noua. Prima semnaleaza o greseala facuta, a doua o omisiune. - -**Pasul 0.5 — kill-switch.** Optiune implicit pornita. Daca e oprita: nicio avertizare, nicio -interogare, in tot produsul. L1/L2 stau deja in spatele `RC_ANAF_VERIF_SELECTIE`; L3 intra pe drumul -de salvare al intregii suite si nu are voie sa fie fara oprire. - -**Mecanismul — CORECTAT 28.07.2026.** NU se folosesc `Optiuni_FIRMA`/`Optiuni_PROGRAM.dbf` din -`DATE\`: acele tabele exista pe disc, dar nu sunt calea folosita si nu apar deloc in cod. Modelul de -urmat este chiar `RC_ANAF_VERIF_SELECTIE`, care are trei straturi (`ocautare.prg:255-285`, `:341-381`): - -1. kill-switch INI: `getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')`, doar `'0'` opreste; -2. optiuni Oracle (`optiuni` / `optiuni_util`), citite cu `citeste_optiune` / - `citeste_optiune_utilizator` din `oinit_optiuni.prg`, cu cache intr-o `Collection`; -3. UI = intrare de meniu (`Meniuri\CONT2000.MPR:210`, `ON SELECTION BAR ... DO ANAF_ComutaVerificare`), - nu ecran cu campuri DBF. - -**Pasul 0.6 — flag de lot.** Apelantii care instantiaza formularul in bucla seteaza un flag public -"rulez in lot", iar verificarea se sare. `anaf_efactura.vc2:12733` instantiaza `frm_modific2024` -**per factura importata**: un import de 150 de facturi ar insemna 150 de `AMESSAGEBOX` succesive -plus 150 de interogari Oracle sincrone. Acelasi lucru la `:12940` si `comun.vc2:2436`. - -**Pasul 1 — colectare.** Din `tact`, id-urile `id_factd` / `id_factc` > 0. Daca nu exista niciunul: -nimic, cost zero, fara interogare Oracle. - -**Pasul 2 — suprimarea platilor deja acoperite.** - -Regula: exista in `tact` o linie cu `tipnota = 1` SI `id_fact = `. - -Citirea lui `tipnota` se face prin `TYPE('tact.tipnota') = 'N'`, ca la `:4752` si `:12847` — -`tact` e construit de apelant, posibil din alt produs ROA. - -**Santinela `-5` NU intra in regula.** `do_adauga_tva_exigibil` scrie `-5` numai cand id-ul -facturii nu se poate rezolva (`:12531`, `:12542`, `:12551`, `:12559`), iar comentariul din cod spune -ce inseamna: "pun -5 ... ca sa-i completez id_fact la scrie_in_act" — adica **"de completat la -scriere"**, nu "rezolvat". Pentru liniile colectate la pasul 1 (`id_factd`/`id_factc` > 0) codul -scrie intotdeauna id-ul real, deci `-5` e imposibil prin constructie pe multimea urmarita. In -schimb, o disjunctie `SAU id_fact = -5` nu ar fi conditionata de id: o singura linie cu `-5` -oriunde in `tact` ar stinge avertizarea pentru TOATE platile din lot, tacut. - -Calificarea pe `tipnota = 1` se pastreaza: fara ea, excluderea ar prinde si notele MANUALE -`4426=4428` — exact cele despre care avertizarea existenta de la `:13165` spune ca sunt probabil -gresite. - -> Nota de reconciliere: o decizie intermediara a review-ului (D23) ceruse mutarea cheii de pe -> `tipnota` pe perechea de conturi, pe motiv ca notele generate de `inchidere_tva_sold` au -> `tipnota = 0` (`oproceduri_inchidere.prg:884`). Motivul a cazut: acel drum nu ajunge niciodata la -> regula, pentru ca `INSERT INTO actactan` (`:848-854`) nu completeaza `id_factd`/`id_factc`, deci -> pasul 1 nu colecteaza nimic. Cheia ramane pe `tipnota`, fara `-5`. - -**Pasul 3 — interogarea, fara lista IN.** - -O singura interogare `goExecutor`, care intoarce `id_fact`-urile cu `tva_incasare = 1` si sold -neexigibil `<> 0`. **Intersectia cu `tact` se face local, in VFP.** - -**Sursa — CORECTATA 28.07.2026.** Interogarea NU se poate scrie peste `jc2007` + `jv2007`: -**coloana `tva_incasare` nu exista pe cele doua tabele** (verificat pe `USER_TAB_COLUMNS`). Ea sta pe -`DOCUMENTE` (`id_doc = id_fact`) si pe view-urile `VJC2025` / `VJV2025`. Se interogheaza view-urile: -au deja tot ce trebuie (cotele, `tva_incasare`, `an`/`luna`, `id_fact`) si sunt exact ce foloseste -deja `pack_contab.cauta_facturaTVAEx`. Cele 14 coloane de cota de mai jos exista, in schimb, si pe -`jc2007`/`jv2007` — verificat. - -Nu se construieste lista `IN (...)`. Pragul Oracle de 1000 (ORA-01795) se atinge la utilizare -normala, nu la 10x: acelasi formular deserveste, dupa propriul caption, "Import extrase bancare, -deconturi curieri, procesatori plati" (`anaf_efactura.vc2:12941`), iar imperecherea se face linie cu -linie (`oproceduri_import.prg:729, 755, 782, 808`). Un extras obisnuit are 300-2000 linii/luna; un -decont de procesator, mult mai mult. Un singur SQL de lungime fixa elimina o clasa intreaga de esec -de pe drumul de salvare al intregii suite. - -**Formula de sold neexigibil** — NU se copiaza din registru. Filtrul existent la -`Clase\ovanzcump.vc2:38011` foloseste -`ro24nb+ro24nt+ro20nb+ro20nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt`, care OMITE cotele 21% si 11%, -in vigoare din august 2025 (`RO21NB/RO21NT/RO11NB/RO11NT`, id-uri 214/215, -`2025\07\ff_2025_07_21_01_COMUN_TVA21.sql:134-140`). Cu formula copiata, avertizarea nu s-ar -declansa NICIODATA pe o factura din 2025 incoace — exact pe facturile pentru care a fost ceruta. - -Lista corecta: -``` -ro24nb+ro24nt+ro20nb+ro20nt+ro21nb+ro21nt+ro11nb+ro11nt+ro19nb+ro19nt+ro9nb+ro9nt+ro5nb+ro5nt -``` - -**Robustete.** Verificarea ruleaza doar dupa ce `verificare_note_contabile` a trecut si doar cu -conexiune valida. Orice esec (tabela inexistenta in alt produs ROA, conexiune cazuta, timeout) -> -**se sare, cu linie in `goLog`**. Niciodata tacut: o verificare care moare invizibil e mai rea decat -una absenta, pentru ca nimeni nu afla ca nu mai merge. Esecul nu blocheaza salvarea. - -**Cum se obtine asta — PRECIZAT 28.07.2026, dupa citirea clasei.** `oexecutor` e in -`COMUN\programe\oproceduri_comune.prg:69-547`. Comportamentul real: - -- `oExecute()` NU arunca eroare VFP pe SQL esuat: intoarce `CT_INSUCCES` (-1). Deci nu urca la - `ON ERROR` global. `goLog.Log` se apeleaza pe toate drumurile de esec. Pana aici, cerinta e - indeplinita din oficiu. -- **DAR** pe eroare ODBC de conexiune cazuta (cod 1526 cu subcod 12152/3113/3114/12560/4068/28/12 — - exact cazul numit mai sus) se deschide un `amessagebox` "Doriti reconectare?" - (`oproceduri_comune.prg:390`) NECONDITIONAT de `tlShowError`, iar raspunsul "Nu" duce la `QUIT` — - **inchide aplicatia**, in mijlocul salvarii. Exact opusul cerintei. -- Deci apelul TREBUIE facut cu reconectarea dezactivata explicit. **Nu exista precedent**: din 150+ - apeluri `oExecute`/`oExecuta` din codebase, niciunul nu trece de 2 parametri. Tiparul se scrie - aici prima oara. -- Semnatura confirmata (`oproceduri_comune.prg:169`): - `oExecute(tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect)`. - `tlReconnect` e al **8-lea** parametru si are **implicit `.T.`** (comentariul din cod, `:175`), - deci trebuie pasat `.F.` EXPLICIT — altfel se obtine exact dialogul cu `QUIT`. - Atentie la parametrii 3-7 care trebuie completati ca sa se ajunga la al 8-lea: pentru fiecare, ia - din cod valoarea pe care codul o considera implicita cand parametrul lipseste, ca sa nu schimbi - din greseala alt comportament (in special `tnHandle` si `tlQuitOnError`). -- Se foloseste `oExecute`, NU `oExecuta` (aceasta din urma afiseaza mesaj propriu, neconditionat, pe - orice esec). Nu se adauga niciun `amessagebox` propriu. -- Nu exista niciun timeout Oracle configurat (`SQLSETPROP QueryTimeout`/`ConnectTimeout`) nicaieri: - un query agatat blocheaza la nesfarsit, nu doar da eroare. De avut in vedere la testare. - -**Pasul 4 — dialogul.** - -Trei butoane: - -``` -Exista plati/incasari pe facturi cu TVA la incasare pentru care nu s-a adaugat -nota de TVA exigibilizat. - -[Adauga acum] [Continua] [Anuleaza] -``` - -- **Adauga acum** — ruleaza `do_adauga_tva_exigibil` pe liniile deja identificate de interogare, - apoi continua salvarea. -- **Continua** — salveaza fara exigibilizare. -- **Anuleaza** — `Return .F.`, ramane in formular fara sa salveze. - -De ce buton si nu instructiune: sistemul stie deja care plati au nevoie de exigibilizare — asta e -chiar interogarea de la pasul 3. O modala care spune "du-te si apasa un buton" ar fi fost -inexecutabila in doua feluri: captionul difera intre cele doua clase (`:2643` vs `:6923`), iar -`Command5.Enabled` se calculeaza dupa **randul curent** (`:5661-5667`, `:13850`) si `cmdSelect.Click` -nu il recalculeaza — deci butonul poate fi gri exact dupa "Selecteaza tot". - -`` — **FIXAT 28.07.2026, marius.mutu: facturi DISTINCTE**, nu linii din `tact`. Actiunea pe care o -propune butonul e per factura, nu per linie: trei plati partiale pe aceeasi factura sunt o singura -factura de exigibilizat, si asa trebuie numarate. Textul dialogului se ajusteaza corespunzator -("Exista facturi cu TVA la incasare pentru care nu s-a adaugat nota de TVA exigibilizat"). - -**Pasul 5 — flag anti-bucla.** - -Proprietate de formular `lAvertizatExigibilizare`, setata dupa prima avertizare; a doua oara in -aceeasi sesiune de formular nu se mai avertizeaza. - -Motiv: cand `chkTVAEX` e bifat si linia e plata/incasare, `do_adauga_tva_exigibil` cheama -`creeaza_note_tva_incasare` (`:12598-12600`), unde `id_fact` vine din cursorul intors de -`pack_contab.defalca_tva_incasare` (`:12412`, `a.id_fact As id_fact`). Daca procedura nu intoarce -randuri, nu se insereaza nimic potrivit -> suprimarea nu prinde niciodata -> avertizare -> buton -> -avertizare -> buton (**dubland notele generate**) -> avertizare, fara iesire in afara de "Continua". -Ca "zero randuri" e un caz real: `oproceduri_inchidere.prg:843-848` il trateaza explicit. - -### Acoperire — drumuri de instantiere - -`frm_modific2007` / `frm_modific2024` sunt instantiate din: `ocont2003.prg:416, 1230, 1679, 2141`; -`oproceduri_incasari.prg:299`; `frm_import_extrase_banca.sc2:1652`; -`anaf_efactura.vc2:12733, 12940`; `frm_initializare_facturi_balanta.sc2:1803`; `comun.vc2:2436`; -`oproceduri_inchidere.prg:719, 902, 1007, 1438`; `frm_import_note_a4200.sc2:1651`; -`frm_import_note_facturi_clienti.sc2:895`; `ooperatii_comune.prg:1137`. - -Premisa "prinde si casa, si banca, si notele manuale" TINE. - -> Nota de metoda: `COMUN/` e in `.gitignore`, deci Grep/ripgrep il sare implicit. Cautarile de tip -> "cine apeleaza" se fac cu `rg --no-ignore` sau cu cale explicita, altfel intorc zero fals. - ---- - -# NU intra in scop (amanat, cu motiv) - -**Defectele din drumul de exigibilizare din meniu** (`inchidere_tva_sold`). De adaugat in TODOS.md -cu descrierea de mai jos, care **inlocuieste** formularea anterioara — aceea descria un defect -inexistent si ar fi trimis pe cine preia lucrarea catre o harta gresita. - -Ce este de fapt: - -1. `oproceduri_inchidere.prg:833` testeaza `Iif(m.lnCota = 21, m.lnSuma21, m.lnSuma11)` intr-o bucla - `For lnCota = 1 To 7` (`:829`). `lnCota` nu ajunge niciodata 21, deci `lnSuma21` e cod mort, iar - la `lnCota = 6` se ia soldul de 11% cu cota 1.21 (`:834`). Linia vecina `:837` o face corect - (`Iif(m.lnCota = 6, m.lnSuma21T, ...)`). Este o greseala de tipar `6` -> `21`. -2. `:802-803` citesc `soldn21` / `soldn11` neconditionat din `crsTVAIncasareTemp`. Aliasurile sunt - emise doar de formele 2025 (`ovanzcump.vc2:44220-44225`, `:55069-55073`). Pe formele 2010 - (`:39660`, `:51403`) nu exista -> eroare VFP 12, modala, la apasarea butonului. Exigibilizarea - din registru e rupta pe perioadele anterioare lui 2025. -3. `lnSuma21`, `lnSuma11`, `lnSuma20`, `lnSuma19` lipsesc din lista `Local` (`:770-773`) — devin - PRIVATE si se scurg in stiva de apel. - -Ce NU este: `ovanzcump.vc2:39660` nu "pierde 24/20"; e forma 2010, folosita pe perioade < 2025, al -carei cursor sursa `vjc2010`/`vjc2013` nu are deloc coloanele `ro21*`/`ro11*` (`oproceduri_decont.prg:18795-18801`), -deci acolo omisiunea e corecta. - -Nu afecteaza L3: butonul catre care trimite avertizarea L3 este `do_adauga_tva_exigibil`, care nu -foloseste nicio lista de cote. Sunt doua butoane diferite, pe doua drumuri diferite. - -**De scris in nota de release:** pe o factura cu TVA la incasare 21%, L3 avertizeaza corect, dar -utilizatorul care merge pe drumul din meniu (registru -> exigibilizare) gaseste lista goala. Butonul -din formular functioneaza. - -Alte lucruri amanate: -- Istoricul complet al atributului de TVA (mai multe perioade). ANAF v9 intoarce o singura perioada. -- Al doilea apel ANAF la data curenta ("era platitor la data documentului, dar nu mai este azi"). -- Persistarea totalului cu TVA de taxare inversa pe randul din `anaf_efactura` la import: nu ar - acoperi facturile deja importate; view-ul repara si istoricul. -- Derivarea listelor de cote din `jtva_coloane` in loc de enumerare in mai multe locuri. E cauza - radacina a defectelor gasite la L3 si L4. - ---- - -# Ce exista deja (si se reutilizeaza) - -| Sub-problema | Cod existent | Se reutilizeaza? | -|---|---|---| -| Perioada TVA de la ANAF | `ParseJsonANAFv8`, `validare.prg:2001-2114` | Da, integral. Se propaga, nu se parseaza din nou | -| Detectia discordantei ROA vs ANAF | `lDiscordanta`, `ocautare.prg:143` | Da. Nu se scrie detectie noua | -| Cache de sesiune | `goCacheANAF_Sesiune`, `ocautare.prg:127`, `:130` | Da, nemodificat | -| Validare CNP / CIF | `VALIDARE_CNP` / `VALIDARE_CIF`, apelate prin `ANAF_ValidareCod` la `:594` | Da, integral | -| Generarea notelor de exigibilizare | `do_adauga_tva_exigibil`, `omodificari.vc2:12483+` | Da (rulat din butonul dialogului) | -| Tiparul de avertizare in `inainte_de_do_termin` | `omodificari.vc2:13165-13176` | Da, se copiaza forma | -| Lista canonica de coloane TVA taxare inversa | `oproceduri_decont.prg:8670` | Da, se preia ca atare | - ---- - -# Reguli de livrare - -- Fiecare transa livreaza `docs\diff_runda_.patch`; write-back in binar - (`txt2vcx.ps1`) si commit DOAR dupa aprobare. Patch-urile nu se comit. -- Comentarii: o singura intrare cumulativa in antetul fisierului, `*!* DD.MM.YYYY` / - `*!* marius.mutu` / 1-2 fraze. Fara comentarii in corpul codului. La L2 (corectie de eroare) nu se - adauga comentariu. -- `ocautare.prg`, `validare.prg` si `omodificari.vc2` contin octeti cp1252 (0xBA). Orice scriere cu - Edit/Write ii corupe in `EF BF BD`. Se editeaza TOT ce e de editat, si abia DUPA ultima scriere se - verifica byte-level si se repara o singura data, luand octetul corect din `svn cat`. -- Scripturile `.sql` din SCRIPTURI_CLAR se scriu cu **CRLF**. -- `changelog_roacont.txt`: cate o intrare scurta per transa. L1/L3/L4 = `:nou:` sau `:modificare:`; - L2 = `:eroare:` (mesajul fals a ajuns la utilizatori). - ---- - -# Ce ramane neverificat - -Stare la 28.07.2026, dupa verificarea pe date (schema dev `MARIUSM_AUTO`). Detalii in -`docs\handoff_transa2_conditii.md`, `handoff_transa3_conditii.md`, `handoff_transa3_deschise.md`. - -- ~~Comportamentul `goExecutor` la timeout / conexiune cazuta~~ — INCHIS, vezi "Robustete" mai sus. -- ~~Daca `pack_contab.defalca_tva_incasare` poate intoarce `id_fact` null/0~~ — INCHIS. `id_fact` in - cursor e mereu parametrul trimis, deci nu poate fi null. Zero randuri ESTE posibil (filtrul final - poate exclude tot), si e chiar garantat pe drumul `omodificari.vc2:12547-12561`, unde santinela - `-5` ajunge ca parametru la `defalca_tva_incasare(-5, ...)`. **Flagul anti-bucla de la Pasul 5 e - confirmat necesar, nu preventiv.** -- ~~Cotele 21/11 in `pack_contab`~~ — INCHIS. `defalca_tva_incasare` deleaga la - `creeaza_note_tva_incasare`, care are `DECODE` explicit pe `id_jtva_coloana` 211/215 (JC) si 38/42 - (JV) pentru `RO21*`/`RO11*`; `cauta_facturaTVAEx` filtreaza si el pe `RO21NT`/`RO11NT`. - **Conditia de intrare a transei 3 e indeplinita.** -- Numarul real de linii pe un decont de curier/procesator — RAMANE DESCHIS pe cifra. Schema dev nu - are date reprezentative (`DECONT`: 2 randuri in toata baza; `EXTRAS CON`: p95 ~10 linii/lot, cu un - ordin de marime sub estimarea din plan, dar pe loturi de test, nu activitate reala). **Nu schimba - decizia**: o interogare unica de lungime fixa elimina `ORA-01795` indiferent de volum, deci nu - exista prag sub care lista `IN(...)` ar fi de preferat. -- Trasarea cap-coada a unei facturi cu linie `AE` (transa 2) — RAMANE DESCHISA pe date reale. - In schema dev NU exista nicio factura venita din import eFactura cu taxare inversa (`anaf_efactura`: - 487 randuri primite, 8 cu `id_fact`, zero suprapunere cu randuri `TI*` nenule). Mecanismul a fost - demonstrat numeric doar pe un caz construit din `jc2007` (`id_fact=8007136`, `ti19bft=19`, - `totctva=119`: diferenta falsa de -19 se anuleaza exact cu `jtva_ti`). **De consemnat in nota de - release**: verificarea finala ramane de facut pe prima factura reala de taxare inversa importata - dupa aplicarea scriptului. - ---- ---- - -# ANEXA — istoricul review-ului - -Nimic de implementat aici. Se pastreaza pentru trasabilitate. - -## Metoda - -Doua runde: `/autoplan` (CEO -> Design -> Eng) pe 27.07, apoi runda 2 cu trei voci independente -(subagenti fara context de review) confruntate cu verificare proprie pe cod. Codex indisponibil pe -masina, deci consensul e "voce independenta + verificare proprie", nu Claude/Codex. Faza DX sarita: -produsul nu e pentru dezvoltatori. - -## Afirmatii verificate pe cod - -CONFIRMATE: `ParseJsonANAFv8` pune datele in cursor (`validare.prg:2012`); `ANAF_VerdictDinCursor` -expune doar 5 campuri (`:1670-1675`); cache-ul pastreaza obiectul intreg (`ocautare.prg:127`, -`:130`); `tact` poarta campurile necesare (`omodificari.vc2:4496`, `:5661`, `:13166`); precedentul -de avertizare (`:13165-13172`); un singur SELECT pentru ambele view-uri (`import_efactura.prg:40`); -coloanele `TI21T`=217, `TI11T`=219, `XX19TIB`=192, `XX19TIT`=193; `lb_anaf` multi-rand -(`ocautare.prg:472-476`); localizarea defectului L2 in `Detalii` (`:648-650`, `:803`); -`Return .F.` opreste salvarea (`_frm_base.vc2`, `do_termin`). - -INFIRMATE: tipul coloanelor de perioada era declarat incert — sunt deja `D`; `mesaj` NU e -echivalent cu `mesaj_ScpTVA` (V(100) vs C(244)); santinela `-5` inseamna "de completat la scriere", -nu "rezolvat"; capcana `inchidere_tva_sold` e evitata prin `id_factd`/`id_factc` necompletate, nu -prin `tipnota`; defectul de cote amanat era descris gresit. - -## Decizii - -D1-D21 (runda 1, `/autoplan`): mod SELECTIVE EXPANSION; lista de coloane `TI*`+`XX*TI*`; coloana in -ambele view-uri; conditie de intrare prin trasare cap-coada; lista de cote cu 21/11; defect -preexistent semnalat nu reparat; texte distincte pentru sfarsit vs anulare; log pe parsare esuata; -eliminarea ramurilor inaccesibile din L2; corectarea localizarii defectului L2; data lipita de -stare; banda multi-rand; interval pentru perioada inchisa; `Pemstatus`; defectul L2 mai larg -(`:600`); banda neutra pentru CNP; regula de suprimare pe `tipnota`; `jtva_ti` coloana vizibila; -fara a treia culoare; ordinea DB-inainte-de-exe. - -D22-D33 (runda 2): N1 `mesaj_ScpTVA` in loc de `mesaj` (rastoarna D7); N2/N3/N4/N5/N6/N7; -`4+32+256`; conditie de intrare pe `pack_contab`; rescrierea textului amanarii. - -D34-D37 (poarta, marius.mutu): trei livrari separate, fixurile N7 raman amanate cu text rescris; -L3 cu buton de actiune in dialog; L4 fara coloana vizibila; L1 cu data si la `lDiscordanta`. - -Contradictie rezolvata la consolidare: D23 (cheia de suprimare pe perechea de conturi) cade in -favoarea E.2 (`tipnota = 1 AND id_fact`, fara `-5`) — motivul lui D23 a disparut odata cu E.3. - -Deciziile D36 si D37 au dizolvat trei constatari: N5, K-1 si N6 nu mai au obiect fara coloana -vizibila; N3 si N4 nu mai au obiect cu butonul in dialog. - -## Teme transversale - -**Tema 1 — "corect pe hartie, inexecutabil de utilizator".** Trei constatari independente (caption -diferit, buton conditionat de randul curent, coloana invizibila din cauza preferintelor de grid) au -avut aceeasi forma. Toate trei au fost eliminate prin deciziile de la poarta. - -**Tema 2 — planul verifica listele de cote in VFP si nu deschide niciun pachet Oracle.** De aici -conditia de intrare pe `pack_contab` pentru transa 3.