Cache ANAF: verificarea in masa a codurilor fiscale, pe transe (SVN r17935)

Verificarea "in masa" (VerificaListaCIF ... 'MASA') pica pe ORA-01795 peste 1000
de coduri, iar esecul trimitea tot lotul la ANAF, cu pauze de o secunda la fiecare
100 de coduri. Pe langa asta, fiecare rand servit din cache era salvat inapoi in
istoric si logat separat.

- programe/validare.prg: CitesteIstoricPentruCoduri citeste pe transe de maxim
  1000 de coduri legate cu OR in aceeasi interogare (fara obiecte noi in baza,
  compatibil cu Oracle 10g); plasa de siguranta cere codurile neacoperite o
  singura data, nu cod cu cod; SalveazaIstoricDinCursor sare peste randurile cu
  sursa CACHE*; bucla de log per rand devine o singura linie cu totalul.
- clase/overificari.vc2: completarea tabelului de parteneri foloseste index pe
  codul normalizat si SEEK in loc de LOCATE cu UDF (era patratic).
- utile/Teste/cache_anaf/: harness-uri de masurare si non-regresie pentru
  timpii de mai jos.

Masurat pe MARIUSM_AUTO, cu ANAF blocat: 1000 de coduri 5,1 s -> 0,318 s;
1001 coduri 16,6 s cu ORA-01795 -> 0,553 s fara eroare; 3000 de coduri 1,565 s;
200 de coduri din cache 3,93 s -> 0,05 s, cu 0 randuri noi in istoric;
completarea tabelului pentru 2000 de parteneri 11,97 s -> 0,028 s.
Randurile intoarse si verdictele raman identice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JCzVWfqscv1xyo5uvJiWiW
This commit is contained in:
2026-08-02 07:27:42 +03:00
parent 4342aae78c
commit 5c8a201438
8 changed files with 2043 additions and 15 deletions

View File

@@ -2727,6 +2727,10 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
loVerificareANAF = CREATEOBJECT("VerificareANAF") && validare.prg loVerificareANAF = CREATEOBJECT("VerificareANAF") && validare.prg
SELECT crsVerificareParteneri
REPLACE ALL cod_fiscalfro WITH ALLTRIM(Strtran(cod_fiscal, loVerificare.GetCodTara(cod_fiscal),''))
INDEX ON cod_fiscalfro TAG cfro
SELECT distinct data FROM cListaCIFTempX INTO CURSOR cListaCIFTempData SELECT distinct data FROM cListaCIFTempX INTO CURSOR cListaCIFTempData
SELECT cListaCIFTempData SELECT cListaCIFTempData
SCAN SCAN
@@ -2741,17 +2745,29 @@ DEFINE CLASS frm_verificare_parteneri AS _frmbase OF "_frm_base.vcx"
SCAN SCAN
SCATTER NAME loRec SCATTER NAME loRec
WITH loRec WITH loRec
lcCheieCauta = PADR(ALLTRIM(STR(.cui)), 30)
SELECT crsVerificareParteneri SELECT crsVerificareParteneri
LOCATE FOR ALLTRIM(Strtran(cod_fiscal, loVerificare.GetCodTara(cod_fiscal),'')) = ALLTRIM(STR(.cui)) AND (EMPTY(NVL(data, {})) OR data = m.ldData) llGasit = .F.
IF FOUND() IF SEEK(m.lcCheieCauta, 'crsVerificareParteneri', 'cfro')
llGasit = .T.
DO WHILE !(EMPTY(NVL(data, {})) OR data = m.ldData)
SKIP
IF EOF() OR cod_fiscalfro <> m.lcCheieCauta
llGasit = .F.
EXIT
ENDIF
ENDDO
ENDIF
IF llGasit
Replace firma With .denumire, adresa With .adresa, datatvamfin With TRANSFORM(.data), platitortvamfin With .tva, stare With .mesaj, cod WITH ALLTRIM(STR(.cui)), ; Replace firma With .denumire, adresa With .adresa, datatvamfin With TRANSFORM(.data), platitortvamfin With .tva, stare With .mesaj, cod WITH ALLTRIM(STR(.cui)), ;
tvaincasare WITH .tvaincasare, splittva WITH .splittva, inactiv WITH .inactiv, ; tvaincasare WITH .tvaincasare, splittva WITH .splittva, inactiv WITH .inactiv, ;
sursa WITH NVL(.sursa, 'ANAF'), data_sursa WITH .data_sursa sursa WITH NVL(.sursa, 'ANAF'), data_sursa WITH .data_sursa
ENDIF ENDIF
ENDWITH ENDWITH
ENDSCAN && (m.lcCursorVerificareANAF) ENDSCAN && (m.lcCursorVerificareANAF)
ENDIF ENDIF
ENDSCAN && cListaCIFTempData ENDSCAN && cListaCIFTempData
SET ORDER TO 0 IN crsVerificareParteneri
USE IN (SELECT('cListaCIFTempData')) USE IN (SELECT('cListaCIFTempData'))
USE IN (SELECT('cListaCIFTempX')) USE IN (SELECT('cListaCIFTempX'))
USE IN (SELECT('cListaCIFTemp')) USE IN (SELECT('cListaCIFTemp'))

View File

@@ -100,6 +100,15 @@
*!* provenienta; altfel cache-ul isi reseta singur ceasul de prospetime la fiecare citire si nu mai *!* provenienta; altfel cache-ul isi reseta singur ceasul de prospetime la fiecare citire si nu mai
*!* expira niciodata *!* expira niciodata
*!* 02.08.2026
*!* marius.mutu
*!* SalveazaIstoricDinCursor sare peste randurile provenite din cache - au fost deja salvate cand au
*!* ajuns prima data din ANAF; VerificaListaCIF lasa o singura linie in goLog cu totalul randurilor
*!* completate din cache (CACHE si CACHE_INDISP), in loc de o linie per rand; CitesteIstoricPentruCoduri
*!* interogheaza codurile pe transe de maxim 1000, legate cu OR in aceeasi interogare (peste 1000
*!* elemente "in (...)" da ORA-01795); plasa de siguranta din VerificaListaCIF aduna codurile ramase
*!* fara raspuns si cere istoricul intr-un singur apel, in loc de un apel Oracle per cod
*!* http://ec.europa.eu/taxation_customs/vies/viesquer.do *!* http://ec.europa.eu/taxation_customs/vies/viesquer.do
*!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CIF/1879855/MFIN *!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CIF/1879855/MFIN
*!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CNP/1810228134187 *!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CNP/1810228134187
@@ -1891,7 +1900,7 @@ Define Class VerificareANAF As Custom
Local llUsed, lcCursorListaCIF, lnRec, lnRecs, lcAlias Local llUsed, lcCursorListaCIF, lnRec, lnRecs, lcAlias
*!* 31.07.2026 marius.mutu: al patrulea parametru tcTraseu forteaza OrdineCache(tcTraseu) in loc de 'MASA' fix *!* 31.07.2026 marius.mutu: al patrulea parametru tcTraseu forteaza OrdineCache(tcTraseu) in loc de 'MASA' fix
Local lcOrdine, ldData, lcAliasNorm, lcListaCoduriN, lcCursorRamas, lnCuiCurent, lcCodFiscalCurent, ldDataCurenta, llGasitCache, lcCursorAnafTemp, loRandAnaf, lnFaraRaspuns Local lcOrdine, ldData, lcAliasNorm, lcListaCoduriN, lcCursorRamas, lnCuiCurent, lcCodFiscalCurent, ldDataCurenta, llGasitCache, lcCursorAnafTemp, loRandAnaf, lnFaraRaspuns, lnCache, lnCacheIndisp, lcListaCoduriRamase
lcCursorListaCIF = "" lcCursorListaCIF = ""
llUsed = .F. llUsed = .F.
@@ -1981,6 +1990,7 @@ Define Class VerificareANAF As Custom
* plasa de siguranta la tacere, indiferent de ordine: codurile fara rand in crsANAF (nici din ANAF, * plasa de siguranta la tacere, indiferent de ordine: codurile fara rand in crsANAF (nici din ANAF,
* nici din cache) se completeaza acum din istoric, marcate CACHE_INDISP; un rand deja prezent * nici din cache) se completeaza acum din istoric, marcate CACHE_INDISP; un rand deja prezent
* (raspuns ANAF gasit sau notFound, sau deja servit din cache mai sus) nu e atins * (raspuns ANAF gasit sau notFound, sau deja servit din cache mai sus) nu e atins
lcListaCoduriRamase = ''
Select (m.lcAliasNorm) Select (m.lcAliasNorm)
Scan For cui_n <> 0 Scan For cui_n <> 0
lnCuiCurent = cui_n lnCuiCurent = cui_n
@@ -1991,17 +2001,27 @@ Define Class VerificareANAF As Custom
llGasitCache = Found() llGasitCache = Found()
Endif Endif
If !m.llGasitCache If !m.llGasitCache
This.CitesteIstoricPentruCoduri(Transform(m.lnCuiCurent), m.ldData, m.lcAlias, 'CACHE_INDISP') lcListaCoduriRamase = m.lcListaCoduriRamase + Iif(Empty(m.lcListaCoduriRamase), '', ',') + Transform(m.lnCuiCurent)
If Used(m.lcAlias)
Select (m.lcAlias)
Locate For cui = m.lnCuiCurent
Endif
lnFaraRaspuns = m.lnFaraRaspuns + Iif(Used(m.lcAlias) And Found(), 0, 1)
Endif Endif
Select (m.lcAliasNorm) Select (m.lcAliasNorm)
Endscan Endscan
Use In (Select(m.lcAliasNorm)) Use In (Select(m.lcAliasNorm))
If !Empty(m.lcListaCoduriRamase)
This.CitesteIstoricPentruCoduri(m.lcListaCoduriRamase, m.ldData, m.lcAlias, 'CACHE_INDISP')
lnRecs = Getwordcount(m.lcListaCoduriRamase, ',')
For lnRec = 1 To m.lnRecs
lnCuiCurent = Val(Getwordnum(m.lcListaCoduriRamase, m.lnRec, ','))
llGasitCache = .F.
If Used(m.lcAlias) And Reccount(m.lcAlias) > 0
Select (m.lcAlias)
Locate For cui = m.lnCuiCurent
llGasitCache = Found()
Endif
lnFaraRaspuns = m.lnFaraRaspuns + Iif(m.llGasitCache, 0, 1)
Endfor
Endif
*!* 01.08.2026 marius.mutu: un singur mesaj la final, doar cand au ramas coduri fara verdict (nici de la ANAF, nici din cache) *!* 01.08.2026 marius.mutu: un singur mesaj la final, doar cand au ramas coduri fara verdict (nici de la ANAF, nici din cache)
If m.lnFaraRaspuns > 0 And !Empty(This.cMesajANAF) If m.lnFaraRaspuns > 0 And !Empty(This.cMesajANAF)
AMESSAGEBOX(This.cMesajANAF + Chr(13) + Chr(10) + Alltrim(Str(m.lnFaraRaspuns)) + ' coduri fiscale nu au putut fi verificate.', 0 + 48, _Screen.Caption) AMESSAGEBOX(This.cMesajANAF + Chr(13) + Chr(10) + Alltrim(Str(m.lnFaraRaspuns)) + ' coduri fiscale nu au putut fi verificate.', 0 + 48, _Screen.Caption)
@@ -2011,13 +2031,22 @@ Define Class VerificareANAF As Custom
This.SalveazaIstoricDinCursor(m.lcAlias, gnIdUtil) This.SalveazaIstoricDinCursor(m.lcAlias, gnIdUtil)
Endif Endif
* criteriul 9: fiecare rand completat din cache (CACHE sau CACHE_INDISP) se lasa si in goLog, cu codul si data_sursa * criteriul 9: totalul randurilor completate din cache (CACHE si CACHE_INDISP), o singura linie in goLog
If Used(m.lcAlias) And Reccount(m.lcAlias) > 0 If Used(m.lcAlias) And Reccount(m.lcAlias) > 0
Select (m.lcAlias) Select (m.lcAlias)
lnCache = 0
lnCacheIndisp = 0
Scan For Left(Nvl(sursa, ''), 5) == 'CACHE' Scan For Left(Nvl(sursa, ''), 5) == 'CACHE'
goLog.Log('cache cui=' + Transform(cui) + ' sursa=' + Alltrim(sursa) + ' data_sursa=' + Dtoc(Nvl(data_sursa, {})), 'VerificaListaCIF') If Upper(Alltrim(sursa)) == 'CACHE_INDISP'
lnCacheIndisp = m.lnCacheIndisp + 1
Else
lnCache = m.lnCache + 1
Endif
Select (m.lcAlias) Select (m.lcAlias)
Endscan Endscan
If m.lnCache + m.lnCacheIndisp > 0
goLog.Log('cache total=' + Transform(m.lnCache + m.lnCacheIndisp) + ' cache=' + Transform(m.lnCache) + ' cache_indisp=' + Transform(m.lnCacheIndisp), 'VerificaListaCIF')
Endif
Endif Endif
Return m.lcAlias Return m.lcAlias
@@ -2605,6 +2634,7 @@ Define Class VerificareANAF As Custom
************************************* *************************************
*** Parcurge un cursor in forma crsANAF si salveaza fiecare rand in ISTORIC_CODURI_FISCALE *** Parcurge un cursor in forma crsANAF si salveaza fiecare rand in ISTORIC_CODURI_FISCALE
*** prin pack_parteneri.save_istoric_cod_fiscal (26 parametri); commit din 100 in 100 si la final *** prin pack_parteneri.save_istoric_cod_fiscal (26 parametri); commit din 100 in 100 si la final
*** Sare peste randurile provenite din cache (sursa incepe cu 'CACHE') - au fost deja salvate
*** Intoarce numarul de randuri salvate cu succes *** Intoarce numarul de randuri salvate cu succes
************************************* *************************************
Function SalveazaIstoricDinCursor Function SalveazaIstoricDinCursor
@@ -2627,7 +2657,7 @@ Define Class VerificareANAF As Custom
Select (m.tcAlias) Select (m.tcAlias)
lnRecnoInit = Recno() lnRecnoInit = Recno()
Scan For cui <> 0 Scan For cui <> 0 And Left(Nvl(sursa, ''), 5) <> 'CACHE'
pcCodFiscal = Transform(cui) pcCodFiscal = Transform(cui)
pcFirma = Nvl(firma, '') pcFirma = Nvl(firma, '')
pcAdresa = Nvl(adresa, '') pcAdresa = Nvl(adresa, '')
@@ -2698,7 +2728,7 @@ Define Class VerificareANAF As Custom
Function CitesteIstoricPentruCoduri Function CitesteIstoricPentruCoduri
Lparameters tcListaCoduriN, tdData, tcAlias, tcSursa Lparameters tcListaCoduriN, tdData, tcAlias, tcSursa
Local lcAlias, lcCursorIstoric, lcSql, ldData, lnZileCache, lcSelect, lcSursa Local lcAlias, lcCursorIstoric, lcSql, ldData, lnZileCache, lcSelect, lcSursa, lcCondCod, lnTotalCod, lnTranse, lnTransa, lnI, lcTransa
*!* 30.07.2026 marius.mutu: pdDataCache/pnZileCache Private, nu Local, ca sa fie vizibile in goExecutor.oExecuta la bind *!* 30.07.2026 marius.mutu: pdDataCache/pnZileCache Private, nu Local, ca sa fie vizibile in goExecutor.oExecuta la bind
Private pdDataCache, pnZileCache Private pdDataCache, pnZileCache
lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF") lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
@@ -2727,6 +2757,21 @@ Define Class VerificareANAF As Custom
lcCursorIstoric = 'crsIstoricCacheTemp' lcCursorIstoric = 'crsIstoricCacheTemp'
Use In (Select(m.lcCursorIstoric)) Use In (Select(m.lcCursorIstoric))
*!* 02.08.2026 marius.mutu: transe de maxim 1000 coduri legate cu OR - peste 1000 elemente "in (...)" da ORA-01795
lnTotalCod = Getwordcount(m.tcListaCoduriN, ',')
lnTranse = Ceiling(m.lnTotalCod / 1000)
lcCondCod = ''
For lnTransa = 1 To m.lnTranse
lcTransa = ''
For lnI = (m.lnTransa - 1) * 1000 + 1 To Min(m.lnTransa * 1000, m.lnTotalCod)
lcTransa = m.lcTransa + Iif(Empty(m.lcTransa), '', ',') + Getwordnum(m.tcListaCoduriN, m.lnI, ',')
Endfor
lcCondCod = m.lcCondCod + Iif(Empty(m.lcCondCod), '', ' or ') + 'cod_fiscal_n in (' + m.lcTransa + ')'
Endfor
If m.lnTranse > 1
lcCondCod = '(' + m.lcCondCod + ')'
Endif
*!* 01.08.2026 marius.mutu: v_tvainc - margine exclusiva (data_sfarsit_tvainc - 1), aliniata cu pack_roartvai; ground truth rtvai_istoric confirma [inceput,sfarsit) *!* 01.08.2026 marius.mutu: v_tvainc - margine exclusiva (data_sfarsit_tvainc - 1), aliniata cu pack_roartvai; ground truth rtvai_istoric confirma [inceput,sfarsit)
TEXT To lcSql TEXTMERGE Noshow TEXT To lcSql TEXTMERGE Noshow
select cod_fiscal_n, firma, adresa, judet, regcom, dataorav_anaf, select cod_fiscal_n, firma, adresa, judet, regcom, dataorav_anaf,
@@ -2739,7 +2784,7 @@ select cod_fiscal_n, firma, adresa, judet, regcom, dataorav_anaf,
case when data_inactivare is not null and ?pdDataCache >= data_inactivare and (data_reactivare is null or ?pdDataCache < data_reactivare) then 1 else 0 end as v_inactiv case when data_inactivare is not null and ?pdDataCache >= data_inactivare and (data_reactivare is null or ?pdDataCache < data_reactivare) then 1 else 0 end as v_inactiv
from (select i.*, row_number() over (partition by cod_fiscal_n order by id desc) as rn from (select i.*, row_number() over (partition by cod_fiscal_n order by id desc) as rn
from istoric_coduri_fiscale i from istoric_coduri_fiscale i
where cod_fiscal_n in (<<m.tcListaCoduriN>>) where <<m.lcCondCod>>
and dataorav_anaf is not null and dataorav_anaf is not null
and sysdate - dataorav_anaf <= ?pnZileCache) and sysdate - dataorav_anaf <= ?pnZileCache)
where rn = 1 where rn = 1

