*!* 15.03.2010
*!* marius.mutu
*!* VerificareCod.Vies - iau direct din pagina web in loc de serviciu web (nu mai merge)

*!* 07.04.2011
*!* marius.mutu
*!* adaugare verificarecod.InfoMfin2Array, ParseTable
*!* modificat Verificarecod.MFIN - alta aranjare in pagina a tabelului cu date de la mfinante.ro
*!* s-a modificat adresa de la mfinante.ro

*!* 12.04.2011
*!* marius.mutu
*!* verificarecod.validare_cif - intorc .T. pentru CIF-urile <> RO (nu am algoritm)
*!* tratare VIES alte tari din UE in afara de RO

*!* 20.01.2012
*!* marius.mutu
*!* VERIFICARE_CIF, MFIN - Taxa pe valoarea adaugata (data luarii in evidenta) + datatvamfin, platitortvamfin

*!* 27.01.2012
*!* marius.mutu
*!* VerificareCod.Init - nu mai este nevoie de tlMFINROMFAST, tlVIESROMFAST ca parametri - se citesc din settings.ini

*!* 28.11.2012
*!* marius.mutu
*!* verificare_cif, mfin - Se verifica si starea pentru un cod fiscal de pe mfinante.ro
*!* s-au adaugat proprietati pentru captcha, si o singura sesiune xmlhttp

*!* 04.12.2014
*!* marius.mutu
*!*	MFIN - se foloseste GET in loc de POST - restrictii puse de MF

*!* 27.02.2017
*!* marius.mutu
*!*	ANAF_SincronWebService_PlatitorTva 
*!* se incearca prima oara cu inHTTP.winHTTPrequest.5.1

*!* 10.01.2018
*!* marius.mutu
*!* VerificareANAF - completare stare TVA Incasare, Split TVA, Inactiv

*!* 20.07.2020
*!* marius.mutu
*!* ANAF_SincronWebService_PlatitorTva api v4

*!* 06.01.2021
*!* marius.mutu
*!* ANAF_SincronWebService_PlatitorTva api v5 +nrRegCom

*!*	24.04.2023
*!*	marius.mutu
*!* ANAF_SincronWebService_PlatitorTva api v8

*!*	19.05.2025
*!*	marius.mutu
*!* ANAF_SincronWebService_PlatitorTva api v9

*!*	25.07.2026
*!*	marius.mutu
*!* NormalizeazaCUI + ANAF_VerificaCuiSingle (verificare la alegerea partenerului, la data documentului)

*!* 27.07.2026
*!* marius.mutu
*!* ANAF_VerificaCuiSingle: raspunsul ANAF se citeste si cand serviciul intoarce cod 404, iar codul e
*!* declarat inexistent doar cand raspunsul chiar contine codul cautat; apelurile web (single si lot)
*!* folosesc timeout-uri reale, iar formatul datei se restaureaza si daca interpretarea raspunsului esueaza;
*!* sonda asincrona de disponibilitate (ANAF_SondaPorneste/AuSositRaspunsul/AReusit/Opreste) verifica in
*!* fundal, la nevoie, daca serviciul ANAF a revenit, fara sa blocheze interfata

*!* 27.07.2026
*!* marius.mutu
*!* ANAF_VerdictDinCursor expune si perioada de inregistrare in scopuri de TVA (inceput, sfarsit,
*!* anulare din oficiu) si mesajul ANAF integral (mesaj_ScpTVA), citite din cursorul deja parsat de
*!* ParseJsonANAFv8; parsarea esuata a datelor de perioada se logheaza

*!* 31.07.2026
*!* marius.mutu
*!* VerificareANAF: cache ANAF pe ISTORIC_CODURI_FISCALE (SalveazaIstoricDinCursor/CitesteIstoricPentruCoduri/
*!* OrdineCache/ZileCache/NormalizeazaCoduriCursor); VerificaListaCIF si ANAF_VerificaCuiSingle salveaza
*!* rezultatele ANAF in istoric; VerificaListaCIF primeste al patrulea parametru optional tcTraseu
*!* ('UNIC'/'MASA', implicit MASA) si citeste ordinea cu OrdineCache(tcTraseu), cu plasa de siguranta la
*!* tacere din istoric si provenienta (sursa/data_sursa) marcata in crsANAF si logata; VERIFICARE_CIF
*!* trimite si tvaincasare/splittva/inactiv la salvare; sursa/data_sursa ajung si pana la obiectul
*!* intors de VERIFICARE_CIF (GetEmptyMfinObj, Procedure ANAF, cursorul cVerificareCod)

*!* 01.08.2026
*!* marius.mutu
*!* VerificaListaCIF, ramura CACHE,ANAF: apelul ramas catre ANAF_SincronWebService_PlatitorTva foloseste
*!* acum un alias temporar (mergeuit apoi in crsANAF), ca randurile deja citite din cache sa nu mai fie
*!* sterse si reetichetate gresit CACHE_INDISP; plus golire explicita a aliasului la intrarea in
*!* VerificaListaCIF, ca sa nu mai acumuleze intre apeluri succesive cu alias implicit (Procedure ANAF) -
*!* defecte gasite la revizia de ansamblu dupa transa cache ANAF

*!* 01.08.2026
*!* marius.mutu
*!* SalveazaIstoricDinCursor trimite acum provenienta randului (sursa) la save_istoric_cod_fiscal, al
*!* 27-lea parametru pnDinCache; pachetul Oracle nu mai improspateaza DATAORAV_ANAF cand randul vine
*!* din cache (CACHE/CACHE_INDISP) - doar cand vin efectiv date noi de la ANAF - dar DATAORAV/ID_UTILV
*!* (urma de audit "cine si cand a verificat partenerul") se actualizeaza in continuare, indiferent de
*!* provenienta; altfel cache-ul isi reseta singur ceasul de prospetime la fiecare citire si nu mai
*!* expira niciodata

*!* 02.08.2026
*!* marius.mutu
*!* SalveazaIstoricDinCursor sare peste randurile provenite din cache - au fost deja salvate cand au
*!* ajuns prima data din ANAF; VerificaListaCIF lasa o singura linie in goLog cu totalul randurilor
*!* completate din cache (CACHE si CACHE_INDISP), in loc de o linie per rand; CitesteIstoricPentruCoduri
*!* interogheaza codurile pe transe de maxim 1000, legate cu OR in aceeasi interogare (peste 1000
*!* elemente "in (...)" da ORA-01795); plasa de siguranta din VerificaListaCIF aduna codurile ramase
*!* fara raspuns si cere istoricul intr-un singur apel, in loc de un apel Oracle per cod

*!* http://ec.europa.eu/taxation_customs/vies/viesquer.do
*!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CIF/1879855/MFIN
*!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CNP/1810228134187

*!* http://localhost:1512/WebRoot/codfiscaldebug.aspx/verificarecod/verificare/CIF/1879855/1

*!* http://localhost/update/codfiscal.aspx/verificarecod/validare/CIF/1879855
*!* http://localhost/update/codfiscal.aspx/verificarecod/validare/CNP/1810228134187

#Define TIP_CNP		1
#Define TIP_CIF		2
#Define TIP_IBAN	3
#Define TIP_CC		4
#Define TIP_ISBN	5
#Define TIP_NIF		6
#Define CRLF Chr(13) + Chr(10)
#Define CR Chr(13)

Clear
Local lcDir, lcPath, llVIESURL, lcRomfastURL, loVerificare
Local llMFINURL, lcMfinanteURL, lcMfinanteParams, I
Local llValid, lcRegCom, llPlatitorTVA

