* test_verif_partener_anaf_v2_ui.prg
* Teste UI pentru verificarea ANAF la selectia partenerului - REVIZIA 2 (V2', 25.07.2026):
* verdict in formularul de cautare (label pe cauta_alfa_form), fara frm_verif_partener_anaf
* (eliminata). Vezi docs\design-alegere-partener-anaf.md sectiunea "REVIZIA 2".
* Testeaza clasele reale din COMUN\programe\ocautare.prg (anaf_verif_cautare/anaf_timer)
* atasate prin hook-ul generic din cauta_alfa.prg, instantiind DIRECT cauta_alfa_form (ca sa evit
* Show() modal al formularului de cautare - vezi capcana "Forme modale" din depanare_testare_vfp.md)
* si navigand grid-ul ca utilizatorul real (AfterRowColChange), nu populare directa de cursor -
* singura populare directa e sursa de date (cursorul RecordSource al gridului), ca in fluxul real
* caut_parteneri()/CautPartenerContabilitate() (SELECT din NOM_PARTENERI).
*
* Mock-uri (INFRASTRUCTURA, permise conform testare-ui-vfp.md): ANAF_VerificaCuiSingle (raspunsuri
* preconfigurate, fara apel real la anaf.ro) si amessagebox (dialogurile de detalii nu blocheaza).
* ANAF_CautaPereche NU se poate mock-ui (e definita SI apelata in ACELASI fisier ocautare.prg -
* rezolutia VFP foloseste versiunea locala indiferent de SET PROCEDURE) - perechile de test sunt
* randuri disposable REALE in NOM_PARTENERI (schema MARIUSM_AUTO), inserate/sterse de acest test.
*
* Date de test (disposable, identificate dupa COD_FISCAL - vezi nota ID_PART mai jos):
*   RO1112223      TEST ANAF CONCORD SRL   - concordant (ANAF platitor, are RO)
*   7654320        TEST ANAF DISCORD SRL   - discordant, ARE pereche (RO7654320, inactiva)
*   RO7654320      TEST ANAF DISCORD SRL   - perechea (INACTIVA), concordanta cu ANAF
*   9000004        TEST ANAF NOPERECHE SRL - discordant, FARA pereche
*   RO 7654320     TEST ANAF SPATIU SRL    - a doua varianta cu cod corect (cod scris cu spatiu)
*   1234567890128  TEST ANAF PERSFIZ       - CNP valid, persoana fizica - fara verificare ANAF
*   1234567890123  TEST ANAF CNP INVALID   - persoana fizica cu CNP invalid
*   1234567        TEST ANAF CIF INVALID   - persoana juridica cu CIF invalid
*   RO9000055      TEST ANAF CADERE SRL    - S5 (handoff_anaf_404.md): esec ANAF simulat, apoi verdict
*                                             normal dupa revenirea serviciului (gnIdCadere)
*   TEST NENUMERIC OIL MARKET SRL  TEST ANAF NENUMERIC SRL - cod fiscal nenumeric in loc de CIF, acelasi
*                                             tipar ca (dar NU acelasi text ca) cazul real FANALEX din
*                                             design-alegere-partener-anaf.md, gnIdNenumeric. ATENTIE: nu
*                                             refolosi textul EXACT "FANALEX OIL MARKET S.R.L." - coincide
*                                             cu un partener real preexistent in schema (ID_PART=2026,
*                                             STERS=0, cu randuri CORESP_TIP_PART reale) folosit la
*                                             investigatia initiala a bug-ului - un DELETE pe acel text
*                                             sterge date reale, nu de test (descoperit 27.07.2026).
*
* NOTA ID_PART: NOM_PARTENERI are trigger BEFORE INSERT (trg_NOM_PARTENERI_befoins) care
* SUPRASCRIE ID_PART cu seq_NOM_PARTENERI.nextval, indiferent de valoarea din INSERT - ID-urile
* nu pot fi alese explicit. Testul insereaza FARA ID_PART si citeste ID-ul real alocat dupa
* insert (dupa COD_FISCAL, care e sub controlul testului) - gnIdConcord/gnIdDiscord/gnIdPereche/
* gnIdNopereche/gnIdPersfiz/gnIdCadere/gnIdNenumeric (PUBLIC).
*
* Scenarii de decizie (RUNDA 11): dialogul propriu (anaf_dialog) a fost inlocuit cu AMESSAGEBOX
* tip 3+48 (Da/Nu/Abandon) si 1+48 (OK/Abandon) cand nu exista pereche. Raspunsul se impune prin
* mock_amessagebox.prg cu gnMockRaspuns (6 = Da, 7 = Nu, 2 = Abandon, 1 = OK), iar textul afisat
* se citeste din gcMockUltimMesaj/gnMockUltimTip - totul sincron, fara Show(1) modal si fara clicker.
*
* RUNDA 12: verificarea ANAF se face la DATA DOCUMENTULUI (proprietatea dDataDoc pe
* anaf_verif_cautare), cheia de cache pe sesiune e 'C'+CUI+'_'+Dtos(data), iar textele (label +
* dialoguri, metodele TextAnaf/AntetDialog/ListaCorecti) includ acum denumirea si codul de la
* ANAF plus data verificarii. Scenariile 11-13 (VerificaDataDocument/VerificaCacheData/
* VerificaDataFallback) acopera data documentului; mock_anaf_verificare.prg retine data primita
* in gdANAFUltimaData (PUBLIC, declarata mai jos).
*
* S12 (contract-cache-anaf.md, 31.07.2026): scenariile cache-ului ANAF pe ISTORIC_CODURI_FISCALE
* (plasa S9/ocautare.prg + helper-ele S3/validare.prg) - CUI-uri dedicate cu cifra de control CIF
* valida (8000090/8000197/8000294/8000391/8000499, gnIdCacheA/B/C/D/F)
* (gnIdCacheA/B/C/D/F), randuri de istoric inserate prin pack_parteneri.save_istoric_cod_fiscal
* (InsereazaIstoricTest); interogarile pe ISTORIC_CODURI_FISCALE se numara cu dummyexecutoristorictest
* (acelasi tipar ca dummyexecutorH2test), ca sa dovedeasca cand cache-ul e sarit sau folosit o singura data.

SET SAFETY OFF
SET TALK OFF
SET DELETED ON
SET EXACT ON
SET CENTURY ON
SET DATE DMY
SET NULLDISPLAY TO ''
CLOSE DATABASES

PUBLIC gcUILog, gcSyncDir
gcUILog  = "D:\ROA\ROACONT\COMUN\utile\Teste\partener_anaf\test_verif_partener_anaf_v2_ui_log.txt"
gcSyncDir = "D:\ROA\ROACONT\COMUN\utile\Teste\partener_anaf\uisync\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)

ON ERROR DO VpaErr WITH ERROR(), MESSAGE(), PROGRAM(), LINENO()
ON SHUTDOWN QUIT

*----- mock-uri INAINTE de test_init_env_auto (rezolutie "primul fisier cautat", capcana g) -----
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\mock_ainputbox.prg" ADDITIVE
SET PROCEDURE TO "D:\ROA\ROACONT\COMUN\utile\Teste\partener_anaf\mock_anaf_verificare.prg" ADDITIVE
DO VpaLog WITH 'mock-uri incarcate'

DO D:\ROA\ROACONT\COMUN\utile\Teste\test_init_env_auto.prg WITH 'CENTRAL', 'MARIUSM_AUTO', 'ROMFASTSOFT'
IF gnHandle <= 0
	DO VpaLog WITH 'EROARE: conectare Oracle esuata - GATA'
	DO HarnessDone WITH 'done-error'
	QUIT
ENDIF
DO VpaLog WITH 'mediu OK, schema=' + gcS

*!* 01.08.2026 marius.mutu: watermark pe ID, o singura data la inceput - garda pt toate DELETE-urile din ISTORIC_CODURI_FISCALE de mai jos
PUBLIC gnIdMaxIstoricV2UI
gnIdMaxIstoricV2UI = 0
IF goExecutor.oExecuta('SELECT NVL(MAX(ID),0) AS IDMAX FROM ISTORIC_CODURI_FISCALE', 'crsWmIstoricV2UI')
	SELECT crsWmIstoricV2UI
	GO TOP
	gnIdMaxIstoricV2UI = IDMAX
	USE IN (SELECT('crsWmIstoricV2UI'))
ENDIF
*!* 01.08.2026 marius.mutu: watermark invalid = SELECT esuat - avertisment explicit, stergerile se vor sari
IF gnIdMaxIstoricV2UI <= 0
	DO VpaLog WITH 'ATENTIE: watermark invalid (0) - stergerile din ISTORIC_CODURI_FISCALE vor fi SARITE'
ENDIF
DO VpaLog WITH 'watermark ISTORIC_CODURI_FISCALE id_max=' + TRANSFORM(gnIdMaxIstoricV2UI)

*-- RE-TEST RUNDA 10: fix aplicat in ocautare.prg (guard '_BAZA' eliminat, NewObject pe _label
*-- din _baza.vcx rezolvat pe SET PATH, cu fallback anaf_label) - FARA workaround de test, cale
*-- reala (Activeaza se apeleaza natural, fara SET CLASSLIB manual).

PUBLIC gnMockRaspuns, gcMockUltimMesaj, gnMockUltimTip
gnMockRaspuns = 6
gcMockUltimMesaj = ''
gnMockUltimTip = 0

*-- goANAFMockData/gnANAFCallCount + obiectele de raspuns ANAF: construite INLINE in programul
*-- principal (nu intr-o PROCEDURE) - vezi capcana l, depanare_testare_vfp.md, si antetul
*-- mock_anaf_verificare.prg. Cheia e 'C' + CUI normalizat (fara RO).
PUBLIC goANAFMockData, gnANAFCallCount, gdANAFUltimaData
goANAFMockData = CREATEOBJECT('Collection')
gnANAFCallCount = 0
gdANAFUltimaData = {}
LOCAL loRespConcord, loRespDiscord, loRespNoPereche
loRespConcord = CREATEOBJECT('Empty')
ADDPROPERTY(loRespConcord, 'cui', '1112223')
ADDPROPERTY(loRespConcord, 'scpTVA', .T.)
ADDPROPERTY(loRespConcord, 'statusInactivi', .F.)
ADDPROPERTY(loRespConcord, 'denumire', 'CONCORD SRL ANAF')
ADDPROPERTY(loRespConcord, 'mesaj', '')
goANAFMockData.Add(loRespConcord, 'C1112223')
loRespDiscord = CREATEOBJECT('Empty')
ADDPROPERTY(loRespDiscord, 'cui', '7654320')
ADDPROPERTY(loRespDiscord, 'scpTVA', .T.)
ADDPROPERTY(loRespDiscord, 'statusInactivi', .F.)
ADDPROPERTY(loRespDiscord, 'denumire', 'DISCORD SRL ANAF')
ADDPROPERTY(loRespDiscord, 'mesaj', '')
goANAFMockData.Add(loRespDiscord, 'C7654320')
loRespNoPereche = CREATEOBJECT('Empty')
ADDPROPERTY(loRespNoPereche, 'cui', '9000004')
ADDPROPERTY(loRespNoPereche, 'scpTVA', .T.)
ADDPROPERTY(loRespNoPereche, 'statusInactivi', .F.)
ADDPROPERTY(loRespNoPereche, 'denumire', 'NOPERECHE SRL ANAF')
ADDPROPERTY(loRespNoPereche, 'mesaj', '')
goANAFMockData.Add(loRespNoPereche, 'C9000004')
LOCAL loRespInactiv
loRespInactiv = CREATEOBJECT('Empty')
ADDPROPERTY(loRespInactiv, 'cui', '9000012')
ADDPROPERTY(loRespInactiv, 'scpTVA', .F.)
ADDPROPERTY(loRespInactiv, 'statusInactivi', .T.)
ADDPROPERTY(loRespInactiv, 'denumire', 'INACTIV SRL ANAF')
ADDPROPERTY(loRespInactiv, 'mesaj', '')
goANAFMockData.Add(loRespInactiv, 'C9000012')
DO VpaLog WITH 'mock ANAF: 4 CUI-uri configurate (1112223, 7654320, 9000004, 9000012)'

*-- T5/sonda (handoff_anaf_404.md): Activeaza() porneste sonda REALA (ANAF_SondaPorneste, validare.prg)
*-- ori de cate ori starea e NECUNOSCUT - fara mock ar insemna apel HTTP real la fiecare test. Mod 'AUTO'
*-- (implicit): sonda "raspunde" instant cu succes la primul ANAF_SondaVerifica() - transparent pentru
*-- toate scenariile vechi (AsteaptaTimer cheama acum ANAF_SondaVerifica() inainte de VerificaRand, ca
*-- anaf_timer.Timer). Mod 'MANUAL': S2/S3/S4 controleaza explicit gcMockSondaGataManual/ReusitaManual.
PUBLIC gcMockSondaModo, glMockSondaActiva, gnMockSondaPornireCount, glMockSondaGataManual, glMockSondaReusitaManual
gcMockSondaModo = 'AUTO'
glMockSondaActiva = .F.
gnMockSondaPornireCount = 0
glMockSondaGataManual = .F.
glMockSondaReusitaManual = .T.

PUBLIC gnIdConcord, gnIdDiscord, gnIdPereche, gnIdNopereche, gnIdPersfiz, gnIdSpatiu, gnIdInactiv, gnIdInexistent
PUBLIC gnIdCnpInv, gnIdCifInv, gnMockInputBox, gnMockInputCount, gcMockUltimPrompt, gcMockInputSecventa
PUBLIC gnIdCadere, gnIdNenumeric
PUBLIC gnIdCacheA, gnIdCacheB, gnIdCacheC, gnIdCacheD, gnIdCacheF
gnMockInputBox = 1
gnMockInputCount = 0
gcMockUltimPrompt = ''
gcMockInputSecventa = ''

TRY
	DO CurataDateTest
	DO CreeazaDateTest

	*=========================================================================
	* Scenariul 1: label CONCORDANT (verde, fara bold) pe randul concordant
	*=========================================================================
	DO PornesteCautare
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdConcord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	DO VerificaLabelConcordant

	DO HarnessStep WITH 0, 'Scenariul 1 concordant: [' + ALLTRIM(goFormT.lb_anaf.Caption) + ']'

	*=========================================================================
	* Scenariul 2: label DISCORDANT (rosu, fara bold) pe randul discordant cu pereche
	*=========================================================================
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	DO VerificaLabelDiscordant

	DO HarnessStep WITH 1, 'Scenariul 2 discordant: [' + ALLTRIM(goFormT.lb_anaf.Caption) + ']'

	*=========================================================================
	* Scenariul 2b (runda 15): cod fiscal invalid - persoana juridica cu CIF invalid,
	* persoana fizica cu CNP invalid (rosu, fara apel ANAF); CNP valid = fara label
	*=========================================================================
	DO VerificaCodInvalid

	*=========================================================================
	* Scenariul 3: debounce - navigare rapida prin 3 randuri, ZERO apeluri ANAF
	* pana nu se opreste pe unul (timer 400ms nu apuca sa se declanseze intre randuri)
	*=========================================================================
	DO VerificaDebounce

	*=========================================================================
	* Scenariul 4: cache - a doua selectie pe ACELASI CUI (alt formular nou),
	* in aceeasi sesiune VFP, ZERO apel ANAF nou (goCacheANAF_Sesiune e global pe sesiune)
	*=========================================================================
	DO VerificaCache

	*=========================================================================
	* Scenariul 5: click pe label -> AMESSAGEBOX cu detalii (format numerotat)
	*=========================================================================
	DO VerificaDetalii

	*=========================================================================
	* Scenariul 6: alegere rapida (D2) - inainte sa expire timerul, verificarea
	* se face SINCRON la VerificaAlegere (nu asteapta timerul)
	*=========================================================================
	DO VerificaAlegereRapidaD2

	*=========================================================================
	* Scenariul 7: kill-switch [anaf] verificare_selectie=0 -> fara label, fara apel ANAF
	*=========================================================================
	DO VerificaKillSwitch

	*=========================================================================
	* Scenariul 8: regresie - cautare NON-partener (fara oVerifAlegere atasat):
	* fara label, inaltime formular NESCHIMBATA, zero impact
	*=========================================================================
	DO VerificaRegresieNonPartener

	IF USED('ctestparteneri')
		USE IN ctestparteneri
	ENDIF
	IF VARTYPE(goFormT) = 'O'
		TRY
			goFormT.oVerifAlegere.Dezactiveaza()
			DO VpaLog WITH 'PASS Dezactiveaza (goFormT): fara eroare (Unbindevents 1-argument, fix runda 10)'
		CATCH TO loExcDez1
			DO VpaLog WITH 'FAIL Dezactiveaza (goFormT): ' + loExcDez1.Message
		ENDTRY
		goFormT.Release()
	ENDIF

	*=========================================================================
	* Scenariul 9 (runda 11): TEXTUL mesajului de decizie - 3 linii scurte
	* (denumire+CUI+ID / verdict ANAF / lista candidatilor) si tipul 3+48 (Da/Nu/Abandon).
	*=========================================================================
	DO VerificaMesajDecizie
	DO HarnessStep WITH 2, 'Mesaj decizie ANAF verificat'

	*=========================================================================
	* Scenariul 10: VerificaAlegere END-TO-END prin AMESSAGEBOX (mock, gnMockRaspuns):
	* 6 = Da (pastreaza selectia), 7 = Nu (prima alternativa), 2 = Abandon (inapoi la cautare).
	*=========================================================================
	DO VerificaAlegereD1aButonPereche
	DO VerificaAlegereD1aButonAles
	DO VerificaAlegereD1aRenunta
	DO VerificaAlegereFaraPereche
	DO HarnessStep WITH 3, 'Scenariile de decizie 6/7/2 executate'

	*=========================================================================
	* Scenariul 10b (runda 15): cu MAI MULTE variante, "Da" cere numarul variantei
	* (numar invalid -> revine la mesaj); cu O SINGURA varianta nu se mai cere nimic
	*=========================================================================
	DO VerificaAlegereVarianta

	*=========================================================================
	* Scenariul 11 (runda 12): data documentului (dDataDoc) ajunge la wrapper ANAF
	* si apare in textul labelului ("... la <data>")
	*=========================================================================
	DO VerificaDataDocument

	*=========================================================================
	* Scenariul 12 (runda 12): cheia de cache pe sesiune include data - acelasi CUI
	* la 2 date diferite => 2 apeluri, acelasi CUI la ACEEASI data => 1 apel (cache-hit)
	*=========================================================================
	DO VerificaCacheData

	*=========================================================================
	* Scenariul 13 (runda 12): fara data documentului (dDataDoc gol) => se foloseste Date()
	*=========================================================================
	DO VerificaDataFallback

	*=========================================================================
	* Scenariul 14 (runda 14): fara dDataDoc, dar cu poAct in stiva (formular de
	* introduceri) => se foloseste poAct.dataact, nu Date()
	*=========================================================================
	DO VerificaDataPoAct

	*=========================================================================
	* Scenariile REVIZIA 4 (runda 17): cascada RC_ANAF_VERIF_SELECTIE, gating pe nivel,
	* C2 (Renunta), H2 (eroare lista), Detalii cu oStare Null, discriminator documente,
	* B1 (label golit), comutare optiune (meniu)
	*=========================================================================
	DO RuleazaIzolat WITH 'VerificaCascadaOptiuni'
	DO RuleazaIzolat WITH 'VerificaGatingNivel'
	DO RuleazaIzolat WITH 'VerificaC2Renunta'
	DO RuleazaIzolat WITH 'VerificaH2EroareListaCorecti'
	DO RuleazaIzolat WITH 'VerificaDetaliiStareNula'
	DO RuleazaIzolat WITH 'VerificaDiscriminatorDocumente'
	DO RuleazaIzolat WITH 'VerificaB1LabelGolit'
	DO RuleazaIzolat WITH 'VerificaComutareOptiune'
	DO RuleazaIzolat WITH 'VerificaInactivCodCorect'
	DO RuleazaIzolat WITH 'VerificaCodInexistentANAF'

	*=========================================================================
	* Scenariile T7 (handoff_anaf_404.md / plan-reparatie-anaf-404-breaker.md): intrerupatorul de
	* disponibilitate ANAF (S1, S5, S6) si codul fiscal nenumeric (P8)
	*=========================================================================
	DO RuleazaIzolat WITH 'VerificaStareCazutaZeroApeluri'
	DO RuleazaIzolat WITH 'VerificaBandaCazutDistinctaDePrompt'
	DO RuleazaIzolat WITH 'VerificaEsecNuSeCacheaza'
	DO RuleazaIzolat WITH 'VerificaCodNenumeric'
	DO RuleazaIzolat WITH 'VerificaFixtureContract404'
	DO RuleazaIzolat WITH 'VerificaSondaInAer'
	DO RuleazaIzolat WITH 'VerificaSondaReuseste'
	DO RuleazaIzolat WITH 'VerificaSondaExpira'

	*=========================================================================
	* Scenariile S12 (contract-cache-anaf.md): cache-ul ANAF pe ISTORIC_CODURI_FISCALE, prin
	* plasa de siguranta din ocautare.prg (S9) si helper-ele din validare.prg (S3)
	*=========================================================================
	DO RuleazaIzolat WITH 'VerificaCacheIndispIstoricPopulat'
	DO RuleazaIzolat WITH 'VerificaCacheIndispIstoricGol'
	DO RuleazaIzolat WITH 'VerificaCacheIndispIstoricVechi'
	DO RuleazaIzolat WITH 'VerificaCodInexistentNuAtingeCache'
	DO RuleazaIzolat WITH 'VerificaSeTesteazaNuAtingeCache'
	DO RuleazaIzolat WITH 'VerificaOrdineCacheAnafSarit'

	DO VpaLog WITH 'GATA - toate scenariile executate'
	DO HarnessStep WITH 4, 'toate scenariile executate'
	DO HarnessDone WITH 'done'

CATCH TO loExc
	DO VpaLog WITH 'CATCH ErrorNo=' + TRANSFORM(loExc.ErrorNo) + ' Message=' + loExc.Message + ' Proc=' + loExc.Procedure + ' Line=' + TRANSFORM(loExc.LineNo) + ' [' + loExc.LineContents + ']'
	DO HarnessDone WITH 'done-error'
FINALLY
	DO CurataDateTest
ENDTRY

QUIT

*==================================================================================
PROCEDURE CurataDateTest
	*-- CORESP_TIP_PART are FK_CORESP_TIP_PART_001 catre NOM_PARTENERI - copilul se sterge inaintea
	*-- parintelui (ORA-02292), aceeasi lista de coduri in ambele instructiuni (lcCoduri).
	LOCAL lnOk, lnOkCoresp, lcCoduri, lnOkIstoric
	lcCoduri = ['RO1112223','7654320','RO7654320','RO 7654320','9000004','9000012','9000039','1234567890128','1234567890123','1234567','RO9000055','TEST NENUMERIC OIL MARKET SRL','8000090','8000197','8000294','8000391','8000499']
	lnOkCoresp = goExecutor.oExecuta([DELETE FROM CORESP_TIP_PART WHERE ID_PART IN (SELECT ID_PART FROM NOM_PARTENERI WHERE COD_FISCAL IN (] + m.lcCoduri + [))])
	lnOk = goExecutor.oExecuta([DELETE FROM NOM_PARTENERI WHERE COD_FISCAL IN (] + m.lcCoduri + [)])
	*-- S12: randuri de istoric ale scenariilor de cache (9000039 e reutilizat de scenariul 4, testul lui isi
	*-- insereaza propriul rand pt. CUI-ul existent gnIdInexistent) - plasa de siguranta, fiecare scenariu isi
	*-- sterge deja randul propriu la final, dar CurataDateTest acopera si opririle premature (CATCH/FINALLY).
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark, prin StergeIstoricV2UI (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	lnOkIstoric = StergeIstoricV2UI("COD_FISCAL IN ('8000090','8000197','8000294','8000391','8000499','9000039')")
	DO VpaLog WITH 'CurataDateTest: sters coresp_tip_part=' + TRANSFORM(m.lnOkCoresp) + ' nom_parteneri=' + TRANSFORM(m.lnOk) + ' istoric_coduri_fiscale=' + TRANSFORM(m.lnOkIstoric)
ENDPROC

*!* 01.08.2026 marius.mutu: helper unic pt DELETE-urile din ISTORIC_CODURI_FISCALE - garda watermark o singura data
PROCEDURE StergeIstoricV2UI
	LPARAMETERS tcCondCod
	LOCAL lnOkD
	IF TYPE('gnIdMaxIstoricV2UI') <> 'N' OR gnIdMaxIstoricV2UI <= 0
		DO VpaLog WITH 'StergeIstoricV2UI: SARIT - watermark invalid, nu sterg nimic (' + m.tcCondCod + ')'
		RETURN 0
	ENDIF
	lnOkD = goExecutor.oExecuta("DELETE FROM ISTORIC_CODURI_FISCALE WHERE ID > " + TRANSFORM(gnIdMaxIstoricV2UI) + " AND " + m.tcCondCod)
	=goExecutor.oExecuta('COMMIT')
	RETURN lnOkD
ENDPROC

PROCEDURE CreeazaDateTest
	*-- FARA ID_PART in INSERT: trigger BEFORE INSERT (trg_NOM_PARTENERI_befoins) suprascrie
	*-- oricum cu seq_NOM_PARTENERI.nextval - ID-urile reale se citesc dupa, pe COD_FISCAL.
	LOCAL lcIns
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CONCORD SRL','TEST ANAF CONCORD SRL','RO1112223',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF DISCORD SRL','TEST ANAF DISCORD SRL','7654320',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF DISCORD SRL','TEST ANAF DISCORD SRL','RO7654320',0,0,1,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF SPATIU SRL','TEST ANAF SPATIU SRL','RO 7654320',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF NOPERECHE SRL','TEST ANAF NOPERECHE SRL','9000004',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF INACTIV SRL','TEST ANAF INACTIV SRL','9000012',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF INEXISTENT SRL','TEST ANAF INEXISTENT SRL','9000039',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF PERSFIZ','TEST ANAF PERSFIZ','1234567890128',0,0,0,2,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CNP INVALID','TEST ANAF CNP INVALID','1234567890123',0,0,0,2,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CIF INVALID SRL','TEST ANAF CIF INVALID SRL','1234567',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CADERE SRL','TEST ANAF CADERE SRL','RO9000055',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF NENUMERIC SRL','TEST ANAF NENUMERIC SRL','TEST NENUMERIC OIL MARKET SRL',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	*-- S12: parteneri disposable pt. scenariile de cache (istoric ANAF pe ISTORIC_CODURI_FISCALE)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CACHE A SRL','TEST ANAF CACHE A SRL','8000090',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CACHE B SRL','TEST ANAF CACHE B SRL','8000197',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CACHE C SRL','TEST ANAF CACHE C SRL','8000294',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CACHE D SRL','TEST ANAF CACHE D SRL','8000391',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	lcIns = [INSERT INTO NOM_PARTENERI (NUME,DENUMIRE,COD_FISCAL,STERS,ID_MOD,INACTIV,TIP_PERSOANA,INSTITUTIE_PUBLICA,ENTITATE_AFILIATA) VALUES ] + ;
		[('TEST ANAF CACHE F SRL','TEST ANAF CACHE F SRL','8000499',0,0,0,1,0,0)]
	=goExecutor.oExecuta(m.lcIns)
	=goExecutor.oExecuta('COMMIT')

	gnIdConcord = 0
	gnIdDiscord = 0
	gnIdPereche = 0
	gnIdNopereche = 0
	gnIdInactiv = 0
	gnIdInexistent = 0
	gnIdPersfiz = 0
	gnIdSpatiu = 0
	gnIdCnpInv = 0
	gnIdCifInv = 0
	gnIdCadere = 0
	gnIdNenumeric = 0
	gnIdCacheA = 0
	gnIdCacheB = 0
	gnIdCacheC = 0
	gnIdCacheD = 0
	gnIdCacheF = 0
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = 'RO 7654320'], @gnIdSpatiu)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = 'RO1112223'], @gnIdConcord)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '7654320'], @gnIdDiscord)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = 'RO7654320'], @gnIdPereche)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '9000004'], @gnIdNopereche)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '9000012'], @gnIdInactiv)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '9000039'], @gnIdInexistent)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '1234567890128'], @gnIdPersfiz)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '1234567890123'], @gnIdCnpInv)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '1234567'], @gnIdCifInv)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = 'RO9000055'], @gnIdCadere)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = 'TEST NENUMERIC OIL MARKET SRL'], @gnIdNenumeric)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '8000090'], @gnIdCacheA)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '8000197'], @gnIdCacheB)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '8000294'], @gnIdCacheC)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '8000391'], @gnIdCacheD)
	=goExecutor.oSelect2Value([SELECT ID_PART AS NR FROM NOM_PARTENERI WHERE COD_FISCAL = '8000499'], @gnIdCacheF)
	DO VpaLog WITH 'CreeazaDateTest: id-uri alocate concord=' + TRANSFORM(gnIdConcord) + ' discord=' + TRANSFORM(gnIdDiscord) + ;
		' pereche=' + TRANSFORM(gnIdPereche) + ' spatiu=' + TRANSFORM(gnIdSpatiu) + ;
		' nopereche=' + TRANSFORM(gnIdNopereche) + ' persfiz=' + TRANSFORM(gnIdPersfiz) + ;
		' cadere=' + TRANSFORM(gnIdCadere) + ' nenumeric=' + TRANSFORM(gnIdNenumeric) + ;
		' cacheA=' + TRANSFORM(gnIdCacheA) + ' cacheB=' + TRANSFORM(gnIdCacheB) + ' cacheC=' + TRANSFORM(gnIdCacheC) + ;
		' cacheD=' + TRANSFORM(gnIdCacheD) + ' cacheF=' + TRANSFORM(gnIdCacheF)