View File

@@ -0,0 +1,425 @@
* test_benchmark_in1000.prg - compara 3 variante pentru citirea din ISTORIC_CODURI_FISCALE
* pe loturi mari de coduri fiscale, ca inlocuitor pentru IN (<lista>) inline care pica pe
* ORA-01795 peste 1000 elemente (CitesteIstoricPentruCoduri, validare.prg:2698).
* A - transe de max 1000 legate cu OR in aceeasi interogare
* B - o interogare per transa de 1000, acumulate in acelasi cursor rezultat
* C - tabela temporara globala (GTT) populata cu INSERT ALL, IN (subquery) pe GTT
* Fiecare varianta ruleaza de 3 ori per lot (1000/2000/5000 coduri), se retine mediana.
* Nu modifica validare.prg. Obiectele Oracle create (GTT de test) se sterg la final.
*
* Rulare: vfp9.exe -A -T "...\test_benchmark_in1000.prg" [watermark]
LPARAMETERS tcWatermark
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcTestLog, pdDataCache, pnZileCache
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_benchmark_in1000_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
ON ERROR DO ErrBench WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO WrLogB WITH 'EROARE: conectare Oracle esuata - GATA'
QUIT
ENDIF
DO WrLogB WITH 'mediu OK, schema=' + gcS
PUBLIC gnErorriSQL, gcUltimaEroareSQL
gnErorriSQL = 0
gcUltimaEroareSQL = ''
LOCAL loExecNou
loExecNou = CREATEOBJECT('oexec_fara_dialog')
loExecNou.nHandle = gnHandle
goExecutor = loExecNou
DO WrLogB WITH 'executor inlocuit (fara dialog modal la eroare SQL)'
pdDataCache = DATE()
pnZileCache = 36500 && vreau sa vad toate randurile din istoric, indiferent de prospetime
*==========================================================
* 0. curatenie ramasa din rularea anterioara + watermark nou
*==========================================================
LOCAL lnWm
lnWm = IIF(TYPE('tcWatermark') = 'C' AND !EMPTY(tcWatermark), INT(VAL(tcWatermark)), 0)
IF lnWm > 0
=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(lnWm))
=goExecutor.oExecuta('COMMIT')
DO WrLogB WITH 'curatenie facuta (ID > ' + TRANSFORM(lnWm) + ')'
ENDIF
PUBLIC gnIdMaxIstoric
gnIdMaxIstoric = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsWm')
gnIdMaxIstoric = crsWm.IDMAX
USE IN crsWm
ENDIF
DO WrLogB WITH 'watermark nou = ' + TRANSFORM(gnIdMaxIstoric)
*==========================================================
* 1. incarc cele 200 coduri reale + pregatesc obiectul GTT pentru varianta C
*==========================================================
LOCAL laReale[200], lnNReale, lcLinie, lnFH
lnNReale = 0
lnFH = FOPEN('D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\codes_200_reale.txt')
IF lnFH >= 0
DO WHILE !FEOF(lnFH)
lcLinie = ALLTRIM(FGETS(lnFH))
IF !EMPTY(lcLinie)
lnNReale = lnNReale + 1
laReale[lnNReale] = lcLinie
ENDIF
ENDDO
=FCLOSE(lnFH)
ENDIF
DO WrLogB WITH 'coduri reale incarcate: ' + TRANSFORM(lnNReale)
DO WrLogB WITH ''
DO WrLogB WITH '=== pregatire GTT pentru varianta C ==='
LOCAL llGttOk
llGttOk = .T.
IF !goExecutor.oExecuta("SELECT 1 AS N FROM ALL_TABLES WHERE TABLE_NAME = 'BENCH_LOT_CF' AND OWNER = SYS_CONTEXT('USERENV','CURRENT_SCHEMA')", 'crsChk')
llGttOk = .F.
ENDIF
LOCAL llExistaDeja
llExistaDeja = (TYPE('crsChk') = 'U' OR !USED('crsChk'))
IF USED('crsChk')
llExistaDeja = (RECCOUNT('crsChk') > 0)
USE IN crsChk
ENDIF
IF !llExistaDeja
IF goExecutor.oExecuta('CREATE GLOBAL TEMPORARY TABLE bench_lot_cf (cod_fiscal_n NUMBER(13)) ON COMMIT PRESERVE ROWS')
DO WrLogB WITH 'GTT bench_lot_cf creata'
ELSE
DO WrLogB WITH 'EROARE la crearea GTT: ' + gcUltimaEroareSQL
llGttOk = .F.
ENDIF
ELSE
DO WrLogB WITH 'GTT bench_lot_cf exista deja (rulare anterioara neterminata) - refolosesc'
ENDIF
*==========================================================
* 2. rulez cele 3 variante pe loturile 1000 / 2000 / 5000
*==========================================================
LOCAL laLoturi[3], lnLot, lnCntLot
laLoturi[1] = 1000
laLoturi[2] = 2000
laLoturi[3] = 5000
FOR lnLot = 1 TO 3
lnCntLot = laLoturi[lnLot]
DO WrLogB WITH ''
DO WrLogB WITH '######## LOT ' + TRANSFORM(lnCntLot) + ' coduri ########'
LOCAL lcLista, lnNRandA, lnNRandB, lnNRandC
lcLista = BenchListaCoduri(lnCntLot, @laReale, lnNReale)
* --- Varianta A: transe de 1000 legate cu OR ---
LOCAL laTA[3], lnI, lnT0, lcSqlA, lnRandA
FOR lnI = 1 TO 3
lnT0 = SECONDS()
lnRandA = BenchRunVarA(lcLista)
laTA[lnI] = SECONDS() - lnT0
ENDFOR
lnNRandA = lnRandA
DO WrLogB WITH 'A (OR-transe) timpi=' + BenchFmtArr(@laTA) + ' mediana=' + TRANSFORM(ROUND(BenchMediana(@laTA), 3)) + ' s randuri=' + TRANSFORM(lnNRandA)
* --- Varianta B: o interogare per transa de 1000, acumulate ---
LOCAL laTB[3], lnRandB
FOR lnI = 1 TO 3
lnT0 = SECONDS()
lnRandB = BenchRunVarB(lcLista)
laTB[lnI] = SECONDS() - lnT0
ENDFOR
lnNRandB = lnRandB
DO WrLogB WITH 'B (bucla transe) timpi=' + BenchFmtArr(@laTB) + ' mediana=' + TRANSFORM(ROUND(BenchMediana(@laTB), 3)) + ' s randuri=' + TRANSFORM(lnNRandB)
* --- Varianta C: GTT + IN (subquery), populare + interogare ---
* NOTA: dezactivata din masuratoarea cronometrata - vezi test_debug_gtt3/4_log.txt:
* pe conexiunea ODBC a aplicatiei (DSN CENTRAL, driver SQORA32.dll din instantclient_11_2_0_2),
* CREATE GLOBAL TEMPORARY TABLE reuseste cu succes (SID neschimbat), dar orice interogare
* ulterioara pe acelasi GTT, in ACEEASI sesiune, intoarce ORA-00942 "table or view does not
* exist" - un tabel normal (CREATE TABLE, fara GLOBAL TEMPORARY), pe aceeasi conexiune, in
* aceeasi succesiune de apeluri, functioneaza corect. Acelasi flux (create/insert/select),
* rulat direct in sqlplus pe acelasi schema/instanta, functioneaza corect. Deci problema e
* specifica GTT + acest driver ODBC, nu Oracle sau schema. Cifrele de populare (INSERT ALL)
* raman valide ca measura a costului insertiei, dar timpul de interogare de mai jos nu e
* comparabil (subquery pe GTT gol -> 0 randuri, cost artificial de mic).
IF llGttOk
LOCAL laTC[3], laTCins[3], lnRandC
FOR lnI = 1 TO 3
lnT0 = SECONDS()
lnRandC = BenchRunVarC(lcLista, @laTCins, lnI)
laTC[lnI] = SECONDS() - lnT0
ENDFOR
lnNRandC = lnRandC
DO WrLogB WITH 'C (GTT+IN sub, NECONCLUDENT - vezi nota) timpi=' + BenchFmtArr(@laTC) + ' mediana=' + TRANSFORM(ROUND(BenchMediana(@laTC), 3)) + ' s randuri=' + TRANSFORM(lnNRandC) + ' (din care populare GTT, mediana=' + TRANSFORM(ROUND(BenchMediana(@laTCins), 3)) + ' s)'
ELSE
DO WrLogB WITH 'C (GTT+IN sub) SARITA - GTT indisponibila'
ENDIF
* sanitate: A si B trebuie sa intoarca acelasi numar de randuri (C e neconcludenta, vezi nota)
IF lnNRandA = lnNRandB
DO WrLogB WITH ' OK: A si B au intors acelasi numar de randuri'
ELSE
DO WrLogB WITH ' ATENTIE: numar de randuri DIFERIT intre A si B!'
ENDIF
ENDFOR
*==========================================================
* 3. varianta D: fezabilitate colectie PL/SQL peste ODBC din VFP
* NOTA: testul complet (test_debug_vard.prg) s-a incheiat cu terminarea abrupta a procesului
* vfp9.exe la incercarea de a lega un array VFP direct ca parametru colectie (?laCoduri) intr-un
* SQLExec - nu o eroare Oracle capturabila, ci un crash al gazdei. Vezi raportul pentru detalii;
* nu se re-ruleaza aici ca sa nu intrerupa restul masuratorilor.
*==========================================================
*==========================================================
* 4. curatenie
*==========================================================
DO WrLogB WITH ''
IF llGttOk
=goExecutor.oExecuta('DROP TABLE bench_lot_cf')
DO WrLogB WITH 'GTT bench_lot_cf stearsa'
ENDIF
IF TYPE('gnIdMaxIstoric') = 'N' AND gnIdMaxIstoric > 0
=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnIdMaxIstoric))
=goExecutor.oExecuta('COMMIT')
DO WrLogB WITH 'curatenie finala: sterse randurile cu ID > ' + TRANSFORM(gnIdMaxIstoric)
ENDIF
DO WrLogB WITH 'GATA ' + TTOC(DATETIME())
QUIT
*==========================================================
* helpere
*==========================================================
PROCEDURE WrLogB
LPARAMETERS tcText
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC
PROCEDURE ErrBench
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
STRTOFILE('EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine) + CHR(13) + CHR(10), gcTestLog, .T.)
RETURN
ENDPROC
FUNCTION BenchMediana
LPARAMETERS taValori
LOCAL laSort[3], lnI, lnJ, lnTmp
FOR lnI = 1 TO 3
laSort[lnI] = taValori[lnI]
ENDFOR
FOR lnI = 1 TO 2
FOR lnJ = lnI + 1 TO 3
IF laSort[lnJ] < laSort[lnI]
lnTmp = laSort[lnI]
laSort[lnI] = laSort[lnJ]
laSort[lnJ] = lnTmp
ENDIF
ENDFOR
ENDFOR
RETURN laSort[2]
ENDFUNC
FUNCTION BenchFmtArr
LPARAMETERS taValori
LOCAL lcRez, lnI
lcRez = '['
FOR lnI = 1 TO 3
lcRez = lcRez + TRANSFORM(ROUND(taValori[lnI], 3)) + IIF(lnI < 3, ', ', '')
ENDFOR
RETURN lcRez + ']'
ENDFUNC
*** construieste lista CSV de coduri normalizate pentru un lot de tnSize: primele MIN(tnSize,200)
*** din cele reale, restul sintetice (8000000001...) - distincte, deterministe intre variante
FUNCTION BenchListaCoduri
LPARAMETERS tnSize, taReale, tnNReale
LOCAL lcLista, lnI, lnNReal
lcLista = ''
lnNReal = MIN(tnSize, tnNReale)
FOR lnI = 1 TO lnNReal
lcLista = lcLista + IIF(EMPTY(lcLista), '', ',') + taReale[lnI]
ENDFOR
FOR lnI = lnNReal + 1 TO tnSize
lcLista = lcLista + IIF(EMPTY(lcLista), '', ',') + TRANSFORM(8000000000 + lnI)
ENDFOR
RETURN lcLista
ENDFUNC
*** taie lcLista (CSV) in transe de maxim tnMax elemente, intoarce array de siruri CSV
FUNCTION BenchTransaza
LPARAMETERS tcLista, tnMax, taTranse
LOCAL lnTotal, lnTranse, lnI, lnDe, lnLa, lnJ
lnTotal = GETWORDCOUNT(tcLista, ',')
lnTranse = CEILING(lnTotal / tnMax)
DIMENSION taTranse[MAX(lnTranse, 1)]
FOR lnI = 1 TO lnTranse
lnDe = (lnI - 1) * tnMax + 1
lnLa = MIN(lnI * tnMax, lnTotal)
LOCAL lcBucata
lcBucata = ''
FOR lnJ = lnDe TO lnLa
lcBucata = lcBucata + IIF(EMPTY(lcBucata), '', ',') + GETWORDNUM(tcLista, lnJ, ',')
ENDFOR
taTranse[lnI] = lcBucata
ENDFOR
RETURN lnTranse
ENDFUNC
*** interogarea de baza (identica cu CitesteIstoricPentruCoduri, validare.prg:2731-2749),
*** cu <<lcCondCod>> ca placeholder pentru conditia pe cod_fiscal_n
FUNCTION BenchSqlBaza
LPARAMETERS tcCondCod
LOCAL lcSql
TEXT TO lcSql TEXTMERGE NOSHOW
select cod_fiscal_n, firma, adresa, judet, regcom, dataorav_anaf,
data_inceput_scptva, data_sfarsit_scptva, data_anul_imp_scptva,
data_inceput_tvainc, data_sfarsit_tvainc, data_inactivare, data_reactivare,
data_inceput_splittva, data_anulare_splittva,
case when ?pdDataCache between data_inceput_scptva and nvl(data_sfarsit_scptva, to_date('29991231','yyyymmdd')) then 1 else 0 end as v_scptva,
case when ?pdDataCache between data_inceput_tvainc and nvl(data_sfarsit_tvainc - 1, to_date('29991231','yyyymmdd')) then 1 else 0 end as v_tvainc,
case when ?pdDataCache between data_inceput_splittva and nvl(data_anulare_splittva, to_date('29991231','yyyymmdd')) then 1 else 0 end as v_splittva,
case when data_inactivare is not null and ?pdDataCache >= data_inactivare and (data_reactivare is null or ?pdDataCache < data_reactivare) then 1 else 0 end as v_inactiv
from (select i.*, row_number() over (partition by cod_fiscal_n order by id desc) as rn
from istoric_coduri_fiscale i
where <<tcCondCod>>
and dataorav_anaf is not null
and sysdate - dataorav_anaf <= ?pnZileCache)
where rn = 1
and (data_inceput_scptva is null or ?pdDataCache >= data_inceput_scptva)
and (data_inceput_tvainc is null or ?pdDataCache >= data_inceput_tvainc)
and (data_inactivare is null or ?pdDataCache >= data_inactivare)
ENDTEXT
RETURN lcSql
ENDFUNC
*** A: transe de 1000 legate cu OR in ACEEASI interogare
FUNCTION BenchRunVarA
LPARAMETERS tcLista
LOCAL laTranse[1], lnTranse, lnI, lcCond, lcSql, lnRand
lnTranse = BenchTransaza(tcLista, 1000, @laTranse)
lcCond = ''
FOR lnI = 1 TO lnTranse
lcCond = lcCond + IIF(EMPTY(lcCond), '', ' or ') + 'cod_fiscal_n in (' + laTranse[lnI] + ')'
ENDFOR
IF lnTranse > 1
lcCond = '(' + lcCond + ')'
ENDIF
lcSql = BenchSqlBaza(lcCond)
IF USED('crsBenchA')
USE IN crsBenchA
ENDIF
lnRand = 0
IF goExecutor.oExecuta(lcSql, 'crsBenchA')
lnRand = RECCOUNT('crsBenchA')
USE IN crsBenchA
ENDIF
RETURN lnRand
ENDFUNC
*** B: o interogare per transa de 1000, acumulate in acelasi cursor rezultat
FUNCTION BenchRunVarB
LPARAMETERS tcLista
LOCAL laTranse[1], lnTranse, lnI, lcCond, lcSql, lnRand
lnTranse = BenchTransaza(tcLista, 1000, @laTranse)
IF USED('crsBenchBAcc')
USE IN crsBenchBAcc
ENDIF
lnRand = 0
FOR lnI = 1 TO lnTranse
lcCond = 'cod_fiscal_n in (' + laTranse[lnI] + ')'
lcSql = BenchSqlBaza(lcCond)
IF USED('crsBenchBTmp')
USE IN crsBenchBTmp
ENDIF
IF goExecutor.oExecuta(lcSql, 'crsBenchBTmp')
IF RECCOUNT('crsBenchBTmp') > 0
IF !USED('crsBenchBAcc')
SELECT * FROM crsBenchBTmp WHERE .F. INTO CURSOR crsBenchBAcc READWRITE
ENDIF
SELECT crsBenchBTmp
SCAN
SCATTER MEMO NAME loRandB
INSERT INTO crsBenchBAcc FROM NAME loRandB
SELECT crsBenchBTmp
ENDSCAN
ENDIF
USE IN crsBenchBTmp
ENDIF
ENDFOR
IF USED('crsBenchBAcc')
lnRand = RECCOUNT('crsBenchBAcc')
USE IN crsBenchBAcc
ENDIF
RETURN lnRand
ENDFUNC
*** C: GTT populata cu INSERT ALL (transe de 300), interogare cu IN (select ... from GTT)
FUNCTION BenchRunVarC
LPARAMETERS tcLista, taTimpInsert, tnRep
LOCAL lnT0, lnRand
=goExecutor.oExecuta('DELETE FROM bench_lot_cf')
lnT0 = SECONDS()
DO BenchPopuleazaGTT WITH tcLista
taTimpInsert[tnRep] = SECONDS() - lnT0
LOCAL lcCond, lcSql
lcCond = 'cod_fiscal_n in (select cod_fiscal_n from bench_lot_cf)'
lcSql = BenchSqlBaza(lcCond)
IF USED('crsBenchC')
USE IN crsBenchC
ENDIF
lnRand = 0
IF goExecutor.oExecuta(lcSql, 'crsBenchC')
lnRand = RECCOUNT('crsBenchC')
USE IN crsBenchC
ENDIF
RETURN lnRand
ENDFUNC
*** populeaza bench_lot_cf cu codurile din tcLista, cate 300 pe instructiune (insert all ... select 1 from dual)
PROCEDURE BenchPopuleazaGTT
LPARAMETERS tcLista
LOCAL laTranse[1], lnTranse, lnI, lnJ, lnDe, lnLa, lnTotal, lcIns
lnTotal = GETWORDCOUNT(tcLista, ',')
lnTranse = CEILING(lnTotal / 300)
FOR lnI = 1 TO lnTranse
lnDe = (lnI - 1) * 300 + 1
lnLa = MIN(lnI * 300, lnTotal)
lcIns = 'insert all'
FOR lnJ = lnDe TO lnLa
lcIns = lcIns + ' into bench_lot_cf (cod_fiscal_n) values (' + GETWORDNUM(tcLista, lnJ, ',') + ')'
ENDFOR
lcIns = lcIns + ' select 1 from dual'
=goExecutor.oExecuta(lcIns)
ENDFOR
ENDPROC
DEFINE CLASS oexec_fara_dialog AS oexecutor
FUNCTION oExecuta
LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect
LOCAL lcSql, lcCursor, lnHandle, lnRez
lcSql = IIF(EMPTY(tcSql), This.cSql, tcSql)
lcCursor = IIF(EMPTY(tcCursor), This.cCursor, tcCursor)
lnHandle = IIF(EMPTY(tnHandle), This.nHandle, tnHandle)
lnRez = This.oExecute(lcSql, lcCursor, tlProgress, tcTitluProgress, lnHandle)
IF lnRez < 1
gnErorriSQL = gnErorriSQL + 1
gcUltimaEroareSQL = TRANSFORM(This.cEroare)
ENDIF
RETURN (lnRez >= 1)
ENDFUNC
ENDDEFINE

View File

@@ -0,0 +1,239 @@
* test_de_ce_rand_nou.prg - izoleaza conditia din pack_istoric_cf.SAVE_ISTORIC_COD_FISCAL care
* declanseaza INSERT-ul pentru codul 1000012, desi verificarea a fost servita din cache si
* valorile par identice cu ultimul rand din istoric.
*
* Verifica pe rand: (a) cum arata exact sirul trimis din VFP (TRANSFORM(cui)), (b) daca
* interogarea de cautare a ultimului rand (where cod_fiscal = <sir>) chiar gaseste ceva,
* (c) octetii reali ai lui COD_FISCAL in randurile existente.
*
* Rulare: vfp9.exe -A -T "...\test_de_ce_rand_nou.prg" [cod]
LPARAMETERS tcCod
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcTestLog, gnErorriSQL, gcUltimaEroareSQL
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_de_ce_rand_nou_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
gnErorriSQL = 0
gcUltimaEroareSQL = ''
ON ERROR DO ErrDeCe WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO WrLog5 WITH 'EROARE: conectare Oracle esuata - GATA'
QUIT
ENDIF
LOCAL loExecNou
loExecNou = CREATEOBJECT('oexec_fara_dialog3')
loExecNou.nHandle = gnHandle
goExecutor = loExecNou
DO WrLog5 WITH 'mediu OK, schema=' + gcS
LOCAL lcCod, lcSql
lcCod = IIF(TYPE('tcCod') = 'C' AND !EMPTY(tcCod), ALLTRIM(tcCod), '1000012')
DO WrLog5 WITH 'cod analizat: ' + lcCod
* (a) sirul construit exact ca in SalveazaIstoricDinCursor: Transform(cui) pe un camp N(13)
IF USED('crsSim')
USE IN crsSim
ENDIF
CREATE CURSOR crsSim (cui N(13))
INSERT INTO crsSim (cui) VALUES (VAL(lcCod))
SELECT crsSim
GO TOP
LOCAL lcTrimis
lcTrimis = TRANSFORM(crsSim.cui)
DO WrLog5 WITH '(a) TRANSFORM(cui) = [' + lcTrimis + '] len=' + TRANSFORM(LEN(lcTrimis))
* (b) octetii lui COD_FISCAL in randurile existente
lcSql = 'SELECT ID, DUMP(COD_FISCAL) AS D, LENGTH(COD_FISCAL) AS L, PLATITORTVAMFIN AS PM,'
lcSql = lcSql + ' PLATITORTVAVIES AS PV, INACTIV AS IN_, TVAINCASARE AS TI, SPLITTVA AS SP'
lcSql = lcSql + ' FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N = ' + lcCod + ' ORDER BY ID'
IF goExecutor.oExecuta(lcSql, 'crsD')
DO WrLog5 WITH '(b) randuri existente:'
SELECT crsD
SCAN
DO WrLog5 WITH ' id=' + TRANSFORM(crsD.ID) + ' len=' + TRANSFORM(crsD.L) + ;
' pm=' + TRANSFORM(NVL(crsD.PM, -1)) + ' pv=' + TRANSFORM(NVL(crsD.PV, -1)) + ;
' inactiv=' + TRANSFORM(NVL(crsD.IN_, -1)) + ' tvainc=' + TRANSFORM(NVL(crsD.TI, -1)) + ;
' split=' + TRANSFORM(NVL(crsD.SP, -1))
DO WrLog5 WITH ' ' + ALLTRIM(NVL(crsD.D, ''))
SELECT crsD
ENDSCAN
USE IN (SELECT('crsD'))
ENDIF
* (b2) au datele de interval componenta de ORA? (VFP trimite inapoi doar data, fara ora)
lcSql = 'SELECT ID, TO_CHAR(DATA_INCEPUT_TVAINC,' + CHR(39) + 'DD.MM.YYYY HH24:MI:SS' + CHR(39) + ') AS T1,'
lcSql = lcSql + ' TO_CHAR(DATA_INCEPUT_SCPTVA,' + CHR(39) + 'DD.MM.YYYY HH24:MI:SS' + CHR(39) + ') AS T2,'
lcSql = lcSql + ' TO_CHAR(DATA_INACTIVARE,' + CHR(39) + 'DD.MM.YYYY HH24:MI:SS' + CHR(39) + ') AS T3'
lcSql = lcSql + ' FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N = ' + lcCod + ' ORDER BY ID'
IF goExecutor.oExecuta(lcSql, 'crsT')
DO WrLog5 WITH '(b2) ora din datele de interval:'
SELECT crsT
SCAN
DO WrLog5 WITH ' id=' + TRANSFORM(crsT.ID) + ' iInc=[' + ALLTRIM(NVL(crsT.T1, '')) + ']' + ;
' iScp=[' + ALLTRIM(NVL(crsT.T2, '')) + '] inact=[' + ALLTRIM(NVL(crsT.T3, '')) + ']'
SELECT crsT
ENDSCAN
USE IN (SELECT('crsT'))
ENDIF
* (c) exact interogarea de cautare din pachet, cu sirul trimis din VFP
PRIVATE pcCautat
pcCautat = lcTrimis
lcSql = 'SELECT ID FROM (SELECT ID FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL = ?pcCautat'
lcSql = lcSql + ' ORDER BY DATAORAV DESC, ID DESC) WHERE ROWNUM = 1'
IF goExecutor.oExecuta(lcSql, 'crsL')
DO WrLog5 WITH '(c) cautarea din pachet (cod_fiscal = sirul trimis): ' + ;
IIF(RECCOUNT('crsL') > 0, 'GASIT id=' + TRANSFORM(crsL.ID), 'NU GASESTE NIMIC -> pachetul face INSERT')
USE IN (SELECT('crsL'))
ENDIF
* (d) acelasi lucru, dar cautand pe cod_fiscal_n
lcSql = 'SELECT ID FROM (SELECT ID FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N = ' + lcCod
lcSql = lcSql + ' ORDER BY DATAORAV DESC, ID DESC) WHERE ROWNUM = 1'
IF goExecutor.oExecuta(lcSql, 'crsL2')
DO WrLog5 WITH '(d) aceeasi cautare pe COD_FISCAL_N: ' + ;
IIF(RECCOUNT('crsL2') > 0, 'GASIT id=' + TRANSFORM(crsL2.ID), 'nu gaseste')
USE IN (SELECT('crsL2'))
ENDIF
* (e) doua apeluri identice de salvare, la rand: al doilea NU ar trebui sa mai adauge rand
PUBLIC gnWm5
gnWm5 = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsW5')
gnWm5 = crsW5.IDMAX
USE IN (SELECT('crsW5'))
ENDIF
DO WrLog5 WITH '(e) watermark inainte de cele doua salvari: ' + TRANSFORM(gnWm5)
DO SalveazaOData WITH lcCod, 1
DO SalveazaOData WITH lcCod, 2
lcSql = 'SELECT ID, COD_FISCAL_N FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnWm5) + ' ORDER BY ID'
IF goExecutor.oExecuta(lcSql, 'crsN5')
DO WrLog5 WITH ' randuri adaugate de cele doua salvari: ' + TRANSFORM(RECCOUNT('crsN5'))
SELECT crsN5
SCAN
DO WrLog5 WITH ' id=' + TRANSFORM(crsN5.ID) + ' cod=' + TRANSFORM(crsN5.COD_FISCAL_N)
SELECT crsN5
ENDSCAN
USE IN (SELECT('crsN5'))
ENDIF
IF gnWm5 > 0
=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnWm5))
=goExecutor.oExecuta('COMMIT')
DO WrLog5 WITH 'curatenie: sterse randurile cu ID > ' + TRANSFORM(gnWm5)
ENDIF
DO WrLog5 WITH 'GATA ' + TTOC(DATETIME())
QUIT
*** apeleaza pachetul cu EXACT parametrii pe care ii trimite SalveazaIstoricDinCursor
*** pentru un rand venit din cache (valorile citite din ultimul rand de istoric)
PROCEDURE SalveazaOData
LPARAMETERS tcCod, tnPas
LOCAL lcSql, lcSel
PRIVATE pcCodFiscal, pcFirma, pcAdresa, pcJudet, pcRegCom, pcCodPostal, pcTelefon, pcFax, pcDataTvamfin, ;
pnPlatitorTvaMfin, pcStare, pnPlatitorTvaVies, pnInterogareVies, pnIdUtil, ;
pnInactiv, pnTvaIncasare, pnSplitTva, ;
pdInceputScpTva, pdSfarsitScpTva, pdAnulImpScpTva, pdInceputTvaInc, pdSfarsitTvaInc, ;
pdInactivare, pdReactivare, pdInceputSplitTva, pdAnulareSplitTva, pnDinCache
lcSel = SELECT()
lcSql = 'SELECT FIRMA, ADRESA, JUDET, REGCOM, INACTIV, TVAINCASARE, SPLITTVA,'
lcSql = lcSql + ' DATA_INCEPUT_SCPTVA, DATA_SFARSIT_SCPTVA, DATA_ANUL_IMP_SCPTVA,'
lcSql = lcSql + ' DATA_INCEPUT_TVAINC, DATA_SFARSIT_TVAINC, DATA_INACTIVARE, DATA_REACTIVARE,'
lcSql = lcSql + ' DATA_INCEPUT_SPLITTVA, DATA_ANULARE_SPLITTVA'
lcSql = lcSql + ' FROM (SELECT * FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N = ' + tcCod
lcSql = lcSql + ' ORDER BY ID DESC) WHERE ROWNUM = 1'
IF !goExecutor.oExecuta(lcSql, 'crsSrc')
DO WrLog5 WITH ' pas ' + TRANSFORM(tnPas) + ': nu pot citi randul sursa'
RETURN
ENDIF
pcCodFiscal = ALLTRIM(tcCod)
pcFirma = ALLTRIM(NVL(crsSrc.FIRMA, ''))
pcAdresa = ALLTRIM(NVL(crsSrc.ADRESA, ''))
pcJudet = ALLTRIM(NVL(crsSrc.JUDET, ''))
pcRegCom = ALLTRIM(NVL(crsSrc.REGCOM, ''))
pcCodPostal = ''
pcTelefon = ''
pcFax = ''
pcDataTvamfin = ''
pnPlatitorTvaMfin = 0
pcStare = ''
pnPlatitorTvaVies = 0
pnInterogareVies = 0
pnIdUtil = gnIdUtil
pnInactiv = NVL(crsSrc.INACTIV, 0)
pnTvaIncasare = NVL(crsSrc.TVAINCASARE, 0)
pnSplitTva = NVL(crsSrc.SPLITTVA, 0)
pdInceputScpTva = NVL(crsSrc.DATA_INCEPUT_SCPTVA, {})
pdSfarsitScpTva = NVL(crsSrc.DATA_SFARSIT_SCPTVA, {})
pdAnulImpScpTva = NVL(crsSrc.DATA_ANUL_IMP_SCPTVA, {})
pdInceputTvaInc = NVL(crsSrc.DATA_INCEPUT_TVAINC, {})
pdSfarsitTvaInc = NVL(crsSrc.DATA_SFARSIT_TVAINC, {})
pdInactivare = NVL(crsSrc.DATA_INACTIVARE, {})
pdReactivare = NVL(crsSrc.DATA_REACTIVARE, {})
pdInceputSplitTva = NVL(crsSrc.DATA_INCEPUT_SPLITTVA, {})
pdAnulareSplitTva = NVL(crsSrc.DATA_ANULARE_SPLITTVA, {})
pnDinCache = 1
USE IN (SELECT('crsSrc'))
lcSql = "begin pack_parteneri.save_istoric_cod_fiscal(?pcCodFiscal,?pcFirma,?pcAdresa,?pcJudet,?pcRegCom,?pcCodPostal,?pcTelefon,?pcFax,?pcDataTvamfin,?pnPlatitorTvaMfin,?pcStare," + ;
"?pnPlatitorTvaVies,?pnInterogareVies,?pnIdUtil,?pnInactiv,?pnTvaIncasare,?pnSplitTva,?pdInceputScpTva,?pdSfarsitScpTva," + ;
"?pdAnulImpScpTva,?pdInceputTvaInc,?pdSfarsitTvaInc,?pdInactivare,?pdReactivare,?pdInceputSplitTva,?pdAnulareSplitTva,?pnDinCache); end;"
IF goExecutor.oExecuta(lcSql)
=goExecutor.oExecuta('COMMIT')
DO WrLog5 WITH ' pas ' + TRANSFORM(tnPas) + ': salvare OK (pnDinCache=1)'
ELSE
DO WrLog5 WITH ' pas ' + TRANSFORM(tnPas) + ': salvare ESUATA'
ENDIF
SELECT (lcSel)
ENDPROC
PROCEDURE WrLog5
LPARAMETERS tcText
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC
PROCEDURE ErrDeCe
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
DO WrLog5 WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
RETURN
ENDPROC
DEFINE CLASS oexec_fara_dialog3 AS oexecutor
FUNCTION oExecuta
LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect
LOCAL lcSql, lcCursor, lnHandle, lnRez
lcSql = IIF(EMPTY(tcSql), This.cSql, tcSql)
lcCursor = IIF(EMPTY(tcCursor), This.cCursor, tcCursor)
lnHandle = IIF(EMPTY(tnHandle), This.nHandle, tnHandle)
lnRez = This.oExecute(lcSql, lcCursor, tlProgress, tcTitluProgress, lnHandle)
IF lnRez < 1
gnErorriSQL = gnErorriSQL + 1
gcUltimaEroareSQL = TRANSFORM(This.cEroare)
DO WrLog5 WITH ' SQL ESUAT: ' + LEFT(TRANSFORM(This.cEroare), 120)
ENDIF
RETURN (lnRez >= 1)
ENDFUNC
ENDDEFINE