lcDir = Addbs(Justpath(Sys(16, 0)))
lcDir = Left(lcDir, Rat('\', lcDir, 2) )
*!*		MESSAGEBOX(lcDir)
Set Default To (lcDir)
lcPath = lcDir + 'controllers;' + ;
	lcDir + 'programe;' + ;
	lcDir + 'utility;'

Set Path To (lcPath)
Set Procedure To regex.prg Additive

*!*	strPattern = "[^A-Za-z 0-9 \.,\?'""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*"
Create Cursor cTeste (test c(200), rezultat L, mesaj c(250))

If .T.
	*!* TREBUIE OPTIUNI - VARIABILE PUBLICE gcVIESDotNet, gcVIESURL

	lcRomfastURL = "http://localhost/update/verificarecod.aspx/verificarecod/verificare/CIF/|CIF|/|TIP|"
	*!*		lcMfinanteURL = "http://www.mfinante.ro/contribuabili/link.jsp?body=/cod.do"
	*!*		lcMfinanteURL = "http://apt1.mfinante.ro/site/contribuabili/link.jsp?body=/cod.do"
	*!*		lcMfinanteParams = "cod=|CIF|"
	lcMfinanteURL = "http://www.mfinante.ro/infocodfiscal.html"
	lcMfinanteParams = "cod=|CIF|&captcha=|CAPTCHA|&B1=VIZUALIZARE"

	For I = 1 To 2

		llVIESURL = I = 1
		llMFINURL = I = 1
		?
		?'------------------------------------------'
		If I = 1
			?'* VERIFICARE CIF PE ROMFAST'
		Else
			?'* VERIFICARE PE MFINANTE SI CU DLL DIRECT PE VIES'
		Endif

		?
		?'* ROMFAST SRL - VALIDARE', I
		llValid = .T.
		lcRegCom = ''
		llPlatitorTVA = .F.
		test_verificare_cif('1879855', '', llVIESURL, llMFINURL, lcRomfastURL, lcMfinanteURL, lcMfinanteParams, llValid, lcRegCom, llPlatitorTVA)

		?
		?'* ROMFAST SRL - VIES', I
		llValid = .T.
		lcRegCom = ''
		llPlatitorTVA = .T.
		test_verificare_cif('1879855', 'VIES', llVIESURL, llMFINURL, lcRomfastURL, lcMfinanteURL, lcMfinanteParams, llValid, lcRegCom, llPlatitorTVA)

		?
		?'* ROMFAST SRL - MFIN', I
		llValid = .T.
		lcRegCom = 'J13/626/1991'
		llPlatitorTVA = .F.
		test_verificare_cif('1879855', 'MFIN', llVIESURL, llMFINURL, lcRomfastURL, lcMfinanteURL, lcMfinanteParams, llValid, lcRegCom, llPlatitorTVA)

		?
		?'* ROMFAST SRL - MFINVIES', I
		llValid = .T.
		lcRegCom = 'J13/626/1991'
		llPlatitorTVA = .T.
		test_verificare_cif('1879855', 'MFINVIES', llVIESURL, llMFINURL, lcRomfastURL, lcMfinanteURL, lcMfinanteParams, llValid, lcRegCom, llPlatitorTVA)

		?
		?'* COD INVALID - VALIDARE', I
		llValid = .F.
		lcRegCom = ''
		llPlatitorTVA = .F.
		test_verificare_cif('187985X', 'MFINVIES', llVIESURL, llMFINURL, lcRomfastURL, lcMfinanteURL, lcMfinanteParams, llValid, lcRegCom, llPlatitorTVA)
	Endfor && i
Endif

?
?'------------------------------------------'
?'* VALIDARE CIF'
loVerificare = Createobject("verificarecod")
test_cif('7320118', .T.)
test_cif('RO7320118', .T.)
test_cif('RO 7320118', .T.)
test_cif('R 7320118', .T.)
test_cif('R7320118', .T.)
test_cif('7320117', .F.)
test_cif('RO7320117', .F.)
test_cif('', .F.)
test_cif('3654392', .F.)
test_cif('14699589', .T.)
test_cif('11071295', .T.)

?
?'------------------------------------------'
?'VALIDARE CNP'
?
test_cnp('1810228134187', .T.)
test_cnp('181022813418', .F.)

Select cTeste
Browse

*!* TESTEAZA FUNCTIA DE VALIDARE CIF
Function test_cif
	Lparameters tcCIF, tuValoareCorect
	Local luRezultat, lcMesaj
	Local luReturn
	luReturn = .F.

	luRezultat = VALIDARE_CIF(tcCIF)
	lcMesaj = 'VALIDARE_CIF(' + tcCIF + ') ' + Transform(luRezultat) + ' (' + Transform(tuValoareCorect) + ')'

	If luRezultat <> tuValoareCorect
		lcMesaj = 'ERR ' + m.lcMesaj
		luReturn = .F.
	Else
		lcMesaj = 'OK  ' + m.lcMesaj
		luReturn = .T.
	Endif
	?m.lcMesaj
	If Used('cTeste')
		Insert Into cTeste (test, rezultat, mesaj) Values('VALIDARE CIF', luReturn, lcMesaj)
	Endif

	Return luReturn

Endfunc && TEST_CIF

*!* TESTEAZA FUNCTIA DE VALIDARE CNP
Function test_cnp
	Lparameters tcCNP, tuValoareCorect
	Local luRezultat, lcMesaj
	Local luReturn
	luReturn = .F.

	luRezultat = VALIDARE_CNP(tcCNP)

	lcMesaj = 'VALIDARE_CNP(' + tcCNP + ') ' + Transform(luRezultat) + ' (' + Transform(tuValoareCorect) + ')'

	If luRezultat <> tuValoareCorect
		lcMesaj = 'ERR ' + m.lcMesaj
		luReturn = .F.
	Else
		lcMesaj = 'OK  ' + m.lcMesaj
		luReturn = .T.
	Endif
	?m.lcMesaj

	If Used('cTeste')
		Insert Into cTeste (test, rezultat, mesaj) Values('VALIDARE CNP', luReturn, lcMesaj)
	Endif

	Return luReturn

Endfunc && TEST_CNP

*!* TESTEAZA FUNCTIA DE VERIFICARE CIF
Function test_verificare_cif
	Lparameters tcCIF, tcTipInterogare, tlVIESURL, tlMFINURL, tcRomfastURL, tcMfinanteURL, tcMfinanteParams, tlValid, tcRegCom, tlPlatitorTVA



	Local lcMesaj, llSucces, lcEroare
	Local loVerificare,	llValid, lcRegCom, llPlatitorTVA
	Local lcXML, loEx As Exception
	Local luReturn
	luReturn = .F.

	llSucces = .F.
	Try
		loVerificare = Createobject("verificarecod", tlVIESURL, tlMFINURL, tcRomfastURL, tcMfinanteURL, tcMfinanteParams)
		lcXML = loVerificare.verificare('CIF', tcCIF, tcTipInterogare)
		llValid = loVerificare.oEntitate.Valid
		lcRegCom = loVerificare.oEntitate.regcom
		llPlatitorTVA = loVerificare.oEntitate.PlatitorTVA
		llSucces = .T.
	Catch To loEx
		lcEroare = loEx.Message
	Endtry

	If llSucces
		lcMesaj = 'VERIFICARE_CIF ' + tcCIF + ' VALID: ' + Transform(llValid) + '(' + Transform(tlValid) + ')' + ;
			' REGCOM: ' + Alltrim(Transform(lcRegCom)) + '(' + Transform(tcRegCom) + ')' + ;
			' PLATITOR TVA: ' + Transform(llPlatitorTVA) + '(' + Transform(tlPlatitorTVA) + ')'
	Else
		lcMesaj = 'VERIFICARE_CIF ' + tcCIF + ' ' + lcEroare
	Endif

	If !llSucces Or (tlValid <> llValid Or tcRegCom <> lcRegCom Or tlPlatitorTVA <> tlPlatitorTVA)
		lcMesaj = 'ERR ' + m.lcMesaj
		luReturn = .F.
	Else
		lcMesaj = 'OK  ' + m.lcMesaj
		luReturn = .T.
	Endif
	?m.lcMesaj

	If Used('cTeste')
		Insert Into cTeste (test, rezultat, mesaj) Values('VERIFICARE CIF', luReturn, lcMesaj)
	Endif
	Return luReturn

Endfunc && TEST_VERIFICARE_CIF


*=============================
*!* verifica lungimea <= 10 caractere


*=============================
*!* VALIDARE CIF
*!* tcCIF - codul fiscal
*!*	toVerificare - optional in cazul in care am multe verificari sa nu se se instantiatieze obiectul la fiecare verificare
Function VALIDARE_CIF
	Lparameters tcCIF, toVerificare
	Local loVerificare, lcCod, llReturn

	If Type('tcCIF') <> 'C'
		lcCod = ''
	Else
		lcCod = tcCIF
	Endif
	If Type('toVerificare') = 'O' And Pemstatus(toVerificare, 'VALIDARE', 5)
		loVerificare = toVerificare
	Else
		loVerificare = Createobject("verificarecod")
	Endif


	llReturn = loVerificare.validare('CIF', lcCod)
	Return llReturn
Endfunc && VALIDARE_CIF


*=============================
*!* VERIFICARE_PLATITORTVA
*!* tcCIF - codul fiscal
*!*	toVerificare - optional in cazul in care am multe verificari sa nu se se instantiatieze obiectul la fiecare verificare
Function VERIFICARE_PLATITORTVA
	Lparameters tcCIF, toVerificare
	Local loVerificare, lcCod, llReturn
	Local llReturn

	If Type('tcCIF') <> 'C'
		lcCod = ''
	Else
		lcCod = tcCIF
	Endif
	If Type('toVerificare') = 'O' And Pemstatus(toVerificare, 'VALIDARE', 5)
		loVerificare = toVerificare
	Else
		loVerificare = Createobject("verificarecod")
	Endif


	llReturn = loVerificare.verificare('CIF', lcCod)
	Return llReturn
Endfunc && VALIDARE_CIF

*=============================
*!* VALIDARE CNP
*!* tcCIF - CNP
*!*	toVerificare - optional in cazul in care am multe verificari sa nu se se instantiatieze obiectul la fiecare verificare
Function VALIDARE_CNP
	Lparameters tcCNP, toVerificare
	Local loVerificare, lcCod, llReturn

	If Type('tcCNP') <> 'C'
		lcCod = ''
	Else
		lcCod = tcCNP
	Endif

	If Type('toVerificare') = 'O' And Pemstatus(toVerificare, 'VALIDARE', 5)
		loVerificare = toVerificare
	Else
		loVerificare = Createobject("verificarecod")
	Endif

	llReturn = loVerificare.validare('CNP', lcCod)
	Return llReturn
Endfunc && VALIDARE_CNP

*====================================
Define Class VerificareCod As Custom
	lVIESURL = .F. && .T. ROMFAST URL, .F. DOT NET DIRECT VIES
	lMFINURL = .F. && .T. ROMFAST URL, .F. www.mfinante.ro
	cRomfastURL = "http://83.103.197.79:3002/contafinupdate/verificarecod.aspx/verificarecod/verificare/CIF/|CIF|/|TIP|" && url catre Romfast pentru verificare MFIN, VIES

	*!*		cMfinanteURL = "http://www.mfinante.ro/contribuabili/link.jsp?body=/cod.do" && url catre www.mfinante.ro
	*!*		cMfinanteParams = "cod=|CIF|"

	cMfinanteURL = "" && "http://voes.mfinante.ro/codfiscal/codfiscal.html" && url catre www.mfinante.ro
	cMfinanteParams = "" && [cod=|CIF|&cap=null&B1=VIZUALIZARE]

	cMFINURL = '' && url catre Romfast pentru verificare informatii cod fiscal
	oEntitate = Null

	cMfinCaptcha = "" && codul CAPTCHA pentru verificarea codurilor fiscale pe mfinante
	oHTTP = Null

	*** se pare ca mfinante.ro are un bug - nu mai cere kaptcha la interogare directa si nu da mesajul "serverul este ocupat" la interogare rapida daca sunt sesiuni diferite
	lOneSession = .T. && oHTTP se retine pe instanta sau se creeaza oHTTP la fiecare interogare
	lCaptcha = .T. && se apeleaza Captcha de la mfinante, valabil doar pentru apelarea din program, nu de pe serverul romfast


	cMfinAnchorString = "AGENTUL ECONOMIC CU CODUL UNIC" && textul dupa care apare tabelul cu informatii MFIN
	cMfinNuExistaString = "NU EXISTA AGENT ECONOMIC CU ACEST COD FISCAL"
	lXMLHTTP = .F. && daca se foloseste xmlhttp pentru interogarea MFINANTE sau InternetExplorer.Application din luna 02/2017 nu mai merge apelul prin xmlhttp

	dDataAct = DATE()
	
	*=================================
	Procedure Init
		Lparameters tlVIESURL, tlMFINURL, tcRomfastURL, tcMfinanteURL, tcMfinanteParams

		This.cMfinanteURL = "http://www.mfinante.gov.ro/infocodfiscal.html" && url catre www.mfinante.ro
		This.cMfinanteParams = "cod=|CIF|&captcha=|CAPTCHA|&B1=VIZUALIZARE"

		*!* 27.01.2012
		If Pcount() >= 2 And Type('goApi') = 'O' And Type('gcSettingsFile') = 'C' And !Empty(m.gcSettingsFile)
			lcMFINROMFAST = goAPI.GetProfileString(m.gcSettingsFile, [validare], "mfinromfast")
			lcVIESROMFAST = goAPI.GetProfileString(m.gcSettingsFile, [validare], "viesromfast")
			lcMFINROMFAST = Nvl(m.lcMFINROMFAST, '')
			lcVIESROMFAST = Nvl(m.lcVIESROMFAST, '')
			If !Inlist(m.lcMFINROMFAST, '.T.', '.F.')
				tlMFINURL = .T.
			Else
				tlMFINURL = &lcMFINROMFAST
			Endif
			If !Inlist(m.lcVIESROMFAST, '.T.', '.F.')
				tlVIESURL = .T.
			Else
				tlVIESURL = &lcVIESROMFAST
			Endif
		Endif && PCOUNT
		*!* 27.01.2012 ^

		If Type('goApi') = 'O' And Type('gcSettingsFile') = 'C' And !Empty(m.gcSettingsFile)
			lcXMLHTTP = goAPI.GetProfileString(m.gcSettingsFile, [validare], "xmlhttp")
			lcXMLHTTP = Nvl(m.lcXMLHTTP, '')
			If !Inlist(m.lcXMLHTTP, '.T.', '.F.')
				llXMLHTTP = .F.
			Else
				llXMLHTTP = &lcXMLHTTP
			Endif
			This.lXMLHTTP = m.llXMLHTTP
		Endif

		This.lVIESURL = Iif(Type('tlVIESURL') = 'L', tlVIESURL, .F.) && default .F. pentru dll
		This.lMFINURL = Iif(Type('tlMFINURL') = 'L', tlMFINURL, .F.) && default .F. pentru www.mfinante.ro
		If Type('tcRomfastUrl') = 'C' And !Empty(tcRomfastURL)
			This.cRomfastURL =  tcRomfastURL
		Endif
		If Type('tcMfinanteUrl') = 'C' And !Empty(tcMfinanteURL)
			This.cMfinanteURL = tcMfinanteURL
		Endif
		If Type('tcMfinanteParams') = 'C' And !Empty(tcMfinanteParams)
			This.cMfinanteParams = tcMfinanteParams
		Endif
		*!* 13.01.2012
		If _vfp.StartMode = 0
			This.cRomfastURL = Strtran(This.cRomfastURL, '83.103.197.79:3002', '10.0.20.122:81')
		Endif
		*!* 13.01.2012 ^		
		This.cMfinCaptcha = ""
	Endproc && Init

	Function Destroy
		Local loEx As Exception
		If Type('This.oHTTP') = 'O' And Pemstatus(This.oHTTP, 'visible', 5)
			Try
				This.oHTTP.Visible = .F.
				This.oHTTP.Quit
				This.oHTTP = Null
			Catch To loEx
				*
			Endtry
		Endif
	Endfunc && Destroy

	*=================================
	Function verificare
		Lparameters tcTip, tcCod, tcExtraParam1, tcExtraParam2, tcExtraParam3, tcExtraParam4, tcExtraParam5
		Local lcTip, lcXML
		lcXML = ''
		lcTip = Iif(Type('tcTip') = 'C' And !Empty(tcTip), Upper(tcTip), 'CIF')

		This.Log('VERIFICARE ' + lcTip + ' ' + tcCod + ' ' + Transform(tcExtraParam1) + ' ' + Transform(tcExtraParam2) + ' ' + Transform(tcExtraParam3) + ' ' + Transform(tcExtraParam4) + ' ' + Transform(tcExtraParam5) )

		Do Case
			Case lcTip = 'CNP'
				lcXML = This.VERIFICARE_CNP(tcCod)
			Case lcTip = 'CIF'
				lcXML = This.VERIFICARE_CIF(tcCod, tcExtraParam1, tcExtraParam2, tcExtraParam3, tcExtraParam4, tcExtraParam5)
			Otherwise
				lcXML = ''
		Endcase

		Return lcXML
	Endfunc && VERIFICARE


	*=================================
	Function XMLCursorToOBj
		Lparameters tcXML
		Local lcCursor, lcSelect, loReturn
		Local lcEroare, loEx

		loReturn = Null
		lcCursor = Sys(2015)
		lcSelect = Select()
		Try
			Xmltocursor(tcXML, lcCursor)
			Select (lcCursor)
			Scatter Name loReturn
		Catch To loEx
			lcEroare = 'XMLCursorToOBj ' + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
			This.Log(m.lcEroare)
		Endtry

		Use In (Select(lcSelect))
		Select (lcSelect)
		Return loReturn
	Endfunc && XMLCursorToOBj

	*=================================
	Function ISCIF
		Lparameters tcCod
		Local lcCod, llIsCIF
		llIsCIF = .F.
		lcCod = Iif(Type('tcCod') <> 'C', '', Alltrim(tcCod))

		Do Case
			Case !Isdigit(lcCod) && Daca incepe cu o litera il consider COD FISCAL && ROXXX
				llIsCIF = .T.
			Case Len(lcCod) <= 10
				llIsCIF = .T.
		Endcase

		Return llIsCIF

	Endfunc && IsCIF

	*=================================
	* VERIFICARE_CNP('1810228134187')
	Procedure VERIFICARE_CNP
		Lparameters tcCNP


		Local lcSelect, lcCNP, llSucces, loEx As Exception, lcEroare, llValid, lcXML

		lcXML = ''
		lcSelect = Select()
		lcCNP = Iif(Empty(tcCNP) Or Type('tcCNP') <> 'C', '', Alltrim(tcCNP))
		lcEroare = ''


		Create Cursor cVerificareCod (Valid L, eroare c(250), cod c(100) Null)
		Cursortoxml("cVerificareCod", "lcXML", 1, 0, 0, "1")
		Select cVerificareCod
		Scatter Name This.oEntitate

		llSucces = .F.
		llValid = .F.
		Try
			llValid = This.validare('CNP', lcCNP)
			llSucces = .T.
		Catch To loEx
			lcEroare = 'VERIFICARE_CNP VALIDARE ' + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
			This.Log(m.lcEroare)
		Endtry

		Try
			Insert Into cVerificareCod(Valid, eroare, cod) ;
				Values (llValid, lcEroare, lcCNP)

			Cursortoxml("cVerificareCod", "lcXML", 1, 0, 0, "1")
		Catch To loEx
			lcEroare = 'VERIFICARE_CNP XML ' + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
			This.Log(m.lcEroare)
		Endtry

		Select cVerificareCod
		Go Top
		Scatter Name This.oEntitate

		Use In (Select('cVerificareCod'))
		Select (lcSelect)

		Return m.lcXML

	Endproc && VERIFICARE_CNP


	*=================================
	* VERIFICARE_CIF('1879855', ['VIES' | 'MFIN' | 'MFINVIES'])
	* valideaza CIF + aduna informatii de pe www.mfinante.ro + platitor tva de pe vies
	Procedure VERIFICARE_CIF
		Lparameters tcVerificareCod, tcTipInterogare, tdData, tcExtraParam3, tcExtraParam4, tcExtraParam5

		Local lcVerificareCod, lcFirma,	lcAdresa, lcJudet, lcRegCom, lcCodpostal, lcTelefon, lcFax, lcSelect, lcXML, llVies, llPlatitorTVA, llValid, lcCodTara, llRO, lcStare
		Local loEx As Exception
		Local lcMfinanteURL, lcMfinanteParams, lcRomfastURL, llMFINURL, loMFIN, loVIES, lcProcedura, llInterogareAnaf
		Local lStare, lcApart, lcBloc, lcDataTVAMFIN, lcEtaj, lcLocalitate, lcNr, lcScara, lcStrada
		Local llPlatitorTVAMFIN, lnSucces, llTVAIncasare, llSplitTVA, llInactiv, ldData, lcSqlIstoric, lcSursa, ldDataSursa

		Local lcTipInterogare, llInterogareVies, llInterogareMfin
		If Empty(tcTipInterogare) Or Type('tcTipInterogare') <> 'C'
			lcTipInterogare = ''
		Else
			lcTipInterogare = Upper(tcTipInterogare)
		ENDIF
		ldData = IIF(EMPTY(m.tdData) or TYPE('tdData') <> 'D', {}, m.tdData)

		llInterogareVies = 'VIES' $ lcTipInterogare
		llInterogareMfin = 'MFIN' $ lcTipInterogare
		llInterogareAnaf = 'ANAF' $ lcTipInterogare
		lcMfinanteURL = This.cMfinanteURL
		lcMfinanteParams = This.cMfinanteParams
		lcRomfastURL = This.cRomfastURL
		llMFINURL = This.lMFINURL
		*!*			This.Log(Alltrim(Transform(tcVerificareCod)))



		Local llSucces, lcEroare

		lcXML = ''
		lcSelect = Select()
		lcVerificareCod = Iif(Empty(tcVerificareCod) Or Type('tcVerificareCod') <> 'C', '', UPPER(Alltrim(tcVerificareCod)))
		*!* 12.04.2011
		lcCodTara = This.GetCodTara(m.lcVerificareCod)
		llRO = lcCodTara = 'RO'
		lcVerificareCod = Strtran(lcVerificareCod, m.lcCodTara, '')
		lcVerificareCod = Strtran(Strtran(Strtran(lcVerificareCod, ' ', ''), 'RO', ''), 'R', '')
		*!* 12.04.2011 ^
		lcFirma = ''
		lcAdresa = ''
		lcJudet = ''
		lcRegCom = ''
		lcCodpostal = ''
		lcTelefon = ''
		lcFax = ''
		llPlatitorTVA = .F.
		llVies = .F.
		lcEroare = ''
		lcDataTVAMFIN = ""
		llPlatitorTVAMFIN = .F.
		lcStare = ''
		lcStrada = ''
		lcNr = ''
		lcLocalitate = ''
		lcBloc = ''
		lcScara = ''
		lcEtaj = ''
		lcApart = ''
		llTVAIncasare = .F.
		llSplitTVA = .F.
		llInactiv = .F.
		lcSursa = ''
		ldDataSursa = {}

		Create Cursor cVerificareCod (Valid L, eroare c(250), cod V(100) Null, firma V(100), adresa V(250), judet V(100), ;
			regcom V(30), codpostal V(20), telefon V(30), fax V(30), datatvamfin V(30), platitortvamfin L, VIES L, PlatitorTVA L, ;
			stare V(100), strada V(100), nr V(25), localitate V(100), Bloc V(30), Scara V(10), Etaj V(10), Apart V(20), ;
			tvaincasare L, splittva L, inactiv L, sursa C(20), data_sursa D)
			
		Cursortoxml("cVerificareCod", "lcXML", 1, 0, 0, "1")
		Select cVerificareCod
		Scatter Name This.oEntitate

		llSucces = .F.
		llValid = .F.
		Try
			llValid = This.validare('CIF', m.tcVerificareCod)
			llSucces = .T.
		Catch To loEx
			lcEroare = 'VERIFICARE_CIF VALIDARE ' + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
			This.Log(m.lcEroare)
		Endtry

		If m.llValid And m.llRO And m.llInterogareAnaf

			loMFIN = This.ANAF(m.lcVerificareCod, m.ldData)

			lcFirma = loMFIN.firma
			lcAdresa = loMFIN.adresa
			lcJudet = loMFIN.judet
			lcRegCom = loMFIN.regcom
			lcCodpostal = loMFIN.codpostal
			lcTelefon = loMFIN.telefon
			lcFax = loMFIN.fax
			lcEroare = loMFIN.eroare
			lcDataTVAMFIN = TRANSFORM(loMFIN.datatvamfin)
			llPlatitorTVAMFIN = loMFIN.platitortvamfin
			lcStare = loMFIN.stare
			lcStrada = loMFIN.strada
			lcNr = loMFIN.nr
			lcLocalitate = loMFIN.localitate
			lcBloc = EVALUATE('loMFIN.Bloc')
			lcScara = loMFIN.scara
			lcEtaj = loMFIN.etaj
			lcApart = loMFIN.apart
			llTvaIncasare = loMFIN.tvaIncasare
			llSplitTVA = loMFIN.SplitTVA
			llInactiv = loMFIN.Inactiv
			lcSursa = Nvl(loMFIN.sursa, 'ANAF')
			ldDataSursa = Nvl(loMFIN.data_sursa, {})
		Endif && llValid AND llInterogareMfin

		If m.llValid And m.llRO And m.llInterogareMfin
			loMFIN = This.MFIN(lcVerificareCod)

			lcFirma = loMFIN.firma
			lcAdresa = loMFIN.adresa
			lcJudet = loMFIN.judet
			lcRegCom = loMFIN.regcom
			lcCodpostal = loMFIN.codpostal
			lcTelefon = loMFIN.telefon
			lcFax = loMFIN.fax
			lcEroare = loMFIN.eroare
			lcDataTVAMFIN = loMFIN.datatvamfin
			llPlatitorTVAMFIN = loMFIN.platitortvamfin
			lcStare = loMFIN.stare
			lcStrada = loMFIN.strada
			lcNr = loMFIN.nr
			lcLocalitate = loMFIN.localitate
			lcBloc = EVALUATE('loMFIN.Bloc')
			lcScara = loMFIN.scara
			lcEtaj = loMFIN.etaj
			lcApart = loMFIN.apart
			llTvaIncasare = loMFIN.tvaIncasare
			llSplitTVA = loMFIN.SplitTVA
			llInactiv = loMFIN.Inactiv
			lcSursa = Nvl(loMFIN.sursa, 'ANAF')
			ldDataSursa = Nvl(loMFIN.data_sursa, {})
		Endif && llValid AND llInterogareMfin

		*!* VERIFICARE VIES pentru platitori TVA
		If llValid And llInterogareVies
			loVIES = This.VIES(m.lcVerificareCod, m.lcCodTara)
			llPlatitorTVA = loVIES.PlatitorTVA
			If !llInterogareMfin Or Empty(lcFirma)
				lcFirma = loVIES.firma
				lcAdresa = loVIES.adresa
			Endif
			llVies = loVIES.VIES
			lcEroare = lcEroare + ' ' + loVIES.eroare
		Endif && llValid AND llInterogareVies
		*		lcAdresa = StripNonAscii(lcAdresa, ' ') && regex.prg

		lcFirma = This.RemoveCharacters(m.lcFirma) && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcFirma, ''))), Chr(170), 'S'), Chr(222), 'T')
		lcAdresa = This.RemoveCharacters(m.lcAdresa) && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcAdresa, ''))), Chr(170), 'S'), Chr(222), 'T')
		lcJudet = This.RemoveCharacters(m.lcJudet) && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcJudet, ''))), Chr(170), 'S'), Chr(222), 'T')
		lcRegCom = This.RemoveCharacters(m.lcRegCom) && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcRegCom, ''))), Chr(170), 'S'), Chr(222), 'T')
		lcLocalitate = This.RemoveCharacters(m.lcLocalitate)
		lcStrada = This.RemoveCharacters(m.lcStrada)
		
		TRY
			Insert Into cVerificareCod(Valid, eroare, cod, firma, adresa, judet, regcom, codpostal, telefon, fax, datatvamfin, platitortvamfin, VIES, PlatitorTVA, stare, strada, nr, localitate, bloc, scara, etaj, apart, tvaincasare, splittva, inactiv, sursa, data_sursa) ;
				Values (m.llValid, Left(m.lcEroare, 250), m.lcVerificareCod, m.lcFirma, m.lcAdresa, m.lcJudet, m.lcRegCom, m.lcCodpostal, m.lcTelefon, m.lcFax, m.lcDataTVAMFIN, m.llPlatitorTVAMFIN, m.llVies, m.llPlatitorTVA, m.lcStare, m.lcStrada, m.lcNr, m.lcLocalitate, m.lcBloc, m.lcscara, m.lcetaj, m.lcapart, m.llTVAIncasare, m.llSplitTVA, m.llInactiv, m.lcSursa, m.ldDataSursa)

			Select cVerificareCod
			Go Top
			Scatter Name This.oEntitate
			Cursortoxml("cVerificareCod", "lcXML", 1, 0, 0, "1")

			*** ROA salvez datele in istoric_coduri_fiscale
			If Type('goExecutor') = 'O'
				Private pcCodFiscal, pcFirma, pcAdresa, pcJudet, pcRegCom, pcCodPostal, pcTelefon, pcFax, pcDataTvamfin, pnPlatitorTvaMfin, pcStare, pnPlatitorTvaVies, pnInterogareVies, ;
					pnInactiv, pnTvaIncasare, pnSplitTva
				pcCodFiscal = m.lcVerificareCod
				pcFirma = m.lcFirma && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcFirma, ''))), Chr(170), 'S'), Chr(222), 'T')
				pcAdresa = m.lcAdresa && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcAdresa, ''))), Chr(170), 'S'), Chr(222), 'T')
				pcJudet = m.lcJudet && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcJudet, ''))), Chr(170), 'S'), Chr(222), 'T')
				pcRegCom = m.lcRegCom && Strtran(Strtran(Upper(Alltrim(Nvl(m.lcRegCom, ''))), Chr(170), 'S'), Chr(222), 'T')
				pcCodPostal = Upper(Alltrim(Nvl(m.lcCodpostal, '')))
				pcTelefon = Upper(Alltrim(Nvl(m.lcTelefon, '')))
				pcFax = Upper(Alltrim(Nvl(m.lcFax, '')))
				pcDataTvamfin = Upper(Alltrim(Nvl(m.lcDataTVAMFIN, '')))
				pnPlatitorTvaMfin = Iif(m.llPlatitorTVAMFIN, 1, 0)
				pcStare = Upper(Alltrim(Nvl(m.lcStare, '')))
				pnPlatitorTvaVies = Iif(m.llPlatitorTVA, 1, 0)
				pnInterogareVies = Iif(m.llVies, 1, 0)
				pnInactiv = Iif(m.llInactiv, 1, 0)
				pnTvaIncasare = Iif(m.llTVAIncasare, 1, 0)
				pnSplitTva = Iif(m.llSplitTVA, 1, 0)
				*!* 02.08.2026 marius.mutu: pe traseul ANAF randul complet e salvat deja de SalveazaIstoricDinCursor - a doua salvare doar insera un rand nou
				If !Empty(m.pcFirma) And !m.llInterogareAnaf
					*!* 02.08.2026 marius.mutu: tnDinCache = 2 - salvare fara date de interval, nu marcheaza prospetime de cache
					lcSqlIstoric = "begin pack_parteneri.save_istoric_cod_fiscal(?pcCodFiscal,?pcFirma,?pcAdresa,?pcJudet,?pcRegCom,?pcCodPostal,?pcTelefon,?pcFax,?pcDataTvamfin,?pnPlatitorTvaMfin,?pcStare," + ;
						"?pnPlatitorTvaVies,?pnInterogareVies,?gnIdUtil,?pnInactiv,?pnTvaIncasare,?pnSplitTva,tnDinCache=>2); end;"
					lnSucces = goExecutor.oExecuta(m.lcSqlIstoric)
				Endif
			Endif
			*** CONTAFIN salvez datele in istoric_coduri_fiscale			
			If Used('ISTORIC_CODURI_FISCALE')
				lcProcedura = [SAVE_ISTORIC_COD_FISCAL] && sa nu dea eroarea ROACONT la compilare ca nu gaseste procedura din CONCONT
				Do &lcProcedura With This.oEntitate In proceduri_comune.prg
			Endif

		Catch To loEx
			lcEroare = 'VERIFICARE_CIF INSERT XML' + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
			This.Log(m.lcEroare)
		Endtry

		Use In (Select('cVerificareCod'))
		Select (lcSelect)

		Return m.lcXML
	Endproc && VERIFICARE_CIF


	*==================================================
	*!* Aduce informatii despre starea de platitor TVA si adresa prin SERVICIU WEB ANAF
	*==================================================
	Procedure ANAF
		Lparameters tcCodFiscal, tdData
		* tcCodFiscal
		* optional tdData

		Local loVerificareANAF As "VerificareANAF"
		Local lcCodFiscal, lcCursorVerificareANAF, lcSelect, loMFIN, ldData
		lcCodFiscal = Iif(!Empty(m.tcCodFiscal) And Type('tcCodFiscal') = 'C', Alltrim(m.tcCodFiscal), '')
		lcSelect = Select()
		ldData = IIF(TYPE('tdData') = 'D' and !EMPTY(m.tdData), m.tdData, DATE(m.gnAn, m.gnLuna, 1))
		loMFIN = This.GetEmptyMfinObj()

		&& verificare serviciu web ANAF
		loVerificareANAF = Createobject("VerificareANAF") && validare.prg
		*!* 01.08.2026 marius.mutu: verificare unui singur CIF cerut manual - traseu UNIC (ANAF intai), nu implicitul MASA
		lcCursorVerificareANAF = loVerificareANAF.VerificaListaCIF(m.lcCodFiscal, m.ldData, , 'UNIC')
		If Used(m.lcCursorVerificareANAF)
			If Reccount(m.lcCursorVerificareANAF) >= 1
				Select (m.lcCursorVerificareANAF)
				Go Top
				loMFIN.firma = firma
				loMFIN.adresa = adresa
				loMFIN.judet = judet
				loMFIN.regcom = nrregcom
				loMFIN.codpostal = ''
				loMFIN.telefon = ''
				loMFIN.fax = ''
				loMFIN.eroare = ''
				loMFIN.datatvamfin = Data
				loMFIN.platitortvamfin = tva
				loMFIN.stare = mesaj
				loMFIN.strada = strada
				loMFIN.nr = nr
				loMFIN.localitate = localitate
				loMFIN.Bloc = Bloc
				loMFIN.scara = scara
				loMFIN.etaj = etaj
				loMFIN.apart = apart
				loMFIN.TVAIncasare = tvaincasare
				loMFIN.SplitTVA = splittva
				loMFIN.Inactiv = inactiv
				loMFIN.sursa = Nvl(sursa, 'ANAF')
				loMFIN.data_sursa = Nvl(data_sursa, {})
			Endif
		Endif

		Select (lcSelect)
		Return loMFIN

	Endproc && ANAF

	*==================================================
	*!* VERIFICARE INFORMATII MFINANTE
	*!* DIRECT PE MFINANTE.RO PE URL ROMFAST
	Procedure MFIN
		Lparameters tcCodFiscal
		Local llMFINURL, lcMfinanteURL, lcMfinanteParams, lcRomfastURL, lcSelect, loHTTP
		Local llPlatitorTVA, lcFirma, lcAdresa, lcEroare, llVies, lcStrada, lcNr, lcLocalitate

		Local loMFIN
		Local lnStatus, lcXML, lcJudet, lcRegCom, lcCodpostal, lcDataTVAMFIN, llPlatitorTVAMFIN, lcStare
		Local lcTelefon, lcFax, lcValues, lcResponse, loEx
		Local Array laMfin[100, 2]
		Local loFormIntroducereCod
		loFormIntroducereCod = Null

		llPlatitorTVA = .F.
		lcFirma = ''
		lcAdresa = ''
		lcEroare = ''
		llVies = .F.
		lcStare = ''
		lcStrada = ''
		lcNr = ''
		lcLocalitate = ''

		lcSelect = Select()
		llMFINURL = This.lMFINURL
		lcMfinanteURL = This.cMfinanteURL
		lcMfinanteParams = This.cMfinanteParams
		lcMfinanteParams = Strtran(lcMfinanteParams, '|CIF|', tcCodFiscal, 1, 1, 1)

		lcRomfastURL = This.cRomfastURL
		lcRomfastURL = Strtran(lcRomfastURL, '|CIF|', tcCodFiscal, 1, 1, 1) && http://localhost/update/verificarecod.aspx/verificarecod/verificare/CIF/|CIF|/|TIP|
		lcRomfastURL = Strtran(lcRomfastURL, '|TIP|', 'MFIN', 1, 1, 1)

		loMFIN = This.GetEmptyMfinObj()

		*!*			if This.lOneSession
		If Type("This.oHTTP") <> "O" && la prima apelare a verificarii MFIN
			If This.lXMLHTTP
				This.oHTTP = Createobject("winhttp.winhttprequest.5.1")
			Else
				This.oHTTP = Createobject("InternetExplorer.Application")
				This.oHTTP.Visible = .F.
			Endif
		Endif
		loHTTP = This.oHTTP
		*!*			ELSE
		*!*				IF This.lXMLHTTP 
		*!*					loHTTP = Createobject("winhttp.winhttprequest.5.1")		
		*!*				ELSE
		*!*					loHTTP = Createobject("InternetExplorer.Application")
		*!*					loHTTP.visible = .T.
		*!*				ENDIF 	
		*!*			endif 	

		*** INTRODUCERE CAPTCHA DACA NU ESTE INTRODUS DEJA
		*** Daca exista proprietatea VerificareCod.UserHostAddress, atunci clasa este instantiata din DISPATCHREQUEST de pe serverul ROMFAST
		If This.lXMLHTTP And !Pemstatus(This, "UserHostAddress", 5) And Empty(This.cMfinCaptcha) And This.lCaptcha
			lcCodFile = Addbs(Getenv("TEMP")) +  "captcha_" + Sys(2015) + ".jpg"
			loHTTP.Open('GET', "http://www.mfinante.ro/kaptcha.jpg", .F.)
			loHTTP.Send()

			= Strtofile(loHTTP.ResponseBody, m.lcCodFile)
			This.cMfinCaptcha = ""
			Clear Class "IntroducereCod"
			loFormIntroducereCod = Createobject("IntroducereCod", m.lcCodFile)
			loFormIntroducereCod.Show(1)
			If File(m.lcCodFile)
				Delete File (m.lcCodFile)
			Endif
			If Type('loFormIntroducereCod') = 'O' And Type('loFormIntroducereCod.cCod') = 'C'
				This.cMfinCaptcha = loFormIntroducereCod.cCod
				Release loFormIntroducereCod
			Endif
		Endif && !PEMSTATUS


		Do Case
			Case This.lMFINURL
				Try

					*!*					loHttp.SetTimeouts(ResolveTimeout, ConnectTimeout, SendTimeout, ReceiveTimeout)
					*				loHttp.SetTimeouts(60000, 60000, 60000, 60000)
					loHTTP.Open("GET", lcRomfastURL, .F.)
					loHTTP.Send()
					lnStatus = loHTTP.Status
					If lnStatus = 200 && OK
						lcXML =  loHTTP.responseText

						Xmltocursor(lcXML, 'cMFINTemp')

						lcFirma = Alltrim(cMFINTemp.firma)
						lcAdresa = Alltrim(cMFINTemp.adresa)
						lcJudet = Alltrim(cMFINTemp.judet)
						lcRegCom = Alltrim(cMFINTemp.regcom)
						lcCodpostal = Alltrim(cMFINTemp.codpostal)
						lcTelefon = Alltrim(cMFINTemp.telefon)
						lcFax = Alltrim(cMFINTemp.fax)
						lcEroare = Alltrim(cMFINTemp.eroare)
						lcDataTVAMFIN = cMFINTemp.datatvamfin
						llPlatitorTVAMFIN = cMFINTemp.platitortvamfin
						lcStare = cMFINTemp.stare
						lcStrada = Alltrim(cMFINTemp.strada)
						lcNr = Alltrim(cMFINTemp.nr)
						lcLocalitate = Alltrim(cMFINTemp.localitate)

						Use In (Select('cMFINTemp'))
					Else
						lcEroare = 'VERIFICARE_CIF MFIN - ' + Alltrim(Transform(lcRomfastURL)) + ' eroare ' + Alltrim(Str(lnStatus))
					Endif && lnStatus
				Catch To loEx
					lcEroare = 'VERIFICARE_CIF MFIN ' + CRLF + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
					This.Log(m.lcEroare)
				Endtry
			Otherwise
				Try
					If !Empty(This.cMfinCaptcha)
						lcMfinanteParams = Strtran(lcMfinanteParams, '|CAPTCHA|', This.cMfinCaptcha, 1, 1, 1)
					Else
						&& daca nu introduc CAPTCHA prima oara, nu il mai cer ulterior. sa vad daca merge ??? 
						lcMfinanteParams = Strtran(lcMfinanteParams, '&captcha=|CAPTCHA|', '', 1, 1, 1)
						This.lCaptcha = .F.
					Endif

					Do Case
						Case .F.
							loHTTP.Open("POST", lcMfinanteURL, .F.)
							loHTTP.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
							lcValues = lcMfinanteParams
							loHTTP.Send(lcValues)
							lnStatus = loHTTP.Status
						Case This.lXMLHTTP
							lcValues = lcMfinanteParams
							loHTTP.Open("GET", m.lcMfinanteURL + '?' + m.lcValues, .F.)
							loHTTP.setRequestHeader ("Content-Type", "multipart/form-data; ")
							loHTTP.setRequestHeader ("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)")
							loHTTP.Send(Null)
							lnStatus = loHTTP.Status
						Otherwise
							* Internet.Application din cauza ca nu mai merge interogarea cu xmlhttp
							lcValues = lcMfinanteParams
							loHTTP.Navigate(m.lcMfinanteURL + '?' + m.lcValues)
							* Astept maxim 10 secunde sa se incarce documentul si verific daca exista tag-ul <table>
							lnSeconds = Seconds()
							lnStatus = -200
							Do While .T.
								Inkey(1)
								lnSecondsPassed = Seconds() - lnSeconds
								Wait Window 'Astept incarcarea paginii mfinante.ro ' + Alltrim(Str(m.lnSecondsPassed)) + '/20 sec.' Nowait

								If (loHTTP.ReadyState = 4 And !loHTTP.Busy) Or m.lnSecondsPassed > 20
									If This.cMfinAnchorString $ Upper(loHTTP.Document.body.innerhtml) Or This.cMfinNuExistaString $ Upper(loHTTP.Document.body.innerhtml)
										lnStatus = 200
										Exit
									Else
										If m.lnSecondsPassed > 20
											Exit
										Endif
									Endif
								Endif
							Enddo
					Endcase

					If lnStatus = 200 && OK
						If This.lXMLHTTP
							lcResponse =  Upper(loHTTP.responseText)
						Else
							lcResponse = loHTTP.Document.body.innerhtml
						Endif
						*STRTOFILE(m.lcResponse, "c:\info_" + m.tcCodFiscal + ".html")
						This.InfoMfin2Array(m.lcResponse, @laMfin)

						lcFirma = This.RemoveCharacters(laMfin(1, 2), .T.) &&  Strtran(Strtran(Upper(Alltrim(Nvl(aMfin(1, 2), ''))), Chr(170), 'S'), Chr(222), 'T')
						lcAdresa = This.RemoveCharacters(laMfin(2, 2), .T., .F., .T.) && Strtran(Strtran(Upper(Alltrim(Nvl(laMfin(2, 2), ''))), Chr(170), 'S'), Chr(222), 'T')
						lcJudet = This.RemoveCharacters(laMfin(3, 2), .T.) && Strtran(Strtran(Upper(Alltrim(Nvl(laMfin(3, 2), ''))), Chr(170), 'S'), Chr(222), 'T')
						lcRegCom = This.RemoveCharacters(laMfin(4, 2), .T., .T., .T.) && Strtran(Strtran(Upper(Alltrim(Nvl(STRTRAN(laMfin(4, 2), ' ',''), ''))), Chr(170), 'S'), Chr(222), 'T')
						lcCodpostal = This.RemoveCharacters(laMfin(6, 2), .T., .T., .T.) && laMfin(6, 2)
						lcTelefon = This.RemoveCharacters(laMfin(7, 2), .T., .T., .T.) && laMfin(7, 2)
						lcFax = This.RemoveCharacters(laMfin(8, 2), .T., .T., .T.) && laMfin(8, 2)
						lcStare = This.RemoveCharacters(laMfin(9, 2), .T., .F., .T.) && Strtran(Strtran(Upper(Alltrim(Nvl(laMfin(9, 2), ''))), Chr(170), 'S'), Chr(222), 'T')
						lcDataTVAMFIN = Nvl(laMfin(16, 2), '')
						llPlatitorTVAMFIN = !(Empty(m.lcDataTVAMFIN) Or Isalpha(m.lcDataTVAMFIN))

						loAdresa = This.ParseAdresaMFin(m.lcAdresa)
						lcStrada = loAdresa.strada
						lcNr = loAdresa.nr
						lcLocalitate = loAdresa.localitate
					Else
						lcEroare = 'VERIFICARE_CIF MFIN - ' + Alltrim(Transform(lcMfinanteURL)) + ' eroare ' + Alltrim(Str(lnStatus))
					Endif
				Catch To loEx
					lcEroare = 'VERIFICARE_CIF MFIN  ' + CRLF + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
					This.Log(m.lcEroare)
				Endtry
		Endcase

		loMFIN.firma = m.lcFirma
		loMFIN.adresa = m.lcAdresa
		loMFIN.judet = m.lcJudet
		loMFIN.regcom = m.lcRegCom
		loMFIN.codpostal = m.lcCodpostal
		loMFIN.telefon = m.lcTelefon
		loMFIN.fax = m.lcFax
		loMFIN.eroare = m.lcEroare
		loMFIN.datatvamfin = m.lcDataTVAMFIN
		loMFIN.platitortvamfin = m.llPlatitorTVAMFIN
		loMFIN.stare = m.lcStare
		loMFIN.strada = m.lcStrada
		loMFIN.nr = m.lcNr
		loMFIN.localitate = m.lcLocalitate

		Select (lcSelect)
		Return loMFIN

	Endproc && MFIN

	*==================================================
	*!* VERIFICARE CALITATE PLATITOR TVA
	*!* DIRECT PE VIES CU DLL DOTNET SAU PE URL ROMFAST
	Procedure VIES
		Lparameters tcCodFiscal, tcCodTara

		Local ws, loVIES, llVIESURL, lcRomfastURL, lcSelect, loHTTP
		Local llPlatitorTVA, lcFirma, lcAdresa, lcEroare, llVies, lcCodTara
		Local lnStatus, lcXML, loEx, lcViesURL

		llPlatitorTVA = .F.
		lcFirma = ''
		lcAdresa = ''
		lcEroare = ''
		llVies = .F.

		lcSelect = Select()
		*!* 12.04.2011
		lcCodTara = Iif(!Empty(m.tcCodTara), Alltrim(Upper(Transform(m.tcCodTara))), 'RO')
		*!* 12.04.2011 ^

		llVIESURL = This.lVIESURL
		lcRomfastURL = This.cRomfastURL
		*!* 12.04.2011
		lcRomfastURL = Strtran(lcRomfastURL, '|CIF|', m.lcCodTara + m.tcCodFiscal, 1, 1, 1) && http://localhost/update/verificarecod.aspx/verificarecod/verificare/CIF/|CIF|/|TIP|
		*!* 12.04.2011 ^		
		lcRomfastURL = Strtran(lcRomfastURL, '|TIP|', 'VIES', 1, 1, 1)

		loVIES = Createobject("empty")
		AddProperty(loVIES, "Vies", .F.)
		AddProperty(loVIES, "Eroare", '')
		AddProperty(loVIES, "Cod", tcCodFiscal)
		AddProperty(loVIES, "PlatitorTVA", .F.)
		AddProperty(loVIES, "Firma", "")
		AddProperty(loVIES, "Adresa", "")

		If This.lVIESURL
			Try
				*!*					loHTTP = Createobject("MSXML2.ServerXMLHTTP")
				loHTTP = Createobject("winhttp.winhttprequest.5.1")
				loHTTP.Open("GET", lcRomfastURL, .F.)
				loHTTP.Send()
				lnStatus = loHTTP.Status
				If lnStatus = 200 && OK
					lcXML =  loHTTP.responseText

					Xmltocursor(lcXML, 'cVIESTemp')
					llPlatitorTVA = cVIESTemp.PlatitorTVA
					lcFirma = Alltrim(cVIESTemp.firma)
					lcAdresa = Alltrim(cVIESTemp.adresa)
					lcEroare = Alltrim(cVIESTemp.eroare)
					llVies = cVIESTemp.VIES
					Use In (Select('cVIESTemp'))
				Else
					lcEroare = 'VERIFICARE_CIF VIES - ' + Alltrim(Transform(lcRomfastURL)) + ' eroare ' + Alltrim(Str(lnStatus))
				Endif && lnStatus
			Catch To loEx
				lcEroare = 'VERIFICARE_CIF VIES ' + CRLF + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
				This.Log(m.lcEroare)
			Endtry
		Else
			If .F.
				Try
					llVies = .F.
					ws = Createobject('DotNetCom.VerificareCIF')
					llPlatitorTVA = ws.VerifCIF(tcCodFiscal)     &&returneza .T. sau .F., in functie de existenta CIF in baza de date EU
					lcFirma = ws.firma
					lcAdresa = Strtran(Strtran(ws.adresa, Chr(13), ''), Chr(10), '')
					llVies = .T.
				Catch To loEx
					lcEroare = 'VERIFICARE_CIF VIES ' + CRLF + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
					This.Log(m.lcEroare)
				Endtry
			ELSE

				*!* 15.03.2010
				IF .F.
					Try
						*!*						loHTTP = Createobject("MSXML2.ServerXMLHTTP") && ("Microsoft.XMLHTTP")
						loHTTP = Createobject("winhttp.winhttprequest.5.1")
						*!* 12.04.2011					
						lcViesURL = "http://ec.europa.eu/taxation_customs/vies/viesquer.do?ms=" + m.lcCodTara + "&iso=" + m.lcCodTara + "&vat=" + m.tcCodFiscal
						*!* 12.04.2011 ^
						loHTTP.Open("GET", m.lcViesURL, .F.)
						loHTTP.Send()
						lnStatus = loHTTP.Status
						If lnStatus = 200 && OK
							lcXML =  loHTTP.responseText
							llPlatitorTVA = 'YES, VALID VAT NUMBER' $ Upper(lcXML)
							lcFirma = ''
							lcAdresa = ''
							llVies = .T.
						Else
							lcEroare = 'VERIFICARE_CIF VIES - ' + m.lcViesURL + ' eroare ' + Alltrim(Str(lnStatus))
						Endif && lnStatus
					Catch To loEx
						lcEroare = 'VERIFICARE_CIF VIES ' + CRLF + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
						This.Log(m.lcEroare)
					Endtry
					*!* 15.03.2010 ^
				ENDIF && .F.
				Try
					loHTTP = Createobject("winhttp.winhttprequest.5.1")
					loHTTP.Open("POST", "http://ec.europa.eu/taxation_customs/vies/services/checkVatService", .F.)
					loHTTP.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

					TEXT TO lcValues NOSHOW TEXTMERGE
					<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'>
						<s:Body>
							<checkVat xmlns='urn:ec.europa.eu:taxud:vies:services:checkVat:types'>
								<countryCode><<m.lcCodTara>></countryCode>
								<vatNumber><<m.tcCodFiscal>></vatNumber>
							</checkVat>
						</s:Body>
					</s:Envelope>
					ENDTEXT 

					loHTTP.Send(lcValues)
					lnStatus = loHTTP.Status
					If lnStatus = 200 && OK				
						lcXML =  loHTTP.responseText
						llPlatitorTVA = (STREXTRACT(m.lcXML, [<valid>],[</valid>],1,1) = 'true') && true/false
						lcFirma = STRTRAN(STREXTRACT(m.lcXML, [<name>],[</name>],1,1), '-','',1,10,1)
						lcAdresa = STRTRAN(STREXTRACT(m.lcXML, [<address>],[</address>],1,1), '-','',1,10,1)
						lcAdresa = Strtran(m.lcAdresa, Chr(13) + CHR(10), ' ')
						llVies = .T.	
					Else
						lcEroare = 'VERIFICARE_CIF VIES - ' + m.lcViesURL + ' eroare ' + Alltrim(Str(lnStatus))
					Endif && lnStatus	
				Catch To loEx
					lcEroare = 'VERIFICARE_CIF VIES ' + CRLF + loEx.Message + " " + loEx.LineContents + " " + Transform(loEx.Lineno)
					This.Log(m.lcEroare)
				Endtry															
			Endif
		Endif
		loVIES.PlatitorTVA = llPlatitorTVA
		loVIES.firma = lcFirma
		loVIES.adresa = lcAdresa
		loVIES.eroare = lcEroare
		loVIES.VIES = llVies

		Select (lcSelect)
		Return loVIES

	Endproc && VIES

	*=================================
	Function validare
		Lparameters tcTip, tcCod
		Local lcTip, llReturn

		llReturn = .F.

		lcTip = Iif(Type('tcTip') = 'C' And !Empty(tcTip), Upper(tcTip), 'CIF')

		Do Case
			Case lcTip = 'CNP'
				llReturn = This.VALIDARE_CNP(tcCod)
			Case lcTip = 'CIF'
				llReturn = This.VALIDARE_CIF(tcCod)
			Otherwise
				llReturn = .F.
		Endcase

		Return llReturn
	Endfunc && VALIDARE

	*=================================
	*!* VALIDEAZA CIF
	*!* RETURN .T. / .F.
	Function VALIDARE_CIF
		Lparameters tcCIF

		Local lcCIFinv, I
		Local llCorect, lcCif, cheieinv, lnSuma, lnRest, lnCifraVerificare, lcCifraControl, lnCifraControl

		If Type('tcCIF') <> 'C'
			tcCIF = ''
		Endif

		*!* 12.04.2011
		lcCif = Alltrim(Nvl(tcCIF, ''))
		lcCodTara = This.GetCodTara(m.lcCif)
		*!* daca primele 2 caractere sunt coduri de tara le elimin
		If !Substr(M.lcCif, 1, 1) $ '0123456789'
			m.lcCif = Alltrim(Substr(m.lcCif, 2))
		Endif
		If !Substr(M.lcCif, 1, 1) $ '0123456789'
			m.lcCif = Alltrim(Substr(m.lcCif, 2))
		Endif
		llCorect = .T.

		If !(Empty(m.lcCodTara) Or m.lcCodTara = 'RO')
			Return m.llCorect
		Endif
		*!* 12.04.2011 ^

		*!*	lcCIF = '7320118'
		*!*	Pas preliminar: Se testeaza daca codul respecta formatul unui cod CIF. Adica lungimea maxima sa fie de 10 cifre si sa contina doar caractere numerice.
		If Len(m.lcCif) > 10 Or Empty(m.lcCif)
			llCorect = .F.
		Else
			For I = 1 To Len(m.lcCif)
				If !Substr(m.lcCif, I, 1) $ '0123456789'
					llCorect = .F.
				Endif
			Endfor
		Endif

		*!*	Pas 1: Se foloseste cheia de testare "753217532". Se inverseaza ordinea cifrelor codului CIF precum si a cheii de testare.
		*!*	Pas 2: Se ignora prima cifra din codul CIF inversat (aceasta este cifra de control) si se inmulteste fiecare cifra cu cifra corespunzatoare din cheia de testare inversata.
		*!*	Pas 3: Se aduna toate produsele obtinute. Suma rezultata se inmulteste cu 10 si produsul este impartit la 11. Cifra obtinuta, in urma operatiei MODULO 11 reprezita cifra de verificare. Daca in urma impartirii s-a obtinut restul 10 atunci cifra de verificare va fi 0.
		*!*	Pas 4: Pentru un CIF valid cifra de verificare va trebui sa corespunda cu cifra de control a codului CIF initial.
		cheieinv = '235712357'
		If llCorect
			lcCIFinv = ''
			lnSuma = 0
			For I = Len(m.lcCif) - 1 To 1 Step - 1
				lcCIFinv = m.lcCIFinv + Substr(m.lcCif, I, 1)
			Endfor

			For I = 1 To Len(m.lcCIFinv)
				lnSuma = lnSuma + Val(Substr(m.lcCIFinv, I, 1)) * Val(Substr(m.cheieinv, I, 1))
			Endfor
			lnRest = Mod(m.lnSuma * 10, 11)
			lnCifraVerificare = Iif(m.lnRest = 10, 0, lnRest)
			lcCifraControl = Substr(m.lcCif, Len(m.lcCif), 1)
			lnCifraControl = Val(lcCifraControl)

			If m.lnCifraVerificare <> m.lnCifraControl
				llCorect = .F.
			Endif
		Endif
		*!*	?IIF(llCorect, 'CORECT', 'INCORECT')
		Return llCorect

	Endfunc && VALIDARE_CIF

	*=================================
	*!* VALIDEAZA CNP
	*!* RETURN .T. / .F.
	Function VALIDARE_CNP
		Lparameters cCnp
		Local cCod
		cCod = Alltrim(cCnp)
		If Len(cCod)!= 13
			Return .F.
		Endif
		Local _X(13), _rest, j
		For j = 1 To 13
			_X(j) = Val(Substr(cCod, j, 1))
		Endfor
		_rest = (_X(1) * 2 + _X(2) * 7 + _X(3) * 9 + _X(4) * 1 + _X(5) * 4 + _X(6) * 6 + _X(7) * 3 + _X(8) * 5 + _X(9) * 8 + _X(10) * 2 + _X(11) * 7 + _X(12) * 9) % 11
		Return Iif((_rest < 10 And _rest = _X(13))Or(_rest = 10 And _X(13) = 1), .T., .F.)
	Endfunc && VALIDARE_CNP

	*=================================
	Function GetError
		Local lcReturn, lnLines
		Local Array laEroare(1)

		lcReturn = ""

		lnLines = Aerror(laEroare)
		If lnLines = 7
			lcReturn = Alltrim(Transform(laEroare(1))) + ' ' + Alltrim(Transform(laEroare(2))) &&+ ALLTRIM(TRANSFORM(laEroare(3)))
		Endif
		Return lcReturn
	Endfunc

	*============================
	Procedure Log
		Lparameters tcText
		If Type('goLog') = 'O'
			goLog.Log(tcText)
		Else
			Local lcText
			lcText = Transform(Datetime()) + " " + Iif(Empty(tcText), "", tcText) + Chr(13) + Chr(10)

			Strtofile(m.lcText, "log.txt", .T.)
		Endif

	Endproc && Log

	Function GetInfoMfin(lcResponse, lnRand)
		Local cAnchorString,  cTable, lcRand, lcReturn

		m.cAnchorString = "AGENTUL ECONOMIC CU CODUL UNIC"
		m.cTable = Upper(Strextract( Substr(lcResponse, Atc( m.cAnchorString, lcResponse)), '<TABLE', '</TABLE>'))

		lcRand = Strextract( cTable, "<TR", "</TR>", lnRand )
		lcReturn = Strextract( lcRand, [SIZE="2">], "</FONT>", 2)
		Return lcReturn
	Endfunc && GetInfoMfin

	*** Parseaza html-ul de la mfinante.ro si transforma tabelul intr-un array cu 2 coloane (descriere, valoare)
	Procedure InfoMfin2Array(lcResponse, laInfo)
		Local lcList, lcTable, lnLinii, I

		If Atc('NU ATI INTRODUS CODUL DE VALIDARE CORECT', m.lcResponse, 1) > 0
			Dimension laInfo(100, 2)
			laInfo = ""
			laInfo(2, 2) = "Nu ati introdus codul de validare corect!"
		Else
			lcString = This.cMfinAnchorString && "AGENTUL ECONOMIC CU CODUL UNIC"
			lcTable = Strextract(Substr(m.lcResponse, Atc(m.lcString, m.lcResponse)), '<TABLE', '</TABLE>', 1, 1)

			If Empty(m.lcTable)
				Dimension laInfo(100, 2)
				laInfo = ""
				laInfo(2, 2) = "Nu s-a gasit tabelul!"
			Else
				* Elimin CR LF TAB NBSP si "reglez" &
				lcTable = Transform(m.lcTable)
				lcTable = Strtran(m.lcTable, Chr(10), '', 1, 1000, 1)
				*		lcTable = Strtran(m.lcTable, Chr(9), '',1,1000,1)
				lcTable = Strtran(m.lcTable, Chr(13), '', 1, 1000, 1)
				lcTable = Strtran(m.lcTable, '&nbsp;', ' ', 1, 1000, 1)
				lcTable = Strtran(m.lcTable, '&amp;', '&', 1, 1000, 1)

				*!*			lcTable = STREXTRACT(m.lcResponse,'<table','table>',1,5)
				*** functia parsetable transforma tabelul html intr-o lista fara tag-uri
				lcList = This.ParseTable(m.lcTable)
				*** se trece lista intr-un vector
				lnLinii = Alines(laInfo, lcList, 1)
				If lnLinii > 1
					*** vectorul laInfo se redimensioneaza la 2 coloane. Prima coloana contine explicatia, a doua valoarea
					Dimension laInfo (Ceiling(lnLinii / 2), 2)
					For I = 1 To Alen(laInfo, 1)
						laInfo(I, 1) = Alltrim(Strtran(Alltrim(Strtran(laInfo(I, 1), "&nbsp;", "", 1, 1000, 1)), Chr(9), ""))
						laInfo(I, 2) = Alltrim(Strtran(Alltrim(Strtran(laInfo(I, 2), "&nbsp;", "", 1, 1000, 1)), Chr(9), ""))
					Endfor
				Else
					Dimension laInfo(100, 2)
					laInfo = ""
					laInfo(2, 2) = "Tabelul are dimensiunea < 2!"
				Endif && lnLinii > 1
			Endif && EMPTY(m.lcTable)
		Endif && NU ATI INTRODUS CODUL DE VALIDARE CORECT
	Endproc && InfoMfin2Array

	*** Parseaza html-ul de la vies si transforma tabelul intr-un array cu 2 coloane (descriere, valoare)
	Procedure InfoVIES2Array(lcResponse, laInfo)

		Local lcList, lcTable, lnLinii, I

		lcTable = Strextract(m.lcResponse, '<table', 'table>', 5, 5)
		*** functia parsetable transforma tabelul html intr-o lista fara tag-uri
		lcList = This.ParseTable(m.lcTable)
		*** se trece lista intr-un vector
		lnLinii = Alines(laInfo, lcList, 1)
		*** vectorul laInfo se redimensioneaza la 2 coloane. Prima coloana contine explicatia, a doua valoarea
		Dimension laInfo (lnLinii / 2, 2)
		For I = 1 To Alen(laInfo, 1)
			laInfo(I, 1) = Alltrim(Strtran(Alltrim(Strtran(laInfo(I, 1), "&nbsp;", "", 1, 10, 1)), Chr(9), ""))
			laInfo(I, 2) = Alltrim(Strtran(Alltrim(Strtran(laInfo(I, 2), "&nbsp;", "", 1, 10, 1)), Chr(9), ""))
		Endfor
	Endproc && InfoMfin2Array

	*** creaza o lista caracter cu valorile dintr-un tabel html
	*** rand 1: cell_1_1, rand 2: cell_1_2, rand 3: cell_2_1, rand 4: cell_2_2 etc.
	Function ParseTable
		Lparameters tcTable

		Local lcList, lcCell, lcData, lnCell, lnTag
		lcList = ''
		For lnCell = 1 To Occurs('<td', Lower(tcTable))
			lcCell = Strextract(tcTable, '<td', 'td>', lnCell, 3)
			lcData = ''
			For lnTag = 1 To Occurs('>', lcCell)
				lcData = lcData + Strextract(lcCell, '>', '<', lnTag, 3)
			Next lnTag
			lcData = Alltrim(Chrtran(lcData, Chr(10) + Chr(13), Space(1)))
			Do While At(Space(2), lcData) > 0
				lcData = Strtran(lcData, Space(2), Space(1))
			Enddo
			lcList = lcList + lcData + CR
		Endfor
		Return lcList
	Endfunc && ParseTable

	*** Extrage codul de tara din codul fiscal (primele 2 caractere)
	Function GetCodTara
		Lparameters tcCodFiscal

		Local lcCodTara, lcCodFiscal
		Local lcChar1, lcChar2
		lcCodTara = ""
		lcCodFiscal = Alltrim(Strtran(Upper(Transform(tcCodFiscal)), ' ', ''))
		lcChar1 = Substr(m.lcCodFiscal, 1, 1)

		If Isalpha(m.lcChar1)
			m.lcCodTara = m.lcCodTara + m.lcChar1
			lcChar2 = Substr(m.lcCodFiscal, 2, 1)
			If Isalpha(m.lcChar2)
				m.lcCodTara = m.lcCodTara + m.lcChar2
			Endif
		Endif

		If m.lcCodTara = 'R' Or Empty(m.lcCodTara)
			m.lcCodTara = 'RO'
		Endif

		Return m.lcCodTara
	Endfunc && GetCodTara

	*** curata textul de diacritice, spatii, CR/LF
	Function RemoveCharacters
		Lparameters tcText, tlDiacritics, tlSpaces, tlCR
		*** tcText: textul initial
		*** tlDiacritics: inlocuieste diacriticele
		*** tlSpaces: sterge spatiile
		*** tlCR: sterge CR si LF

		If Pcount() = 1
			tlDiacritics = .T.
		Endif

		Local lcText
		lcText = Nvl(m.tcText, '')
		If m.tlDiacritics
			lcText = STRTRAN(STRTRAN(Strtran(Nvl(m.lcText, ''), Chr(197) + CHR(162), 'T', 1,100,1), Chr(197) + CHR(63), 'S', 1,100,1), Chr(196) + CHR(63), 'A', 1,100,1)
			lcText = Strtran(Nvl(m.lcText, ''), Chr(195) + CHR(63), 'I', 1,100,1)
			lcText = Strtran(Strtran(Strtran(Strtran(Strtran(Nvl(m.lcText, ''), Chr(170), 'S', 1,100,1), Chr(222), 'T', 1,100,1), Chr(226), 'A', 1,100,1), Chr(227), 'A', 1,100,1), Chr(238), 'I', 1,100,1)
			lcText = STRTRAN(Strtran(Strtran(Strtran(Nvl(m.lcText, ''), Chr(206), 'I', 1,100,1), Chr(194), 'A', 1,100,1), Chr(195), 'A', 1,100,1), Chr(196), 'A', 1,100,1)
			lcText = STRTRAN(m.lcText, CHR(2), '',1,100,1) && caracter neprintabil		
		ENDIF


		If m.tlSpaces
			lcText = Strtran(m.lcText, ' ', '', 1, 100, 1)
		Endif
		If m.tlCR
			lcText = Strtran(Strtran(m.lcText, Chr(13), ''), Chr(10), '')
		Endif

		Return m.lcText
	Endfunc

	******************************************************
	*** Primeste o adresa de forma Strada NR LOCALITATE
	*** Intoarce un obiect cu proprietatile: STRADA, NR, LOCALITATE
	******************************************************
	Procedure ParseAdresaMFin
		Lparameters tcAdresa
		* tcAdresa: Bld. Stefan cel Mare   14   Tirgu Neamt
		Local lcAdresa, loAdresa
		loAdresa = Createobject("empty")
		AddProperty(loAdresa, "strada", "")
		AddProperty(loAdresa, "nr", "")
		AddProperty(loAdresa, "localitate", "")

		lcAdresa = Iif(!Empty(m.tcAdresa) And Type('tcAdresa') = 'C', m.tcAdresa, '')
		If !Empty(m.lcAdresa)
			lcPatternNrLocalitate = "\d+[A-Za-z\s]+$" && 14   Tirgu Neamt
			lcNrLocalitate = GetRegexp(m.lcAdresa, m.lcPatternNrLocalitate, 1) && 14   Tirgu Neamt

			lcPatternLocalitate = "[A-Za-z\s]+$" && Tirgu Neamt
			loAdresa.localitate = GetRegexp(m.lcAdresa, m.lcPatternLocalitate, 1) && Tirgu Neamt

			loAdresa.nr = Alltrim(Strtran(m.lcNrLocalitate, loAdresa.localitate, '')) && 14

			If !Empty(m.lcNrLocalitate)
				loAdresa.strada = Alltrim(Strtran(m.lcAdresa, m.lcNrLocalitate, '')) && Bld. Stefan cel Mare
			Endif
		Endif && !EMPTY()

		Return loAdresa
	Endproc && ParseAdresaMfin

	***************************************************************
	*** Intoarce un obiect Mfin cu atribute goale, pentru uz intern
	***************************************************************
	Function GetEmptyMfinObj
		Local loMFIN

		loMFIN = Createobject("empty")
		AddProperty(loMFIN, "Eroare", '')
		AddProperty(loMFIN, "Cod", "")
		AddProperty(loMFIN, "Firma", "")
		AddProperty(loMFIN, "Adresa", "")
		AddProperty(loMFIN, "Judet", "")
		AddProperty(loMFIN, "Regcom", "")
		AddProperty(loMFIN, "codpostal", "")
		AddProperty(loMFIN, "telefon", "")
		AddProperty(loMFIN, "fax", "")
		AddProperty(loMFIN, "DataTVAMFIN", "")
		AddProperty(loMFIN, "PlatitorTVAMFIN", .F.)
		AddProperty(loMFIN, "Stare", "")
		AddProperty(loMFIN, "Strada", "")
		AddProperty(loMFIN, "Nr", "")
		AddProperty(loMFIN, "Localitate", "")
		AddProperty(loMFIN, "Bloc", "")
		AddProperty(loMFIN, "Scara", "")
		AddProperty(loMFIN, "Etaj", "")
		AddProperty(loMFIN, "Apart", "")
		AddProperty(loMFIN, "TvaIncasare", .F.)
		AddProperty(loMFIN, "SplitTVA", .F.)
		AddProperty(loMFIN, "Inactiv", .F.)
		AddProperty(loMFIN, "sursa", '')
		AddProperty(loMFIN, "data_sursa", {})
		Return loMFIN
	Endfunc && GetEmptyMfinObj