ENDPROC

PROCEDURE PornesteCautare
	*-- replica exact structura cursorului produs de caut_parteneri() (denumire, nume,
	*-- cod_fiscal, id_part, inactiv), populat REAL din NOM_PARTENERI (nu valori inventate).
	LOCAL lnOk
	IF USED('ctestparteneri')
		USE IN ctestparteneri
	ENDIF
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV, TIP_PERSOANA FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART IN (] + TRANSFORM(gnIdConcord) + [,] + TRANSFORM(gnIdDiscord) + [,] + TRANSFORM(gnIdPereche) + [,] + ;
		TRANSFORM(gnIdNopereche) + [,] + TRANSFORM(gnIdPersfiz) + [,] + TRANSFORM(gnIdCnpInv) + [,] + TRANSFORM(gnIdCifInv) + ;
		[) AND INACTIV = 0 ORDER BY ID_PART], 'ctestparteneri')
	IF m.lnOk < 0
		DO VpaLog WITH 'FAIL PornesteCautare: query esuat - ' + goExecutor.cEroare
		RETURN
	ENDIF

	PUBLIC goFormT, poVerifAlegere
	goFormT = CREATEOBJECT('cauta_alfa_form', 'ctestparteneri', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	goFormT.crs_cursor = 'ctestparteneri'
	goFormT.Lb_titlu_alb_b121.Caption = 'Test ANAF'
	goFormT.lAles = .F.
	goFormT.cIdColumn = 'id_part'

	PRIVATE lnInaltimeInitiala
	lnInaltimeInitiala = goFormT.Height

	poVerifAlegere = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(goFormT, 'oVerifAlegere', poVerifAlegere)
	poVerifAlegere.Activeaza(goFormT)

	goFormT.WindowType = 0
	goFormT.Show()
	DOEVENTS FORCE

	*-- labelul primeste banda lui proprie sub grid: forma creste cu 54, iar banda are fundal propriu
	IF VARTYPE(goFormT.lb_anaf) = 'O' AND goFormT.Height = m.lnInaltimeInitiala + 54 ;
			AND goFormT.lb_anaf.Anchor = 14 AND goFormT.lb_anaf.BackStyle = 1
		DO VpaLog WITH 'PASS activare: lb_anaf creat in banda proprie, forma marita cu 54px (inaltime=' + TRANSFORM(goFormT.Height) + ')'
	ELSE
		DO VpaLog WITH 'FAIL activare: lb_anaf tip=' + TRANSFORM(VARTYPE(goFormT.lb_anaf)) + ' inaltime=' + TRANSFORM(goFormT.Height) + ;
			' (initiala=' + TRANSFORM(m.lnInaltimeInitiala) + ')'
	ENDIF

	*-- RUNDA 11: geometria label-ului DUPA Show() - bug-ul live era ca Anchor setat inainte de Top
	*-- il readucea sus peste banda de titlu, iar gridul (Anchor=15) se intindea de doua ori.
	IF VARTYPE(goFormT.lb_anaf) = 'O'
		IF goFormT.lb_anaf.Top >= goFormT._GRID1.Top + goFormT._GRID1.Height ;
				AND goFormT.lb_anaf.Top + goFormT.lb_anaf.Height <= goFormT.Height ;
				AND goFormT.lb_anaf.Top > 30
			DO VpaLog WITH 'PASS geometrie-label: lb_anaf sub grid si in forma (Top=' + TRANSFORM(goFormT.lb_anaf.Top) + ;
				' grid jos=' + TRANSFORM(goFormT._GRID1.Top + goFormT._GRID1.Height) + ' forma=' + TRANSFORM(goFormT.Height) + ')'
		ELSE
			DO VpaLog WITH 'FAIL geometrie-label: Top=' + TRANSFORM(goFormT.lb_anaf.Top) + ' inaltime label=' + TRANSFORM(goFormT.lb_anaf.Height) + ;
				' grid jos=' + TRANSFORM(goFormT._GRID1.Top + goFormT._GRID1.Height) + ' forma=' + TRANSFORM(goFormT.Height)
		ENDIF
	ENDIF
ENDPROC

PROCEDURE AsteaptaTimer
	LPARAMETERS toVerif
	*-- LIMITARE CONFIRMATA (vezi raport): Timer.Interval (anaf_timer, 400ms) NU se declanseaza
	*-- fiabil in acest runtime headless prin DOEVENTS FORCE + INKEY in bucla (testat: 1.5s asteptare,
	*-- 0 apeluri) - WM_TIMER pare sa ceara o bucla de mesaje continua (READ EVENTS / Show(1) modal
	*-- intern), nu pompari discrete. Apel DIRECT VerificaRand(.F.) - echivalent functional cu
	*-- "timerul s-a declansat" - ca sa testez restul logicii (verdict/cache/dialog). Debounce-ul
	*-- PROPRIU-ZIS (timerul reseteaza la fiecare navigare) e verificat separat, fara acest apel.
	*-- T5/sonda: ANAF_SondaVerifica() INAINTE de VerificaRand, exact ca anaf_timer.Timer (ocautare.prg) -
	*-- altfel o sonda pornita de Activeaza() (stare NECUNOSCUT) n-ar mai fi rezolvata niciodata in acest
	*-- runtime headless si ar bloca toate scenariile vechi in banda "se verifica...".
	LOCAL loV
	loV = IIF(VARTYPE(m.toVerif) = 'O', m.toVerif, poVerifAlegere)
	ANAF_SondaVerifica()
	IF VARTYPE(m.loV) = 'O'
		m.loV.VerificaRand(.F.)
	ENDIF
	DOEVENTS FORCE
ENDPROC

PROCEDURE VerificaLabelConcordant
	*-- runda 17 (B2): textul spune acum "F4 = detalii" (nu "click detalii"); bold doar la avertisment.
	LOCAL lcCap
	lcCap = ALLTRIM(goFormT.lb_anaf.Caption)
	IF 'ANAF:' $ m.lcCap AND 'F4 = detalii' $ m.lcCap AND goFormT.lb_anaf.ForeColor = RGB(0,128,0) AND !goFormT.lb_anaf.FontBold
		DO VpaLog WITH 'PASS label-concordant: [' + m.lcCap + '] verde, fara bold'
	ELSE
		DO VpaLog WITH 'FAIL label-concordant: [' + m.lcCap + '] ForeColor=' + TRANSFORM(goFormT.lb_anaf.ForeColor) + ' Bold=' + TRANSFORM(goFormT.lb_anaf.FontBold)
	ENDIF
ENDPROC

PROCEDURE VerificaLabelDiscordant
	*-- runda 17 (B2): discordanta e acum bold (SeteazaLabel: FontBold = tlAvertisment); text "F4 = detalii".
	LOCAL lcCap
	lcCap = ALLTRIM(goFormT.lb_anaf.Caption)
	IF 'ANAF:' $ m.lcCap AND 'F4 = detalii' $ m.lcCap AND goFormT.lb_anaf.ForeColor = RGB(192,0,0) AND goFormT.lb_anaf.FontBold AND goFormT.lb_anaf.MousePointer = 15
		DO VpaLog WITH 'PASS label-discordant (B2): [' + m.lcCap + '] rosu, BOLD, cursor mana'
	ELSE
		DO VpaLog WITH 'FAIL label-discordant (B2): [' + m.lcCap + '] ForeColor=' + TRANSFORM(goFormT.lb_anaf.ForeColor) + ' Bold=' + TRANSFORM(goFormT.lb_anaf.FontBold)
	ENDIF
ENDPROC

PROCEDURE VerificaCodInvalid
	*-- runda 15: validarea codului se face INAINTE de ANAF (fara apel), dupa TIP_PERSOANA din cursor
	*-- (1 = juridica -> CIF, 2 = fizica -> CNP).
	LOCAL lnInainte, lcCap
	poVerifAlegere.nIdPart = 0
	lnInainte = gnANAFCallCount
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdCifInv
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	lcCap = ALLTRIM(goFormT.lb_anaf.Caption)
	*-- runda 17 (B2): eticheta primeste sufixul "F4 = detalii" si e BOLD (avertisment), ca discordanta ANAF
	IF m.lcCap == CHR(149) + '  CIF invalid (1234567)  (F4 = detalii)' AND goFormT.lb_anaf.ForeColor = RGB(192,0,0) AND goFormT.lb_anaf.FontBold ;
			AND gnANAFCallCount = m.lnInainte
		DO VpaLog WITH 'PASS cod-invalid-cif (B2): [' + m.lcCap + '] rosu, bold, fara apel ANAF'
	ELSE
		DO VpaLog WITH 'FAIL cod-invalid-cif (B2): [' + m.lcCap + '] ForeColor=' + TRANSFORM(goFormT.lb_anaf.ForeColor) + ;
			' Bold=' + TRANSFORM(goFormT.lb_anaf.FontBold) + ' apeluri=' + TRANSFORM(gnANAFCallCount - m.lnInainte)
	ENDIF

	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdCnpInv
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	lcCap = ALLTRIM(goFormT.lb_anaf.Caption)
	IF m.lcCap == CHR(149) + '  CNP invalid (1234567890123)  (F4 = detalii)' AND goFormT.lb_anaf.ForeColor = RGB(192,0,0) AND goFormT.lb_anaf.FontBold
		DO VpaLog WITH 'PASS cod-invalid-cnp (B2): [' + m.lcCap + '] rosu, bold'
	ELSE
		DO VpaLog WITH 'FAIL cod-invalid-cnp (B2): [' + m.lcCap + '] ForeColor=' + TRANSFORM(goFormT.lb_anaf.ForeColor) + ' Bold=' + TRANSFORM(goFormT.lb_anaf.FontBold)
	ENDIF

	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdPersfiz
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	lcCap = ALLTRIM(goFormT.lb_anaf.Caption)
	IF m.lcCap == CHR(149) + '  Verificare ANAF la alegerea partenerului (F4 = detalii)' AND goFormT.lb_anaf.ForeColor = RGB(112,112,112)
		DO VpaLog WITH 'PASS cod-valid-cnp: persoana fizica cu CNP valid - banda revine la text neutru, fara verificare ANAF'
	ELSE
		DO VpaLog WITH 'FAIL cod-valid-cnp: label neasteptat [' + m.lcCap + '] ForeColor=' + TRANSFORM(goFormT.lb_anaf.ForeColor)
	ENDIF
ENDPROC

PROCEDURE VerificaAlegereVarianta
	*-- runda 15/16: la 2+ variante, "Nu" cere numarul variantei prin aInputBox (numar invalid = revine
	*-- la mesaj); la o singura varianta se pastreaza comportamentul vechi (fara intrebare).
	LOCAL llRez, lcM, lnInputInainte
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	gcMockUltimMesaj = ''
	gcMockUltimPrompt = ''
	gnMockRaspuns = 7
	gnMockInputCount = 0
	gcMockInputSecventa = '0,2'	&& primul raspuns invalid (Renunta), al doilea = varianta 2
	PRIVATE poANAFInlocuire
	poANAFInlocuire = .NULL.
	llRez = poVerifAlegere.VerificaAlegere(goFormT)
	lcM = gcMockUltimMesaj
	IF m.llRez AND VARTYPE(poANAFInlocuire) = 'O' AND poANAFInlocuire.nIdPart = gnIdSpatiu ;
			AND gnMockInputCount = 2 AND 'Nu = Alege din lista (1-2)' $ m.lcM AND '(1-2)' $ gcMockUltimPrompt
		DO VpaLog WITH 'PASS varianta-aleasa: numar invalid -> revine la mesaj, apoi varianta 2 (id_part=' + ;
			TRANSFORM(poANAFInlocuire.nIdPart) + '), apeluri aInputBox=' + TRANSFORM(gnMockInputCount)
	ELSE
		DO VpaLog WITH 'FAIL varianta-aleasa: llRez=' + TRANSFORM(m.llRez) + ' inlocuire=' + ;
			TRANSFORM(IIF(VARTYPE(poANAFInlocuire) = 'O', poANAFInlocuire.nIdPart, -1)) + ' asteptat=' + TRANSFORM(gnIdSpatiu) + ;
			' apeluri=' + TRANSFORM(gnMockInputCount) + ' prompt=[' + gcMockUltimPrompt + '] mesaj=[' + STRTRAN(m.lcM, CHR(13), ' | ') + ']'
	ENDIF

	*-- o singura varianta ramasa (perechea) - nu se mai cere numarul
	=goExecutor.oExecuta([UPDATE NOM_PARTENERI SET STERS = 1 WHERE ID_PART = ] + TRANSFORM(gnIdSpatiu))
	=goExecutor.oExecuta('COMMIT')
	gcMockUltimMesaj = ''
	gnMockInputCount = 0
	gcMockInputSecventa = ''
	poANAFInlocuire = .NULL.
	llRez = poVerifAlegere.VerificaAlegere(goFormT)
	lcM = gcMockUltimMesaj
	IF m.llRez AND VARTYPE(poANAFInlocuire) = 'O' AND poANAFInlocuire.nIdPart = gnIdPereche ;
			AND gnMockInputCount = 0 AND 'Nu = Alege 1 TEST ANAF DISCORD SRL' $ m.lcM
		DO VpaLog WITH 'PASS varianta-unica: o singura varianta - fara intrebare, aleasa direct (id_part=' + ;
			TRANSFORM(poANAFInlocuire.nIdPart) + ')'
	ELSE
		DO VpaLog WITH 'FAIL varianta-unica: llRez=' + TRANSFORM(m.llRez) + ' inlocuire=' + ;
			TRANSFORM(IIF(VARTYPE(poANAFInlocuire) = 'O', poANAFInlocuire.nIdPart, -1)) + ' asteptat=' + TRANSFORM(gnIdPereche) + ;
			' apeluri=' + TRANSFORM(gnMockInputCount) + ' mesaj=[' + STRTRAN(m.lcM, CHR(13), ' | ') + ']'
	ENDIF
	=goExecutor.oExecuta([UPDATE NOM_PARTENERI SET STERS = 0 WHERE ID_PART = ] + TRANSFORM(gnIdSpatiu))
	=goExecutor.oExecuta('COMMIT')
	gnMockRaspuns = 6
ENDPROC

PROCEDURE VerificaDebounce
	LOCAL lnInainte
	*-- reseteaza cache-ul de sesiune ca sa fim siguri ca fara debounce ar fi aparut apeluri noi
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	poVerifAlegere.nIdPart = 0	&& forteaza "randul curent" sa difere, ca VerificaRand sa nu iasa devreme din cache local
	lnInainte = gnANAFCallCount
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdConcord
	goFormT._GRID1.AfterRowColChange(1)
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	LOCATE FOR id_part = gnIdNopereche
	goFormT._GRID1.AfterRowColChange(1)
	DOEVENTS FORCE
	*-- randurile intermediare (concord, discord) NU se verifica; banda isi face acum repaint la fiecare
	*-- schimbare de rand, iar repaint-ul pompeaza mesaje, deci timerul poate apuca sa se declanseze
	*-- pentru randul CURENT (nopereche) inainte de AsteaptaTimer - un singur apel, tot pe randul oprit.
	IF gnANAFCallCount <= m.lnInainte + 1 AND (gnANAFCallCount = m.lnInainte OR ALLTRIM(poVerifAlegere.cCui) == '9000004')
		DO VpaLog WITH 'PASS debounce: 3 navigari rapide, niciun apel pe randurile intermediare (apeluri noi=' + ;
			TRANSFORM(gnANAFCallCount - m.lnInainte) + ', CUI curent=' + ALLTRIM(poVerifAlegere.cCui) + ')'
	ELSE
		DO VpaLog WITH 'FAIL debounce: gnANAFCallCount a crescut cu ' + TRANSFORM(gnANAFCallCount - m.lnInainte) + ;
			' in timpul navigarii rapide, CUI curent=' + ALLTRIM(poVerifAlegere.cCui)
	ENDIF
	DO AsteaptaTimer
	IF gnANAFCallCount = m.lnInainte + 1
		DO VpaLog WITH 'PASS debounce-final: dupa oprire pe ultimul rand (nopereche), exact 1 apel ANAF nou'
	ELSE
		DO VpaLog WITH 'FAIL debounce-final: gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(m.lnInainte+1)
	ENDIF
ENDPROC

PROCEDURE VerificaCache
	LOCAL lnInainte, loForm2, loVerif2, lnOk
	*-- pre-incalzeste cache-ul pt. CUI 7654320 (VerificaDebounce, care ruleaza inainte, RESETEAZA
	*-- goCacheANAF_Sesiune la inceputul ei - fara acest pas, primul apel de mai jos ar fi cache-miss
	*-- legitim, nu ce vreau sa testez aici: AL DOILEA apel, pe formular nou, e cache-hit).
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	lnInainte = gnANAFCallCount
	*-- formular NOU (alta instanta anaf_verif_cautare), acelasi CUI (gnIdDiscord/7654320) deja
	*-- verificat mai sus - goCacheANAF_Sesiune e PUBLIC, pe toata sesiunea, nu per-formular.
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdDiscord), 'ctestcache2')
	loForm2 = CREATEOBJECT('cauta_alfa_form', 'ctestcache2', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loForm2.crs_cursor = 'ctestcache2'
	loForm2.lAles = .F.
	loVerif2 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loForm2, 'oVerifAlegere', loVerif2)
	loVerif2.Activeaza(loForm2)
	loForm2.WindowType = 0
	loForm2.Show()
	SELECT ctestcache2
	GO TOP
	loForm2._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerif2
	IF gnANAFCallCount = m.lnInainte AND 'F4 = detalii' $ ALLTRIM(loForm2.lb_anaf.Caption)
		DO VpaLog WITH 'PASS cache: formular nou, acelasi CUI 7654320 - 0 apeluri ANAF noi, label tot discordant (din cache)'
	ELSE
		DO VpaLog WITH 'FAIL cache: gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(m.lnInainte) + ' label=[' + ALLTRIM(loForm2.lb_anaf.Caption) + ']'
	ENDIF
	TRY
		loVerif2.Dezactiveaza()
		DO VpaLog WITH 'PASS Dezactiveaza (cache, instanta 2): fara eroare (fix runda 10)'
	CATCH TO loExcDez
		DO VpaLog WITH 'FAIL Dezactiveaza (cache, instanta 2): ' + loExcDez.Message
	ENDTRY
	loForm2.Release()
	IF USED('ctestcache2')
		USE IN ctestcache2
	ENDIF
