* test_mock_batch_anaf_demo.prg - test demonstrativ headless pentru mock_batch_anaf.prg (poveste S11).
* Verifica cele 6 scenarii cerute (lot complet, lot partial, lot integral notFound, tacere, raspuns
* neinteles, HTTP 404 cu corp complet) plus acumularea pe mai multe grupuri (>100 coduri) si contorul
* de apeluri/CUI-uri trimise (esential pentru S6). Fara retea, fara UI - doar clasa VerificareANAFMockBatch
* si cursorul crsANAF rezultat.
*
* CONTRACT ACTUALIZAT 31.07.2026 (dupa S6): la tacere/raspuns neinteles/gate 404, cursorul de iesire
* se creeaza INTOTDEAUNA (plasa de siguranta din VerificaListaCIF cheama necondiionat
* CitesteIstoricPentruCoduri) - absenta datelor se exprima prin RECCOUNT=0, nu prin !USED(). Scenariile
* 4/5/6 si noul 4b verifica asta explicit; niciun apelant real nu distingea intre cursor-lipsa si
* cursor-gol (toti fac USED()+SCAN sau USED()+RECCOUNT), deci schimbarea de contract e sigura -
* decizie orchestrator, vezi docs\diff-S14b-validare-traseu.md si docs\diff-S14c-teste-s11.md.
* IMPORTANT (capcana l, COMUN\docs\depanare_testare_vfp.md): CREATEOBJECT/ADDPROPERTY apelate dintr-o
* PROCEDURE/FUNCTION se comporta gresit in acest runtime headless. Tot ce construieste obiecte de
* configurare (Empty+AddProperty, Collection) sta in programul PRINCIPAL, fara nicio DO catre un helper -
* de aceea scriptul e "plat" (fara PROCEDURE-uri de scenariu), doar cu bannere de comentarii intre
* scenarii; singurele PROCEDURE-uri sunt WriteTestLog si VpaErr (fara CREATEOBJECT in interior).
*
* Ordinea SET PROCEDURE e INVERSA fata de mock_anaf_verificare.prg (partener_anaf): acolo mock-ul
* trebuia incarcat PRIMUL, ca sa castige coliziunea de nume de FUNCTION. Aici nu exista coliziune de
* nume (VerificareANAFMockBatch != VerificareANAF) - clasa mea e o SUBCLASA si are nevoie ca parintele
* VerificareANAF sa fie deja definit (validare.prg, incarcat de test_init_env_auto), deci mock_batch_anaf.prg
* se incarca DUPA test_init_env_auto.

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, gnTestOk, gnTestTotal
gcTestLog = "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\test_mock_batch_anaf_demo_log.txt"
gnTestOk = 0
gnTestTotal = 0
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcTestLog)

ON ERROR DO VpaErr 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 WriteTestLog WITH 'EROARE: conectare Oracle esuata - GATA'
	QUIT
ENDIF
DO WriteTestLog WITH 'mediu OK, schema=' + gcS

*!* 01.08.2026 marius.mutu: watermark pe ID, inainte de orice scriere - garda pt DELETE-ul din CurataIstoricTest
PUBLIC gnIdMaxIstoricTest
gnIdMaxIstoricTest = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsWmIstoricTest')
	SELECT crsWmIstoricTest
	GO TOP
	gnIdMaxIstoricTest = IDMAX
	USE IN (SELECT('crsWmIstoricTest'))
ENDIF
*!* 01.08.2026 marius.mutu: watermark invalid = SELECT esuat - avertisment explicit, stergerile se vor sari
IF gnIdMaxIstoricTest <= 0
	DO WriteTestLog WITH 'ATENTIE: watermark invalid (0) - stergerile din ISTORIC_CODURI_FISCALE vor fi SARITE'
ENDIF
DO WriteTestLog WITH 'watermark ISTORIC_CODURI_FISCALE id_max=' + TRANSFORM(gnIdMaxIstoricTest)