Enddefine

*************************************
*** Normalizeaza un cod fiscal: UPPER, fara spatii, fara prefixul RO daca restul e numeric
*************************************
Function NormalizeazaCUI
	Lparameters tcCui

	Local lcCui, lcRest, lnI, llNumeric
	lcCui = Upper(Strtran(Alltrim(Nvl(m.tcCui, '')), ' ', ''))
	If Left(m.lcCui, 2) = 'RO'
		lcRest = Substr(m.lcCui, 3)
		llNumeric = !Empty(m.lcRest)
		For lnI = 1 To Len(m.lcRest)
			If !Isdigit(Substr(m.lcRest, lnI, 1))
				llNumeric = .F.
				Exit
			Endif
		Endfor
		If m.llNumeric
			lcCui = m.lcRest
		Endif
	Endif

	Return m.lcCui
Endfunc && NormalizeazaCUI

*************************************
*** Wrapper single-CUI peste VerificareANAF: tdData = data documentului (lipsa -> data curenta), degradare tacuta (.NULL.),
*** tlNegasit (prin referinta) = ANAF a raspuns ca nu exista codul, spre deosebire de lipsa raspunsului
*************************************
Function ANAF_VerificaCuiSingle
	Lparameters tcCui, tdData, tlNegasit, tcClasaEsec

	Local lcCuiNormalizat, loHTTP, loEx As Exception, loResult, lcJsonString, ldData
	Local loVerificareANAF As "VerificareANAF", lcAliasTemp, lnI, llValid
	Local llRaspunsPrimit, lnCuiCautat

	If Type('gvANAF_EroareLogataSesiune') = 'U'
		Public gvANAF_EroareLogataSesiune
		gvANAF_EroareLogataSesiune = .F.
	Endif

	tcClasaEsec = ''
	tlNegasit = .F.
	lcCuiNormalizat = NormalizeazaCUI(m.tcCui)
	llValid = !Empty(m.lcCuiNormalizat)
	If m.llValid
		For lnI = 1 To Len(m.lcCuiNormalizat)
			If !Isdigit(Substr(m.lcCuiNormalizat, lnI, 1))
				llValid = .F.
				Exit
			Endif
		Endfor
	Endif
	If !m.llValid
		Return .Null.
	Endif

	loResult = .Null.
	lcAliasTemp = "crsANAFSingleTemp"
	llRaspunsPrimit = .F.
	ldData = Iif(Vartype(m.tdData) = 'D' And !Empty(m.tdData), m.tdData, Date())
	lnCuiCautat = Int(Val(m.lcCuiNormalizat))

	Try
		loVerificareANAF = Createobject("VerificareANAF") && incarca nfjsonread/nfjsoncreate (Init)

		loHTTP = ANAF_CreeazaCerereANAF(m.lnCuiCautat, m.ldData, .F.)
		llRaspunsPrimit = .T.
		lcJsonString = Alltrim(loHTTP.responseText)

		If !Empty(m.lcJsonString) And Left(m.lcJsonString, 1) = '{'
			Use In (Select(m.lcAliasTemp))
			loVerificareANAF.ParseJsonANAFv8(nfjsonread(m.lcJsonString), m.lcAliasTemp)
			loVerificareANAF.SalveazaIstoricDinCursor(m.lcAliasTemp, gnIdUtil)
			loResult = ANAF_VerdictDinCursor(m.lcAliasTemp, m.lnCuiCautat, @tlNegasit, @tcClasaEsec)
		Else
			tcClasaEsec = 'RASPUNS_NEINTELES'
		Endif
	Catch To loEx
		If !gvANAF_EroareLogataSesiune
			If Type('goLog') = 'O'
				goLog.Log('ANAF_VerificaCuiSingle: ' + loEx.Message, 'ANAF_VerificaCuiSingle')
			Endif
			gvANAF_EroareLogataSesiune = .T.
		Endif
		loResult = .Null.
		tlNegasit = .F.
		tcClasaEsec = Iif(m.llRaspunsPrimit, 'RASPUNS_NEINTELES', 'FARA_RASPUNS')
	Endtry

	Return m.loResult
