* test_c1_echivalenta_lot.prg * C1 ("testul de vineri la 2 noaptea"): lotul (coada ghidata) scrie in ACT exact ce scrie calea * de un singur document. Ruleaza pe schema de test MARIUSM_AUTO@ROA_CENTRAL (scriere aprobata), * aceeasi schema in doua rulari succesive cu anulare intre ele (varianta de rezerva din plan - * C4 devine premisa lui C1, vezi docs\plan_efactura_23_24.md, sectiunea "Riscuri de instabilitate * a testelor"). * * RUN 1 (calea de un singur document): pentru fiecare din cele 10 facturi, pozitioneaza randul in * crsFacturi si ruleaza EXACT secventa pe care grdFacturi.AfterRowColChange o ruleaza la navigare * (CompleteazaFactura/actualizeaza_grid2/CompleteazaDetaliiFactura, anaf_efactura.vc2:14557-14564), * apoi Thisform.do_executa(lnRuta) o singura data - fara bucla, fara CoadaContabilizareEF in * mijloc. Ruta se calculeaza cu CoadaContabilizareEF().Ruta() (cod real, neschimbat) ca sa fie * IDENTICA cu ce ar calcula coada - singura diferenta fata de operatorul real e ca acesta ar primi * intrebarea xmenu('Import contabilitate;Import gestiune'); ruta e transmisa direct ca sa nu * blocheze headless-ul, exact cum face si coada (do_coada -> Thisform.do_executa(m.lnRuta), * anaf_efactura.vc2:12377) - deci comparatia ramane pe ImportGeneral/introducere_compacta, nu pe * mecanismul de intrebare. Toate cele 10 facturi sunt fara linii gestionabile (in_stoc=0), deci * Ruta() = 1 (ImportGeneral) in ambele rulari - ImportModifica/frm_modific2024 nu e acoperit de * acest test (blocheaza pe dialog nativ Windows in mediu headless, vezi * editare_factura\test_writeback_buton1.prg, antet). * * C4 (anulare + revenire la starea initiala) devine aici premisa lui C1: dupa RUN 1, AnulareLotEF * sterge lotul si reseteaza id_fact - verificat separat ca ACT revine la 0 randuri active pe acele * documente si legatura eFactura se reseteaza. * * RUN 2 (coada): dupa anulare, cursoarele crsFacturi/crsDetaliiFacturi se reconstruiesc din Oracle * (stare curata, id_fact=0), se bifeaza toate cele 10 si se cheama Thisform.do_coada() REAL, * neschimbat. * * Comparatie: pentru fiecare din cele 10 facturi, ACT (WHERE id_fact = AND * sters=0), toate coloanele EXCLUS ID_ACT/DATAORA (cerute explicit de sarcina) plus COD si ID_FACT * (numar de document / legatura, generate din nou la fiecare rulare - includerea lor ar da FAIL * garantat, nelegat de corectitudine). Randurile se ordoneaza deterministic (SCD/SCC/ASCD/ASCC/ * PROC_TVA/ID_JTVA_COLOANA/SUMA) inainte de comparatie. * * Modaluri ocolite (documentat in raport, nu doar aici): * - frm_introd_compact2007.Show(1) (pmenu.prg:introducere_compacta) - blocheaza headless-ul; * un Timer independent (tmrC1Deblocare, la finalul fisierului) cauta formularul in * _SCREEN.Forms si ii apasa REAL butonul Terminat1.Command1 (verificare() + la_iesire() + * Release, cod neschimbat) - exact tiparul din todo21\test_todo21_e2e_verificare.prg * (tmrE2EDeblocare). Acelasi bypass in AMBELE rulari, deci comparatia ramane valida. * - AMESSAGEBOX mockuit (mock_amessagebox.prg, raspunde 6/Da) - pentru confirmarea lotului din * do_coada si orice avertisment neasteptat; nu e nevoie sa raspunda la nimic pe setul ales * (facturi fara duplicate, cu partener identificat). * * Rulare: powershell -ExecutionPolicy Bypass -File test_c1_echivalenta_lot.ps1 SET SAFETY OFF SET TALK OFF PUBLIC gcLog, gnC1Diferente, gcMockUltimMesaj, gnMockUltimTip gcLog = 'D:\ROA\ROACONT\COMUN\utile\Teste\test_c1_echivalenta_lot_log.txt' gnC1Diferente = 0 gcMockUltimMesaj = '' gnMockUltimTip = 0 STRTOFILE('START ' + TTOC(DATETIME()) + CHR(13) + CHR(10), gcLog) PUBLIC gnEsecuri gnEsecuri = 0 ON ERROR DO PrErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO() ON SHUTDOWN QUIT PUBLIC goTmrC1, gnC1Ticks, gnC1TicksSameForm, glC1UltimulClick gnC1Ticks = 0 gnC1TicksSameForm = 0 glC1UltimulClick = .F. * lista fixa de 10 facturi eFactura primite, necontabilizate, cu partener identificat (cod fiscal * gaseste id_part activ in nom_parteneri), fara linii gestionabile (in_stoc=0), furnizori distincti * (evita ambiguitatea MIN(id_fact) pe cheia naturala an/luna/nract/dataact/partener - verificat * manual, fiecare din cele 10 are alt id_part) - gasite prin interogare pe MARIUSM_AUTO@ROA_CENTRAL LOCAL ARRAY laIdFacturi(10) laIdFacturi(1) = 3998 && Vodafone Romania S.A. laIdFacturi(2) = 3990 && Digi Romania S.A. laIdFacturi(3) = 3959 && FIVE-HOLDING S.A. laIdFacturi(4) = 2422 && STERA INDUSTRY SRL laIdFacturi(5) = 1311 && RAJA S.A. CONSTANTA laIdFacturi(6) = 3795 && DANTE INTERNATIONAL SA laIdFacturi(7) = 3562 && DEDEMAN SRL laIdFacturi(8) = 3499 && REFLEQT EDUCATION S.R.L. laIdFacturi(9) = 3064 && SC FAN COURIER EXPRESS SRL laIdFacturi(10) = 2549 && Rompetrol Rafinare S.A. LOCAL lcListaId, lnI lcListaId = '' FOR lnI = 1 TO 10 lcListaId = lcListaId + IIF(EMPTY(lcListaId), '', ',') + TRANSFORM(laIdFacturi(lnI)) ENDFOR DO PrLog WITH 'set de test: ' + lcListaId TRY *===================================================================== * mediu + mock-uri (mock PRIMUL, castiga fisierul cautat primul - testare-ui-vfp.md capcana g) *===================================================================== SET PROCEDURE TO 'D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg' ADDITIVE DO ('D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg') WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT' IF gnHandle <= 0 DO PrLog WITH 'FAIL: conectare Oracle esuata (gnHandle=' + TRANSFORM(gnHandle) + ')' DO PrFinal QUIT ENDIF DO PrLog WITH 'mediu OK, schema=' + gcS + ' gnAn=' + TRANSFORM(gnAn) + ' gnLuna=' + TRANSFORM(gnLuna) + ' glLunaInchisa=' + TRANSFORM(glLunaInchisa) IF glLunaInchisa DO PrLog WITH 'BLOCAT: luna curenta e inchisa pe schema de test - nici lotul, nici do_executa nu pot scrie' DO PrFinal QUIT ENDIF SET PROCEDURE TO import_efactura.prg ADDITIVE SET PROCEDURE TO recunoastere_articol_ef.prg ADDITIVE SET PROCEDURE TO coada_contabilizare_ef.prg ADDITIVE SET PROCEDURE TO anulare_lot_ef.prg ADDITIVE SET PROCEDURE TO pmenu.prg ADDITIVE SET PROCEDURE TO oscrie_in_fisiere.prg ADDITIVE DO PrLog WITH 'proceduri incarcate' * coada ghidata activa pe schema de test (valoarea initiala revine la finalul testului) SET PROCEDURE TO ('D:\ROA\ROACONT\COMUN\utile\Teste\optiuni_test.prg') ADDITIVE SalveazaOptiuni('EFACTURA_LOT_ACTIV') scrie_optiune('EFACTURA_LOT_ACTIV', '1', 'test C1 - coada ghidata activa') DO PrLog WITH 'EFACTURA_LOT_ACTIV=1 setat pe ' + gcS *===================================================================== * fixtura: cont sintetic pe liniile a 3 din cele 10 facturi, ca echivalenta lot vs document unic * sa aiba ce compara in ACT (fara cont pe nicio linie, do_executa nu scrie nimic si testul ramane * PARTIAL 0/10 - vezi anaf_vefactura_detalii.cont in BuildCursoare, mai jos). Numarul de document * (xnumar_act) al acelorasi 3 facturi e rescris pe o valoare sintetica fara coliziune in * IREG_PARTENERI (schema de test are 30+ randuri ACT vechi pe numerele originale ale acestor * furnizori) - fara asta facturi_duplicate() refuza do_executa pe toate cele 3, indiferent de cont. *===================================================================== goExecutor.oExecute("update anaf_efactura_detalii set cont = '628', acont = null where id_efactura in (3998,3990,3959)", '') goExecutor.oExecute("update anaf_efactura set xnumar_act = 'ZZTC1-90000001' where id = 3998", '') goExecutor.oExecute("update anaf_efactura set xnumar_act = 'ZZTC1-90000002' where id = 3990", '') goExecutor.oExecute("update anaf_efactura set xnumar_act = 'ZZTC1-90000003' where id = 3959", '') SQLCOMMIT(gnHandle) DO PrLog WITH 'fixtura: cont=628 si numar_act sintetic scrise pe facturile 3998/3990/3959' *===================================================================== * RUN 1: calea de un singur document, o factura pe rand *===================================================================== DO BuildCursoare WITH lcListaId DO PrLog WITH 'cursoare construite: crsFacturi reccount=' + TRANSFORM(RECCOUNT('crsFacturi')) + ' crsDetaliiFacturi reccount=' + TRANSFORM(RECCOUNT('crsDetaliiFacturi')) IF RECCOUNT('crsFacturi') <> 10 DO PrLog WITH 'FAIL: crsFacturi nu are cele 10 facturi asteptate' DO PrFinal QUIT ENDIF DO BuildCursoareHelper DO PrLog WITH 'cursoare helper construite (cTipArticoleP/E, cTip, cGestiuni, cGestiuni2, cUMISO, cUM)' SELECT crsFacturi LOCAL loForm loForm = CREATEOBJECT('frm_import_efactura', .T.) DO PrLog WITH 'frm_import_efactura instantiat, lLotActiv=' + TRANSFORM(loForm.lLotActiv) IF !loForm.lLotActiv DO PrLog WITH 'BLOCAT: This.lLotActiv=.F. dupa Init - EFACTURA_LOT_ACTIV nu a fost citit ca 1' DO PrFinal QUIT ENDIF goTmrC1 = CREATEOBJECT('tmrC1Deblocare') goTmrC1.Enabled = .T. LOCAL loCoadaR, lnRuta, lnIdEF, lnRecnoF, lnIdFactDupa LOCAL ARRAY laRun1IdFact(10) loCoadaR = CREATEOBJECT('CoadaContabilizareEF') FOR lnI = 1 TO 10 lnIdEF = laIdFacturi(lnI) SELECT crsFacturi LOCATE FOR id = lnIdEF IF !FOUND() DO PrLog WITH 'FAIL RUN1[' + TRANSFORM(lnI) + '] id=' + TRANSFORM(lnIdEF) + ' nu e in crsFacturi' laRun1IdFact(lnI) = 0 LOOP ENDIF lnRecnoF = RECNO('crsFacturi') DO PrLog WITH ' RUN1[' + TRANSFORM(lnI) + '] inainte CompleteazaFactura' GO lnRecnoF IN crsFacturi loForm.CompleteazaFactura() DO PrLog WITH ' RUN1[' + TRANSFORM(lnI) + '] inainte actualizeaza_grid2' GO lnRecnoF IN crsFacturi loForm.actualizeaza_grid2() DO PrLog WITH ' RUN1[' + TRANSFORM(lnI) + '] inainte CompleteazaDetaliiFactura' GO lnRecnoF IN crsFacturi loForm.CompleteazaDetaliiFactura() GO lnRecnoF IN crsFacturi lnRuta = loCoadaR.Ruta('crsDetaliiFacturi') IF lnRuta = 2 * linii gestionabile (in_stoc=1) - ImportModifica/frm_modific2024 blocheaza pe dialog nativ * Windows in mediu headless (in afara domeniului acestui test, vezi antetul .prg); starea * poate deriva intre rulari repetate (scrierea de id_articol schimba in_stoc pe viitor) DO PrLog WITH ' RUN1[' + TRANSFORM(lnI) + '] SKIP: ruta=2 (linii gestionabile, in afara domeniului acestui test)' laRun1IdFact(lnI) = 0 SELECT crsFacturi LOOP ENDIF DO PrLog WITH ' RUN1[' + TRANSFORM(lnI) + '] inainte do_executa ruta=' + TRANSFORM(lnRuta) gnC1TicksSameForm = 0 glC1UltimulClick = .F. gcMockUltimMesaj = '' TRY loForm.do_executa(lnRuta) CATCH TO loExEx DO PrLog WITH ' EXCEPTIE do_executa RUN1[' + TRANSFORM(lnI) + ']: ' + loExEx.Message ENDTRY lnIdFactDupa = 0 goExecutor.oSelecteaza2Value('select id_fact from anaf_efactura where id = ' + TRANSFORM(lnIdEF), @lnIdFactDupa) laRun1IdFact(lnI) = NVL(lnIdFactDupa, 0) DO PrLog WITH ' RUN1[' + TRANSFORM(lnI) + '] id_efactura=' + TRANSFORM(lnIdEF) + ' ruta=' + TRANSFORM(lnRuta) + ; ' id_fact=' + TRANSFORM(laRun1IdFact(lnI)) + ' click_formular=' + TRANSFORM(glC1UltimulClick) + ; IIF(!EMPTY(gcMockUltimMesaj), ' mesaj_amessagebox=[' + gcMockUltimMesaj + ']', '') SELECT crsFacturi ENDFOR goTmrC1.Enabled = .F. LOCAL lnOKRun1 lnOKRun1 = 0 FOR lnI = 1 TO 10 IF laRun1IdFact(lnI) <> 0 lnOKRun1 = lnOKRun1 + 1 ENDIF ENDFOR DO PrLog WITH 'RUN1 terminat: ' + TRANSFORM(lnOKRun1) + '/10 documente create' IF lnOKRun1 = 0 DO PrLog WITH 'FAIL C1: niciun document creat in RUN1 - nimic de comparat' DO PrFinal QUIT ENDIF *===================================================================== * fotografiaza ACT-ul lui RUN1 INAINTE de anulare (C4 le sterge imediat dupa - o interogare * vie pe id_fact-urile lui RUN1 dupa C4 ar intoarce 0 randuri necondiitonat, nelegat de * corectitudinea coezii). RUN1_SEQ leaga fotografia inapoi de indexul facturii (1..10). *===================================================================== LOCAL lcCaseSeq, lcListaIdFact1, lcSqlSnap lcCaseSeq = '' lcListaIdFact1 = '' FOR lnI = 1 TO 10 IF laRun1IdFact(lnI) = 0 LOOP ENDIF lcCaseSeq = lcCaseSeq + 'WHEN ' + TRANSFORM(laRun1IdFact(lnI)) + ' THEN ' + TRANSFORM(lnI) + ' ' lcListaIdFact1 = lcListaIdFact1 + IIF(EMPTY(lcListaIdFact1), '', ',') + TRANSFORM(laRun1IdFact(lnI)) ENDFOR IF USED('crsRun1Snapshot') USE IN crsRun1Snapshot ENDIF lcSqlSnap = [select t.*, case id_fact ] + lcCaseSeq + [end as run1_seq from act t where id_fact in (] + lcListaIdFact1 + [) and sters = 0] goExecutor.oExecute(lcSqlSnap, 'crsRun1Snapshot') DO PrLog WITH 'RUN1 snapshot ACT inainte de anulare: ' + TRANSFORM(RECCOUNT('crsRun1Snapshot')) + ' randuri' *===================================================================== * C4: anulare in bloc, verificare revenire la starea initiala *===================================================================== LOCAL loAnul, lnStersE loAnul = CREATEOBJECT('AnulareLotEF') loAnul.Verifica(lcListaId) DO PrLog WITH 'AnulareLotEF.Verifica: acceptate=' + TRANSFORM(RECCOUNT('crsAcceptate')) + ' refuzate=' + TRANSFORM(RECCOUNT('crsRefuzate')) IF RECCOUNT('crsRefuzate') > 0 SELECT crsRefuzate SCAN DO PrLog WITH ' REFUZAT id_efactura=' + TRANSFORM(id_efactura) + ' motiv=' + ALLTRIM(NVL(motiv,'')) ENDSCAN ENDIF lnStersE = loAnul.Executa() DO PrLog WITH 'AnulareLotEF.Executa: sterse=' + TRANSFORM(lnStersE) + ' cEroare=[' + ALLTRIM(NVL(loAnul.cEroare,'')) + ']' LOCAL llC4OK, lnActRamase, lnIdFactRamas llC4OK = (lnStersE = lnOKRun1) FOR lnI = 1 TO 10 IF laRun1IdFact(lnI) = 0 LOOP ENDIF lnActRamase = 0 goExecutor.oSelecteaza2Value('select count(*) from act where id_fact = ' + TRANSFORM(laRun1IdFact(lnI)) + ' and sters = 0', @lnActRamase) IF NVL(lnActRamase,0) <> 0 llC4OK = .F. DO PrLog WITH ' C4 FAIL: id_fact=' + TRANSFORM(laRun1IdFact(lnI)) + ' mai are ' + TRANSFORM(lnActRamase) + ' randuri active in ACT' ENDIF lnIdFactRamas = -1 goExecutor.oSelecteaza2Value('select nvl(id_fact,0) from anaf_efactura where id = ' + TRANSFORM(laIdFacturi(lnI)), @lnIdFactRamas) IF NVL(lnIdFactRamas,-1) <> 0 llC4OK = .F. DO PrLog WITH ' C4 FAIL: anaf_efactura.id=' + TRANSFORM(laIdFacturi(lnI)) + ' id_fact nu s-a resetat (=' + TRANSFORM(lnIdFactRamas) + ')' ENDIF ENDFOR DO PrLog WITH 'VERDICT C4: ' + IIF(llC4OK, 'PASS', 'FAIL') *===================================================================== * AnulareLotEF/pack_contafin.sterge_document lasa uneori (nu mereu) un rand IREG_PARTENERI legat * de documentul tocmai sters - garda facturi_duplicate() refuza atunci reimportul urmator cu * acelasi numar (bug real, in afara acestui fisier). Testul isi curata singur urmele proprii * (serie_act sintetica ZZTC1, unica acestui test) ca sa fie rulabil de mai multe ori la rand. *===================================================================== LOCAL lnOrfaniIreg lnOrfaniIreg = 0 goExecutor.oSelecteaza2Value([select count(*) from ireg_parteneri ip where ip.serie_act = 'ZZTC1' and not exists (select 1 from act a where a.id_fact = ip.id_fact and a.sters = 0)], @lnOrfaniIreg) IF NVL(lnOrfaniIreg, 0) > 0 goExecutor.oExecute([delete from ireg_parteneri ip where ip.serie_act = 'ZZTC1' and not exists (select 1 from act a where a.id_fact = ip.id_fact and a.sters = 0)], '') SQLCOMMIT(gnHandle) ENDIF DO PrLog WITH 'curatenie orfani IREG_PARTENERI (serie_act=ZZTC1): ' + TRANSFORM(NVL(lnOrfaniIreg, 0)) + ' sterse' *===================================================================== * RUN 2: coada reala, UN singur apel do_coada() peste tot lotul bifat - exact ce ar face * operatorul. INKEY(0.01,'H') dintre documente (anaf_efactura.vc2:12406) e poll, nu asteptare * nelimitata, deci plafonul, confirmarea si raportul final sunt exercitate real. *===================================================================== DO BuildCursoare WITH lcListaId DO PrLog WITH 'RUN2: cursoare reconstruite dupa anulare, crsFacturi reccount=' + TRANSFORM(RECCOUNT('crsFacturi')) LOCAL loCoadaR2 loCoadaR2 = CREATEOBJECT('CoadaContabilizareEF') loCoadaR2.MarcheazaEligibilitate('crsFacturi', glLunaInchisa) SELECT crsFacturi REPLACE ALL ales WITH 0 LOCAL lnEligibile SELECT COUNT(*) FROM crsFacturi WHERE eligibil_lot = 1 INTO ARRAY laEligibile lnEligibile = laEligibile(1) DO PrLog WITH 'RUN2: facturi eligibile=' + TRANSFORM(lnEligibile) + ' din 10' IF lnEligibile < lnOKRun1 SELECT crsFacturi SCAN FOR eligibil_lot = 0 DO PrLog WITH ' RUN2 neeligibila: id=' + TRANSFORM(id) + ' motiv=' + ALLTRIM(NVL(motiv_lot,'')) ENDSCAN ENDIF * bifeaza toate facturile eligibile si fara linii gestionabile (ruta=2 - acelasi motiv de * excludere ca in RUN1, ImportModifica/frm_modific2024 blocheaza pe dialog nativ Windows headless) LOCAL lnBifate lnBifate = 0 FOR lnI = 1 TO 10 SELECT crsFacturi LOCATE FOR id = laIdFacturi(lnI) IF !FOUND() DO PrLog WITH ' RUN2[' + TRANSFORM(lnI) + '] FAIL: id=' + TRANSFORM(laIdFacturi(lnI)) + ' nu e in crsFacturi' LOOP ENDIF IF eligibil_lot <> 1 DO PrLog WITH ' RUN2[' + TRANSFORM(lnI) + '] SKIP: neeligibila (' + ALLTRIM(NVL(motiv_lot,'')) + ')' LOOP ENDIF LOCAL lnGestionabile LOCAL ARRAY laGest(1) SELECT COUNT(*) FROM crsDetaliiFacturi WHERE id_efactura = laIdFacturi(lnI) AND NVL(in_stoc,0) = 1 INTO ARRAY laGest lnGestionabile = laGest(1) IF lnGestionabile > 0 DO PrLog WITH ' RUN2[' + TRANSFORM(lnI) + '] SKIP: ruta=2 (linii gestionabile, in afara domeniului acestui test)' LOOP ENDIF SELECT crsFacturi REPLACE ales WITH 1 FOR id = laIdFacturi(lnI) lnBifate = lnBifate + 1 ENDFOR DO PrLog WITH 'RUN2: ' + TRANSFORM(lnBifate) + ' facturi bifate pentru un singur apel do_coada()' goTmrC1.Enabled = .T. gnC1TicksSameForm = 0 gcMockUltimMesaj = '' TRY loForm.do_coada() CATCH TO loExCoada DO PrLog WITH ' EXCEPTIE do_coada RUN2: ' + loExCoada.Message ENDTRY goTmrC1.Enabled = .F. DO PrLog WITH 'RUN2: do_coada() terminat, ultim mesaj amessagebox=[' + gcMockUltimMesaj + ']' IF USED('crsCoadaRaport') SELECT crsCoadaRaport SCAN DO PrLog WITH ' raport coada: id_efactura=' + TRANSFORM(id_efactura) + ' numar_act=' + ALLTRIM(numar_act) + ' stare=' + ALLTRIM(stare) + ' motiv=' + ALLTRIM(motiv) ENDSCAN ENDIF LOCAL ARRAY laRun2IdFact(10) FOR lnI = 1 TO 10 laRun2IdFact(lnI) = 0 lnIdFactDupa = 0 goExecutor.oSelecteaza2Value('select nvl(id_fact,0) from anaf_efactura where id = ' + TRANSFORM(laIdFacturi(lnI)), @lnIdFactDupa) laRun2IdFact(lnI) = NVL(lnIdFactDupa, 0) DO PrLog WITH ' RUN2[' + TRANSFORM(lnI) + '] id_efactura=' + TRANSFORM(laIdFacturi(lnI)) + ' id_fact=' + TRANSFORM(laRun2IdFact(lnI)) ENDFOR *===================================================================== * comparatie ACT, factura cu factura (RUN1 din fotografie, RUN2 din interogare vie) *===================================================================== LOCAL lnTotalDif, lnComparate, lcVerdict lnTotalDif = 0 lnComparate = 0 FOR lnI = 1 TO 10 IF laRun1IdFact(lnI) = 0 OR laRun2IdFact(lnI) = 0 DO PrLog WITH 'SKIP compara[' + TRANSFORM(lnI) + '] id_efactura=' + TRANSFORM(laIdFacturi(lnI)) + ; ' - lipseste documentul pe una din cai (run1=' + TRANSFORM(laRun1IdFact(lnI)) + ' run2=' + TRANSFORM(laRun2IdFact(lnI)) + ')' LOOP ENDIF lnComparate = lnComparate + 1 lnTotalDif = lnTotalDif + CompareInvoiceSnap(lnI, laRun2IdFact(lnI), 'id_efactura=' + TRANSFORM(laIdFacturi(lnI))) ENDFOR DO PrLog WITH 'facturi comparate=' + TRANSFORM(lnComparate) + '/10, diferente totale=' + TRANSFORM(lnTotalDif) * restul din 10 sunt SARIT de do_coada pe lipsuri reale (regula runda 18) - nu sunt parte din * echivalenta lot vs. document unic; pragul minim de comparatii evita un PASS fals pe 0 facturi DO CASE CASE lnTotalDif > 0 lcVerdict = 'FAIL - ' + TRANSFORM(lnTotalDif) + ' diferente' CASE lnComparate >= 2 lcVerdict = 'PASS (' + TRANSFORM(lnComparate) + '/10 comparate)' OTHERWISE lcVerdict = 'PARTIAL (' + TRANSFORM(lnComparate) + '/10 comparate) - sub pragul minim de 2, vezi SKIP mai sus' ENDCASE DO PrLog WITH 'VERDICT C1: ' + lcVerdict * curatenie optiune (documentele NU se sterg - aprobat explicit de Marius) RestaureazaOptiuni() DO PrLog WITH 'optiune EFACTURA_LOT_ACTIV restaurata' CATCH TO loExMain DO PrLog WITH 'EXCEPTIE NEASTEPTATA: ' + loExMain.Message + ' (' + TRANSFORM(loExMain.LineNo) + ') ' + loExMain.Procedure ENDTRY DO PrFinal QUIT ********************************************************** PROCEDURE BuildCursoare LPARAMETERS tcListaId * construieste crsFacturi/crsDetaliiFacturi pentru exact facturile din tcListaId, copie * fidela din efactura_import\test_import_efactura_smoke.prg (schema + select), cu filtru pe id * in loc de interval de date - la a doua chemare (dupa anulare) reflecta starea curenta din * Oracle (id_fact resetat, completat/completatdet reveniti la 0) LOCAL lcSchema, lcSelect, lcOrder, lcGroup, lcFiltru, lcFiltruOriginal, llModParam, llAfiseaza IF USED('crsFacturi') USE IN crsFacturi ENDIF IF USED('crsDetaliiFacturi') USE IN crsDetaliiFacturi ENDIF IF USED('crsDetaliiFacturiTemp') USE IN crsDetaliiFacturiTemp ENDIF 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), partener 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 C(30) 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) null, descriere M null, detalii_plata M null, diferenta N(16,4) null, procesat N(1), SerieActRoa V(10) Null, NrActRoa N(14) Null, IdPartRoa N(10) Null, PartenerRoa V(100) null, codFiscalROA V(20), idValutaROA N(5) null,numeValutaROA V(5) null, cursROA N(16,6) null,Cont c(4) Null,ACont c(4) Null,TVAIncasare N(1),Fdoc V(20) null,Id_Fdoc N(5) Null,Nrord V(100) null,Id_Lucrare I Null,Contract V(100) Null,Id_Ctr I Null,Sectie V(100) null,Id_Sectie I Null,dst_chlt V(100) null, Id_venchelt I NUll, nresp V(100) null, Id_responsabil I NUll , completat N(1), completatdet N(1), creditnote N(1), explicatiaROA V(100) null, eligibil_lot N(1), motiv_lot V(120), eroare_lot N(1), de_completat V(200), part_inactiv N(1) ENDTEXT TEXT TO lcSelect TEXTMERGE NOSHOW SELECT 0 as ales, id, id_fact, data_act, data_scad, numar_act, xfurnizor, xclient, partener, id_incarcare, id_descarcare, tip_mesaj_raspuns, mesaj_raspuns, data_raspuns, NVL(trimis,0) as trimis, data_trimis, cod_fiscal, 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, case when jtotctva is null then null when NVL(nume_valuta,'RON') <> 'RON' then null else decode(creditnote,0,1,-1) * NVL(total_cu_tva,0.00) - (NVL(jtotctva,0.00) - NVL(jtva_ti,0.00)) end as diferenta, procesat, '' as SerieActRoa, CAST(null as Number(14)) as NrActRoa, CAST(null as Number(20)) as idPartRoa, '' as PartenerRoa, '' as codFiscalROA, CAST(null as Number(10)) as idValutaROA, '' as numeValutaROA, CAST(null as Number(16,6)) as cursROA, '' as Cont, '' as acont, 0 as TVAIncasare, '' as Fdoc, CAST(0 as Number(5)) as Id_Fdoc, '' as Nrord, CAST(0 as Number(10)) as id_Lucrare, '' as Contract, CAST(null as Number(10)) as id_ctr, '' Sectie, CAST(0 as Number(10)) as id_Sectie, '' as dst_chlt, CAST(0 as Number(10)) as id_Venchelt, '' as nresp, CAST(0 as Number(10)) as id_responsabil, 0 as completat, 0 as completatdet, creditnote, '' as explicatiaROA, 1 as eligibil_lot, '' as motiv_lot, 0 as eroare_lot, '' as de_completat, 0 as part_inactiv FROM anaf_vefactura_primit ENDTEXT lcOrder = [data_act,numar_act,data_raspuns] lcGroup = [] lcFiltru = [id in (] + m.tcListaId + [)] lcFiltruOriginal = [] llModParam = .T. llAfiseaza = .F. PRIVATE poFacturi, poFacturiDetalii poFacturi = NULL poFacturiDetalii = NULL gencursor('poFacturi', 'crsFacturi', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcGroup, llModParam, lcFiltruOriginal) poFacturi.ca_baza1.afisare() TEXT TO lcSchema NOSHOW distribuie N(1), id_tip N(10) null, id_articol N(20) null, id_gestiune N(20) null, cont C(4) null, acont C(4) null, sursa_cont V(10) null, 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), um_iso V(50), um_roa V(50), pret N(20,6), proctva N(7,2), tiptva V(2), valoarefaratva N(20,6), discountfaratva N(20,6), in_stoc N(1), articol_roa V(250), codmat_roa V(50), codbare V(50), codclient V(100), codfurnizor V(100), codcpv V(50), codnc8 V(50), nume_gestiune V(50), cgest V(20), tva N(20,6), pretv N(20,6), tvav N(20,6), pretvtva N(20,6) ENDTEXT TEXT TO lcSelect NOSHOW select 0 as distribuie, CAST(0 as number(10)) as id_tip, id_articol, id_gestiune, cont, acont, sursa_cont, id, id_efactura, nr, articol, descriere, detalii, cantitate, um, um_iso, um_roa, pret, proctva, tiptva, valoarefaratva, discountfaratva, in_stoc, articol_roa, codmat_roa, codbare, codclient, codfurnizor, codcpv, codnc8, nume_gestiune, cgest, 0 as tva, 0 as pretv, 0 as tvav, 0 as pretvtva from anaf_vefactura_detalii ENDTEXT lcOrder = [id_efactura,nr] lcGroup = [] lcFiltru = [id_efactura in (] + m.tcListaId + [)] lcFiltruOriginal = [] llModParam = .T. llAfiseaza = .F. gencursor('poFacturiDetalii', 'crsDetaliiFacturiTemp', lcSelect, lcFiltru, lcSchema, lcOrder, llAfiseaza, lcGroup, llModParam, lcFiltruOriginal) poFacturiDetalii.ca_baza1.afisare() SELECT * FROM crsDetaliiFacturiTemp INTO CURSOR crsDetaliiFacturi READWRITE USE IN (SELECT('crsDetaliiFacturiTemp')) ENDPROC ********************************************************** * cursoare helper cerute la instantierea frm_import_efactura (grid-urile le leaga la CREATEOBJECT, * nu doar la Show()): fara ele, VFP incearca sa rezolve alias-urile lipsa (cTip/cGestiuni/cUMISO/cUM) * prin dialogul nativ "locate file", ~1 minut per alias lipsa - de-aici blocajul de peste 4 minute. * Copie fidela din test_import_efactura_smoke.prg PROCEDURE BuildCursoareHelper LOCAL llSucces IF USED('cTipArticoleP') USE IN cTipArticoleP ENDIF CREATE CURSOR cTipArticoleP (id I, in_stoc N(1), tip V(50), cont V(4), ordine I) INSERT INTO cTipArticoleP (id, tip, cont, in_stoc, ordine) VALUES (0, 'Nedefinit','', 0, 0) INSERT INTO cTipArticoleP (id, tip, cont, in_stoc, ordine) VALUES (12, 'Terti','628', 0, 12) SELECT cTipArticoleP GO TOP IN cTipArticoleP INDEX on ordine TAG ordine IF USED('cTipArticoleE') USE IN cTipArticoleE ENDIF CREATE CURSOR cTipArticoleE (id I, in_stoc N(1), tip V(50), cont V(4), ordine I) INSERT INTO cTipArticoleE (id, tip, cont, in_stoc, ordine) VALUES (0, 'Nedefinit','', 0, 0) INSERT INTO cTipArticoleE (id, tip, cont, in_stoc, ordine) VALUES (34, 'Servicii vandute','704', 0, 6) SELECT cTipArticoleE GO TOP IN cTipArticoleE INDEX on ordine TAG ordine IF USED('cTip') USE IN cTip ENDIF SELECT id, tip, cont, in_stoc, ordine FROM cTipArticoleP ORDER BY ordine INTO CURSOR cTip SELECT cTip INDEX on id TAG id IF USED('cGestiuni') USE IN cGestiuni ENDIF llSucces = goExecutor.oExecuta([select distinct nume_gestiune,cgest,id_gestiune,nr_pag,cont from vgest_gestiuni_util where inactiv = 0 and id_util = ] + ALLTRIM(STR(m.gnIdUtil)), 'cGestiuni') SELECT cGestiuni APPEND BLANK INDEX on id_gestiune TAG id_gest IF USED('cGestiuni2') USE IN cGestiuni2 ENDIF SELECT CAST(ALLTRIM(nume_gestiune) + '-' + ALLTRIM(NVL(cgest, '')) AS V(50)) AS nume_gestiune, id_gestiune FROM cGestiuni ORDER BY nume_gestiune INTO CURSOR cGestiuni2 IF USED('cUMISO') USE IN cUMISO ENDIF llSucces = goExecutor.oExecuta("select cod_um_iso, um_iso from syn_vnom_um_iso", 'cUMISO') SELECT cUMISO INDEX on cod_um_iso TAG cod_um_iso IF USED('cUM') USE IN cUM ENDIF llSucces = goExecutor.oExecuta("select id, um, cod_um_iso, um_iso from vnom_um", 'cUM') SELECT cUM INDEX on id TAG id ENDPROC ********************************************************** * fotografiaza + compara ACT: RUN1 din crsRun1Snapshot (fotografiat inainte de anulare - dupa C4 * id_fact-urile lui RUN1 nu mai au randuri active in ACT, o interogare vie ar da FAIL garantat), * RUN2 din interogare vie. Comparatie CA MULTIME (fiecare rand din run1 cauta o pereche * neconsumata in run2 cu toate coloanele egale), nu pozitionala - ordinea fizica de scriere in * ACT nu e parte din contractul de echivalenta, si SQL local (INDEX ON) vs ORDER BY Oracle pot * desparti altfel randurile egale la cheia de sortare. Exclus ID_ACT/DATAORA (cerute de sarcina) * + COD/ID_FACT (generate din nou la fiecare rulare) + RUN1_SEQ (doar cheia fotografiei). * Loghez fiecare diferenta gasita; intoarce numarul de diferente PROCEDURE CompareInvoiceSnap LPARAMETERS tnSeq, tnIdFact2, tcEticheta LOCAL lcSql, lnQ2, lnDif, lnJ, lnK, lnNCol, lcCol, llGasit, llMatch, lnTotR1 LOCAL ARRAY laFld(1) lnDif = 0 IF USED('crsC1R1') USE IN crsC1R1 ENDIF SELECT * FROM crsRun1Snapshot WHERE run1_seq = m.tnSeq INTO CURSOR crsC1R1 READWRITE lcSql = [select * from act where id_fact = ] + TRANSFORM(m.tnIdFact2) + [ and sters = 0] lnQ2 = goExecutor.oExecute(m.lcSql, 'crsC1R2') IF RECCOUNT('crsC1R1') <= 0 OR m.lnQ2 <= 0 DO PrLog WITH ' ' + m.tcEticheta + ': FAIL interogare ACT (run1(fotografie)=' + TRANSFORM(RECCOUNT('crsC1R1')) + ' run2=' + TRANSFORM(m.lnQ2) + ')' USE IN (SELECT('crsC1R1')) IF USED('crsC1R2') USE IN (SELECT('crsC1R2')) ENDIF RETURN 1 ENDIF IF RECCOUNT('crsC1R1') <> RECCOUNT('crsC1R2') DO PrLog WITH ' ' + m.tcEticheta + ': FAIL numar randuri ACT diferit - run1(fotografie)=' + ; TRANSFORM(RECCOUNT('crsC1R1')) + ' run2(id_fact=' + TRANSFORM(m.tnIdFact2) + ')=' + TRANSFORM(RECCOUNT('crsC1R2')) USE IN (SELECT('crsC1R1')) USE IN (SELECT('crsC1R2')) RETURN 1 ENDIF lnNCol = AFIELDS(laFld, 'crsC1R1') lnTotR1 = RECCOUNT('crsC1R1') LOCAL ARRAY laConsumat(MAX(RECCOUNT('crsC1R2'),1)) FOR lnK = 1 TO RECCOUNT('crsC1R2') laConsumat(lnK) = .F. ENDFOR SELECT crsC1R1 GO TOP FOR lnJ = 1 TO lnTotR1 llGasit = .F. SELECT crsC1R2 GO TOP FOR lnK = 1 TO RECCOUNT('crsC1R2') GO lnK IN crsC1R2 IF !laConsumat(lnK) llMatch = .T. FOR lnI = 1 TO lnNCol lcCol = UPPER(laFld(lnI,1)) IF INLIST(m.lcCol, 'ID_ACT', 'DATAORA', 'COD', 'ID_FACT', 'RUN1_SEQ') LOOP ENDIF IF !(EVALUATE('crsC1R1.' + m.lcCol) == EVALUATE('crsC1R2.' + m.lcCol)) llMatch = .F. EXIT ENDIF ENDFOR IF llMatch laConsumat(lnK) = .T. llGasit = .T. EXIT ENDIF ENDIF ENDFOR IF !llGasit lnDif = lnDif + 1 DO PrLog WITH ' ' + m.tcEticheta + ': DIFERENTA rand run1 fara pereche in run2 - scd=' + TRANSFORM(crsC1R1.scd) + ; ' scc=' + TRANSFORM(crsC1R1.scc) + ' suma=' + TRANSFORM(crsC1R1.suma) + ' proc_tva=' + TRANSFORM(NVL(crsC1R1.proc_tva,-1)) + ; ' id_jtva_coloana=' + TRANSFORM(NVL(crsC1R1.id_jtva_coloana,-1)) + ; ' | coloane diferite fata de cel mai apropiat rand run2: ' + ColoaneDiferite() ENDIF SELECT crsC1R1 SKIP ENDFOR FOR lnK = 1 TO RECCOUNT('crsC1R2') IF !laConsumat(lnK) GO lnK IN crsC1R2 lnDif = lnDif + 1 DO PrLog WITH ' ' + m.tcEticheta + ': DIFERENTA rand run2 fara pereche in run1 - scd=' + TRANSFORM(crsC1R2.scd) + ; ' scc=' + TRANSFORM(crsC1R2.scc) + ' suma=' + TRANSFORM(crsC1R2.suma) + ' proc_tva=' + TRANSFORM(NVL(crsC1R2.proc_tva,-1)) + ; ' id_jtva_coloana=' + TRANSFORM(NVL(crsC1R2.id_jtva_coloana,-1)) ENDIF ENDFOR IF lnDif = 0 DO PrLog WITH ' ' + m.tcEticheta + ': OK (' + TRANSFORM(lnTotR1) + ' randuri ACT identice ca multime)' ENDIF USE IN (SELECT('crsC1R1')) USE IN (SELECT('crsC1R2')) RETURN m.lnDif ENDPROC ********************************************************** * Pentru randul curent din crsC1R1, cauta in crsC1R2 randul cu acelasi scd/scc/suma si intoarce * coloanele in care difera (aceleasi excluderi ca la comparatie). Lasa ambele cursoare pe pozitia * de la intrare FUNCTION ColoaneDiferite LOCAL lnR1, lnR2, lnI, lnNC, lcCol, lcRez LOCAL ARRAY laFldD(1) lnR1 = RECNO('crsC1R1') lnR2 = RECNO('crsC1R2') lnNC = AFIELDS(laFldD, 'crsC1R1') lcRez = '' SELECT crsC1R2 LOCATE FOR scd == crsC1R1.scd AND scc == crsC1R1.scc AND suma = crsC1R1.suma IF FOUND() FOR lnI = 1 TO m.lnNC lcCol = UPPER(laFldD(m.lnI,1)) IF INLIST(m.lcCol, 'ID_ACT', 'DATAORA', 'COD', 'ID_FACT', 'RUN1_SEQ') LOOP ENDIF IF !(EVALUATE('crsC1R1.' + m.lcCol) == EVALUATE('crsC1R2.' + m.lcCol)) lcRez = m.lcRez + IIF(EMPTY(m.lcRez), '', ', ') + m.lcCol + '=[' + ; ALLTRIM(TRANSFORM(EVALUATE('crsC1R1.' + m.lcCol))) + '] vs [' + ; ALLTRIM(TRANSFORM(EVALUATE('crsC1R2.' + m.lcCol))) + ']' ENDIF ENDFOR ELSE lcRez = '(niciun rand run2 cu acelasi scd/scc/suma)' ENDIF IF m.lnR2 > 0 GO m.lnR2 IN crsC1R2 ENDIF SELECT crsC1R1 IF m.lnR1 > 0 GO m.lnR1 IN crsC1R1 ENDIF RETURN LEFT(IIF(EMPTY(m.lcRez), '(niciuna)', m.lcRez), 400) ENDFUNC ********************************************************** PROCEDURE PrLog LPARAMETERS tcMsg LOCAL lcL SET SAFETY OFF lcL = IIF(FILE(gcLog), FILETOSTR(gcLog), '') STRTOFILE(lcL + TRANSFORM(tcMsg) + CHR(13) + CHR(10), gcLog) ENDPROC ********************************************************** PROCEDURE PrErr LPARAMETERS tnErr, tcMsg, tcProg, tnLine DO PrLog WITH 'EROARE ' + TRANSFORM(tnErr) + ': ' + TRANSFORM(tcMsg) + ' in ' + TRANSFORM(tcProg) + ' linia ' + TRANSFORM(tnLine) ENDPROC ********************************************************** PROCEDURE PrFinal DO PrLog WITH 'DONE ' + TTOC(DATETIME()) ENDPROC ********************************************************** * deblocarea Show(1) a lui frm_introd_compact2007 (introducere_compacta, pmenu.prg): apasa REAL * butonul Terminat1.Command1 (verificare() + la_iesire() + Release, cod neschimbat) de indata ce * formularul apare in _SCREEN.Forms. Daca acelasi formular ramane deschis peste ~5s (validare * interna esuata - verificare() a intors .F.), il elibereaza fortat ca sa nu agate testul; acel * document ramane fara id_fact si testul il raporteaza SKIP/FAIL, nu PASS fals. ********************************************************** DEFINE CLASS tmrC1Deblocare AS Timer Interval = 250 Enabled = .F. PROCEDURE Timer LOCAL lnI, loF, llGasit gnC1Ticks = gnC1Ticks + 1 llGasit = .F. FOR lnI = 1 TO _SCREEN.FormCount loF = _SCREEN.Forms(lnI) IF UPPER(TRANSFORM(loF.Name)) == 'FRM_INTROD_COMPACT2007' llGasit = .T. gnC1TicksSameForm = gnC1TicksSameForm + 1 IF gnC1TicksSameForm > 20 DO PrLog WITH ' tmrC1Deblocare: force release dupa ' + TRANSFORM(gnC1TicksSameForm) + ' ticks (verificare() a esuat probabil)' TRY loF.Release() CATCH ENDTRY ELSE TRY loF.Terminat1.Command1.Click() glC1UltimulClick = .T. CATCH TO loErrClick DO PrLog WITH ' tmrC1Deblocare: EXCEPTIE la Click: ' + loErrClick.Message ENDTRY ENDIF EXIT ENDIF ENDFOR IF !llGasit gnC1TicksSameForm = 0 ENDIF ENDPROC ENDDEFINE