View File

@@ -0,0 +1,267 @@
* test_rand_nou_din_cache.prg - de ce apare un rand NOU in ISTORIC_CODURI_FISCALE cand
* verificarea in masa a fost servita integral din cache.
*
* Ruleaza VerificaListaCIF pe coduri proaspete (ANAF blocat), apoi identifica randurile
* adaugate peste watermark si le compara, camp cu camp, cu randul care exista deja pentru
* acelasi cod fiscal - ca sa se vada CE anume a considerat pachetul ca fiind "diferit"
* (pack_istoric_cf.SAVE_ISTORIC_COD_FISCAL compara ultima inregistrare cu parametrii primiti).
*
* Rulare: vfp9.exe -A -T "...\test_rand_nou_din_cache.prg" [N]
LPARAMETERS tcN
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcTestLog, gnApeluriANAF, gnErorriSQL, gcUltimaEroareSQL
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_rand_nou_din_cache_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
gnApeluriANAF = 0
gnErorriSQL = 0
gcUltimaEroareSQL = ''
ON ERROR DO ErrRand WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO WrLog4 WITH 'EROARE: conectare Oracle esuata - GATA'
QUIT
ENDIF
DO WrLog4 WITH 'mediu OK, schema=' + gcS
LOCAL loExecNou
loExecNou = CREATEOBJECT('oexec_fara_dialog2')
loExecNou.nHandle = gnHandle
goExecutor = loExecNou
LOCAL lnN, lcSql, lnZile, loVer
lnN = IIF(TYPE('tcN') = 'C' AND !EMPTY(tcN), INT(VAL(tcN)), 200)
loVer = CREATEOBJECT('VerificareANAFRand')
lnZile = loVer.ZileCache()
PUBLIC gnWm
gnWm = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsW')
gnWm = crsW.IDMAX
USE IN (SELECT('crsW'))
ENDIF
DO WrLog4 WITH 'watermark = ' + TRANSFORM(gnWm)
IF gnWm <= 0
DO WrLog4 WITH 'EROARE: watermark invalid - GATA'
QUIT
ENDIF
lcSql = 'SELECT COD_FISCAL_N FROM (SELECT DISTINCT COD_FISCAL_N FROM ISTORIC_CODURI_FISCALE'
lcSql = lcSql + ' WHERE COD_FISCAL_N IS NOT NULL AND DATAORAV_ANAF IS NOT NULL'
lcSql = lcSql + ' AND SYSDATE - DATAORAV_ANAF <= ' + TRANSFORM(lnZile)
lcSql = lcSql + ' ORDER BY COD_FISCAL_N) WHERE ROWNUM <= ' + TRANSFORM(lnN)
=goExecutor.oExecuta(lcSql, 'crsCodR')
IF USED('cLotR')
USE IN cLotR
ENDIF
CREATE CURSOR cLotR (cod_fiscal C(30) NULL, data D NULL)
SELECT crsCodR
SCAN
INSERT INTO cLotR (cod_fiscal, data) VALUES (ALLTRIM(TRANSFORM(crsCodR.COD_FISCAL_N)), DATE())
SELECT crsCodR
ENDSCAN
USE IN (SELECT('crsCodR'))
DO WrLog4 WITH 'lot = ' + TRANSFORM(RECCOUNT('cLotR')) + ' coduri proaspete'
=loVer.VerificaListaCIF('cLotR', DATE(), 'crsRezR', 'MASA')
DO WrLog4 WITH 'randuri intoarse: ' + TRANSFORM(IIF(USED('crsRezR'), RECCOUNT('crsRezR'), 0))
DO WrLog4 WITH 'apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)
* --- ce s-a adaugat ---
lcSql = 'SELECT ID, COD_FISCAL, COD_FISCAL_N, FIRMA, ADRESA, JUDET, REGCOM, CODPOSTAL,'
lcSql = lcSql + ' TELEFON, FAX, DATATVAMFIN, PLATITORTVAMFIN, STARE, PLATITORTVAVIES,'
lcSql = lcSql + ' INACTIV, TVAINCASARE, SPLITTVA, SCHEMA_SURSA'
lcSql = lcSql + ' FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnWm) + ' ORDER BY ID'
IF !goExecutor.oExecuta(lcSql, 'crsNoi')
DO WrLog4 WITH 'EROARE la citirea randurilor noi'
ELSE
DO WrLog4 WITH ''
DO WrLog4 WITH '=== randuri NOI adaugate: ' + TRANSFORM(RECCOUNT('crsNoi')) + ' ==='
SELECT crsNoi
SCAN
DO WrLog4 WITH ''
DO WrLog4 WITH 'ID nou ' + TRANSFORM(crsNoi.ID) + ' cod_fiscal=[' + TRANSFORM(crsNoi.COD_FISCAL) + ']' + ;
' cod_fiscal_n=' + TRANSFORM(crsNoi.COD_FISCAL_N)
DO ComparaCuAnterior WITH crsNoi.COD_FISCAL_N, crsNoi.ID
DO AratatCeSATrimis WITH crsNoi.COD_FISCAL_N
SELECT crsNoi
ENDSCAN
USE IN (SELECT('crsNoi'))
ENDIF
DO WrLog4 WITH ''
=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnWm))
=goExecutor.oExecuta('COMMIT')
DO WrLog4 WITH 'curatenie: sterse randurile cu ID > ' + TRANSFORM(gnWm)
DO WrLog4 WITH 'GATA ' + TTOC(DATETIME())
QUIT
*** ce a trimis SalveazaIstoricDinCursor pentru codul asta (randul din cursorul de rezultat)
PROCEDURE AratatCeSATrimis
LPARAMETERS tnCodN
LOCAL lcSel
lcSel = SELECT()
IF !USED('crsRezR')
RETURN
ENDIF
SELECT crsRezR
LOCATE FOR cui = tnCodN
IF !FOUND()
DO WrLog4 WITH ' (codul nu e in cursorul de rezultat)'
SELECT (lcSel)
RETURN
ENDIF
DO WrLog4 WITH ' trimis de VFP: sursa=[' + ALLTRIM(NVL(crsRezR.sursa, '')) + ']' + ;
' scptva=' + TRANSFORM(crsRezR.scpTVA) + ' tvainc=' + TRANSFORM(crsRezR.tvaincasare) + ;
' split=' + TRANSFORM(crsRezR.splittva) + ' inactiv=' + TRANSFORM(crsRezR.inactiv)
DO WrLog4 WITH ' iScp=' + DTOC(crsRezR.data_inceput_ScpTVA) + ' sScp=' + DTOC(crsRezR.data_sfarsit_ScpTVA) + ;
' aScp=' + DTOC(crsRezR.data_anul_imp_ScpTVA) + ' iInc=' + DTOC(crsRezR.dataInceputTvaInc) + ;
' sInc=' + DTOC(crsRezR.dataSfarsitTvaInc)
DO WrLog4 WITH ' inactivare=' + DTOC(crsRezR.dataInactivare) + ' reactivare=' + DTOC(crsRezR.dataReactivare) + ;
' iSplit=' + DTOC(crsRezR.dataInceputSplitTVA) + ' aSplit=' + DTOC(crsRezR.dataAnulareSplitTVA)
DO WrLog4 WITH ' lungimi trimise: firma=' + TRANSFORM(LEN(NVL(crsRezR.firma, ''))) + ;
' adresa=' + TRANSFORM(LEN(NVL(crsRezR.adresa, ''))) + ;
' judet=' + TRANSFORM(LEN(NVL(crsRezR.judet, ''))) + ;
' regcom=' + TRANSFORM(LEN(NVL(crsRezR.nrRegCom, '')))
DO WrLog4 WITH ' firma=[' + NVL(crsRezR.firma, '') + ']'
DO WrLog4 WITH ' adresa=[' + NVL(crsRezR.adresa, '') + ']'
DO AratatLungimiOracle WITH tnCodN
SELECT (lcSel)
ENDPROC
*** lungimile reale, in Oracle, ale campurilor text din randurile codului
PROCEDURE AratatLungimiOracle
LPARAMETERS tnCodN
LOCAL lcSql
lcSql = 'SELECT ID, LENGTH(FIRMA) AS LF, LENGTH(ADRESA) AS LA, LENGTH(JUDET) AS LJ,'
lcSql = lcSql + ' LENGTH(REGCOM) AS LR, LENGTH(CODPOSTAL) AS LC, LENGTH(TELEFON) AS LT,'
lcSql = lcSql + ' LENGTH(FAX) AS LX, LENGTH(DATATVAMFIN) AS LD, LENGTH(STARE) AS LS'
lcSql = lcSql + ' FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N = ' + TRANSFORM(tnCodN) + ' ORDER BY ID'
IF goExecutor.oExecuta(lcSql, 'crsLen')
DO WrLog4 WITH ' lungimi in Oracle (NULL = gol):'
SELECT crsLen
SCAN
DO WrLog4 WITH ' id=' + TRANSFORM(crsLen.ID) + ' firma=' + TRANSFORM(NVL(crsLen.LF, -1)) + ;
' adresa=' + TRANSFORM(NVL(crsLen.LA, -1)) + ' judet=' + TRANSFORM(NVL(crsLen.LJ, -1)) + ;
' regcom=' + TRANSFORM(NVL(crsLen.LR, -1)) + ' cp=' + TRANSFORM(NVL(crsLen.LC, -1)) + ;
' tel=' + TRANSFORM(NVL(crsLen.LT, -1)) + ' fax=' + TRANSFORM(NVL(crsLen.LX, -1)) + ;
' dtvamfin=' + TRANSFORM(NVL(crsLen.LD, -1)) + ' stare=' + TRANSFORM(NVL(crsLen.LS, -1))
SELECT crsLen
ENDSCAN
USE IN (SELECT('crsLen'))
ENDIF
ENDPROC
PROCEDURE ComparaCuAnterior
LPARAMETERS tnCodN, tnIdNou
LOCAL lcSql, lcLinie
lcSql = 'SELECT ID, COD_FISCAL, FIRMA, ADRESA, JUDET, REGCOM, CODPOSTAL, TELEFON, FAX,'
lcSql = lcSql + ' DATA_INCEPUT_SCPTVA, DATA_SFARSIT_SCPTVA, DATA_ANUL_IMP_SCPTVA,'
lcSql = lcSql + ' DATA_INCEPUT_TVAINC, DATA_SFARSIT_TVAINC, DATA_INACTIVARE, DATA_REACTIVARE,'
lcSql = lcSql + ' DATA_INCEPUT_SPLITTVA, DATA_ANULARE_SPLITTVA,'
lcSql = lcSql + ' DATATVAMFIN, PLATITORTVAMFIN, STARE, PLATITORTVAVIES, INACTIV, TVAINCASARE, SPLITTVA,'
lcSql = lcSql + ' TO_CHAR(DATAORAV,' + CHR(39) + 'DD.MM.YYYY HH24:MI' + CHR(39) + ') AS DORAV, SCHEMA_SURSA'
lcSql = lcSql + ' FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N = ' + TRANSFORM(tnCodN)
lcSql = lcSql + ' ORDER BY ID'
IF !goExecutor.oExecuta(lcSql, 'crsIst')
DO WrLog4 WITH ' eroare la citirea istoricului codului'
RETURN
ENDIF
DO WrLog4 WITH ' istoricul codului (' + TRANSFORM(RECCOUNT('crsIst')) + ' randuri):'
SELECT crsIst
SCAN
lcLinie = ' ' + IIF(crsIst.ID = tnIdNou, '>>', ' ') + ' id=' + TRANSFORM(crsIst.ID) + ;
' cf=[' + ALLTRIM(NVL(crsIst.COD_FISCAL, '')) + ']' + ;
' firma=[' + ALLTRIM(LEFT(NVL(crsIst.FIRMA, ''), 30)) + ']' + ;
' adresa=[' + ALLTRIM(LEFT(NVL(crsIst.ADRESA, ''), 25)) + ']' + ;
' judet=[' + ALLTRIM(NVL(crsIst.JUDET, '')) + ']' + ;
' regcom=[' + ALLTRIM(NVL(crsIst.REGCOM, '')) + ']'
DO WrLog4 WITH lcLinie
lcLinie = ' cp=[' + ALLTRIM(NVL(crsIst.CODPOSTAL, '')) + ']' + ;
' tel=[' + ALLTRIM(NVL(crsIst.TELEFON, '')) + ']' + ;
' fax=[' + ALLTRIM(NVL(crsIst.FAX, '')) + ']' + ;
' dtvamfin=[' + ALLTRIM(NVL(crsIst.DATATVAMFIN, '')) + ']' + ;
' ptvamfin=' + TRANSFORM(NVL(crsIst.PLATITORTVAMFIN, -1)) + ;
' stare=[' + ALLTRIM(NVL(crsIst.STARE, '')) + ']' + ;
' vies=' + TRANSFORM(NVL(crsIst.PLATITORTVAVIES, -1)) + ;
' inactiv=' + TRANSFORM(NVL(crsIst.INACTIV, -1)) + ;
' tvainc=' + TRANSFORM(NVL(crsIst.TVAINCASARE, -1)) + ;
' split=' + TRANSFORM(NVL(crsIst.SPLITTVA, -1)) + ;
' dataorav=' + ALLTRIM(NVL(crsIst.DORAV, '')) + ;
' schema=' + ALLTRIM(NVL(crsIst.SCHEMA_SURSA, ''))
DO WrLog4 WITH lcLinie
lcLinie = ' iScp=' + DTOC(NVL(crsIst.DATA_INCEPUT_SCPTVA, {})) + ;
' sScp=' + DTOC(NVL(crsIst.DATA_SFARSIT_SCPTVA, {})) + ;
' aScp=' + DTOC(NVL(crsIst.DATA_ANUL_IMP_SCPTVA, {})) + ;
' iInc=' + DTOC(NVL(crsIst.DATA_INCEPUT_TVAINC, {})) + ;
' sInc=' + DTOC(NVL(crsIst.DATA_SFARSIT_TVAINC, {})) + ;
' inact=' + DTOC(NVL(crsIst.DATA_INACTIVARE, {})) + ;
' react=' + DTOC(NVL(crsIst.DATA_REACTIVARE, {})) + ;
' iSpl=' + DTOC(NVL(crsIst.DATA_INCEPUT_SPLITTVA, {})) + ;
' aSpl=' + DTOC(NVL(crsIst.DATA_ANULARE_SPLITTVA, {}))
DO WrLog4 WITH lcLinie
SELECT crsIst
ENDSCAN
USE IN (SELECT('crsIst'))
ENDPROC
PROCEDURE WrLog4
LPARAMETERS tcText
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC
PROCEDURE ErrRand
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
DO WrLog4 WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
RETURN
ENDPROC
DEFINE CLASS oexec_fara_dialog2 AS oexecutor
FUNCTION oExecuta
LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect
LOCAL lcSql, lcCursor, lnHandle, lnRez
lcSql = IIF(EMPTY(tcSql), This.cSql, tcSql)
lcCursor = IIF(EMPTY(tcCursor), This.cCursor, tcCursor)
lnHandle = IIF(EMPTY(tnHandle), This.nHandle, tnHandle)
lnRez = This.oExecute(lcSql, lcCursor, tlProgress, tcTitluProgress, lnHandle)
IF lnRez < 1
gnErorriSQL = gnErorriSQL + 1
gcUltimaEroareSQL = TRANSFORM(This.cEroare)
ENDIF
RETURN (lnRez >= 1)
ENDFUNC
ENDDEFINE
DEFINE CLASS VerificareANAFRand AS VerificareANAF
PROCEDURE OrdineCache
LPARAMETERS tcTraseu
RETURN 'CACHE,ANAF'
ENDPROC
PROCEDURE ANAF_SincronWebService_PlatitorTva
LPARAMETERS tcCursorListaCIF, tdData, tcAlias
gnApeluriANAF = gnApeluriANAF + 1
RETURN IIF(EMPTY(tcAlias), 'crsANAF', tcAlias)
ENDPROC
ENDDEFINE