*-- S4 a adaugat, la finalul VerificaListaCIF, scrierea in ISTORIC_CODURI_FISCALE
*-- (SalveazaIstoricDinCursor) - curatenie ACUM, ca sa nu depindem de o rulare anterioara
*-- intrerupta (nu exista cand a fost scris testul initial, S4 a venit dupa).
DO CurataIstoricTest

*-- mock-ul e o SUBCLASA a VerificareANAF (validare.prg) - se incarca DUPA test_init_env_auto (vezi antet)
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\cache_anaf\mock_batch_anaf.prg" ADDITIVE
DO WriteTestLog WITH 'mock_batch_anaf.prg incarcat'

PUBLIC goANAFBatchMock, goANAFBatchScenariuPerGrup, gcANAFBatchScenariu, glANAFBatchIgnoraGate404
PUBLIC gnANAFBatchApeluri, gcANAFBatchCuiuriTrimise
goANAFBatchMock = CREATEOBJECT('Collection')
goANAFBatchScenariuPerGrup = CREATEOBJECT('Collection')
gcANAFBatchScenariu = 'NORMAL'
glANAFBatchIgnoraGate404 = .F.
gnANAFBatchApeluri = 0
gcANAFBatchCuiuriTrimise = ''

PUBLIC goMockANAF
goMockANAF = CREATEOBJECT('VerificareANAFMockBatch')