Endfunc && ANAF_VerificaCuiSingle

*************************************
*** Alege intre obiect de rezultat / tlNegasit (exact 1 rand, denumire goala, cui = CUI-ul cautat) /
*** tcClasaEsec = 'RASPUNS_NEINTELES', pe baza cursorului lasat de ParseJsonANAFv8; ambele prin referinta
*************************************
Function ANAF_VerdictDinCursor
	Lparameters tcAlias, tnCuiCautat, tlNegasit, tcClasaEsec

	Local loResult, lnReccountTemp

	loResult = .Null.
	tlNegasit = .F.
	tcClasaEsec = ''

	If Used(m.tcAlias)
		Select (m.tcAlias)
		*!* 01.08.2026 marius.mutu: pozitionare explicita - apelantul poate lasa cursorul pe EOF
		Go Top
		lnReccountTemp = Reccount()
		If m.lnReccountTemp = 1 And !Empty(denumire)
			loResult = Createobject("empty")
			Addproperty(loResult, "cui", cui)
			Addproperty(loResult, "scpTVA", Nvl(scpTVA, .F.))
			Addproperty(loResult, "statusInactivi", Nvl(statusInactivi, .F.))
			Addproperty(loResult, "denumire", Nvl(denumire, ""))
			Addproperty(loResult, "mesaj", Nvl(mesaj, ""))
			Addproperty(loResult, "dInceputScpTVA", Nvl(data_inceput_ScpTVA, {}))
			Addproperty(loResult, "dSfarsitScpTVA", Nvl(data_sfarsit_ScpTVA, {}))
			Addproperty(loResult, "dAnulareScpTVA", Nvl(data_anul_imp_ScpTVA, {}))
			Addproperty(loResult, "cMesajScpTVA", Nvl(mesaj_ScpTVA, ""))
		Else
			If m.lnReccountTemp = 1 And Empty(denumire) And Nvl(cui, 0) = m.tnCuiCautat
				tlNegasit = .T.
			Else
				tcClasaEsec = 'RASPUNS_NEINTELES'
			Endif
		Endif
		Use In (Select(m.tcAlias))
	Else
		tcClasaEsec = 'RASPUNS_NEINTELES'
	Endif

	Return m.loResult
