* test_dvi_valuta_ron.prg
* Runda30 (F1, plan fizzy-imagining-parnas.md): factura import EUR (curs 5.23) cu TVA DVI
* platita in RON (fara valuta proprie a DVI - selectie explicita, diferita de valuta facturii).
* Verifica:
*   - randul T (TVA DVI) primeste rand_dvi=1, valuta_proprie=1 (RON <> EUR factura),
*     in_valuta=0, participa_valuta=.F.;
*   - suma T NU se schimba dupa do_executa()/sincronizeaza()/recalc_tva_document() explicit;
*   - suma T e imuna la schimbarea cursului facturii (copiaza_valoare sare randul protejat);
*   - footer TVA in valuta (recalculeaza/ntva_val) EXCLUDE randul T RON chiar daca suma_val
*     ar contine reziduu (assert direct pe filtrul participa_valuta din Sum);
*   - uneste_document (test izolat, cursor construit direct) nu comaseaza un rand T protejat;
*   - debifare in_valuta la nivel de document: randurile B/S se golesc de valuta, randul T
*     protejat ramane neschimbat (deja RON) si isi pastreaza valuta_proprie=1.
*
* ASUMPTII (de confruntat cu implementarea reala, vezi raportul catre orchestrator):
*   - proprietatile noi de dialog se numesc nDviIdValuta, cDviValuta, nDviCurs (RON = 0/''/0);
*   - toDlg.dvi_valuta_proprie e calculat de do_adauga_factura ca 1 cand valuta/curs DVI difera
*     de valuta/curs facturii (aici construit direct in ConstruiesteToDlgF1F2, ca proxy);
*   - recalc_tva_document primeste garda suplimentara Nvl(valuta_proprie,0)=0 langa mod_manual.
*
* Rulare:
*   powershell -ExecutionPolicy Bypass -File test_dvi_valuta_ron.ps1

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

PUBLIC gcUILog, gcSyncDir
gcUILog  = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\test_dvi_valuta_ron_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync_dvi_valuta_ron\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)

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