View File

@@ -0,0 +1,247 @@
* test_timp_completare_tabel.prg - masoara PARTEA DE APELANT a verificarii in masa: bucla care
* muta rezultatele din crsANAF in tabelul afisat (crsVerificareParteneri), din
* frm_verificare_parteneri.do_verifica (COMUN\clase\overificari.vc2:2741-2756).
*
* Bucla reala face, pentru fiecare rezultat, un LOCATE cu expresie care apeleaza un UDF
* (loVerificare.GetCodTara) pe fiecare rand parcurs => N x N apeluri de functie.
* Se compara cu aceeasi completare pe cursor indexat (SEEK).
*
* Fara Oracle in bucla masurata: cursoarele sunt construite local, deci timpul e pur VFP.
*
* Rulare: vfp9.exe -A -T "...\test_timp_completare_tabel.prg"
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcTestLog
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_timp_completare_tabel_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
ON ERROR DO ErrCompl WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
DO WrLog3 WITH 'mediu OK'
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
* goLog dezactivat aici: masor doar bucla de VFP, nu scrierea in log
goLog.cLogFile = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_log_inexistent.txt'
LOCAL lnI
FOR lnI = 1 TO 4
DO MasoaraLot WITH IIF(lnI = 1, 200, IIF(lnI = 2, 500, IIF(lnI = 3, 1000, 2000)))
ENDFOR
DO TestSemanticaData
DO WrLog3 WITH 'GATA ' + TTOC(DATETIME())
QUIT
* verifica varianta LOCATE (A) vs SEEK+SKIP (C) pe acelasi cod fiscal cu mai multe randuri
* cu date diferite - trebuie sa aleaga acelasi rand (primul, in ordinea fizica, care satisface conditia)
PROCEDURE TestSemanticaData
LOCAL loVerificare, ldData
loVerificare = CREATEOBJECT('verificarecod', .F., .F.)
ldData = DATE()
DO WrLog3 WITH ''
DO WrLog3 WITH '=== test semantica: acelasi cod, date diferite ==='
* caz 1: doua randuri cu data GRESITA inaintea celui cu data corecta -> trebuie 2 SKIP pana la potrivire
DO ConstrTabelDuplicat WITH ldData - 60, ldData - 30, ldData
DO VerificaSemantica WITH loVerificare, ldData, 'caz 1 (2 SKIP pana la data corecta)', 'PARTENER 3'
* caz 2: randul cu data GOALA vine inaintea celui cu data corecta -> primul (cu data goala) trebuie ales
DO ConstrTabelDuplicat WITH ldData - 30, {}, ldData
DO VerificaSemantica WITH loVerificare, ldData, 'caz 2 (data goala inaintea celei corecte)', 'PARTENER 2'
ENDPROC
PROCEDURE ConstrTabelDuplicat
LPARAMETERS tdData1, tdData2, tdData3
IF USED('crsTabel')
USE IN crsTabel
ENDIF
CREATE CURSOR crsTabel (ales L, denumire C(100) NULL, cod_fiscal C(30) NULL, Valid L NULL, ;
firma C(100) NULL, cod C(100) NULL, adresa C(250) NULL, judet C(100) NULL, regcom C(30) NULL, ;
datatvamfin C(30) NULL, platitortvamfin L NULL, IsCIF L NULL, duplicat L, atribut_fiscal C(2), ;
stare C(100), atentie C(100), cod_fiscalfro C(30) NULL, tvaincasare L, splittva L, inactiv L, Data D NULL)
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO9999999', 'ALT PARTENER', .T., .T., tdData1)
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO1234567', 'PARTENER 1', .T., .T., tdData1)
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO1234567', 'PARTENER 2', .T., .T., tdData2)
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) VALUES ('RO1234567', 'PARTENER 3', .T., .T., tdData3)
ENDPROC
PROCEDURE VerificaSemantica
LPARAMETERS toVerificare, tdData, tcEticheta, tcAsteptat
LOCAL lcCheieCauta, llGasit, lcRezA, lcRezC
* varianta A: LOCATE cu UDF, exact bucla veche
SELECT crsTabel
LOCATE FOR ALLTRIM(STRTRAN(cod_fiscal, toVerificare.GetCodTara(cod_fiscal), '')) = '1234567' AND (EMPTY(NVL(data, {})) OR data = tdData)
lcRezA = IIF(FOUND(), ALLTRIM(denumire), '<niciunul>')
* varianta C: SEEK pe cod_fiscalfro + SKIP cat timp cheia ramane egala, pana la data care se potriveste
SELECT crsTabel
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(cod_fiscal, toVerificare.GetCodTara(cod_fiscal), ''))
INDEX ON cod_fiscalfro TAG cfro
lcCheieCauta = PADR('1234567', 30)
llGasit = .F.
IF SEEK(lcCheieCauta, 'crsTabel', 'cfro')
llGasit = .T.
DO WHILE !(EMPTY(NVL(data, {})) OR data = tdData)
SKIP
IF EOF() OR cod_fiscalfro <> lcCheieCauta
llGasit = .F.
EXIT
ENDIF
ENDDO
ENDIF
lcRezC = IIF(llGasit, ALLTRIM(denumire), '<niciunul>')
DO WrLog3 WITH ' ' + tcEticheta + ': A=' + lcRezA + ' C=' + lcRezC + ' asteptat=' + tcAsteptat
DO WrLog3 WITH IIF(lcRezA == lcRezC AND lcRezA == tcAsteptat, ' PASS', ' FAIL')
USE IN (SELECT('crsTabel'))
ENDPROC
PROCEDURE MasoaraLot
LPARAMETERS tnN
LOCAL lnT1, lnT2, lnT3, lnK, loVerificare, ldData
loVerificare = CREATEOBJECT('verificarecod', .F., .F.)
ldData = DATE()
DO WrLog3 WITH ''
DO WrLog3 WITH '=== lot ' + TRANSFORM(tnN) + ' parteneri ==='
* rezultatele ANAF/cache (forma crsANAF, doar campurile folosite de bucla)
IF USED('crsRezANAF')
USE IN crsRezANAF
ENDIF
CREATE CURSOR crsRezANAF (cui N(13), denumire V(100), adresa C(244), mesaj V(100), ;
tva L, tvaincasare L, splittva L, inactiv L)
FOR lnK = 1 TO tnN
INSERT INTO crsRezANAF (cui, denumire, adresa, mesaj, tva, tvaincasare, splittva, inactiv) ;
VALUES (10000000 + lnK, 'FIRMA ' + ALLTRIM(STR(lnK)), 'ADRESA ' + ALLTRIM(STR(lnK)), '', .T., .F., .F., .F.)
ENDFOR
* varianta 1: exact bucla din overificari.vc2
DO ConstrTabel WITH tnN
lnT1 = SECONDS()
SELECT crsRezANAF
SCAN
SCATTER NAME loRec
WITH loRec
SELECT crsTabel
LOCATE FOR ALLTRIM(STRTRAN(cod_fiscal, loVerificare.GetCodTara(cod_fiscal), '')) = ALLTRIM(STR(.cui)) AND (EMPTY(NVL(data, {})) OR data = ldData)
IF FOUND()
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
splittva WITH .splittva, inactiv WITH .inactiv
ENDIF
ENDWITH
SELECT crsRezANAF
ENDSCAN
lnT1 = SECONDS() - lnT1
DO WrLog3 WITH 'A LOCATE + UDF (cod real) = ' + TRANSFORM(ROUND(lnT1, 3)) + ' s'
SELECT COUNT(*) AS n FROM crsTabel WHERE !EMPTY(NVL(firma, '')) INTO CURSOR crsCtrl1
DO WrLog3 WITH ' randuri completate: ' + TRANSFORM(crsCtrl1.n)
USE IN (SELECT('crsCtrl1'))
* varianta 2: aceeasi completare pe cursor indexat
DO ConstrTabel WITH tnN
lnT2 = SECONDS()
SELECT crsTabel
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(STRTRAN(UPPER(NVL(cod_fiscal, '')), 'RO', ''), ' ', ''))
INDEX ON cod_fiscalfro TAG cfro
SELECT crsRezANAF
SCAN
SCATTER NAME loRec
WITH loRec
IF SEEK(PADR(ALLTRIM(STR(.cui)), 30), 'crsTabel', 'cfro')
SELECT crsTabel
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
splittva WITH .splittva, inactiv WITH .inactiv
ENDIF
ENDWITH
SELECT crsRezANAF
ENDSCAN
lnT2 = SECONDS() - lnT2
DO WrLog3 WITH 'B SEEK pe cursor indexat = ' + TRANSFORM(ROUND(lnT2, 3)) + ' s'
SELECT COUNT(*) AS n FROM crsTabel WHERE !EMPTY(NVL(firma, '')) INTO CURSOR crsCtrl2
DO WrLog3 WITH ' randuri completate: ' + TRANSFORM(crsCtrl2.n)
USE IN (SELECT('crsCtrl2'))
DO WrLog3 WITH 'raport A/B = ' + TRANSFORM(ROUND(lnT1 / MAX(lnT2, 0.001), 1)) + 'x'
* varianta 3: exact codul propus in overificari.vc2 (SEEK + parcurgere pe cheie egala pentru data)
DO ConstrTabel WITH tnN
lnT3 = SECONDS()
SELECT crsTabel
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(cod_fiscal, loVerificare.GetCodTara(cod_fiscal), ''))
INDEX ON cod_fiscalfro TAG cfro
SELECT crsRezANAF
SCAN
SCATTER NAME loRec
WITH loRec
lcCheieCauta = PADR(ALLTRIM(STR(.cui)), 30)
SELECT crsTabel
llGasit = .F.
IF SEEK(m.lcCheieCauta, 'crsTabel', 'cfro')
llGasit = .T.
DO WHILE !(EMPTY(NVL(data, {})) OR data = ldData)
SKIP
IF EOF() OR cod_fiscalfro <> m.lcCheieCauta
llGasit = .F.
EXIT
ENDIF
ENDDO
ENDIF
IF llGasit
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
splittva WITH .splittva, inactiv WITH .inactiv
ENDIF
ENDWITH
SELECT crsRezANAF
ENDSCAN
lnT3 = SECONDS() - lnT3
DO WrLog3 WITH 'C SEEK + SKIP pe cheie (cod propus) = ' + TRANSFORM(ROUND(lnT3, 3)) + ' s'
SELECT COUNT(*) AS n FROM crsTabel WHERE !EMPTY(NVL(firma, '')) INTO CURSOR crsCtrl3
DO WrLog3 WITH ' randuri completate: ' + TRANSFORM(crsCtrl3.n)
USE IN (SELECT('crsCtrl3'))
DO WrLog3 WITH 'raport A/C = ' + TRANSFORM(ROUND(lnT1 / MAX(lnT3, 0.001), 1)) + 'x'
ENDPROC
PROCEDURE ConstrTabel
LPARAMETERS tnN
LOCAL lnK
IF USED('crsTabel')
USE IN crsTabel
ENDIF
CREATE CURSOR crsTabel (ales L, denumire C(100) NULL, cod_fiscal C(30) NULL, Valid L NULL, ;
firma C(100) NULL, cod C(100) NULL, adresa C(250) NULL, judet C(100) NULL, regcom C(30) NULL, ;
datatvamfin C(30) NULL, platitortvamfin L NULL, IsCIF L NULL, duplicat L, atribut_fiscal C(2), ;
stare C(100), atentie C(100), cod_fiscalfro C(30) NULL, tvaincasare L, splittva L, inactiv L, Data D)
FOR lnK = 1 TO tnN
INSERT INTO crsTabel (cod_fiscal, denumire, Valid, IsCIF, Data) ;
VALUES ('RO' + ALLTRIM(STR(10000000 + lnK)), 'PARTENER ' + ALLTRIM(STR(lnK)), .T., .T., DATE())
ENDFOR
ENDPROC
PROCEDURE WrLog3
LPARAMETERS tcText
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC
PROCEDURE ErrCompl
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
DO WrLog3 WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
RETURN
ENDPROC

