Merge claude/anaf-tva-efactura: registre 2025, exigibilizare TVA, verificare ANAF

This commit is contained in:
2026-07-28 15:12:58 +03:00
6 changed files with 52 additions and 997 deletions

3
.gitignore vendored
View File

@@ -104,5 +104,6 @@ roacont_ref.FPT
# --- COMUN este gestionat separat, prin propriul sau git (romfast/comun.git) --- # --- COMUN este gestionat separat, prin propriul sau git (romfast/comun.git) ---
COMUN/ COMUN/
docs/diff_runda*.patch docs/diff_*.patch
.gstack/ .gstack/
docs/local/

View File

@@ -20865,7 +20865,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
SET STEP ON
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -21063,7 +21062,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -21274,7 +21272,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -21485,7 +21482,6 @@ DEFINE CLASS frm_deconttva AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -22921,7 +22917,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
SET STEP ON
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -23119,7 +23114,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -23330,7 +23324,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -23541,7 +23534,6 @@ DEFINE CLASS frm_deconttva_201601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -25155,7 +25147,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
SET STEP ON
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -25353,7 +25344,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -25564,7 +25554,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -25775,7 +25764,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -25997,7 +25985,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -26221,7 +26208,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -26425,7 +26411,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -26631,7 +26616,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -26835,7 +26819,6 @@ DEFINE CLASS frm_deconttva_201701 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -28466,7 +28449,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
SET STEP ON
lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(NVL(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -28664,7 +28646,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -28875,7 +28856,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -29086,7 +29066,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -29308,7 +29287,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -29532,7 +29510,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -29736,7 +29713,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -29942,7 +29918,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" lcPrenumeDeclarant = ""
@@ -30146,7 +30121,6 @@ DEFINE CLASS frm_deconttva_202601 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
Set Date To Ymd Set Date To Ymd
Set Mark To '-' Set Mark To '-'
Set Step On
lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,'')) lcNumePrenumeDeclarant = Alltrim(Nvl(gofirma.declarant,''))
lcNumeDeclarant = lcNumePrenumeDeclarant lcNumeDeclarant = lcNumePrenumeDeclarant
lcPrenumeDeclarant = "" 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 ; *!* 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,'')) ) *!* (Select Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') From cListRC WHERE !EMPTY(NVL(denumire,'')) )
*!* Endif *!* Endif
SET STEP ON
WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT
*** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE) *** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE)
TEXT to m.lcSql textmerge noshow TEXT to m.lcSql textmerge noshow
@@ -42642,14 +42615,14 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
from vjc2010 from vjc2010
where an = <<m.gnAn>> where an = <<m.gnAn>>
and luna = <<m.gnLuna>> and luna = <<m.gnLuna>>
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) and tva_incasare = 1)
group by id_fact, cont) ip group by id_fact, cont) ip
on jc.id_fact = ip.id_fact on jc.id_fact = ip.id_fact
where jc.an = <<m.gnAn>> where jc.an = <<m.gnAn>>
and jc.luna = <<m.gnLuna>> and jc.luna = <<m.gnLuna>>
and jc.tva_incasare = 1 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 and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0
ENDTEXT 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)) lcWhere = Alltrim(Substr(m.lcWhere, m.lnPos + 11))
Endif Endif
Endif Endif
SET STEP ON
Do Case Do Case
Case m.lnTipJurnal = 1 Case m.lnTipJurnal = 1
pcSubtitlu = "Achizitii de bunuri si prestari de sevicii taxabile din tara" 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 ; *!* 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,'')) ) *!* (Select Padl(nract,14,'0') + '|' + Dtos(dataact) + '|' + Padr(denumire,100,' ') From cListRC WHERE !EMPTY(NVL(denumire,'')) )
*!* Endif *!* Endif
SET STEP ON
WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT WAIT WINDOW 'TVA exigibilizat din plati facturi cu TVA Incasare' NOWAIT
*** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE) *** ADAUG TVA INCASARE (DIN INCASARI/PLATI, TVA 4427 LA 90 ZILE)
TEXT to m.lcSql textmerge noshow 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 JTVA_COLOANE J2 On J.id_jtva_coloana = J2.id_tva
left join nom_fdoc fdoc on a.id_fdoc = fdoc.id_fdoc 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 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 ORDER BY a.cod, J2.COLOANA_JC
ENDTEXT ENDTEXT
@@ -44214,7 +44185,6 @@ DEFINE CLASS frm_regcump2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
*!* 25.08.2014 *!* 25.08.2014
*!* marius.mutu *!* marius.mutu
*!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0 *!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0
SET STEP ON
Local lcXMLFacturi Local lcXMLFacturi
If !(luna_inchisa Or m.glEMama) If !(luna_inchisa Or m.glEMama)
Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO09NB+RO05NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO09NT+RO05NT) as soldn, ; 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 ENDPROC
PROCEDURE do_excel 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 do export_excel_grid WITH thisform._grdbase1,"dataact, nract", "", this.lb_titlu_alb_b121.caption IN proceduri_excel.prg
return return
@@ -50521,7 +50490,6 @@ DEFINE CLASS frm_regvanz2010 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
update_jtva_coloane('JV') update_jtva_coloane('JV')
*** SELECTEZ FACTURILE CU TVA_INCASARE CU TOTAL BAZA, TVA, BAZAN, TVAN *** 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, ; 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, ; (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, ; (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 *!* 25.08.2014
*!* marius.mutu *!* marius.mutu
*!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0 *!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0
SET STEP ON
Local lcXMLFacturi Local lcXMLFacturi
If !(luna_inchisa Or m.glEMama) If !(luna_inchisa Or m.glEMama)
Select *, (RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ; 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, select jv.id_fact,
ip.cont, ip.cont,
nvl(ip.sold, 0) as soldf, nvl(ip.sold, 0) as soldf,
(RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as soldn, (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as soldn,
nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as solddif, nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) as solddif,
jv.denumire, jv.denumire,
jv.nract, jv.nract,
jv.serie_act, jv.serie_act,
@@ -53830,6 +53797,10 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
jv.RO11nt, jv.RO11nt,
jv.RO21nb, jv.RO21nb,
jv.RO21nt, jv.RO21nt,
jv.RO20nb,
jv.RO20nt,
jv.RO24nb,
jv.RO24nt,
jv.ro19nb, jv.ro19nb,
jv.ro19nt, jv.ro19nt,
jv.ro9nb, jv.ro9nb,
@@ -53849,15 +53820,15 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
from vjv2010 from vjv2010
where an = <<m.gnAn>> where an = <<m.gnAn>>
and luna = <<m.gnLuna>> and luna = <<m.gnLuna>>
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) and tva_incasare = 1)
group by id_fact, cont) ip group by id_fact, cont) ip
on jv.id_fact = ip.id_fact on jv.id_fact = ip.id_fact
where jv.an = <<m.gnAn>> where jv.an = <<m.gnAn>>
and jv.luna = <<m.gnLuna>> and jv.luna = <<m.gnLuna>>
and jv.tva_incasare = 1 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 (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 + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0 and nvl(ip.sold, 0) - (RO11nb + RO11nt + RO21nb + RO21nt + RO20nb + RO20nt + RO24nb + RO24nt + ro19nb + ro19nt + ro9nb + ro9nt + ro5nb + ro5nt) <> 0
ENDTEXT ENDTEXT
llSucces = goExecutor.oExecuta(m.lcSql, "crsSoldDif") llSucces = goExecutor.oExecuta(m.lcSql, "crsSoldDif")
@@ -53888,7 +53859,6 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
ENDPROC ENDPROC
PROCEDURE do_excel 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 do export_excel_grid WITH thisform._grdbase1,"dataact, nract", "", this.lb_titlu_alb_b121.caption IN proceduri_excel.prg
return 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 JTVA_COLOANE J2 On J.id_jtva_coloana = J2.id_tva
left join nom_fdoc fdoc on a.id_fdoc = fdoc.id_fdoc 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 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 order by a.cod, J2.COLOANA_JC
ENDTEXT ENDTEXT
@@ -55063,7 +55033,6 @@ DEFINE CLASS frm_regvanz2025 AS _frmbase OF "..\comun\clase\_frm_base.vcx"
*!* 25.08.2014 *!* 25.08.2014
*!* marius.mutu *!* marius.mutu
*!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0 *!* se transmit si soldurile pe cote de TVA 24,9,5 pentru cazul in care soldul total este 0
SET STEP ON
Local lcXMLFacturi Local lcXMLFacturi
If !(luna_inchisa Or m.glEMama) If !(luna_inchisa Or m.glEMama)
Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ; Select *, (RO11NB+RO21NB+RO24NB+RO20NB+RO19NB+RO9NB+RO5NB + RO11NT+RO21NT+RO24NT+RO20NT+RO19NT+RO9NT+RO5NT) as soldn, ;

View File

@@ -771,7 +771,7 @@ Procedure inchidere_tva_sold
Local lnIdSet, lnNrAct, lnProcTVA, lnRecords, lnSucces, lnSuma, loAct Local lnIdSet, lnNrAct, lnProcTVA, lnRecords, lnSucces, lnSuma, loAct
Local lnCota, lnCotaTVA, lnSuma24, lnSuma5, lnSuma9, lnSumaT Local lnCota, lnCotaTVA, lnSuma24, lnSuma5, lnSuma9, lnSumaT
Local lnSuma24T, lnSuma5T, lnSuma9T, lnSumaNT, lcMesaj 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 lcJurnal = Upper(Alltrim(m.tcJurnal)) && JC/JV
If m.lcJurnal = 'JC' && Jurnal Cumparari If m.lcJurnal = 'JC' && Jurnal Cumparari
lcSCD = '4426' lcSCD = '4426'
@@ -788,7 +788,6 @@ SET STEP ON
lcMesaj = '' lcMesaj = ''
lnIdSet = 99999 && nota fara predefinire lnIdSet = 99999 && nota fara predefinire
lnBut = lans(m.lnIdSet) lnBut = lans(m.lnIdSet)
Set Step On
If m.lnBut = 1 If m.lnBut = 1
Select actactan Select actactan
Scatter Name loAct Scatter Name loAct
@@ -799,8 +798,18 @@ SET STEP ON
lnNrAct = crsTVAIncasareTemp.nract lnNrAct = crsTVAIncasareTemp.nract
lnIdFact = crsTVAIncasareTemp.id_fact lnIdFact = crsTVAIncasareTemp.id_fact
lnSumaT = soldn lnSumaT = soldn
lnSuma21 = soldn21 lnSuma21 = 0
lnSuma11 = soldn11 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 lnSuma24 = soldn24
lnSuma20 = soldn20 lnSuma20 = soldn20
@@ -809,16 +818,12 @@ SET STEP ON
lnSuma5 = soldn5 lnSuma5 = soldn5
If m.lcJurnal = 'JC' && Jurnal Cumparari If m.lcJurnal = 'JC' && Jurnal Cumparari
lnSuma21T = ro21nt
lnSuma11T = ro11nt
lnSuma24T = ro24nt lnSuma24T = ro24nt
lnSuma20T = ro20nt lnSuma20T = ro20nt
lnSuma19T = ro19nt lnSuma19T = ro19nt
lnSuma9T = ro09nt lnSuma9T = ro09nt
lnSuma5T = ro05nt lnSuma5T = ro05nt
ELSE ELSE
lnSuma21T = ro21nt
lnSuma11T = ro11nt
lnSuma24T = ro24nt lnSuma24T = ro24nt
lnSuma20T = ro20nt lnSuma20T = ro20nt
lnSuma19T = ro19nt lnSuma19T = ro19nt
@@ -830,7 +835,7 @@ SET STEP ON
lnSuma = m.lnSumaT lnSuma = m.lnSumaT
lnCotaTVA = 0.00 lnCotaTVA = 0.00
If m.lnSumaT = 0 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)))))) 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 Endif

