diff --git a/utile/Teste/storno/extract_fixture_3795.prg b/utile/Teste/storno/extract_fixture_3795.prg new file mode 100644 index 0000000..49c11b8 --- /dev/null +++ b/utile/Teste/storno/extract_fixture_3795.prg @@ -0,0 +1,49 @@ +* extract_fixture_3795.prg +* Extrage xml-ul original al randului ANAF_EFACTURA.ID = 3795 (MARIUSM_AUTO) prin +* GetXmlOriginalEFactura, pentru anonimizare si salvare ca fixtura de test (storno diacritice reale). +* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\storno\extract_fixture_3795.prg" +* Iesire: D:\ROA\ROACONT\COMUN\utile\Teste\storno\_raw_3795.xml + _raw_3795_log.txt + +SET SAFETY OFF +SET TALK OFF +CLOSE DATABASES + +PUBLIC gcUILog +gcUILog = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\_raw_3795_log.txt" +STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +TRY + DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' + IF gnHandle <= 0 + DO PrLogLocal WITH 'FAIL: conectare Oracle esuata' + QUIT + ENDIF + + LOCAL lcXml, lcMesaj, llSucces + llSucces = GetXmlOriginalEFactura(3795, @lcXml, @lcMesaj) + DO PrLogLocal WITH 'GetXmlOriginalEFactura(3795) = ' + TRANSFORM(llSucces) + ' mesaj=[' + m.lcMesaj + '] len=' + TRANSFORM(LEN(m.lcXml)) + IF m.llSucces + STRTOFILE(m.lcXml, "D:\ROA\ROACONT\COMUN\utile\Teste\storno\_raw_3795.xml") + DO PrLogLocal WITH 'salvat _raw_3795.xml' + ENDIF +CATCH TO loEx + DO PrLogLocal WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure +ENDTRY + +QUIT + +PROCEDURE PrLogLocal + LPARAMETERS tcMsg + LOCAL lcL + SET SAFETY OFF + lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + STRTOFILE(lcL + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcUILog) +ENDPROC + +PROCEDURE PrErrLocal + LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo + DO PrLogLocal WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo) +ENDPROC diff --git a/utile/Teste/storno/mock_amessagebox_storno.prg b/utile/Teste/storno/mock_amessagebox_storno.prg new file mode 100644 index 0000000..0351394 --- /dev/null +++ b/utile/Teste/storno/mock_amessagebox_storno.prg @@ -0,0 +1,27 @@ +* mock_amessagebox_storno.prg - mock AMESSAGEBOX specific testului E2E storno +* (test_storno_e2e.prg). Raspunde diferit dupa continutul mesajului: 1 (OK) la gate-ul +* initial "genereaza XML-ul de stornare", 6 (Da) la confirmarea "Trimiteti la ANAF", +* altfel gnMockRaspuns implicit. Logheaza TOATE apelurile in PUBLIC gaAmsgCalls/gnAmsgCalls, +* utile ca sa vedem daca un guard neasteptat (CIF/luna blocata) a oprit fluxul. +FUNCTION amessagebox + LPARAMETERS tcMessage, tnDialogBoxType, tcTitle, tcFont, tnTimeOut, tnTimeoutValue + LOCAL lnRaspuns + DO CASE + CASE 'genereaza XML-ul de stornare' $ tcMessage + lnRaspuns = 1 + CASE 'Trimiteti la ANAF' $ tcMessage + lnRaspuns = 6 + OTHERWISE + lnRaspuns = IIF(TYPE('gnMockRaspuns') = 'N', gnMockRaspuns, 6) + ENDCASE + IF TYPE('gnAmsgCalls') = 'N' + gnAmsgCalls = gnAmsgCalls + 1 + DIMENSION gaAmsgCalls[gnAmsgCalls, 2] + gaAmsgCalls[gnAmsgCalls, 1] = TRANSFORM(tcMessage) + gaAmsgCalls[gnAmsgCalls, 2] = lnRaspuns + ENDIF + IF TYPE('gcUILog') = 'C' + DO PrLogLocal WITH 'MOCK amessagebox: [' + LEFT(TRANSFORM(tcMessage), 100) + '] -> ' + TRANSFORM(lnRaspuns) + ENDIF + RETURN lnRaspuns +ENDFUNC diff --git a/utile/Teste/storno/mock_anaf_server_storno.prg b/utile/Teste/storno/mock_anaf_server_storno.prg new file mode 100644 index 0000000..8b60952 --- /dev/null +++ b/utile/Teste/storno/mock_anaf_server_storno.prg @@ -0,0 +1,55 @@ +* mock_anaf_server_storno.prg - MOCK pentru AnafeFacturaServer, STRICT pentru testul E2E +* storno eFactura (test_storno_e2e.prg). ZERO apeluri reale la ANAF: RefreshTokenAuto / +* TrimiteFacturaXML / SaveFile / Xml2PdfAnaf doar logheaza apelul in PUBLIC gaMockApeluri / +* gnMockApeluri (declarate de test INAINTE de a instantia acest mock) si intorc raspunsuri +* canonice, fara retea si fara disc (in afara de SaveFile, care doar logheaza). +DEFINE CLASS MockAnafServerStorno AS Custom + cCodFiscal = '' + lTest = .T. + cToken = 'MOCK-TOKEN-STORNO' + cRefreshToken = 'MOCK-REFRESH-STORNO' + dTokenGendate = {} + dTokenExpdate = {} + + PROCEDURE RegMock + LPARAMETERS tcMetoda, tcP2, tcP3 + gnMockApeluri = gnMockApeluri + 1 + DIMENSION gaMockApeluri[gnMockApeluri, 3] + gaMockApeluri[gnMockApeluri, 1] = tcMetoda + gaMockApeluri[gnMockApeluri, 2] = TRANSFORM(tcP2) + gaMockApeluri[gnMockApeluri, 3] = TRANSFORM(tcP3) + IF TYPE('gcUILog') = 'C' + DO PrLogLocal WITH 'MOCK ' + tcMetoda + ' p2=[' + TRANSFORM(tcP2) + '] p3=[' + TRANSFORM(tcP3) + ']' + ENDIF + ENDPROC + + PROCEDURE RefreshTokenAuto + This.RegMock('RefreshTokenAuto', '', '') + ENDPROC + + PROCEDURE TrimiteFacturaXML + LPARAMETERS tcFile, tlValidare, tlValidareOnline, tlNuTrimiteEFacturaANAF, tlExtern, tlB2C + LOCAL loReturn + This.RegMock('TrimiteFacturaXML', tcFile, TRANSFORM(tlB2C)) + loReturn = CREATEOBJECT('Empty') + ADDPROPERTY(loReturn, 'lSucces', .T.) + ADDPROPERTY(loReturn, 'cIdIncarcare', 'MOCK-ID-STORNO-12345') + ADDPROPERTY(loReturn, 'cMesaj', '') + ADDPROPERTY(loReturn, 'cResponse', '') + ADDPROPERTY(loReturn, 'nStatus', 200) + ADDPROPERTY(loReturn, 'cFile', TRANSFORM(tcFile)) + RETURN loReturn + ENDPROC + + PROCEDURE SaveFile + LPARAMETERS tcFile, tlVariable, tcDirectory, tcFileName + This.RegMock('SaveFile', tcFile, TRANSFORM(tcDirectory) + '|' + TRANSFORM(tcFileName)) + RETURN .T. + ENDPROC + + PROCEDURE Xml2PdfAnaf + LPARAMETERS tcXml, tcFile, tlVariable + This.RegMock('Xml2PdfAnaf', tcFile, '') + RETURN tcFile + ENDPROC +ENDDEFINE diff --git a/utile/Teste/storno/storno_fixture_b2c_cnp.xml b/utile/Teste/storno/storno_fixture_b2c_cnp.xml new file mode 100644 index 0000000..4333bc8 --- /dev/null +++ b/utile/Teste/storno/storno_fixture_b2c_cnp.xml @@ -0,0 +1 @@ +TEST-B2C-012026-05-08380RONRO99999901VATFURNIZOR TEST SAJ40/9999/2020PERSOANA FIZICA TEST199010112345619.00100.0019.00S19.0VAT100.00100.00119.00119.0011.0100.00TEST-B2CS19.0VAT100.00 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_creditnote_minimal.xml b/utile/Teste/storno/storno_fixture_creditnote_minimal.xml new file mode 100644 index 0000000..4866757 --- /dev/null +++ b/utile/Teste/storno/storno_fixture_creditnote_minimal.xml @@ -0,0 +1 @@ +TEST-CN-012026-05-02381RONRO99999901VATFURNIZOR TEST SAJ40/9999/2020CLIENT TEST SRLJ40/8888/19999.5050.009.50S19.0VAT50.0050.0059.5059.5011.050.00TEST-CNS19.0VAT50.00 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_diacritice_reale.xml b/utile/Teste/storno/storno_fixture_diacritice_reale.xml new file mode 100644 index 0000000..d7e7945 --- /dev/null +++ b/utile/Teste/storno/storno_fixture_diacritice_reale.xml @@ -0,0 +1 @@ +urn:cen.eu:en16931:2017#compliant#urn:efactura.mfinante.ro:CIUS-RO:1.0.1TEST-3795-012026-03-252026-03-28380RONRO99999901Str. Test nr. 1SECTOR6060787RO-BRORO99999901VATFURNIZOR TEST SAJ40/9999/2020Capital social 200 RON+40210000000RO99999902Str. Client nr. 2Constanţa900189RO-CTRORO99999902VATCLIENT TEST SRLJ40/8888/199948RO00AAAA0000000000000001CONT RON48RO00TREZ0000000000000002CONT RONfalse95Discount DVCR1VAT21TYPE108.43S21.0VATtrueTVTransportation by vendor10.74S21.0VAT18.1886.5918.18S21.0VAT84.2886.59104.778.4310.74104.771Produs2.084.28Piesa auto test diacriticeTEST-001S21.0VAT42.15 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_factura_negativa.xml b/utile/Teste/storno/storno_fixture_factura_negativa.xml new file mode 100644 index 0000000..b1554da --- /dev/null +++ b/utile/Teste/storno/storno_fixture_factura_negativa.xml @@ -0,0 +1 @@ +TEST-NEG-012026-05-05380RONRO99999901VATFURNIZOR TEST SAJ40/9999/2020CLIENT TEST SRLJ40/8888/1999-19.00-100.00-19.00S19.0VAT-100.00-100.00-119.00-119.001-1.0-100.00TEST-NEGS19.0VAT100.00 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_fara_partytaxscheme.xml b/utile/Teste/storno/storno_fixture_fara_partytaxscheme.xml new file mode 100644 index 0000000..ff4cb59 --- /dev/null +++ b/utile/Teste/storno/storno_fixture_fara_partytaxscheme.xml @@ -0,0 +1 @@ +TEST-NOPTS-012026-05-09380RONFURNIZOR NEPLATITOR TVA SRLRO99999903CLIENT TEST SRLJ40/8888/19990.00100.000.00OVAT100.00100.00100.00100.0011.0100.00TEST-NOPTSOVAT100.00 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_paymentterms.xml b/utile/Teste/storno/storno_fixture_paymentterms.xml new file mode 100644 index 0000000..76eab54 --- /dev/null +++ b/utile/Teste/storno/storno_fixture_paymentterms.xml @@ -0,0 +1 @@ +TEST-PT-012026-05-07380RONRO99999901VATFURNIZOR TEST SAJ40/9999/2020CLIENT TEST SRLJ40/8888/199930 zile119.0019.00100.0019.00S19.0VAT100.00100.00119.00119.0011.0100.00TEST-PTS19.0VAT100.00 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_prefix_n3.xml b/utile/Teste/storno/storno_fixture_prefix_n3.xml new file mode 100644 index 0000000..e10ed3d --- /dev/null +++ b/utile/Teste/storno/storno_fixture_prefix_n3.xml @@ -0,0 +1 @@ +urn:cen.eu:en16931:2017#compliant#urn:efactura.mfinante.ro:CIUS-RO:1.0.1TEST-N3-012026-04-10380RONRO99999901VATFURNIZOR TEST SAJ40/9999/2020CLIENT TEST SRLJ40/8888/199919.00100.0019.00S19.0VAT100.00100.00119.00119.0011.0100.00TEST-N3S19.0VAT100.00 \ No newline at end of file diff --git a/utile/Teste/storno/storno_fixture_sume_zero.xml b/utile/Teste/storno/storno_fixture_sume_zero.xml new file mode 100644 index 0000000..f17b804 --- /dev/null +++ b/utile/Teste/storno/storno_fixture_sume_zero.xml @@ -0,0 +1 @@ +TEST-ZERO-012026-05-06380RONRO99999901VATFURNIZOR TEST SAJ40/9999/2020CLIENT TEST SRLJ40/8888/1999false95-0.00S19.0VAT0.000.000.00S0.0VAT0.000.000.00-0.000.0010.00.00TEST-ZEROS0.0VAT0.00 \ No newline at end of file diff --git a/utile/Teste/storno/test4_storno_efactura_anaf_test.prg b/utile/Teste/storno/test4_storno_efactura_anaf_test.prg new file mode 100644 index 0000000..74bbb7d --- /dev/null +++ b/utile/Teste/storno/test4_storno_efactura_anaf_test.prg @@ -0,0 +1,227 @@ +* test4_storno_efactura_anaf_test.prg +* Test 4 (docs\plan_storno_efactura.md): upload real pe ANAF TEST al unui storno + reincarcarea +* facturii corecte cu acelasi numar ca originalul. Sursa: MARIUSM_AUTO.anaf_efactura (test=1). +* Maxim 4 incarcari (aprobat); interzisa orice trimitere spre /prod/. +* Validarea online (ValidareEFacturaANAF) e SARITA intentionat: xmlefactura.prg:1275,1278 +* construieste URL-ul hardcodat pe /prod/, indiferent de context (fara proprietate lTest pe +* ExportEFactura) - decizie aprobata, ANAF valideaza oricum la upload. +* +* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test4_storno_efactura_anaf_test.prg" +* Iesire: test4_storno_efactura_anaf_test_log.txt (acelasi folder) + +SET SAFETY OFF +SET TALK OFF +SET DELETED ON +SET EXACT ON +SET CENTURY ON +SET DATE DMY +SET NULLDISPLAY TO '' +CLOSE DATABASES + +PUBLIC gcUILog, gcOutDir +gcOutDir = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\out\" +IF !DIRECTORY(gcOutDir) + MD (gcOutDir) +ENDIF +gcUILog = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test4_storno_efactura_anaf_test_log.txt" +STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +PUBLIC lnUploads +lnUploads = 0 + +TRY + DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' + IF gnHandle <= 0 + DO PrLogLocal WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')' + QUIT + ENDIF + DO PrLogLocal WITH 'mediu initializat, gnHandle=' + TRANSFORM(gnHandle) + + IF !('nfjsonread' $ LOWER(SET("Procedure"))) + SET PROCEDURE TO 'D:\ROA\ROACONT\COMUN\utile\nfjson\nfjsonread.prg' ADDITIVE + ENDIF + + *========================================================================= + DO PrLogLocal WITH '=== PAS 1: selectie sursa (MARIUSM_AUTO.anaf_efactura, test=1, factura_emisa=1, FACTURA TRIMISA) ===' + LOCAL lcSql, lnIdSursa, lcIdIncarcareSursa + lnIdSursa = 0 + lcSql = "select id, id_incarcare from anaf_efactura" + lcSql = lcSql + " where factura_emisa=1 and test=1 and tip_mesaj_raspuns='FACTURA TRIMISA'" + lcSql = lcSql + " and detalii_zip is not null order by id desc" + IF !goExecutor.oExecuta(lcSql, "cSursa") + DO PrLogLocal WITH 'FAIL: select sursa: ' + ALLTRIM(NVL(goExecutor.cEroare,'')) + QUIT + ENDIF + IF RECCOUNT('cSursa') = 0 + DO PrLogLocal WITH 'FAIL: nicio sursa disponibila in MARIUSM_AUTO (factura_emisa=1, test=1, FACTURA TRIMISA, cu detalii_zip)' + QUIT + ENDIF + SELECT cSursa + GO TOP + lnIdSursa = id + lcIdIncarcareSursa = ALLTRIM(NVL(id_incarcare, '')) + USE IN (SELECT('cSursa')) + DO PrLogLocal WITH 'sursa aleasa: id=' + TRANSFORM(lnIdSursa) + ' id_incarcare_original=' + lcIdIncarcareSursa + + *========================================================================= + DO PrLogLocal WITH '=== PAS 2: GetXmlOriginalEFactura + StornoEFacturaXML ===' + LOCAL lcXmlOriginal, lcMsgGet, llRetGet + llRetGet = GetXmlOriginalEFactura(lnIdSursa, @lcXmlOriginal, @lcMsgGet) + IF !llRetGet + DO PrLogLocal WITH 'FAIL: GetXmlOriginalEFactura: ' + lcMsgGet + QUIT + ENDIF + DO PrLogLocal WITH 'GetXmlOriginalEFactura OK, len=' + TRANSFORM(LEN(lcXmlOriginal)) + + LOCAL lcFileOriginal, lcFileStorno, lcMsgStorno, llRetStorno + LOCAL laMod[1,4] + lcFileOriginal = gcOutDir + 'test4_original_' + TRANSFORM(lnIdSursa) + '.xml' + lcFileStorno = gcOutDir + 'test4_storno_' + TRANSFORM(lnIdSursa) + '.xml' + STRTOFILE(lcXmlOriginal, lcFileOriginal) + + llRetStorno = StornoEFacturaXML(lcXmlOriginal, '', 'Stornare factura test 4 ANAF TEST', lcFileStorno, @laMod, @lcMsgStorno) + IF !llRetStorno + DO PrLogLocal WITH 'FAIL: StornoEFacturaXML: ' + lcMsgStorno + QUIT + ENDIF + DO PrLogLocal WITH 'StornoEFacturaXML OK, fisier=' + lcFileStorno + + *========================================================================= + DO PrLogLocal WITH '=== PAS 3: pregatire AnafeFacturaServer pe TEST (token + CIF), garda /test/ ===' + LOCAL loAnaf As 'AnafeFacturaServer' + loAnaf = CREATEOBJECT('AnafeFacturaServer', .F., '', gcS, '') + loAnaf.lTest = .T. + loAnaf.RefreshTokenAuto() + + DO PrLogLocal WITH 'CIF=' + loAnaf.cCodFiscal + ' lTest=' + TRANSFORM(loAnaf.lTest) + ' tokenExp=' + DTOC(loAnaf.dTokenExpdate) + ' tokenGol=' + TRANSFORM(EMPTY(loAnaf.cToken)) + + * garda: nicio trimitere daca lTest nu e .T., tokenul e gol sau expirat - fara presupuneri + IF !loAnaf.lTest + DO PrLogLocal WITH 'BLOCAT: lTest nu e .T. - opresc, fara nicio trimitere' + QUIT + ENDIF + IF EMPTY(loAnaf.cToken) + DO PrLogLocal WITH 'BLOCAT: token gol - opresc, fara nicio trimitere' + QUIT + ENDIF + IF loAnaf.dTokenExpdate <= DATE() + DO PrLogLocal WITH 'BLOCAT: token expirat (' + DTOC(loAnaf.dTokenExpdate) + ') - opresc, fara nicio trimitere' + QUIT + ENDIF + + *========================================================================= + DO PrLogLocal WITH '=== PAS 4: upload 1/2 - storno pe TEST ===' + LOCAL loRetStorno + IF !loAnaf.lTest + DO PrLogLocal WITH 'BLOCAT (garda finala): lTest nu mai e .T. inainte de upload storno' + QUIT + ENDIF + loRetStorno = loAnaf.TrimiteFacturaXML(lcFileStorno, .F., .F., .F., .F., .F.) + lnUploads = lnUploads + 1 + DO PrLogLocal WITH 'upload storno: lSucces=' + TRANSFORM(loRetStorno.lSucces) + ' status=' + TRANSFORM(loRetStorno.nStatus) + ' idIncarcare=' + ALLTRIM(NVL(loRetStorno.cIdIncarcare,'')) + ' mesaj=[' + ALLTRIM(NVL(loRetStorno.cMesaj,'')) + ']' + DO PrLogLocal WITH 'raspuns brut storno: ' + ALLTRIM(NVL(loRetStorno.cResponse,'')) + + *========================================================================= + DO PrLogLocal WITH '=== PAS 5: upload 2/2 - reincarcare XML original (acelasi numar) pe TEST ===' + LOCAL loRetReincarcare + IF !loAnaf.lTest + DO PrLogLocal WITH 'BLOCAT (garda finala): lTest nu mai e .T. inainte de reincarcare' + QUIT + ENDIF + loRetReincarcare = loAnaf.TrimiteFacturaXML(lcFileOriginal, .F., .F., .F., .F., .F.) + lnUploads = lnUploads + 1 + DO PrLogLocal WITH 'upload reincarcare: lSucces=' + TRANSFORM(loRetReincarcare.lSucces) + ' status=' + TRANSFORM(loRetReincarcare.nStatus) + ' idIncarcare=' + ALLTRIM(NVL(loRetReincarcare.cIdIncarcare,'')) + ' mesaj=[' + ALLTRIM(NVL(loRetReincarcare.cMesaj,'')) + ']' + DO PrLogLocal WITH 'raspuns brut reincarcare: ' + ALLTRIM(NVL(loRetReincarcare.cResponse,'')) + + DO PrLogLocal WITH '=== PAS 6: storno CreditNote - NEEXECUTAT: nicio sursa CreditNote emisa in MARIUSM_AUTO.anaf_efactura (test=1) ===' + DO PrLogLocal WITH '=== PAS 7: storno B2C - NEEXECUTAT: nicio sursa cu CNP 13 cifre in MARIUSM_AUTO.anaf_efactura (test=1) ===' + + *========================================================================= + DO PrLogLocal WITH '=== PAS 8: verificare stare incarcari (stareMesaj, /test/) ===' + IF !EMPTY(ALLTRIM(NVL(loRetStorno.cIdIncarcare,''))) + DO VerificaStare WITH loAnaf, ALLTRIM(loRetStorno.cIdIncarcare), 'storno' + ELSE + DO PrLogLocal WITH 'storno: fara id_incarcare, nu se poate verifica starea (vezi mesajul de upload de mai sus)' + ENDIF + IF !EMPTY(ALLTRIM(NVL(loRetReincarcare.cIdIncarcare,''))) + DO VerificaStare WITH loAnaf, ALLTRIM(loRetReincarcare.cIdIncarcare), 'reincarcare' + ELSE + DO PrLogLocal WITH 'reincarcare: fara id_incarcare, nu se poate verifica starea (vezi mesajul de upload de mai sus)' + ENDIF + + DO PrLogLocal WITH 'TOTAL incarcari efectuate: ' + TRANSFORM(lnUploads) + ' (limita aprobata: 4)' + DO PrLogLocal WITH 'TOTAL: test terminat fara exceptie' +CATCH TO loEx + DO PrLogLocal WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure +ENDTRY + +QUIT + +********************************************************** +* interogheaza stareMesaj pe /test/ pentru un id_incarcare, cu reincercari, fara sa scrie nimic +PROCEDURE VerificaStare + LPARAMETERS toAnaf, tcIdIncarcare, tcLabel + + LOCAL loHTTP, lcServer, lnStatus, lcResponse, lnIncercare, llGata, loJson, lcStare + LOCAL loEx As Exception + llGata = .F. + + FOR lnIncercare = 1 TO 5 + lcServer = 'https://api.anaf.ro/test/FCTEL/rest/stareMesaj?id_incarcare=' + tcIdIncarcare + TRY + loHTTP = CREATEOBJECT('winHTTP.winHTTPrequest.5.1') + loHTTP.Open('GET', lcServer, .F.) + loHTTP.setRequestHeader('Authorization', 'Bearer ' + toAnaf.cToken) + loHTTP.Send() + lnStatus = loHTTP.Status + lcResponse = loHTTP.ResponseText + CATCH TO loEx + lnStatus = 0 + lcResponse = '' + ENDTRY + + DO PrLogLocal WITH '[' + tcLabel + '] stareMesaj incercare ' + TRANSFORM(lnIncercare) + '/5 id_incarcare=' + tcIdIncarcare + ' status=' + TRANSFORM(lnStatus) + ' raspuns=' + lcResponse + + lcStare = '' + TRY + loJson = nfjsonread(lcResponse) + IF TYPE('loJson.stare') = 'C' + lcStare = LOWER(ALLTRIM(loJson.stare)) + ENDIF + CATCH + lcStare = '' + ENDTRY + + IF INLIST(lcStare, 'ok', 'nok') + llGata = .T. + DO PrLogLocal WITH '[' + tcLabel + '] stare finala ANAF: ' + lcStare + EXIT + ENDIF + + IF lnIncercare < 5 + INKEY(20, 'H') + ENDIF + ENDFOR + + IF !llGata + DO PrLogLocal WITH '[' + tcLabel + '] stare neconcludenta dupa 5 incercari (posibil inca in prelucrare la ANAF) - vezi ultimul raspuns de mai sus' + ENDIF +ENDPROC + +********************************************************** +PROCEDURE PrLogLocal + LPARAMETERS tcMsg + LOCAL lcL + SET SAFETY OFF + lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + STRTOFILE(lcL + TTOC(DATETIME()) + ' ' + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcUILog) +ENDPROC + +********************************************************** +PROCEDURE PrErrLocal + LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo + DO PrLogLocal WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo) +ENDPROC diff --git a/utile/Teste/storno/test4b_retry_storno_si_poll.prg b/utile/Teste/storno/test4b_retry_storno_si_poll.prg new file mode 100644 index 0000000..b9db3fb --- /dev/null +++ b/utile/Teste/storno/test4b_retry_storno_si_poll.prg @@ -0,0 +1,143 @@ +* test4b_retry_storno_si_poll.prg +* Continuare test4 (docs\plan_storno_efactura.md): PAS 4 (upload storno) a esuat cu eroare +* tehnica ANAF (Cod: 1814, fara id_incarcare) la prima incercare - reincercare (upload 3/4 +* aprobate) + continuare poll stareMesaj pe /test/ pentru storno (nou) si reincarcare +* (id_incarcare=5036305973, "in prelucrare" la ultima verificare). +* Refoloseste fisierul deja generat: out\test4_storno_1127.xml (nu regenereaza StornoEFacturaXML). +* +* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test4b_retry_storno_si_poll.prg" +* Iesire: test4b_retry_storno_si_poll_log.txt (acelasi folder) + +SET SAFETY OFF +SET TALK OFF +SET DELETED ON +SET EXACT ON +SET CENTURY ON +SET DATE DMY +SET NULLDISPLAY TO '' +CLOSE DATABASES + +PUBLIC gcUILog, gcOutDir +gcOutDir = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\out\" +gcUILog = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test4b_retry_storno_si_poll_log.txt" +STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +TRY + DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' + IF gnHandle <= 0 + DO PrLogLocal WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')' + QUIT + ENDIF + DO PrLogLocal WITH 'mediu initializat, gnHandle=' + TRANSFORM(gnHandle) + + IF !('nfjsonread' $ LOWER(SET("Procedure"))) + SET PROCEDURE TO 'D:\ROA\ROACONT\COMUN\utile\nfjson\nfjsonread.prg' ADDITIVE + ENDIF + + LOCAL lcFileStorno + lcFileStorno = gcOutDir + 'test4_storno_1127.xml' + IF !FILE(lcFileStorno) + DO PrLogLocal WITH 'FAIL: nu exista fisierul storno de la rularea anterioara: ' + lcFileStorno + QUIT + ENDIF + + LOCAL loAnaf As 'AnafeFacturaServer' + loAnaf = CREATEOBJECT('AnafeFacturaServer', .F., '', gcS, '') + loAnaf.lTest = .T. + loAnaf.RefreshTokenAuto() + DO PrLogLocal WITH 'CIF=' + loAnaf.cCodFiscal + ' lTest=' + TRANSFORM(loAnaf.lTest) + ' tokenExp=' + DTOC(loAnaf.dTokenExpdate) + ' tokenGol=' + TRANSFORM(EMPTY(loAnaf.cToken)) + + IF !loAnaf.lTest OR EMPTY(loAnaf.cToken) OR loAnaf.dTokenExpdate <= DATE() + DO PrLogLocal WITH 'BLOCAT: garda lTest/token nu trece - opresc, fara nicio trimitere' + QUIT + ENDIF + + DO PrLogLocal WITH '=== PAS 4 (reincercare, upload 3/4 aprobate): storno pe TEST ===' + LOCAL loRetStorno + loRetStorno = loAnaf.TrimiteFacturaXML(lcFileStorno, .F., .F., .F., .F., .F.) + DO PrLogLocal WITH 'upload storno (reincercare): lSucces=' + TRANSFORM(loRetStorno.lSucces) + ' status=' + TRANSFORM(loRetStorno.nStatus) + ' idIncarcare=' + ALLTRIM(NVL(loRetStorno.cIdIncarcare,'')) + ' mesaj=[' + ALLTRIM(NVL(loRetStorno.cMesaj,'')) + ']' + DO PrLogLocal WITH 'raspuns brut storno (reincercare): ' + ALLTRIM(NVL(loRetStorno.cResponse,'')) + + IF !EMPTY(ALLTRIM(NVL(loRetStorno.cIdIncarcare,''))) + DO VerificaStare WITH loAnaf, ALLTRIM(loRetStorno.cIdIncarcare), 'storno-reincercare' + ELSE + DO PrLogLocal WITH 'storno-reincercare: fara id_incarcare, nu se poate verifica starea' + ENDIF + + DO PrLogLocal WITH '=== continuare poll reincarcare (id_incarcare=5036305973, era "in prelucrare") ===' + DO VerificaStare WITH loAnaf, '5036305973', 'reincarcare' + + DO PrLogLocal WITH 'TOTAL: test terminat fara exceptie' +CATCH TO loEx + DO PrLogLocal WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure +ENDTRY + +QUIT + +********************************************************** +PROCEDURE VerificaStare + LPARAMETERS toAnaf, tcIdIncarcare, tcLabel + + LOCAL loHTTP, lcServer, lnStatus, lcResponse, lnIncercare, llGata, loJson, lcStare + LOCAL loEx As Exception + llGata = .F. + + FOR lnIncercare = 1 TO 6 + lcServer = 'https://api.anaf.ro/test/FCTEL/rest/stareMesaj?id_incarcare=' + tcIdIncarcare + TRY + loHTTP = CREATEOBJECT('winHTTP.winHTTPrequest.5.1') + loHTTP.Open('GET', lcServer, .F.) + loHTTP.setRequestHeader('Authorization', 'Bearer ' + toAnaf.cToken) + loHTTP.Send() + lnStatus = loHTTP.Status + lcResponse = loHTTP.ResponseText + CATCH TO loEx + lnStatus = 0 + lcResponse = '' + ENDTRY + + DO PrLogLocal WITH '[' + tcLabel + '] stareMesaj incercare ' + TRANSFORM(lnIncercare) + '/6 id_incarcare=' + tcIdIncarcare + ' status=' + TRANSFORM(lnStatus) + ' raspuns=' + lcResponse + + lcStare = '' + TRY + loJson = nfjsonread(lcResponse) + IF TYPE('loJson.stare') = 'C' + lcStare = LOWER(ALLTRIM(loJson.stare)) + ENDIF + CATCH + lcStare = '' + ENDTRY + + IF INLIST(lcStare, 'ok', 'nok') + llGata = .T. + DO PrLogLocal WITH '[' + tcLabel + '] stare finala ANAF: ' + lcStare + EXIT + ENDIF + + IF lnIncercare < 6 + INKEY(25, 'H') + ENDIF + ENDFOR + + IF !llGata + DO PrLogLocal WITH '[' + tcLabel + '] stare neconcludenta dupa 6 incercari (posibil inca in prelucrare la ANAF) - vezi ultimul raspuns de mai sus' + ENDIF +ENDPROC + +********************************************************** +PROCEDURE PrLogLocal + LPARAMETERS tcMsg + LOCAL lcL + SET SAFETY OFF + lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + STRTOFILE(lcL + TTOC(DATETIME()) + ' ' + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcUILog) +ENDPROC + +********************************************************** +PROCEDURE PrErrLocal + LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo + DO PrLogLocal WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo) +ENDPROC diff --git a/utile/Teste/storno/test4c_descarcare_raspuns.prg b/utile/Teste/storno/test4c_descarcare_raspuns.prg new file mode 100644 index 0000000..0be2ad7 --- /dev/null +++ b/utile/Teste/storno/test4c_descarcare_raspuns.prg @@ -0,0 +1,109 @@ +* test4c_descarcare_raspuns.prg +* Continuare test4: descarca raspunsul ANAF (nok) pentru reincarcarea originalului cu acelasi +* numar (id_descarcare=3059138503), ca sa se vada mesajul exact de respingere. Doar GET/descarcare +* si dezarhivare locala - nu scrie nimic in Oracle, nu conteaza ca incarcare. +* +* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test4c_descarcare_raspuns.prg" + +SET SAFETY OFF +SET TALK OFF +CLOSE DATABASES + +PUBLIC gcUILog, gcOutDir +gcOutDir = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\out\" +gcUILog = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test4c_descarcare_raspuns_log.txt" +STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +TRY + DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' + IF gnHandle <= 0 + DO PrLogLocal WITH 'FAIL: conectare Oracle esuata' + QUIT + ENDIF + + LOCAL loAnaf As 'AnafeFacturaServer' + loAnaf = CREATEOBJECT('AnafeFacturaServer', .F., '', gcS, '') + loAnaf.lTest = .T. + loAnaf.RefreshTokenAuto() + IF !loAnaf.lTest OR EMPTY(loAnaf.cToken) + DO PrLogLocal WITH 'BLOCAT: garda lTest/token nu trece' + QUIT + ENDIF + + DO DescarcaSiLogheaza WITH loAnaf, '3059138503', 'reincarcare-nok' + DO DescarcaSiLogheaza WITH loAnaf, '3059138527', 'storno-reincercare-ok' + + DO PrLogLocal WITH 'TOTAL: test terminat fara exceptie' +CATCH TO loEx + DO PrLogLocal WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure +ENDTRY + +QUIT + +********************************************************** +PROCEDURE DescarcaSiLogheaza + LPARAMETERS toAnaf, tcIdDescarcare, tcLabel + + LOCAL loHTTP, lcServer, lnStatus, lcZip, lcDir, lcMesaj, llSucces + LOCAL loEx As Exception + + lcServer = 'https://api.anaf.ro/test/FCTEL/rest/descarcare?id=' + tcIdDescarcare + TRY + loHTTP = CREATEOBJECT('winHTTP.winHTTPrequest.5.1') + loHTTP.Open('GET', lcServer, .F.) + loHTTP.setRequestHeader('Authorization', 'Bearer ' + toAnaf.cToken) + loHTTP.Send() + lnStatus = loHTTP.Status + CATCH TO loEx + DO PrLogLocal WITH '[' + tcLabel + '] descarcare eroare: ' + loEx.Message + RETURN + ENDTRY + + DO PrLogLocal WITH '[' + tcLabel + '] descarcare id=' + tcIdDescarcare + ' status=' + TRANSFORM(lnStatus) + ' content-type=' + loHTTP.getResponseHeader('Content-Type') + + IF lnStatus <> 200 + DO PrLogLocal WITH '[' + tcLabel + '] raspuns brut (non-200): ' + loHTTP.ResponseText + RETURN + ENDIF + + lcZip = gcOutDir + 'test4_descarcare_' + tcIdDescarcare + '.zip' + STRTOFILE(loHTTP.ResponseBody, lcZip) + + lcDir = '' + lcMesaj = '' + llSucces = MyUnzip(lcZip, @lcDir, @lcMesaj, .T.) + IF !llSucces + DO PrLogLocal WITH '[' + tcLabel + '] MyUnzip esuat: ' + lcMesaj + ' (zip pastrat: ' + lcZip + ')' + RETURN + ENDIF + + DO PrLogLocal WITH '[' + tcLabel + '] dezarhivat in ' + lcDir + + LOCAL lcFisier, laFisiere[1], lnI, lnFisiere + lnFisiere = ADIR(laFisiere, ADDBS(lcDir) + '*.*') + FOR lnI = 1 TO lnFisiere + lcFisier = ADDBS(lcDir) + laFisiere[lnI, 1] + DO PrLogLocal WITH '[' + tcLabel + '] fisier: ' + laFisiere[lnI,1] + ' (' + TRANSFORM(laFisiere[lnI,2]) + ' octeti)' + IF LOWER(JUSTEXT(lcFisier)) = 'xml' + DO PrLogLocal WITH '[' + tcLabel + '] continut: ' + FILETOSTR(lcFisier) + ENDIF + ENDFOR +ENDPROC + +********************************************************** +PROCEDURE PrLogLocal + LPARAMETERS tcMsg + LOCAL lcL + SET SAFETY OFF + lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + STRTOFILE(lcL + TTOC(DATETIME()) + ' ' + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcUILog) +ENDPROC + +********************************************************** +PROCEDURE PrErrLocal + LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo + DO PrLogLocal WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo) +ENDPROC diff --git a/utile/Teste/storno/test_storno_e2e.prg b/utile/Teste/storno/test_storno_e2e.prg new file mode 100644 index 0000000..0f5b0f1 --- /dev/null +++ b/utile/Teste/storno/test_storno_e2e.prg @@ -0,0 +1,411 @@ +* test_storno_e2e.prg +* Test E2E HEADLESS pentru "Generare XML storno si trimitere la ANAF" din borderoul eFactura: +* exerseaza codul REAL din anaf_efactura.vcx (metoda do_storno_efactura + clasa +* frm_storno_efactura), nu copii ale lui. Vezi docs\handoff_storno_efactura.md. +* +* Ruleaza direct pe binarul real din proiect (COMUN\CLASE\anaf_efactura.vcx, cu write-back): +* vfp9.exe -A -T "...\test_storno_e2e.prg" +* +* ZERO trimiteri ANAF: Thisform.oAnaf.AnafeFacturaServer e inlocuit cu MockAnafServerStorno +* (mock_anaf_server_storno.prg) imediat dupa ce forma reala citeste cCodFiscal/lTest de la +* serverul real. cmdValideaza (ValidareEFacturaANAF, apel HTTP real, hardcodat /prod/ - +* xmlefactura.prg:1275,1278) NU e apelat; se ocoleste cu SetStare(1) direct. + +SET SAFETY OFF +SET TALK OFF +SET DELETED ON +SET EXACT ON +SET CENTURY ON +SET DATE DMY +SET NULLDISPLAY TO '' +CLOSE DATABASES + +PUBLIC gcUILog, gcTestDir, gcTesteDir +PUBLIC gnPass, gnFail, gnMockRaspuns, gnAmsgCalls, gnMockApeluri +PUBLIC loAnaf, loForm, loMockSrv, loStornoForm, lnLastErrorNo, lcLastErrorMsg +DECLARE gaAmsgCalls[1,2] +DECLARE gaMockApeluri[1,3] +gnPass = 0 +gnFail = 0 +gnAmsgCalls = 0 +gnMockApeluri = 0 +gnMockRaspuns = 6 +lnLastErrorNo = 0 +lcLastErrorMsg = '' + +gcTestDir = ADDBS(JUSTPATH(SYS(16))) +gcTesteDir = ADDBS(JUSTPATH(JUSTPATH(SYS(16)))) +gcUILog = gcTestDir + 'test_storno_e2e_log_real.txt' +STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +* mock-urile INAINTEA test_init_env_auto: la nume duplicat de procedura castiga fisierul +* cautat PRIMUL (vezi mock_amessagebox.prg / capcana testare-ui-vfp.md) +SET PROCEDURE TO (gcTestDir + 'mock_amessagebox_storno.prg') ADDITIVE +SET PROCEDURE TO (gcTestDir + 'mock_anaf_server_storno.prg') ADDITIVE + +TRY + DO (gcTesteDir + 'test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' + IF gnHandle <= 0 + DO PrLogLocal WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')' + QUIT + ENDIF + DO PrLogLocal WITH 'mediu initializat, gnHandle=' + TRANSFORM(gnHandle) + ' gcS=' + gcS + + * gnId_Prg_Owner: setat de roacont.prg la pornirea reala a aplicatiei (=0). test_init_env_auto.prg + * NU il seteaza pentru ROACONT - do_storno_efactura il foloseste direct (is_luna_blocata), + * fara TYPE()-check => "variable not found" daca lipseste (capcana de mediu, nu bug de aplicatie). + PUBLIC gnId_Prg_Owner + gnId_Prg_Owner = 0 + + * gnEFACTURA_*/gcEFACTURA_*: memvari globale create dinamic de optiuni_firma() (oinit_optiuni.prg, + * apelata din ocomenzi.vc2:6675 la login real) din tabela de optiuni (v_optiuni, macro-substitutie + * PUBLIC gn&lcvarname.). test_init_env_auto.prg:290 apeleaza ACELASI loader - nu setez manual, + * doar diagnostichez ce a produs, pentru cele 11 legate de controale in pgfeFactura.Page4 + * (vc2:4952-5201). + LOCAL i, laEFVars[11], lcEFDiag + laEFVars[1] = 'gnEFACTURA_ZIP_DATABASE' + laEFVars[2] = 'gnEFACTURA_SAVE' + laEFVars[3] = 'gnEFACTURA_SAVE_ANAF_PDF' + laEFVars[4] = 'gnEFACTURA_VALIDARE_ONLINE' + laEFVars[5] = 'gcEFACTURA_NETWORK_PATH' + laEFVars[6] = 'gcEFACTURA_RESPONSESPATH' + laEFVars[7] = 'gcEFACTURA_SAVE_CLIENTI_FILE' + laEFVars[8] = 'gcEFACTURA_SAVE_CLIENTI_PATH' + laEFVars[9] = 'gcEFACTURA_SAVE_FURNIZORI_FILE' + laEFVars[10] = 'gcEFACTURA_SAVE_FURNIZORI_PATH' + laEFVars[11] = 'gcEFACTURA_SERVER_PATH' + FOR i = 1 TO 11 + lcEFDiag = laEFVars[i] + '=TYPE[' + TYPE(laEFVars[i]) + ']' + IF TYPE(laEFVars[i]) != 'U' + lcEFDiag = lcEFDiag + ' val=[' + TRANSFORM(EVALUATE(laEFVars[i])) + ']' + ENDIF + DO PrLogLocal WITH lcEFDiag + ENDFOR + + *========================================================================= + DO PrLogLocal WITH '=== PAS 0: sursa reala MARIUSM_AUTO.anaf_vefactura_trimis id=1127 (FACTURA TRIMISA) ===' + LOCAL lnIdSursa, lnTestSursa, ldDataSursa, llLunaBlocataDiag + lnIdSursa = 0 + * numar_act/data_act nu exista pe tabela anaf_efactura (are xnumar_act/xdata_act) - doar pe + * view-ul anaf_vefactura_trimis (verificat cu DESC pe MARIUSM_AUTO@ROA_CENTRAL). + IF !goExecutor.oExecuta("select id, numar_act, data_act, test, tip_mesaj_raspuns from anaf_vefactura_trimis where id = 1127", "cSursa") + DO PrLogLocal WITH 'FAIL: select sursa id=1127: ' + ALLTRIM(NVL(goExecutor.cEroare,'')) + QUIT + ENDIF + IF RECCOUNT('cSursa') = 0 + DO PrLogLocal WITH 'FAIL: id=1127 nu exista in MARIUSM_AUTO.anaf_vefactura_trimis' + QUIT + ENDIF + SELECT cSursa + lnIdSursa = id + lnTestSursa = NVL(test, 0) + ldDataSursa = data_act + DO PrLogLocal WITH 'sursa: id=' + TRANSFORM(lnIdSursa) + ' numar=[' + ALLTRIM(NVL(numar_act, '')) + '] data=' + DTOC(ldDataSursa) + ' test=' + TRANSFORM(lnTestSursa) + ' tip_mesaj=' + ALLTRIM(NVL(tip_mesaj_raspuns, '')) + USE IN (SELECT('cSursa')) + + llLunaBlocataDiag = IS_LUNA_BLOCATA(gcS, gnId_Prg_Owner, YEAR(ldDataSursa), MONTH(ldDataSursa)) + DO PrLogLocal WITH 'diagnostic is_luna_blocata(' + TRANSFORM(YEAR(ldDataSursa)) + '/' + TRANSFORM(MONTH(ldDataSursa)) + ')=' + TRANSFORM(llLunaBlocataDiag) + ' (informativ - daca e .T., formularul de storno nu va aparea deloc)' + + *========================================================================= + DO PrLogLocal WITH '=== PAS 1: cursoarele borderoului (copie fluxul real ANAFeFactura.vizeFactura, anaf_efactura.prg:2867+) ===' + PUBLIC poFacturiEmise, poFacturiPrimite, poFacturiTrimise, poFacturiDetalii + LOCAL lcData1, lcSchema, lcSelect, lcFiltru, lcFiltruOriginal, lcOrder, lcgroup, llModParam, llAfiseaza + lcData1 = '01' + PADL(INT(gnLuna), 2, '0') + ALLTRIM(STR(gnAn)) + + * FACTURI PRIMITE (goale - nu sunt necesare pentru storno, dar cursorul trebuie sa existe: + * lipsa lui a lasat formularul cu controale incomplete intr-o sesiune anterioara - vezi + * testare-ui-vfp.md, capcana j) + TEXT TO lcSchema NOSHOW +ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1) + ENDTEXT + TEXT TO lcSelect NOSHOW +SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_primit + ENDTEXT + lcOrder = [data_act,numar_act,data_raspuns] + lcgroup = [] + lcFiltru = [1=2] + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + gencursor('poFacturiPrimite', 'crsFacturiPrimite', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiPrimite.ca_baza1.afisare() + SELECT crsFacturiPrimite + GO TOP + + * FACTURI TRIMISE - filtru tintit pe sursa reala (id=1127), nu pe luna curenta + TEXT TO lcSchema NOSHOW +ales N(1), id N(20), id_fact N(20), data_act D, data_scad D, numar_act C(30), xfurnizor C(200), xclient C(200), id_incarcare C(36), id_descarcare c(36) null, mesaj_trimis C(250) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, trimis N(1) null, data_trimis T null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, total_fara_tva N(16,4), total_tva N(16,4), total_tva_ron N(16,4), total_cu_tva N(16,4), discount_fara_tva N(16,4), taxe_fara_tva N(16,4), valoare_fara_tva N(16,4), total_de_plata N(16,4), nume_valuta C(5), test N(1) null, jtotctva N(16,4), descriere M null, detalii_plata M null, diferenta N(16,4), procesat N(1), tip_persoana N(1) null, descarcat N(1) null, filepath c(250) null, procesat_server N(1) null, creditnote N(1) + ENDTEXT + TEXT TO lcSelect NOSHOW +SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, id_incarcare, id_descarcare, mesaj_trimis, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, total_fara_tva, total_tva, total_tva_ron, total_cu_tva, discount_fara_tva, taxe_fara_tva, valoare_fara_tva, total_de_plata, nume_valuta, test, jtotctva, descriere, detalii_plata, decode(creditnote,0,1,-1) * NVL(total_cu_tva, 0.00)-NVL(jtotctva, 0.00) as diferenta, procesat, tip_persoana, descarcat, filepath, procesat_server, creditnote FROM anaf_vefactura_trimis + ENDTEXT + lcOrder = [data_act,numar_act,data_trimis,data_raspuns] + lcgroup = [] + lcFiltru = [id = 1127] + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + gencursor('poFacturiTrimise', 'crsFacturiTrimise', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiTrimise.ca_baza1.afisare() + SELECT crsFacturiTrimise + GO TOP + DO TVerdict WITH RECCOUNT('crsFacturiTrimise') = 1 AND NVL(crsFacturiTrimise.Id, 0) = lnIdSursa, 'PRECONDITIE crsFacturiTrimise populat cu id=1127 (flux real gencursor)', 'reccount=' + TRANSFORM(RECCOUNT('crsFacturiTrimise')) + ' id curent=' + TRANSFORM(NVL(crsFacturiTrimise.Id, 0)) + + * FACTURI EMISE (goale) + TEXT TO lcSchema NOSHOW +ales N(1), id N(20), id_fact N(20), id_vanzare N(10), data_act D, numar_act N(14), in_valuta N(1) null, curs N(10,4) null, valval N(16,2), tvaval N(16,2),totval N(16,2), total_fara_tva N(16,2), total_tva N(16,2), total_cu_tva N(16,2), nume_valuta C(5) null, client C(100), id_client N(10), cod_fiscal C(30), tip_persoana N(1) null, trimis N(1) null, data_trimis T null, stare C(100) null, id_incarcare C(36) null, mesaj_trimis C(250) null, id_descarcare c(36) null, tip_mesaj_raspuns C(50) null,mesaj_raspuns C(250) null, data_raspuns D null, cod_fiscal_emitent C(30) null, cod_fiscal_beneficiar C(30) null, detalii M null, xfurnizor C(200), xclient C(200), xdata_act D, xnumar_act C(30), xtotal_fara_tva N(16,4), xtotal_tva N(16,4), xtotal_tva_ron N(16,4), xtotal_cu_tva N(16,4), xdiscount_fara_tva N(16,4), xtaxe_fara_tva N(16,4), xvaloare_fara_tva N(16,4), xtotal_de_plata N(16,4), xnume_valuta C(5), test N(1) null, id_util N(10), utilizator C(100), jtotctva N(16,4), diferenta N(16,4), procesat N(1), procesat_server N(1), creditnote N(1) + ENDTEXT + TEXT TO lcSelect NOSHOW +SELECT 0 as ales, id, id_fact, id_vanzare, data_act, numar_act, in_valuta, curs, valval, tvaval, totval, total_fara_tva, total_tva,total_cu_tva, nume_valuta, client, id_client, cod_fiscal, NVL(tip_persoana,1) as tip_persoana, NVL(trimis,0) as trimis, data_trimis, stare, id_incarcare, mesaj_trimis, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, cod_fiscal_emitent, cod_fiscal_beneficiar, '' as detalii, xfurnizor, xclient, xdata_act, xnumar_act, xtotal_fara_tva, xtotal_tva, xtotal_tva_ron, xtotal_cu_tva, xdiscount_fara_tva, xtaxe_fara_tva, xvaloare_fara_tva, xtotal_de_plata, xnume_valuta, test, id_util, utilizator, jtotctva, decode(creditnote,0,1,-1) * ROUND(NVL(xtotal_cu_tva , 0.00) * decode(in_valuta,1,curs,1), 2)-NVL(jtotctva, 0.00) as diferenta, procesat, procesat_server,creditnote FROM anaf_vefactura_emis + ENDTEXT + lcOrder = [data_act,numar_act] + lcgroup = [] + lcFiltru = [1=2] + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + gencursor('poFacturiEmise', 'crsFacturiEmise', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiEmise.ca_baza1.afisare() + + * DETALII (goale) + TEXT TO lcSchema NOSHOW +id N(20), id_efactura N(20), nr N(5), articol V(250), descriere V(250), detalii M, cantitate N(18,6), um V(20), pret N(20,6), proctva N(7,2), valoarefaratva N(20,6), discountfaratva N(20,6) + ENDTEXT + TEXT TO lcSelect NOSHOW +select id, id_efactura, nr, articol, descriere, detalii, cantitate, um, pret, proctva, valoarefaratva, discountfaratva from anaf_vefactura_detalii + ENDTEXT + lcOrder = [nr] + lcgroup = [] + lcFiltru = [1=2] + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + gencursor('poFacturiDetalii', 'crsDetaliiFacturi', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiDetalii.ca_baza1.afisare() + + *========================================================================= + DO PrLogLocal WITH '=== PAS 2: forma REALA anaf_efactura (modeless) + mock pe AnafeFacturaServer ===' + LOCAL lcCifReal + loAnaf = CREATEOBJECT('ANAFeFactura') + lcCifReal = ALLTRIM(loAnaf.AnafeFacturaServer.cCodFiscal) + DO PrLogLocal WITH 'AnafeFacturaServer real (INAINTE de inlocuire): cCodFiscal=[' + lcCifReal + '] lTest=' + TRANSFORM(loAnaf.AnafeFacturaServer.lTest) + + loMockSrv = NEWOBJECT('MockAnafServerStorno', gcTestDir + 'mock_anaf_server_storno.prg') + loMockSrv.cCodFiscal = lcCifReal + loMockSrv.lTest = (lnTestSursa = 1) + loAnaf.AnafeFacturaServer = loMockSrv + DO PrLogLocal WITH 'AnafeFacturaServer INLOCUIT cu MockAnafServerStorno (ZERO retea): cCodFiscal=[' + loAnaf.AnafeFacturaServer.cCodFiscal + '] lTest=' + TRANSFORM(loAnaf.AnafeFacturaServer.lTest) + ' Class=' + loAnaf.AnafeFacturaServer.Class +CATCH TO loExOuter + DO PrLogLocal WITH 'EXCEPTIE NEPRINSA: ' + loExOuter.Message + ' (' + TRANSFORM(loExOuter.LineNo) + ') ' + loExOuter.Procedure + gnFail = gnFail + 1 + DO PrLogLocal WITH 'REZULTAT FINAL: PASS=' + TRANSFORM(gnPass) + ' FAIL=' + TRANSFORM(gnFail) + QUIT +ENDTRY + +* ABATERE: instantiat prin frmtest_anaf.scx (subclasa goala peste anaf_efactura.vcx, stub de test, +* vezi frmtest_anaf.sc2 in acest folder) in loc de CREATEOBJECT direct pe clasa din .vcx - sfatul +* lui Marius: instantierea prin forma .scx arata calea COMPLETA a controlului in mesajul de eroare, +* nu doar numele de baza "_checkbox1". Afara din orice TRY, ca eroarea sa treaca prin ON ERROR +* (logata cu AERROR, executia continua) in loc sa opreasca testul. +* CREATEOBJECT('form1', ) a dat "Class definition FORM1 is not found" - .scx foloseste alt +* mecanism de incarcare decat .vcx; DO FORM e calea nativa pentru clase de forma. +DO FORM (gcTestDir + 'frmtest_anaf.scx') NAME loForm NOSHOW WITH loAnaf +IF VARTYPE(loForm) != 'O' + DO PrLogLocal WITH 'FAIL: DO FORM frmtest_anaf nu a returnat obiect, VARTYPE=' + VARTYPE(loForm) + QUIT +ENDIF +DO PrLogLocal WITH 'loForm creat dupa eroarea 177 (abatere de mediu, consemnata): VARTYPE=O, Class=' + loForm.Class + +TRY + DO PrLogLocal WITH 'ClassLibrary anaf_efactura = implicit, via SET CLASSLIB (COMUN\CLASE\anaf_efactura.vcx, binar real cu write-back)' + * ABATERE: loForm.Show() NU se apeleaza (nu e necesar - do_storno_efactura foloseste doar + * Thisform.oAnaf si crsFacturiTrimise). + loForm.WindowType = 0 + DO PrLogLocal WITH 'BORDEROU creat (nu afisat - vezi abaterea de mai sus): Class=' + loForm.Class + + *========================================================================= + DO PrLogLocal WITH '=== PAS 3: driver Timer pe _SCREEN (Show(1) in do_storno_efactura e modal si pompeaza mesaje Windows) ===' + IF TYPE('_SCREEN.tmrDrvStorno') = 'U' + _SCREEN.ADDOBJECT('tmrDrvStorno', 'Timer') + ENDIF + _SCREEN.tmrDrvStorno.Interval = 200 + PUBLIC loDriverStorno + loDriverStorno = CREATEOBJECT('DriverStorno') + BINDEVENT(_SCREEN.tmrDrvStorno, 'Timer', loDriverStorno, 'Executa') + _SCREEN.tmrDrvStorno.Enabled = .T. + + DO PrLogLocal WITH '=== PAS 4: This.do_storno_efactura() - exact ce apeleaza optiunea de meniu 10 (anaf_efactura.vc2:5829) ===' + DO PrLogLocal WITH 'ON(ERROR) inainte de do_storno_efactura: [' + ON('ERROR') + ']' + loForm.do_storno_efactura() + + _SCREEN.tmrDrvStorno.Enabled = .F. + TRY + UNBINDEVENTS(_SCREEN.tmrDrvStorno) + CATCH + ENDTRY + + DO TVerdict WITH loDriverStorno.lDone, 'driverul a ajuns la final (a tratat forma de storno pana la capat)', 'nState final=' + TRANSFORM(loDriverStorno.nState) + ' tick-uri=' + TRANSFORM(loDriverStorno.nTicks) + + LOCAL i + IF !loDriverStorno.lDone OR loDriverStorno.nState < 4 + FOR i = 1 TO gnAmsgCalls + DO PrLogLocal WITH 'AMESSAGEBOX vazut: [' + gaAmsgCalls[i, 1] + '] -> ' + TRANSFORM(gaAmsgCalls[i, 2]) + ENDFOR + ENDIF + + DO PrLogLocal WITH 'TOTAL apeluri mock server: ' + TRANSFORM(gnMockApeluri) + FOR i = 1 TO gnMockApeluri + DO PrLogLocal WITH ' mock[' + TRANSFORM(i) + '] ' + gaMockApeluri[i, 1] + ' | ' + gaMockApeluri[i, 2] + ' | ' + gaMockApeluri[i, 3] + ENDFOR + + TRY + loForm.Release() + CATCH + ENDTRY + + DO PrLogLocal WITH 'REZULTAT FINAL: PASS=' + TRANSFORM(gnPass) + ' FAIL=' + TRANSFORM(gnFail) +CATCH TO loExOuter + DO PrLogLocal WITH 'EXCEPTIE NEPRINSA: ' + loExOuter.Message + ' (' + TRANSFORM(loExOuter.LineNo) + ') ' + loExOuter.Procedure + gnFail = gnFail + 1 + DO PrLogLocal WITH 'REZULTAT FINAL: PASS=' + TRANSFORM(gnPass) + ' FAIL=' + TRANSFORM(gnFail) +ENDTRY + +QUIT + +********************************************************** +PROCEDURE TVerdict + LPARAMETERS tlCond, tcLabel, tcDetaliu + IF tlCond + gnPass = gnPass + 1 + DO PrLogLocal WITH 'PASS ' + tcLabel + ' | ' + TRANSFORM(tcDetaliu) + ELSE + gnFail = gnFail + 1 + DO PrLogLocal WITH 'FAIL ' + tcLabel + ' | ' + TRANSFORM(tcDetaliu) + ENDIF +ENDPROC + +********************************************************** +PROCEDURE PrLogLocal + LPARAMETERS tcMsg + LOCAL lcL + SET SAFETY OFF + lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + STRTOFILE(lcL + TTOC(DATETIME()) + ' ' + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcUILog) +ENDPROC + +********************************************************** +PROCEDURE PrErrLocal + LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo + LOCAL laErrDetail[1], i, lcDetail + lnLastErrorNo = tnError + lcLastErrorMsg = TRANSFORM(tcMessage) + DO PrLogLocal WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo) + AERROR(laErrDetail) + lcDetail = '' + FOR i = 1 TO ALEN(laErrDetail, 1) + lcDetail = lcDetail + TRANSFORM(i) + '=[' + TRANSFORM(NVL(laErrDetail[i], '')) + '] ' + ENDFOR + DO PrLogLocal WITH 'AERROR: ' + lcDetail +ENDPROC + +********************************************************** +FUNCTION ExistaApelMock + LPARAMETERS tcMetoda + LOCAL i + FOR i = 1 TO gnMockApeluri + IF gaMockApeluri[i, 1] == tcMetoda + RETURN .T. + ENDIF + ENDFOR + RETURN .F. +ENDFUNC + +********************************************************** +* Driver pentru dialogul modal Show(1) al frm_storno_efactura (deschis din interiorul +* do_storno_efactura). Vezi COMUN\docs\testare-ui-vfp.md, sectiunea "Dialoguri modale (Show(1))", +* varianta B: Timer pe _SCREEN, detectie prin _SCREEN.Forms (nu _SCREEN.ActiveForm - nu merge +* headless). +DEFINE CLASS DriverStorno AS Custom + nState = 0 + nTicks = 0 + lDone = .F. + + PROCEDURE Executa + LOCAL loStorno, i, llRet + LOCAL loExD + This.nTicks = This.nTicks + 1 + IF This.nTicks = 1 + DO PrLogLocal WITH 'ON(ERROR) in interiorul DriverStorno.Executa (primul tick): [' + ON('ERROR') + ']' + ENDIF + TRY + DO CASE + CASE This.nState = 0 + loStorno = .NULL. + FOR i = 1 TO _SCREEN.FormCount + IF UPPER(_SCREEN.Forms(i).Class) == 'FRM_STORNO_EFACTURA' + loStorno = _SCREEN.Forms(i) + EXIT + ENDIF + ENDFOR + IF ISNULL(loStorno) + IF This.nTicks > 150 + DO PrLogLocal WITH 'DRIVER FAIL: frm_storno_efactura nu a aparut in ~30s (nState=0)' + gnFail = gnFail + 1 + This.lDone = .T. + _SCREEN.tmrDrvStorno.Enabled = .F. + ENDIF + RETURN + ENDIF + loStornoForm = loStorno + DO PrLogLocal WITH 'DRIVER: frm_storno_efactura gasita dupa ' + TRANSFORM(This.nTicks) + ' tick-uri, Class=' + loStorno.Class + DO TVerdict WITH lnLastErrorNo = 0, 'fara eroare pana la afisarea formei stornului', 'lnLastErrorNo=' + TRANSFORM(lnLastErrorNo) + ' [' + lcLastErrorMsg + ']' + DO TVerdict WITH RECCOUNT('crsStornoDetalii') > 0, 'grid crsStornoDetalii populat', 'reccount=' + TRANSFORM(RECCOUNT('crsStornoDetalii')) + DO TVerdict WITH 'TEST' $ UPPER(loStorno.Caption), 'Caption contine TEST', 'caption=[' + loStorno.Caption + ']' + DO TVerdict WITH UPPER(ALLTRIM(loStorno.lblStare.Caption)) == 'NEVALIDAT', 'stare initiala Nevalidat', 'stare=[' + loStorno.lblStare.Caption + ']' + DO TVerdict WITH FILE(loStorno.pcFisierStorno), 'fisier storno exista pe disc', 'fisier=[' + loStorno.pcFisierStorno + ']' + This.nState = 1 + + CASE This.nState = 1 + loStorno = loStornoForm + loStorno.pcNumarNou = ALLTRIM(loStorno.pcNumarNou) + 'X' + loStorno.pcMotiv = 'Motiv test E2E' + llRet = loStorno.RegenereazaXml() + DO TVerdict WITH llRet, 'RegenereazaXml dupa schimbare numar/motiv', 'numarnou=[' + loStorno.pcNumarNou + '] return=' + TRANSFORM(llRet) + DO TVerdict WITH RECCOUNT('crsStornoDetalii') > 0, 'grid populat dupa regenerare', 'reccount=' + TRANSFORM(RECCOUNT('crsStornoDetalii')) + This.nState = 2 + + CASE This.nState = 2 + loStorno = loStornoForm + loStorno.SetStare(1) + DO TVerdict WITH UPPER(ALLTRIM(loStorno.lblStare.Caption)) == 'VALID', 'SetStare(1) -> Valid (ocolire ValidareEFacturaANAF, retea reala, cf. instructiuni)', 'stare=[' + loStorno.lblStare.Caption + ']' + loStorno.cmdTrimite.Click() + DO TVerdict WITH UPPER(ALLTRIM(loStorno.lblStare.Caption)) == 'TRIMIS', 'dupa cmdTrimite.Click -> Trimis', 'stare=[' + loStorno.lblStare.Caption + ']' + DO TVerdict WITH ExistaApelMock('TrimiteFacturaXML'), 'mock a primit TrimiteFacturaXML', '' + This.nState = 3 + + CASE This.nState = 3 + loStorno = loStornoForm + TRY + loStorno.Release() + CATCH TO loExD + DO PrLogLocal WITH 'DRIVER: eroare la Release: ' + loExD.Message + ENDTRY + This.lDone = .T. + This.nState = 4 + _SCREEN.tmrDrvStorno.Enabled = .F. + ENDCASE + CATCH TO loExD + DO PrLogLocal WITH 'DRIVER EXCEPTIE nState=' + TRANSFORM(This.nState) + ': ' + loExD.Message + ' linia ' + TRANSFORM(loExD.LineNo) + gnFail = gnFail + 1 + This.lDone = .T. + _SCREEN.tmrDrvStorno.Enabled = .F. + TRY + loStornoForm.Release() + CATCH + ENDTRY + ENDTRY + ENDPROC +ENDDEFINE diff --git a/utile/Teste/storno/test_storno_efactura.prg b/utile/Teste/storno/test_storno_efactura.prg new file mode 100644 index 0000000..e55a3d3 --- /dev/null +++ b/utile/Teste/storno/test_storno_efactura.prg @@ -0,0 +1,449 @@ +* test_storno_efactura.prg +* Teste StornoEFacturaXML/GetXmlOriginalEFactura (COMUN\programe\anaf_efactura.prg) si +* rutarea CN/FCN + B2C din SendEfactura/ValidareEFacturaANAF (verificare fara retea). +* Fixturi in COMUN\utile\Teste\storno\ (anonimizate, cu diacritice reale la fixtura din id 3795). +* +* Rulare: vfp9.exe -A -T "D:\ROA\ROACONT\COMUN\utile\Teste\storno\test_storno_efactura.prg" +* Iesire in D:\ROA\ROACONT\COMUN\utile\Teste\storno\test_storno_efactura_log.txt + +SET SAFETY OFF +SET TALK OFF +SET DELETED ON +SET EXACT ON +SET CENTURY ON +SET DATE DMY +SET NULLDISPLAY TO '' +CLOSE DATABASES + +PUBLIC gcUILog, gcFixDir, gcOutDir +gcFixDir = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\" +gcOutDir = "D:\ROA\ROACONT\COMUN\utile\Teste\storno\out\" +IF !DIRECTORY(gcOutDir) + MD (gcOutDir) +ENDIF +gcUILog = gcFixDir + "test_storno_efactura_log.txt" +STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO PrErrLocal WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +PUBLIC lnPass, lnFail +lnPass = 0 +lnFail = 0 + +TRY + DO "D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg" WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' + IF gnHandle <= 0 + DO PrLogLocal WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')' + QUIT + ENDIF + DO PrLogLocal WITH 'mediu initializat, gnHandle=' + TRANSFORM(gnHandle) + ' gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + + *========================================================================= + DO PrLogLocal WITH '=== TEST 0: functiile noi sunt incarcate (SET PROCEDURE anaf_efactura.prg din init) ===' + LOCAL lcMsg0, llRet0 + LOCAL laMod0[1,4] + llRet0 = StornoEFacturaXML('', '', '', gcOutDir + 't0.xml', @laMod0, @lcMsg0) + DO Assert WITH !llRet0 AND 'gol' $ LOWER(lcMsg0), 'StornoEFacturaXML e apelabila si valideaza XML gol', 'retur=' + TRANSFORM(llRet0) + ' mesaj=[' + lcMsg0 + ']' + + *========================================================================= + DO PrLogLocal WITH '=== TEST 1 + 1b + 2: round-trip dubla negare + diacritice + noduri neatinse (fixtura reala id 3795) ===' + DO TestRoundTrip WITH 'storno_fixture_diacritice_reale.xml', 'diacritice_reale', .T. + + DO PrLogLocal WITH '=== TEST 1 + 2: round-trip (fixtura simpla cu reduceri/majorari pe document) ===' + DO TestRoundTrip WITH 'storno_fixture_diacritice_reale.xml', 'diacritice_reale_bis', .F. + + DO PrLogLocal WITH '=== TEST 1 + 1c: round-trip + namespace corect pe prefixe custom n1/n2/n3 ===' + DO TestRoundTrip WITH 'storno_fixture_prefix_n3.xml', 'prefix_n3', .F. + DO TestNamespaceN3 + + DO PrLogLocal WITH '=== TEST 1: round-trip pe CreditNote minimal ===' + DO TestRoundTrip WITH 'storno_fixture_creditnote_minimal.xml', 'creditnote_minimal', .F. + + DO PrLogLocal WITH '=== TEST 1: round-trip pe factura deja negativa (D13: permisa) ===' + DO TestRoundTrip WITH 'storno_fixture_factura_negativa.xml', 'factura_negativa', .F. + + DO PrLogLocal WITH '=== TEST 1: sume zero / -0.00 raman neschimbate (nu apar in taModificari) ===' + DO TestSumeZero + + DO PrLogLocal WITH '=== TEST 1: cbc:Amount in PaymentTerms NU se neaga (doar Amount/BaseAmount sub AllowanceCharge) ===' + DO TestPaymentTermsNeatins + + DO PrLogLocal WITH '=== TEST: motiv cu caractere speciale (& si <) scris corect prin DOM, nu concatenare ===' + DO TestMotivSpecial + + DO PrLogLocal WITH '=== TEST: numar nou cu slash pastrat exact (scris prin DOM) ===' + DO TestNumarCuSlash + + DO PrLogLocal WITH '=== TEST 3b: blocaje fara retea (in interiorul StornoEFacturaXML) ===' + DO TestBlocaje + + DO PrLogLocal WITH '=== TEST: fixtura B2C (CNP 13 cifre) si furnizor fara PartyTaxScheme - parsare OK, pregatite pentru Lane 2/C ===' + DO TestRoundTrip WITH 'storno_fixture_b2c_cnp.xml', 'b2c_cnp', .F. + DO TestRoundTrip WITH 'storno_fixture_fara_partytaxscheme.xml', 'fara_partytaxscheme', .F. + + DO PrLogLocal WITH '=== TEST: rutare CN/FCN si B2C (logica SendEfactura/ValidareEFacturaANAF, fara apel retea) ===' + DO TestRutareCNSiB2C + + DO PrLogLocal WITH '=== TEST 3: validare online ANAF TEST - neexecutat (fara token de test verificat; risc cunoscut SET STEP ON anaf_efactura.prg:717 cu token expirat) ===' + + DO PrLogLocal WITH '=== TEST 4: upload real ANAF - INTERZIS pentru Lane 1, neexecutat ===' + + DO PrLogLocal WITH 'TOTAL: PASS=' + TRANSFORM(lnPass) + ' FAIL=' + TRANSFORM(lnFail) + DO PrLogLocal WITH 'TOTAL: test terminat fara exceptie' +CATCH TO loEx + DO PrLogLocal WITH 'EXCEPTIE: ' + loEx.Message + ' (' + TRANSFORM(loEx.LineNo) + ') ' + loEx.Procedure +ENDTRY + +QUIT + +********************************************************** +* neaga de doua ori (storno al storno-ului) si verifica identitatea: valorile noi din a doua +* trecere trebuie sa fie exact valorile originale din prima trecere (textual, fara rotunjire). +* Foloseste taModificari (nu re-parseaza XML-ul), deci verifica direct contractul functiei. +PROCEDURE TestRoundTrip + LPARAMETERS tcFixtura, tcLabel, tlVerificaDiacritice + + LOCAL lcXml, lcFile1, lcFile2, lcMsg1, lcMsg2, llRet1, llRet2 + LOCAL laMod1[1,4], laMod2[1,4] + + IF !FILE(gcFixDir + tcFixtura) + DO Assert WITH .F., '[' + tcLabel + '] fixtura exista', gcFixDir + tcFixtura + RETURN + ENDIF + lcXml = FILETOSTR(gcFixDir + tcFixtura) + lcFile1 = gcOutDir + tcLabel + '_storno1.xml' + lcFile2 = gcOutDir + tcLabel + '_storno2.xml' + + llRet1 = StornoEFacturaXML(m.lcXml, '', 'Stornare factura test ' + m.tcLabel, m.lcFile1, @laMod1, @lcMsg1) + DO Assert WITH llRet1, '[' + tcLabel + '] StornoEFacturaXML (prima trecere) reuseste', 'mesaj=[' + lcMsg1 + ']' + IF !llRet1 + RETURN + ENDIF + DO Assert WITH FILE(m.lcFile1), '[' + tcLabel + '] fisierul storno1 exista pe disc', m.lcFile1 + + IF m.tlVerificaDiacritice + LOCAL lcBrutOriginal, lcBrutStorno + lcBrutOriginal = FILETOSTR(gcFixDir + tcFixtura) + lcBrutStorno = FILETOSTR(m.lcFile1) + *-- Constan[C5 A3]a (U+0163, "t cu virgula") pastrat identic pe octeti in storno + DO Assert WITH ('Constan' + CHR(0xC5) + CHR(0xA3) + 'a') $ m.lcBrutStorno, '[' + tcLabel + '] 1b: diacritice C5 A3 (U+0163) pastrate pe octeti in storno1', 'len=' + TRANSFORM(LEN(m.lcBrutStorno)) + ENDIF + + llRet2 = StornoEFacturaXML(FILETOSTR(m.lcFile1), 'ORIG-TEST-' + tcLabel, '', m.lcFile2, @laMod2, @lcMsg2) + DO Assert WITH llRet2, '[' + tcLabel + '] StornoEFacturaXML (a doua trecere, pe storno1) reuseste', 'mesaj=[' + lcMsg2 + ']' + IF !llRet2 + RETURN + ENDIF + + *-- filtreaza doar randurile de sume/cantitati (tip 2 total, tip 3 linie), fara antet (tip 1) + LOCAL lnI, lnJ1, lnJ2 + DIMENSION laF1[1], laF2[1] + lnJ1 = 0 + FOR lnI = 1 TO ALEN(laMod1, 1) + IF laMod1[lnI, 4] = 2 OR laMod1[lnI, 4] = 3 + lnJ1 = lnJ1 + 1 + DIMENSION laF1[lnJ1, 2] + laF1[lnJ1, 1] = laMod1[lnI, 2] + laF1[lnJ1, 2] = laMod1[lnI, 3] + ENDIF + ENDFOR + lnJ2 = 0 + FOR lnI = 1 TO ALEN(laMod2, 1) + IF laMod2[lnI, 4] = 2 OR laMod2[lnI, 4] = 3 + lnJ2 = lnJ2 + 1 + DIMENSION laF2[lnJ2, 2] + laF2[lnJ2, 1] = laMod2[lnI, 2] + laF2[lnJ2, 2] = laMod2[lnI, 3] + ENDIF + ENDFOR + + DO Assert WITH lnJ1 = lnJ2 AND lnJ1 > 0, '[' + tcLabel + '] 1: numarul de noduri numerice negate e acelasi la dus si intors', 'trecere1=' + TRANSFORM(lnJ1) + ' trecere2=' + TRANSFORM(lnJ2) + + IF lnJ1 = lnJ2 AND lnJ1 > 0 + LOCAL llToateOk + llToateOk = .T. + FOR lnI = 1 TO lnJ1 + *-- valoarea noua din trecerea 1 (negata) trebuie sa fie valoarea originala din trecerea 2 + IF ALLTRIM(laF1[lnI, 2]) <> ALLTRIM(laF2[lnI, 1]) + llToateOk = .F. + ENDIF + *-- valoarea noua din trecerea 2 (negata a doua oara) trebuie sa fie exact valoarea originala din trecerea 1 + IF ALLTRIM(laF1[lnI, 1]) <> ALLTRIM(laF2[lnI, 2]) + llToateOk = .F. + ENDIF + ENDFOR + DO Assert WITH llToateOk, '[' + tcLabel + '] 1: dubla negare da exact valorile originale (textual)', '' + ENDIF + + *-- 2: un nod static, neatins de negare, ramane identic intre original si storno1 + LOCAL loDOMOrig, loDOMStorno, loNodOrig, loNodStorno + loDOMOrig = CREATEOBJECT('MSXML2.DOMDocument.6.0') + loDOMOrig.Async = .F. + loDOMOrig.setProperty('SelectionLanguage', 'XPath') + loDOMOrig.LoadXML(m.lcXml) + loDOMStorno = CREATEOBJECT('MSXML2.DOMDocument.6.0') + loDOMStorno.Async = .F. + loDOMStorno.setProperty('SelectionLanguage', 'XPath') + loDOMStorno.Load(m.lcFile1) + + loNodOrig = loDOMOrig.documentElement.selectSingleNode("//*[local-name()='RegistrationName']") + loNodStorno = loDOMStorno.documentElement.selectSingleNode("//*[local-name()='RegistrationName']") + IF !ISNULL(m.loNodOrig) AND !ISNULL(m.loNodStorno) + DO Assert WITH loNodOrig.Text == loNodStorno.Text, '[' + tcLabel + '] 2: RegistrationName (nod neatins) identic in storno', '[' + loNodOrig.Text + '] vs [' + loNodStorno.Text + ']' + ENDIF + + *-- ID radacinii trebuie sa fie exact numarul cerut (implicit + '-S') + LOCAL loIdOrig, loIdStorno + loIdOrig = loDOMOrig.documentElement.selectSingleNode("*[local-name()='ID']") + loIdStorno = loDOMStorno.documentElement.selectSingleNode("*[local-name()='ID']") + IF !ISNULL(m.loIdOrig) AND !ISNULL(m.loIdStorno) + DO Assert WITH ALLTRIM(loIdStorno.Text) == ALLTRIM(loIdOrig.Text) + '-S', '[' + tcLabel + '] numar storno implicit = numar original + -S', '[' + loIdStorno.Text + ']' + ENDIF + + *-- BillingReference catre originalul (numarul VECHI, dinainte de schimbare) + LOCAL loRef + loRef = loDOMStorno.documentElement.selectSingleNode("//*[local-name()='BillingReference']/*[local-name()='InvoiceDocumentReference']/*[local-name()='ID']") + IF !ISNULL(m.loRef) AND !ISNULL(m.loIdOrig) + DO Assert WITH ALLTRIM(loRef.Text) == ALLTRIM(loIdOrig.Text), '[' + tcLabel + '] BillingReference contine numarul original', '[' + loRef.Text + ']' + ELSE + DO Assert WITH .F., '[' + tcLabel + '] BillingReference/InvoiceDocumentReference/ID gasit', '' + ENDIF + + *-- Nota scrisa (a fost trimisa nevida la trecerea 1) + LOCAL loNote + loNote = loDOMStorno.documentElement.selectSingleNode("*[local-name()='Note']") + IF !ISNULL(m.loNote) + DO Assert WITH 'Stornare factura test' $ loNote.Text, '[' + tcLabel + '] Nota scrisa pe document', '[' + loNote.Text + ']' + ELSE + DO Assert WITH .F., '[' + tcLabel + '] Nota (cbc:Note) gasita dupa storno', '' + ENDIF +ENDPROC + +********************************************************** +* namespace-ul nodurilor NOI (BillingReference/ID, Note) trebuie sa fie cel din radacina +* originalului (n1/CommonBasicComponents-2, n2/CommonAggregateComponents-2), nu prefix implicit +PROCEDURE TestNamespaceN3 + LOCAL lcFile1, loDOM, loRef, loNote + LOCAL lcUriCbc, lcUriCac + lcUriCbc = 'urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2' + lcUriCac = 'urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2' + lcFile1 = gcOutDir + 'prefix_n3_storno1.xml' + IF !FILE(m.lcFile1) + DO Assert WITH .F., '[prefix_n3] 1c: fisierul storno1 exista (rulat de TestRoundTrip)', m.lcFile1 + RETURN + ENDIF + + loDOM = CREATEOBJECT('MSXML2.DOMDocument.6.0') + loDOM.Async = .F. + loDOM.setProperty('SelectionLanguage', 'XPath') + loDOM.Load(m.lcFile1) + + loRef = loDOM.documentElement.selectSingleNode("//*[local-name()='BillingReference']") + IF !ISNULL(m.loRef) + DO Assert WITH loRef.namespaceURI == lcUriCac, '[prefix_n3] 1c: BillingReference in namespace cac corect', loRef.namespaceURI + ELSE + DO Assert WITH .F., '[prefix_n3] 1c: BillingReference gasit', '' + ENDIF + + LOCAL loRefId + loRefId = loDOM.documentElement.selectSingleNode("//*[local-name()='BillingReference']/*[local-name()='InvoiceDocumentReference']/*[local-name()='ID']") + IF !ISNULL(m.loRefId) + DO Assert WITH loRefId.namespaceURI == lcUriCbc, '[prefix_n3] 1c: ID din InvoiceDocumentReference in namespace cbc corect', loRefId.namespaceURI + ELSE + DO Assert WITH .F., '[prefix_n3] 1c: BillingReference/InvoiceDocumentReference/ID gasit', '' + ENDIF + + loNote = loDOM.documentElement.selectSingleNode("*[local-name()='Note']") + IF !ISNULL(m.loNote) + DO Assert WITH loNote.namespaceURI == lcUriCbc, '[prefix_n3] 1c: Note in namespace cbc corect', loNote.namespaceURI + ELSE + DO Assert WITH .F., '[prefix_n3] 1c: Note gasita', '' + ENDIF +ENDPROC + +********************************************************** +* -0.00 si 0.00 nu trebuie sa apara deloc in taModificari (raman neschimbate, cf. spec) +PROCEDURE TestSumeZero + LOCAL lcXml, lcFile, lcMsg, llRet + LOCAL laMod[1,4] + lcXml = FILETOSTR(gcFixDir + 'storno_fixture_sume_zero.xml') + lcFile = gcOutDir + 'sume_zero_storno1.xml' + llRet = StornoEFacturaXML(m.lcXml, '', '', m.lcFile, @laMod, @lcMsg) + DO Assert WITH llRet, '[sume_zero] StornoEFacturaXML reuseste', 'mesaj=[' + lcMsg + ']' + IF !llRet + RETURN + ENDIF + + LOCAL lnI, llGasitZero + llGasitZero = .F. + FOR lnI = 1 TO ALEN(laMod, 1) + IF (laMod[lnI, 4] = 2 OR laMod[lnI, 4] = 3) AND ('0.00' $ laMod[lnI, 2] OR '0,00' $ laMod[lnI, 2]) + IF VAL(STRTRAN(ALLTRIM(laMod[lnI, 2]), '-', '')) = 0 + llGasitZero = .T. + ENDIF + ENDIF + ENDFOR + DO Assert WITH !llGasitZero, '[sume_zero] nicio valoare zero (inclusiv -0.00) nu apare in taModificari', 'randuri=' + TRANSFORM(ALEN(laMod,1)) + + *-- verificare directa pe fisier: -0.00 din AllowanceCharge/Amount ramane neschimbat + LOCAL lcOut + lcOut = FILETOSTR(m.lcFile) + DO Assert WITH '-0.00' $ m.lcOut, '[sume_zero] -0.00 (AllowanceCharge/Amount) prezent neschimbat in storno', '' +ENDPROC + +********************************************************** +* cbc:Amount din cac:PaymentTerms nu are parintele AllowanceCharge -> nu se neaga +PROCEDURE TestPaymentTermsNeatins + LOCAL lcXml, lcFile, lcMsg, llRet + LOCAL laMod[1,4] + lcXml = FILETOSTR(gcFixDir + 'storno_fixture_paymentterms.xml') + lcFile = gcOutDir + 'paymentterms_storno1.xml' + llRet = StornoEFacturaXML(m.lcXml, '', '', m.lcFile, @laMod, @lcMsg) + DO Assert WITH llRet, '[paymentterms] StornoEFacturaXML reuseste', 'mesaj=[' + lcMsg + ']' + IF !llRet + RETURN + ENDIF + + LOCAL loDOM, loPT + loDOM = CREATEOBJECT('MSXML2.DOMDocument.6.0') + loDOM.Async = .F. + loDOM.setProperty('SelectionLanguage', 'XPath') + loDOM.Load(m.lcFile) + loPT = loDOM.documentElement.selectSingleNode("//*[local-name()='PaymentTerms']/*[local-name()='Amount']") + IF !ISNULL(m.loPT) + DO Assert WITH ALLTRIM(loPT.Text) == '119.00', '[paymentterms] cbc:Amount din PaymentTerms ramane neatins (119.00)', '[' + loPT.Text + ']' + ELSE + DO Assert WITH .F., '[paymentterms] nodul PaymentTerms/Amount gasit', '' + ENDIF +ENDPROC + +********************************************************** +* Nota cu '&' si '<' scrisa prin .Text (DOM face escape automat) - XML-ul ramane valid +PROCEDURE TestMotivSpecial + LOCAL lcXml, lcFile, lcMsg, llRet, lcNota + LOCAL laMod[1,4] + lcXml = FILETOSTR(gcFixDir + 'storno_fixture_diacritice_reale.xml') + lcFile = gcOutDir + 'motiv_special_storno1.xml' + lcNota = 'Marfa < prag & retur client' + llRet = StornoEFacturaXML(m.lcXml, '', m.lcNota, m.lcFile, @laMod, @lcMsg) + DO Assert WITH llRet, '[motiv_special] StornoEFacturaXML reuseste cu motiv & si <', 'mesaj=[' + lcMsg + ']' + IF !llRet + RETURN + ENDIF + + LOCAL loDOM, loNote + loDOM = CREATEOBJECT('MSXML2.DOMDocument.6.0') + loDOM.Async = .F. + loDOM.setProperty('SelectionLanguage', 'XPath') + loDOM.Load(m.lcFile) + DO Assert WITH loDOM.parseError.errorcode = 0, '[motiv_special] xml-ul rezultat e valid (parseError=0)', TRANSFORM(loDOM.parseError.errorcode) + loNote = loDOM.documentElement.selectSingleNode("*[local-name()='Note']") + IF !ISNULL(m.loNote) + DO Assert WITH loNote.Text == m.lcNota, '[motiv_special] textul notei intact dupa reincarcare (& si < pastrate ca text)', '[' + loNote.Text + ']' + ELSE + DO Assert WITH .F., '[motiv_special] Note gasita', '' + ENDIF +ENDPROC + +********************************************************** +* numar cu '/' (documente cu numerotare pe serie/numar) scris prin .Text, fara conflict XML +PROCEDURE TestNumarCuSlash + LOCAL lcXml, lcFile, lcMsg, llRet, lcNumar + LOCAL laMod[1,4] + lcXml = FILETOSTR(gcFixDir + 'storno_fixture_diacritice_reale.xml') + lcFile = gcOutDir + 'numar_slash_storno1.xml' + lcNumar = 'FF/2026/S' + llRet = StornoEFacturaXML(m.lcXml, m.lcNumar, '', m.lcFile, @laMod, @lcMsg) + DO Assert WITH llRet, '[numar_slash] StornoEFacturaXML reuseste cu numar continand /', 'mesaj=[' + lcMsg + ']' + IF !llRet + RETURN + ENDIF + + LOCAL loDOM, loId + loDOM = CREATEOBJECT('MSXML2.DOMDocument.6.0') + loDOM.Async = .F. + loDOM.setProperty('SelectionLanguage', 'XPath') + loDOM.Load(m.lcFile) + loId = loDOM.documentElement.selectSingleNode("*[local-name()='ID']") + IF !ISNULL(m.loId) + DO Assert WITH loId.Text == m.lcNumar, '[numar_slash] ID radacinii = numarul cu / exact', '[' + loId.Text + ']' + ELSE + DO Assert WITH .F., '[numar_slash] ID gasit', '' + ENDIF +ENDPROC + +********************************************************** +* blocaje interne StornoEFacturaXML, fara nicio conexiune de retea +PROCEDURE TestBlocaje + LOCAL lcMsg, llRet + LOCAL laMod[1,4] + + llRet = StornoEFacturaXML('', '', '', gcOutDir + 'blocaj_gol.xml', @laMod, @lcMsg) + DO Assert WITH !llRet AND 'gol' $ LOWER(lcMsg), '3b: XML gol -> blocare cu mesaj clar', '[' + lcMsg + ']' + + llRet = StornoEFacturaXML(' eroare de parsare', '[' + lcMsg + ']' + + llRet = StornoEFacturaXML('1', '', '', gcOutDir + 'blocaj_radacina.xml', @laMod, @lcMsg) + DO Assert WITH !llRet AND 'Invoice/CreditNote' $ lcMsg, '3b: radacina ne-Invoice/CreditNote -> blocare cu mesaj clar', '[' + lcMsg + ']' + + llRet = StornoEFacturaXML('2026-01-01', '', '', gcOutDir + 'blocaj_lipsa.xml', @laMod, @lcMsg) + DO Assert WITH !llRet AND 'Lipseste' $ lcMsg, '3b: lipseste ID/IssueDate/Supplier -> blocare cu mesaj clar', '[' + lcMsg + ']' + + LOCAL lcXmlBadNum + lcXmlBadNum = STRTRAN(FILETOSTR(gcFixDir + 'storno_fixture_diacritice_reale.xml'), '18.18', 'ABC', 1, 1) + DO Assert WITH 'ABC' $ lcXmlBadNum, '3b: pregatire fixtura cu valoare nenumerica (substitutie reusita)', '' + llRet = StornoEFacturaXML(m.lcXmlBadNum, '', '', gcOutDir + 'blocaj_nenumeric.xml', @laMod, @lcMsg) + DO Assert WITH !llRet AND 'nenumeric' $ LOWER(lcMsg) AND 'TaxAmount' $ lcMsg, '3b: valoare nenumerica -> blocare, mesajul numeste nodul', '[' + lcMsg + ']' + + DO PrLogLocal WITH ' (CIF strain / luna blocata: verificari la pasul 2 in frm_storno_efactura, Lane 2/C - nu exista inca cod de testat)' +ENDPROC + +********************************************************** +* rutarea CN/FCN (standard=CN la upload, FCN la validare) si detectia B2C (CNP 13 cifre) - +* aceeasi expresie ca in SendEfactura/ValidareEFacturaANAF, verificata fara HTTP +PROCEDURE TestRutareCNSiB2C + LOCAL lcInv, lcCn, lcB2c + lcInv = FILETOSTR(gcFixDir + 'storno_fixture_diacritice_reale.xml') + lcCn = FILETOSTR(gcFixDir + 'storno_fixture_creditnote_minimal.xml') + lcB2c = FILETOSTR(gcFixDir + 'storno_fixture_b2c_cnp.xml') + + DO Assert WITH IIF('CreditNote' $ lcInv, 'CN', 'UBL') == 'UBL', 'rutare: Invoice -> standard=UBL / validare FACT1', '' + DO Assert WITH IIF('CreditNote' $ lcCn, 'CN', 'UBL') == 'CN', 'rutare: CreditNote -> standard=CN', '' + DO Assert WITH IIF('CreditNote' $ lcCn, 'FCN', 'FACT1') == 'FCN', 'rutare: CreditNote -> validare FCN', '' + DO Assert WITH IIF('CreditNote' $ lcInv, 'FCN', 'FACT1') == 'FACT1', 'rutare: Invoice -> validare FACT1', '' + + LOCAL lcCustomer, lcPartyLegal, lcCodFiscalClient + lcCustomer = STREXTRACT(lcB2c, '', '', 1, 1) + lcPartyLegal = STREXTRACT(lcCustomer, '', '', 1, 1) + lcCodFiscalClient = ALLTRIM(STREXTRACT(lcPartyLegal, '', '', 1, 1)) + DO Assert WITH LEN(lcCodFiscalClient) = 13, 'B2C: CNP de 13 cifre detectat din fixtura (llB2C ar deveni .T.)', 'cnp=[' + lcCodFiscalClient + '] len=' + TRANSFORM(LEN(lcCodFiscalClient)) +ENDPROC + +********************************************************** +PROCEDURE Assert + LPARAMETERS tlCond, tcTitlu, tcDetaliu + IF tlCond + lnPass = lnPass + 1 + DO PrLogLocal WITH ' OK ' + tcTitlu + IIF(EMPTY(tcDetaliu), '', ' (' + tcDetaliu + ')') + ELSE + lnFail = lnFail + 1 + DO PrLogLocal WITH ' FAIL ' + tcTitlu + IIF(EMPTY(tcDetaliu), '', ' (' + tcDetaliu + ')') + ENDIF +ENDPROC + +********************************************************** +PROCEDURE PrLogLocal + LPARAMETERS tcMsg + LOCAL lcL + SET SAFETY OFF + lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '') + STRTOFILE(lcL + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcUILog) +ENDPROC + +********************************************************** +PROCEDURE PrErrLocal + LPARAMETERS tnError, tcMessage, tcProgram, tnLineNo + DO PrLogLocal WITH 'EROARE ' + TRANSFORM(tnError) + ' ' + TRANSFORM(tcMessage) + ' in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLineNo) +ENDPROC