Endfunc && ANAF_VerdictDinCursor

*************************************
*** Construieste, deschide (sincron sau asincron) si trimite o cerere PlatitorTvaRest v9 pentru un singur CUI;
*** folosita atat de wrapper-ul de verificare cat si de sonda de disponibilitate
*************************************
Function ANAF_CreeazaCerereANAF
	Lparameters tnCui, tdData, tlAsync

	Local loHTTP, loEx As Exception, loCol As "empty", laCoduri[1], lcSend, lcServer, ldData, lcDataFormatted

	Try
		loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
		Try
			loHTTP.SetTimeouts(2000, 2000, 3000, 3000) && rezolvare/conectare 2s, trimitere/primire 3s
		Catch To loEx
		Endtry
	Catch To loEx
		loHTTP = .Null.
	Endtry

	ldData = Iif(Vartype(m.tdData) = 'D' And !Empty(m.tdData), m.tdData, Date())
	lcDataFormatted = Left(Dtos(m.ldData), 4) + "-" + Substr(Dtos(m.ldData), 5, 2) + "-" + Substr(Dtos(m.ldData), 7, 2)

	loCol = Createobject("empty")
	Addproperty(loCol, "cui", Int(Val(Transform(m.tnCui))))
	Addproperty(loCol, "data", m.lcDataFormatted)
	laCoduri[1] = loCol
	lcSend = nfjsoncreate(@laCoduri)

	lcServer = 'https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva'

	loHTTP.Open('POST', lcServer, m.tlAsync)
	loHTTP.setRequestHeader("Content-Type", "application/json;")
	loHTTP.Send(lcSend)

	Return m.loHTTP
Endfunc && ANAF_CreeazaCerereANAF

*************************************
*** Sonda asincrona de disponibilitate ANAF: porneste o cerere pe un CUI constant (1879855, ROMFAST SRL,
*** deja folosit ca CUI de test in acest fisier), fara sa scrie in cache si fara sa produca vreun verdict de partener
*************************************
Function ANAF_SondaPorneste
	Local loEx As Exception

	ANAF_SondaOpreste()
	If Type('goANAF_SondaHTTP') = 'U'
		Public goANAF_SondaHTTP, glANAF_SondaReusita
	Endif
	goANAF_SondaHTTP = .Null.
	glANAF_SondaReusita = .F.
	Try
		goANAF_SondaHTTP = ANAF_CreeazaCerereANAF(1879855, Date(), .T.)
	Catch To loEx
		goANAF_SondaHTTP = .Null.
	Endtry

	Return (Vartype(goANAF_SondaHTTP) = 'O')
Endfunc && ANAF_SondaPorneste

*************************************
*** .T. daca sonda in curs si-a primit raspunsul (indiferent de rezultat) sau nu exista nicio sonda activa
*************************************
Function ANAF_SondaAuSositRaspunsul
	Local loEx As Exception, llSosit, llEroare
	llEroare = .F.
	
	If Vartype(goANAF_SondaHTTP) <> 'O'
		Return .T.
	Endif
	llSosit = .F.
	Try
		llSosit = goANAF_SondaHTTP.WaitForResponse(0)
	Catch To loEx
		glANAF_SondaReusita = .F.
		llEroare = .T.
	ENDTRY
	IF m.llEroare
		Return .T.
	ENDIF 
	If m.llSosit
		glANAF_SondaReusita = .T.
	Endif
	Return m.llSosit
Endfunc && ANAF_SondaAuSositRaspunsul

*************************************
*** Verdictul sondei, valabil dupa ce ANAF_SondaAuSositRaspunsul() a intors .T.
*************************************
Function ANAF_SondaAReusit
	Return (Vartype(glANAF_SondaReusita) = 'L' And glANAF_SondaReusita)
Endfunc && ANAF_SondaAReusit

*************************************
*** Abandoneaza si elibereaza sonda in curs, daca exista; intoarce .T. daca chiar era o sonda in aer
*************************************
Function ANAF_SondaOpreste
	Local loEx As Exception, llOprita

	llOprita = (Vartype(goANAF_SondaHTTP) = 'O')
	If m.llOprita
		Try
			goANAF_SondaHTTP.Abort()
		Catch To loEx
		Endtry
		goANAF_SondaHTTP = .Null.
	Endif

	Return m.llOprita
Endfunc && ANAF_SondaOpreste

*********************************************
*** Verificare coduri fiscale folosind serviciul web ANAF, cate 500 de coduri per interogare
*********************************************
Define Class VerificareANAF As Custom

	*!* 01.08.2026 marius.mutu: ultimul esec ANAF de pe traseul batch - se arata o singura data, la final, doar daca raman coduri neacoperite
	cMesajANAF = ''

	Procedure Init
		If !'nfjsonread' $ Lower(Set("Procedure"))
			Set Procedure To nfjsonread.prg Additive
		Endif
		If !'nfjsoncreate' $ Lower(Set("Procedure"))
			Set Procedure To nfjsoncreate.prg Additive
		Endif
	Endproc && Init

	*************************************
	***	VerificaListaCIF("31103995,1879855", Date(), "crsANAF")
	*** Verifica codurile fiscale din lista, la data
	*** Intoarce un cursor crsANAF (cui N(13), Data d, denumire c(60), adresa c(244), tva L, data_sfarsit d, data_anul_imp d, mesaj c(100))
	*** Ordinea ANAF/cache vine din OrdineCache(tcTraseu) - tcTraseu optional ('UNIC'/'MASA'), implicit 'MASA'
	*** cand lipseste sau e gol; pe CACHE,ANAF codurile cu rand proaspat in istoric nu se mai trimit la ANAF;
	*** indiferent de ordine, codurile ramase fara raspuns (tacere) se completeaza din istoric drept plasa de
	*** siguranta - codul gasit explicit "notFound" de ANAF nu atinge cache-ul, pentru ca primeste deja un
	*** rand in crsANAF (denumire goala) si nu mai e considerat "tacere"
	*************************************
	Function VerificaListaCIF
		Lparameters tcListaCIF, tdData, tcAlias, tcTraseu
		* tcListaCIF: lista coduri fiscale sau numele unui cursor cu coduri fiscale
		* tcTraseu: optional, 'UNIC' sau 'MASA' (vezi OrdineCache); implicit 'MASA' cand lipseste - apelantii
		* existenti (fara al patrulea parametru) raman pe comportamentul de azi

		Local llUsed, lcCursorListaCIF, lnRec, lnRecs, lcAlias
		*!* 31.07.2026 marius.mutu: al patrulea parametru tcTraseu forteaza OrdineCache(tcTraseu) in loc de 'MASA' fix
		Local lcOrdine, ldData, lcAliasNorm, lcListaCoduriN, lcCursorRamas, lnCuiCurent, lcCodFiscalCurent, ldDataCurenta, llGasitCache, lcCursorAnafTemp, loRandAnaf, lnFaraRaspuns, lnCache, lnCacheIndisp, lcListaCoduriRamase

		lcCursorListaCIF = ""
		llUsed = .F.
		lcAlias = ""
		lnFaraRaspuns = 0
		This.cMesajANAF = ''

		goLog.Log('tcListaCIF: ' + tcListaCIF, 'VerificaListaCIF')
		If Used(tcListaCIF)
			* cursor
			lcCursorListaCIF = m.tcListaCIF
			llUsed = .T.
		Else
			* lista
			*!* 01.08.2026 marius.mutu: nume unic - "cListaCIFTemp" colida cu variabila locala din overificari.vc2:2734
			lcCursorListaCIF = "crsListaCIFIntern"
			lnRecs = Getwordcount(m.tcListaCIF, ',')
			Create Cursor (lcCursorListaCIF) (cod_fiscal c(30) Null, data D null)
			For lnRec = 1 To m.lnRecs
				lcCodFiscal = Getwordnum(m.tcListaCIF, m.lnRec, ',')
				Insert Into (lcCursorListaCIF) (cod_fiscal, data) Values (m.lcCodFiscal, m.tdData)
			Endfor
		Endif

		ldData = Iif(!Empty(m.tdData) And Type('tdData') = "D", m.tdData, Date())
		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		*!* 01.08.2026 marius.mutu: golire explicita la intrare - dupa fixul de mai jos, nimic altceva nu mai garanteaza un alias curat pe niciun traseu
		Use In (Select(m.lcAlias))
		lcOrdine = This.OrdineCache(Iif(Empty(m.tcTraseu), 'MASA', Upper(Alltrim(m.tcTraseu))))
		lcAliasNorm = This.NormalizeazaCoduriCursor(m.lcCursorListaCIF, m.ldData)

		If Left(m.lcOrdine, 5) == 'CACHE'
			* CACHE,ANAF: codurile cu rand proaspat in istoric nu se mai trimit la ANAF
			lcListaCoduriN = ''
			Select (m.lcAliasNorm)
			Scan For cui_n <> 0
				lcListaCoduriN = m.lcListaCoduriN + Iif(Empty(m.lcListaCoduriN), '', ',') + Alltrim(Str(cui_n))
				Select (m.lcAliasNorm)
			Endscan
			This.CitesteIstoricPentruCoduri(m.lcListaCoduriN, m.ldData, m.lcAlias, 'CACHE')

			lcCursorRamas = 'crsListaRamasANAF'
			Use In (Select(m.lcCursorRamas))
			Create Cursor (m.lcCursorRamas) (cod_fiscal c(30) Null, data D null)
			Select (m.lcAliasNorm)
			*!* 02.08.2026 marius.mutu: la ANAF ajung doar codurile care sunt CUI RO valid - restul nu pot fi nici in cache, nici verificate
			Scan For cui_n <> 0
				lnCuiCurent = cui_n
				lcCodFiscalCurent = cod_fiscal
				ldDataCurenta = data
				llGasitCache = .F.
				If m.lnCuiCurent <> 0 And Used(m.lcAlias) And Reccount(m.lcAlias) > 0
					Select (m.lcAlias)
					Locate For cui = m.lnCuiCurent
					llGasitCache = Found()
				Endif
				If !m.llGasitCache
					Insert Into (m.lcCursorRamas) (cod_fiscal, data) Values (m.lcCodFiscalCurent, m.ldDataCurenta)
				Endif
				Select (m.lcAliasNorm)
			Endscan

			If Reccount(m.lcCursorRamas) > 0
				*!* 01.08.2026 marius.mutu: alias temporar - ANAF_SincronWebService_PlatitorTva goleste neconditionat aliasul primit (:2025), iar aici e deja populat din cache
				lcCursorAnafTemp = 'crsAnafBatchTemp'
				Use In (Select(m.lcCursorAnafTemp))
				lcCursorAnafTemp = This.ANAF_SincronWebService_PlatitorTva(m.lcCursorRamas, m.tdData, m.lcCursorAnafTemp)
				If Used(m.lcCursorAnafTemp) And Reccount(m.lcCursorAnafTemp) > 0
					Select (m.lcCursorAnafTemp)
					Scan
						Scatter Name loRandAnaf Memo
						Insert Into (m.lcAlias) FROM NAME loRandAnaf
						Select (m.lcCursorAnafTemp)
					Endscan
				Endif
				Use In (Select(m.lcCursorAnafTemp))
			Endif
			Use In (Select(m.lcCursorRamas))
		Else
			* ANAF,CACHE: comportamentul de azi, ANAF intai pentru toate codurile
			lcAlias = This.ANAF_SincronWebService_PlatitorTva(m.lcCursorListaCIF, m.tdData, m.lcAlias)
		Endif

		If !m.llUsed
			Use In (Select(lcCursorListaCIF))
		Endif

		* plasa de siguranta la tacere, indiferent de ordine: codurile fara rand in crsANAF (nici din ANAF,
		* nici din cache) se completeaza acum din istoric, marcate CACHE_INDISP; un rand deja prezent
		* (raspuns ANAF gasit sau notFound, sau deja servit din cache mai sus) nu e atins
		lcListaCoduriRamase = ''
		Select (m.lcAliasNorm)
		Scan For cui_n <> 0
			lnCuiCurent = cui_n
			llGasitCache = .F.
			If Used(m.lcAlias) And Reccount(m.lcAlias) > 0
				Select (m.lcAlias)
				Locate For cui = m.lnCuiCurent
				llGasitCache = Found()
			Endif
			If !m.llGasitCache
				lcListaCoduriRamase = m.lcListaCoduriRamase + Iif(Empty(m.lcListaCoduriRamase), '', ',') + Transform(m.lnCuiCurent)
			Endif
			Select (m.lcAliasNorm)
		Endscan
		Use In (Select(m.lcAliasNorm))

		If !Empty(m.lcListaCoduriRamase)
			This.CitesteIstoricPentruCoduri(m.lcListaCoduriRamase, m.ldData, m.lcAlias, 'CACHE_INDISP')
			lnRecs = Getwordcount(m.lcListaCoduriRamase, ',')
			For lnRec = 1 To m.lnRecs
				lnCuiCurent = Val(Getwordnum(m.lcListaCoduriRamase, m.lnRec, ','))
				llGasitCache = .F.
				If Used(m.lcAlias) And Reccount(m.lcAlias) > 0
					Select (m.lcAlias)
					Locate For cui = m.lnCuiCurent
					llGasitCache = Found()
				Endif
				lnFaraRaspuns = m.lnFaraRaspuns + Iif(m.llGasitCache, 0, 1)
			Endfor
		Endif

		*!* 01.08.2026 marius.mutu: un singur mesaj la final, doar cand au ramas coduri fara verdict (nici de la ANAF, nici din cache)
		If m.lnFaraRaspuns > 0 And !Empty(This.cMesajANAF)
			AMESSAGEBOX(This.cMesajANAF + Chr(13) + Chr(10) + Alltrim(Str(m.lnFaraRaspuns)) + ' coduri fiscale nu au putut fi verificate.', 0 + 48, _Screen.Caption)
		Endif

		If Used(m.lcAlias) And Reccount(m.lcAlias) > 0
			This.SalveazaIstoricDinCursor(m.lcAlias, gnIdUtil)
		Endif

		* criteriul 9: totalul randurilor completate din cache (CACHE si CACHE_INDISP), o singura linie in goLog
		If Used(m.lcAlias) And Reccount(m.lcAlias) > 0
			Select (m.lcAlias)
			lnCache = 0
			lnCacheIndisp = 0
			Scan For Left(Nvl(sursa, ''), 5) == 'CACHE'
				If Upper(Alltrim(sursa)) == 'CACHE_INDISP'
					lnCacheIndisp = m.lnCacheIndisp + 1
				Else
					lnCache = m.lnCache + 1
				Endif
				Select (m.lcAlias)
			Endscan
			If m.lnCache + m.lnCacheIndisp > 0
				goLog.Log('cache total=' + Transform(m.lnCache + m.lnCacheIndisp) + ' cache=' + Transform(m.lnCache) + ' cache_indisp=' + Transform(m.lnCacheIndisp), 'VerificaListaCIF')
			Endif
		Endif

		Return m.lcAlias
	Endfunc && AnafPlatitorTVA

	*************************************
	*** Normalizeaza codurile fiscale dintr-un cursor in forma tcCursorListaCIF (cod_fiscal C(30)[, data D]),
	*** dupa acelasi tipar ca ANAF_SincronWebService_PlatitorTva (cod tara RO, doar cifre, <=10 caractere).
	*** Cand sursa nu are coloana data (ex. orapoarte.prg:1994/2311, cursor doar cu cod_fiscal), se
	*** foloseste tdData pentru toate randurile - acelasi fallback ca llDataCursor din functia de mai sus
	*** Intoarce un cursor nou (cod_fiscal, data, cui_n N(13)) - cui_n = 0 cand codul nu e un CUI RO valid
	*************************************
	Function NormalizeazaCoduriCursor
		Lparameters tcCursorListaCIF, tdData

		Local loVerificareCod As "VerificareCod", lcCodFiscal, lcCodTara, lcCodFiscalFRO, lcAliasNorm, lcSelect, llDataCursor, ldDataRand, ldDataImplicit, lnCuiNorm
		lcSelect = Select()
		lcAliasNorm = 'crsCoduriNormalizate'
		Use In (Select(m.lcAliasNorm))
		Create Cursor (m.lcAliasNorm) (cod_fiscal C(30), data D, cui_n N(13))

		ldDataImplicit = Iif(Type('tdData') = 'D' And !Empty(m.tdData), m.tdData, Date())
		llDataCursor = (Type(m.tcCursorListaCIF + '.data') = 'D')

		loVerificareCod = Createobject("VerificareCod")
		Select (m.tcCursorListaCIF)
		Scan
			*!* 01.08.2026 marius.mutu: cursoarele sursa au cod_fiscal/data nullable - fara Nvl, insertul de mai jos pica pe coloanele not null
			lcCodFiscal = Alltrim(Nvl(cod_fiscal, ''))
			lcCodTara = loVerificareCod.GetCodTara(m.lcCodFiscal)
			lcCodFiscalFRO = Strtran(m.lcCodFiscal, m.lcCodTara, '')
			lcCodFiscalFRO = Strtran(Strtran(Strtran(m.lcCodFiscalFRO, ' ', ''), 'RO', ''), 'R', '')
			ldDataRand = Iif(m.llDataCursor And !Empty(Nvl(data, {})), Nvl(data, {}), m.ldDataImplicit)
			*!* 02.08.2026 marius.mutu: pe langa formatul de baza, si cifra de control (VALIDARE_CIF) - un CIF invalid nu are ce cauta nici in cache, nici la ANAF
			lnCuiNorm = 0
			If m.lcCodTara = 'RO' And Isdigit(m.lcCodFiscalFRO) And Len(m.lcCodFiscalFRO) <= 10 ;
					And Val(m.lcCodFiscalFRO) <> 0 And loVerificareCod.VALIDARE_CIF(m.lcCodFiscalFRO)
				lnCuiNorm = Int(Val(m.lcCodFiscalFRO))
			Endif
			Insert Into (m.lcAliasNorm) (cod_fiscal, data, cui_n) Values (m.lcCodFiscal, m.ldDataRand, m.lnCuiNorm)
			Select (m.tcCursorListaCIF)
		Endscan

		Select (m.lcSelect)
		Return m.lcAliasNorm
	Endfunc && NormalizeazaCoduriCursor

	*
	Function ANAF_SincronWebService_PlatitorTva
		Lparameters tcCursorListaCIF, tdData, tcAlias

		Local loCol As "empty"
		Local loHTTP As 'Microsoft.XMLHTTP'
		Local laCoduri[1], lcAlias, lcData, lcDataFormatted, lcJsonString, lcListaCIF, lcSend, lcServer, lcCodFiscal, llDataCursor
		Local ldData, lnRec, lnRecords, loJsonObject, lnIdx, lnRec1, lnRec2, lnGrup, lnGrupuri, loEx As Exception
		Local loVerificareCod As "VerificareCod"
		Local lcCodFiscalFRO, lcCodTara, lcMesaj, llRO, lnReqNo, lnWaitSeconds, laFound, lcCodJudet

		lcJsonString = ""
		
		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		USE IN (SELECT(m.lcAlias))
		
		ldData = Iif(!Empty(m.tdData) And Type('tdData') = "D", m.tdData, Date())

		lcData = Dtos(m.ldData)
		*lcDataFormatted = Left(m.lcData, 4) + "-" + Substr(m.lcData, 5, 2) + "-" + Substr(m.lcData, 7, 2)
		lnRecords = Reccount(tcCursorListaCIF)

		IF m.lnRecords = 0
			Return m.lcAlias
		ENDIF 	
		
		llDataCursor = (TYPE(tcCursorListaCIF + '.data') = 'D') && daca exista coloana data in cursor, folosesc data din cursor, daca este completata
				
		goLog.Log('lnRecords: ' + Transform(m.lnRecords), 'ANAF_SincronWebService_PlatitorTva')
		Try
			loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
			Try
				loHTTP.SetTimeouts(2000, 2000, 3000, 3000)
			Catch To loEx
			Endtry
		Catch To loEx
		ENDTRY

		If Type('loHTTP') <> 'O'
			Try
				loHTTP = Createobject('Microsoft.XMLHTTP')	&& 04.07.2016
			Catch To loEx
				This.cMesajANAF = loEx.Message
			Endtry
		Endif
		If Type('loHTTP') <> 'O'
			goLog.Log("TYPE('loHTTP') <> 'O'", 'ANAF_SincronWebService_PlatitorTva')
			Return m.lcAlias
		Endif

		* lcServer = 'https://webservicesp.anaf.ro:/PlatitorTvaRest/api/v1/ws/tva' && api v1
		* lcServer = 'https://webservicesp.anaf.ro/PlatitorTvaRest/api/v3/ws/tva'