View File

@@ -0,0 +1,306 @@
* test_timp_masa_peste1000.prg - continuarea masuratorii din test_timp_verificare_masa.prg:
* 1. curata randurile ramase in ISTORIC_CODURI_FISCALE peste watermark-ul rularii anterioare
* 2. costul unei scrieri goLog (STRTOFILE additive) in functie de marimea fisierului de log
* 3. costul unui apel CitesteIstoricPentruCoduri cu UN singur cod (plasa de siguranta)
* 4. rularea completa VerificaListaCIF pe un lot de peste 1000 de coduri (ANAF blocat),
* unde interogarea de cache pica pe ORA-01795 si se ajunge cod-cu-cod
*
* Rulare: vfp9.exe -A -T "...\test_timp_masa_peste1000.prg" [watermark]
LPARAMETERS tcWatermark
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcTestLog, gnApeluriANAF, gcMockUltimMesaj, gnMockUltimTip, gnMockRaspuns
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_timp_masa_peste1000_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
gnApeluriANAF = 0
gcMockUltimMesaj = ''
gnMockUltimTip = 0
gnMockRaspuns = 6
ON ERROR DO ErrP1000 WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO WrLog2 WITH 'EROARE: conectare Oracle esuata - GATA'
QUIT
ENDIF
DO WrLog2 WITH 'mediu OK, schema=' + gcS
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
* mock_amessagebox NU acopera apelurile de amessagebox facute din oproceduri_comune.prg
* (VFP rezolva intai in fisierul de proceduri curent), iar oexecutor.oExecuta deschide un
* formular modal la orice eroare SQL - headless asta blocheaza procesul. Deci inlocuiesc
* executorul cu o subclasa care nu deschide dialogul si numara erorile.
PUBLIC gnErorriSQL, gcUltimaEroareSQL
gnErorriSQL = 0
gcUltimaEroareSQL = ''
LOCAL loExecNou
loExecNou = CREATEOBJECT('oexec_fara_dialog')
loExecNou.nHandle = gnHandle
goExecutor = loExecNou
DO WrLog2 WITH 'executor inlocuit (fara dialog modal la eroare SQL)'
LOCAL lnWm, lcSql, lnT, lnI, lnRep
lnWm = IIF(TYPE('tcWatermark') = 'C' AND !EMPTY(tcWatermark), INT(VAL(tcWatermark)), 0)
*==========================================================
* 1. curatenie dupa rularea anterioara
*==========================================================
IF lnWm > 0
lcSql = 'SELECT COUNT(*) AS N FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(lnWm)
IF goExecutor.oExecuta(lcSql, 'crsRest')
DO WrLog2 WITH 'randuri peste watermark ' + TRANSFORM(lnWm) + ': ' + TRANSFORM(crsRest.N)
USE IN (SELECT('crsRest'))
ENDIF
=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(lnWm))
=goExecutor.oExecuta('COMMIT')
DO WrLog2 WITH 'curatenie facuta (ID > ' + TRANSFORM(lnWm) + ')'
ELSE
DO WrLog2 WITH 'fara watermark - nu sterg nimic'
ENDIF
PUBLIC gnIdMaxIstoric
gnIdMaxIstoric = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsWm2')
gnIdMaxIstoric = crsWm2.IDMAX
USE IN (SELECT('crsWm2'))
ENDIF
DO WrLog2 WITH 'watermark nou = ' + TRANSFORM(gnIdMaxIstoric)
*==========================================================
* 2. costul unei scrieri de log, in functie de marimea fisierului
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 2. cost STRTOFILE additive (asta face goLog.Log) ==='
LOCAL lcF, lcLinie
lcLinie = REPLICATE('x', 120) + CHR(13) + CHR(10)
lnRep = 300
lcF = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_probalog_mic.txt'
STRTOFILE('', lcF)
lnT = SECONDS()
FOR lnI = 1 TO lnRep
STRTOFILE(lcLinie, lcF, .T.)
ENDFOR
lnT = SECONDS() - lnT
DO WrLog2 WITH '2a fisier ~0 MB: ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/scriere (' + TRANSFORM(ROUND(lnT, 3)) + ' s / ' + TRANSFORM(lnRep) + ')'
lcF = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_probalog_mare.txt'
STRTOFILE(REPLICATE(lcLinie, 40000), lcF)
DO WrLog2 WITH ' fisier mare pregatit: ' + TRANSFORM(ROUND(FSIZE(lcF) / 1048576, 2)) + ' MB'
lnT = SECONDS()
FOR lnI = 1 TO lnRep
STRTOFILE(lcLinie, lcF, .T.)
ENDFOR
lnT = SECONDS() - lnT
DO WrLog2 WITH '2b fisier ' + TRANSFORM(ROUND(FSIZE(lcF) / 1048576, 2)) + ' MB: ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/scriere (' + TRANSFORM(ROUND(lnT, 3)) + ' s)'
* pentru comparatie: acelasi volum scris cu handle deschis o singura data
lcF = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_probalog_handle.txt'
IF FILE(lcF)
ERASE (lcF)
ENDIF
LOCAL lnH
lnH = FCREATE(lcF)
lnT = SECONDS()
FOR lnI = 1 TO lnRep
=FPUTS(lnH, lcLinie)
ENDFOR
=FCLOSE(lnH)
lnT = SECONDS() - lnT
DO WrLog2 WITH '2c acelasi volum, handle deschis o data: ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 3)) + ' ms/scriere'
*==========================================================
* 3. costul plasei de siguranta: o interogare per cod
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 3. CitesteIstoricPentruCoduri cu UN cod (plasa de siguranta) ==='
LOCAL loVer, lnZile
loVer = CREATEOBJECT('VerificareANAFTimp2')
lnZile = loVer.ZileCache()
lcSql = 'SELECT COD_FISCAL_N FROM (SELECT DISTINCT COD_FISCAL_N FROM ISTORIC_CODURI_FISCALE'
lcSql = lcSql + ' WHERE COD_FISCAL_N IS NOT NULL AND DATAORAV_ANAF IS NOT NULL'
lcSql = lcSql + ' AND SYSDATE - DATAORAV_ANAF <= ' + TRANSFORM(lnZile)
lcSql = lcSql + ' ORDER BY COD_FISCAL_N) WHERE ROWNUM <= 1200'
=goExecutor.oExecuta(lcSql, 'crsCod2')
IF USED('cLot')
USE IN cLot
ENDIF
CREATE CURSOR cLot (cod_fiscal C(30) NULL, data D NULL)
SELECT crsCod2
SCAN
INSERT INTO cLot (cod_fiscal, data) VALUES (ALLTRIM(TRANSFORM(crsCod2.COD_FISCAL_N)), DATE())
SELECT crsCod2
ENDSCAN
USE IN (SELECT('crsCod2'))
DO WrLog2 WITH 'coduri proaspete disponibile: ' + TRANSFORM(RECCOUNT('cLot'))
IF USED('crsUnul')
USE IN crsUnul
ENDIF
lnRep = MIN(100, RECCOUNT('cLot'))
lnT = SECONDS()
SELECT cLot
GO TOP
FOR lnI = 1 TO lnRep
=loVer.CitesteIstoricPentruCoduri(ALLTRIM(NVL(cLot.cod_fiscal, '')), DATE(), 'crsUnul', 'CACHE_INDISP')
SELECT cLot
SKIP
ENDFOR
lnT = SECONDS() - lnT
DO WrLog2 WITH '3a ' + TRANSFORM(lnRep) + ' apeluri cu un singur cod = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
DO WrLog2 WITH ' = ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/cod -> ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 1)) + ' s la 1000 de coduri'
*==========================================================
* 4. flux complet peste limita de 1000
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 4. VerificaListaCIF pe lot > 1000 coduri (ANAF blocat) ==='
IF USED('cLot1001')
USE IN cLot1001
ENDIF
CREATE CURSOR cLot1001 (cod_fiscal C(30) NULL, data D NULL)
SELECT cLot
SCAN
INSERT INTO cLot1001 (cod_fiscal, data) VALUES (cLot.cod_fiscal, DATE())
SELECT cLot
ENDSCAN
FOR lnI = RECCOUNT('cLot1001') + 1 TO 1001
INSERT INTO cLot1001 (cod_fiscal, data) VALUES (ALLTRIM(STR(9000000 + lnI)), DATE())
ENDFOR
DO WrLog2 WITH 'lot = ' + TRANSFORM(RECCOUNT('cLot1001')) + ' coduri; START ' + TTOC(DATETIME())
gnApeluriANAF = 0
lnT = SECONDS()
=loVer.VerificaListaCIF('cLot1001', DATE(), 'crsRez1001', 'MASA')
lnT = SECONDS() - lnT
DO WrLog2 WITH ' erori SQL in flux: ' + TRANSFORM(gnErorriSQL) + ' [' + LEFT(gcUltimaEroareSQL, 90) + ']'
DO WrLog2 WITH '4a TOTAL = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru ' + TRANSFORM(RECCOUNT('cLot1001')) + ' coduri'
DO WrLog2 WITH ' randuri intoarse: ' + TRANSFORM(IIF(USED('crsRez1001'), RECCOUNT('crsRez1001'), 0))
DO WrLog2 WITH ' apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)
DO WrLog2 WITH ' ultim dialog interceptat: [' + LEFT(gcMockUltimMesaj, 100) + ']'
* acelasi lot, dar sub limita (1000 de coduri) - reper
IF USED('cLot1000')
USE IN cLot1000
ENDIF
CREATE CURSOR cLot1000 (cod_fiscal C(30) NULL, data D NULL)
SELECT cLot1001
GO TOP
FOR lnI = 1 TO 1000
INSERT INTO cLot1000 (cod_fiscal, data) VALUES (cLot1001.cod_fiscal, DATE())
SELECT cLot1001
SKIP
ENDFOR
DO WrLog2 WITH 'lot de reper = ' + TRANSFORM(RECCOUNT('cLot1000')) + ' coduri'
gnApeluriANAF = 0
lnT = SECONDS()
=loVer.VerificaListaCIF('cLot1000', DATE(), 'crsRez1000', 'MASA')
lnT = SECONDS() - lnT
DO WrLog2 WITH '4b TOTAL = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru 1000 de coduri (sub limita IN)'
DO WrLog2 WITH ' randuri intoarse: ' + TRANSFORM(IIF(USED('crsRez1000'), RECCOUNT('crsRez1000'), 0))
DO WrLog2 WITH ' apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)
*==========================================================
* 5. flux la 3000 de coduri (reale + sintetice) - dovada ca scaleaza peste 1000
*==========================================================
DO WrLog2 WITH ''
DO WrLog2 WITH '=== 5. VerificaListaCIF pe lot de 3000 coduri (ANAF blocat) ==='
IF USED('cLot3000')
USE IN cLot3000
ENDIF
CREATE CURSOR cLot3000 (cod_fiscal C(30) NULL, data D NULL)
SELECT cLot1001
GO TOP
SCAN
INSERT INTO cLot3000 (cod_fiscal, data) VALUES (cLot1001.cod_fiscal, DATE())
SELECT cLot1001
ENDSCAN
FOR lnI = RECCOUNT('cLot3000') + 1 TO 3000
INSERT INTO cLot3000 (cod_fiscal, data) VALUES (ALLTRIM(STR(9500000 + lnI)), DATE())
ENDFOR
DO WrLog2 WITH 'lot = ' + TRANSFORM(RECCOUNT('cLot3000')) + ' coduri; START ' + TTOC(DATETIME())
gnApeluriANAF = 0
gnErorriSQL = 0
lnT = SECONDS()
=loVer.VerificaListaCIF('cLot3000', DATE(), 'crsRez3000', 'MASA')
lnT = SECONDS() - lnT
DO WrLog2 WITH ' erori SQL in flux: ' + TRANSFORM(gnErorriSQL) + ' [' + LEFT(gcUltimaEroareSQL, 90) + ']'
DO WrLog2 WITH '5a TOTAL = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru ' + TRANSFORM(RECCOUNT('cLot3000')) + ' coduri'
DO WrLog2 WITH ' randuri intoarse: ' + TRANSFORM(IIF(USED('crsRez3000'), RECCOUNT('crsRez3000'), 0))
DO WrLog2 WITH ' apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)
*==========================================================
DO WrLog2 WITH ''
DO CurataP1000
DO WrLog2 WITH 'GATA ' + TTOC(DATETIME())
QUIT
PROCEDURE WrLog2
LPARAMETERS tcText
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC
PROCEDURE ErrP1000
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
DO WrLog2 WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
RETURN
ENDPROC
PROCEDURE CurataP1000
IF TYPE('gnIdMaxIstoric') <> 'N' OR gnIdMaxIstoric <= 0
DO WrLog2 WITH 'curatenie SARITA - watermark invalid'
RETURN
ENDIF
=goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnIdMaxIstoric))
=goExecutor.oExecuta('COMMIT')
DO WrLog2 WITH 'curatenie: sterse randurile cu ID > ' + TRANSFORM(gnIdMaxIstoric)
ENDPROC
DEFINE CLASS oexec_fara_dialog AS oexecutor
FUNCTION oExecuta
LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect
LOCAL lcSql, lcCursor, lnHandle, lnRez
lcSql = IIF(EMPTY(tcSql), This.cSql, tcSql)
lcCursor = IIF(EMPTY(tcCursor), This.cCursor, tcCursor)
lnHandle = IIF(EMPTY(tnHandle), This.nHandle, tnHandle)
lnRez = This.oExecute(lcSql, lcCursor, tlProgress, tcTitluProgress, lnHandle)
IF lnRez < 1
gnErorriSQL = gnErorriSQL + 1
gcUltimaEroareSQL = TRANSFORM(This.cEroare)
ENDIF
RETURN (lnRez >= 1)
ENDFUNC
ENDDEFINE
DEFINE CLASS VerificareANAFTimp2 AS VerificareANAF
PROCEDURE OrdineCache
LPARAMETERS tcTraseu
RETURN 'CACHE,ANAF'
ENDPROC
PROCEDURE ANAF_SincronWebService_PlatitorTva
LPARAMETERS tcCursorListaCIF, tdData, tcAlias
gnApeluriANAF = gnApeluriANAF + 1
RETURN IIF(EMPTY(tcAlias), 'crsANAF', tcAlias)
ENDPROC
ENDDEFINE

