Files
comun/utile/Teste/partener_anaf/test_e2e_anaf_firma.prg
Marius Mutu 019d241e50 teste ANAF: verificari pentru preluarea codului CAEN si a reviziei
Testul sintetic acopera CaenAnaf (completarea zeroului din fata, valori
neplauzibile) si CaenRevizie (format nou/vechi de numar de registru): 42 -> 53
verificari. Proba e2e goleste caen/caen_revizie inainte de rulare si le
verifica dupa, cu contoare SEPARATE de judet/localitate ca cifrele masurate in
rundele anterioare sa ramana comparabile. Mock-ul de dialog expune acum si
codul CAEN si numarul de registru brute de la ANAF.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015husoVS24ewJZr21ZoVR3v
2026-08-23 21:22:56 +03:00

338 lines
14 KiB
Plaintext

* test_e2e_anaf_firma.prg
* Proba END-TO-END pentru todo #22 (preluare date ANAF la datele firmei), pe traseul REAL:
* formularul frm_firme_nou_desktopf + Click pe But_verifica1 -> anaf_completeaza_firma ->
* verifica_partener (apel ANAF live) -> ParseAdresaAnaf/FaraPrefixLoc -> AnafNomenclator ->
* Ct_localitate1.modifica_judet / modifica_localitate, peste nomenclatorul Oracle REAL.
*
* Ce acopera in plus fata de test_anaf_nomenclator.prg: acela ruleaza potrivirea pe cursoare
* SINTETICE, in afara formularului. Aici cursoarele sunt cele construite de ct_localitate din
* syn_vnom_judete / syn_vnom_localitati (inclusiv randul-santinela "<ALEGETI ...>"), iar
* apasarea e pe butonul real - conform regulii: testele pe frontend exerseaza fluxul real,
* nu populeaza direct cursoarele.
*
* ATENTIE (1): foloseste test_init_env_auto_ROADEF, nu test_init_env_auto.prg. Acela porneste pe
* D:\ROA\ROACONT\, alt working copy de COMUN, fara modificarile necomise de aici - ar testa
* codul vechi si ar da rezultate false.
* ATENTIE (2): tot codul care construieste obiecte sta INLINE in programul principal, nu in
* proceduri (capcana l din COMUN\docs\testare-ui-vfp.md), iar TRY/CATCH nu contine RETURN
* (VFP9: eroare 2060 "RETURN/RETRY statement not allowed in TRY/CATCH").
*
* Rulare headless (nu tine VFP IDE sau roadef.exe deschis):
* Remove-Item <acest .prg cu extensia .fxp> -Force
* & "C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe" -A -T ;
* "D:\ROA\ROADEF\COMUN\utile\Teste\partener_anaf\test_e2e_anaf_firma.prg"
* Log: test_e2e_anaf_firma_log.txt, langa acest fisier.
*
* Numarul de coduri fiscale rulate: gnE2ELimita (implicit 8). Codurile vin din
* ..\cache_anaf\codes_200_reale.txt (coduri reale). Fiecare cod = un apel ANAF live.
SET SAFETY OFF
SET TALK OFF
PUBLIC gcLogE2E, gnOk, gnEsec, gnSarite, gnE2ELimita, goNomE2E, ;
gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip, ;
gnMockRaspunsShowInfo, gnMockShowInfoApeluri, ;
gcMockAnafJudet, gcMockAnafLocalitate, gcMockAnafAdresa, gcMockAnafFirma, ;
gcMockAnafCaen, gcMockAnafRegCom, gnCaenOk, gnCaenLipsa, gnRevizie3
gcLogE2E = ADDBS(JUSTPATH(SYS(16, 0))) + 'test_e2e_anaf_firma_log.txt'
IF EMPTY(JUSTPATH(SYS(16, 0)))
gcLogE2E = 'D:\ROA\ROADEF\COMUN\utile\Teste\partener_anaf\test_e2e_anaf_firma_log.txt'
ENDIF
gnOk = 0
gnEsec = 0
gnSarite = 0
gnCaenOk = 0
gnCaenLipsa = 0
gnRevizie3 = 0
* cate coduri se ruleaza: implicit 8, sau variabila de mediu E2E_LIMITA (ex. 200 pentru
* o masuratoare completa) - vfp9.exe nu poate primi parametri pentru scriptul din -T
gnE2ELimita = IIF(VAL(GETENV('E2E_LIMITA')) > 0, INT(VAL(GETENV('E2E_LIMITA'))), 8)
goNomE2E = .NULL.
gnMockRaspuns = 6 && "Da" la dialogurile amessagebox
gcMockUltimMesaj = '' && mock_amessagebox memoreaza aici textul ultimului dialog
gnMockUltimTip = 0
gnMockRaspunsShowInfo = 6 && "Da" la "Doriti sa se completeze datele in formular?"
gnMockShowInfoApeluri = 0
* datele BRUTE de la ANAF, depuse de mock_verifica_partener_show_info INAINTE de potrivire
gcMockAnafJudet = ''
gcMockAnafLocalitate = ''
gcMockAnafAdresa = ''
gcMockAnafFirma = ''
gcMockAnafCaen = ''
gcMockAnafRegCom = ''
STRTOFILE('START test_e2e_anaf_firma ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLogE2E)
ON ERROR DO E2EErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
* ===== mock-urile de dialoguri, INAINTEA fisierelor aplicatiei =====
* La nume duplicat de FUNCTION, VFP foloseste fisierul cautat PRIMUL
* (COMUN\docs\testare-ui-vfp.md capcana g). Incarcate DUPA mediu, dialogurile raman modale
* si rularea headless se blocheaza pe primul CIF (masurat: proba s-a oprit pe 10117033).
SET PROCEDURE TO D:\ROA\ROADEF\COMUN\utile\Teste\partener_anaf\mock_verifica_partener_show_info.prg ADDITIVE
SET PROCEDURE TO D:\ROA\ROADEF\COMUN\utile\Teste\mock_amessagebox.prg ADDITIVE
* ===== mediu =====
DO D:\ROA\ROADEF\COMUN\utile\Teste\test_init_env_auto_roadef.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF TYPE('gnHandle') <> 'N' OR gnHandle <= 0
DO E2ELog WITH 'EROARE: conectare Oracle esuata, gnHandle=' + TRANSFORM(IIF(TYPE('gnHandle') = 'N', gnHandle, -1))
DO E2ELog WITH 'REZULTAT: NEDETERMINAT'
QUIT
ENDIF
DO E2ELog WITH 'mediu OK: gcS=' + gcS + ' gnIdFirma=' + TRANSFORM(gnIdFirma) + ;
' gnScrieRegistru=' + TRANSFORM(gnScrieRegistru) + ' gcNumeProgram=' + gcNumeProgram
* ===== dovada 1: rulam pe COMUN-ul din ROADEF, cu fixul din todo #22 =====
LOCAL llAreFix, loEx AS Exception
llAreFix = .F.
TRY
goNomE2E = CREATEOBJECT('AnafNomenclator')
llAreFix = (VARTYPE(goNomE2E) = 'O')
CATCH TO loEx
llAreFix = .F.
ENDTRY
DO E2ELog WITH 'AnafNomenclator disponibil: ' + IIF(m.llAreFix, 'DA', 'NU')
IF !m.llAreFix
DO E2ELog WITH 'REZULTAT: NEDETERMINAT - s-a incarcat un COMUN fara fixul din todo #22'
QUIT
ENDIF
* ===== dovada 2: mock-ul de dialog a castigat =====
* Cu obiect gol, functia REALA moare la loPartener.platitortvamfin inainte de amessagebox;
* mock-ul intoarce 6 fara sa deschida nimic. Daca nu castiga, rularea s-ar bloca pe primul modal.
LOCAL loDummyE2E, lnProbaMock
loDummyE2E = CREATEOBJECT('empty')
lnProbaMock = -1
TRY
lnProbaMock = verifica_partener_show_info(m.loDummyE2E, '0', '', 'proba mock')
CATCH TO loEx
lnProbaMock = -2
ENDTRY
gnMockShowInfoApeluri = 0
DO E2ELog WITH 'mock verifica_partener_show_info activ: ' + ;
IIF(m.lnProbaMock = 6, 'DA', 'NU (raspuns ' + TRANSFORM(m.lnProbaMock) + ')')
IF m.lnProbaMock <> 6
DO E2ELog WITH 'REZULTAT: NEDETERMINAT - fara mock, primul dialog modal blocheaza rularea headless'
QUIT
ENDIF
* ===== firma curenta, ca in oproceduri_roadef.viz_firme =====
LOCAL lcSqlFirma
lcSqlFirma = [select * from syn_v_nom_firme where sters = 0 and id_firma = ] + ALLTRIM(STR(goFirma.id_firma))
IF !goExecutor.oExecuta(m.lcSqlFirma, 'crsFirmaE2E') OR RECCOUNT('crsFirmaE2E') = 0
DO E2ELog WITH 'EROARE: nu am putut citi firma curenta (' + m.lcSqlFirma + ')'
DO E2ELog WITH 'REZULTAT: NEDETERMINAT'
QUIT
ENDIF
SELECT crsFirmaE2E
GO TOP
DO E2ELog WITH 'firma de lucru: id_firma=' + TRANSFORM(id_firma) + ' [' + ALLTRIM(NVL(firma, '')) + ']'
* ===== lista de coduri fiscale reale =====
LOCAL lcFisCoduri, lnTotalCoduri, lnI, lcCod
LOCAL ARRAY laCoduri[1]
* lotul de coduri: implicit cel de 200, sau variabila de mediu E2E_CODURI (cale completa)
lcFisCoduri = ALLTRIM(GETENV('E2E_CODURI'))
IF EMPTY(m.lcFisCoduri)
lcFisCoduri = 'D:\ROA\ROADEF\COMUN\utile\Teste\cache_anaf\codes_200_reale.txt'
ENDIF
IF !FILE(m.lcFisCoduri)
DO E2ELog WITH 'EROARE: lipseste ' + m.lcFisCoduri
DO E2ELog WITH 'REZULTAT: NEDETERMINAT'
QUIT
ENDIF
lnTotalCoduri = ALINES(laCoduri, FILETOSTR(m.lcFisCoduri))
DO E2ELog WITH 'lot: ' + m.lcFisCoduri
DO E2ELog WITH 'coduri disponibile: ' + TRANSFORM(m.lnTotalCoduri) + ', rulez primele ' + TRANSFORM(gnE2ELimita)
DO E2ELog WITH REPLICATE('-', 110)
* ===== rulare: un cod fiscal = un formular nou + un Click pe butonul real =====
* Totul inline (capcana l): CREATEOBJECT pe formular dintr-o procedura e nesigur headless.
PRIVATE poRec
LOCAL lnRulate, loFrm, llFrmOk, llClickOk, lcErr
LOCAL lcAdrAnaf, lcJudAnaf, lcLocAnaf, lcJudet, lcLoc, lnIdJudet, lnIdLoc
LOCAL llOkJud, llOkLoc, lcDetaliu
lnRulate = 0
FOR lnI = 1 TO m.lnTotalCoduri
lcCod = ALLTRIM(laCoduri[m.lnI])
IF !EMPTY(m.lcCod) AND ISDIGIT(m.lcCod) AND m.lnRulate < gnE2ELimita
lnRulate = m.lnRulate + 1
* record proaspat pentru fiecare cod, direct din cursorul firmei (ca in viz_firme:
* Select v_firme / Scatter Name loRec), ca sa nu ramana stare de la codul anterior.
* Plasa: _frm_base.Destroy face USE IN (SELECT(thisform.ccursor)) si, cu ccursor gol,
* poate inchide zona de lucru curenta - refacem cursorul daca s-a pierdut.
IF !USED('crsFirmaE2E')
IF !goExecutor.oExecuta(m.lcSqlFirma, 'crsFirmaE2E')
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> ESEC: nu am putut reface crsFirmaE2E'
gnEsec = gnEsec + 1
LOOP
ENDIF
ENDIF
SELECT crsFirmaE2E
GO TOP
SCATTER NAME poRec MEMO
* golim campurile pe care le completeaza traseul ANAF, ca sa nu confundam o valoare
* ramasa din firma curenta cu una preluata acum
poRec.cod_fiscal = m.lcCod
poRec.judet = ''
poRec.id_judet = .NULL.
poRec.localitate = ''
poRec.id_loc = .NULL.
poRec.adresa = ''
* CAEN-ul si revizia: golite ca sa nu confundam o valoare veche cu una preluata acum
IF TYPE('poRec.caen') <> 'U'
poRec.caen = ''
ENDIF
IF TYPE('poRec.caen_revizie') <> 'U'
poRec.caen_revizie = ''
ENDIF
IF TYPE('poRec.modificare_schema') = 'U'
ADDPROPERTY(poRec, 'modificare_schema', 0)
ENDIF
gcMockUltimMesaj = ''
gcMockAnafJudet = ''
gcMockAnafLocalitate = ''
gcMockAnafAdresa = ''
gcMockAnafFirma = ''
gcMockAnafCaen = ''
gcMockAnafRegCom = ''
gnMockShowInfoApeluri = 0
llFrmOk = .F.
lcErr = ''
TRY
loFrm = CREATEOBJECT('frm_firme_nou_desktopf', poRec, poRec.id_firma, 'UPDATE')
llFrmOk = (VARTYPE(loFrm) = 'O')
CATCH TO loEx
lcErr = loEx.Message + ' [' + loEx.Procedure + ':' + TRANSFORM(loEx.LineNo) + ']'
ENDTRY
IF !m.llFrmOk
gnEsec = gnEsec + 1
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> ESEC: nu s-a putut crea formularul: ' + m.lcErr
ELSE
llClickOk = .F.
lcErr = ''
TRY
loFrm.But_verifica1.Click()
llClickOk = .T.
CATCH TO loEx
lcErr = loEx.Message + ' [' + loEx.Procedure + ':' + TRANSFORM(loEx.LineNo) + ']'
ENDTRY
IF !m.llClickOk
gnEsec = gnEsec + 1
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> ESEC: exceptie in But_verifica1.Click: ' + m.lcErr
ELSE
lcAdrAnaf = UPPER(ALLTRIM(gcMockAnafAdresa))
lcJudAnaf = UPPER(ALLTRIM(gcMockAnafJudet))
lcLocAnaf = UPPER(ALLTRIM(gcMockAnafLocalitate))
lcJudet = ALLTRIM(NVL(poRec.judet, ''))
lcLoc = ALLTRIM(NVL(poRec.localitate, ''))
lnIdJudet = NVL(poRec.id_judet, -1)
lnIdLoc = NVL(poRec.id_loc, -1)
IF gnMockShowInfoApeluri = 0 OR EMPTY(m.lcJudAnaf)
* ANAF n-a intors un partener valid, sau l-a intors fara adresa (cod inactiv /
* fara raspuns / notFound): nu se poate judeca potrivirea peste nomenclator
gnSarite = gnSarite + 1
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> SARIT: ANAF nu a intors adresa. Ultim dialog: [' + ;
LEFT(STRTRAN(STRTRAN(gcMockUltimMesaj, CHR(13), ' '), CHR(10), ' '), 150) + ']'
ELSE
* judetul e OK daca s-a completat, are id din nomenclator si denumirea potrivita
* corespunde textului brut primit de la ANAF
llOkJud = !EMPTY(m.lcJudet) AND m.lnIdJudet > 0 AND E2EPotrivit(m.lcJudet, m.lcJudAnaf)
* localitatea: la fel; santinela "<ALEGETI LOCALITATEA>" NU e rezultat valid
llOkLoc = !EMPTY(m.lcLoc) AND !('<ALEGETI' $ UPPER(m.lcLoc)) AND m.lnIdLoc > 0 ;
AND E2EPotrivit(m.lcLoc, m.lcLocAnaf)
* CAEN: contorizat SEPARAT de judet/localitate, ca sa ramana comparabile
* cifrele masurate in rundele anterioare (997/1000)
IF !EMPTY(gcMockAnafCaen)
IF ALLTRIM(NVL(poRec.caen, '')) == ALLTRIM(gcMockAnafCaen)
gnCaenOk = gnCaenOk + 1
ELSE
gnCaenLipsa = gnCaenLipsa + 1
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> CAEN NEPRELUAT: ANAF[' + ;
gcMockAnafCaen + '] formular[' + ALLTRIM(NVL(poRec.caen, '')) + ']'
ENDIF
* revizia 3 se pune doar cand numarul de registru e in formatul nou
IF !('/' $ gcMockAnafRegCom) AND !EMPTY(gcMockAnafRegCom)
IF ALLTRIM(NVL(poRec.caen_revizie, '')) == '3'
gnRevizie3 = gnRevizie3 + 1
ELSE
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> REVIZIE GRESITA: regcom[' + ;
gcMockAnafRegCom + '] revizie[' + ALLTRIM(NVL(poRec.caen_revizie, '')) + '] asteptat 3'
ENDIF
ENDIF
ENDIF
lcDetaliu = 'ANAF[jud=' + m.lcJudAnaf + ' loc=' + m.lcLocAnaf + ']' + ;
' -> NOM[judet=' + m.lcJudet + ' id_judet=' + TRANSFORM(m.lnIdJudet) + ;
' localitate=' + m.lcLoc + ' id_loc=' + TRANSFORM(m.lnIdLoc) + ']'
IF m.llOkJud AND m.llOkLoc
gnOk = gnOk + 1
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> OK ' + m.lcDetaliu
ELSE
gnEsec = gnEsec + 1
DO E2ELog WITH 'CIF ' + m.lcCod + ' -> ESEC ' + ;
IIF(!m.llOkJud, '[judet] ', '') + IIF(!m.llOkLoc, '[localitate] ', '') + m.lcDetaliu
DO E2ELog WITH ' adresa ANAF: ' + LEFT(m.lcAdrAnaf, 150)
DO E2ELog WITH ' ultim dialog: [' + ;
LEFT(STRTRAN(STRTRAN(gcMockUltimMesaj, CHR(13), ' '), CHR(10), ' '), 200) + ']'
ENDIF
ENDIF
ENDIF
loFrm.Release()
loFrm = .NULL.
ENDIF
ENDIF
ENDFOR
DO E2ELog WITH REPLICATE('-', 110)
DO E2ELog WITH 'TOTAL: ' + TRANSFORM(gnOk) + ' ok, ' + TRANSFORM(gnEsec) + ' esec, ' + ;
TRANSFORM(gnSarite) + ' sarite (fara raspuns ANAF), din ' + TRANSFORM(m.lnRulate) + ' coduri rulate'
DO E2ELog WITH 'CAEN : ' + TRANSFORM(gnCaenOk) + ' preluat corect, ' + TRANSFORM(gnCaenLipsa) + ;
' nepreluat; revizia 3 pusa pe ' + TRANSFORM(gnRevizie3) + ' firme cu numar de registru in format nou'
DO E2ELog WITH 'REZULTAT: ' + IIF(gnEsec = 0, 'TOATE OK', 'AU FOST ESECURI') + ' ' + TTOC(DATETIME())
QUIT
*********************************************************************
* Denumirea aleasa din nomenclator corespunde textului brut de la ANAF?
* Comparatia foloseste cheia toleranta a clasei (fara sufixul dintre paranteze, fara
* separatoare, cu A si I unificate) - altfel "TIRGU MURES" din nomenclator nu ar corespunde
* cu "TARGU MURES" de la ANAF si am raporta un esec fals.
* goNomE2E e construit INLINE in main (capcana l); aici doar se foloseste.
FUNCTION E2EPotrivit
LPARAMETERS tcDinNomenclator, tcDeLaAnaf
LOCAL lcA, lcB
IF VARTYPE(goNomE2E) <> 'O' OR EMPTY(ALLTRIM(NVL(m.tcDeLaAnaf, '')))
RETURN .F.
ENDIF
lcA = goNomE2E.cheie_fuzzy(m.tcDinNomenclator)
lcB = goNomE2E.cheie_fuzzy(m.tcDeLaAnaf)
RETURN !EMPTY(m.lcA) AND (m.lcA == m.lcB)
ENDFUNC
*********************************************************************
PROCEDURE E2EErr
LPARAMETERS tnErr, tcMsg, tcProg, tnLine
DO E2ELog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC
*********************************************************************
PROCEDURE E2ELog
LPARAMETERS tcMsg
LOCAL lcL
lcL = IIF(FILE(gcLogE2E), FILETOSTR(gcLogE2E), '')
STRTOFILE(m.lcL + TRANSFORM(m.tcMsg) + CHR(13) + CHR(10), gcLogE2E)
ENDPROC