diff --git a/clase/anaf_efactura.vc2 b/clase/anaf_efactura.vc2 index 5a6e45a..051fd0a 100644 --- a/clase/anaf_efactura.vc2 +++ b/clase/anaf_efactura.vc2 @@ -5228,7 +5228,7 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx" PROCEDURE citesteraspunsuri Local llSucces, lnOptiune, lnZile, llFortareRaspunsuri, llTest - lnOptiune = xmenu('Ultima zi;Ultimele 2 zile;Ultimele 3 zile;Ultimele 7 zile;Ultimele 15 zile;Ultimele 30 zile;Ultimele 60 zile') + lnOptiune = xmenu('Ultima zi;Ultimele 2 zile;Ultimele 3 zile;Ultimele 7 zile;Ultimele 15 zile;Ultimele 30 zile;Ultimele 60 zile;Import arhiva zip de pe disc...') IF EMPTY(m.lnOptiune) RETURN ENDIF @@ -5238,7 +5238,11 @@ DEFINE CLASS anaf_efactura AS _frmbase OF "_frm_base.vcx" llTest = This.lTest *!* llSucces = Thisform.oAnaf.RaspunsuriFacturi(m.lnZile, m.llFortareRaspunsuri) - llSucces = efactura_client(m.lnZile, m.llFortareRaspunsuri, m.llTest) + IF m.lnOptiune = 8 + llSucces = Thisform.oAnaf.AnafeFacturaServer.ImportZipLocal() + ELSE + llSucces = efactura_client(m.lnZile, m.llFortareRaspunsuri, m.llTest) + ENDIF Thisform.LockScreen = .T. save_grid_tag(Thisform.pgfeFactura.page2.grdFacturiPrimite) diff --git a/docs/depanare_testare_vfp.md b/docs/depanare_testare_vfp.md index 43b621c..bfdc3fe 100644 --- a/docs/depanare_testare_vfp.md +++ b/docs/depanare_testare_vfp.md @@ -105,6 +105,15 @@ obiecte/coloane din ADD OBJECT (strica structura: "Cannot add this object to a G - Fix-ul unui typo intr-o clasa partajata poate activa defecte latente in aval (codul care nu rulase niciodata incepe sa ruleze). La regresii dupa fix-uri "inofensive" in COMUN, cauta defectul latent, nu doar diff-ul. +- **Literal string de peste 255 de caractere = eroare de COMPILARE, nu de runtime** (masurat + 24.07.2026: 255 trece, 256 pica). Mesajul difera dupa forma liniei: `Unrecognized command + verb` daca linia incepe cu un apel de metoda (`goExecutor.oExecuta("", 'c')`), + `Command contains unrecognized phrase/keyword` la o atribuire (`lc = ""`). + Insidios: restul programului ruleaza normal, doar linia aceea lipseste din `.fxp` si da + eroare 16 cand se ajunge la ea - deci un test poate raporta "FAIL" pe altceva decat cauza + reala. De aceea tot SQL-ul lung din codebase e scris cu `TEXT TO [TEXTMERGE] NOSHOW` + ... `ENDTEXT` sau concatenat din bucati, nu ca literal unic. Verificare rapida: + `awk 'length($0) > 260 {print NR": "length($0)}' fisier.prg`. - **Coloana de grid cu ControlSource EXPRESIE (nu camp) cere `Bound = .F.`**. Fara el: eroare 9 "Data type mismatch" la CREATEOBJECT-ul formei (faza de constructie, raportata la linia apelanta, Details gol). Caz: import_nota.GridArt @@ -162,7 +171,49 @@ Descoperite depanand harness-ul pentru "Data type mismatch" la `CREATEOBJECT('IM cursor pe care nu l-ai deschis tu confirma mecanismul (faza de instantiere), chiar daca nu e mesajul EXACT din bug-ul original. -## 7. Studiu de caz: "Property CNRCRT is not found" (15.07.2026) +## 7. Verificare de sintaxa prin compilare headless (dupa orice editare de `.prg`) + +Cel mai ieftin test dupa o modificare intr-un `.prg`: `COMPILE` headless, care prinde erorile +de sintaxa fara sa porneasca aplicatia si fara Oracle. Reguli: + +- **`config.fpw` propriu cu `SAFETY=OFF` si `RESOURCE=OFF`, pasat cu `-c`** (lipit de + flag, fara spatiu). Fara el, `COMPILE` peste un `.err`/`.fxp` existent si `STRTOFILE` peste + un log existent scot dialogul modal "overwrite?" si procesul pare agatat. `SET SAFETY OFF` + ca prima linie in script e complementar, nu inlocuitor (`-A` singur porneste cu SAFETY ON). + Verificare ca a fost preluat: logheaza `SET("SAFETY")` / `SET("RESOURCE")` la start. +- **`-c` explicit are prioritate si merge impreuna cu `-A`**: desi `-A` ignora + config.fpw-ul implicit, un `-c` explicit tot e preluat (verificat 24.07.2026: + `vfp9.exe -c -A -T script.prg` a raportat `SAFETY=[OFF] RESOURCE=[OFF]`). +- **Compileaza o COPIE a fisierului, in scratchpad, nu sursa din working copy**: `COMPILE` + scrie `.fxp`-ul langa `.prg`, iar `.fxp`-urile din SVN sunt artefacte de build - regenerate + ad-hoc, ar aparea ca modificari in working copy. VFP compileaza fara sa rezolve simbolurile + (clase, functii din alte fisiere), deci copia izolata e suficienta pentru sintaxa. +- **Sterge `.err`-ul vechi inainte de `COMPILE`**, altfel nu poti distinge un `.err` ramas de + la rularea precedenta de unul nou. Verdictul se citeste din existenta `.err`: + exista => logheaza continutul lui; nu exista => compilare curata. + +Sablon (rulat dupa fiecare runda de editare pe `anaf_efactura.prg`, 24.07.2026): + +``` +SET SAFETY OFF +lcDir = '\' +STRTOFILE('START ' + TTOC(DATETIME()) + ' SAFETY=' + SET("SAFETY") + CRLF, lcLog) +IF FILE(lcDir + 'copie.err') + DELETE FILE (lcDir + 'copie.err') +ENDIF +COMPILE (lcDir + 'copie.prg') +IF FILE(lcDir + 'copie.err') + STRTOFILE('ERR:' + CRLF + FILETOSTR(lcDir + 'copie.err'), lcLog, 1) +ELSE + STRTOFILE('OK: compilare fara erori', lcLog, 1) +ENDIF +QUIT +``` + +Nu inlocuieste testul functional: `COMPILE` valideaza sintaxa, nu apeluri catre metode +inexistente sau proprietati gresite (acelea apar abia la runtime). + +## 8. Studiu de caz: "Property CNRCRT is not found" (15.07.2026) Lant complet: `frm_import_extrase_banca.modificanote` copia `crsJTVATemp` fara index (defect latent) -> coloana `cExplicatieTVA` din `frm_modific2024.grdRulaje` face diff --git a/programe/anaf_efactura.prg b/programe/anaf_efactura.prg index 78a768f..d522045 100644 --- a/programe/anaf_efactura.prg +++ b/programe/anaf_efactura.prg @@ -1135,6 +1135,109 @@ ENDTEXT RETURN m.llSucces ENDPROC && ProcesareRaspunsuri + ********************************* + *!* 24.07.2026 marius.mutu - import manual arhiva zip eFactura descarcata din SPV + ********************************* + PROCEDURE ImportZipLocal + LPARAMETERS tcZipFile + * tcZipFile: (optional) arhiva zip descarcata din SPV. Daca lipseste, se alege cu Getfile + + Local laFiles[1], lcCodFiscalClient, lcCodFiscalFurnizor, lcDir, lcErrorMessage, lcFilePath + Local lcId, lcSemnatura, lcTip, lcXmlFile, lcZipFile, llSucces, lnFile, lnFiles, loFactura + + lcZipFile = IIF(TYPE('tcZipFile') = 'C' AND !EMPTY(NVL(m.tcZipFile, '')), ALLTRIM(m.tcZipFile), GETFILE('zip', 'Arhiva zip eFactura', 'Import')) + IF EMPTY(m.lcZipFile) OR !FILE(m.lcZipFile) + RETURN .F. + ENDIF + + lcDir = ADDBS(SYS(2023)) + SYS(2015) + '\' + lcErrorMessage = '' + llSucces = This.UnzipFile(m.lcZipFile, @lcDir, @lcErrorMessage) + + IF !m.llSucces + AMESSAGEBOX('Eroare la dezarhivarea ' + m.lcZipFile + CHR(13) + CHR(10) + m.lcErrorMessage, 0+48, _SCREEN.Caption) + RETURN .F. + ENDIF + + * xml-ul facturii este fisierul xml care nu este semnatura MFinante + lcXmlFile = '' + lnFiles = ADIR(laFiles, ADDBS(m.lcDir) + '*.xml') + FOR lnFile = 1 TO m.lnFiles + IF !('SEMNATURA' $ UPPER(laFiles[m.lnFile, 1])) + lcXmlFile = ADDBS(m.lcDir) + ALLTRIM(laFiles[m.lnFile, 1]) + EXIT + ENDIF + ENDFOR + + IF EMPTY(m.lcXmlFile) + AMESSAGEBOX('Arhiva nu contine fisierul xml al facturii!', 0+48, _SCREEN.Caption) + RETURN .F. + ENDIF + + lcId = ALLTRIM(JUSTSTEM(m.lcXmlFile)) + loFactura = ParseEFactura(m.lcXmlFile) + + IF TYPE('loFactura') <> 'O' OR loFactura.Eroare + AMESSAGEBOX('Eroare la citirea facturii din ' + m.lcXmlFile, 0+48, _SCREEN.Caption) + RETURN .F. + ENDIF + + lcCodFiscalFurnizor = UPPER(ALLTRIM(GetNrFromString(NVL(loFactura.CodFiscalFurnizor, '')))) + lcCodFiscalClient = UPPER(ALLTRIM(GetNrFromString(NVL(loFactura.CodFiscalClient, '')))) + + DO CASE + CASE !EMPTY(m.lcCodFiscalClient) AND m.lcCodFiscalClient == ALLTRIM(This.cCodFiscal) + lcTip = 'FACTURA PRIMITA' + CASE !EMPTY(m.lcCodFiscalFurnizor) AND m.lcCodFiscalFurnizor == ALLTRIM(This.cCodFiscal) + lcTip = 'FACTURA TRIMISA' + OTHERWISE + AMESSAGEBOX('Factura nu apartine firmei curente (cod fiscal ' + ALLTRIM(This.cCodFiscal) + ')!' + CHR(13) + CHR(10) + ; + 'Emitent: ' + m.lcCodFiscalFurnizor + ' Beneficiar: ' + m.lcCodFiscalClient, 0+48, _SCREEN.Caption) + RETURN .F. + ENDCASE + + * Salvez arhiva in directorul local de raspunsuri, ca la descarcarea din SPV + lcFilePath = GetPdfPath('EFACTURA', IIF(m.lcTip == 'FACTURA PRIMITA', 'PRIMITE', 'TRIMISE')) + m.lcId + '_' + m.lcId + '.zip' + IF !FILE(m.lcFilePath) + This.SaveFile(m.lcZipFile, .F., JUSTPATH(m.lcFilePath), JUSTFNAME(m.lcFilePath)) + ENDIF + + * Cursor temporar cu structura din InitDB, cu factura importata + llSucces = goExecutor.oExecuta("select a.*, cast(NULL as varchar2(1000)) as factura_detalii, 0 as modificat from anaf_efactura a where 1 = 0", "canaf_efactura_temp") + + IF !m.llSucces + AMESSAGEBOX('Eroare la citirea structurii anaf_efactura!', 0+48, _SCREEN.Caption) + RETURN .F. + ENDIF + + INSERT INTO canaf_efactura_temp (id_incarcare, id_descarcare, data_raspuns, mesaj_raspuns, tip_mesaj_raspuns, ; + cod_fiscal_emitent, cod_fiscal_beneficiar, factura_emisa, test, descarcat, filepath, detalii, modificat) ; + VALUES (m.lcId, m.lcId, DATETIME(), 'Import manual ' + JUSTFNAME(m.lcZipFile), m.lcTip, ; + m.lcCodFiscalFurnizor, m.lcCodFiscalClient, IIF(m.lcTip == 'FACTURA PRIMITA', 0, 1), IIF(This.lTest, 1, 0), ; + 0, m.lcFilePath, FILETOSTR(m.lcXmlFile), 1) + + TABLEUPDATE(1, .F., 'canaf_efactura_temp') + + ADDPROPERTY(loFactura, 'cIdIncarcare', m.lcId) + This.cUpdateFactura(loFactura, 'canaf_efactura_temp') + + llSucces = This.UpdateDb('canaf_efactura_temp') + + USE IN (SELECT('canaf_efactura_temp')) + + lcSemnatura = ADDBS(m.lcDir) + 'semnatura_' + m.lcId + '.xml' + DELETE FILE (m.lcXmlFile) + IF FILE(m.lcSemnatura) + DELETE FILE (m.lcSemnatura) + ENDIF + + IF m.llSucces + AMESSAGEBOX('Factura ' + ALLTRIM(loFactura.NumarAct) + ' din ' + DTOC(loFactura.DataAct) + ' a fost importata in borderoul eFactura!', 0+64, _SCREEN.Caption) + ENDIF + + RETURN m.llSucces + ENDPROC && ImportZipLocal + ********************************* * RASPUNSURI FACTURI diff --git a/utile/Teste/efactura_import/test_import_zip_efactura.prg b/utile/Teste/efactura_import/test_import_zip_efactura.prg new file mode 100644 index 0000000..500adfe --- /dev/null +++ b/utile/Teste/efactura_import/test_import_zip_efactura.prg @@ -0,0 +1,237 @@ +* test_import_zip_efactura.prg +* Test UI pentru importul manual al unei arhive zip eFactura in borderou +* (COMUN\clase\anaf_efactura.vcx > clasa anaf_efactura + AnafeFacturaServer.ImportZipLocal). +* Mediu: CENTRAL / MARIUSM_AUTO, perioada ianuarie 2026 (data facturii din xml). +* +* Ce acopera: +* T1 - garda pe cod fiscal: arhiva nu apartine firmei de test => import respins, 0 randuri +* T2 - import complet cu codul fiscal al beneficiarului din xml => anaf_efactura + detalii +* T3 - factura apare in grila "Facturi primite" a borderoului real (captura de ecran) +* GETFILE (alegerea fisierului) NU poate fi automatizat headless - functie nativa VFP, +* nu poate fi umbrita de un mock - de aceea arhiva se transmite ca parametru. +* +* Rulare: powershell -ExecutionPolicy Bypass -File test_import_zip_efactura.ps1 + +SET SAFETY OFF +SET TALK OFF + +PUBLIC gcUILog, gcSyncDir, gnMockRaspuns, gcTestDir, gcZipFile, gcIdInc, gcCifBenef +PUBLIC poFacturiEmise, poFacturiPrimite, poFacturiTrimise, poFacturiDetalii +PUBLIC loAnaf, loForm, gnPass, gnFail + +gcTestDir = 'D:\ROA\ROACONT\COMUN\utile\Teste\efactura_import\' +gcUILog = gcTestDir + 'test_import_zip_efactura_log.txt' +gcSyncDir = gcTestDir + 'uisync_importzip\' +gcZipFile = 'D:\ROA\ROACONT\5967557693.zip' +gcIdInc = '5967557693' +gcCifBenef = '29923675' +gnMockRaspuns = 6 +gnPass = 0 +gnFail = 0 + +STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcUILog) + +ON ERROR DO TErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() +ON SHUTDOWN QUIT + +* Mock-urile se incarca INAINTE de test_init_env_auto: la nume duplicat de procedura +* castiga fisierul incarcat PRIMUL (vezi docs\testare-ui-vfp.md, punctul j) +SET PROCEDURE TO ('D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg') ADDITIVE +SET PROCEDURE TO ('D:\ROA\ROACONT\COMUN\utile\Teste\ui_harness.prg') ADDITIVE + +DO ('D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT', 2026, 1 + +DO HarnessLog WITH 'INIT gnHandle=' + TRANSFORM(gnHandle) + ' gcS=' + TRANSFORM(gcS) + ' perioada=' + TRANSFORM(gnLuna) + '/' + TRANSFORM(gnAn) +DO HarnessLog WITH 'FIRMA=' + TRANSFORM(gcFirma) + ' cod fiscal=' + TRANSFORM(goFirma.codfiscalfro) + +* Curatenie: sterg importul unei rulari anterioare, ca testul sa fie repetabil +goExecutor.oExecuta("delete from anaf_efactura_detalii where id_efactura in (select id from anaf_efactura where id_incarcare = '" + gcIdInc + "')") +goExecutor.oExecuta("delete from anaf_efactura where id_incarcare = '" + gcIdInc + "'") +DO HarnessLog WITH 'CURATENIE randuri anterioare OK' + +loAnaf = CREATEOBJECT('ANAFeFactura') +DO HarnessLog WITH 'ANAFeFactura creat; cod fiscal server=' + TRANSFORM(loAnaf.AnafeFacturaServer.cCodFiscal) + ' lTest=' + TRANSFORM(loAnaf.AnafeFacturaServer.lTest) + +* ---------- cursoarele borderoului, copie exacta din ANAFeFactura.vizeFactura (anaf_efactura.prg:2867-2942) ---------- + * FACTURI PRIMITE + lcData1 = '01' + PADL(INT(m.gnLuna),2,'0') + ALLTRIM(STR(m.gnAn)) + 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 = [] + * Aduc inregistrarile cand se activeaza prima data pagina cu facturi primite + lcFiltru = [1=2] && [(extract(year from data_act) = ?gnAn and extract(month from data_act) = ?gnLuna) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))] + 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 + 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 = [] + * Aduc inregistrarile cand se activeaza prima data pagina cu facturi trimise + lcFiltru = [1=2] && [(extract(year from data_act) = ?gnAn and extract(month from data_act) = ?gnLuna) or (data_act is null and data_raspuns >= to_date('] + m.lcData1 + [','ddmmyyyy'))] + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + + gencursor('poFacturiTrimise', 'crsFacturiTrimise', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiTrimise.ca_baza1.afisare() + Select crsFacturiTrimise + Go Top + + * FACTURI EMISE + 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 = [(extract(year from data_act)=?gnAn and extract(month from data_act)=?gnLuna) OR (trimis = 1 and tip_mesaj_raspuns is null and extract(year from data_act) >=2023)] + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + + * Afisez toate facturile emise, ca sa le pot vizualiza pe cele netrimise sau trimise cu starea lor (trimis, eroare etc.) + gencursor('poFacturiEmise', 'crsFacturiEmise', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiEmise.ca_baza1.afisare() + + +* DETALII FACTURI PRIMITE/TRIMISE/EMISE + 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] && IIF(!EMPTY(NVL(crsFacturiPrimite.id,0)), [id_efactura=] + ALLTRIM(STR(crsFacturiPrimite.id)), [1=2]) + lcFiltruOriginal = [] + llModParam = .T. + llAfiseaza = .F. + + gencursor('poFacturiDetalii', 'crsDetaliiFacturi', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcgroup, llModParam, lcFiltruOriginal) + poFacturiDetalii.ca_baza1.afisare() + +* ---------- Formularul REAL al borderoului, non-modal (Show(1) ar bloca testul) ---------- +Select crsFacturiEmise +loForm = CREATEOBJECT('anaf_efactura', loAnaf) +loForm.WindowType = 0 +loForm.Show() +loForm.WindowState = 2 +DO HarnessLog WITH 'BORDEROU deschis: [' + TRANSFORM(loForm.Caption) + ']' +DO HarnessStep WITH 0, 'borderou_deschis' + +* ---------- T1: garda pe cod fiscal (firma de test nu e nici emitent, nici beneficiar) ---------- +llRezultat = loForm.oAnaf.AnafeFacturaServer.ImportZipLocal(gcZipFile) +lnRanduri = 0 +goExecutor.oSelecteaza2Value("select count(*) from anaf_efactura where id_incarcare = '" + gcIdInc + "'", @lnRanduri) +DO TVerdict WITH !llRezultat AND NVL(lnRanduri, 0) = 0, 'T1 garda cod fiscal', 'import respins=' + TRANSFORM(!llRezultat) + ' randuri in anaf_efactura=' + TRANSFORM(lnRanduri) +DO HarnessStep WITH 1, 'garda_cod_fiscal' + +* ---------- T2: import complet, cu codul fiscal al beneficiarului din xml ---------- +loForm.oAnaf.AnafeFacturaServer.cCodFiscal = gcCifBenef +llRezultat = loForm.oAnaf.AnafeFacturaServer.ImportZipLocal(gcZipFile) +DO TVerdict WITH llRezultat, 'T2 import', 'ImportZipLocal a returnat ' + TRANSFORM(llRezultat) + +* SQL in TEXT/ENDTEXT: un literal string mai lung de 255 caractere nu compileaza +TEXT TO lcSqlVerif NOSHOW +select id, xnumar_act, xdata_act, xdata_scad, xtotal_fara_tva, xtotal_tva, xtotal_cu_tva, xnume_valuta, + xfurnizor, xclient, tip_mesaj_raspuns, factura_emisa, cod_fiscal_emitent, cod_fiscal_beneficiar, + descarcat, procesat, creditnote, filepath, + nvl(length(detalii),0) as len_detalii, nvl(length(detalii_zip),0) as len_zip + from anaf_efactura + where id_incarcare = ?gcIdInc +ENDTEXT +goExecutor.oExecuta(lcSqlVerif, 'cVerif') + +IF USED('cVerif') AND RECCOUNT('cVerif') = 1 + SELECT cVerif + GO TOP + DO HarnessLog WITH 'ANAF_EFACTURA id=' + TRANSFORM(cVerif.id) + ' numar=[' + TRANSFORM(cVerif.xnumar_act) + '] data=' + TRANSFORM(cVerif.xdata_act) + ' scadenta=' + TRANSFORM(cVerif.xdata_scad) + DO HarnessLog WITH ' furnizor=[' + TRANSFORM(cVerif.xfurnizor) + '] client=[' + TRANSFORM(cVerif.xclient) + ']' + DO HarnessLog WITH ' fara tva=' + TRANSFORM(cVerif.xtotal_fara_tva) + ' tva=' + TRANSFORM(cVerif.xtotal_tva) + ' cu tva=' + TRANSFORM(cVerif.xtotal_cu_tva) + ' valuta=' + TRANSFORM(cVerif.xnume_valuta) + DO HarnessLog WITH ' tip=[' + TRANSFORM(cVerif.tip_mesaj_raspuns) + '] emisa=' + TRANSFORM(cVerif.factura_emisa) + ' cif emitent=' + TRANSFORM(cVerif.cod_fiscal_emitent) + ' cif benef=' + TRANSFORM(cVerif.cod_fiscal_beneficiar) + DO HarnessLog WITH ' descarcat=' + TRANSFORM(cVerif.descarcat) + ' procesat=' + TRANSFORM(cVerif.procesat) + ' creditnote=' + TRANSFORM(cVerif.creditnote) + ' len(detalii)=' + TRANSFORM(cVerif.len_detalii) + ' len(zip)=' + TRANSFORM(cVerif.len_zip) + DO HarnessLog WITH ' filepath=[' + TRANSFORM(cVerif.filepath) + '] exista pe disc=' + TRANSFORM(FILE(ALLTRIM(NVL(cVerif.filepath, '')))) + + DO TVerdict WITH ALLTRIM(NVL(cVerif.xnumar_act, '')) == 'SRC/0000809', 'T2.1 numar factura', TRANSFORM(cVerif.xnumar_act) + DO TVerdict WITH cVerif.xdata_act = {^2026-01-28}, 'T2.2 data factura', TRANSFORM(cVerif.xdata_act) + DO TVerdict WITH ROUND(NVL(cVerif.xtotal_cu_tva, 0), 2) = -5166.63, 'T2.3 total cu tva', TRANSFORM(cVerif.xtotal_cu_tva) + DO TVerdict WITH ROUND(NVL(cVerif.xtotal_fara_tva, 0), 2) = -4269.94, 'T2.4 total fara tva', TRANSFORM(cVerif.xtotal_fara_tva) + DO TVerdict WITH ALLTRIM(UPPER(NVL(cVerif.tip_mesaj_raspuns, ''))) == 'FACTURA PRIMITA' AND NVL(cVerif.factura_emisa, -1) = 0, 'T2.5 tip factura primita', TRANSFORM(cVerif.tip_mesaj_raspuns) + DO TVerdict WITH ALLTRIM(NVL(cVerif.cod_fiscal_emitent, '')) == '17043227' AND ALLTRIM(NVL(cVerif.cod_fiscal_beneficiar, '')) == gcCifBenef, 'T2.6 coduri fiscale', TRANSFORM(cVerif.cod_fiscal_emitent) + '/' + TRANSFORM(cVerif.cod_fiscal_beneficiar) + DO TVerdict WITH NVL(cVerif.len_detalii, 0) > 4000, 'T2.7 xml salvat in detalii', TRANSFORM(cVerif.len_detalii) + ' caractere' + DO TVerdict WITH FILE(ALLTRIM(NVL(cVerif.filepath, ''))), 'T2.8 arhiva copiata local', TRANSFORM(cVerif.filepath) + + lnDetalii = 0 + goExecutor.oSelecteaza2Value("select count(*) from anaf_efactura_detalii where id_efactura = " + ALLTRIM(STR(cVerif.id)), @lnDetalii) + DO TVerdict WITH NVL(lnDetalii, 0) > 0, 'T2.9 linii in anaf_efactura_detalii', TRANSFORM(lnDetalii) + ' linii' + + goExecutor.oExecuta("select nr, articol, cantitate, um, pret, proctva, valoarefaratva from anaf_efactura_detalii where id_efactura = " + ALLTRIM(STR(cVerif.id)) + " order by nr", 'cLinii') + IF USED('cLinii') + SELECT cLinii + SCAN + DO HarnessLog WITH ' linia ' + TRANSFORM(cLinii.nr) + ': [' + TRANSFORM(cLinii.articol) + '] cant=' + TRANSFORM(cLinii.cantitate) + ' ' + TRANSFORM(cLinii.um) + ' pret=' + TRANSFORM(cLinii.pret) + ' tva=' + TRANSFORM(cLinii.proctva) + ' valoare=' + TRANSFORM(cLinii.valoarefaratva) + ENDSCAN + USE IN (SELECT('cLinii')) + ENDIF +ELSE + DO TVerdict WITH .F., 'T2.1-T2.9 verificare in baza de date', 'nu am gasit exact 1 rand in anaf_efactura' +ENDIF + +USE IN (SELECT('cVerif')) +DO HarnessStep WITH 2, 'dupa_import' + +* ---------- T3: factura in grila reala "Facturi primite" din borderou ---------- +* ATENTIE: pagina "Facturi primite in SPV" e obiectul Page2, dar are PageOrder = 3, +* iar ActivePage merge pe PageOrder - deci activarea ei se face cu 3, nu cu 2. +loForm.pgfeFactura.ActivePage = 3 +loForm.Refresh() +lnGasit = 0 +IF USED('crsFacturiPrimite') + SELECT crsFacturiPrimite + COUNT FOR ALLTRIM(NVL(numar_act, '')) == 'SRC/0000809' TO lnGasit + DO HarnessLog WITH 'crsFacturiPrimite: ' + TRANSFORM(RECCOUNT('crsFacturiPrimite')) + ' randuri, din care factura importata: ' + TRANSFORM(lnGasit) +ENDIF +DO TVerdict WITH lnGasit = 1, 'T3 factura vizibila in grila Facturi primite', TRANSFORM(lnGasit) + ' randuri gasite' +DO HarnessStep WITH 3, 'grila_facturi_primite' + +DO HarnessLog WITH 'REZULTAT FINAL: PASS=' + TRANSFORM(gnPass) + ' FAIL=' + TRANSFORM(gnFail) +DO HarnessDone WITH IIF(gnFail = 0, 'done OK', 'done CU ESECURI') + +QUIT + +*********************** +PROCEDURE TVerdict + LPARAMETERS tlOk, tcNume, tcDetalii + IF tlOk + gnPass = gnPass + 1 + ELSE + gnFail = gnFail + 1 + ENDIF + DO HarnessLog WITH IIF(tlOk, 'PASS ', 'FAIL ') + tcNume + ' | ' + TRANSFORM(tcDetalii) +ENDPROC + +*********************** +PROCEDURE TErr + LPARAMETERS tnError, tcMessage, tcProgram, tnLine + DO HarnessLog WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine) +ENDPROC diff --git a/utile/Teste/efactura_import/test_import_zip_efactura.ps1 b/utile/Teste/efactura_import/test_import_zip_efactura.ps1 new file mode 100644 index 0000000..f326279 --- /dev/null +++ b/utile/Teste/efactura_import/test_import_zip_efactura.ps1 @@ -0,0 +1,12 @@ +# test_import_zip_efactura.ps1 - wrapper peste harness-ul generic pentru testul de import +# arhiva zip eFactura in borderou (clasa anaf_efactura + AnafeFacturaServer.ImportZipLocal). +# Rulare: powershell -ExecutionPolicy Bypass -File test_import_zip_efactura.ps1 +$ErrorActionPreference = 'Stop' +$Teste = $PSScriptRoot +& (Join-Path (Split-Path $Teste -Parent) 'vfp_ui_harness.ps1') ` + -TestPrg (Join-Path $Teste 'test_import_zip_efactura.prg') ` + -Steps @('borderou_deschis','garda_cod_fiscal','dupa_import','grila_facturi_primite') ` + -ShotsDir (Join-Path $Teste 'screenshots_importzip') ` + -SyncDir (Join-Path $Teste 'uisync_importzip') ` + -ReadyTimeoutSec 300 ` + -StepTimeoutSec 180 diff --git a/utile/Teste/test_init_env_auto.prg b/utile/Teste/test_init_env_auto.prg index 0d22299..7088ca1 100644 --- a/utile/Teste/test_init_env_auto.prg +++ b/utile/Teste/test_init_env_auto.prg @@ -253,11 +253,16 @@ IF m.llSucces gnIdSucursala = null gcFirma = ALLTRIM(firma) SCATTER NAME goFirma + *!* 24.07.2026 marius.mutu - ca in start_firma (ostartfirma.prg): codfiscalfro nu e coloana in v_firme + IF TYPE('goFirma.codfiscalfro') = 'U' + ADDPROPERTY(goFirma, 'codfiscalfro', ALLTRIM(STRTRAN(ALLTRIM(NVL(goFirma.cod_fiscal, '')), 'RO', ''))) + ENDIF ELSE goFirma = CREATEOBJECT('custom') goFirma.addproperty('cod_fiscal', '') goFirma.addproperty('schema', m.gcS) goFirma.addproperty('firma', m.gcS) + goFirma.addproperty('codfiscalfro', '') ENDIF USE IN (SELECT('cFirma'))