TRY
	LOCAL gcAppPath, lcPath
	gcAppPath = "D:\ROA\ROAGEST\"
	SET DEFAULT TO (gcAppPath)

	lcPath = gcAppPath + 'Date;' + gcAppPath + 'Include;' + gcAppPath + 'FERESTRE;' + ;
		gcAppPath + 'GRAFICE;' + gcAppPath + 'CLASE;' + gcAppPath + 'MENIURI;' + ;
		gcAppPath + 'PROGRAME;' + gcAppPath + 'RAPOARTE;' + gcAppPath + 'COMUN;' + ;
		gcAppPath + 'COMUN\CLASE;' + gcAppPath + 'COMUN\FERESTRE;' + gcAppPath + 'COMUN\PROGRAME;' + ;
		gcAppPath + 'COMUN\GRAFICE;' + gcAppPath + 'COMUN\RAPOARTE;' + gcAppPath + 'COMUN\MENIURI;' + ;
		gcAppPath + 'COMUN\UTILE\GRIDEXTRAS;' + gcAppPath + 'COMUN\UTILE\CTL32;' + ;
		gcAppPath + 'COMUN\UTILE\HPDF;' + gcAppPath + 'COMUN\UTILE\HPDF\REPORTOUTPUT;' + ;
		gcAppPath + 'COMUN\UTILE\WEB;' + gcAppPath + 'COMUN\UTILE\EXCEL;' + ;
		ADDBS(SUBSTR(gcAppPath,1,RAT([\],gcAppPath,2)))+[COMUNROA\]
	SET PATH TO &lcPath ADDITIVE
	DO DcLog WITH 'SET PATH OK'

	*----- CLASE -----
	SET CLASSLIB TO (gcAppPath + "comun\clase\appwiz") ADDITIVE
	SET CLASSLIB TO GESTIUNI ADDITIVE
	SET CLASSLIB TO CAUT ADDITIVE
	SET CLASSLIB TO BAZA ADDITIVE
	SET CLASSLIB TO comun ADDITIVE
	SET CLASSLIB TO accessibility.vcx ADDITIVE
	SET CLASSLIB TO messagebox ADDITIVE
	SET CLASSLIB TO registry ADDITIVE
	SET CLASSLIB TO cauta_alfa_forms.vcx ADDITIVE
	SET CLASSLIB TO DECABAZA ADDITIVE
	SET CLASSLIB TO onomenclatoare ADDITIVE
	SET CLASSLIB TO stocuri.vcx ADDITIVE
	SET CLASSLIB TO rulaje.vcx ADDITIVE
	SET CLASSLIB TO ointroduceri ADDITIVE
	SET CLASSLIB TO ointroduceri_web ADDITIVE
	SET CLASSLIB TO ointroduceri_depozit ADDITIVE
	SET CLASSLIB TO overificari ADDITIVE
	SET CLASSLIB TO ferestre_oracle ADDITIVE
	SET CLASSLIB TO ferestre_cere_date.vcx ADDITIVE
	SET CLASSLIB TO configurare.vcx ADDITIVE
	SET CLASSLIB TO serii_numere.vcx ADDITIVE
	SET CLASSLIB TO omodificari.vcx ADDITIVE
	SET CLASSLIB TO ocompensari.vcx ADDITIVE
	SET CLASSLIB TO caut_ora ADDITIVE
	SET CLASSLIB TO onote_contabile ADDITIVE
	SET CLASSLIB TO otoolbar ADDITIVE
	SET CLASSLIB TO bon_fisc ADDITIVE
	SET CLASSLIB TO onom_articole ADDITIVE
	SET CLASSLIB TO onom_retete ADDITIVE
	SET CLASSLIB TO orapoarte ADDITIVE
	SET CLASSLIB TO orapoarte_gestiuni ADDITIVE
	SET CLASSLIB TO orapoarte_parametri ADDITIVE
	SET CLASSLIB TO ONOM_CURS ADDITIVE
	SET CLASSLIB TO ctl32_statusbar_fals.vcx ADDITIVE
	SET CLASSLIB TO ctl32_common.vcx ADDITIVE
	SET CLASSLIB TO ctl32_structs.vcx ADDITIVE
	SET CLASSLIB TO ctl32_progressbar.vcx ADDITIVE
	SET CLASSLIB TO ctl32_balloontip.vcx ADDITIVE
	SET CLASSLIB TO ocriterii.vcx ADDITIVE
	SET CLASSLIB TO oavize.vcx ADDITIVE
	SET CLASSLIB TO onomenclatoare2 ADDITIVE
	SET CLASSLIB TO wwdialogs.vcx ADDITIVE
	SET CLASSLIB TO oimportxml.vcx ADDITIVE
	SET CLASSLIB TO excelxml.vcx ADDITIVE
	SET CLASSLIB TO orapoarte_obinv.vcx ADDITIVE
	DO DcLog WITH 'SET CLASSLIB OK'

	*----- PROCEDURI (mock-uri PRIMELE, ui_harness la final) -----
	SET PROCEDURE TO PROCEDURI
	SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.prg" ADDITIVE
	SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_cauta_nom_articole.prg" ADDITIVE
	SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\mock_caut_valuta.prg" ADDITIVE
	SET PROCEDURE TO acces_meniu ADDITIVE
	SET PROCEDURE TO cauta_alfa ADDITIVE
	SET PROCEDURE TO pmenu ADDITIVE
	SET PROCEDURE TO proceduri_comune ADDITIVE
	SET PROCEDURE TO quitapp ADDITIVE
	SET PROCEDURE TO init_program ADDITIVE
	SET PROCEDURE TO oproceduri_listari.prg ADDITIVE
	SET PROCEDURE TO oproceduri_configurare.prg ADDITIVE
	SET PROCEDURE TO oproceduri_articole.prg ADDITIVE
	SET PROCEDURE TO oproceduri_retete.prg ADDITIVE
	SET PROCEDURE TO orapoarte.prg ADDITIVE
	SET PROCEDURE TO mesaje ADDITIVE
	SET PROCEDURE TO oserii_numere.prg ADDITIVE
	SET PROCEDURE TO oexport.prg ADDITIVE
	SET PROCEDURE TO wwConfig.prg ADDITIVE
	SET PROCEDURE TO proceduri_rapoarte.prg ADDITIVE
	SET PROCEDURE TO OPROCEDURI_CURS.PRG ADDITIVE
	SET PROCEDURE TO validare.prg ADDITIVE
	SET PROCEDURE TO GENCURSOR.PRG ADDITIVE
	SET PROCEDURE TO OPROCEDURI_COMUNE.PRG ADDITIVE
	SET PROCEDURE TO OINIT_OPTIUNI.PRG ADDITIVE
	SET PROCEDURE TO updateserver.prg ADDITIVE
	SET PROCEDURE TO oinainte_de.prg ADDITIVE
	SET PROCEDURE TO ooperatii_comune.prg ADDITIVE
	SET PROCEDURE TO Ocompensari.PRG ADDITIVE
	SET PROCEDURE TO OPROCEDURI_aMS.PRG ADDITIVE
	SET PROCEDURE TO oproceduri_rulaje ADDITIVE
	SET PROCEDURE TO oproceduri_stocuri ADDITIVE
	SET PROCEDURE TO OINTRODUCERI ADDITIVE
	SET PROCEDURE TO oHeader.prg ADDITIVE
	SET PROCEDURE TO proceduri_excel.PRG ADDITIVE
	SET PROCEDURE TO onomenclatoare.PRG ADDITIVE
	SET PROCEDURE TO osecurity ADDITIVE
	SET PROCEDURE TO ocautare ADDITIVE
	SET PROCEDURE TO orefaceri ADDITIVE
	SET PROCEDURE TO ofacturare_comun.PRG ADDITIVE
	SET PROCEDURE TO ofacturare_stoc.PRG ADDITIVE
	SET PROCEDURE TO oproceduri_casademarcat ADDITIVE
	SET PROCEDURE TO oproceduri_casa_marcat_e500 ADDITIVE
	SET PROCEDURE TO oproceduri_casa_marcat_mp500 ADDITIVE
	SET PROCEDURE TO oproceduri_util.prg ADDITIVE
	SET PROCEDURE TO wwxmlhttp.prg ADDITIVE
	SET PROCEDURE TO ini.prg ADDITIVE
	SET PROCEDURE TO odocumente.prg ADDITIVE
	SET PROCEDURE TO regex.prg ADDITIVE
	SET PROCEDURE TO wwutils.prg ADDITIVE
	SET PROCEDURE TO inchidere_k ADDITIVE
	SET PROCEDURE TO iniacces.prg ADDITIVE
	SET PROCEDURE TO oupdate.prg ADDITIVE
	SET PROCEDURE TO procese.prg ADDITIVE
	SET PROCEDURE TO version.prg ADDITIVE
	SET PROCEDURE TO xmlaccess.prg ADDITIVE
	SET PROCEDURE TO xmlparser.prg ADDITIVE
	SET PROCEDURE TO filebringer.prg ADDITIVE
	SET PROCEDURE TO wwcodeupdate.prg ADDITIVE
	SET PROCEDURE TO wwhttp.prg ADDITIVE
	SET PROCEDURE TO xdate.prg ADDITIVE
	SET PROCEDURE TO ofacturare.prg ADDITIVE
	SET PROCEDURE TO oproceduri_obinv.prg ADDITIVE
	SET PROCEDURE TO oproceduri_facturare.prg ADDITIVE
	SET PROCEDURE TO email.prg ADDITIVE
	SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\ui_harness.prg" ADDITIVE
	DO DcLog WITH 'SET PROCEDURE OK'

	*----- goMockValuta (contract vechi, folosit ca fallback) + goMockValutaCoada (contract nou,
	*      coada FIFO - pregatit aici pentru cand mock_caut_valuta.prg va fi actualizat separat;
	*      acest test NU invoca picker-ul cmdValuta/cmdDviValuta.Click, seteaza id_valuta/curs
	*      direct pe dialog, ca in testele existente). -----
	PUBLIC goMockValuta, goMockValutaCoada
	goMockValuta = CREATEOBJECT('Custom')
	goMockValuta.AddProperty('id_valuta', 978)
	goMockValuta.AddProperty('nume_val', 'EUR')
	goMockValutaCoada = CREATEOBJECT('Collection')
	LOCAL loValFact, loValDvi
	loValFact = CREATEOBJECT('Custom')
	loValFact.AddProperty('id_valuta', 978)
	loValFact.AddProperty('nume_val', 'EUR')
	goMockValutaCoada.Add(loValFact)
	loValDvi = CREATEOBJECT('Custom')
	loValDvi.AddProperty('id_valuta', 1)
	loValDvi.AddProperty('nume_val', 'RON')
	goMockValutaCoada.Add(loValDvi)

	*----- Globale -----
	PUBLIC gnPc, gnPval, gnPcant, gnPpret, gnPPretval, gnPCurs, gnPVal, gnPPretV, gnPPretVal
	STORE 2 TO gnPc, gnPval, gnPVal
	gnPcant = 3
	STORE 4 TO gnPpret, gnPPretval, gnPPretVal, gnPPretV, gnPCurs
	PUBLIC gl406, gcS, gnAn, gnLuna, gnIdFirma, gnIdSucursala, gcAcces, gcFirma
	gl406 = .T.
	gcS = 'CONTAFIN'
	gnAn = YEAR(DATE())
	gnLuna = MONTH(DATE())
	gnIdFirma = 110
	gnIdSucursala = 110
	gcAcces = "1;2;3;4;5;6;7;8;"
	gcFirma = gcS
	PUBLIC nror(65000)

	PUBLIC gnButon
	STORE 2 TO gnButon
	PUBLIC gcMockArtCodmat, gcMockAcontCrt
	gcMockArtCodmat = ''
	gcMockAcontCrt = ''
	PUBLIC gnMockRaspuns
	gnMockRaspuns = 6

	PUBLIC goExecutor, goApp
	goExecutor = CREATEOBJECT('dummyexecutor')
	goApp = CREATEOBJECT('dummyapp')

	*----- poAct: antetul notei (moneda principala EUR, curs 5.23) -----
	PUBLIC poAct
	poAct = CREATEOBJECT('Custom')
	poAct.AddProperty('nume_val', 'EUR')
	poAct.AddProperty('curs', 5.23)
	poAct.AddProperty('proc_tva', 1.21)
	poAct.AddProperty('nnir', 0)
	poAct.AddProperty('id_valuta', 978)
	poAct.AddProperty('id_fdoc', 1)
	poAct.AddProperty('fdoc', 'Factura')
	poAct.AddProperty('id_partc', 601)
	poAct.AddProperty('partc', 'RAJA')
	poAct.AddProperty('serie_act', '')
	poAct.AddProperty('dataact', DATE())
	poAct.AddProperty('tva_incasare', 0)
	poAct.AddProperty('id_set', 1)
	poAct.AddProperty('id_gestin', 1)

	*----- jtva_coloane2 / saft_taxtable: perechi reale 21% -----
	IF USED('jtva_coloane2')
		USE IN ('jtva_coloane2')
	ENDIF
	CREATE CURSOR jtva_coloane2 (ordine N(8), id_jtva_coloana N(14), denumire C(100), ;
		jc N(1), jv N(1), afisat N(1), coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14))
	INSERT INTO jtva_coloane2 VALUES (0, 0, '', 0, 0, 1, '', '', 0, 0)
	INSERT INTO jtva_coloane2 VALUES (1, 208, 'ACH. INT. 21%', 1, 0, 1, 'RO21B', 'RO21T', 21, 209)
	INSERT INTO jtva_coloane2 VALUES (2, 209, 'TVA ACH. INT. 21%', 1, 0, 1, 'RO21T', '', 21, 0)
	INSERT INTO jtva_coloane2 VALUES (3, 220, 'ACH. IMP. 21%', 1, 0, 1, 'FO21B', 'FO21T', 21, 221)
	INSERT INTO jtva_coloane2 VALUES (4, 221, 'TVA ACH. IMP. 21%', 1, 0, 1, 'FO21T', '', 21, 0)

	IF USED('saft_taxtable')
		USE IN ('saft_taxtable')
	ENDIF
	CREATE CURSOR saft_taxtable (taxname C(250) NULL, typename C(250) NULL, taxcode N(6) NULL, ;
		taxtype N(3) NULL, descriere C(250) NULL, tip C(100) NULL, descriere_tip C(250) NULL, ;
		procent_taxa N(7,2) NULL, procent_prorata N(7,2) NULL, inactiv N(1) NULL, tva N(1) NULL, ;
		wht N(1) NULL, tva_achizitii N(1) NULL, tva_livrari N(1) NULL)
	INDEX ON taxcode TAG taxcode
	INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
		VALUES ('', 0, '', 0, 1, 1, 1, 1)
	INSERT INTO saft_taxtable (taxname, taxcode, descriere, procent_taxa, tva, wht, tva_achizitii, tva_livrari) ;
		VALUES ('301204-Import de bunuri cota 21%', 301204, '', 21, 1, 0, 1, 0)

	DO CreeazaIntrodc WITH 'introdc'
	DO CreeazaIntrodc WITH 'introdc_sablon'
	INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
			id_jtva_coloana, ptva, explicatie_tva) ;
		VALUES ('371', '401', 1, 1, 1, .T., 'B', 208, 21, 'ACH. INT. 21%')
	INSERT INTO introdc_sablon (scd, scc, cu_tva, ordine, id_set, participa_valuta, tip_rand, ;
			id_jtva_coloana, ptva, explicatie_tva) ;
		VALUES ('4426', '401', 1, 2, 1, .T., 'T', 209, 21, 'TVA ACH. INT. 21%')
	GO TOP IN introdc_sablon

	DO CreeazaRulTemp
	INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
		VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 21)

	*-- index ord_doc INAINTE de CREATEOBJECT (capcana p, docs/testare-ui-vfp.md)
	SELECT introdc
	INDEX ON Str(Nvl(nr_doc,0),8) + Icase(tip_rand='B','1', tip_rand='S','2', tip_rand='G','3', tip_rand='T','4', tip_rand='D','5', '6') + Padr(Nvl(scd,''),10) TAG ord_doc
	SET ORDER TO ord_doc

	DO DcLog WITH 'cursoare pregatite, CREATEOBJECT(import_nota, .F.)'
	PUBLIC goObj
	goObj = CREATEOBJECT('IMPORT_nota', .F.)
	IF VARTYPE(goObj) <> 'O'
		DO DcLog WITH 'FAIL: instantiere import_nota'
		DO HarnessDone WITH 'done-error'
		QUIT
	ENDIF
	goObj.lDialogAratat = .T.
	goObj.oact = poAct
	goObj.lSpargeSecundare = .F.
	goObj.WindowType = 0
	goObj.Visible = .T.
	goObj.Show()
	goObj.WindowState = 2
	DOEVENTS FORCE

	SELECT rul_temp
	ZAP
	goObj.gridart.Refresh()
	DOEVENTS FORCE

	PRIVATE pnAsserts, pnPass
	STORE 0 TO pnAsserts, pnPass

	*========================= DOC1: FACTURA EUR + TVA DVI in RON =========================
	PUBLIC goDlg, goT, gcDocKey1
	DO AdaugaDoc1
	DO HarnessStep WITH 0, 'dupa AdaugaDoc1: introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'

	SELECT introdc
	LOCATE FOR Nvl(rand_dvi,0) = 1
	=Assert3('1-rand T-DVI gasit (rand_dvi=1)', IIF(FOUND(),1,0), 1)
	IF FOUND()
		gcDocKey1 = ALLTRIM(NVL(doc_key,''))
		DO DcLog WITH 'T-DVI: doc_key=[' + gcDocKey1 + '] suma=' + TRANSFORM(suma) + ' in_valuta=' + TRANSFORM(NVL(in_valuta,0)) + ' participa_valuta=' + TRANSFORM(participa_valuta) + ' valuta_proprie=' + TRANSFORM(NVL(valuta_proprie,0))
		=Assert3('2-T-DVI.in_valuta=0', NVL(in_valuta,0), 0)
		=Assert3('3-T-DVI.participa_valuta=.F.', IIF(participa_valuta,1,0), 0)
		=Assert3('4-T-DVI.valuta_proprie=1', NVL(valuta_proprie,0), 1)
		=Assert3('5-T-DVI.id_valuta=0', NVL(id_valuta,0), 0)
		=Assert3('6-T-DVI.curs=0', NVL(curs,0), 0)
		=AssertStr('7-T-DVI.nume_val=""', ALLTRIM(NVL(nume_val,'?')), '')
		=Assert3('8-T-DVI.suma=1098.30 (baza*cota auto, nemanual)', suma, 1098.30)
		=Assert3('9-T-DVI.mod_manual=0 (valoare auto)', NVL(mod_manual,0), 0)
	ELSE
		DO DcLog WITH '  FAIL: nu exista rand T-DVI - sar restul verificarilor dependente'
	ENDIF

	*========================= GARDA do_executa (nu rescrie T protejat) =========================
	goObj.do_executa()
	DOEVENTS FORCE
	SELECT introdc
	LOCATE FOR Nvl(rand_dvi,0) = 1
	=Assert3('10-dupa do_executa(): T-DVI.suma neschimbata (1098.30)', IIF(FOUND(),suma,-1), 1098.30)

	*========================= GARDA recalc_tva_document (nu rescrie T protejat) =========================
	IF !EMPTY(gcDocKey1)
		TRY
			goObj.recalc_tva_document(gcDocKey1)
		CATCH TO loExcRtd
			DO DcLog WITH 'INFO recalc_tva_document a aruncat eroare (poate nu accepta parametru direct): ' + loExcRtd.Message
		ENDTRY
		DOEVENTS FORCE
		SELECT introdc
		LOCATE FOR Nvl(rand_dvi,0) = 1
		=Assert3('11-dupa recalc_tva_document(): T-DVI.suma neschimbata (1098.30)', IIF(FOUND(),suma,-1), 1098.30)
	ELSE
		pnAsserts = pnAsserts + 1
		DO DcLog WITH '  FAIL 11: gcDocKey1 gol, nu pot apela recalc_tva_document'
	ENDIF

	*========================= SINCRONIZARE completa (pipeline complet) =========================
	LOCAL llEroareSync
	llEroareSync = .F.
	TRY
		goObj.sincronizeaza()
	CATCH TO loExcS1
		llEroareSync = .T.
		DO DcLog WITH 'EROARE la sincronizeaza() ' + TRANSFORM(loExcS1.ErrorNo) + ' [' + loExcS1.Message + '] in ' + loExcS1.Procedure + ':' + TRANSFORM(loExcS1.LineNo)
	ENDTRY
	DOEVENTS FORCE
	=Assert3('12-sincronizeaza() fara eroare', IIF(llEroareSync,0,1), 1)
	SELECT introdc
	LOCATE FOR Nvl(rand_dvi,0) = 1
	=Assert3('13-dupa sincronizeaza(): rand T-DVI inca gasit', IIF(FOUND(),1,0), 1)
	IF FOUND()
		=Assert3('14-dupa sincronizeaza(): T-DVI.suma neschimbata (1098.30)', suma, 1098.30)
		=Assert3('15-dupa sincronizeaza(): T-DVI.valuta_proprie ramane 1', NVL(valuta_proprie,0), 1)
		=Assert3('16-dupa sincronizeaza(): T-DVI.participa_valuta ramane .F.', IIF(participa_valuta,1,0), 0)
	ELSE
		pnAsserts = pnAsserts + 3
		DO DcLog WITH '  FAIL 14-16: T-DVI a disparut dupa sincronizare'
	ENDIF

	DO HarnessStep WITH 1, 'dupa garzi executie/recalc/sincronizare - vezi log'

	*========================= FOOTER TVA VALUTA: participa_valuta exclude T-DVI din ntva_val =========================
	*-- injectez artificial un suma_val nenul pe T-DVI (bypass motor) - daca filtrul pe
	*-- participa_valuta e corect, ntva_val NU se schimba fata de o rulare fara injectie.
	LOCAL lnNtvaValInainte, lnNtvaValDupa
	goObj.recalculeaza()
	lnNtvaValInainte = goObj.ntva_val
	SELECT introdc
	LOCATE FOR Nvl(rand_dvi,0) = 1
	IF FOUND()
		REPLACE suma_val WITH 999.99
		goObj.recalculeaza()
		lnNtvaValDupa = goObj.ntva_val
		DO DcLog WITH 'FOOTER: ntva_val inainte=' + TRANSFORM(lnNtvaValInainte) + ' dupa injectie suma_val=999.99 pe T-DVI: ' + TRANSFORM(lnNtvaValDupa)
		=Assert3('17-footer ntva_val NU include suma_val injectata pe T-DVI (participa_valuta=.F.)', ABS(lnNtvaValDupa - lnNtvaValInainte), 0)
		*-- recalculeaza() e agregare read-only dar scaneaza cu SUM/CALCULATE (scope ALL), care
		*-- muta pointerul de inregistrare la EOF - re-LOCATE inainte de REPLACE, altfel reset-ul
		*-- de mai jos rateaza randul T-DVI (ramane cu suma_val=999.99 injectat mai sus).
		LOCATE FOR Nvl(rand_dvi,0) = 1
		REPLACE suma_val WITH 0
		goObj.recalculeaza()
	ELSE
		pnAsserts = pnAsserts + 1
		DO DcLog WITH '  FAIL 17: T-DVI negasit pentru testul de footer'
	ENDIF

	DO HarnessStep WITH 2, 'footer TVA valuta verificat - vezi log'

	*========================= IMUNITATE LA SCHIMBAREA CURSULUI FACTURII (copiaza_valoare) =========================
	SELECT introdc
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
	=Assert3('18-rand B gasit pentru schimbare curs', IIF(FOUND(),1,0), 1)
	IF FOUND()
		goObj.grid1.cCurs.text1.Value = 6.00
		goObj.grid1.cCurs.text1.Valid()
		DOEVENTS FORCE
	ENDIF
	SELECT introdc
	LOCATE FOR Nvl(rand_dvi,0) = 1
	IF FOUND()
		=Assert3('19-dupa schimbare curs factura: T-DVI.curs ramane 0', NVL(curs,0), 0)
		=Assert3('20-dupa schimbare curs factura: T-DVI.suma_val ramane 0', NVL(suma_val,0), 0)
		=Assert3('21-dupa schimbare curs factura: T-DVI.suma neschimbata (1098.30)', suma, 1098.30)
	ELSE
		pnAsserts = pnAsserts + 3
		DO DcLog WITH '  FAIL 19-21: T-DVI negasit dupa schimbare curs factura'
	ENDIF
	SELECT introdc
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
	IF FOUND()
		=Assert3('22-randul B a primit noul curs (6.00, propagare normala)', curs, 6.00)
	ENDIF

	DO HarnessStep WITH 3, 'imunitate curs verificata - vezi log'

	*========================= DEBIFARE in_valuta LA NIVEL DE DOCUMENT, CU T PROTEJAT =========================
	SELECT introdc
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND tip_rand == 'B'
	=Assert3('23-rand B gasit pentru debifare in_valuta', IIF(FOUND(),1,0), 1)
	IF FOUND()
		goObj.grid1.cInValuta.check1.Value = 0
		goObj.grid1.cInValuta.check1.Valid()
		=Assert3('24-armare lSyncPending dupa debifare (pre-DOEVENTS)', IIF(goObj.lSyncPending,1,0), 1)
		DOEVENTS FORCE
		=Assert3('25-sync consumat dupa debifare', IIF(goObj.lSyncPending,1,0), 0)
	ENDIF
	LOCAL lnCntBSGolite
	lnCntBSGolite = 0
	SELECT introdc
	SCAN FOR ALLTRIM(NVL(doc_key,'')) == gcDocKey1 AND INLIST(tip_rand,'B','S')
		lnCntBSGolite = lnCntBSGolite + 1
		=Assert3('26.'+TRANSFORM(RECNO())+'-B/S.in_valuta=0 dupa debifare', NVL(in_valuta,0), 0)
		=Assert3('27.'+TRANSFORM(RECNO())+'-B/S.curs=0 dupa debifare', NVL(curs,0), 0)
	ENDSCAN
	=Assert3('28-cel putin un rand B/S golit', IIF(lnCntBSGolite>0,1,0), 1)
	SELECT introdc
	LOCATE FOR Nvl(rand_dvi,0) = 1
	IF FOUND()
		=Assert3('29-T-DVI ramane in_valuta=0 dupa debifare document (nu s-a schimbat)', NVL(in_valuta,0), 0)
		=Assert3('30-T-DVI ramane valuta_proprie=1 dupa debifare document (nu se reseteaza)', NVL(valuta_proprie,0), 1)
		=Assert3('31-T-DVI.suma neschimbata (1098.30) dupa debifare document', suma, 1098.30)
	ELSE
		pnAsserts = pnAsserts + 3
		DO DcLog WITH '  FAIL 29-31: T-DVI negasit dupa debifare document'
	ENDIF

	DO HarnessStep WITH 4, 'debifare in_valuta cu T protejat verificata - vezi log'

	*========================= UNESTE_DOCUMENT CU RAND T PROTEJAT (cursor izolat, construit direct) =========================
	DO TestUnesteDocumentCuProtejat

	*========================= IDENTITATE PROPRIE PE RANDUL DVI (cursor izolat, construit direct) =========================
	DO TestIdentitateDviProtejata

	DO DcLog WITH 'REZULTAT: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS'
	IF pnPass = pnAsserts
		DO DcLog WITH 'REZULTAT: PASS (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ')'
	ELSE
		DO DcLog WITH 'REZULTAT: FAIL (' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' assert-uri PASS)'
	ENDIF

	DO HarnessStep WITH 5, 'final: ' + TRANSFORM(pnPass) + '/' + TRANSFORM(pnAsserts) + ' PASS'
	DO HarnessDone WITH 'done'

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