*!*			lcServer = 'https://webservicesp.anaf.ro/PlatitorTvaRest/api/v5/ws/tva'
*!*			lcServer = 'https://webservicesp.anaf.ro/PlatitorTvaRest/api/v6/ws/tva'
		lcServer = 'https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva'

		loVerificareCod = Createobject("VerificareCod")
		lnReqNo = 100 && maxim 100 CUI-uri pe verificare
		lnWaitSeconds = 1 && minim 1 secunda intre interogari
		lnGrupuri = Max(CEILING(m.lnRecords / m.lnReqNo), 1) && grupuri de cate 500 de coduri maxim per interogare
		For lnGrup = 1 To m.lnGrupuri
			lnRec1 = m.lnReqNo * (m.lnGrup - 1) + 1
			lnRec2 = Min(m.lnReqNo * m.lnGrup, m.lnRecords)
			Wait Window 'Verific codurile fiscale ' + Alltrim(Str(m.lnRec1)) + '..' + Alltrim(Str(m.lnRec2)) + ' / ' + Alltrim(Str(m.lnRecords)) Nowait

			Release laCoduri
			Dimension laCoduri(m.lnRec2 - lnRec1 + 1)
			lnIdx = 0
			Select (m.tcCursorListaCIF)
			Scan For Between(Recno(), lnRec1, lnRec2)
				lcCodFiscal = Alltrim(cod_fiscal)
				IF m.llDataCursor AND !EMPTY(data)
					lcData = DTOS(data)
				ELSE
					lcData = DTOS(m.ldData)	
				ENDIF 
				lcDataFormatted = Left(m.lcData, 4) + "-" + Substr(m.lcData, 5, 2) + "-" + Substr(m.lcData, 7, 2)
			
				lcCodTara = loVerificareCod.GetCodTara(m.lcCodFiscal)
				llRO = (m.lcCodTara = 'RO')

				lcCodFiscalFRO = Strtran(m.lcCodFiscal, m.lcCodTara, '')
				lcCodFiscalFRO = Strtran(Strtran(Strtran(m.lcCodFiscalFRO, ' ', ''), 'RO', ''), 'R', '')
											
				*!* 02.08.2026 marius.mutu: acelasi filtru ca in NormalizeazaCoduriCursor - format de baza plus cifra de control (VALIDARE_CIF)
				If m.llRO AND (Isdigit(m.lcCodFiscalFRO) and Len(m.lcCodFiscalFRO) <= 10 and Val(m.lcCodFiscalFRO) <> 0 and loVerificareCod.VALIDARE_CIF(m.lcCodFiscalFRO))
					loCol = Createobject("empty")
					AddProperty(loCol, "cui", Int(Val(m.lcCodFiscalFRO)))
					AddProperty(loCol, "data", m.lcDataFormatted)
					lnIdx = lnIdx + 1
					laCoduri[lnIdx] = loCol
				ENDIF
			Endscan && tcCursorListaCIF
			*!* 02.08.2026 marius.mutu: grup fara niciun CUI valid - nu se mai trimite cerere goala la ANAF
			IF m.lnIdx = 0
				LOOP
			ENDIF
			Dimension laCoduri(lnIdx)

			lcSend = nfjsoncreate(@laCoduri)
			goLog.Log('lcSend: ' + m.lcSend, 'ANAF_SincronWebService_PlatitorTva')

			*!* 31.07.2026 marius.mutu: procesarea raspunsului (status+corp) mutata in ProceseazaRaspunsHTTP, mai jos
			Try
				loHTTP.Open('POST', lcServer, .F.) && !!! POST e blocat de furnizor
				loHTTP.setRequestHeader("Content-Type", "application/json;")
				loHTTP.Send(lcSend)
				lcAlias = This.ProceseazaRaspunsHTTP(loHTTP.Status, loHTTP.responseText, m.tcAlias)
			Catch To loEx
				This.cMesajANAF = loEx.Message
			Endtry
			*
			If m.lnGrup < m.lnGrupuri
				INKEY(m.lnWaitSeconds)&& astept o secunda intre interogari
			ENDIF
		Endfor && lnGrup
		*
		Return m.lcAlias
	Endfunc && ANAF_SincronWebService_PlatitorTva

	*************************************
	*** Proceseaza UN raspuns HTTP deja primit pe calea batch (status + corp), separat de trimiterea
	*** cererii ca sa poata fi testat direct, cu status+corp fabricate, fara transport HTTP real.
	*** Corpul se citeste indiferent de status (nu doar pe 200) - ANAF poate intoarce si 404 cu corp
	*** JSON complet cand toate codurile din grup sunt inexistente (masurat 27.07.2026), la fel ca pe
	*** calea single-CUI (ANAF_VerificaCuiSingle). Un raspuns e considerat inteles cand are structura
	*** found/notFound, chiar daca found e gol (lot integral notFound); altfel ramane tacere - cursorul
	*** nu se modifica, deci codurile din grup raman fara rand in crsANAF, ca la o cadere reala de serviciu
	*************************************
	Function ProceseazaRaspunsHTTP
		Lparameters tnStatus, tcResponseText, tcAlias

		Local lcAlias, lcJsonString, loJsonObject, loEx As Exception, lcMesaj, llRaspunsInteles

		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		lcJsonString = Alltrim(Nvl(m.tcResponseText, ''))
		goLog.Log('tnStatus: ' + Transform(m.tnStatus) + ' lcJsonString: ' + m.lcJsonString, 'ANAF_SincronWebService_PlatitorTva')

		If Empty(m.lcJsonString) Or Left(m.lcJsonString, 1) <> '{'
			If !Empty(m.lcJsonString)
				IF 'mentenanta'$LOWER(m.lcJsonString)
					This.cMesajANAF = 'Serviciul web ANAF este in mentenanta!'
				ELSE
					This.cMesajANAF = 'Serviciul web ANAF nu a intors un raspuns corespunzator.'
				ENDIF
			Endif
			Return m.lcAlias && tacere: fara corp folosibil, cursorul ramane neschimbat
		Endif

		Try
			loJsonObject = nfjsonread(m.lcJsonString) && nfJson from http://vfpx.codeplex.com/
			llRaspunsInteles = (Type('loJsonObject') = 'O' And Pemstatus(m.loJsonObject, 'found_vfpsafe_', 5))
			If m.llRaspunsInteles
				lcAlias = This.ParseJsonANAFv8(m.loJsonObject, m.tcAlias)
			Else
				lcMesaj = 'Serviciul web ANAF a intors mesaj de eroare: ' + IIF(TYPE('loJsonObject.message') = 'C', loJsonObject.message, '')
				This.cMesajANAF = m.lcMesaj
			Endif
		Catch To loEx
			This.cMesajANAF = loEx.Message
		Endtry

		Return m.lcAlias
	Endfunc && ProceseazaRaspunsHTTP

	*************************************
	*** Parseaza obiectul cu raspunsul de la ANAF si creeaza cursorul crsANAF
	*** intoarce numele cursorului creat
	*************************************
	Procedure ParseJsonANAFv8
		Lparameters toJsonObject, m.tcAlias

		Local lcSave_SetDate, lnRec, loRec, loAdresa
		Local lcAlias, lnCUI, lnRecords, loDate, loDateGenerale, loEx, loInregistrareRTVAI
		Local loInregistrareSplitTVA, loInregistrareTVA, loJsonObject, loStareInactiv

		loJsonObject = Iif(Type('toJsonObject') = "O" And Pemstatus(toJsonObject, "found_vfpsafe_", 5), toJsonObject, Null)

		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		If !Used(m.lcAlias)
			Create Cursor (m.lcAlias) (cui N(13), data D, denumire V(100), firma V(100), adresa C(244), nrRegCom C(30), scpTVA L, data_inceput_ScpTVA D, data_sfarsit_ScpTVA D, data_anul_imp_ScpTVA D, mesaj_ScpTVA C(244), ;
				dataInceputTvaInc D, dataSfarsitTvaInc D, dataActualizareTvaInc D, dataPublicareTvaInc D, tipActTvaInc C(100), statusTvaIncasare L, dataInactivare D, dataReactivare D, dataPublicare D, dataRadiere D, statusInactivi L, ;
				dataInceputSplitTVA D, dataAnulareSplitTVA D, statusSplitTVA L, ;
				tva L, tvaincasare L, splittva L, inactiv L, ;
				mesaj V(100), judet V(100), strada V(100), nr V(20), localitate V(100), Bloc V(20), scara V(20), etaj V(20), apart V(20), ;
				sursa C(20), data_sursa D)
		Endif

		If !Isnull(loJsonObject)
			goLog.Log('JsonObject ' + Transform(Alen(loJsonObject.found_vfpsafe_, 1)) + ' found ' + Transform(Alen(loJsonObject.notfound, 1)) + ' not found', 'ParseJsonANAF')

			lcSave_SetDate = Set("Date")
			Set Date To YMD
			Try
			*
			lnRecords = Alen(loJsonObject.found_vfpsafe_, 1)
			For lnRec = 1 To m.lnRecords
				loRec = loJsonObject.found_vfpsafe_(m.lnRec)
				If Type('loRec') <> 'O'
					LOOP 
				ENDIF 
				SELECT (m.lcAlias)
				SCATTER NAME loDate MEMO BLANK

				IF TYPE('loRec.date_generale') = 'O'
					loDateGenerale = loRec.date_generale

					loDateGenerale.adresa = This.RemoveCharacters(loDateGenerale.adresa)
					loAdresa = This.ParseAdresaAnaf(loDateGenerale.adresa)			
					
					loDate.cui = loDateGenerale.Cui
					loDate.data = CTOD(loDateGenerale.data)
					
					loDate.denumire = This.RemoveCharacters(loDateGenerale.denumire) 
					loDate.firma = loDateGenerale.denumire
					
					loDate.adresa = loDateGenerale.adresa				
					loDate.judet = loAdresa.judet
					loDate.strada = loAdresa.strada
					loDate.nr = loAdresa.nr
					loDate.localitate = loAdresa.localitate
					loDate.bloc = loAdresa.Bloc
					loDate.scara = loAdresa.scara
					loDate.etaj = loAdresa.etaj
					loDate.apart = loAdresa.apart	
											
					loDate.nrRegCom = IIF(TYPE('loDateGenerale.nrRegCom') <> 'U', loDateGenerale.nrRegCom, '')	
				ENDIF 
				
				IF TYPE('loRec.inregistrare_scop_tva') = 'O'		
					loInregistrareTVA = loRec.inregistrare_scop_tva
					
					loDate.scpTVA = loInregistrareTVA.scpTVA
					IF TYPE('loInregistrareTVA.perioade_tva',1) <> "U"
						TRY
							loDate.data_inceput_ScpTVA = CTOD(loInregistrareTVA.perioade_tva[1].data_inceput_ScpTVA)
							loDate.data_sfarsit_ScpTVA = CTOD(loInregistrareTVA.perioade_tva[1].data_sfarsit_ScpTVA)
							loDate.data_anul_imp_ScpTVA = CTOD(loInregistrareTVA.perioade_tva[1].data_anul_imp_ScpTVA)
							loDate.mesaj_ScpTVA = loInregistrareTVA.perioade_tva[1].mesaj_ScpTVA
							IF !Empty(loInregistrareTVA.perioade_tva[1].data_inceput_ScpTVA) And Empty(loDate.data_inceput_ScpTVA)
								goLog.Log('ParseJsonANAFv8: data_inceput_ScpTVA neparsabila (' + loInregistrareTVA.perioade_tva[1].data_inceput_ScpTVA + ')', 'ParseJsonANAF')
							ENDIF
							IF !Empty(loInregistrareTVA.perioade_tva[1].data_sfarsit_ScpTVA) And Empty(loDate.data_sfarsit_ScpTVA)
								goLog.Log('ParseJsonANAFv8: data_sfarsit_ScpTVA neparsabila (' + loInregistrareTVA.perioade_tva[1].data_sfarsit_ScpTVA + ')', 'ParseJsonANAF')
							ENDIF
							IF !Empty(loInregistrareTVA.perioade_tva[1].data_anul_imp_ScpTVA) And Empty(loDate.data_anul_imp_ScpTVA)
								goLog.Log('ParseJsonANAFv8: data_anul_imp_ScpTVA neparsabila (' + loInregistrareTVA.perioade_tva[1].data_anul_imp_ScpTVA + ')', 'ParseJsonANAF')
							ENDIF
						CATCH TO loEx
						ENDTRY
					ENDIF 	
				ENDIF 		
				
				IF TYPE('loRec.inregistrare_RTVAI') = 'O'							
					loInregistrareRTVAI = loRec.inregistrare_RTVAI
					
					loDate.dataInceputTvaInc = CTOD(loInregistrareRTVAI.dataInceputTvaInc)
					loDate.dataSfarsitTvaInc = CTOD(loInregistrareRTVAI.dataSfarsitTvaInc)
					loDate.dataActualizareTvaInc = CTOD(loInregistrareRTVAI.dataActualizareTvaInc)
					loDate.dataPublicareTvaInc = CTOD(loInregistrareRTVAI.dataPublicareTvaInc)
					loDate.tipActTvaInc = loInregistrareRTVAI.tipActTvaInc
					loDate.statusTvaIncasare = loInregistrareRTVAI.statusTvaIncasare
				ENDIF 	
				
				IF TYPE('loRec.stare_inactiv') = 'O'						
					loStareInactiv = loRec.stare_inactiv
					
					loDate.dataInactivare = CTOD(loStareInactiv.dataInactivare)
					loDate.dataReactivare = CTOD(loStareInactiv.dataReactivare) 
					loDate.dataPublicare = CTOD(loStareInactiv.dataPublicare)
					loDate.dataRadiere = CTOD(loStareInactiv.dataRadiere)
					loDate.statusInactivi = loStareInactiv.statusInactivi 
				ENDIF 
				
				IF TYPE('loRec.inregistrare_SplitTVA') = 'O'
					loInregistrareSplitTVA = loRec.inregistrare_SplitTVA
					
					loDate.dataInceputSplitTVA = CTOD(loInregistrareSplitTVA.dataInceputSplitTVA)
					loDate.dataAnulareSplitTVA = CTOD(loInregistrareSplitTVA.dataAnulareSplitTVA) 
					loDate.statusSplitTVA = loInregistrareSplitTVA.statusSplitTVA
					loDate.statusSplitTVA = loInregistrareSplitTVA.statusSplitTVA 
				ENDIF 		
				
				loDate.tva = loDate.scpTVA
				loDate.tvaincasare = loDate.statusTvaIncasare
				loDate.splittva = loDate.statusSplitTVA
				loDate.inactiv = loDate.statusInactivi
				loDate.mesaj = loDate.mesaj_ScpTVA
				loDate.sursa = 'ANAF'

				IF !EMPTY(NVL(loDate.cui, 0))
					Insert Into (m.lcAlias) FROM NAME loDate 
				ENDIF 	
			Endfor

			For lnRec = 1 To Alen(loJsonObject.notfound, 1)
				lnCUI = loJsonObject.notfound(m.lnRec)
				If Type('lnCUI') = 'N'
					SELECT (m.lcAlias)
					SCATTER NAME loDate MEMO BLANK
					
					loDate.cui = m.lnCUI
					loDate.sursa = 'ANAF'

					IF !EMPTY(NVL(loDate.cui, 0))
						Insert Into (m.lcAlias) FROM NAME loDate 
					ENDIF 
				Endif
			Endfor
			*	
			Finally
				Set Date To &lcSave_SetDate
			Endtry
		Else
			goLog.Log('JsonObject is null', 'ParseJsonANAF')
		Endif
		Return m.lcAlias
	ENDPROC
	
	*************************************
	*** Parseaza obiectul cu raspunsul de la ANAF si creeaza cursorul crsANAF
	*** intoarce numele cursorului creat
	*************************************
	Procedure ParseJsonANAFv3
		Lparameters toJsonObject, m.tcAlias

		Local lcSave_SetDate, lnRec, loRec, loAdresa
		loJsonObject = Iif(Type('toJsonObject') = "O" And Pemstatus(toJsonObject, "found_vfpsafe_", 5), toJsonObject, Null)

		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		If !Used(m.lcAlias)
			Create Cursor (m.lcAlias) (cui N(13), data D, denumire V(100), firma V(100), adresa C(244), nrRegCom C(30), scpTVA L, data_inceput_ScpTVA D, data_sfarsit_ScpTVA D, data_anul_imp_ScpTVA D, mesaj_ScpTVA C(244), ;
				dataInceputTvaInc D, dataSfarsitTvaInc D, dataActualizareTvaInc D, dataPublicareTvaInc D, tipActTvaInc C(100), statusTvaIncasare L, dataInactivare D, dataReactivare D, dataPublicare D, dataRadiere D, statusInactivi L, ;
				dataInceputSplitTVA D, dataAnulareSplitTVA D, statusSplitTVA L, ;
				tva L, tvaincasare L, splittva L, inactiv L, ;
				mesaj V(100), judet V(100), strada V(100), nr V(20), localitate V(100), Bloc V(20), scara V(20), etaj V(20), apart V(20))			
		Endif

		If !Isnull(loJsonObject)
			goLog.Log('JsonObject ' + Transform(Alen(loJsonObject.found_vfpsafe_, 1)) + ' found ' + Transform(Alen(loJsonObject.notfound, 1)) + ' not found', 'ParseJsonANAF')

			lcSave_SetDate = Set("Date")
			Set Date To YMD
			*
			For lnRec = 1 To Alen(loJsonObject.found_vfpsafe_, 1)
				loRec = loJsonObject.found_vfpsafe_(m.lnRec)
				If Type('loRec') = 'O'
					loRec.adresa = This.RemoveCharacters(loRec.adresa)
					loAdresa = This.ParseAdresaAnaf(loRec.adresa)
					lcNrRegCom = IIF(TYPE('loRec.nrRegCom') <> 'U', loRec.nrRegCom, '')
						
					Insert Into (m.lcAlias) (cui, data, denumire, firma, adresa, nrRegCom, ;
					scpTVA, data_inceput_ScpTVA, data_sfarsit_ScpTVA, data_anul_imp_ScpTVA, mesaj_ScpTVA, ;
					dataInceputTvaInc, dataSfarsitTvaInc, dataActualizareTvaInc, dataPublicareTvaInc, tipActTvaInc, statusTvaIncasare, ;
					dataInactivare, dataReactivare, dataPublicare, dataRadiere, statusInactivi, ;
					dataInceputSplitTVA, dataAnulareSplitTVA, statusSplitTVA, ;
					tva, tvaincasare, splittva, inactiv, ;
					mesaj, judet, strada, nr, localitate, Bloc, scara, etaj, apart) VALUES ;
					(loRec.cui, CTOD(loRec.data), loRec.denumire, loRec.denumire, loRec.adresa, m.lcNrRegCom, ;
					loRec.scpTVA, CTOD(loRec.data_inceput_ScpTVA), CTOD(loRec.data_sfarsit_ScpTVA), CTOD(loRec.data_anul_imp_ScpTVA), loRec.mesaj_ScpTVA, ;
					CTOD(loRec.dataInceputTvaInc), CTOD(loRec.dataSfarsitTvaInc), CTOD(loRec.dataActualizareTvaInc), CTOD(loRec.dataPublicareTvaInc), loRec.tipActTvaInc, loRec.statusTvaIncasare, ;
					CTOD(loRec.dataInactivare), CTOD(loRec.dataReactivare), CTOD(loRec.dataPublicare), CTOD(loRec.dataRadiere), loRec.statusInactivi, ;
					CTOD(loRec.dataInceputSplitTVA), CTOD(loRec.dataAnulareSplitTVA), loRec.statusSplitTVA, ;
					loRec.scpTVA, loRec.statusTvaIncasare, loRec.statusSplitTVA, loRec.statusInactivi, ;
					loRec.mesaj_ScpTVA, loAdresa.judet, loAdresa.strada, loAdresa.nr, loAdresa.localitate, loAdresa.Bloc, loAdresa.scara, loAdresa.etaj, loAdresa.apart)						
				Endif
			Endfor

			For lnRec = 1 To Alen(loJsonObject.notfound, 1)
				loRec = loJsonObject.notfound(m.lnRec)
				If Type('loRec') = 'O'
					loRec.adresa = This.RemoveCharacters(loRec.adresa)
					loAdresa = This.ParseAdresaAnaf(loRec.adresa)
					lcNrRegCom = IIF(TYPE('loRec.nrRegCom') <> 'U', loRec.nrRegCom, '')
					
					Insert Into (m.lcAlias) (cui, data, denumire, firma, adresa, nrRegCom, ;
					scpTVA, data_inceput_ScpTVA, data_sfarsit_ScpTVA, data_anul_imp_ScpTVA, mesaj_ScpTVA, ;
					dataInceputTvaInc, dataSfarsitTvaInc, dataActualizareTvaInc, dataPublicareTvaInc, tipActTvaInc, statusTvaIncasare, ;
					dataInactivare, dataReactivare, dataPublicare, dataRadiere, statusInactivi, ;
					dataInceputSplitTVA, dataAnulareSplitTVA, statusSplitTVA, ;
					tva, tvaincasare, splittva, inactiv, ;
					mesaj, judet, strada, nr, localitate, Bloc, scara, etaj, apart) VALUES ;
					(loRec.cui, CTOD(loRec.data), loRec.denumire, loRec.denumire, loRec.adresa, m.lcNrRegCom, ;
					loRec.scpTVA, CTOD(loRec.data_inceput_ScpTVA), CTOD(loRec.data_sfarsit_ScpTVA), CTOD(loRec.data_anul_imp_ScpTVA), loRec.mesaj_ScpTVA, ;
					CTOD(loRec.dataInceputTvaInc), CTOD(loRec.dataSfarsitTvaInc), CTOD(loRec.dataActualizareTvaInc), CTOD(loRec.dataPublicareTvaInc), loRec.tipActTvaInc, loRec.statusTvaIncasare, ;
					CTOD(loRec.dataInactivare), CTOD(loRec.dataReactivare), CTOD(loRec.dataPublicare), CTOD(loRec.dataRadiere), loRec.statusInactivi, ;
					CTOD(loRec.dataInceputSplitTVA), CTOD(loRec.dataAnulareSplitTVA), loRec.statusSplitTVA, ;
					loRec.scpTVA, loRec.statusTvaIncasare, loRec.statusSplitTVA, loRec.statusInactivi, ;					
					loRec.mesaj_ScpTVA, loAdresa.judet, loAdresa.strada, loAdresa.nr, loAdresa.localitate, loAdresa.Bloc, loAdresa.scara, loAdresa.etaj, loAdresa.apart)						

				Endif
			Endfor
			*	
			Set Date To &lcSave_SetDate
		Else
			goLog.Log('JsonObject is null', 'ParseJsonANAF')
		Endif
		Return m.lcAlias
	ENDPROC
	
	*************************************
	*** Parseaza obiectul cu raspunsul de la ANAF si creeaza cursorul crsANAF
	*** intoarce numele cursorului creat
	*************************************
	Procedure ParseJsonANAFv1
		Lparameters toJsonObject, m.tcAlias

		Local lcSave_SetDate, lnRec, loRec, loAdresa
		loJsonObject = Iif(Type('toJsonObject') = "O" And Pemstatus(toJsonObject, "found_vfpsafe_", 5), toJsonObject, Null)

		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		If !Used(m.lcAlias)
			Create Cursor (m.lcAlias)(cui N(13), Data D, denumire V(100), firma V(100), adresa V(244), tva L, data_sfarsit D, data_anul_imp D, mesaj V(100), judet V(100), strada V(100), nr V(20), localitate V(100), Bloc V(20), scara V(20), etaj V(20), apart V(20))
		Endif

		If !Isnull(loJsonObject)
			goLog.Log('JsonObject ' + Transform(Alen(loJsonObject.found_vfpsafe_, 1)) + ' found ' + Transform(Alen(loJsonObject.notfound, 1)) + ' not found', 'ParseJsonANAF')

			lcSave_SetDate = Set("Date")
			Set Date To YMD
			*
			For lnRec = 1 To Alen(loJsonObject.found_vfpsafe_, 1)
				loRec = loJsonObject.found_vfpsafe_(m.lnRec)
				If Type('loRec') = 'O'
					loRec.adresa = This.RemoveCharacters(loRec.adresa)
					loAdresa = This.ParseAdresaAnaf(loRec.adresa)
					Insert Into (m.lcAlias) (cui, Data, denumire, firma, adresa, tva, data_sfarsit, data_anul_imp, mesaj, judet, strada, nr, localitate, Bloc, scara, etaj, apart) Values;
						(loRec.cui, Ctod(loRec.Data), loRec.denumire, loRec.denumire, loRec.adresa, loRec.tva, Ctod(loRec.data_sfarsit), Ctod(loRec.data_anul_imp), loRec.mesaj, loAdresa.judet, loAdresa.strada, loAdresa.nr, loAdresa.localitate, loAdresa.Bloc, loAdresa.scara, loAdresa.etaj, loAdresa.apart)
				Endif
			Endfor

			For lnRec = 1 To Alen(loJsonObject.notfound, 1)
				loRec = loJsonObject.notfound(m.lnRec)
				If Type('loRec') = 'O'
					loRec.adresa = This.RemoveCharacters(loRec.adresa)
					loAdresa = This.ParseAdresaAnaf(loRec.adresa)
					Insert Into (m.lcAlias) (cui, Data, denumire, firma, adresa, tva, data_sfarsit, data_anul_imp, mesaj, judet, strada, nr, localitate, Bloc, scara, etaj, apart) Values;
						(loRec.cui, Ctod(loRec.Data), loRec.denumire, loRec.denumire, loRec.adresa, loRec.tva, Ctod(loRec.data_sfarsit), Ctod(loRec.data_anul_imp), loRec.mesaj, loAdresa.judet, loAdresa.strada, loAdresa.nr, loAdresa.localitate, loAdresa.Bloc, loAdresa.scara, loAdresa.etaj, loAdresa.apart)
				Endif
			Endfor
			*	
			Set Date To &lcSave_SetDate
		Else
			goLog.Log('JsonObject is null', 'ParseJsonANAF')
		Endif
		Return m.lcAlias
	Endproc

		*** curata textul de diacritice, spatii, CR/LF
	Function RemoveCharacters
		Lparameters tcText, tlDiacritics, tlSpaces, tlCR
		*** tcText: textul initial
		*** tlDiacritics: inlocuieste diacriticele
		*** tlSpaces: sterge spatiile
		*** tlCR: sterge CR si LF

		If Pcount() = 1
			tlDiacritics = .T.
		Endif

		Local lcText
		lcText = Nvl(m.tcText, '')
		If m.tlDiacritics
			lcText = STRTRAN(STRTRAN(Strtran(Nvl(m.lcText, ''), Chr(197) + CHR(162), 'T', 1,100,1), Chr(197) + CHR(63), 'S', 1,100,1), Chr(196) + CHR(63), 'A', 1,100,1)
			lcText = Strtran(Nvl(m.lcText, ''), Chr(195) + CHR(63), 'I', 1,100,1)
			lcText = Strtran(Strtran(Strtran(Strtran(Strtran(Nvl(m.lcText, ''), Chr(170), 'S', 1,100,1), Chr(222), 'T', 1,100,1), Chr(226), 'A', 1,100,1), Chr(227), 'A', 1,100,1), Chr(238), 'I', 1,100,1)
			lcText = STRTRAN(Strtran(Strtran(Strtran(Nvl(m.lcText, ''), Chr(206), 'I', 1,100,1), Chr(194), 'A', 1,100,1), Chr(195), 'A', 1,100,1), Chr(196), 'A', 1,100,1)
		Endif

		If m.tlSpaces
			lcText = Strtran(m.lcText, ' ', '', 1, 100, 1)
		Endif
		If m.tlCR
			lcText = Strtran(Strtran(m.lcText, Chr(13), ''), Chr(10), '')
		Endif

		Return m.lcText
	ENDFUNC
	
	******************************************************
	*** Primeste o adresa de forma * JUD. CONSTANTA, MUN. CONSTANTA, ALEEA CRIZANTEMELOR, NR.6, CAMERA 2, BL.H1, SC.F, ET.2, AP.109
	*** Intoarce un obiect cu proprietatile: STRADA, NR, LOCALITATE
	******************************************************
	Procedure ParseAdresaAnaf
		Lparameters tcAdresa
		* JUD. CONSTANTA, MUN. CONSTANTA, ALEEA CRIZANTEMELOR, NR.6, CAMERA 2, BL.H1, SC.F, ET.2, AP.109
		Local lcAdresa, loAdresa, lcCamera, lcItem, lnItem, lnItems, lcPrefix
		lcAdresa = Iif(!Empty(m.tcAdresa) And Type('tcAdresa') = 'C', Alltrim(m.tcAdresa), "")

		lcCamera = ""
		loAdresa = Createobject("empty")
		AddProperty(loAdresa, "judet", "")
		AddProperty(loAdresa, "strada", "")
		AddProperty(loAdresa, "nr", "")
		AddProperty(loAdresa, "localitate", "")
		AddProperty(loAdresa, "bloc", "")
		AddProperty(loAdresa, "scara", "")
		AddProperty(loAdresa, "etaj", "")
		AddProperty(loAdresa, "apart", "")

		If !Empty(m.lcAdresa)
			lnItems = Getwordcount(m.lcAdresa)
			For lnItem = 1 To m.lnItems
				lcItem = Alltrim(Getwordnum(m.lcAdresa, m.lnItem, ','))
				Do Case
					Case m.lnItem = 1 && 'JUD.'$UPPER(lcItem)
						*!*						lcJudet = ALLTRIM(STRTRAN(m.lcItem, 'JUD.', '',1,1,1))
						loAdresa.judet = Getwordnum(m.lcItem, 2, ' ') && CONSTANTA
					Case m.lnItem = 2 && 'MUN.'$UPPER(lcItem)
						*!*						lcLocalitate = ALLTRIM(STRTRAN(m.lcItem, 'MUN.', '',1,1,1))
						IF LEFT(m.lcItem, 7) = "SECTOR "
							loAdresa.localitate = STRTRAN(m.lcItem, "SECTOR ", "BUCURESTI SECTORUL ")
						ELSE 	
							loAdresa.localitate = Getwordnum(m.lcItem, 2, ' ') && CONSTANTA
						ENDIF 	
					Case m.lnItem = 3
						lcPrefix = Getwordnum(m.lcItem, 1, ' ') && STR. / BD.
						loAdresa.strada = ALLTRIM(STRTRAN(m.lcItem, m.lcPrefix, '',1,1,1)) && Getwordnum(m.lcItem, 2, ' ') && CRIZANTEMELOR
					Case m.lnItem = 4
						loAdresa.nr = Alltrim(Strtran(m.lcItem, 'NR.', '', 1, 1, 1)) && 6
				ENDCASE 	
				IF Left(Upper(m.lcItem), 3) = 'BL.'
					loAdresa.Bloc = Alltrim(Strtran(m.lcItem, 'BL.', '', 1, 1, 1)) && H1
				ENDIF 	
				IF Left(Upper(m.lcItem), 3) = 'SC.'
					loAdresa.scara = Alltrim(Strtran(m.lcItem, 'SC.', '', 1, 1, 1)) && F
				ENDIF 	
				IF Left(Upper(m.lcItem), 3) = 'ET.'
					loAdresa.etaj = Alltrim(Strtran(m.lcItem, 'ET.', '', 1, 1, 1)) && 2
				ENDIF 	
				IF Left(Upper(m.lcItem), 3) = 'AP.'
					loAdresa.apart = Alltrim(Strtran(m.lcItem, 'AP.', '', 1, 1, 1)) && 109
				ENDIF 	
				IF Left(Upper(m.lcItem), 6) = 'CAMERA'
					lcCamera = Alltrim(Strtran(m.lcItem, 'CAMERA', '', 1, 1, 1)) && 2
				ENDIF 	
			ENDFOR
			If !Empty(m.lcCamera) And !Empty(loAdresa.apart)
				loAdresa.apart = loAdresa.apart + ' C. ' + m.lcCamera
			Endif			
		Endif && !empty

		Return loAdresa
	Endproc

	*************************************
	*** Parcurge un cursor in forma crsANAF si salveaza fiecare rand in ISTORIC_CODURI_FISCALE
	*** prin pack_parteneri.save_istoric_cod_fiscal (26 parametri); commit din 100 in 100 si la final
	*** Sare peste randurile provenite din cache (sursa incepe cu 'CACHE') - au fost deja salvate
	*** Intoarce numarul de randuri salvate cu succes
	*************************************
	Function SalveazaIstoricDinCursor
		Lparameters tcAlias, tnIdUtil

		Local lnSalvate, lcSelect, lcSqlIstoric, lnRecnoInit
		Private pcCodFiscal, pcFirma, pcAdresa, pcJudet, pcRegCom, pcCodPostal, pcTelefon, pcFax, pcDataTvamfin, ;
			pnPlatitorTvaMfin, pcStare, pnPlatitorTvaVies, pnInterogareVies, pnIdUtil, ;
			pnInactiv, pnTvaIncasare, pnSplitTva, ;
			pdInceputScpTva, pdSfarsitScpTva, pdAnulImpScpTva, pdInceputTvaInc, pdSfarsitTvaInc, ;
			pdInactivare, pdReactivare, pdInceputSplitTva, pdAnulareSplitTva, pnDinCache

		lnSalvate = 0
		If Empty(m.tcAlias) Or !Used(m.tcAlias)
			Return m.lnSalvate
		Endif

		lcSelect = Select()
		pnIdUtil = m.tnIdUtil

		Select (m.tcAlias)
		lnRecnoInit = Recno()
		Scan For cui <> 0 And Left(Nvl(sursa, ''), 5) <> 'CACHE'
			pcCodFiscal = Transform(cui)
			pcFirma = Nvl(firma, '')
			pcAdresa = Nvl(adresa, '')
			pcJudet = Nvl(judet, '')
			pcRegCom = Nvl(nrRegCom, '')
			pcCodPostal = ''
			pcTelefon = ''
			pcFax = ''
			pcDataTvamfin = ''
			pnPlatitorTvaMfin = 0
			pcStare = ''
			pnPlatitorTvaVies = 0
			pnInterogareVies = 0
			pnInactiv = Iif(Nvl(inactiv, .F.), 1, 0)
			pnTvaIncasare = Iif(Nvl(tvaincasare, .F.), 1, 0)
			pnSplitTva = Iif(Nvl(splittva, .F.), 1, 0)
			pdInceputScpTva = data_inceput_ScpTVA
			pdSfarsitScpTva = data_sfarsit_ScpTVA
			pdAnulImpScpTva = data_anul_imp_ScpTVA
			pdInceputTvaInc = dataInceputTvaInc
			pdSfarsitTvaInc = dataSfarsitTvaInc
			pdInactivare = dataInactivare
			pdReactivare = dataReactivare
			pdInceputSplitTva = dataInceputSplitTVA
			pdAnulareSplitTva = dataAnulareSplitTVA
			*!* 01.08.2026 marius.mutu: pnDinCache=1 cand randul vine din cache - opreste improspatarea DATAORAV_ANAF pe ecoul din cache, jos in pachet
			pnDinCache = Iif(Left(Nvl(sursa, ''), 5) == 'CACHE', 1, 0)

			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,?pnDinCache); end;"
			If goExecutor.oExecuta(m.lcSqlIstoric)
				lnSalvate = m.lnSalvate + 1
				If Mod(m.lnSalvate, 100) = 0
					goExecutor.oExecuta('COMMIT')
				Endif
			Endif
			Select (m.tcAlias)
		Endscan

		If m.lnSalvate > 0
			goExecutor.oExecuta('COMMIT')
		Endif

		*!* 01.08.2026 marius.mutu: Scan lasa pointerul pe EOF - il pun la loc, ca sa nu afectez apelantul
		Select (m.tcAlias)
		Try
			Go m.lnRecnoInit
		Catch
			Go Top
		Endtry

		Select (m.lcSelect)
		Return m.lnSalvate
	Endfunc && SalveazaIstoricDinCursor

	*************************************
	*** Citeste din ISTORIC_CODURI_FISCALE ultima verificare proaspata (pe DATAORAV_ANAF) pentru
	*** codurile din tcListaCoduriN (normalizate, numerice, separate prin virgula) si calculeaza
	*** in SQL, la tdData, verdictele din intervale (platitor TVA, TVA la incasare, split TVA, inactiv)
	*** Adauga randurile in tcAlias (cursor in forma crsANAF + sursa/data_sursa), creandu-l daca lipseste
	*** tcSursa (optional, implicit 'CACHE') eticheteaza randurile inserate - 'CACHE' sau 'CACHE_INDISP'
	*** Un rand NU se intoarce cand tdData e inainte de inceputul unui interval cunoscut (scpTVA/TVAINC/
	*** inactivare) - ANAF intoarce o singura perioada, nu istoricul complet, deci pentru o data anterioara
	*** primei perioade memorate cache-ul nu poate afirma "nu era" - codul ramane netratat, merge la ANAF
	*** Intoarce numele cursorului; ramane gol, fara eroare, cand nu gaseste nimic
	*************************************
	Function CitesteIstoricPentruCoduri
		Lparameters tcListaCoduriN, tdData, tcAlias, tcSursa

		Local lcAlias, lcCursorIstoric, lcSql, ldData, lnZileCache, lcSelect, lcSursa, lcCondCod, lnTotalCod, lnTranse, lnTransa, lnI, lcTransa
		*!* 30.07.2026 marius.mutu: pdDataCache/pnZileCache Private, nu Local, ca sa fie vizibile in goExecutor.oExecuta la bind
		Private pdDataCache, pnZileCache
		lcAlias = Iif(!Empty(m.tcAlias) And Type('tcAlias') = "C", m.tcAlias, "crsANAF")
		ldData = Iif(Type('tdData') = 'D' And !Empty(m.tdData), m.tdData, Date())
		lcSursa = Iif(!Empty(m.tcSursa) And Type('tcSursa') = 'C', Upper(Alltrim(m.tcSursa)), 'CACHE')
		pdDataCache = m.ldData
		lcSelect = Select()

		If !Used(m.lcAlias)
			*!* 31.07.2026 marius.mutu: aceeasi forma ca crsANAF din ParseJsonANAFv8 - Null pe cele 9 campuri de data muta problema in ParseJsonANAFv8 (SCATTER/aritmetica pe date); NULL-ul din Oracle e tratat cu Nvl la Insert Into, mai jos
			Create Cursor (m.lcAlias) (cui N(13), data D, denumire V(100), firma V(100), adresa C(244), nrRegCom C(30), scpTVA L, data_inceput_ScpTVA D, data_sfarsit_ScpTVA D, data_anul_imp_ScpTVA D, mesaj_ScpTVA C(244), ;
				dataInceputTvaInc D, dataSfarsitTvaInc D, dataActualizareTvaInc D, dataPublicareTvaInc D, tipActTvaInc C(100), statusTvaIncasare L, dataInactivare D, dataReactivare D, dataPublicare D, dataRadiere D, statusInactivi L, ;
				dataInceputSplitTVA D, dataAnulareSplitTVA D, statusSplitTVA L, ;
				tva L, tvaincasare L, splittva L, inactiv L, ;
				mesaj V(100), judet V(100), strada V(100), nr V(20), localitate V(100), Bloc V(20), scara V(20), etaj V(20), apart V(20), ;
				sursa C(20), data_sursa D)
		Endif

		If Empty(m.tcListaCoduriN)
			Select (m.lcSelect)
			Return m.lcAlias
		Endif

		lnZileCache = This.ZileCache()
		pnZileCache = m.lnZileCache
		lcCursorIstoric = 'crsIstoricCacheTemp'
		Use In (Select(m.lcCursorIstoric))

		*!* 02.08.2026 marius.mutu: transe de maxim 1000 coduri legate cu OR - peste 1000 elemente "in (...)" da ORA-01795
		lnTotalCod = Getwordcount(m.tcListaCoduriN, ',')
		lnTranse = Ceiling(m.lnTotalCod / 1000)
		lcCondCod = ''
		For lnTransa = 1 To m.lnTranse
			lcTransa = ''
			For lnI = (m.lnTransa - 1) * 1000 + 1 To Min(m.lnTransa * 1000, m.lnTotalCod)
				lcTransa = m.lcTransa + Iif(Empty(m.lcTransa), '', ',') + Getwordnum(m.tcListaCoduriN, m.lnI, ',')
			Endfor
			lcCondCod = m.lcCondCod + Iif(Empty(m.lcCondCod), '', ' or ') + 'cod_fiscal_n in (' + m.lcTransa + ')'
		Endfor
		If m.lnTranse > 1
			lcCondCod = '(' + m.lcCondCod + ')'
		Endif

		*!* 01.08.2026 marius.mutu: v_tvainc - margine exclusiva (data_sfarsit_tvainc - 1), aliniata cu pack_roartvai; ground truth rtvai_istoric confirma [inceput,sfarsit)
		*!* 02.08.2026 marius.mutu: randul curent se alege pe dataorav_anaf desc - dupa fuziunea istoricelor, ID-ul nu mai urmeaza ordinea cronologica
		TEXT To lcSql TEXTMERGE Noshow