ENDPROC

PROCEDURE VerificaDetalii
	LOCAL lnLenInainte, lcLog, llClick
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	*-- runda 14: Detalii se declanseaza la Click simplu (Bindevent pe Click, nu pe DblClick)
	lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
	goFormT.lb_anaf.Click()
	llClick = 'MOCK amessagebox' $ SUBSTR(FILETOSTR(gcUILog), m.lnLenInainte + 1)
	IF m.llClick
		DO VpaLog WITH 'PASS detalii-click: click simplu pe label -> AMESSAGEBOX de detalii'
	ELSE
		DO VpaLog WITH 'FAIL detalii-click: click simplu pe label nu a deschis detaliile'
	ENDIF
	*-- Detalii se incheie cu do_termin() (dupa Da/Nu se inchide cautarea) - formularul e Release-uit,
	*-- deci scenariile urmatoare au nevoie de unul nou.
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
	poVerifAlegere.Detalii()
	lcLog = FILETOSTR(gcUILog)
	lcLog = SUBSTR(m.lcLog, m.lnLenInainte + 1)
	*-- runda 12: antet "<denumire>  (CUI: <cod>, ID: <id>)" + lista "Parteneri ROA cu CUI <cod corect>:"
	IF 'MOCK amessagebox' $ m.lcLog ;
			AND ('TEST ANAF DISCORD SRL  (CUI: 7654320, ID: ' + TRANSFORM(gnIdDiscord) + ')') $ m.lcLog ;
			AND 'Parteneri ROA cu CUI RO7654320:' $ m.lcLog ;
			AND ('1. TEST ANAF DISCORD SRL (ID: ' + TRANSFORM(gnIdPereche) + ')  inactiv') $ m.lcLog ;
			AND ('2. TEST ANAF SPATIU SRL (ID: ' + TRANSFORM(gnIdSpatiu) + ')') $ m.lcLog
		DO VpaLog WITH 'PASS detalii: AMESSAGEBOX apelat cu antet + lista completa de candidati (inclusiv cod cu spatiu), cod fiscal corect RO7654320'
	ELSE
		DO VpaLog WITH 'FAIL detalii: log dupa apel = [' + m.lcLog + ']'
	ENDIF
ENDPROC

PROCEDURE VerificaAlegereRapidaD2
	*-- D2: alege un rand FARA sa astepte timerul (VerificaRand(.T.) sincron in VerificaAlegere)
	LOCAL lnInainte
	*-- formularul precedent a fost inchis de Detalii (do_termin) - reia cu unul nou
	DO PregatesteFormularD1a
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')	&& reset - CUI 1112223 nu a mai fost verificat "proaspat" pt. acest test
	ENDIF
	poVerifAlegere.nIdPart = 0
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdConcord
	goFormT._GRID1.AfterRowColChange(1)	&& porneste timer-ul, dar NU il astept
	lnInainte = gnANAFCallCount
	PRIVATE poANAFInlocuire
	poANAFInlocuire = .NULL.
	poVerifAlegere.nNivel = 3	&& runda 17: verificarea sincrona la alegere exista doar la nivelul 3
	LOCAL llRez
	llRez = poVerifAlegere.VerificaAlegere(goFormT)
	IF gnANAFCallCount = m.lnInainte + 1 AND m.llRez
		DO VpaLog WITH 'PASS D2-alegere-rapida: verificarea s-a facut SINCRON (apel ANAF imediat, fara sa astepte timerul), concordant -> continua'
	ELSE
		DO VpaLog WITH 'FAIL D2-alegere-rapida: gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(m.lnInainte+1) + ' llRez=' + TRANSFORM(m.llRez)
	ENDIF
	*-- lasa timerul ramas activ sa se stinga, ca sa nu interfereze cu pasii urmatori
	DO AsteaptaTimer
ENDPROC