QUIT

*==================================================================================
PROCEDURE AdaugaDoc1
	*-- FACTURA 15000 RAJA, 1000 EUR curs 5.23 (5230 lei), TVA pe DVI ('D'): DVI 101 BIROUL
	*-- VAMAL, tva 1098.30 lei, dar platita in RON (fara valuta proprie DVI) - diferita de
	*-- valuta facturii (EUR) => valuta_proprie=1 pe randul T rezultat.
	goDlg = CREATEOBJECT('import_adauga_factura', goObj)
	goDlg.cFelDoc = 'Factura'
	goDlg.nIdFdoc = 1
	goDlg.nNract = 15000
	goDlg.dDataAct = DATE()
	goDlg.nIdPartener = 601
	goDlg.cPartener = 'RAJA'
	goDlg.cExplicatia = 'Import marfa RAJA'
	goDlg.nSuma = 1000
	goDlg.nSumaLei = 0
	goDlg.nCurs = 5.23
	goDlg.nIdValuta = 978
	goDlg.cValuta = 'EUR'
	goDlg.nIdExplicatieTva = 220
	goDlg.cExplicatieTva = 'ACH. IMP. 21%'
	goDlg.optTipTva.Value = 2 && D = DVI
	goDlg.chkInValutaCont.Value = 1
	goDlg.chkParticipaValuta.Value = 1
	goDlg.cSerieDvi = ''
	goDlg.nNractDvi = 101
	goDlg.dDviData = DATE()
	goDlg.nIdFdocDVI = 2
	goDlg.cFelDocDvi = 'DVI'
	goDlg.nDviIdPartener = 900
	goDlg.cDviPartener = 'BIROUL VAMAL'
	goDlg.nDviTvaLei = 1098.30
	goDlg.nDviTvaVal = 0
	*-- F1 NOU: valuta/curs proprii DVI - RON (fara valuta), explicit diferite de factura (EUR)
	goDlg.nDviIdValuta = 0
	goDlg.cDviValuta = ''
	goDlg.nDviCurs = 0
	goDlg.actualizeaza_stare_dvi()
	goDlg.WindowType = 0
	goDlg.Visible = .T.
	goDlg.Show()
	DOEVENTS FORCE
	DO DcLog WITH 'DOC1: valideaza = ' + TRANSFORM(goDlg.valideaza())
	DO ConstruiesteToDlgF1F2
	DO DcLog WITH 'DOC1: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
	goDlg.Hide()
	DOEVENTS FORCE
