* 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 ""), 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 -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 "" NU e rezultat valid llOkLoc = !EMPTY(m.lcLoc) AND !(' 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