PROCEDURE VerificaKillSwitch
	*-- RE-TEST RUNDA 10: kill-switch mutat la instantierea poVerifAlegere in apelanti
	*-- (CautPartenerContabilitate/caut_parteneri) - cu switch OFF, poVerifAlegere ramane .NULL.
	*-- si Activeaza NU se mai apeleaza deloc. Replic aici EXACT conditia din productie
	*-- (Alltrim(Nvl(getini(...),'')) <> '0'), fara sa creez deloc anaf_verif_cautare cand e OFF.
	LOCAL lcOrig, lnInainte, loFormK, loVerifK, lnOk, llActiveaza
	lcOrig = getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')
	DO VpaLog WITH 'kill-switch: valoare originala=[' + TRANSFORM(NVL(m.lcOrig,'.NULL.')) + ']'
	TRY
		=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', '0')
		lnInainte = gnANAFCallCount
		lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
			[WHERE ID_PART = ] + TRANSFORM(gnIdDiscord), 'ctestkill')
		loFormK = CREATEOBJECT('cauta_alfa_form', 'ctestkill', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
			'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
		loFormK.crs_cursor = 'ctestkill'
		loFormK.lAles = .F.
		LOCAL lnInaltimeK
		lnInaltimeK = loFormK.Height
		*-- aceeasi conditie ca in CautPartenerContabilitate/caut_parteneri (ocautare.prg)
		llActiveaza = (Alltrim(Nvl(getini(gcGeneralIniFile, 'anaf', 'verificare_selectie'), '')) <> '0')
		IF m.llActiveaza
			loVerifK = CREATEOBJECT('anaf_verif_cautare')
			ADDPROPERTY(loFormK, 'oVerifAlegere', loVerifK)
			loVerifK.Activeaza(loFormK)
		ENDIF
		loFormK.WindowType = 0
		loFormK.Show()
		SELECT ctestkill
		GO TOP
		loFormK._GRID1.AfterRowColChange(1)
		DOEVENTS FORCE
		IF gnANAFCallCount = m.lnInainte AND loFormK.Height = m.lnInaltimeK AND !PEMSTATUS(loFormK, 'lb_anaf', 5)
			DO VpaLog WITH 'PASS kill-switch: verificare_selectie=0 -> nimic nu se ataseaza (poVerifAlegere=.NULL.), 0 apeluri ANAF, fara lb_anaf, inaltime neschimbata (' + TRANSFORM(loFormK.Height) + ')'
		ELSE
			DO VpaLog WITH 'FAIL kill-switch: gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(m.lnInainte) + ' inaltime=' + TRANSFORM(loFormK.Height) + '/' + TRANSFORM(m.lnInaltimeK) + ' PEMSTATUS lb_anaf=' + TRANSFORM(PEMSTATUS(loFormK,'lb_anaf',5))
		ENDIF
		IF VARTYPE(loVerifK) = 'O'
			loVerifK.Dezactiveaza()
		ENDIF
		loFormK.Release()
		IF USED('ctestkill')
			USE IN ctestkill
		ENDIF
	CATCH TO loExcK
		DO VpaLog WITH 'FAIL kill-switch (exceptie): ' + loExcK.Message
	FINALLY
		=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', NVL(m.lcOrig,''))
		DO VpaLog WITH 'kill-switch: restaurat la [' + TRANSFORM(NVL(m.lcOrig,'')) + ']'
	ENDTRY
ENDPROC

PROCEDURE VerificaRegresieNonPartener
	*-- cautare generica FARA activare ANAF (poVerifAlegere ramane .NULL. - ca la orice
	*-- nomenclator care nu e partener, ex. cont/articol): fara oVerifAlegere atasat deloc.
	LOCAL loFormR, lnInaltimeOrig, lnOk
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctestregr')
	loFormR = CREATEOBJECT('cauta_alfa_form', 'ctestregr', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormR.crs_cursor = 'ctestregr'
	loFormR.lAles = .F.
	lnInaltimeOrig = loFormR.Height
	*-- FARA AddProperty('oVerifAlegere',...) - simuleaza cauta_alfa()/CautPartenerContabilitate()
	*-- apelate cu hook-ul dezactivat (llNuVerificaANAF / tlVerificaANAF=.F., cazul implicit
	*-- caut_parteneri fara activare explicita)
	loFormR.WindowType = 0
	loFormR.Show()
	SELECT ctestregr
	GO TOP
	loFormR._GRID1.AfterRowColChange(1)
	DOEVENTS FORCE
	IF loFormR.Height = m.lnInaltimeOrig AND PEMSTATUS(loFormR, 'lb_anaf', 5) = .F.
		DO VpaLog WITH 'PASS regresie-non-ANAF: fara oVerifAlegere -> fara lb_anaf, inaltime neschimbata (' + TRANSFORM(loFormR.Height) + ')'
	ELSE
		DO VpaLog WITH 'FAIL regresie-non-ANAF: inaltime=' + TRANSFORM(loFormR.Height) + '/' + TRANSFORM(m.lnInaltimeOrig) + ' PEMSTATUS lb_anaf=' + TRANSFORM(PEMSTATUS(loFormR,'lb_anaf',5))
	ENDIF
	loFormR.Release()
	IF USED('ctestregr')
		USE IN ctestregr
	ENDIF
ENDPROC

PROCEDURE VerificaMesajDecizie
	*-- runda 11: mesajul e scurt si structurat, iar dialogul e AMESSAGEBOX tip 3+48 (Da/Nu/Abandon).
	LOCAL llRez, lcM, llLinii, llLista
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	gcMockUltimMesaj = ''
	gnMockUltimTip = 0
	gnMockRaspuns = 6
	PRIVATE poANAFInlocuire
	poANAFInlocuire = .NULL.
	llRez = poVerifAlegere.VerificaAlegere(goFormT)
	lcM = gcMockUltimMesaj

	*-- runda 14: antet "<denumire>  (CUI: <cod>, ID: <id>)" + "ANAF: <stare> (<den ANAF>, <cod>) la <data>", fara "!"
	llLinii = OCCURS(CHR(13), m.lcM) >= 3 AND 'ANAF: Platitor TVA' $ m.lcM AND !('! ANAF:' $ m.lcM) ;
		AND ('(CUI: 7654320, ID: ' + TRANSFORM(gnIdDiscord) + ')') $ m.lcM
	llLista = 'Parteneri ROA cu CUI RO7654320:' $ m.lcM AND ('1. TEST ANAF DISCORD SRL (ID: ' + TRANSFORM(gnIdPereche) + ')  inactiv') $ m.lcM ;
		AND ('2. TEST ANAF SPATIU SRL (ID: ' + TRANSFORM(gnIdSpatiu) + ')') $ m.lcM ;
		AND 'Nu = Alege din lista (1-2)' $ m.lcM ;
		AND 'Da = Pastreaza selectia' $ m.lcM AND 'Abandon = Inapoi la cautare' $ m.lcM
	IF m.llLinii AND m.llLista AND gnMockUltimTip = 51
		DO VpaLog WITH 'PASS mesaj-decizie: 3 linii + lista numerotata, tip=51 (3+48) - [' + STRTRAN(m.lcM, CHR(13), ' | ') + ']'
	ELSE
		DO VpaLog WITH 'FAIL mesaj-decizie: linii=' + TRANSFORM(m.llLinii) + ' lista=' + TRANSFORM(m.llLista) + ;
			' tip=' + TRANSFORM(gnMockUltimTip) + ' mesaj=[' + STRTRAN(m.lcM, CHR(13), ' | ') + ']'
	ENDIF
ENDPROC

PROCEDURE PregatesteFormularD1a
	*-- reface goFormT (a fost Release-uit dupa scenariile 1-8) pozitionat pe randul discordant
	*-- CU pereche (gnIdDiscord), pentru scenariile de VerificaAlegere end-to-end (dialog real).
	LOCAL lnOk
	IF VARTYPE(goFormT) = 'O'
		TRY
			goFormT.Release()
		CATCH
		ENDTRY
	ENDIF
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	IF USED('ctestparteneri')
		USE IN ctestparteneri
	ENDIF
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART IN (] + TRANSFORM(gnIdConcord) + [,] + TRANSFORM(gnIdDiscord) + [,] + TRANSFORM(gnIdPereche) + [,] + ;
		TRANSFORM(gnIdNopereche) + [) AND INACTIV = 0 ORDER BY ID_PART], 'ctestparteneri')
	PUBLIC goFormT, poVerifAlegere
	goFormT = CREATEOBJECT('cauta_alfa_form', 'ctestparteneri', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	goFormT.crs_cursor = 'ctestparteneri'
	goFormT.lAles = .F.
	poVerifAlegere = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(goFormT, 'oVerifAlegere', poVerifAlegere)
	poVerifAlegere.Activeaza(goFormT)
	poVerifAlegere.nNivel = 3	&& runda 17: dialogul de confirmare exista doar la nivelul 3 (opt-in)
	goFormT.WindowType = 0
	goFormT.Show()
ENDPROC

PROCEDURE VerificaAlegereD1aButonPereche
	*-- clic pe butonul 1 (Alege perechea) - poANAFInlocuire trebuie sa fie perechea (gnIdPereche)
	LOCAL llRez, lnInactivInainte
	*-- verificare Oracle INAINTE (fara reactivare - vezi si verificarea de dupa, mai jos)
	lnInactivInainte = 0
	=goExecutor.oSelect2Value([SELECT INACTIV AS NR FROM NOM_PARTENERI WHERE ID_PART = ] + TRANSFORM(gnIdPereche), @lnInactivInainte)
	DO VpaLog WITH 'DEBUG fara-reactivare: INACTIV INAINTE de alegere = ' + TRANSFORM(m.lnInactivInainte)
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	gnMockRaspuns = 7	&& Nu
	PRIVATE poANAFInlocuire
	poANAFInlocuire = .NULL.
	llRez = poVerifAlegere.VerificaAlegere(goFormT)

	IF m.llRez AND VARTYPE(poANAFInlocuire) = 'O' AND poANAFInlocuire.nIdPart = gnIdPereche AND poANAFInlocuire.cCodFiscal == 'RO7654320'
		DO VpaLog WITH 'PASS D1a-alege-perechea: raspuns Nu (7), poANAFInlocuire.nIdPart=' + TRANSFORM(gnIdPereche) + ' (perechea INACTIVA, doar folosita - NU reactivata)'
	ELSE
		DO VpaLog WITH 'FAIL D1a-alege-perechea: llRez=' + TRANSFORM(m.llRez) + ' poANAFInlocuire=' + TRANSFORM(VARTYPE(poANAFInlocuire))
	ENDIF

	*-- verificare FARA REACTIVARE: randul pereche ramane INACTIV=1 in Oracle (nicio scriere) -
	*-- comparat explicit INAINTE vs DUPA (nu doar valoarea absoluta), cum a cerut orchestratorul.
	LOCAL lnInactivDupa
	lnInactivDupa = 0
	=goExecutor.oSelect2Value([SELECT INACTIV AS NR FROM NOM_PARTENERI WHERE ID_PART = ] + TRANSFORM(gnIdPereche), @lnInactivDupa)
	DO VpaLog WITH 'DEBUG fara-reactivare: INACTIV DUPA alegere = ' + TRANSFORM(m.lnInactivDupa)
	IF m.lnInactivDupa = m.lnInactivInainte AND m.lnInactivDupa = 1
		DO VpaLog WITH 'PASS fara-reactivare: NOM_PARTENERI.INACTIV neschimbat (inainte=' + TRANSFORM(m.lnInactivInainte) + ' dupa=' + TRANSFORM(m.lnInactivDupa) + ', ambele =1) dupa alegerea perechii (nicio scriere in Oracle)'
	ELSE
		DO VpaLog WITH 'FAIL fara-reactivare: INACTIV inainte=' + TRANSFORM(m.lnInactivInainte) + ' dupa=' + TRANSFORM(m.lnInactivDupa) + ' (astept ambele =1, neschimbat)'
	ENDIF
ENDPROC

PROCEDURE VerificaAlegereD1aButonAles
	*-- raspuns Da (6) - pastreaza selectia curenta: llRez=.T., poANAFInlocuire ramane .NULL.
	LOCAL llRez
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	gnMockRaspuns = 6	&& Da
	PRIVATE poANAFInlocuire
	poANAFInlocuire = .NULL.
	llRez = poVerifAlegere.VerificaAlegere(goFormT)

	IF m.llRez AND ISNULL(poANAFInlocuire)
		DO VpaLog WITH 'PASS D1a-alege-ales: raspuns Da (6), pastreaza alegerea initiala (poANAFInlocuire=.NULL.)'
	ELSE
		DO VpaLog WITH 'FAIL D1a-alege-ales: llRez=' + TRANSFORM(m.llRez) + ' poANAFInlocuire=' + TRANSFORM(VARTYPE(poANAFInlocuire))
	ENDIF
ENDPROC

PROCEDURE VerificaAlegereD1aRenunta
	*-- raspuns Abandon (2) - llRez=.F. (ramai in cautare, formularul NU se inchide)
	LOCAL llRez
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	gnMockRaspuns = 2	&& Abandon
	llRez = poVerifAlegere.VerificaAlegere(goFormT)

	IF !m.llRez AND goFormT.Visible
		DO VpaLog WITH 'PASS D1a-renunta: raspuns Abandon (2), llRez=.F., formularul de cautare RAMANE deschis'
	ELSE
		DO VpaLog WITH 'FAIL D1a-renunta: llRez=' + TRANSFORM(m.llRez) + ' Visible=' + TRANSFORM(goFormT.Visible)
	ENDIF
ENDPROC

PROCEDURE VerificaAlegereFaraPereche
	*-- randul nopereche (discordant, FARA pereche) - dialog OK/Abandon (tip 1+48), raspuns OK (1)
	LOCAL llRez
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdNopereche
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	gcMockUltimMesaj = ''
	gnMockUltimTip = 0
	gnMockRaspuns = 1	&& OK
	llRez = poVerifAlegere.VerificaAlegere(goFormT)

	IF m.llRez AND gnMockUltimTip = 49 ;
			AND 'Nu exista partener cu CUI RO9000004 (il puteti crea cu butonul Nou).' $ gcMockUltimMesaj ;
			AND 'De acord = Pastreaza selectia' $ gcMockUltimMesaj AND 'Abandon = Inapoi la cautare' $ gcMockUltimMesaj
		DO VpaLog WITH 'PASS fara-pereche-continua: raspuns OK (1), tip=49 (1+48), llRez=.T. - [' + STRTRAN(gcMockUltimMesaj, CHR(13), ' | ') + ']'
	ELSE
		DO VpaLog WITH 'FAIL fara-pereche-continua: llRez=' + TRANSFORM(m.llRez) + ' tip=' + TRANSFORM(gnMockUltimTip) + ;
			' mesaj=[' + STRTRAN(gcMockUltimMesaj, CHR(13), ' | ') + ']'
	ENDIF

	TRY
		goFormT.oVerifAlegere.Dezactiveaza()
		DO VpaLog WITH 'PASS Dezactiveaza (fara-pereche): fara eroare (fix runda 10)'
	CATCH TO loExcDezFP
		DO VpaLog WITH 'FAIL Dezactiveaza (fara-pereche): ' + loExcDezFP.Message
	ENDTRY
	TRY
		goFormT.Release()
	CATCH
	ENDTRY
ENDPROC

PROCEDURE VerificaDataDocument
	*-- runda 12: dDataDoc explicit pe anaf_verif_cautare - trebuie sa ajunga la mock (gdANAFUltimaData)
	*-- si sa apara in textul labelului ("... la " + Dtoc(data)). Instanta proprie (nu goFormT/poVerifAlegere
	*-- - eliberate dupa scenariul 10), pe randul concordant (gnIdConcord), ca sa nu depinda de dialog.
	LOCAL loFormD, loVerifD, lnOk, ldDataDoc, lcCap
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ldDataDoc = {^2026/06/15}
	gdANAFUltimaData = {}
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctestdatadoc')
	loFormD = CREATEOBJECT('cauta_alfa_form', 'ctestdatadoc', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormD.crs_cursor = 'ctestdatadoc'
	loFormD.lAles = .F.
	loVerifD = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormD, 'oVerifAlegere', loVerifD)
	loVerifD.dDataDoc = ldDataDoc
	loVerifD.Activeaza(loFormD)
	loFormD.WindowType = 0
	loFormD.Show()
	SELECT ctestdatadoc
	GO TOP
	loFormD._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifD
	lcCap = ALLTRIM(loFormD.lb_anaf.Caption)
	IF gdANAFUltimaData == ldDataDoc AND (' la ' + DTOC(ldDataDoc)) $ lcCap
		DO VpaLog WITH 'PASS data-document: mock a primit data documentului (' + DTOC(ldDataDoc) + '), label=[' + lcCap + ']'
	ELSE
		DO VpaLog WITH 'FAIL data-document: gdANAFUltimaData=' + TRANSFORM(gdANAFUltimaData) + ' astept=' + DTOC(ldDataDoc) + ' label=[' + lcCap + ']'
	ENDIF
	loVerifD.Dezactiveaza()
	loFormD.Release()
	IF USED('ctestdatadoc')
		USE IN ctestdatadoc
	ENDIF
ENDPROC

PROCEDURE VerificaCacheData
	*-- runda 12: cheia de cache pe sesiune e 'C'+CUI+'_'+Dtos(data) - acelasi CUI la 2 date diferite
	*-- => 2 apeluri ANAF noi (chei diferite); acelasi CUI la ACEEASI data => 1 singur apel (cache-hit).
	LOCAL lnOk, ldData1, ldData2, lnInainte
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ldData1 = {^2026/03/10}
	ldData2 = {^2026/04/20}
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctestcachedata')
	lnInainte = gnANAFCallCount

	DO VerificaCacheDataUnRand WITH ldData1, 'ctestcachedata'
	IF gnANAFCallCount = lnInainte + 1
		DO VpaLog WITH 'PASS cache-data (data1): prima verificare la ' + DTOC(ldData1) + ' - 1 apel ANAF nou'
	ELSE
		DO VpaLog WITH 'FAIL cache-data (data1): gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(lnInainte + 1)
	ENDIF

	DO VerificaCacheDataUnRand WITH ldData1, 'ctestcachedata'
	IF gnANAFCallCount = lnInainte + 1
		DO VpaLog WITH 'PASS cache-data (data1 repetata): ACEEASI data - 0 apeluri noi (cache-hit)'
	ELSE
		DO VpaLog WITH 'FAIL cache-data (data1 repetata): gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(lnInainte + 1)
	ENDIF

	DO VerificaCacheDataUnRand WITH ldData2, 'ctestcachedata'
	IF gnANAFCallCount = lnInainte + 2
		DO VpaLog WITH 'PASS cache-data (data2): data DIFERITA (' + DTOC(ldData2) + ') - 1 apel ANAF nou (chei de cache diferite)'
	ELSE
		DO VpaLog WITH 'FAIL cache-data (data2): gnANAFCallCount=' + TRANSFORM(gnANAFCallCount) + ' astept=' + TRANSFORM(lnInainte + 2)
	ENDIF

	IF USED('ctestcachedata')
		USE IN ctestcachedata
	ENDIF
ENDPROC

PROCEDURE VerificaCacheDataUnRand
	*-- instanta NOUA de anaf_verif_cautare (nIdPart porneste de la 0) pe fiecare apel - altfel
	*-- VerificaRand iese devreme din cache local (This.nIdPart), nu ajunge la goCacheANAF_Sesiune.
	LPARAMETERS tdData, tcCursor
	LOCAL loFormC, loVerifC
	loFormC = CREATEOBJECT('cauta_alfa_form', tcCursor, '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormC.crs_cursor = tcCursor
	loFormC.lAles = .F.
	loVerifC = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormC, 'oVerifAlegere', loVerifC)
	loVerifC.dDataDoc = tdData
	loVerifC.Activeaza(loFormC)
	loFormC.WindowType = 0
	loFormC.Show()
	SELECT (tcCursor)
	GO TOP
	loFormC._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifC
	loVerifC.Dezactiveaza()
	loFormC.Release()
ENDPROC

PROCEDURE VerificaDataFallback
	*-- runda 12: dDataDoc gol (valoarea implicita {} din DEFINE CLASS) => ANAF_StarePartener /
	*-- ANAF_VerificaCuiSingle folosesc Date() curent (fallback).
	LOCAL loFormF, loVerifF, lnOk, lcCap
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	gdANAFUltimaData = {}
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctestfallback')
	loFormF = CREATEOBJECT('cauta_alfa_form', 'ctestfallback', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormF.crs_cursor = 'ctestfallback'
	loFormF.lAles = .F.
	loVerifF = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormF, 'oVerifAlegere', loVerifF)
	loVerifF.Activeaza(loFormF)
	loFormF.WindowType = 0
	loFormF.Show()
	SELECT ctestfallback
	GO TOP
	loFormF._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifF
	lcCap = ALLTRIM(loFormF.lb_anaf.Caption)
	IF gdANAFUltimaData == DATE() AND (' la ' + DTOC(DATE())) $ lcCap
		DO VpaLog WITH 'PASS data-fallback: dDataDoc gol -> Date() curent (' + DTOC(DATE()) + ') folosit, label=[' + lcCap + ']'
	ELSE
		DO VpaLog WITH 'FAIL data-fallback: gdANAFUltimaData=' + TRANSFORM(gdANAFUltimaData) + ' Date()=' + DTOC(DATE()) + ' label=[' + lcCap + ']'
	ENDIF
	loVerifF.Dezactiveaza()
	loFormF.Release()
	IF USED('ctestfallback')
		USE IN ctestfallback
	ENDIF
ENDPROC

PROCEDURE VerificaDataPoAct
	*-- runda 14: dDataDoc gol, dar poAct.dataact vizibil in stiva (ca in formularele de
	*-- introduceri, unde poAct e PRIVATE in lans()/viz_act) => se verifica la data documentului.
	PRIVATE poAct
	LOCAL loFormP, loVerifP, lnOk, lcCap, ldDoc
	ldDoc = DATE() - 40
	poAct = CREATEOBJECT('Empty')
	ADDPROPERTY(poAct, 'dataact', m.ldDoc)
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	gdANAFUltimaData = {}
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctestpoact')
	loFormP = CREATEOBJECT('cauta_alfa_form', 'ctestpoact', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormP.crs_cursor = 'ctestpoact'
	loFormP.lAles = .F.
	loVerifP = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormP, 'oVerifAlegere', loVerifP)
	loVerifP.Activeaza(loFormP)
	loFormP.WindowType = 0
	loFormP.Show()
	SELECT ctestpoact
	GO TOP
	loFormP._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifP
	lcCap = ALLTRIM(loFormP.lb_anaf.Caption)
	IF gdANAFUltimaData == m.ldDoc AND (' la ' + DTOC(m.ldDoc)) $ lcCap
		DO VpaLog WITH 'PASS data-poact: dDataDoc gol + poAct.dataact (' + DTOC(m.ldDoc) + ') -> data documentului folosita, label=[' + lcCap + ']'
	ELSE
		DO VpaLog WITH 'FAIL data-poact: gdANAFUltimaData=' + TRANSFORM(gdANAFUltimaData) + ' poAct.dataact=' + DTOC(m.ldDoc) + ' label=[' + lcCap + ']'
	ENDIF
	loVerifP.Dezactiveaza()
	loFormP.Release()
	IF USED('ctestpoact')
		USE IN ctestpoact
	ENDIF
ENDPROC

PROCEDURE VerificaInactivCodCorect
	*-- cod fiscal corect (fara RO, ANAF neplatitor), discordanta doar din "inactiv la ANAF":
	*-- nu se mai cauta perechi si nu se mai sugereaza crearea unui partener cu acelasi cod.
	LOCAL loFormI, loVerifI, lnOk, llRez, lcCapI
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdInactiv), 'ctestinactiv')
	loFormI = CREATEOBJECT('cauta_alfa_form', 'ctestinactiv', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormI.crs_cursor = 'ctestinactiv'
	loFormI.lAles = .F.
	loVerifI = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormI, 'oVerifAlegere', loVerifI)
	loVerifI.Activeaza(loFormI)
	loVerifI.nNivel = 3
	loFormI.WindowType = 0
	loFormI.Show()
	SELECT ctestinactiv
	GO TOP
	loFormI._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifI
	lcCapI = ALLTRIM(loFormI.lb_anaf.Caption)

	gcMockUltimMesaj = ''
	gnMockUltimTip = 0
	gnMockRaspuns = 1	&& De acord
	llRez = loVerifI.VerificaAlegere(loFormI)
	IF m.llRez AND gnMockUltimTip = 49 AND 'Neplatitor TVA, Inactiv' $ gcMockUltimMesaj ;
			AND !('butonul Nou' $ gcMockUltimMesaj) AND !('Parteneri ROA cu CUI' $ gcMockUltimMesaj) ;
			AND 'Neplatitor TVA, Inactiv' $ m.lcCapI
		DO VpaLog WITH 'PASS inactiv-cod-corect: confirmare fara sugestia de creare - [' + STRTRAN(gcMockUltimMesaj, CHR(13), ' | ') + ']'
	ELSE
		DO VpaLog WITH 'FAIL inactiv-cod-corect: llRez=' + TRANSFORM(m.llRez) + ' tip=' + TRANSFORM(gnMockUltimTip) + ;
			' label=[' + m.lcCapI + '] mesaj=[' + STRTRAN(gcMockUltimMesaj, CHR(13), ' | ') + ']'
	ENDIF

	gcMockUltimMesaj = ''
	loVerifI.Detalii()
	IF 'Nu exista alta varianta de partener de ales.' $ gcMockUltimMesaj AND !('butonul Nou' $ gcMockUltimMesaj) ;
			AND !('Parteneri ROA cu CUI' $ gcMockUltimMesaj)
		DO VpaLog WITH 'PASS inactiv-detalii: F4 arata doar starea, fara lista de variante'
	ELSE
		DO VpaLog WITH 'FAIL inactiv-detalii: mesaj=[' + STRTRAN(gcMockUltimMesaj, CHR(13), ' | ') + ']'
	ENDIF

	loVerifI.Dezactiveaza()
	loFormI.Release()
	IF USED('ctestinactiv')
		USE IN ctestinactiv
	ENDIF
ENDPROC

PROCEDURE VerificaCodInexistentANAF
	*-- cod fiscal valid ca structura, dar pe care ANAF nu il gaseste: se semnaleaza in banda, nu se
	*-- mai trece tacut peste el (deosebit de "ANAF nu a raspuns", care ramane tacut).
	LOCAL loFormX, loVerifX, lnOk, lcCapX, lnInainte
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdInexistent), 'ctestinexistent')
	loFormX = CREATEOBJECT('cauta_alfa_form', 'ctestinexistent', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormX.crs_cursor = 'ctestinexistent'
	loFormX.lAles = .F.
	loVerifX = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormX, 'oVerifAlegere', loVerifX)
	loVerifX.Activeaza(loFormX)
	loFormX.WindowType = 0
	loFormX.Show()
	SELECT ctestinexistent
	GO TOP
	loFormX._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifX
	lcCapX = ALLTRIM(loFormX.lb_anaf.Caption)

	IF 'Cod fiscal inexistent la ANAF (9000039)' $ m.lcCapX AND loFormX.lb_anaf.ForeColor = RGB(192,0,0) ;
			AND loFormX.lb_anaf.FontBold AND loVerifX.lNegasit
		DO VpaLog WITH 'PASS cod-inexistent: banda semnaleaza codul negasit la ANAF - [' + m.lcCapX + ']'
	ELSE
		DO VpaLog WITH 'FAIL cod-inexistent: label=[' + m.lcCapX + '] ForeColor=' + TRANSFORM(loFormX.lb_anaf.ForeColor) + ;
			' Bold=' + TRANSFORM(loFormX.lb_anaf.FontBold) + ' lNegasit=' + TRANSFORM(loVerifX.lNegasit)
	ENDIF

	*-- al doilea rand pe acelasi cod: verdictul "inexistent" NU se mai retine in cache (T4/handoff_anaf_404
	*-- - doar rezultatele POZITIVE se cacheaza) - fiecare verificare noua face iar apel ANAF, acelasi verdict.
	lnInainte = gnANAFCallCount
	loVerifX.nIdPart = 0
	loFormX._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifX
	IF gnANAFCallCount = m.lnInainte + 1 AND 'Cod fiscal inexistent la ANAF' $ ALLTRIM(loFormX.lb_anaf.Caption)
		DO VpaLog WITH 'PASS cod-inexistent-fara-cache: verdictul "inexistent" nu se cacheaza - apel ANAF nou (' + ;
			TRANSFORM(gnANAFCallCount - m.lnInainte) + '), acelasi verdict'
	ELSE
		DO VpaLog WITH 'FAIL cod-inexistent-fara-cache: apeluri noi=' + TRANSFORM(gnANAFCallCount - m.lnInainte) + ;
			' label=[' + ALLTRIM(loFormX.lb_anaf.Caption) + ']'
	ENDIF

	gcMockUltimMesaj = ''
	loVerifX.Detalii()
	IF 'Codul fiscal nu exista la ANAF.' $ gcMockUltimMesaj
		DO VpaLog WITH 'PASS cod-inexistent-detalii: F4 explica de ce nu exista verdict'
	ELSE
		DO VpaLog WITH 'FAIL cod-inexistent-detalii: mesaj=[' + STRTRAN(gcMockUltimMesaj, CHR(13), ' | ') + ']'
	ENDIF

	loVerifX.Dezactiveaza()
	loFormX.Release()
	IF USED('ctestinexistent')
		USE IN ctestinexistent
	ENDIF