select cod_fiscal_n, firma, adresa, judet, regcom, dataorav_anaf,
       data_inceput_scptva, data_sfarsit_scptva, data_anul_imp_scptva,
       data_inceput_tvainc, data_sfarsit_tvainc, data_inactivare, data_reactivare,
       data_inceput_splittva, data_anulare_splittva,
       case when ?pdDataCache between data_inceput_scptva and nvl(data_sfarsit_scptva, to_date('29991231','yyyymmdd')) then 1 else 0 end as v_scptva,
       case when ?pdDataCache between data_inceput_tvainc and nvl(data_sfarsit_tvainc - 1, to_date('29991231','yyyymmdd')) then 1 else 0 end as v_tvainc,
       case when ?pdDataCache between data_inceput_splittva and nvl(data_anulare_splittva, to_date('29991231','yyyymmdd')) then 1 else 0 end as v_splittva,
       case when data_inactivare is not null and ?pdDataCache >= data_inactivare and (data_reactivare is null or ?pdDataCache < data_reactivare) then 1 else 0 end as v_inactiv
  from (select i.*, row_number() over (partition by cod_fiscal_n order by dataorav_anaf desc, id desc) as rn
          from istoric_coduri_fiscale i
         where <<m.lcCondCod>>
           and dataorav_anaf is not null
           and sysdate - dataorav_anaf <= ?pnZileCache)
 where rn = 1
   and (data_inceput_scptva is null or ?pdDataCache >= data_inceput_scptva)
   and (data_inceput_tvainc is null or ?pdDataCache >= data_inceput_tvainc)
   and (data_inactivare is null or ?pdDataCache >= data_inactivare)
		ENDTEXT

		If goExecutor.oExecuta(m.lcSql, m.lcCursorIstoric) And Used(m.lcCursorIstoric)
			Select (m.lcCursorIstoric)
			Scan
				*!* 31.07.2026 marius.mutu: campurile din VALUES calificate cu alias literal crsIstoricCacheTemp - necalificat da eroare 12 (inghitita de ON ERROR), Insert Into ramanea mereu gol
				Insert Into (m.lcAlias) (cui, data, denumire, firma, adresa, judet, nrRegCom, ;
						data_inceput_ScpTVA, data_sfarsit_ScpTVA, data_anul_imp_ScpTVA, ;
						dataInceputTvaInc, dataSfarsitTvaInc, dataInactivare, dataReactivare, ;
						dataInceputSplitTVA, dataAnulareSplitTVA, ;
						scpTVA, statusTvaIncasare, statusSplitTVA, statusInactivi, ;
						tva, tvaincasare, splittva, inactiv, sursa, data_sursa) Values ;
					(crsIstoricCacheTemp.cod_fiscal_n, m.ldData, Nvl(crsIstoricCacheTemp.firma, ''), Nvl(crsIstoricCacheTemp.firma, ''), Nvl(crsIstoricCacheTemp.adresa, ''), Nvl(crsIstoricCacheTemp.judet, ''), Nvl(crsIstoricCacheTemp.regcom, ''), ;
						Nvl(crsIstoricCacheTemp.data_inceput_scptva, {}), Nvl(crsIstoricCacheTemp.data_sfarsit_scptva, {}), Nvl(crsIstoricCacheTemp.data_anul_imp_scptva, {}), ;
						Nvl(crsIstoricCacheTemp.data_inceput_tvainc, {}), Nvl(crsIstoricCacheTemp.data_sfarsit_tvainc, {}), Nvl(crsIstoricCacheTemp.data_inactivare, {}), Nvl(crsIstoricCacheTemp.data_reactivare, {}), ;
						Nvl(crsIstoricCacheTemp.data_inceput_splittva, {}), Nvl(crsIstoricCacheTemp.data_anulare_splittva, {}), ;
						(crsIstoricCacheTemp.v_scptva = 1), (crsIstoricCacheTemp.v_tvainc = 1), (crsIstoricCacheTemp.v_splittva = 1), (crsIstoricCacheTemp.v_inactiv = 1), ;
						(crsIstoricCacheTemp.v_scptva = 1), (crsIstoricCacheTemp.v_tvainc = 1), (crsIstoricCacheTemp.v_splittva = 1), (crsIstoricCacheTemp.v_inactiv = 1), m.lcSursa, crsIstoricCacheTemp.dataorav_anaf)
			Endscan
			Use In (Select(m.lcCursorIstoric))
		Endif

		Select (m.lcSelect)
		Return m.lcAlias
	Endfunc && CitesteIstoricPentruCoduri

	*************************************
	*** Citeste din OPTIUNI (per schema) ordinea traseelor de verificare ANAF/cache
	*** tcTraseu: 'UNIC' (un singur cod) sau 'MASA' (lot); implicit cand randul lipseste din OPTIUNI:
	*** 'ANAF,CACHE' pe UNIC, 'CACHE,ANAF' pe MASA
	*************************************
	Function OrdineCache
		Lparameters tcTraseu

		Local lcTraseu, lcVarName, lcImplicit, lcSql, lcCursor, lcOrdine, lcSelect
		*!* 31.07.2026 marius.mutu: lcSelect salvat/restaurat - fara asta apelantul ramanea cu work area-ul schimbat
		lcSelect = Select()
		lcTraseu = Upper(Alltrim(Nvl(m.tcTraseu, '')))
		lcImplicit = Iif(m.lcTraseu == 'MASA', 'CACHE,ANAF', 'ANAF,CACHE')
		lcVarName = 'ANAFCACHEORDINE_' + Iif(m.lcTraseu == 'MASA', 'MASA', 'UNIC')
		lcCursor = 'crsOptiuneOrdineCache'
		lcOrdine = ''

		lcSql = "select varvalue from optiuni where varname = '" + m.lcVarName + "'"
		If goExecutor.oExecuta(m.lcSql, m.lcCursor) And Used(m.lcCursor)
			If Reccount(m.lcCursor) > 0
				lcOrdine = Upper(Strtran(Alltrim(Nvl(&lcCursor..varvalue, '')), ' ', ''))
			Endif
			Use In (Select(m.lcCursor))
		Endif

		Select (m.lcSelect)
		Return Iif(Empty(m.lcOrdine), m.lcImplicit, m.lcOrdine)
	Endfunc && OrdineCache

	*************************************
	*** Citeste din OPTIUNI (per schema) vechimea maxima a cache-ului, in zile, masurata pe DATAORAV_ANAF
	*** Implicit cand randul lipseste din OPTIUNI: 30
	*************************************
	Function ZileCache
		Local lcCursor, lcSql, lnZile, lcSelect
		*!* 31.07.2026 marius.mutu: lcSelect salvat/restaurat - acelasi defect ca la OrdineCache
		lcSelect = Select()
		lcCursor = 'crsOptiuneZileCache'
		lnZile = 30

		lcSql = "select varvalue from optiuni where varname = 'ANAFCACHEZILE'"
		If goExecutor.oExecuta(m.lcSql, m.lcCursor) And Used(m.lcCursor)
			If Reccount(m.lcCursor) > 0 And !Empty(Alltrim(Nvl(&lcCursor..varvalue, '')))
				lnZile = Val(Alltrim(&lcCursor..varvalue))
			Endif
			Use In (Select(m.lcCursor))
		Endif

		If m.lnZile <= 0
			lnZile = 30
		Endif

		Select (m.lcSelect)
		Return m.lnZile
	Endfunc && ZileCache


