* 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