ENDPROC

PROCEDURE RuleazaIzolat
	*-- izoleaza fiecare scenariu nou REVIZIA 4 - o eroare neasteptata intr-unul singur nu opreste
	*-- restul suitei (spre deosebire de eroarea din TRY-ul principal, care oricum face QUIT).
	LPARAMETERS tcProcedura
	LOCAL loExcIz
	TRY
		DO (tcProcedura)
	CATCH TO loExcIz
		DO VpaLog WITH 'FAIL ' + tcProcedura + ' (EXCEPTIE): ErrorNo=' + TRANSFORM(loExcIz.ErrorNo) + ;
			' Message=' + loExcIz.Message + ' Proc=' + loExcIz.Procedure + ' Line=' + TRANSFORM(loExcIz.LineNo)
	ENDTRY
ENDPROC

PROCEDURE VerificaStareCazutaZeroApeluri
	*-- S1 (handoff_anaf_404.md): stare de serviciu CAZUT -> randul NU face niciun apel ANAF nou,
	*-- banda arata "ANAF nu a raspuns - verificare sarita" (gri, fara bold). ANAF_SeteazaStareServiciu
	*-- e functia reala din ocautare.prg (nu un global impins direct), ca sceanariul sa treaca prin
	*-- acelasi mecanism ca in productie.
	LOCAL loFormS, loVerifS, lnOk, lnInainte, lcCapS
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ANAF_SeteazaStareServiciu('CAZUT', 'test S1')
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctests1')
	loFormS = CREATEOBJECT('cauta_alfa_form', 'ctests1', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormS.crs_cursor = 'ctests1'
	loFormS.lAles = .F.
	loVerifS = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormS, 'oVerifAlegere', loVerifS)
	loVerifS.Activeaza(loFormS)
	loFormS.WindowType = 0
	loFormS.Show()
	SELECT ctests1
	GO TOP
	lnInainte = gnANAFCallCount
	loFormS._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifS
	lcCapS = ALLTRIM(loFormS.lb_anaf.Caption)
	IF gnANAFCallCount = lnInainte AND 'ANAF nu a raspuns - verificare sarita' $ lcCapS ;
			AND loFormS.lb_anaf.ForeColor = RGB(112,112,112) AND !loFormS.lb_anaf.FontBold
		DO VpaLog WITH 'PASS stare-cazuta-zero-apeluri (S1): stare CAZUT -> 0 apeluri ANAF, banda gri [' + lcCapS + ']'
	ELSE
		DO VpaLog WITH 'FAIL stare-cazuta-zero-apeluri (S1): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' label=[' + lcCapS + '] ForeColor=' + TRANSFORM(loFormS.lb_anaf.ForeColor) + ' Bold=' + TRANSFORM(loFormS.lb_anaf.FontBold)
	ENDIF
	loVerifS.Dezactiveaza()
	loFormS.Release()
	IF USED('ctests1')
		USE IN ctests1
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa test S1')
ENDPROC

PROCEDURE VerificaBandaCazutDistinctaDePrompt
	*-- S6 (handoff_anaf_404.md): banda gri "ANAF nu a raspuns - verificare sarita" (stare CAZUT) e
	*-- DISTINCTA de promptul gri generic "Verificare ANAF la alegerea partenerului (F4 = detalii)" -
	*-- regresia care ascundea initial defectul (fara ea, utilizatorul nu distinge "inca neverificat"
	*-- de "ANAF picat").
	LOCAL loFormB, loVerifB, lnOk, lcPromptGeneric, lcBandaCazut
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctests6')
	loFormB = CREATEOBJECT('cauta_alfa_form', 'ctests6', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormB.crs_cursor = 'ctests6'
	loFormB.lAles = .F.
	loVerifB = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormB, 'oVerifAlegere', loVerifB)
	loVerifB.Activeaza(loFormB)	&& Activeaza cheama AfiseazaPrompt() - captureaza promptul generic
	loFormB.WindowType = 0
	loFormB.Show()
	lcPromptGeneric = ALLTRIM(loFormB.lb_anaf.Caption)

	ANAF_SeteazaStareServiciu('CAZUT', 'test S6')
	SELECT ctests6
	GO TOP
	loFormB._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifB
	lcBandaCazut = ALLTRIM(loFormB.lb_anaf.Caption)

	IF !(m.lcPromptGeneric == m.lcBandaCazut) AND 'Verificare ANAF la alegerea partenerului' $ m.lcPromptGeneric ;
			AND 'ANAF nu a raspuns - verificare sarita' $ m.lcBandaCazut
		DO VpaLog WITH 'PASS banda-cazut-distincta (S6): prompt generic=[' + m.lcPromptGeneric + '] vs banda CAZUT=[' + m.lcBandaCazut + ']'
	ELSE
		DO VpaLog WITH 'FAIL banda-cazut-distincta (S6): prompt=[' + m.lcPromptGeneric + '] banda=[' + m.lcBandaCazut + ']'
	ENDIF

	loVerifB.Dezactiveaza()
	loFormB.Release()
	IF USED('ctests6')
		USE IN ctests6
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa test S6')
ENDPROC

PROCEDURE VerificaEsecNuSeCacheaza
	*-- S5 (handoff_anaf_404.md): esecul (FARA_RASPUNS) NU se scrie in cache; dupa ce serviciul revine
	*-- (stare VIU), ACELASI CUI se verifica din nou si primeste verdict - blocheaza regresia "verdict
	*-- lipsa pana la repornirea programului". goANAFMockData primeste STRING 'FARA_RASPUNS' pt. cheia
	*-- CUI-ului de test (vezi mock_anaf_verificare.prg), apoi e inlocuita cu obiectul de succes.
	LOCAL lnOk, loFormE1, loVerifE1, loFormE2, loVerifE2, lnInainte, lcCap1, lcCap2, loRespCadere

	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	IF goANAFMockData.GetKey('C9000055') <> 0
		goANAFMockData.Remove('C9000055')
	ENDIF
	goANAFMockData.Add('FARA_RASPUNS', 'C9000055')
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'pregatire S5')

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCadere), 'ctests5a')
	loFormE1 = CREATEOBJECT('cauta_alfa_form', 'ctests5a', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormE1.crs_cursor = 'ctests5a'
	loFormE1.lAles = .F.
	loVerifE1 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormE1, 'oVerifAlegere', loVerifE1)
	loVerifE1.Activeaza(loFormE1)
	loFormE1.WindowType = 0
	loFormE1.Show()
	SELECT ctests5a
	GO TOP
	lnInainte = gnANAFCallCount
	loFormE1._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifE1
	lcCap1 = ALLTRIM(loFormE1.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte + 1 AND 'ANAF nu a raspuns - verificare sarita' $ lcCap1 ;
			AND goCacheANAF_Sesiune.GetKey('C9000055_' + DTOS(DATE())) = 0
		DO VpaLog WITH 'PASS esec-nu-se-cacheaza (S5, pas 1): apel ANAF esuat (' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' apel nou), banda=[' + lcCap1 + '], NU s-a scris in cache'
	ELSE
		DO VpaLog WITH 'FAIL esec-nu-se-cacheaza (S5, pas 1): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' banda=[' + lcCap1 + '] cache-key=' + TRANSFORM(goCacheANAF_Sesiune.GetKey('C9000055_' + DTOS(DATE())))
	ENDIF
	loVerifE1.Dezactiveaza()
	loFormE1.Release()
	IF USED('ctests5a')
		USE IN ctests5a
	ENDIF

	*-- serviciul revine: inlocuieste intrarea mock cu un obiect de succes real + stare VIU (fara sa
	*-- astepte cele 10 minute de expirare CAZUT - vezi ANAF_SeteazaStareServiciu, ocautare.prg)
	goANAFMockData.Remove('C9000055')
	loRespCadere = CREATEOBJECT('Empty')
	ADDPROPERTY(loRespCadere, 'cui', '9000055')
	ADDPROPERTY(loRespCadere, 'scpTVA', .T.)
	ADDPROPERTY(loRespCadere, 'statusInactivi', .F.)
	ADDPROPERTY(loRespCadere, 'denumire', 'CADERE SRL ANAF')
	ADDPROPERTY(loRespCadere, 'mesaj', '')
	goANAFMockData.Add(loRespCadere, 'C9000055')
	ANAF_SeteazaStareServiciu('VIU', 'revenire S5')

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCadere), 'ctests5b')
	loFormE2 = CREATEOBJECT('cauta_alfa_form', 'ctests5b', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormE2.crs_cursor = 'ctests5b'
	loFormE2.lAles = .F.
	loVerifE2 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormE2, 'oVerifAlegere', loVerifE2)
	loVerifE2.Activeaza(loFormE2)
	loFormE2.WindowType = 0
	loFormE2.Show()
	SELECT ctests5b
	GO TOP
	lnInainte = gnANAFCallCount
	loFormE2._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifE2
	lcCap2 = ALLTRIM(loFormE2.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte + 1 AND 'ANAF: Platitor TVA' $ lcCap2 AND 'CADERE SRL ANAF' $ lcCap2
		DO VpaLog WITH 'PASS esec-nu-se-cacheaza (S5, pas 2): dupa revenire (VIU), acelasi CUI 9000055 se re-verifica (' + ;
			TRANSFORM(gnANAFCallCount - lnInainte) + ' apel nou) si primeste verdict [' + lcCap2 + ']'
	ELSE
		DO VpaLog WITH 'FAIL esec-nu-se-cacheaza (S5, pas 2): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ' banda=[' + lcCap2 + ']'
	ENDIF
	loVerifE2.Dezactiveaza()
	loFormE2.Release()
	IF USED('ctests5b')
		USE IN ctests5b
	ENDIF
ENDPROC

PROCEDURE VerificaCodNenumeric
	*-- P8 (handoff_anaf_404.md, acelasi tipar ca si cazul real FANALEX din design-alegere-partener-anaf.md,
	*-- dar cu text disponibil pentru testare - textul EXACT real coincide cu un partener preexistent in
	*-- schema, vezi nota din antetul fisierului): cod fiscal nenumeric dupa normalizare (litere in loc de
	*-- cifre) -> banda gri distincta, fara apel ANAF si fara tacere completa (comportamentul dinainte de reparatie).
	LOCAL loFormN, loVerifN, lnOk, lcCapN, lnInainte
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV, TIP_PERSOANA FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdNenumeric), 'ctestnenum')
	loFormN = CREATEOBJECT('cauta_alfa_form', 'ctestnenum', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormN.crs_cursor = 'ctestnenum'
	loFormN.lAles = .F.
	loVerifN = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormN, 'oVerifAlegere', loVerifN)
	loVerifN.Activeaza(loFormN)
	loFormN.WindowType = 0
	loFormN.Show()
	SELECT ctestnenum
	GO TOP
	lnInainte = gnANAFCallCount
	loFormN._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifN
	lcCapN = ALLTRIM(loFormN.lb_anaf.Caption)
	IF gnANAFCallCount = lnInainte AND lcCapN == CHR(149) + '  Cod fiscal nenumeric - nu se poate verifica la ANAF' ;
			AND loFormN.lb_anaf.ForeColor = RGB(112,112,112) AND !loFormN.lb_anaf.FontBold
		DO VpaLog WITH 'PASS cod-nenumeric (P8): cod fiscal "TEST NENUMERIC OIL MARKET SRL" (tiparul cazului real FANALEX) -> banda gri distincta, fara apel ANAF - [' + lcCapN + ']'
	ELSE
		DO VpaLog WITH 'FAIL cod-nenumeric (P8): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ' label=[' + lcCapN + ']'
	ENDIF

	*-- F4 (Detalii) pe cod nenumeric: text nou dedicat (cClasaEsec == 'COD_NENUMERIC'), distinct de
	*-- "Codul fiscal nu exista la ANAF." si "ANAF nu a raspuns - verificarea a fost sarita." (ocautare.prg)
	LOCAL lnLenInainte, lcLog
	lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
	loVerifN.Detalii()
	lcLog = SUBSTR(FILETOSTR(gcUILog), lnLenInainte + 1)
	IF 'MOCK amessagebox' $ lcLog AND 'Codul fiscal nu este numeric - nu se poate verifica la ANAF.' $ lcLog ;
			AND !('Codul fiscal nu exista la ANAF.' $ lcLog) AND !('verificarea a fost sarita' $ lcLog)
		DO VpaLog WITH 'PASS cod-nenumeric-detalii (P8): F4 arata textul dedicat codului nenumeric, distinct de negasit/fara-raspuns'
	ELSE
		DO VpaLog WITH 'FAIL cod-nenumeric-detalii (P8): log=[' + lcLog + ']'
	ENDIF

	loVerifN.Dezactiveaza()
	loFormN.Release()
	IF USED('ctestnenum')
		USE IN ctestnenum
	ENDIF
ENDPROC

PROCEDURE VerificaFixtureContract404
	*-- F1 (handoff_anaf_404.md), REVIZUIT dupa T5/sonda: logica de verdict a fost extrasa in
	*-- ANAF_VerdictDinCursor (validare.prg) - fixture-ul apeleaza acum FUNCTIA REALA (nu o replica
	*-- locala), peste cursorul produs de ParseJsonANAFv8 (tot cod real, fara HTTP), cu cele doua
	*-- corpuri MASURATE pe serviciul ANAF real (plan-reparatie-anaf-404-breaker.md, cauza 1).
	LOCAL loVerif, lcJson404, lcJsonStrain, loObj404, loObjStrain, lcAlias404, lcAliasStrain
	LOCAL lnCuiCautat, loResult404, loResultStrain, llNegasit404, llNegasitStrain, lcClasa404, lcClasaStrain

	loVerif = CREATEOBJECT("VerificareANAF")
	lnCuiCautat = 123456789

	*=== corp masurat, status 404: {"found":[],"notFound":[123456789]} -> verdict "inexistent" ===
	lcJson404 = '{"found":[],"notFound":[123456789]}'
	lcAlias404 = 'crsFixtureF1a'
	IF USED(lcAlias404)
		USE IN (lcAlias404)
	ENDIF
	loObj404 = nfjsonread(lcJson404)
	loVerif.ParseJsonANAFv8(loObj404, lcAlias404)
	llNegasit404 = .F.
	lcClasa404 = ''
	loResult404 = ANAF_VerdictDinCursor(lcAlias404, lnCuiCautat, @llNegasit404, @lcClasa404)
	IF ISNULL(loResult404) AND llNegasit404 AND EMPTY(lcClasa404)
		DO VpaLog WITH 'PASS fixture-404-inexistent (F1): ANAF_VerdictDinCursor REALA, corp {"found":[],"notFound":[123456789]} -> tlNegasit=.T., clasa=[]'
	ELSE
		DO VpaLog WITH 'FAIL fixture-404-inexistent (F1): rezultat=' + TRANSFORM(VARTYPE(loResult404)) + ' llNegasit=' + TRANSFORM(llNegasit404) + ' clasa=[' + lcClasa404 + ']'
	ENDIF
	IF USED(lcAlias404)
		USE IN (lcAlias404)
	ENDIF

	*=== corp strain (proxy/mentenanta/eroare) - NU trebuie sa dea verdict "inexistent" ===
	lcJsonStrain = '{"message":"service unavailable"}'
	lcAliasStrain = 'crsFixtureF1b'
	IF USED(lcAliasStrain)
		USE IN (lcAliasStrain)
	ENDIF
	loObjStrain = nfjsonread(lcJsonStrain)
	loVerif.ParseJsonANAFv8(loObjStrain, lcAliasStrain)
	llNegasitStrain = .F.
	lcClasaStrain = ''
	loResultStrain = ANAF_VerdictDinCursor(lcAliasStrain, lnCuiCautat, @llNegasitStrain, @lcClasaStrain)
	IF ISNULL(loResultStrain) AND !llNegasitStrain AND lcClasaStrain == 'RASPUNS_NEINTELES'
		DO VpaLog WITH 'PASS fixture-corp-strain (F1): ANAF_VerdictDinCursor REALA, corp {"message":"service unavailable"} -> clasa=RASPUNS_NEINTELES'
	ELSE
		DO VpaLog WITH 'FAIL fixture-corp-strain (F1): rezultat=' + TRANSFORM(VARTYPE(loResultStrain)) + ' llNegasit=' + TRANSFORM(llNegasitStrain) + ' clasa=[' + lcClasaStrain + ']'
	ENDIF
	IF USED(lcAliasStrain)
		USE IN (lcAliasStrain)
	ENDIF
ENDPROC

PROCEDURE VerificaSondaInAer
	*-- S2 (handoff_anaf_404.md, T5/sonda): sonda in aer (stare SE_TESTEAZA) -> randul NU face apel
	*-- propriu (gnANAFCallCount neschimbat), banda "ANAF: se verifica <cod>...". Plus (tabelul de
	*-- moduri de esec): formular inchis CU sonda inca in aer -> starea revine la NECUNOSCUT, nu CAZUT
	*-- (Dezactiveaza: ANAF_SondaOpreste() + ANAF_SeteazaStareServiciu, ocautare.prg).
	LOCAL loFormS2, loVerifS2, lnOk, lnInainte, lcCap
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'pregatire S2')
	gcMockSondaModo = 'MANUAL'
	glMockSondaGataManual = .F.	&& sonda pleaca si NU raspunde inca
	gnMockSondaPornireCount = 0

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctests2')
	loFormS2 = CREATEOBJECT('cauta_alfa_form', 'ctests2', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormS2.crs_cursor = 'ctests2'
	loFormS2.lAles = .F.
	loVerifS2 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormS2, 'oVerifAlegere', loVerifS2)
	loVerifS2.Activeaza(loFormS2)	&& stare NECUNOSCUT -> porneste sonda (mock) -> SE_TESTEAZA
	loFormS2.WindowType = 0
	loFormS2.Show()
	SELECT ctests2
	GO TOP
	lnInainte = gnANAFCallCount
	loFormS2._GRID1.AfterRowColChange(1)	&& DupaRand -> EvalueazaRand(.F.) - vede SE_TESTEAZA, NU cheama AsteaptaTimer
	DOEVENTS FORCE
	lcCap = ALLTRIM(loFormS2.lb_anaf.Caption)
	IF gnANAFCallCount = lnInainte AND ANAF_StareServiciu() == 'SE_TESTEAZA' ;
			AND 'ANAF: se verifica' $ lcCap AND 'RO1112223' $ lcCap AND gnMockSondaPornireCount = 1
		DO VpaLog WITH 'PASS sonda-in-aer (S2): sonda in aer -> 0 apeluri ANAF, banda [' + lcCap + ']'
	ELSE
		DO VpaLog WITH 'FAIL sonda-in-aer (S2): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ' stare=' + ANAF_StareServiciu() + ;
			' banda=[' + lcCap + '] porniri-sonda=' + TRANSFORM(gnMockSondaPornireCount)
	ENDIF

	*-- inchide formularul CU sonda inca in aer (glMockSondaGataManual ramane .F.) - starea trebuie sa
	*-- revina la NECUNOSCUT, nu sa ramana blocata (fals) in SE_TESTEAZA sau sa treaca in CAZUT
	loVerifS2.Dezactiveaza()
	IF ANAF_StareServiciu() == 'NECUNOSCUT'
		DO VpaLog WITH 'PASS sonda-inchisa-in-aer (S2): formular inchis cu sonda in aer -> stare revine la NECUNOSCUT'
	ELSE
		DO VpaLog WITH 'FAIL sonda-inchisa-in-aer (S2): stare=' + ANAF_StareServiciu()
	ENDIF

	loFormS2.Release()
	IF USED('ctests2')
		USE IN ctests2
	ENDIF
	gcMockSondaModo = 'AUTO'