Enddefine && VerificareANAF

*** WEBSITE ALTERNATIV PENTRU VERIFICARE PLATITOR TVA VIES
Procedure VIES_VAT
	Lparameters tara, vat_id

	Local lResult
	lResult = .F.

	#Define HTTPSTATUS_OK 200
	#Define HTTPSTATUS_CREATED 201
	#Define HTTPSTATUS_ACCEPTED 202
	#Define HTTPSTATUS_MULTISTATUS 207
	#Define HTTPSTATUS_BADREQUEST 400
	#Define HTTPSTATUS_UNAUTHORIZED 401
	#Define HTTPSTATUS_FORBIDDEN 403
	#Define HTTPSTATUS_NOTFOUND 404
	#Define HTTPSTATUS_INTERNALSERVERERROR 500
	Local oHTTP As "Microsoft.XMLHTTP", cURL
	oHTTP = Createobject("Microsoft.XMLHTTP")
	cURL = 'http://isvat.appspot.com/' + Upper(Trim(tara)) + '/' + Upper(Trim(vat_id)) + '/'
	Try
		oHTTP.Open("GET", cURL, .F.)
		oHTTP.Send()
		If oHTTP.Status = HTTPSTATUS_OK
			lResult = Iif(oHTTP.responseText = 'true', .T., .F.)
		Endif
	Catch
		lResult = .F.
		* error handling code here.
	Endtry

	Return lResult
Endproc && VIES_VAT

Procedure ONRC
	cCui = '1879855'

	oHTTP = Createobject('winhttp.winhttprequest.5.1')
	oHTTP.Open('POST', 'http://recom1-ssl.onrc.ro/cgi-bin/intguest.cgi', .F.)
	oHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
	oHTTP.setRequestHeader("Referrer", "http://recom1-ssl.onrc.ro/cgi-bin/recom.cgi?o7=1&l=R")
	oHTTP.setRequestHeader("Authorization", "Basic Z3Vlc3Q6Z3Vlc3Q")
	oHTTP.setRequestHeader("credentials", "guest:guest")
	oHTTP.Send("l=R&o=7&jud=99&cfiscalf=" + cCui + "&cauta=Selectie")

	cTable = Strextract(oHTTP.responseText, '<table', 'table>', 5, 4)
	Messagebox(cTable)
Endproc && ONRC


*** FORMULAR INTRODUCERE COD KAPTCH MFINANTE
Define Class IntroducereCod As Form
	Height = 140
	Width = 393
	DoCreate = .T.
	AutoCenter = .T.
	Caption = "Cod Siguranta Ministerul de Finante"
	WindowType = 1
	cCod = ""
	_MemberData = [<VFPData><memberdata name="ccod" display="cCod"/><memberdata name="ccodfile" display="cCodFile"/></VFPData>]
	ccodfile = ""
	Name = "Form1"
	ControlBox = .F.


	Add Object label1 As Label With ;
		BackStyle = 0, ;
		Caption = "Introduceti codul din imaginea de mai sus" + CRLF + "si apasati ENTER", ;
		Height = 40, ;
		Left = 39, ;
		Top = 84, ;
		Width = 234, ;
		Name = "Label1"


	Add Object text1 As TextBox With ;
		FontBold = .T., ;
		FontSize = 12, ;
		Height = 30, ;
		Left = 283, ;
		Top = 76, ;
		Width = 54, ;
		Name = "Text1"


	Add Object imagine As Image With ;
		Height = 53, ;
		Left = 83, ;
		Top = 12, ;
		Width = 200, ;
		Name = "Imagine"


	Procedure Init
		Lparameters tcCodFile
		This.ccodfile = m.tcCodFile
		Thisform.imagine.Picture = m.tcCodFile
		This.Icon = _Screen.Icon
	Endproc


	Procedure Unload
		Return This.cCod
	Endproc


	Procedure text1.Valid
		Thisform.cCod = Alltrim(This.Value)
		Thisform.Hide()
	Endproc


Enddefine && IntroducereCod
  