View File

@@ -1,7 +1,28 @@
<!-- <!--
27/07/2026 28/07/2026
ROACONT - 2.11.66 ROACONT - 2.11.66
:modificare:
Borderou eFactura, facturi primite. Facturile cu taxare inversa nu mai apar colorate ca avand diferenta fata de contabilitate. In eFactura taxarea inversa are TVA zero, dar in contabilitate se inregistreaza 4426 = 4427, iar diferenta afisata tine cont acum de acest TVA. Necesita actualizarea bazei de date.
:nou:
Note contabile. La salvarea notei, programul verifica incasarile si platile care au factura pereche completata si avertizeaza daca pentru vreuna dintre facturile cu TVA la incasare nu s-a adaugat nota de TVA exigibilizat. Notele de TVA exigibilizat se pot adauga pe loc. Verificarea poate fi oprita din settings.ini, sectiunea [tva], avertizare_exigibilizare=0.
:modificare:
Alegere partener. Starea de TVA de la ANAF arata si de cand este valabila, cu eticheta care spune ce reprezinta perioada: inregistrat TVA de la o data pana la alta, sau cod TVA anulat din data. In lista, perioada apare doar cand starea difera de nomenclator, partenerul este inactiv sau perioada s-a incheiat deja; tasta F4 arata intotdeauna perioada completa si mesajul primit de la ANAF, inclusiv atunci cand nu exista niciun partener cu codul fiscal corect.
:modificare:
Initializari > Optiuni utilizator > "Verificare ANAF la alegerea partenerului". Mesajul cu setarea curenta intreaba acum daca doriti sa o modificati, iar la raspunsul Nu setarea ramane neschimbata. Cand verificarea este oprita de pe calculatorul curent, se propune tot oprirea locala, nu valoarea care ar fi oprit verificarea pentru utilizator pe orice calculator.
:eroare:
Registrele de cumparari si vanzari, incepand cu 01.08.2025. Filtrul "Diferenta sold" si lista TVA-ului exigibilizat din plati nu luau in calcul facturile cu TVA neexigibil la 24% sau 20%, deci facturile mai vechi cu TVA la incasare lipseau din rezultate.
:eroare:
Exigibilizare TVA la incasare din Registrul de cumparari/vanzari. Butonul dadea eroare pe perioadele anterioare anului 2025, iar cota de 21% nu era luata in calcul la impartirea soldului pe cote.
:eroare:
Alegere partener. La codurile numerice de 13 cifre (CNP) si la codurile fiscale invalide, detaliile verificarii (F4) spuneau gresit "ANAF nu a raspuns - verificarea a fost sarita". Acum se afiseaza "Persoana fizica - CNP corect", respectiv "Cod fiscal invalid - nu s-a interogat ANAF".
:nou: :nou:
D406 SAF-T. La validarea cu erori se deschide si un fisier de erori pe intelesul utilizatorului: pentru fiecare eroare - pagina, pozitia, partenerul sau contul in cauza si cum se rezolva. Erorile fictive "Cod taxa nu se afla in lista" (bug al validatorului ANAF) sunt separate la sfarsit si se pot ignora. D406 SAF-T. La validarea cu erori se deschide si un fisier de erori pe intelesul utilizatorului: pentru fiecare eroare - pagina, pozitia, partenerul sau contul in cauza si cum se rezolva. Erorile fictive "Cod taxa nu se afla in lista" (bug al validatorului ANAF) sunt separate la sfarsit si se pot ignora.
--> -->

View File

@@ -1,941 +0,0 @@
<!-- /autoplan restore point: /c/Users/mmari/.gstack/projects/ROACONT/claude-partener-anaf-autoplan-restore-20260726-165226.md -->
# 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/<subiect>)
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. <denumire> 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 `<TOATE INREGISTRARILE>` 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 <cod>..."), 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).

View File

@@ -1 +1 @@
2026_07_26_02 2026_07_28_01