ENDPROC

PROCEDURE ConstruiesteToDlgF1F2
	*-- toDlg construit INLINE (capcana l) - camp de baza + extensiile F1 (dvi_*) si F2 (discount,
	*-- neutre in acest test). Deciderul valutar al DVI e dvi_in_valuta (nu dvi_tva_val).
	goT = CREATEOBJECT('Empty')
	=ADDPROPERTY(goT,'serie_act',ALLTRIM(NVL(goDlg.cSerieAct,'')))
	=ADDPROPERTY(goT,'nract',goDlg.nNract)
	=ADDPROPERTY(goT,'dataact',goDlg.dDataAct)
	=ADDPROPERTY(goT,'fdoc',goDlg.cFelDoc)
	=ADDPROPERTY(goT,'id_fdoc',goDlg.nIdFdoc)
	=ADDPROPERTY(goT,'id_partc',goDlg.nIdPartener)
	=ADDPROPERTY(goT,'partc',goDlg.cPartener)
	=ADDPROPERTY(goT,'explicatia',ALLTRIM(NVL(goDlg.cExplicatia,'')))
	=ADDPROPERTY(goT,'suma',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,IIF(goDlg.nSumaLei<>0,goDlg.nSumaLei,ROUND(goDlg.nSuma*goDlg.nCurs,gnPC)),goDlg.nSuma))
	=ADDPROPERTY(goT,'suma_val',IIF(goDlg.chkInValutaCont.Value=1 AND goDlg.nCurs<>0,goDlg.nSuma,0))
	=ADDPROPERTY(goT,'in_valuta',goDlg.chkInValutaCont.Value)
	=ADDPROPERTY(goT,'participa_valuta',(goDlg.chkParticipaValuta.Value=1))
	=ADDPROPERTY(goT,'id_valuta',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nIdValuta,0))
	=ADDPROPERTY(goT,'curs',IIF(goDlg.chkInValutaCont.Value=1,goDlg.nCurs,0))
	=ADDPROPERTY(goT,'nume_val',IIF(goDlg.chkInValutaCont.Value=1,ALLTRIM(NVL(goDlg.cValuta,'')),''))
	=ADDPROPERTY(goT,'cTipTva',IIF(goDlg.optTipTva.Value=1,'F',IIF(goDlg.optTipTva.Value=2,'D','N')))
	=ADDPROPERTY(goT,'id_jtva_coloana',goDlg.nIdExplicatieTva)
	=ADDPROPERTY(goT,'dvi_serie',CHRTRAN(ALLTRIM(NVL(goDlg.cSerieDvi,'')),CHR(34),''))
	=ADDPROPERTY(goT,'dvi_nract',goDlg.nNractDvi)
	=ADDPROPERTY(goT,'dvi_dataact',goDlg.dDviData)
	=ADDPROPERTY(goT,'dvi_id_fdoc',goDlg.nIdFdocDVI)
	=ADDPROPERTY(goT,'dvi_fdoc',goDlg.cFelDocDvi)
	=ADDPROPERTY(goT,'dvi_id_partc',goDlg.nDviIdPartener)
	=ADDPROPERTY(goT,'dvi_partc',goDlg.cDviPartener)
	=ADDPROPERTY(goT,'dvi_scc','401')
	=ADDPROPERTY(goT,'dvi_tva_lei',goDlg.nDviTvaLei)
	=ADDPROPERTY(goT,'dvi_tva_val',goDlg.nDviTvaVal)
	*-- F1 NOU: valuta/curs proprii ale DVI (deciderul e dvi_in_valuta, nu dvi_tva_val)
	=ADDPROPERTY(goT,'dvi_in_valuta',!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON'))
	=ADDPROPERTY(goT,'dvi_id_valuta',goDlg.nDviIdValuta)
	=ADDPROPERTY(goT,'dvi_curs',goDlg.nDviCurs)
	=ADDPROPERTY(goT,'dvi_nume_val',ALLTRIM(NVL(goDlg.cDviValuta,'')))
	=ADDPROPERTY(goT,'dvi_valuta_proprie',IIF(!(EMPTY(goDlg.cDviValuta) OR UPPER(ALLTRIM(NVL(goDlg.cDviValuta,'')))=='RON') OR !(EMPTY(goDlg.cValuta) OR UPPER(ALLTRIM(NVL(goDlg.cValuta,'')))=='RON'),IIF(goDlg.nDviIdValuta<>goDlg.nIdValuta OR goDlg.nDviCurs<>goDlg.nCurs,1,0),0))
	*-- Runda32 (neutru in acest test - fara discount)
	=ADDPROPERTY(goT,'disc_baza_lei',0)
	=ADDPROPERTY(goT,'disc_baza_val',0)
ENDPROC

PROCEDURE TestUnesteDocumentCuProtejat
	*-- test izolat: cursor introdc construit DIRECT (nu prin dialog) cu un document ce are
	*-- 2 randuri T "normale" (mod_manual=0, valuta_proprie=0, de comasat) + 1 rand T protejat
	*-- (rand_dvi=1, valuta_proprie=1, mod_manual=0, NU trebuie comasat). Verifica ca
	*-- uneste_document() lasa randul protejat intact si comaseaza doar restul.
	LOCAL lcDocKeyX, lnCntTDupa
	lcDocKeyX = 'X|900001|0|0'

	SELECT introdc
	APPEND BLANK
	REPLACE tip_rand WITH 'S', scd WITH '371', scc WITH '401', suma WITH 1000, suma_val WITH 0, ;
		nr_doc WITH 900001, nract WITH 900001, fdoc WITH 'Factura', doc_key WITH lcDocKeyX, ;
		mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0

	APPEND BLANK
	REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '401', suma WITH 100, suma_val WITH 0, ;
		ptva WITH 21, nr_doc WITH 900001, nract WITH 900001, fdoc WITH 'Factura', doc_key WITH lcDocKeyX, ;
		mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0

	APPEND BLANK
	REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '4427', suma WITH 110, suma_val WITH 0, ;
		ptva WITH 21, nr_doc WITH 900001, nract WITH 900001, fdoc WITH 'Factura', doc_key WITH lcDocKeyX, ;
		mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0

	APPEND BLANK
	REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '401', suma WITH 1098.30, suma_val WITH 0, ;
		ptva WITH 21, nr_doc WITH 900001, nract WITH 101, fdoc WITH 'DVI', partc WITH 'BIROUL VAMAL', ;
		doc_key WITH lcDocKeyX, mod_manual WITH 0, rand_dvi WITH 1, valuta_proprie WITH 1

	TRY
		goObj.uneste_document(PADR(lcDocKeyX, 80))
	CATCH TO loExcU
		DO DcLog WITH 'EROARE uneste_document ' + TRANSFORM(loExcU.ErrorNo) + ' [' + loExcU.Message + '] in ' + loExcU.Procedure + ':' + TRANSFORM(loExcU.LineNo)
	ENDTRY

	lnCntTDupa = 0
	SELECT introdc
	SCAN FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'T'
		lnCntTDupa = lnCntTDupa + 1
		DO DcLog WITH 'UNESTE: rand T ramas rand_dvi=' + TRANSFORM(NVL(rand_dvi,0)) + ' valuta_proprie=' + TRANSFORM(NVL(valuta_proprie,0)) + ' suma=' + TRANSFORM(suma)
	ENDSCAN
	=Assert3('32-uneste_document: raman EXACT 2 randuri T (1 comasat + 1 protejat)', lnCntTDupa, 2)

	SELECT introdc
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'T' AND Nvl(rand_dvi,0) = 1
	=Assert3('33-uneste_document: randul protejat (rand_dvi=1) supravietuieste', IIF(FOUND(),1,0), 1)
	IF FOUND()
		=Assert3('34-uneste_document: randul protejat.suma neschimbata (1098.30)', suma, 1098.30)
		=Assert3('35-uneste_document: randul protejat.valuta_proprie ramane 1', NVL(valuta_proprie,0), 1)
	ELSE
		pnAsserts = pnAsserts + 2
		DO DcLog WITH '  FAIL 34-35: randul protejat negasit dupa uneste_document'
	ENDIF

	SELECT introdc
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'T' AND Nvl(rand_dvi,0) = 0
	=Assert3('36-uneste_document: randul comasat (nemanual, nevaluta_proprie) exista', IIF(FOUND(),1,0), 1)
	IF FOUND()
		=Assert3('37-uneste_document: randul comasat.suma = 100+110 = 210', suma, 210)
	ELSE
		pnAsserts = pnAsserts + 1
		DO DcLog WITH '  FAIL 37: randul comasat negasit dupa uneste_document'
	ENDIF
ENDPROC

PROCEDURE TestIdentitateDviProtejata
	*-- test izolat: randul DVI (rand_dvi=1) trebuie sa isi pastreze identitatea PROPRIE
	*-- (nract, serie_act, partc, fdoc, id_fdoc) cand copiaza_valoare() propaga aceste campuri
	*-- pe grupul doc_key; un rand NORMAL din acelasi grup trebuie sa PRIMEASCA valoarea noua
	*-- (assert dublu per camp - altfel testul ar trece si daca propagarea s-ar strica de tot).
	*-- Verifica si coerenta doc_key pe grup dupa fiecare propagare (toate 5 campuri sunt chei -
	*-- llCheie regenereaza doc_key pe tot grupul, inclusiv pe randul protejat).
	LOCAL lcDocKeyX, lnRecnoB, lcDocKeyCrt
	lcDocKeyX = 'IDPROT|5001|1|601'

	SELECT introdc
	APPEND BLANK
	REPLACE tip_rand WITH 'B', scd WITH '371', scc WITH '401', suma WITH 1000, ;
		nr_doc WITH 950001, nract WITH 5001, serie_act WITH 'FACT', id_fdoc WITH 1, fdoc WITH 'Factura', ;
		id_partc WITH 601, partc WITH 'FURNIZOR ORIGINAL', doc_key WITH lcDocKeyX, ;
		mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0

	APPEND BLANK
	REPLACE tip_rand WITH 'S', scd WITH '4426', scc WITH '401', suma WITH 190, ;
		nr_doc WITH 950001, nract WITH 5001, serie_act WITH 'FACT', id_fdoc WITH 1, fdoc WITH 'Factura', ;
		id_partc WITH 601, partc WITH 'FURNIZOR ORIGINAL', doc_key WITH lcDocKeyX, ;
		mod_manual WITH 0, rand_dvi WITH 0, valuta_proprie WITH 0

	APPEND BLANK
	REPLACE tip_rand WITH 'T', scd WITH '4426', scc WITH '401', suma WITH 95, ;
		nr_doc WITH 950001, nract WITH 9001, serie_act WITH 'VAMA', id_fdoc WITH 2, fdoc WITH 'DVI', ;
		id_partc WITH 900, partc WITH 'DIRECTIA VAMALA', doc_key WITH lcDocKeyX, ;
		mod_manual WITH 0, rand_dvi WITH 1, valuta_proprie WITH 1

	SELECT introdc
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyX AND tip_rand == 'B'
	=Assert3('38-IDP: randul B gasit pentru test identitate DVI', IIF(FOUND(),1,0), 1)
	IF !FOUND()
		pnAsserts = pnAsserts + 20
		DO DcLog WITH '  FAIL 39-59: randul B negasit, sar restul testului de identitate DVI'
		RETURN
	ENDIF
	lnRecnoB = RECNO()

	*-- NOTA: introdc e cursor PARTAJAT intre scenariile fisierului - alte scenarii (AdaugaDoc1,
	*-- TestUnesteDocumentCuProtejat) au deja propriile randuri rand_dvi=1/tip_rand='S' cu alt
	*-- doc_key. Fiecare LOCATE de mai jos e SCOPAT pe lcDocKeyCrt (doc_key-ul CURENT al
	*-- grupului, recalculat dupa fiecare propagare) - dublu rol: (a) evita sa gaseasca randul
	*-- altui scenariu, (b) FOUND() dupa scopare e chiar dovada de coerenta - daca doc_key nu
	*-- s-ar fi propagat uniform pe grup, randul n-ar mai fi gasit sub noul doc_key.

	*-- 1. nract: 5001 -> 5002
	GO lnRecnoB
	REPLACE nract WITH 5002
	goObj.copiaza_valoare('nract')
	SELECT introdc
	GO lnRecnoB
	lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
	=Assert3('39-IDP nract: B.nract=5002 (propriu, control)', nract, 5002)
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
	=Assert3('40-IDP nract: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=Assert3('41-IDP nract: DVI.nract ramane 9001 (protejat)', NVL(nract,0), 9001)
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
	=Assert3('42-IDP nract: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=Assert3('43-IDP nract: S.nract=5002 (propagat pe randul normal)', NVL(nract,0), 5002)

	*-- 2. serie_act: 'FACT' -> 'FACT2'
	GO lnRecnoB
	REPLACE serie_act WITH 'FACT2'
	goObj.copiaza_valoare('serie_act')
	GO lnRecnoB
	lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
	=Assert3('44-IDP serie_act: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=AssertStr('45-IDP serie_act: DVI.serie_act ramane VAMA (protejat)', ALLTRIM(NVL(serie_act,'')), 'VAMA')
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
	=Assert3('46-IDP serie_act: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=AssertStr('47-IDP serie_act: S.serie_act=FACT2 (propagat)', ALLTRIM(NVL(serie_act,'')), 'FACT2')

	*-- 3. partc: 'FURNIZOR ORIGINAL' -> 'FURNIZOR NOU'
	GO lnRecnoB
	REPLACE partc WITH 'FURNIZOR NOU'
	goObj.copiaza_valoare('partc')
	GO lnRecnoB
	lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
	=Assert3('48-IDP partc: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=AssertStr('49-IDP partc: DVI.partc ramane DIRECTIA VAMALA (protejat)', ALLTRIM(NVL(partc,'')), 'DIRECTIA VAMALA')
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
	=Assert3('50-IDP partc: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=AssertStr('51-IDP partc: S.partc=FURNIZOR NOU (propagat)', ALLTRIM(NVL(partc,'')), 'FURNIZOR NOU')

	*-- 4. fdoc: 'Factura' -> 'Factura Noua'
	GO lnRecnoB
	REPLACE fdoc WITH 'Factura Noua'
	goObj.copiaza_valoare('fdoc')
	GO lnRecnoB
	lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
	=Assert3('52-IDP fdoc: DVI gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=AssertStr('53-IDP fdoc: DVI.fdoc ramane DVI (protejat)', ALLTRIM(NVL(fdoc,'')), 'DVI')
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
	=Assert3('54-IDP fdoc: S gasit sub doc_key curent (coerenta grup)', IIF(FOUND(),1,0), 1)
	=AssertStr('55-IDP fdoc: S.fdoc=Factura Noua (propagat)', ALLTRIM(NVL(fdoc,'')), 'Factura Noua')

	*-- 5. id_fdoc: 1 -> 3
	GO lnRecnoB
	REPLACE id_fdoc WITH 3
	goObj.copiaza_valoare('id_fdoc')
	GO lnRecnoB
	lcDocKeyCrt = ALLTRIM(NVL(doc_key,''))
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND Nvl(rand_dvi,0) = 1
	=Assert3('56-IDP id_fdoc: DVI gasit sub doc_key curent (coerenta grup finala)', IIF(FOUND(),1,0), 1)
	=Assert3('57-IDP id_fdoc: DVI.id_fdoc ramane 2 (protejat)', NVL(id_fdoc,0), 2)
	LOCATE FOR ALLTRIM(NVL(doc_key,'')) == lcDocKeyCrt AND tip_rand == 'S'
	=Assert3('58-IDP id_fdoc: S gasit sub doc_key curent (coerenta grup finala)', IIF(FOUND(),1,0), 1)
	=Assert3('59-IDP id_fdoc: S.id_fdoc=3 (propagat)', NVL(id_fdoc,0), 3)
ENDPROC

PROCEDURE CreeazaRulTemp
	IF USED('rul_temp')
		USE IN ('rul_temp')
	ENDIF
	CREATE CURSOR rul_temp ( ;
		id_rul N(20,0), an N(4,0), luna N(2,0), cod N(20,0);
		, serie C(100), nnir N(20,0), id_articol N(10,0), denumire C(100);
		, codmat C(50), codmatf C(50), codbare C(50), um C(20);
		, id_gestiune N(5,0), nume_gestiune C(50), cgest C(20), nr_pag N(2,0);
		, gestionar C(50), comisie_receptie1 C(50), comisie_receptie2 C(50), comisie_receptie3 C(50);
		, cant N(14,3), cante N(14,3), cont C(10), acont C(20);
		, pret N(18,4), tva N(18,4), valoare N(18,4), valtva N(18,4);
		, proc_tva N(5,2), pretv N(18,4), pretvtva N(18,4), tvav N(18,4);
		, valoarev N(18,4), valtvav N(18,4), proc_tvav N(5,2), adaos N(18,4);
		, adaos_tva N(18,4), valoare_adaos N(18,4), valtva_adaos N(18,4), procent N(10,3);
		, discunitar N(18,4), discount_tva N(18,4), valoare_discount N(18,4), valtva_discount N(18,4);
		, proc_disc N(7,3), pretd N(14,4), curs N(18,4), id_valuta N(10,0);
		, nume_val C(20), id_lucrare N(20,0), nrord C(100), id_responsabil N(10,0);
		, nresp C(100), resp_marca N(18,4), dataact T, id_util N(5,0);
		, util C(30), dataora T, id_sectie N(5,0), sectie C(50);
		, csectie C(10), alcooltutun N(1,0), datain T, dataout T;
		, id_fact N(20,0), id_gestiunec N(10,0), nume_gestiunec C(50), cgestc C(20);
		, id_responsabilc N(5,0), id_reteta N(10,0), reteta C(50), nrespc C(100);
		, respc_marca N(18,4), id_set N(20,0), id_tip_rulaj N(10,0), tip_rulaj C(50);
		, id_obiect_depozit N(10,0), id_rul_aux N(10,0), nract N(20,0), serie_act C(10);
		, dataoras T, id_utils N(10,0), lot C(30), adata_expirare T;
		, id_sucursala N(5,0), sucursala C(250), id_part_rez N(10,0), part_rez C(100);
		, id_lucrare_rez N(10,0), nrord_rez C(100), subgrupa C(100), grupa C(100);
		, id_subgrupa N(5,0), id_grupa N(5,0), in_stoc N(1,0), in_crm N(1,0);
		, id_furnizor N(10,0), furnizor C(100), id_jtva_coloana N(4,0), explicatie_tva C(100);
		, taxcode N(6,0), taxname C(254), saft_procent N(18,4), codnc8 C(20);
		, id_tara_origine N(4,0), cod_tara_origine C(5), tara_origine C(50), greutate N(12,4);
		, fdoc C(30), id_fdoc N(18,4);
		, pret_lei N(18,4), pret_val N(14,4), cota_tva N(6,2))
ENDPROC

PROCEDURE CreeazaIntrodc
	*-- Runda30 (F1/pas2): coloane NOI rand_dvi N(1), valuta_proprie N(1) fata de structura veche.
	LPARAMETERS tcAlias
	IF USED(tcAlias)
		USE IN (tcAlias)
	ENDIF
	CREATE CURSOR (tcAlias) ( ;
		id_note N(14), explicatia C(100), scd C(10), ascd C(20), scc C(10), ascc C(20), ;
		cu_tva N(1), id_set N(14), ordine N(8), in_valuta N(1), id_jtva_coloana N(14) NULL, ;
		ptva N(6,2), explicatie_tva C(50), tipjurnal C(2), taxcode N(6), paymentcode C(9), ;
		suma N(18,4), suma_val N(18,4), id_partd N(14), id_partc N(14), partd C(100), partc C(100), ;
		id_fact N(14), id_factd N(14), id_factc N(14), pereched N(14), perechec N(14), ;
		nract N(14), serie_act C(10), explicatia4 C(50), explicatia5 C(50), participa_valuta L, ;
		id_valuta N(14), curs N(14,4), nume_val C(10), dataact D, fdoc C(50), id_fdoc N(14), ;
		se_scrie N(1), tva_incasare N(1), doc_color N(10), doc_label C(10), tip_rand C(1), ;
		doc_key C(80), nr_doc N(8), suma_doc N(18,4), suma_doc_val N(18,4), mod_manual N(1), expl_manual N(1), ;
		scd_orig C(20), ascd_orig C(20), rand_dvi N(1), valuta_proprie N(1))
ENDPROC

FUNCTION RECCOUNT_ACTIVE
	LPARAMETERS tcAlias
	LOCAL lnSel, lnCnt
	lnSel = SELECT()
	SELECT (tcAlias)
	COUNT TO lnCnt FOR !DELETED()
	SELECT (lnSel)
	RETURN lnCnt
ENDFUNC

PROCEDURE Assert3
	LPARAMETERS tcLabel, tuActual, tuExpected
	pnAsserts = pnAsserts + 1
	IF ABS(NVL(tuActual,0) - tuExpected) < 0.02
		pnPass = pnPass + 1
		DO DcLog WITH '  PASS ' + tcLabel + ' (=' + TRANSFORM(tuActual) + ')'
	ELSE
		DO DcLog WITH '  FAIL ' + tcLabel + ' (actual=' + TRANSFORM(tuActual) + ' asteptat=' + TRANSFORM(tuExpected) + ')'
	ENDIF
ENDPROC

PROCEDURE AssertStr
	LPARAMETERS tcLabel, tcActual, tcExpected
	pnAsserts = pnAsserts + 1
	IF tcActual == tcExpected
		pnPass = pnPass + 1
		DO DcLog WITH '  PASS ' + tcLabel + ' (=[' + tcActual + '])'
	ELSE
		DO DcLog WITH '  FAIL ' + tcLabel + ' (actual=[' + tcActual + '] asteptat=[' + tcExpected + '])'
	ENDIF
ENDPROC

PROCEDURE DcErr
	LPARAMETERS tnErr, tcMsg, tcProg, tnLine
	DO DcLog WITH 'ON ERROR ' + TRANSFORM(tnErr) + ' [' + tcProg + ':' + TRANSFORM(tnLine) + '] ' + tcMsg
ENDPROC

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

DEFINE CLASS dummyapp AS Custom
	PROCEDURE ReadIni
		LPARAMETERS tcSection, tcKey
		RETURN ''
	ENDPROC
	PROCEDURE WriteIni
		LPARAMETERS tcSection, tcKey, tcValue
		RETURN .T.
	ENDPROC
ENDDEFINE

DEFINE CLASS dummyexecutor AS Custom
	cEroare = ''
	PROCEDURE oExecute
		LPARAMETERS tcSql, tcCursor
		IF USED(m.tcCursor)
			USE IN (m.tcCursor)
		ENDIF
		IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
			DO CreeazaJtvaColoaneView WITH m.tcCursor
			RETURN 1
		ENDIF
		IF UPPER(ALLTRIM(m.tcCursor)) == 'RUL_TEMP'
			CREATE CURSOR (m.tcCursor) (denumire C(100), codmat C(30), cant N(14,3), ;
				pret_val N(18,4), pretd N(18,4), pret N(18,4), pret_lei N(18,4), cont C(10), ;
				acont C(20), serie C(30), lot C(30), adata_expirare C(10), proc_disc N(6,2), cota_tva N(6,2))
			RETURN 1
		ENDIF
		IF 'CONFIG_ANALITICE' $ UPPER(m.tcSql)
			CREATE CURSOR (m.tcCursor) (camp_leg_prefix C(30), camp_leg_sufix C(30))
			INSERT INTO (m.tcCursor) VALUES ('', '')
			RETURN 1
		ENDIF
		IF 'FCONTURI_ANALITICE' $ UPPER(m.tcSql)
			CREATE CURSOR (m.tcCursor) (acont C(20))
			INSERT INTO (m.tcCursor) VALUES (IIF(TYPE('gcMockAcontCrt') = 'C', gcMockAcontCrt, ''))
			RETURN 1
		ENDIF
		IF 'VPLCONT_ANALITIC' $ UPPER(m.tcSql)
			CREATE CURSOR (m.tcCursor) (cont C(10), acont C(20))
			INSERT INTO (m.tcCursor) VALUES ('371', '4')
			RETURN 1
		ENDIF
		CREATE CURSOR (m.tcCursor) (id_temp N(1))
		RETURN 1
	ENDPROC
	PROCEDURE oExecuta
		LPARAMETERS tcSql, tcCursor
		IF !EMPTY(m.tcCursor)
			IF USED(m.tcCursor)
				USE IN (m.tcCursor)
			ENDIF
			IF UPPER(m.tcCursor) == 'CJTVACOL4427'
				CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14))
			ELSE
				CREATE CURSOR (m.tcCursor) (id_temp N(1))
			ENDIF
		ENDIF
		RETURN .T.
	ENDPROC
	PROCEDURE oSelect2Value
		LPARAMETERS tcSql, toValue
		toValue = ''
		RETURN 1
	ENDPROC
	PROCEDURE oReset
	ENDPROC
ENDDEFINE

PROCEDURE CreeazaJtvaColoaneView
	LPARAMETERS tcCursor
	IF USED(m.tcCursor)
		USE IN (m.tcCursor)
	ENDIF
	CREATE CURSOR (m.tcCursor) (id_jtva_coloana N(14), denumire C(100), jc N(1), jv N(1), ;
		coloana_jc C(20), coloana_jv C(20), cota_tva N(6,2), id_tva N(14) NULL, afisat N(1), ;
		id_jtva_ex N(14) NULL, id_jtva_neex N(14) NULL, ordine N(8), ;
		taxcode N(6) NULL, taxcode_neexigibil N(6) NULL, taxcode_n50 N(6) NULL, ;
		taxcode_n50_tvai N(6) NULL, taxcode_n100 N(6) NULL, taxcode_regularizare N(6) NULL, taxcode_tvai N(6) NULL)
	INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, afisat, ordine, cota_tva) VALUES (0, '', 0, 0, 1, 0, 0)
	INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
		VALUES (208, 'ACH. INT. 21%', 1, 0, 'RO21B', 21, 209, 1, 1, 301104)
	INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
		VALUES (209, 'TVA ACH. INT. 21%', 1, 0, 'RO21T', 21, 1, 2, 301104)
	INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, id_tva, afisat, ordine, taxcode) ;
		VALUES (220, 'ACH. IMP. 21%', 1, 0, 'FO21B', 21, 221, 1, 3, 301204)
	INSERT INTO (m.tcCursor) (id_jtva_coloana, denumire, jc, jv, coloana_jc, cota_tva, afisat, ordine, taxcode) ;
		VALUES (221, 'TVA ACH. IMP. 21%', 1, 0, 'FO21T', 21, 1, 4, 301204)
ENDPROC