View File

@@ -0,0 +1,483 @@
* test_timp_verificare_masa.prg - masoara UNDE se duce timpul la verificarea in masa a
* codurilor fiscale cand raspunsul vine din cache (ISTORIC_CODURI_FISCALE), nu de la ANAF.
*
* Traseul masurat: VerificareANAF.VerificaListaCIF(..., 'MASA') din COMUN\programe\validare.prg,
* apelat de frm_verificare_parteneri.do_verifica (COMUN\clase\overificari.vc2:2736) si de
* orapoarte.prg:1997.
*
* ANAF-ul REAL nu e apelat niciodata: subclasa VerificareANAFTimp (finalul fisierului) blocheaza
* ANAF_SincronWebService_PlatitorTva si numara apelurile, deci tot ce se masoara e cost local
* (Oracle + VFP), nu latenta serviciului ANAF.
*
* Ce masoara, in ordine:
* A. rulare completa VerificaListaCIF pe N coduri proaspete in cache (implicit N=200)
* B. descompunerea pe faze a aceleiasi rulari (OrdineCache, ZileCache, NormalizeazaCoduriCursor,
* CitesteIstoricPentruCoduri, bucla de Locate, SalveazaIstoricDinCursor, bucla de goLog)
* C. costul brut al unui apel Oracle prin goExecutor (cu si fara scriere in goLog)
* D. limita IN (...) din CitesteIstoricPentruCoduri: lista de coduri se pune inline in SQL,
* deci peste 1000 de coduri Oracle da ORA-01795
* E. bucla de completare din apelant (overificari.vc2:2741-2756): LOCATE cu UDF per rand,
* comparata cu aceeasi completare pe cursor indexat
*
* Rulare: vfp9.exe -A -T "...\test_timp_verificare_masa.prg" [N]
* Log: test_timp_verificare_masa_log.txt (langa script)
* Curatenie: randurile scrise in ISTORIC_CODURI_FISCALE peste watermark-ul de ID se sterg la final.
LPARAMETERS tcN
SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES
PUBLIC gcTestLog, gnApeluriANAF, gcMockUltimMesaj, gnMockUltimTip, gnMockRaspuns
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_timp_verificare_masa_log.txt"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13) + CHR(10), gcTestLog)
gnApeluriANAF = 0
gcMockUltimMesaj = ''
gnMockUltimTip = 0
gnMockRaspuns = 6
ON ERROR DO ErrTimp WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT
DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
DO WrLog WITH 'EROARE: conectare Oracle esuata - GATA'
QUIT
ENDIF
DO WrLog WITH 'mediu OK, schema=' + gcS
* mock-ul de amessagebox se incarca ULTIMUL (dialogurile modale ar bloca rularea headless)
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
* mock_amessagebox NU acopera apelul de amessagebox din oexecutor.oExecuta: VFP rezolva intai
* in fisierul de proceduri curent (oproceduri_comune.prg), iar acolo amessagebox deschide un
* FORMULAR modal (MessageBox.vcx), invizibil in enumerarea ferestrelor - headless blocheaza
* procesul la nesfarsit. Sectiunea D provoaca intentionat ORA-01795, deci executorul trebuie
* sa fie unul care nu deschide dialogul.
PUBLIC gnErorriSQL, gcUltimaEroareSQL
gnErorriSQL = 0
gcUltimaEroareSQL = ''
LOCAL loExecFaraDialog
loExecFaraDialog = CREATEOBJECT('oexec_fara_dialog_t')
loExecFaraDialog.nHandle = gnHandle
goExecutor = loExecFaraDialog
LOCAL lnN, lnI, lnT, lcSql, lcLista, lnRandInit, lnRandFinal
lnN = IIF(TYPE('tcN') = 'C' AND !EMPTY(tcN), INT(VAL(tcN)), 200)
DO WrLog WITH 'N cerut = ' + TRANSFORM(lnN)
* goLog scrie doar daca fisierul de log EXISTA (log_mesaje.prg:54) - in productie exista,
* deci il cream, ca masuratoarea sa includa costul real de logare
PUBLIC gcLogApp
gcLogApp = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_timp_log_app.txt"
STRTOFILE('', gcLogApp)
goLog.cLogFile = gcLogApp
* --- watermark ID, inainte de orice scriere ---
PUBLIC gnIdMaxIstoric
gnIdMaxIstoric = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsWmT')
SELECT crsWmT
GO TOP
gnIdMaxIstoric = IDMAX
USE IN (SELECT('crsWmT'))
ENDIF
DO WrLog WITH 'watermark ISTORIC_CODURI_FISCALE id_max=' + TRANSFORM(gnIdMaxIstoric)
IF gnIdMaxIstoric <= 0
DO WrLog WITH 'ATENTIE: watermark invalid - curatenia finala se va sari'
ENDIF
LOCAL loVer, lnZile
loVer = CREATEOBJECT('VerificareANAFTimp')
lnZile = loVer.ZileCache()
DO WrLog WITH 'ZileCache = ' + TRANSFORM(lnZile)
* --- context: cat de mare e istoricul, cate coduri sunt proaspete ---
IF goExecutor.oExecuta('SELECT COUNT(*) AS N FROM ISTORIC_CODURI_FISCALE', 'crsCtx1')
DO WrLog WITH 'randuri in ISTORIC_CODURI_FISCALE: ' + TRANSFORM(crsCtx1.N)
USE IN (SELECT('crsCtx1'))
ENDIF
lcSql = 'SELECT COUNT(DISTINCT COD_FISCAL_N) AS N FROM ISTORIC_CODURI_FISCALE'
lcSql = lcSql + ' WHERE DATAORAV_ANAF IS NOT NULL AND SYSDATE - DATAORAV_ANAF <= ' + TRANSFORM(lnZile)
IF goExecutor.oExecuta(lcSql, 'crsCtx2')
DO WrLog WITH 'coduri proaspete in cache (<= ' + TRANSFORM(lnZile) + ' zile): ' + TRANSFORM(crsCtx2.N)
USE IN (SELECT('crsCtx2'))
ENDIF
* --- lotul de test: coduri PROASPETE din cache, ca sa nu se ajunga la ANAF ---
lcSql = 'SELECT COD_FISCAL_N FROM (SELECT DISTINCT COD_FISCAL_N FROM ISTORIC_CODURI_FISCALE'
lcSql = lcSql + ' WHERE COD_FISCAL_N IS NOT NULL AND DATAORAV_ANAF IS NOT NULL'
lcSql = lcSql + ' AND SYSDATE - DATAORAV_ANAF <= ' + TRANSFORM(lnZile)
lcSql = lcSql + ' ORDER BY COD_FISCAL_N) WHERE ROWNUM <= ' + TRANSFORM(lnN)
IF !goExecutor.oExecuta(lcSql, 'crsCoduriSursa')
DO WrLog WITH 'EROARE: nu pot citi codurile din istoric - GATA'
QUIT
ENDIF
IF USED('cCoduriMasa')
USE IN cCoduriMasa
ENDIF
CREATE CURSOR cCoduriMasa (cod_fiscal C(30) NULL, data D NULL)
SELECT crsCoduriSursa
SCAN
INSERT INTO cCoduriMasa (cod_fiscal, data) VALUES (ALLTRIM(TRANSFORM(crsCoduriSursa.COD_FISCAL_N)), DATE())
SELECT crsCoduriSursa
ENDSCAN
USE IN (SELECT('crsCoduriSursa'))
lnN = RECCOUNT('cCoduriMasa')
DO WrLog WITH '--- lot efectiv: ' + TRANSFORM(lnN) + ' coduri proaspete'
IF lnN = 0
DO WrLog WITH 'EROARE: niciun cod proaspat in cache - GATA'
QUIT
ENDIF
*==========================================================
* A. rulare completa VerificaListaCIF (traseu MASA = CACHE,ANAF)
*==========================================================
DO WrLog WITH ''
DO WrLog WITH '=== A. VerificaListaCIF complet, ' + TRANSFORM(lnN) + ' coduri ==='
gnApeluriANAF = 0
lnRandInit = NrRanduriIstoric()
lnT = SECONDS()
LOCAL lcRez
lcRez = loVer.VerificaListaCIF('cCoduriMasa', DATE(), 'crsANAFTest', 'MASA')
lnT = SECONDS() - lnT
lnRandFinal = NrRanduriIstoric()
DO WrLog WITH 'TOTAL VerificaListaCIF = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru ' + TRANSFORM(lnN) + ' coduri'
DO WrLog WITH ' = ' + TRANSFORM(ROUND(lnT / MAX(lnN, 1) * 1000, 2)) + ' ms/cod'
DO WrLog WITH 'randuri intoarse: ' + TRANSFORM(IIF(USED('crsANAFTest'), RECCOUNT('crsANAFTest'), 0))
DO WrLog WITH 'apeluri ANAF (blocate de subclasa): ' + TRANSFORM(gnApeluriANAF)
DO WrLog WITH 'randuri NOI in ISTORIC_CODURI_FISCALE dupa rulare: ' + TRANSFORM(lnRandFinal - lnRandInit)
IF USED('crsANAFTest')
SELECT sursa, COUNT(*) AS nr FROM crsANAFTest GROUP BY sursa INTO CURSOR crsSurse
SELECT crsSurse
SCAN
DO WrLog WITH ' sursa [' + ALLTRIM(NVL(crsSurse.sursa, '')) + '] = ' + TRANSFORM(crsSurse.nr)
SELECT crsSurse
ENDSCAN
USE IN (SELECT('crsSurse'))
ENDIF
*==========================================================
* B. descompunere pe faze
*==========================================================
DO WrLog WITH ''
DO WrLog WITH '=== B. descompunere pe faze ==='
LOCAL loVerB, lcAliasNorm, lnCui, lcCod, ldData, llGasit, lnFaraRasp
loVerB = CREATEOBJECT('VerificareANAFTimp')
lnT = SECONDS()
LOCAL lcOrdine
lcOrdine = loVerB.OrdineCacheReal('MASA')
DO WrLog WITH 'B1 OrdineCache(MASA) = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s -> ' + lcOrdine
lnT = SECONDS()
=loVerB.ZileCache()
DO WrLog WITH 'B2 ZileCache = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s'
lnT = SECONDS()
lcAliasNorm = loVerB.NormalizeazaCoduriCursor('cCoduriMasa', DATE())
DO WrLog WITH 'B3 NormalizeazaCoduriCursor = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s'
lnT = SECONDS()
lcLista = ''
SELECT (lcAliasNorm)
SCAN FOR cui_n <> 0
lcLista = lcLista + IIF(EMPTY(lcLista), '', ',') + ALLTRIM(STR(cui_n))
SELECT (lcAliasNorm)
ENDSCAN
DO WrLog WITH 'B4 construire lista coduri = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s'
IF USED('crsFazaB')
USE IN crsFazaB
ENDIF
lnT = SECONDS()
=loVerB.CitesteIstoricPentruCoduri(lcLista, DATE(), 'crsFazaB', 'CACHE')
DO WrLog WITH 'B5 CitesteIstoricPentruCoduri (1 interogare) = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s'
DO WrLog WITH ' randuri din cache: ' + TRANSFORM(IIF(USED('crsFazaB'), RECCOUNT('crsFazaB'), 0))
* bucla de Locate care alege codurile ramase (validare.prg:1939-1954)
lnT = SECONDS()
lnFaraRasp = 0
SELECT (lcAliasNorm)
SCAN
lnCui = cui_n
llGasit = .F.
IF lnCui <> 0 AND USED('crsFazaB') AND RECCOUNT('crsFazaB') > 0
SELECT crsFazaB
LOCATE FOR cui = lnCui
llGasit = FOUND()
ENDIF
IF !llGasit
lnFaraRasp = lnFaraRasp + 1
ENDIF
SELECT (lcAliasNorm)
ENDSCAN
DO WrLog WITH 'B6 bucla Locate (2 treceri in cod real) = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s'
DO WrLog WITH ' coduri neacoperite de cache: ' + TRANSFORM(lnFaraRasp)
lnT = SECONDS()
LOCAL lnSalvate
lnSalvate = loVerB.SalveazaIstoricDinCursor('crsFazaB', gnIdUtil)
lnT = SECONDS() - lnT
DO WrLog WITH 'B7 SalveazaIstoricDinCursor = ' + TRANSFORM(ROUND(lnT, 3)) + ' s pentru ' + TRANSFORM(lnSalvate) + ' randuri'
DO WrLog WITH ' = ' + TRANSFORM(ROUND(lnT / MAX(lnSalvate, 1) * 1000, 2)) + ' ms/rand (1 apel PL/SQL per rand)'
lnT = SECONDS()
IF USED('crsFazaB')
SELECT crsFazaB
SCAN FOR LEFT(NVL(sursa, ''), 5) == 'CACHE'
goLog.Log('cache cui=' + TRANSFORM(cui) + ' sursa=' + ALLTRIM(sursa), 'testtimp')
SELECT crsFazaB
ENDSCAN
ENDIF
DO WrLog WITH 'B8 bucla de goLog pe randurile din cache = ' + TRANSFORM(ROUND(SECONDS() - lnT, 3)) + ' s'
*==========================================================
* C. costul brut al unui apel Oracle prin goExecutor
*==========================================================
DO WrLog WITH ''
DO WrLog WITH '=== C. cost apel Oracle prin goExecutor ==='
LOCAL lnRep
lnRep = MIN(lnN, 200)
lnT = SECONDS()
FOR lnI = 1 TO lnRep
=goExecutor.oExecuta('begin null; end;')
ENDFOR
lnT = SECONDS() - lnT
DO WrLog WITH 'C1 ' + TRANSFORM(lnRep) + ' x [begin null; end;] cu goLog activ = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
DO WrLog WITH ' = ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/apel'
LOCAL lcLogVechi
lcLogVechi = goLog.cLogFile
goLog.cLogFile = 'D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\_log_inexistent.txt'
lnT = SECONDS()
FOR lnI = 1 TO lnRep
=goExecutor.oExecuta('begin null; end;')
ENDFOR
lnT = SECONDS() - lnT
DO WrLog WITH 'C2 ' + TRANSFORM(lnRep) + ' x [begin null; end;] fara goLog = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
DO WrLog WITH ' = ' + TRANSFORM(ROUND(lnT / lnRep * 1000, 2)) + ' ms/apel'
goLog.cLogFile = lcLogVechi
*==========================================================
* D. limita IN (...) din CitesteIstoricPentruCoduri
*==========================================================
DO WrLog WITH ''
DO WrLog WITH '=== D. limita listei IN (...) ==='
LOCAL lcLista1000, lcLista1001, llOk
lcLista1000 = ListaSintetica(1000)
lcLista1001 = ListaSintetica(1001)
lcSql = 'SELECT COUNT(*) AS N FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N IN (' + lcLista1000 + ')'
llOk = (goExecutor.oExecute(lcSql, 'crsLim1') >= 1)
DO WrLog WITH 'D1 IN cu 1000 elemente: ' + IIF(llOk, 'OK', 'ESEC -> ' + goExecutor.cEroare)
IF USED('crsLim1')
USE IN crsLim1
ENDIF
lcSql = 'SELECT COUNT(*) AS N FROM ISTORIC_CODURI_FISCALE WHERE COD_FISCAL_N IN (' + lcLista1001 + ')'
llOk = (goExecutor.oExecute(lcSql, 'crsLim2') >= 1)
DO WrLog WITH 'D2 IN cu 1001 elemente: ' + IIF(llOk, 'OK', 'ESEC -> ' + goExecutor.cEroare)
IF USED('crsLim2')
USE IN crsLim2
ENDIF
* efectul in flux: lot de 1001 coduri, cache-ul pica, ANAF blocat -> plasa de siguranta
* face cate o interogare per cod
IF USED('cCoduri1001')
USE IN cCoduri1001
ENDIF
CREATE CURSOR cCoduri1001 (cod_fiscal C(30) NULL, data D NULL)
SELECT cCoduriMasa
SCAN
INSERT INTO cCoduri1001 (cod_fiscal, data) VALUES (cCoduriMasa.cod_fiscal, DATE())
SELECT cCoduriMasa
ENDSCAN
FOR lnI = RECCOUNT('cCoduri1001') + 1 TO 1001
INSERT INTO cCoduri1001 (cod_fiscal, data) VALUES (ALLTRIM(STR(9000000 + lnI)), DATE())
ENDFOR
DO WrLog WITH 'D3 lot de ' + TRANSFORM(RECCOUNT('cCoduri1001')) + ' coduri (peste limita IN)'
gnApeluriANAF = 0
gcMockUltimMesaj = ''
lnT = SECONDS()
=loVer.VerificaListaCIF('cCoduri1001', DATE(), 'crsANAF1001', 'MASA')
lnT = SECONDS() - lnT
DO WrLog WITH 'D4 TOTAL VerificaListaCIF pe 1001 coduri = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
DO WrLog WITH ' randuri intoarse: ' + TRANSFORM(IIF(USED('crsANAF1001'), RECCOUNT('crsANAF1001'), 0))
DO WrLog WITH ' apeluri ANAF (blocate): ' + TRANSFORM(gnApeluriANAF)
DO WrLog WITH ' ultim dialog modal interceptat: [' + LEFT(gcMockUltimMesaj, 120) + ']'
*==========================================================
* E. bucla de completare din apelant (overificari.vc2)
*==========================================================
DO WrLog WITH ''
DO WrLog WITH '=== E. completarea tabelului in apelant (do_verifica) ==='
IF !USED('crsANAFTest') OR RECCOUNT('crsANAFTest') = 0
DO WrLog WITH 'E: sarit - nu am rezultate de completat'
ELSE
DO ConstruiestePart WITH lnN
LOCAL loVerificare, ldDataE
loVerificare = CREATEOBJECT('verificarecod', .F., .F.)
ldDataE = DATE()
lnT = SECONDS()
SELECT crsANAFTest
SCAN
SCATTER NAME loRec
WITH loRec
SELECT crsPartTest
LOCATE FOR ALLTRIM(STRTRAN(cod_fiscal, loVerificare.GetCodTara(cod_fiscal), '')) = ALLTRIM(STR(.cui)) AND (EMPTY(NVL(data, {})) OR data = ldDataE)
IF FOUND()
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
splittva WITH .splittva, inactiv WITH .inactiv
ENDIF
ENDWITH
SELECT crsANAFTest
ENDSCAN
lnT = SECONDS() - lnT
DO WrLog WITH 'E1 completare cu LOCATE + UDF (cod real) = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
DO WrLog WITH ' ' + TRANSFORM(RECCOUNT('crsANAFTest')) + ' rezultate x ' + TRANSFORM(RECCOUNT('crsPartTest')) + ' randuri in tabel'
* aceeasi completare, pe cursor indexat pe codul normalizat (reper pentru cat s-ar putea castiga)
DO ConstruiestePart WITH lnN
lnT = SECONDS()
SELECT crsPartTest
REPLACE ALL cod_fiscalfro WITH ALLTRIM(STRTRAN(STRTRAN(UPPER(NVL(cod_fiscal, '')), 'RO', ''), ' ', ''))
INDEX ON cod_fiscalfro TAG cfro
SELECT crsANAFTest
SCAN
SCATTER NAME loRec
WITH loRec
IF SEEK(PADR(ALLTRIM(STR(.cui)), 30), 'crsPartTest', 'cfro')
SELECT crsPartTest
REPLACE firma WITH .denumire, adresa WITH .adresa, stare WITH .mesaj, ;
cod WITH ALLTRIM(STR(.cui)), tvaincasare WITH .tvaincasare, ;
splittva WITH .splittva, inactiv WITH .inactiv
ENDIF
ENDWITH
SELECT crsANAFTest
ENDSCAN
lnT = SECONDS() - lnT
DO WrLog WITH 'E2 aceeasi completare pe cursor indexat (SEEK) = ' + TRANSFORM(ROUND(lnT, 3)) + ' s'
ENDIF
*==========================================================
* curatenie
*==========================================================
DO WrLog WITH ''
DO CurataIstoricTimp
DO WrLog WITH 'GATA ' + TTOC(DATETIME())
QUIT
PROCEDURE WrLog
LPARAMETERS tcText
STRTOFILE(TRANSFORM(tcText) + CHR(13) + CHR(10), gcTestLog, .T.)
ENDPROC
PROCEDURE ErrTimp
LPARAMETERS tnError, tcMessage, tcProgram, tnLine
DO WrLog WITH 'EROARE ' + TRANSFORM(tnError) + ' [' + TRANSFORM(tcMessage) + '] in ' + ;
TRANSFORM(tcProgram) + ' linia ' + TRANSFORM(tnLine)
RETURN
ENDPROC
FUNCTION NrRanduriIstoric
LOCAL lnRez
lnRez = 0
IF goExecutor.oExecuta('SELECT COUNT(*) AS N FROM ISTORIC_CODURI_FISCALE', 'crsNrIst')
lnRez = crsNrIst.N
USE IN (SELECT('crsNrIst'))
ENDIF
RETURN lnRez
ENDFUNC
FUNCTION ListaSintetica
LPARAMETERS tnCate
LOCAL lcRez, lnJ
lcRez = ''
FOR lnJ = 1 TO tnCate
lcRez = lcRez + IIF(EMPTY(lcRez), '', ',') + ALLTRIM(STR(8000000 + lnJ))
ENDFOR
RETURN lcRez
ENDFUNC
PROCEDURE ConstruiestePart
LPARAMETERS tnCate
LOCAL lnK
IF USED('crsPartTest')
USE IN crsPartTest
ENDIF
CREATE CURSOR crsPartTest (ales L, denumire C(100) NULL, cod_fiscal C(30) NULL, Valid L NULL, ;
firma C(100) NULL, cod C(100) NULL, adresa C(250) NULL, judet C(100) NULL, regcom C(30) NULL, ;
datatvamfin C(30) NULL, platitortvamfin L NULL, IsCIF L NULL, duplicat L, atribut_fiscal C(2), ;
stare C(100), atentie C(100), cod_fiscalfro C(30) NULL, tvaincasare L, splittva L, inactiv L, Data D)
SELECT cCoduriMasa
SCAN
INSERT INTO crsPartTest (cod_fiscal, denumire, Valid, IsCIF, Data) ;
VALUES (cCoduriMasa.cod_fiscal, 'PARTENER ' + ALLTRIM(NVL(cCoduriMasa.cod_fiscal, '')), .T., .T., DATE())
SELECT cCoduriMasa
ENDSCAN
ENDPROC
PROCEDURE CurataIstoricTimp
LOCAL lnSterse
IF TYPE('gnIdMaxIstoric') <> 'N' OR gnIdMaxIstoric <= 0
DO WrLog WITH 'curatenie SARITA - watermark invalid'
RETURN
ENDIF
lnSterse = goExecutor.oExecuta('DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ' + TRANSFORM(gnIdMaxIstoric))
=goExecutor.oExecuta('COMMIT')
DO WrLog WITH 'curatenie: sterse randurile cu ID > ' + TRANSFORM(gnIdMaxIstoric)
ENDPROC
*** executor care nu deschide formularul modal de eroare (altfel headless se blocheaza)
DEFINE CLASS oexec_fara_dialog_t AS oexecutor
FUNCTION oExecuta
LPARAMETERS tcSql, tcCursor, tlProgress, tcTitluProgress, tnHandle, tlShowError, tlQuitOnError, tlReconnect
LOCAL lcSql, lcCursor, lnHandle, lnRez
lcSql = IIF(EMPTY(tcSql), This.cSql, tcSql)
lcCursor = IIF(EMPTY(tcCursor), This.cCursor, tcCursor)
lnHandle = IIF(EMPTY(tnHandle), This.nHandle, tnHandle)
lnRez = This.oExecute(lcSql, lcCursor, tlProgress, tcTitluProgress, lnHandle)
IF lnRez < 1
gnErorriSQL = gnErorriSQL + 1
gcUltimaEroareSQL = TRANSFORM(This.cEroare)
ENDIF
RETURN (lnRez >= 1)
ENDFUNC
ENDDEFINE
*** subclasa de test: blocheaza ANAF-ul real si expune OrdineCache-ul real sub alt nume
DEFINE CLASS VerificareANAFTimp AS VerificareANAF
PROCEDURE OrdineCache
LPARAMETERS tcTraseu
RETURN 'CACHE,ANAF'
ENDPROC
PROCEDURE OrdineCacheReal
LPARAMETERS tcTraseu
RETURN VerificareANAF::OrdineCache(tcTraseu)
ENDPROC
PROCEDURE ANAF_SincronWebService_PlatitorTva
LPARAMETERS tcCursorListaCIF, tdData, tcAlias
gnApeluriANAF = gnApeluriANAF + 1
RETURN IIF(EMPTY(tcAlias), 'crsANAF', tcAlias)
ENDPROC
ENDDEFINE