ENDPROC

PROCEDURE VerificaSondaReuseste
	*-- S3 (handoff_anaf_404.md, T5/sonda): sonda reuseste -> stare devine VIU si randul CURENT se
	*-- re-evalueaza SINGUR (fara navigare noua) - EvalueazaRand nu comite This.nIdPart cat timp
	*-- lcClasaEsec=='SE_TESTEAZA' (ocautare.prg), deci a doua evaluare pe acelasi rand nu iese
	*-- devreme pe "acelasi rand" si ajunge la verdictul real. Blocheaza verdictul lipit pe rand.
	LOCAL loFormS3, loVerifS3, lnOk, lcCap1, lcCap2
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'pregatire S3')
	gcMockSondaModo = 'MANUAL'
	glMockSondaGataManual = .F.
	glMockSondaReusitaManual = .T.

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctests3')
	loFormS3 = CREATEOBJECT('cauta_alfa_form', 'ctests3', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormS3.crs_cursor = 'ctests3'
	loFormS3.lAles = .F.
	loVerifS3 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormS3, 'oVerifAlegere', loVerifS3)
	loVerifS3.Activeaza(loFormS3)	&& NECUNOSCUT -> porneste sonda (mock) -> SE_TESTEAZA
	loFormS3.WindowType = 0
	loFormS3.Show()
	SELECT ctests3
	GO TOP
	loFormS3._GRID1.AfterRowColChange(1)
	DOEVENTS FORCE
	lcCap1 = ALLTRIM(loFormS3.lb_anaf.Caption)

	*-- raspunsul soseste, cu succes - FARA sa navighez randul din nou (acelasi rand, acelasi id_part)
	glMockSondaGataManual = .T.
	glMockSondaReusitaManual = .T.
	ANAF_SondaVerifica()	&& acelasi apel ca in anaf_timer.Timer, inaintea lui EvalueazaRand
	loVerifS3.VerificaRand(.F.)
	DOEVENTS FORCE
	lcCap2 = ALLTRIM(loFormS3.lb_anaf.Caption)

	IF 'ANAF: se verifica' $ lcCap1 AND ANAF_StareServiciu() == 'VIU' AND 'ANAF:' $ lcCap2 AND !('se verifica' $ lcCap2)
		DO VpaLog WITH 'PASS sonda-reuseste (S3): sonda reusita -> stare VIU, randul curent re-evaluat SINGUR (fara navigare noua) - [' + lcCap1 + '] -> [' + lcCap2 + ']'
	ELSE
		DO VpaLog WITH 'FAIL sonda-reuseste (S3): banda1=[' + lcCap1 + '] stare=' + ANAF_StareServiciu() + ' banda2=[' + lcCap2 + ']'
	ENDIF

	loVerifS3.Dezactiveaza()
	loFormS3.Release()
	IF USED('ctests3')
		USE IN ctests3
	ENDIF
	gcMockSondaModo = 'AUTO'
ENDPROC

PROCEDURE VerificaSondaExpira
	*-- S4 (handoff_anaf_404.md, T5/sonda): sonda ramane in aer peste termenul de viata (10s, masurat
	*-- fata de gtANAF_StareServiciuMoment, PUBLIC in ocautare.prg) -> stare CAZUT, nu ramane blocata
	*-- in SE_TESTEAZA. "Time travel" pe gtANAF_StareServiciuMoment (global de sesiune expus explicit
	*-- pentru asta), fara sa astept efectiv 10 secunde reale.
	LOCAL loFormS4, loVerifS4, lnOk, lcCap
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'pregatire S4')
	gcMockSondaModo = 'MANUAL'
	glMockSondaGataManual = .F.	&& sonda ramane in aer, nu raspunde niciodata

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdConcord), 'ctests4')
	loFormS4 = CREATEOBJECT('cauta_alfa_form', 'ctests4', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormS4.crs_cursor = 'ctests4'
	loFormS4.lAles = .F.
	loVerifS4 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormS4, 'oVerifAlegere', loVerifS4)
	loVerifS4.Activeaza(loFormS4)	&& NECUNOSCUT -> porneste sonda (mock) -> SE_TESTEAZA
	loFormS4.WindowType = 0
	loFormS4.Show()

	*-- da timpul inapoi cu 15s fata de momentul tranzitiei, ca sa simulez expirarea celor 10s fara
	*-- sa astept efectiv
	gtANAF_StareServiciuMoment = DATETIME() - 15

	ANAF_SondaVerifica()	&& acelasi apel ca in anaf_timer.Timer - constata expirarea si inchide sonda
	SELECT ctests4
	GO TOP
	loFormS4._GRID1.AfterRowColChange(1)
	DOEVENTS FORCE
	lcCap = ALLTRIM(loFormS4.lb_anaf.Caption)

	IF ANAF_StareServiciu() == 'CAZUT' AND 'ANAF nu a raspuns - verificare sarita' $ lcCap
		DO VpaLog WITH 'PASS sonda-expira (S4): sonda in aer peste 10s -> stare CAZUT, nu ramane blocata in SE_TESTEAZA - [' + lcCap + ']'
	ELSE
		DO VpaLog WITH 'FAIL sonda-expira (S4): stare=' + ANAF_StareServiciu() + ' banda=[' + lcCap + ']'
	ENDIF

	loVerifS4.Dezactiveaza()
	loFormS4.Release()
	IF USED('ctests4')
		USE IN ctests4
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa S4')
	gcMockSondaModo = 'AUTO'
ENDPROC

PROCEDURE VerificaCascadaOptiuni
	*-- REVIZIA 4 pct.1: ini '0' bate tot; utilizator bate firma; firma bate hardcodatul;
	*-- absent != 0 (H7); fara crsOptiuni/crsOptiuniUtilizator -> fara eroare (nivel hardcodat).
	LOCAL lcOptIni, lnNivel, llAveaRandFirma, lcValOrigFirma, llAveaRandUtil, lcValOrigUtil
	LOCAL lcAliasInainte, lcAliasDupa, llEroareCascada, loExcCasc

	lcOptIni = getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')
	llAveaRandFirma = .F.
	lcValOrigFirma = ''
	IF USED('crsOptiuni')
		SELECT crsOptiuni
		LOCATE FOR UPPER(ALLTRIM(varname)) = 'RC_ANAF_VERIF_SELECTIE'
		llAveaRandFirma = FOUND()
		IF llAveaRandFirma
			lcValOrigFirma = varvalue
		ENDIF
	ENDIF

	*=== a) kill-switch ini='0' bate tot (chiar cu firma=3) ===
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', '0')
	IF USED('crsOptiuni')
		SELECT crsOptiuni
		IF llAveaRandFirma
			REPLACE varvalue WITH '3'
		ELSE
			INSERT INTO crsOptiuni (varname, varvalue) VALUES ('RC_ANAF_VERIF_SELECTIE', '3')
		ENDIF
	ENDIF
	RELEASE goCacheANAF_Nivel
	lnNivel = ANAF_NivelVerificare()
	IF lnNivel = 0
		DO VpaLog WITH 'PASS cascada-kill-switch: ini=0 bate tot (firma=3) -> nivel=0'
	ELSE
		DO VpaLog WITH 'FAIL cascada-kill-switch: nivel=' + TRANSFORM(lnNivel) + ' astept=0'
	ENDIF

	*=== b) firma bate hardcodatul (fara kill-switch, fara utilizator) ===
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', '1')
	RELEASE goCacheANAF_Nivel
	lnNivel = ANAF_NivelVerificare()
	IF lnNivel = 3
		DO VpaLog WITH 'PASS cascada-firma: fara kill-switch, fara utilizator, firma=3 -> nivel=3 (bate hardcodatul 1)'
	ELSE
		DO VpaLog WITH 'FAIL cascada-firma: nivel=' + TRANSFORM(lnNivel) + ' astept=3'
	ENDIF

	*=== c) utilizator bate firma ===
	IF !USED('crsOptiuniUtilizator')
		=actualizeaza_optiuni_utilizator()
	ENDIF
	llAveaRandUtil = .F.
	lcValOrigUtil = ''
	IF USED('crsOptiuniUtilizator')
		SELECT crsOptiuniUtilizator
		LOCATE FOR UPPER(ALLTRIM(varname)) = 'RC_ANAF_VERIF_SELECTIE'
		llAveaRandUtil = FOUND()
		IF llAveaRandUtil
			lcValOrigUtil = varvalue
			REPLACE varvalue WITH '2'
		ELSE
			INSERT INTO crsOptiuniUtilizator (varname, varvalue) VALUES ('RC_ANAF_VERIF_SELECTIE', '2')
		ENDIF
	ENDIF
	RELEASE goCacheANAF_Nivel
	lnNivel = ANAF_NivelVerificare()
	IF lnNivel = 2
		DO VpaLog WITH 'PASS cascada-utilizator: utilizator=2 bate firma=3 -> nivel=2'
	ELSE
		DO VpaLog WITH 'FAIL cascada-utilizator: nivel=' + TRANSFORM(lnNivel) + ' astept=2'
	ENDIF

	*=== d) absent != 0 (H7): fara utilizator, fara firma -> hardcodat 1, NU 0 ===
	IF USED('crsOptiuniUtilizator')
		SELECT crsOptiuniUtilizator
		LOCATE FOR UPPER(ALLTRIM(varname)) = 'RC_ANAF_VERIF_SELECTIE'
		IF FOUND()
			IF llAveaRandUtil
				REPLACE varvalue WITH lcValOrigUtil
			ELSE
				DELETE
			ENDIF
		ENDIF
	ENDIF
	IF USED('crsOptiuni')
		SELECT crsOptiuni
		LOCATE FOR UPPER(ALLTRIM(varname)) = 'RC_ANAF_VERIF_SELECTIE'
		IF FOUND()
			IF llAveaRandFirma
				REPLACE varvalue WITH lcValOrigFirma
			ELSE
				DELETE
			ENDIF
		ENDIF
	ENDIF
	RELEASE goCacheANAF_Nivel
	lnNivel = ANAF_NivelVerificare()
	IF lnNivel = 1
		DO VpaLog WITH 'PASS cascada-absent (H7): fara ini-kill-switch/utilizator/firma -> nivel=1 (NU 0)'
	ELSE
		DO VpaLog WITH 'FAIL cascada-absent (H7): nivel=' + TRANSFORM(lnNivel) + ' astept=1'
	ENDIF

	*=== e) fara crsOptiuni/crsOptiuniUtilizator deloc -> fara eroare, nivel hardcodat, Alias() neschimbat ===
	*-- zona de lucru neutra INAINTE de a inchide cursoarele - altfel USE IN pe alias-ul curent
	*-- goleste singur Alias(), fals-negativ nelegat de H6 (ANAF_NivelVerificare nu e cauza).
	SELECT dual
	lcAliasInainte = ALIAS()
	llEroareCascada = .F.
	IF USED('crsOptiuniUtilizator')
		USE IN crsOptiuniUtilizator
	ENDIF
	IF USED('crsOptiuni')
		USE IN crsOptiuni
	ENDIF
	RELEASE goCacheANAF_Nivel
	TRY
		lnNivel = ANAF_NivelVerificare()
	CATCH TO loExcCasc
		llEroareCascada = .T.
		lnNivel = -99
	ENDTRY
	lcAliasDupa = ALIAS()
	IF !llEroareCascada AND lnNivel = 1
		DO VpaLog WITH 'PASS cascada-fara-cursoare: crsOptiuni/crsOptiuniUtilizator inchise -> fara eroare, nivel=1'
	ELSE
		DO VpaLog WITH 'FAIL cascada-fara-cursoare: eroare=' + TRANSFORM(llEroareCascada) + ' nivel=' + TRANSFORM(lnNivel)
	ENDIF
	IF lcAliasInainte == lcAliasDupa
		DO VpaLog WITH 'PASS cascada-alias (H6, fara cursoare): Alias() neschimbat [' + lcAliasDupa + ']'
	ELSE
		DO VpaLog WITH 'FAIL cascada-alias (H6, fara cursoare): inainte=[' + lcAliasInainte + '] dupa=[' + lcAliasDupa + ']'
	ENDIF

	*-- restaureaza mediul (numai date locale/ini - nicio scriere in Oracle in aceasta procedura)
	=actualizeaza_optiuni()
	=actualizeaza_optiuni_utilizator()
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', NVL(lcOptIni, ''))
	RELEASE goCacheANAF_Nivel
ENDPROC