TRY

	*=========================================================================
	* Scenariul 1: lot COMPLET - toate cele 3 CUI-uri configurate, gasite la ANAF
	*=========================================================================
	goANAFBatchMock = CREATEOBJECT('Collection')
	LOCAL loR1, loR2, loR3
	loR1 = CREATEOBJECT('Empty')
	ADDPROPERTY(loR1, 'denumire', 'ALFA PLATITOR SRL')
	ADDPROPERTY(loR1, 'scpTVA', .T.)
	ADDPROPERTY(loR1, 'dataInceputScpTVA', '2020-01-01')
	goANAFBatchMock.Add(loR1, 'C1000001')
	loR2 = CREATEOBJECT('Empty')
	ADDPROPERTY(loR2, 'denumire', 'BETA INACTIV SRL')
	ADDPROPERTY(loR2, 'inactiv', .T.)
	ADDPROPERTY(loR2, 'dataInactivare', '2021-06-15')
	goANAFBatchMock.Add(loR2, 'C1000002')
	loR3 = CREATEOBJECT('Empty')
	ADDPROPERTY(loR3, 'denumire', 'GAMA SPLITTVA SRL')
	ADDPROPERTY(loR3, 'splitTva', .T.)
	ADDPROPERTY(loR3, 'dataInceputSplitTVA', '2022-03-01')
	ADDPROPERTY(loR3, 'tvaIncasare', .T.)
	ADDPROPERTY(loR3, 'dataInceputTvaInc', '2022-03-01')
	goANAFBatchMock.Add(loR3, 'C1000003')

	IF USED('cLotComplet')
		USE IN cLotComplet
	ENDIF
	CREATE CURSOR cLotComplet (cod_fiscal C(30))
	INSERT INTO cLotComplet (cod_fiscal) VALUES ('1000001')
	INSERT INTO cLotComplet (cod_fiscal) VALUES ('1000002')
	INSERT INTO cLotComplet (cod_fiscal) VALUES ('1000003')

	gnANAFBatchApeluri = 0
	gcANAFBatchCuiuriTrimise = ''
	IF USED('crsLotComplet')
		USE IN crsLotComplet
	ENDIF
	LOCAL lcRezAlias
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotComplet', DATE(), 'crsLotComplet')

	IF USED('crsLotComplet') AND RECCOUNT('crsLotComplet') = 3
		SELECT crsLotComplet
		LOCATE FOR cui = 1000001
		LOCAL llOk1
		llOk1 = FOUND() AND ALLTRIM(denumire) == 'ALFA PLATITOR SRL' AND tva AND !inactiv
		LOCATE FOR cui = 1000002
		llOk1 = llOk1 AND FOUND() AND inactiv AND !tva
		LOCATE FOR cui = 1000003
		llOk1 = llOk1 AND FOUND() AND splittva AND tvaincasare
		IF llOk1 AND gnANAFBatchApeluri = 1 AND gcANAFBatchCuiuriTrimise == '1000001,1000002,1000003'
			DO VerificaTrece WITH 'lot-complet', '3 randuri corecte (tva/inactiv/splittva), 1 apel, cuiuri=' + gcANAFBatchCuiuriTrimise
		ELSE
			DO VerificaCade WITH 'lot-complet', 'campuri gresite sau contor apeluri=' + TRANSFORM(gnANAFBatchApeluri) + ' cuiuri=[' + gcANAFBatchCuiuriTrimise + ']'
		ENDIF
	ELSE
		DO VerificaCade WITH 'lot-complet', 'cursor lipsa sau numar randuri gresit (asteptat 3)'
	ENDIF

	*=========================================================================
	* Scenariul 2: lot PARTIAL - 2 gasite, 1 explicit NOTFOUND
	*=========================================================================
	goANAFBatchMock = CREATEOBJECT('Collection')
	LOCAL loR4, loR5
	loR4 = CREATEOBJECT('Empty')
	ADDPROPERTY(loR4, 'denumire', 'DELTA GASIT SRL')
	ADDPROPERTY(loR4, 'scpTVA', .T.)
	goANAFBatchMock.Add(loR4, 'C1000004')
	loR5 = CREATEOBJECT('Empty')
	ADDPROPERTY(loR5, 'denumire', 'EPSILON GASIT SRL')
	goANAFBatchMock.Add(loR5, 'C1000005')
	goANAFBatchMock.Add('NOTFOUND', 'C1000006')

	IF USED('cLotPartial')
		USE IN cLotPartial
	ENDIF
	CREATE CURSOR cLotPartial (cod_fiscal C(30))
	INSERT INTO cLotPartial (cod_fiscal) VALUES ('1000004')
	INSERT INTO cLotPartial (cod_fiscal) VALUES ('1000005')
	INSERT INTO cLotPartial (cod_fiscal) VALUES ('1000006')

	IF USED('crsLotPartial')
		USE IN crsLotPartial
	ENDIF
	gnANAFBatchApeluri = 0
	gcANAFBatchCuiuriTrimise = ''
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotPartial', DATE(), 'crsLotPartial')

	IF USED('crsLotPartial') AND RECCOUNT('crsLotPartial') = 3
		SELECT crsLotPartial
		LOCATE FOR cui = 1000004
		LOCAL llOk2
		llOk2 = FOUND() AND ALLTRIM(denumire) == 'DELTA GASIT SRL'
		LOCATE FOR cui = 1000006
		llOk2 = llOk2 AND FOUND() AND EMPTY(denumire)
		IF llOk2
			DO VerificaTrece WITH 'lot-partial', '3 randuri (2 cu date, 1 doar cu cui negasit)'
		ELSE
			DO VerificaCade WITH 'lot-partial', 'randuri lipsa sau campuri gresite'
		ENDIF
	ELSE
		DO VerificaCade WITH 'lot-partial', 'cursor lipsa sau numar randuri gresit (asteptat 3)'
	ENDIF

	*=========================================================================
	* Scenariul 3: lot INTEGRAL notFound - niciun CUI configurat (cazul care azi
	* deschide fereastra de eroare la validare.prg:1986-1994, pe traseul real)
	*=========================================================================
	goANAFBatchMock = CREATEOBJECT('Collection')

	IF USED('cLotNotfound')
		USE IN cLotNotfound
	ENDIF
	CREATE CURSOR cLotNotfound (cod_fiscal C(30))
	INSERT INTO cLotNotfound (cod_fiscal) VALUES ('1000007')
	INSERT INTO cLotNotfound (cod_fiscal) VALUES ('1000008')

	IF USED('crsLotNotfound')
		USE IN crsLotNotfound
	ENDIF
	gnANAFBatchApeluri = 0
	gcANAFBatchCuiuriTrimise = ''
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotNotfound', DATE(), 'crsLotNotfound')

	IF USED('crsLotNotfound') AND RECCOUNT('crsLotNotfound') = 2
		SELECT crsLotNotfound
		LOCATE FOR cui = 1000007
		LOCAL llOk3
		llOk3 = FOUND() AND EMPTY(denumire) AND ALLTRIM(sursa) == 'ANAF'
		LOCATE FOR cui = 1000008
		llOk3 = llOk3 AND FOUND() AND EMPTY(denumire) AND ALLTRIM(sursa) == 'ANAF'
		IF llOk3 AND gnANAFBatchApeluri = 1
			DO VerificaTrece WITH 'lot-integral-notfound', '2 randuri, doar cui completat, sursa=ANAF (notFound explicit, distinct de tacere - vezi scenariile 4/4b), 1 apel'
		ELSE
			DO VerificaCade WITH 'lot-integral-notfound', 'randuri gresite'
		ENDIF
	ELSE
		DO VerificaCade WITH 'lot-integral-notfound', 'cursor lipsa sau numar randuri gresit (asteptat 2)'
	ENDIF

	*=========================================================================
	* Scenariul 4: TACERE - fara raspuns folosibil (echivalent unui timeout/exceptie
	* la trimitere). CONTRACT NOU (dupa S6): cursorul de iesire se creeaza INTOTDEAUNA
	* (plasa de siguranta din VerificaListaCIF cheama necondiionat CitesteIstoricPentruCoduri,
	* care face Create Cursor daca alias-ul nu exista deja) - absenta datelor se exprima
	* prin RECCOUNT=0 (CUI 1000009 nu are niciodata istoric in acest test), nu prin !USED().
	* Toti cei 4 apelanti reali (orapoarte.prg, overificari.vc2, validare.prg:830-831) testeaza
	* USED()+SCAN sau USED()+RECCOUNT>=1 - un cursor gol produce acelasi efect practic ca lipsa
	* lui, deci schimbarea de contract nu rupe pe nimeni (decizie orchestrator 31.07.2026).
	*=========================================================================
	goANAFBatchMock = CREATEOBJECT('Collection')
	gcANAFBatchScenariu = 'TACERE'

	IF USED('cLotTacere')
		USE IN cLotTacere
	ENDIF
	CREATE CURSOR cLotTacere (cod_fiscal C(30))
	INSERT INTO cLotTacere (cod_fiscal) VALUES ('1000009')

	IF USED('crsLotTacere')
		USE IN crsLotTacere
	ENDIF
	gnANAFBatchApeluri = 0
	gcANAFBatchCuiuriTrimise = ''
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotTacere', DATE(), 'crsLotTacere')

	IF USED('crsLotTacere') AND RECCOUNT('crsLotTacere') = 0 AND gnANAFBatchApeluri = 1 AND gcANAFBatchCuiuriTrimise == '1000009'
		DO VerificaTrece WITH 'tacere', 'cursor creat dar gol (Reccount=0, 1000009 fara istoric) - contract nou S6; apelul (grupul) tot s-a incercat (apeluri=1, cui trimis)'
	ELSE
		DO VerificaCade WITH 'tacere', 'cursor/randuri neasteptate (used=' + TRANSFORM(USED('crsLotTacere')) + ' reccount=' + TRANSFORM(IIF(USED('crsLotTacere'), RECCOUNT('crsLotTacere'), -1)) + ') sau contor gresit (apeluri=' + TRANSFORM(gnANAFBatchApeluri) + ')'
	ENDIF
	gcANAFBatchScenariu = 'NORMAL'

	*=========================================================================
	* Scenariul 4b: TACERE + ISTORIC EXISTENT - demonstreaza ca distinctia tacere vs.
	* cod inexistent confirmat de ANAF (notFound, scenariul 3) tot se poate observa dupa
	* schimbarea de contract de mai sus, desi ambele produc acum un cursor: prin campul
	* `sursa`. CUI 1000012 seedat manual in ISTORIC_CODURI_FISCALE (istoric real, nu prin
	* ANAF) - la tacere, plasa de siguranta il gaseste si completeaza randul cu
	* sursa='CACHE_INDISP' si denumirea din istoric; scenariul 3 (notFound explicit)
	* produce sursa='ANAF' cu denumire goala. Fara istoric (scenariul 4, CUI 1000009):
	* niciun rand deloc pentru acel cui - a treia stare, tot distincta.
	*=========================================================================
	LOCAL lcSqlSeed4b
	lcSqlSeed4b = [insert into istoric_coduri_fiscale (dataora, id_util, dataorav, id_utilv, ] + ;
		[cod_fiscal, firma, cod_fiscal_n, dataorav_anaf, inactiv, tvaincasare, splittva, ] + ;
		[data_inceput_tvainc, data_sfarsit_tvainc) values (sysdate, ] + TRANSFORM(gnIdUtil) + ;
		[, sysdate, ] + TRANSFORM(gnIdUtil) + [, '1000012', 'ETA TACERE CACHE SRL', 1000012, ] + ;
		[sysdate, 0, 1, 0, to_date('2015-01-01','yyyy-mm-dd'), null)]
	=goExecutor.oExecuta(m.lcSqlSeed4b)
	=goExecutor.oExecuta('COMMIT')

	goANAFBatchMock = CREATEOBJECT('Collection')
	gcANAFBatchScenariu = 'TACERE'

	IF USED('cLotTacere4b')
		USE IN cLotTacere4b
	ENDIF
	CREATE CURSOR cLotTacere4b (cod_fiscal C(30))
	INSERT INTO cLotTacere4b (cod_fiscal) VALUES ('1000012')

	IF USED('crsLotTacere4b')
		USE IN crsLotTacere4b
	ENDIF
	gnANAFBatchApeluri = 0
	*-- 'UNIC' forteaza ANAF,CACHE (S14b) - altfel ordinea implicita MASA=CACHE,ANAF ar servi
	*-- 1000012 direct din cache INAINTE de ANAF (sursa=CACHE, nu CACHE_INDISP) si TACERE nu s-ar exercita
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotTacere4b', DATE(), 'crsLotTacere4b', 'UNIC')

	LOCAL llOk4b
	llOk4b = .F.
	IF USED('crsLotTacere4b') AND RECCOUNT('crsLotTacere4b') = 1
		SELECT crsLotTacere4b
		LOCATE FOR cui = 1000012
		llOk4b = FOUND() AND ALLTRIM(sursa) == 'CACHE_INDISP' AND ALLTRIM(denumire) == 'ETA TACERE CACHE SRL' AND !EMPTY(data_sursa)
	ENDIF
	IF llOk4b
		DO VerificaTrece WITH 'tacere-cu-istoric-distinct-de-notfound', 'CUI cu istoric la tacere -> 1 rand, sursa=CACHE_INDISP, denumire din istoric - distinct de notFound (sursa=ANAF, scenariul 3) si de tacere fara istoric (0 randuri, scenariul 4)'
	ELSE
		DO VerificaCade WITH 'tacere-cu-istoric-distinct-de-notfound', 'randul CACHE_INDISP asteptat nu a aparut corect (used=' + TRANSFORM(USED('crsLotTacere4b')) + ')'
	ENDIF
	gcANAFBatchScenariu = 'NORMAL'

	*=========================================================================
	* Scenariul 5: RASPUNS NEINTELES - raspuns primit dar nu porneste cu '{' (corp
	* nevalid); acelasi efect ca tacerea (cursor gol via RECCOUNT=0), dar cod de
	* scenariu distinct. CONTRACT NOU (dupa S6): vezi Scenariul 4.
	*=========================================================================
	gcANAFBatchScenariu = 'RASPUNS_NEINTELES'

	IF USED('crsLotTacere')
		USE IN crsLotTacere
	ENDIF
	gnANAFBatchApeluri = 0
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotTacere', DATE(), 'crsLotTacere')

	IF USED('crsLotTacere') AND RECCOUNT('crsLotTacere') = 0 AND gnANAFBatchApeluri = 1
		DO VerificaTrece WITH 'raspuns-neinteles', 'cursor creat dar gol (Reccount=0, scenariu distinct de tacere, acelasi efect) - contract nou S6'
	ELSE
		DO VerificaCade WITH 'raspuns-neinteles', 'cursor/randuri neasteptate (used=' + TRANSFORM(USED('crsLotTacere')) + ' reccount=' + TRANSFORM(IIF(USED('crsLotTacere'), RECCOUNT('crsLotTacere'), -1)) + ')'
	ENDIF
	gcANAFBatchScenariu = 'NORMAL'

	*=========================================================================
	* Scenariul 6: HTTP 404 cu corp COMPLET {"found":[],"notFound":[<cui>]} -
	* AZI corpul e ignorat (gate "Status = 200", validare.prg:1968); cu
	* glANAFBatchIgnoraGate404 = .T. se simuleaza fixul propus pentru S5
	*=========================================================================
	goANAFBatchMock = CREATEOBJECT('Collection')
	LOCAL loR404
	loR404 = CREATEOBJECT('Empty')
	ADDPROPERTY(loR404, 'denumire', 'ZETA 404 SRL')
	goANAFBatchMock.Add(loR404, 'C1000010')
	goANAFBatchMock.Add('NOTFOUND', 'C1000011')

	IF USED('cLot404')
		USE IN cLot404
	ENDIF
	CREATE CURSOR cLot404 (cod_fiscal C(30))
	INSERT INTO cLot404 (cod_fiscal) VALUES ('1000010')
	INSERT INTO cLot404 (cod_fiscal) VALUES ('1000011')

	gcANAFBatchScenariu = 'HTTP404_CORP_COMPLET'
	glANAFBatchIgnoraGate404 = .F.
	IF USED('crsLot404')
		USE IN crsLot404
	ENDIF
	lcRezAlias = goMockANAF.VerificaListaCIF('cLot404', DATE(), 'crsLot404')
	LOCAL llOk6a
	*-- contract nou S6: cursor creat dar gol (0 randuri, 1000010/1000011 fara istoric), nu absent
	llOk6a = USED('crsLot404') AND RECCOUNT('crsLot404') = 0

	glANAFBatchIgnoraGate404 = .T.
	IF USED('crsLot404')
		USE IN crsLot404
	ENDIF
	lcRezAlias = goMockANAF.VerificaListaCIF('cLot404', DATE(), 'crsLot404')
	LOCAL llOk6b
	llOk6b = USED('crsLot404') AND RECCOUNT('crsLot404') = 2

	IF m.llOk6a AND m.llOk6b
		DO VerificaTrece WITH 'http-404-corp-complet', 'gate AZI ignora corpul (0 randuri); cu glANAFBatchIgnoraGate404=.T. (fixture S5) parseaza 2 randuri'
	ELSE
		DO VerificaCade WITH 'http-404-corp-complet', 'gate-azi=' + TRANSFORM(m.llOk6a) + ' fixture-viitor=' + TRANSFORM(m.llOk6b)
	ENDIF
	gcANAFBatchScenariu = 'NORMAL'
	glANAFBatchIgnoraGate404 = .F.

	*=========================================================================
	* Scenariul 7: GRUPURI MULTIPLE (>100 coduri) - 101 CUI-uri intr-un singur apel
	* -> 2 grupuri (100 + 1); primul override 'TACERE' pe grupul 2 (S4: acumulare in
	* cursor pe mai multe grupuri, dar contorul de apeluri/cuiuri numara AMBELE grupuri
	* chiar daca al doilea nu produce randuri)
	*=========================================================================
	goANAFBatchMock = CREATEOBJECT('Collection')
	LOCAL lnG, lcCuiG, loRG
	FOR lnG = 1 TO 101
		lcCuiG = TRANSFORM(2000000 + lnG)
		loRG = CREATEOBJECT('Empty')
		ADDPROPERTY(loRG, 'denumire', 'GRUP TEST ' + lcCuiG)
		goANAFBatchMock.Add(loRG, 'C' + lcCuiG)
	ENDFOR

	IF USED('cLotGrupuri')
		USE IN cLotGrupuri
	ENDIF
	CREATE CURSOR cLotGrupuri (cod_fiscal C(30))
	FOR lnG = 1 TO 101
		INSERT INTO cLotGrupuri (cod_fiscal) VALUES (TRANSFORM(2000000 + lnG))
	ENDFOR

	goANAFBatchScenariuPerGrup = CREATEOBJECT('Collection')
	goANAFBatchScenariuPerGrup.Add('TACERE', '2')

	IF USED('crsLotGrupuri')
		USE IN crsLotGrupuri
	ENDIF
	gnANAFBatchApeluri = 0
	gcANAFBatchCuiuriTrimise = ''
	lcRezAlias = goMockANAF.VerificaListaCIF('cLotGrupuri', DATE(), 'crsLotGrupuri')

	LOCAL lnCuiuriTrimise
	lnCuiuriTrimise = GETWORDCOUNT(gcANAFBatchCuiuriTrimise, ',')
	IF USED('crsLotGrupuri') AND RECCOUNT('crsLotGrupuri') = 100 AND gnANAFBatchApeluri = 2 AND lnCuiuriTrimise = 101
		DO VerificaTrece WITH 'grupuri-multiple', '2 grupuri trimise (apeluri=2, cuiuri=101), doar grupul 1 (100) a produs randuri - grupul 2 (TACERE) nu'
	ELSE
		DO VerificaCade WITH 'grupuri-multiple', 'randuri=' + TRANSFORM(IIF(USED('crsLotGrupuri'), RECCOUNT('crsLotGrupuri'), -1)) + ' apeluri=' + TRANSFORM(gnANAFBatchApeluri) + ' cuiuri=' + TRANSFORM(lnCuiuriTrimise)
	ENDIF
	goANAFBatchScenariuPerGrup = CREATEOBJECT('Collection')

	*=========================================================================
	* Scenariul 8: E4 chiar a scris in ISTORIC_CODURI_FISCALE - foloseste randurile
	* lasate de Scenariul 1 (lot-complet, CUI 1000001/1000002/1000003), scrise de
	* VerificaListaCIF -> SalveazaIstoricDinCursor (validare.prg:1875-1877). Verifica
	* atat numarul de randuri cat si ca DATAORAV_ANAF (nu DATAORAV) s-a pus pe azi -
	* semnul ca apelul a adus efectiv date de interval (contract-cache-anaf.md 2.3). ATENTIE:
	* DATAORAV_ANAF se pune DOAR cand cel putin una din cele 9 date de interval e trimisa, NU
	* la simplele flag-uri booleene inactiv/tvaincasare/splittva (decizie S1, motivata in
	* docs\diff-S1-oracle-istoric.md ~93-102) - de-asta CUI 1000003 (splitTva/tvaIncasare) are
	* si cate o data de inceput in fixture-ul Scenariului 1, nu doar flag-urile goale.
	*=========================================================================
	LOCAL lnIstoricOk
	lnIstoricOk = 0
	=goExecutor.oSelect2Value([SELECT COUNT(*) AS NR FROM ISTORIC_CODURI_FISCALE ] + ;
		[WHERE DATAORAV_ANAF IS NOT NULL AND TRUNC(DATAORAV_ANAF) = TRUNC(SYSDATE) AND ( ] + ;
		[  (COD_FISCAL_N = 1000001 AND NVL(INACTIV,0) = 0) ] + ;
		[  OR (COD_FISCAL_N = 1000002 AND NVL(INACTIV,0) = 1) ] + ;
		[  OR (COD_FISCAL_N = 1000003 AND NVL(SPLITTVA,0) = 1 AND NVL(TVAINCASARE,0) = 1) )], @lnIstoricOk)
	IF m.lnIstoricOk = 3
		DO VerificaTrece WITH 'e4-scriere-istoric', '3 randuri in ISTORIC_CODURI_FISCALE cu DATAORAV_ANAF=azi si flag-urile corecte (inactiv/splittva/tvaincasare)'
	ELSE
		DO VerificaCade WITH 'e4-scriere-istoric', 'randuri gasite=' + TRANSFORM(m.lnIstoricOk) + ' (asteptat 3)'
	ENDIF

	DO WriteTestLog WITH 'GATA - ' + TRANSFORM(gnTestOk) + '/' + TRANSFORM(gnTestTotal) + ' scenarii PASS'

