Files
comun/utile/Teste/test_c1_echivalenta_lot.prg
Marius Mutu 940bb39701 Import eFactura in lot: borderou cu ce lipseste, coada de contabilizare, alegerea contului
Borderoul tine per factura ce mai are de completat si daca are articole de gestiune
(camp gest, coloana si filtru), coada contabilizeaza in serie facturile bifate si
incheie cu un rezumat, iar contul de furnizor/client se alege din planul de conturi.
Cheia normalizata de articol, rezolvarea automata a partenerului si anularea in bloc
intra tot aici. Pozitia in lista se pastreaza peste reaplicarea filtrului.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Aroafxp4z8bmM5oVECZRXY
2026-09-09 22:06:48 +03:00

781 lines
34 KiB
Plaintext

* 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 = <id_fact din run> 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