PROCEDURE VerificaGatingNivel
	*-- REVIZIA 4 pct.2/3/12: replica gating-ul din CautPartenerContabilitate (ocautare.prg:834-844).
	LOCAL lVerificaANAF, lnNivelANAF, lnInainte, lcOptIni, loFormG, lnOk, lcCapG, llLabelOk, llRezG
	PRIVATE poVerifAlegereG
	poVerifAlegereG = .NULL.

	*=== 12) regresie: apelant FARA lVerificaANAF=>1 -> poVerifAlegere ramane .NULL. ===
	lVerificaANAF = .F.
	IF m.lVerificaANAF
		lnNivelANAF = ANAF_NivelVerificare()
		IF m.lnNivelANAF > 0
			poVerifAlegereG = CREATEOBJECT('anaf_verif_cautare')
		ENDIF
	ENDIF
	IF ISNULL(poVerifAlegereG)
		DO VpaLog WITH 'PASS gating-regresie (12): lVerificaANAF=.F. -> poVerifAlegere ramane .NULL.'
	ELSE
		DO VpaLog WITH 'FAIL gating-regresie (12): poVerifAlegere s-a instantiat fara lVerificaANAF=>1'
	ENDIF

	*=== 3) nivel 0 (kill-switch): opt-in cerut, dar nivelul=0 -> poVerifAlegere ramane .NULL., 0 apeluri ===
	lcOptIni = getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', '0')
	RELEASE goCacheANAF_Nivel
	poVerifAlegereG = .NULL.
	lVerificaANAF = .T.
	lnInainte = gnANAFCallCount
	IF m.lVerificaANAF
		lnNivelANAF = ANAF_NivelVerificare()
		IF m.lnNivelANAF > 0
			poVerifAlegereG = CREATEOBJECT('anaf_verif_cautare')
		ENDIF
	ENDIF
	IF ISNULL(poVerifAlegereG) AND lnNivelANAF = 0 AND gnANAFCallCount = lnInainte
		DO VpaLog WITH 'PASS gating-nivel0 (3): kill-switch=0, opt-in -> poVerifAlegere ramane .NULL., 0 apeluri ANAF'
	ELSE
		DO VpaLog WITH 'FAIL gating-nivel0 (3): nivel=' + TRANSFORM(lnNivelANAF) + ' poVerifAlegere=' + TRANSFORM(VARTYPE(poVerifAlegereG)) + ' apeluri=' + TRANSFORM(gnANAFCallCount-lnInainte)
	ENDIF
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', NVL(lcOptIni,''))
	RELEASE goCacheANAF_Nivel

	*=== 2) nivel 1 (implicit): label prezent, VerificaAlegere NU face apel HTTP la alegere ===
	lnNivelANAF = ANAF_NivelVerificare()
	IF lnNivelANAF <= 0 OR lnNivelANAF >= 3
		DO VpaLog WITH 'FAIL gating-nivel1 (2): mediul nu e la nivelul implicit asteptat (nivel=' + TRANSFORM(lnNivelANAF) + '), test omis'
	ELSE
		lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
			[WHERE ID_PART = ] + TRANSFORM(gnIdDiscord), 'ctestgating1')
		loFormG = CREATEOBJECT('cauta_alfa_form', 'ctestgating1', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
			'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
		loFormG.crs_cursor = 'ctestgating1'
		loFormG.lAles = .F.
		poVerifAlegereG = CREATEOBJECT('anaf_verif_cautare')
		ADDPROPERTY(loFormG, 'oVerifAlegere', poVerifAlegereG)
		poVerifAlegereG.nNivel = lnNivelANAF
		poVerifAlegereG.Activeaza(loFormG)
		loFormG.WindowType = 0
		loFormG.Show()
		SELECT ctestgating1
		GO TOP
		loFormG._GRID1.AfterRowColChange(1)
		DO AsteaptaTimer WITH poVerifAlegereG
		lcCapG = ALLTRIM(loFormG.lb_anaf.Caption)
		llLabelOk = 'ANAF:' $ lcCapG
		lnInainte = gnANAFCallCount
		llRezG = poVerifAlegereG.VerificaAlegere(loFormG)
		IF llLabelOk AND llRezG AND gnANAFCallCount = lnInainte
			DO VpaLog WITH 'PASS gating-nivel1 (2): label prezent [' + lcCapG + '], VerificaAlegere -> 0 apeluri ANAF noi, llRez=.T.'
		ELSE
			DO VpaLog WITH 'FAIL gating-nivel1 (2): label=[' + lcCapG + '] llRez=' + TRANSFORM(llRezG) + ' apeluri=' + TRANSFORM(gnANAFCallCount-lnInainte)
		ENDIF
		poVerifAlegereG.Dezactiveaza()
		loFormG.Release()
		IF USED('ctestgating1')
			USE IN ctestgating1
		ENDIF
	ENDIF
ENDPROC

PROCEDURE VerificaC2Renunta
	*-- REVIZIA 4 C2 (cel mai important): poANAFInlocuire setat + gnbuton=2 (Renunta) =>
	*-- AplicaInlocuirePartenerANAF NU se apeleaza, obiectul intors ramane blank (id_part=0).
	LOCAL loCauta
	PRIVATE poANAFInlocuire, gnbuton
	poANAFInlocuire = CREATEOBJECT('Empty')
	ADDPROPERTY(poANAFInlocuire, 'nIdPart', gnIdPereche)
	ADDPROPERTY(poANAFInlocuire, 'cDenumire', 'TEST ANAF DISCORD SRL')
	ADDPROPERTY(poANAFInlocuire, 'cCodFiscal', 'RO7654320')
	loCauta = CREATEOBJECT('Empty')
	ADDPROPERTY(loCauta, 'id_part', 0)
	ADDPROPERTY(loCauta, 'denumire', '')
	ADDPROPERTY(loCauta, 'nume', '')
	ADDPROPERTY(loCauta, 'cod_fiscal', '')

	gnbuton = 2	&& Renunta - utilizatorul a ales o varianta in Detalii, apoi a anulat cautarea
	*-- replica exact garda din CautPartenerContabilitate (ocautare.prg:848-850)
	IF TYPE('gnbuton') = 'N' AND gnbuton = 1
		AplicaInlocuirePartenerANAF(loCauta, poANAFInlocuire, '')
	ENDIF
	IF loCauta.id_part = 0 AND EMPTY(loCauta.cod_fiscal)
		DO VpaLog WITH 'PASS C2-renunta: gnbuton=2 -> AplicaInlocuirePartenerANAF NU se apeleaza, obiectul ramane blank (id_part=0)'
	ELSE
		DO VpaLog WITH 'FAIL C2-renunta: id_part=' + TRANSFORM(loCauta.id_part) + ' cod_fiscal=[' + loCauta.cod_fiscal + ']'
	ENDIF

	*-- control: cu gnbuton=1, acelasi poANAFInlocuire CHIAR se aplica
	gnbuton = 1
	IF TYPE('gnbuton') = 'N' AND gnbuton = 1
		AplicaInlocuirePartenerANAF(loCauta, poANAFInlocuire, '')
	ENDIF
	IF loCauta.id_part = gnIdPereche AND loCauta.cod_fiscal == 'RO7654320'
		DO VpaLog WITH 'PASS C2-control: gnbuton=1 -> AplicaInlocuirePartenerANAF SE aplica (id_part=' + TRANSFORM(loCauta.id_part) + ')'
	ELSE
		DO VpaLog WITH 'FAIL C2-control: id_part=' + TRANSFORM(loCauta.id_part) + ' cod_fiscal=[' + loCauta.cod_fiscal + ']'
	ENDIF
ENDPROC

PROCEDURE VerificaH2EroareListaCorecti
	*-- H2: ANAF_CautaPereche esuat (mock pe goExecutor) => mesaj de eroare, FARA sugestia "Nou".
	LOCAL loReal, lnLenInainte, lcLog, loExcH2
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	loReal = goExecutor
	goExecutor = CREATEOBJECT('dummyexecutorH2test')
	goExecutor.oReal = loReal
	lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
	lcLog = ''
	TRY
		poVerifAlegere.Detalii()
		lcLog = SUBSTR(FILETOSTR(gcUILog), lnLenInainte + 1)
	CATCH TO loExcH2
		lcLog = 'EXCEPTIE: ' + loExcH2.Message
	FINALLY
		goExecutor = loReal
	ENDTRY

	IF 'MOCK amessagebox' $ lcLog AND 'Nu s-a putut citi lista de parteneri.' $ lcLog AND !('Nou' $ lcLog)
		DO VpaLog WITH 'PASS H2-eroare-lista: ANAF_CautaPereche esuat -> mesaj eroare, fara sugestia Nou'
	ELSE
		DO VpaLog WITH 'FAIL H2-eroare-lista: log=[' + lcLog + ']'
	ENDIF
ENDPROC

PROCEDURE VerificaDetaliiStareNula
	*-- Detalii cu oStare=.Null. (ANAF picat/cod invalid) => se deschide, cu linia explicativa.
	LOCAL lnLenInainte, lcLog
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	poVerifAlegere.oStare = .NULL.
	lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
	poVerifAlegere.Detalii()
	lcLog = SUBSTR(FILETOSTR(gcUILog), lnLenInainte + 1)
	IF 'MOCK amessagebox' $ lcLog AND 'ANAF nu a raspuns - verificarea a fost sarita.' $ lcLog
		DO VpaLog WITH 'PASS detalii-stare-nula (7): oStare=.Null. -> se deschide, cu linia explicativa'
	ELSE
		DO VpaLog WITH 'FAIL detalii-stare-nula (7): log=[' + lcLog + ']'
	ENDIF
ENDPROC

PROCEDURE VerificaDiscriminatorDocumente
	*-- discriminatorul "are documente in perioada" (mock pe goExecutor - IREG_PARTENERI), cu si fara randuri.
	LOCAL loReal, lnLenInainte, lcLog1, lcLog2, loExcDoc
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer

	loReal = goExecutor
	goExecutor = CREATEOBJECT('dummyexecutordoctest')
	goExecutor.oReal = loReal
	lcLog1 = ''
	lcLog2 = ''
	TRY
		goExecutor.nIdsConDocumente = 0
		lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
		poVerifAlegere.Detalii()
		lcLog1 = SUBSTR(FILETOSTR(gcUILog), lnLenInainte + 1)

		*-- primul Detalii s-a incheiat cu do_termin() - reface formularul inainte de al doilea
		goExecutor = loReal
		DO PregatesteFormularD1a
		SELECT ctestparteneri
		LOCATE FOR id_part = gnIdDiscord
		goFormT._GRID1.AfterRowColChange(1)
		DO AsteaptaTimer
		goExecutor = CREATEOBJECT('dummyexecutordoctest')
		goExecutor.oReal = loReal

		goExecutor.nIdsConDocumente = gnIdPereche
		lnLenInainte = IIF(FILE(gcUILog), LEN(FILETOSTR(gcUILog)), 0)
		poVerifAlegere.Detalii()
		lcLog2 = SUBSTR(FILETOSTR(gcUILog), lnLenInainte + 1)
	CATCH TO loExcDoc
		lcLog1 = 'EXCEPTIE: ' + loExcDoc.Message
		lcLog2 = lcLog1
	FINALLY
		goExecutor = loReal
	ENDTRY

	IF 'MOCK amessagebox' $ lcLog1 AND !('are documente in perioada' $ lcLog1)
		DO VpaLog WITH 'PASS discriminator-fara-documente (8): niciun candidat marcat "are documente in perioada"'
	ELSE
		DO VpaLog WITH 'FAIL discriminator-fara-documente (8): log=[' + lcLog1 + ']'
	ENDIF

	IF ('1. TEST ANAF DISCORD SRL (ID: ' + TRANSFORM(gnIdPereche) + ')  inactiv  are documente in perioada') $ lcLog2 ;
			AND !(('2. TEST ANAF SPATIU SRL (ID: ' + TRANSFORM(gnIdSpatiu) + ')  are documente in perioada') $ lcLog2)
		DO VpaLog WITH 'PASS discriminator-cu-documente (8): perechea marcata "are documente in perioada", spatiu nu'
	ELSE
		DO VpaLog WITH 'FAIL discriminator-cu-documente (8): log=[' + lcLog2 + ']'
	ENDIF
ENDPROC

PROCEDURE VerificaB1LabelGolit
	*-- B1: verdictul anterior nu ramane pe ecran cand cautarea nu mai are rezultate.
	LOCAL lcCapInainte, lcCapDupa
	DO PregatesteFormularD1a
	SELECT ctestparteneri
	LOCATE FOR id_part = gnIdDiscord
	goFormT._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer
	lcCapInainte = ALLTRIM(goFormT.lb_anaf.Caption)

	SELECT ctestparteneri
	ZAP
	poVerifAlegere.VerificaRand(.F.)
	lcCapDupa = ALLTRIM(goFormT.lb_anaf.Caption)

	*-- banda nu ramane goala: fara rezultate revine la textul neutru, nu la verdictul anterior
	IF !EMPTY(lcCapInainte) AND lcCapDupa == CHR(149) + '  Verificare ANAF la alegerea partenerului (F4 = detalii)'
		DO VpaLog WITH 'PASS B1-label-golit (9): verdict anterior [' + lcCapInainte + '] -> text neutru dupa cautare fara rezultate'
	ELSE
		DO VpaLog WITH 'FAIL B1-label-golit (9): inainte=[' + lcCapInainte + '] dupa=[' + lcCapDupa + ']'
	ENDIF
ENDPROC

PROCEDURE VerificaComutareOptiune
	*-- ANAF_ComutaVerificare scrie valoarea corecta si are efect imediat (10/11), Alias() neschimbat (H6).
	LOCAL lcOptIni, lnNivelInainte, lnNivelDupa, lcAliasInainte, lcAliasDupa, llAveaRand, lcValOrig
	lcOptIni = getini(gcGeneralIniFile, 'anaf', 'verificare_selectie')
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', '')
	IF !USED('crsOptiuniUtilizator')
		=actualizeaza_optiuni_utilizator()
	ENDIF
	llAveaRand = .F.
	lcValOrig = ''
	SELECT crsOptiuniUtilizator
	LOCATE FOR UPPER(ALLTRIM(varname)) = 'RC_ANAF_VERIF_SELECTIE'
	llAveaRand = FOUND()
	IF llAveaRand
		lcValOrig = varvalue
		REPLACE varvalue WITH '1'
	ELSE
		INSERT INTO crsOptiuniUtilizator (varname, varvalue) VALUES ('RC_ANAF_VERIF_SELECTIE', '1')
	ENDIF
	RELEASE goCacheANAF_Nivel
	lnNivelInainte = ANAF_NivelVerificare()

	gnMockRaspuns = 6
	gnMockInputBox = 0	&& valoarea noua ceruta in aInputBox
	lcAliasInainte = ALIAS()
	ANAF_ComutaVerificare()	&& intrare unica: arata valoarea curenta, cere valoarea noua (0)
	lcAliasDupa = ALIAS()
	lnNivelDupa = ANAF_NivelVerificare()	&& fara Release manual - trebuie sa se invalideze singur

	IF lnNivelInainte = 1 AND lnNivelDupa = 0
		DO VpaLog WITH 'PASS comutare-optiune (11): valoare noua 0 scrisa, efect imediat (cache invalidat automat)'
	ELSE
		DO VpaLog WITH 'FAIL comutare-optiune (11): nivelInainte=' + TRANSFORM(lnNivelInainte) + ' nivelDupa=' + TRANSFORM(lnNivelDupa)
	ENDIF
	IF lcAliasInainte == lcAliasDupa
		DO VpaLog WITH 'PASS comutare-alias (10/H6): Alias() neschimbat de ANAF_ComutaVerificare [' + lcAliasDupa + ']'
	ELSE
		DO VpaLog WITH 'FAIL comutare-alias (10/H6): inainte=[' + lcAliasInainte + '] dupa=[' + lcAliasDupa + ']'
	ENDIF

	RELEASE goCacheANAF_Nivel
	SELECT crsOptiuniUtilizator
	LOCATE FOR UPPER(ALLTRIM(varname)) = 'RC_ANAF_VERIF_SELECTIE'
	IF FOUND()
		REPLACE varvalue WITH '1'
	ENDIF
	RELEASE goCacheANAF_Nivel
	gnMockInputBox = 3
	ANAF_ComutaVerificare()	&& valoare noua 3, pornind de la 1
	lnNivelDupa = ANAF_NivelVerificare()
	IF lnNivelDupa = 3
		DO VpaLog WITH 'PASS comutare-optiune2 (11): valoare noua 3 scrisa'
	ELSE
		DO VpaLog WITH 'FAIL comutare-optiune2 (11): nivelDupa=' + TRANSFORM(lnNivelDupa)
	ENDIF

	*-- 9 = oprire pe calculatorul curent (settings.ini), fara sa atinga optiunea utilizatorului
	RELEASE goCacheANAF_Nivel
	gnMockInputBox = 9
	ANAF_ComutaVerificare()
	lnNivelDupa = ANAF_NivelVerificare()
	IF lnNivelDupa = 0 AND ALLTRIM(NVL(getini(gcGeneralIniFile, 'anaf', 'verificare_selectie'), '')) == '0'
		DO VpaLog WITH 'PASS comutare-ini (11): valoarea 9 scrie settings.ini=0, nivel efectiv 0'
	ELSE
		DO VpaLog WITH 'FAIL comutare-ini (11): nivelDupa=' + TRANSFORM(lnNivelDupa) + ' ini=[' + ALLTRIM(NVL(getini(gcGeneralIniFile, 'anaf', 'verificare_selectie'), '')) + ']'
	ENDIF

	*-- alegerea unei valori 0/1/3 cand ini=0 trebuie sa ridice si kill-switch-ul, altfel optiunea ramane inoperanta
	RELEASE goCacheANAF_Nivel
	gnMockInputBox = 1
	ANAF_ComutaVerificare()
	lnNivelDupa = ANAF_NivelVerificare()
	IF lnNivelDupa = 1 AND !(ALLTRIM(NVL(getini(gcGeneralIniFile, 'anaf', 'verificare_selectie'), '')) == '0')
		DO VpaLog WITH 'PASS comutare-ini-ridicat (11): valoarea 1 ridica kill-switch-ul din settings.ini, nivel efectiv 1'
	ELSE
		DO VpaLog WITH 'FAIL comutare-ini-ridicat (11): nivelDupa=' + TRANSFORM(lnNivelDupa) + ' ini=[' + ALLTRIM(NVL(getini(gcGeneralIniFile, 'anaf', 'verificare_selectie'), '')) + ']'
	ENDIF

	*-- restaureaza (scriere reala in Oracle, pt. utilizatorul de test gnIdUtil=-3)
	scrie_optiune_utilizator('RC_ANAF_VERIF_SELECTIE', NVL(lcValOrig,''), 'Intreaba la alegerea unui partener discordant')
	=actualizeaza_optiuni_utilizator()
	=setini(gcGeneralIniFile, 'anaf', 'verificare_selectie', NVL(lcOptIni,''))
	RELEASE goCacheANAF_Nivel
ENDPROC

PROCEDURE InsereazaIstoricTest
	*-- S12: insereaza un rand in ISTORIC_CODURI_FISCALE prin pack_parteneri.save_istoric_cod_fiscal
	*-- (26 parametri, acelasi apel ca in validare.prg), cu scpTVA activ din tdInceput - cel putin o
	*-- data de interval, altfel DATAORAV_ANAF ramane null si randul nu conteaza ca proaspat (contract
	*-- -cache-anaf.md 2.3). Fara CREATEOBJECT/ADDPROPERTY (doar variabile Private + goExecutor.oExecuta),
	*-- deci sigura de apelat dintr-o PROCEDURA (spre deosebire de capcana l). Intoarce .T./.F.
	LPARAMETERS tcCui, tcFirma, tdInceput
	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
	LOCAL lcSqlIstoric, llOk
	pcCodFiscal = m.tcCui
	pcFirma = m.tcFirma
	pcAdresa = ''
	pcJudet = ''
	pcRegCom = ''
	pcCodPostal = ''
	pcTelefon = ''
	pcFax = ''
	pcDataTvamfin = ''
	pnPlatitorTvaMfin = 0
	pcStare = ''
	pnPlatitorTvaVies = 0
	pnInterogareVies = 0
	pnIdUtil = 0
	pnInactiv = 0
	pnTvaIncasare = 0
	pnSplitTva = 0
	pdInceputScpTva = m.tdInceput
	pdSfarsitScpTva = {}
	pdAnulImpScpTva = {}
	pdInceputTvaInc = {}
	pdSfarsitTvaInc = {}
	pdInactivare = {}
	pdReactivare = {}
	pdInceputSplitTva = {}
	pdAnulareSplitTva = {}
	lcSqlIstoric = "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); end;"
	llOk = goExecutor.oExecuta(m.lcSqlIstoric)
	IF m.llOk
		=goExecutor.oExecuta('COMMIT')
	ENDIF
	RETURN m.llOk
ENDPROC

PROCEDURE VerificaCacheIndispIstoricPopulat
	*-- S12 scenariile 1+6 (contract-cache-anaf.md, plasa S9): ANAF cazut + istoric proaspat pt.
	*-- acelasi CUI -> verdict citit din istoric, etichetat CACHE_INDISP, cu dDataSursa completat si
	*-- sufixul "ANAF indisponibil" pe banda; AL DOILEA apel (formular nou, acelasi CUI) vine din
	*-- goCacheANAF_Sesiune, FARA o a doua interogare pe ISTORIC_CODURI_FISCALE (contor prin dummy
	*-- executor, acelasi tipar ca H2/discriminatorul de documente, mai sus in fisier).
	LOCAL loFormP, loVerifP, lnOk, lcCapP, lnInainte, llInsP, loReal, loFormP2, loVerifP2, lnOk2, loDummy, loExcP2
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	llInsP = InsereazaIstoricTest('8000090', 'TEST S12 CACHE POPULAT SRL', {^2020-01-01})
	IF !m.llInsP
		DO VpaLog WITH 'FAIL cache-indisp-populat (S12/1): insert istoric esuat - ' + goExecutor.cEroare
		RETURN
	ENDIF
	ANAF_SeteazaStareServiciu('CAZUT', 'test S12/1')

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCacheA), 'ctests12a')
	loFormP = CREATEOBJECT('cauta_alfa_form', 'ctests12a', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormP.crs_cursor = 'ctests12a'
	loFormP.lAles = .F.
	loVerifP = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormP, 'oVerifAlegere', loVerifP)
	loVerifP.Activeaza(loFormP)
	loFormP.WindowType = 0
	loFormP.Show()
	SELECT ctests12a
	GO TOP
	lnInainte = gnANAFCallCount
	loFormP._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifP
	lcCapP = ALLTRIM(loFormP.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte AND VARTYPE(loVerifP.oStare) = 'O' AND loVerifP.oStare.cSursa == 'CACHE_INDISP' ;
			AND !EMPTY(loVerifP.oStare.dDataSursa) AND 'ANAF indisponibil' $ lcCapP AND 'date din' $ lcCapP
		DO VpaLog WITH 'PASS cache-indisp-populat (S12/1): ANAF cazut + istoric proaspat -> cSursa=CACHE_INDISP, dDataSursa=' + ;
			DTOC(loVerifP.oStare.dDataSursa) + ', banda=[' + lcCapP + '], 0 apeluri ANAF noi'
	ELSE
		DO VpaLog WITH 'FAIL cache-indisp-populat (S12/1): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' oStare=' + TRANSFORM(VARTYPE(loVerifP.oStare)) + ' banda=[' + lcCapP + ']'
	ENDIF

	*-- scenariul 6: al doilea apel, pe formular NOU, acelasi CUI - trebuie servit din goCacheANAF_Sesiune,
	*-- FARA o a doua interogare pe ISTORIC_CODURI_FISCALE.
	loReal = goExecutor
	loDummy = CREATEOBJECT('dummyexecutoristorictest')
	loDummy.oReal = loReal
	goExecutor = loDummy
	TRY
		lnOk2 = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
			[WHERE ID_PART = ] + TRANSFORM(gnIdCacheA), 'ctests12a2')
		loFormP2 = CREATEOBJECT('cauta_alfa_form', 'ctests12a2', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
			'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
		loFormP2.crs_cursor = 'ctests12a2'
		loFormP2.lAles = .F.
		loVerifP2 = CREATEOBJECT('anaf_verif_cautare')
		ADDPROPERTY(loFormP2, 'oVerifAlegere', loVerifP2)
		loVerifP2.Activeaza(loFormP2)
		loFormP2.WindowType = 0
		loFormP2.Show()
		SELECT ctests12a2
		GO TOP
		loFormP2._GRID1.AfterRowColChange(1)
		DO AsteaptaTimer WITH loVerifP2
	CATCH TO loExcP2
		DO VpaLog WITH 'FAIL cache-sesiune-fara-oracle (S12/6, EXCEPTIE): ' + loExcP2.Message
	FINALLY
		goExecutor = loReal
	ENDTRY

	IF VARTYPE(loVerifP2.oStare) = 'O' AND loVerifP2.oStare.cSursa == 'CACHE_INDISP' AND loDummy.nIstoricQueryCount = 0
		DO VpaLog WITH 'PASS cache-sesiune-fara-oracle (S12/6): al doilea apel (formular nou, acelasi CUI) servit din goCacheANAF_Sesiune, 0 interogari noi pe ISTORIC_CODURI_FISCALE'
	ELSE
		DO VpaLog WITH 'FAIL cache-sesiune-fara-oracle (S12/6): oStare=' + TRANSFORM(VARTYPE(loVerifP2.oStare)) + ;
			' interogari-istoric=' + TRANSFORM(loDummy.nIstoricQueryCount)
	ENDIF

	TRY
		loVerifP.Dezactiveaza()
		loVerifP2.Dezactiveaza()
	CATCH
	ENDTRY
	loFormP.Release()
	loFormP2.Release()
	IF USED('ctests12a')
		USE IN ctests12a
	ENDIF
	IF USED('ctests12a2')
		USE IN ctests12a2
	ENDIF
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark, prin StergeIstoricV2UI (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	=StergeIstoricV2UI("COD_FISCAL = '8000090'")
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa S12/1')
ENDPROC

PROCEDURE VerificaCacheIndispIstoricGol
	*-- S12 scenariul 2: ANAF cazut, istoric FARA niciun rand pt. CUI -> comportament identic cu azi
	*-- (.NULL., banda "ANAF nu a raspuns - verificare sarita"), fara eticheta de cache.
	LOCAL loFormG, loVerifG, lnOk, lcCapG, lnInainte
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	ANAF_SeteazaStareServiciu('CAZUT', 'test S12/2')

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCacheB), 'ctests12b')
	loFormG = CREATEOBJECT('cauta_alfa_form', 'ctests12b', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormG.crs_cursor = 'ctests12b'
	loFormG.lAles = .F.
	loVerifG = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormG, 'oVerifAlegere', loVerifG)
	loVerifG.Activeaza(loFormG)
	loFormG.WindowType = 0
	loFormG.Show()
	SELECT ctests12b
	GO TOP
	lnInainte = gnANAFCallCount
	loFormG._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifG
	lcCapG = ALLTRIM(loFormG.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte AND ISNULL(loVerifG.oStare) AND 'ANAF nu a raspuns - verificare sarita' $ lcCapG
		DO VpaLog WITH 'PASS cache-indisp-istoric-gol (S12/2): ANAF cazut, istoric gol -> .NULL., banda identica cu azi [' + lcCapG + ']'
	ELSE
		DO VpaLog WITH 'FAIL cache-indisp-istoric-gol (S12/2): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' oStare=' + TRANSFORM(VARTYPE(loVerifG.oStare)) + ' banda=[' + lcCapG + ']'
	ENDIF

	loVerifG.Dezactiveaza()
	loFormG.Release()
	IF USED('ctests12b')
		USE IN ctests12b
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa S12/2')
ENDPROC

PROCEDURE VerificaCacheIndispIstoricVechi
	*-- S12 scenariul 3: ANAF cazut, istoric are un rand pt. CUI dar DATAORAV_ANAF mai vechi decat
	*-- ANAFCACHEZILE (30 zile implicit) -> filtrul din CitesteIstoricPentruCoduri il exclude, deci
	*-- comportamentul ramane identic cu istoricul gol (.NULL.).
	LOCAL loFormV, loVerifV, lnOk, lcCapV, lnInainte, llInsV
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	llInsV = InsereazaIstoricTest('8000294', 'TEST S12 CACHE VECHI SRL', {^2020-01-01})
	IF !m.llInsV
		DO VpaLog WITH 'FAIL cache-indisp-istoric-vechi (S12/3): insert istoric esuat - ' + goExecutor.cEroare
		RETURN
	ENDIF
	*-- imbatraneste DATAORAV_ANAF direct in Oracle - numai randul propriu de test (COD_FISCAL='8000294')
	=goExecutor.oExecuta("UPDATE ISTORIC_CODURI_FISCALE SET DATAORAV_ANAF = SYSDATE - 40 WHERE COD_FISCAL = '8000294'")
	=goExecutor.oExecuta('COMMIT')
	ANAF_SeteazaStareServiciu('CAZUT', 'test S12/3')

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCacheC), 'ctests12c')
	loFormV = CREATEOBJECT('cauta_alfa_form', 'ctests12c', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormV.crs_cursor = 'ctests12c'
	loFormV.lAles = .F.
	loVerifV = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormV, 'oVerifAlegere', loVerifV)
	loVerifV.Activeaza(loFormV)
	loFormV.WindowType = 0
	loFormV.Show()
	SELECT ctests12c
	GO TOP
	lnInainte = gnANAFCallCount
	loFormV._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifV
	lcCapV = ALLTRIM(loFormV.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte AND ISNULL(loVerifV.oStare) AND 'ANAF nu a raspuns - verificare sarita' $ lcCapV
		DO VpaLog WITH 'PASS cache-indisp-istoric-vechi (S12/3): istoric 40 zile (peste ANAFCACHEZILE=30) -> .NULL., nu se ofera nimic [' + lcCapV + ']'
	ELSE
		DO VpaLog WITH 'FAIL cache-indisp-istoric-vechi (S12/3): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' oStare=' + TRANSFORM(VARTYPE(loVerifV.oStare)) + ' banda=[' + lcCapV + ']'
	ENDIF

	loVerifV.Dezactiveaza()
	loFormV.Release()
	IF USED('ctests12c')
		USE IN ctests12c
	ENDIF
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark, prin StergeIstoricV2UI (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	=StergeIstoricV2UI("COD_FISCAL = '8000294'")
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa S12/3')
ENDPROC

PROCEDURE VerificaCodInexistentNuAtingeCache
	*-- S12 scenariul 4: cod fiscal valid ca structura dar negasit la ANAF (tlNegasit) -> verdict
	*-- "inexistent", istoricul NU e atins deloc (nici citit, nici folosit ca plasa) - chiar daca exista
	*-- un rand proaspat pt. acelasi CUI. Contor de interogari pe ISTORIC_CODURI_FISCALE prin dummy
	*-- executor (acelasi tipar ca H2/discriminatorul de documente, mai sus in fisier).
	LOCAL loFormN, loVerifN, lnOk, lcCapN, llInsN, loReal, loDummy, loExcN4
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	llInsN = InsereazaIstoricTest('9000039', 'TEST S12 NU TREBUIE FOLOSIT SRL', {^2020-01-01})
	IF !m.llInsN
		DO VpaLog WITH 'FAIL cod-inexistent-nu-atinge-cache (S12/4): insert istoric esuat - ' + goExecutor.cEroare
		RETURN
	ENDIF

	loReal = goExecutor
	loDummy = CREATEOBJECT('dummyexecutoristorictest')
	loDummy.oReal = loReal
	goExecutor = loDummy
	TRY
		lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
			[WHERE ID_PART = ] + TRANSFORM(gnIdInexistent), 'ctests12d')
		loFormN = CREATEOBJECT('cauta_alfa_form', 'ctests12d', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
			'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
		loFormN.crs_cursor = 'ctests12d'
		loFormN.lAles = .F.
		loVerifN = CREATEOBJECT('anaf_verif_cautare')
		ADDPROPERTY(loFormN, 'oVerifAlegere', loVerifN)
		loVerifN.Activeaza(loFormN)
		loFormN.WindowType = 0
		loFormN.Show()
		SELECT ctests12d
		GO TOP
		loFormN._GRID1.AfterRowColChange(1)
		DO AsteaptaTimer WITH loVerifN
		lcCapN = ALLTRIM(loFormN.lb_anaf.Caption)
	CATCH TO loExcN4
		lcCapN = 'EXCEPTIE: ' + loExcN4.Message
	FINALLY
		goExecutor = loReal
	ENDTRY

	IF 'Cod fiscal inexistent la ANAF (9000039)' $ lcCapN AND loDummy.nIstoricQueryCount = 0
		DO VpaLog WITH 'PASS cod-inexistent-nu-atinge-cache (S12/4): verdict inexistent, 0 interogari pe ISTORIC_CODURI_FISCALE (istoric avea rand proaspat, neatins) - [' + lcCapN + ']'
	ELSE
		DO VpaLog WITH 'FAIL cod-inexistent-nu-atinge-cache (S12/4): banda=[' + lcCapN + '] interogari-istoric=' + TRANSFORM(loDummy.nIstoricQueryCount)
	ENDIF

	TRY
		loVerifN.Dezactiveaza()
	CATCH
	ENDTRY
	loFormN.Release()
	IF USED('ctests12d')
		USE IN ctests12d
	ENDIF
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark, prin StergeIstoricV2UI (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	=StergeIstoricV2UI("COD_FISCAL = '9000039'")
ENDPROC

PROCEDURE VerificaSeTesteazaNuAtingeCache
	*-- S12 scenariul 5: sonda in aer (stare SE_TESTEAZA) ramane neschimbata dupa S9 - randul NU face
	*-- apel ANAF propriu si NU atinge istoricul (spre deosebire de CAZUT/FARA_RASPUNS, care citesc din
	*-- cache); banda ramane "ANAF: se verifica ...", nu devine CACHE_INDISP.
	LOCAL loFormT5, loVerifT5, lnOk, lcCapT5, lnInainte, llInsT5
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	llInsT5 = InsereazaIstoricTest('8000391', 'TEST S12 CACHE SONDA SRL', {^2020-01-01})
	IF !m.llInsT5
		DO VpaLog WITH 'FAIL se-testeaza-nu-atinge-cache (S12/5): insert istoric esuat - ' + goExecutor.cEroare
		RETURN
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'pregatire S12/5')
	gcMockSondaModo = 'MANUAL'
	glMockSondaGataManual = .F.

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCacheD), 'ctests12e')
	loFormT5 = CREATEOBJECT('cauta_alfa_form', 'ctests12e', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormT5.crs_cursor = 'ctests12e'
	loFormT5.lAles = .F.
	loVerifT5 = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormT5, 'oVerifAlegere', loVerifT5)
	loVerifT5.Activeaza(loFormT5)	&& NECUNOSCUT -> porneste sonda (mock) -> SE_TESTEAZA
	loFormT5.WindowType = 0
	loFormT5.Show()
	SELECT ctests12e
	GO TOP
	lnInainte = gnANAFCallCount
	loFormT5._GRID1.AfterRowColChange(1)
	DOEVENTS FORCE
	lcCapT5 = ALLTRIM(loFormT5.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte AND ANAF_StareServiciu() == 'SE_TESTEAZA' AND 'ANAF: se verifica' $ lcCapT5 ;
			AND (ISNULL(loVerifT5.oStare) OR loVerifT5.oStare.cSursa <> 'CACHE_INDISP')
		DO VpaLog WITH 'PASS se-testeaza-nu-atinge-cache (S12/5): sonda in aer -> neschimbat, banda [' + lcCapT5 + '], nu trece prin cache desi istoricul are rand proaspat'
	ELSE
		DO VpaLog WITH 'FAIL se-testeaza-nu-atinge-cache (S12/5): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' stare=' + ANAF_StareServiciu() + ' banda=[' + lcCapT5 + ']'
	ENDIF

	loVerifT5.Dezactiveaza()
	loFormT5.Release()
	IF USED('ctests12e')
		USE IN ctests12e
	ENDIF
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark, prin StergeIstoricV2UI (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	=StergeIstoricV2UI("COD_FISCAL = '8000391'")
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa S12/5')
	gcMockSondaModo = 'AUTO'
ENDPROC

PROCEDURE VerificaOrdineCacheAnafSarit
	*-- S12 scenariul 7: OrdineCache('UNIC')=CACHE,ANAF + rand proaspat in istoric -> ANAF NU e apelat
	*-- deloc (verificat prin gnANAFCallCount), verdictul vine direct din cache (cSursa=CACHE - pe acest
	*-- traseu istoricul e incercat INAINTE de starea serviciului).
	LOCAL loFormO, loVerifO, lnOk, lcCapO, lnInainte, llInsO, lcOrdineOrig, llAveaRand
	IF TYPE('goCacheANAF_Sesiune') = 'O'
		goCacheANAF_Sesiune = CREATEOBJECT('Collection')
	ENDIF
	llInsO = InsereazaIstoricTest('8000499', 'TEST S12 CACHE ORDINE SRL', {^2020-01-01})
	IF !m.llInsO
		DO VpaLog WITH 'FAIL ordine-cache-anaf-sarit (S12/7): insert istoric esuat - ' + goExecutor.cEroare
		RETURN
	ENDIF
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'pregatire S12/7')

	lcOrdineOrig = ''
	=goExecutor.oSelect2Value("SELECT VARVALUE AS NR FROM OPTIUNI WHERE VARNAME = 'ANAFCACHEORDINE_UNIC'", @lcOrdineOrig)
	llAveaRand = !EMPTY(NVL(lcOrdineOrig, ''))
	IF m.llAveaRand
		=goExecutor.oExecuta("UPDATE OPTIUNI SET VARVALUE = 'CACHE,ANAF' WHERE VARNAME = 'ANAFCACHEORDINE_UNIC'")
	ELSE
		=goExecutor.oExecuta("INSERT INTO OPTIUNI (VARNAME, VARVALUE) VALUES ('ANAFCACHEORDINE_UNIC', 'CACHE,ANAF')")
	ENDIF
	=goExecutor.oExecuta('COMMIT')

	lnOk = goExecutor.oExecute([SELECT DISTINCT DENUMIRE, NUME, COD_FISCAL, ID_PART, INACTIV FROM NOM_PARTENERI ] + ;
		[WHERE ID_PART = ] + TRANSFORM(gnIdCacheF), 'ctests12f')
	loFormO = CREATEOBJECT('cauta_alfa_form', 'ctests12f', '', 'Denumire,Nume,Cod fiscal,Id,Inactiv', ;
		'denumire,nume,cod_fiscal,id_part,inactiv', .F., '', 1, '', '', '', '')
	loFormO.crs_cursor = 'ctests12f'
	loFormO.lAles = .F.
	loVerifO = CREATEOBJECT('anaf_verif_cautare')
	ADDPROPERTY(loFormO, 'oVerifAlegere', loVerifO)
	loVerifO.Activeaza(loFormO)
	loFormO.WindowType = 0
	loFormO.Show()
	SELECT ctests12f
	GO TOP
	lnInainte = gnANAFCallCount
	loFormO._GRID1.AfterRowColChange(1)
	DO AsteaptaTimer WITH loVerifO
	lcCapO = ALLTRIM(loFormO.lb_anaf.Caption)

	IF gnANAFCallCount = lnInainte AND VARTYPE(loVerifO.oStare) = 'O' AND loVerifO.oStare.cSursa == 'CACHE'
		DO VpaLog WITH 'PASS ordine-cache-anaf-sarit (S12/7): OrdineCache=CACHE,ANAF + rand proaspat -> 0 apeluri ANAF, verdict din cache [' + lcCapO + ']'
	ELSE
		DO VpaLog WITH 'FAIL ordine-cache-anaf-sarit (S12/7): apeluri noi=' + TRANSFORM(gnANAFCallCount - lnInainte) + ;
			' oStare=' + TRANSFORM(VARTYPE(loVerifO.oStare)) + ' banda=[' + lcCapO + ']'
	ENDIF

	loVerifO.Dezactiveaza()
	loFormO.Release()
	IF USED('ctests12f')
		USE IN ctests12f
	ENDIF
	*-- restaureaza optiunea originala (per schema - alte teste/utilizatori depind de implicit)
	IF m.llAveaRand
		=goExecutor.oExecuta("UPDATE OPTIUNI SET VARVALUE = '" + STRTRAN(m.lcOrdineOrig, "'", "''") + "' WHERE VARNAME = 'ANAFCACHEORDINE_UNIC'")
	ELSE
		=goExecutor.oExecuta("DELETE FROM OPTIUNI WHERE VARNAME = 'ANAFCACHEORDINE_UNIC'")
	ENDIF
	=goExecutor.oExecuta('COMMIT')
	*!* 01.08.2026 marius.mutu: garda pe ID > watermark, prin StergeIstoricV2UI (nu SCHEMA_SURSA - stergea randuri de referinta proprii)
	=StergeIstoricV2UI("COD_FISCAL = '8000499'")
	ANAF_SeteazaStareServiciu('NECUNOSCUT', 'reset dupa S12/7')
ENDPROC

PROCEDURE VpaErr
	*-- OBLIGATORIU headless (depanare_testare_vfp.md): handlerul ON ERROR se termina cu QUIT.
	*-- In fluxul normal, erorile din TRY-ul principal ajung la CATCH TO loExc (nu aici) - VpaErr
	*-- prinde doar erori DIN AFARA acelui TRY (ex. evenimente async, Timer.Timer) care altfel ar
	*-- lasa un dialog modal si ar agata rularea. Curatare best-effort inainte de QUIT.
	LPARAMETERS tnErr, tcMsg, tcProg, tnLine
	DO VpaLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
	DO VpaLog WITH 'ON ERROR: oprire fortata (QUIT) - eroare in afara TRY/CATCH principal'
	TRY
		DO CurataDateTest
	CATCH
	ENDTRY
	QUIT
ENDPROC

PROCEDURE VpaLog
	LPARAMETERS tcMsg
	SET SAFETY OFF
	LOCAL lcL
	lcL = IIF(FILE(gcUILog), FILETOSTR(gcUILog), '')
	STRTOFILE(lcL + tcMsg + CHR(13)+CHR(10), gcUILog)
ENDPROC

*-- runda 11: clicker-ul de dialog (anaf_test_dlg_clicker) a fost eliminat odata cu anaf_dialog -
*-- deciziile trec acum prin mock_amessagebox.prg (gnMockRaspuns), sincron, fara Show(1) modal.

*-- runda 17: dublura de goExecutor pentru H2 (ANAF_CautaPereche esuat) - delegheaza la executorul
*-- real pentru orice alt SELECT, intercepteaza doar interogarea NOM_PARTENERI din ANAF_CautaPereche.
DEFINE CLASS dummyexecutorH2test AS Custom
	oReal = .NULL.
	cEroare = ''
	PROCEDURE oExecute
		LPARAMETERS tcSql, tcCursor
		LOCAL lnRez
		IF 'NOM_PARTENERI' $ UPPER(tcSql) AND 'STERS = 0' $ UPPER(tcSql) AND 'COD_FISCAL' $ UPPER(tcSql)
			This.cEroare = 'eroare simulata test H2'
			RETURN -1
		ENDIF
		lnRez = This.oReal.oExecute(tcSql, tcCursor)
		This.cEroare = This.oReal.cEroare
		RETURN lnRez
	ENDPROC
	*-- pass-through defensiv: orice alt apel (ex. din goLog.Log) merge la executorul real, nu la eroarea simulata
	PROCEDURE oExecuta
		LPARAMETERS tcSql, tcCursor
		RETURN This.oReal.oExecuta(m.tcSql, m.tcCursor)
	ENDPROC
	PROCEDURE oSelect2Value
		LPARAMETERS tcSql, tuValue
		RETURN This.oReal.oSelect2Value(m.tcSql, @tuValue)
	ENDPROC
ENDDEFINE

*-- runda 17: dublura de goExecutor pentru discriminatorul "are documente in perioada" - intercepteaza
*-- doar interogarea IREG_PARTENERI din MarcheazaDocumente, cu raspuns controlat de nIdsConDocumente.
DEFINE CLASS dummyexecutordoctest AS Custom
	oReal = .NULL.
	cEroare = ''
	nIdsConDocumente = 0
	PROCEDURE oExecute
		LPARAMETERS tcSql, tcCursor
		LOCAL lnRez
		IF 'IREG_PARTENERI' $ UPPER(tcSql) AND 'ID_PART IN' $ UPPER(tcSql)
			IF USED(tcCursor)
				USE IN (tcCursor)
			ENDIF
			CREATE CURSOR (tcCursor) (id_part N(10))
			IF This.nIdsConDocumente > 0
				INSERT INTO (tcCursor) (id_part) VALUES (This.nIdsConDocumente)
			ENDIF
			RETURN 1
		ENDIF
		lnRez = This.oReal.oExecute(tcSql, tcCursor)
		This.cEroare = This.oReal.cEroare
		RETURN lnRez
	ENDPROC
	*-- pass-through defensiv: orice alt apel (ex. din goLog.Log) merge la executorul real
	PROCEDURE oExecuta
		LPARAMETERS tcSql, tcCursor
		RETURN This.oReal.oExecuta(m.tcSql, m.tcCursor)
	ENDPROC
	PROCEDURE oSelect2Value
		LPARAMETERS tcSql, tuValue
		RETURN This.oReal.oSelect2Value(m.tcSql, @tuValue)
	ENDPROC
ENDDEFINE

*-- S12: dublura de goExecutor pentru scenariile de cache - numara interogarile care ating
*-- ISTORIC_CODURI_FISCALE (CitesteIstoricPentruCoduri trece prin oExecuta, validare.prg), ca sa
*-- dovedeasca cand cache-ul Oracle e sarit (cod negasit la ANAF) sau folosit o singura data (al
*-- doilea apel pe acelasi CUI vine din goCacheANAF_Sesiune).
DEFINE CLASS dummyexecutoristorictest AS Custom
	oReal = .NULL.
	cEroare = ''
	nIstoricQueryCount = 0
	PROCEDURE oExecuta
		LPARAMETERS tcSql, tcCursor
		LOCAL lnRez
		IF 'ISTORIC_CODURI_FISCALE' $ UPPER(tcSql)
			This.nIstoricQueryCount = This.nIstoricQueryCount + 1
		ENDIF
		lnRez = This.oReal.oExecuta(m.tcSql, m.tcCursor)
		This.cEroare = This.oReal.cEroare
		RETURN lnRez
	ENDPROC
	PROCEDURE oExecute
		LPARAMETERS tcSql, tcCursor
		LOCAL lnRez
		lnRez = This.oReal.oExecute(m.tcSql, m.tcCursor)
		This.cEroare = This.oReal.cEroare
		RETURN lnRez
	ENDPROC
	PROCEDURE oSelect2Value
		LPARAMETERS tcSql, tuValue
		RETURN This.oReal.oSelect2Value(m.tcSql, @tuValue)
	ENDPROC
ENDDEFINE