CATCH TO loExc
	DO WriteTestLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'

FINALLY
	*-- curatenie si la FINAL (inclusiv dupa o eventuala eroare) - fara ea, fiecare
	*-- rulare acumuleaza randuri noi in ISTORIC_CODURI_FISCALE (raportat de team-lead,
	*-- 110 randuri ramase dupa o singura rulare de regresie S5).
	DO CurataIstoricTest
ENDTRY

QUIT

*==================================================================================
PROCEDURE VerificaTrece
	LPARAMETERS tcScenariu, tcDetaliu
	gnTestTotal = gnTestTotal + 1
	gnTestOk = gnTestOk + 1
	DO WriteTestLog WITH 'PASS ' + tcScenariu + ': ' + tcDetaliu
ENDPROC

PROCEDURE VerificaCade
	LPARAMETERS tcScenariu, tcDetaliu
	gnTestTotal = gnTestTotal + 1
	DO WriteTestLog WITH 'FAIL ' + tcScenariu + ': ' + tcDetaliu
ENDPROC

PROCEDURE WriteTestLog
	LPARAMETERS tcMesaj
	STRTOFILE(TTOC(DATETIME()) + ' ' + tcMesaj + CHR(13)+CHR(10), gcTestLog, 1)
ENDPROC

*-- sterge DOAR codurile de test proprii acestui fisier (1000001-1000099, 2000001-2000199) din
*-- ISTORIC_CODURI_FISCALE, scrise de SalveazaIstoricDinCursor (S4) la fiecare VerificaListaCIF.
*-- Fara CREATEOBJECT/ADDPROPERTY in interior - sigur ca PROCEDURE apelata prin DO (capcana l).
*-- Nu atinge 8000xxx/9000xxx (partener_anaf) sau alte coduri din alte suite.
PROCEDURE CurataIstoricTest
	LOCAL lnSterse
	*!* 01.08.2026 marius.mutu: watermark invalid - nu sterg nimic (fara el, DELETE ar lovi tot istoricul comun)
	IF TYPE('gnIdMaxIstoricTest') <> 'N' OR gnIdMaxIstoricTest <= 0
		DO WriteTestLog WITH 'CurataIstoricTest: SARIT - watermark invalid, nu sterg nimic'
		RETURN
	ENDIF
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	lnSterse = goExecutor.oExecuta([DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > ] + TRANSFORM(gnIdMaxIstoricTest) + [ AND ] + ;
		[((COD_FISCAL_N BETWEEN 1000000 AND 1000099) OR (COD_FISCAL_N BETWEEN 2000000 AND 2000199))])
	=goExecutor.oExecuta('COMMIT')
	DO WriteTestLog WITH 'CurataIstoricTest: sters=' + TRANSFORM(lnSterse)
ENDPROC

PROCEDURE VpaErr
	LPARAMETERS tnErr, tcMsg, tcProg, tnLine
	DO WriteTestLog WITH 'ON ERROR nEroare=' + TRANSFORM(tnErr) + ' mesaj=' + tcMsg + ' program=' + tcProg + ' linia=' + TRANSFORM(tnLine)
ENDPROC
