* test_adauga_factura_ui.prg
* Test UI care introduce date PRIN FORMULARUL real de adaugare factura (clasa
* import_adauga_factura din COMUN\clase\ointroduceri.vcx), nu prin insert direct in tabel.
* Deschide dialogul, completeaza campurile programatic (contract construieste_todlg,
* "populabil programatic"), apeleaza actiunea OK (inainte_de_do_termin -> oParinte.
* do_adauga_factura) si verifica perechea baza+TVA rezultata in introdc. Foloseste
* harness-ul generic (ui_harness.prg + vfp_ui_harness.ps1) - dovada ca e reutilizabil.
*
* Scenarii (fara articole in rul_temp => sincronizeaza nu intra pe spargere/Oracle):
*   pas0 nota goala; pas1 dialog LEI; pas2 rezultat LEI; pas3 dialog VALUTA (EUR curs 5);
*   pas4 rezultat VALUTA; pas5 dialog DVI (TVA in vama); pas6 rezultat DVI.

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_adauga_factura_ui_log.txt"
gcSyncDir = "D:\ROA\ROAGEST\COMUN\utile\Teste\achizitie_import\uisync\"
STRTOFILE("START " + TTOC(DATETIME()) + CHR(13)+CHR(10), gcUILog)

ON ERROR DO AfErr 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 AfLog 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 AfLog WITH 'SET CLASSLIB OK'

	*----- PROCEDURI (mock amessagebox PRIMUL, ui_harness la final) -----
	SET PROCEDURE TO PROCEDURI
	SET PROCEDURE TO "D:\ROA\ROAGEST\COMUN\utile\Teste\mock_amessagebox.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 AfLog WITH 'SET PROCEDURE OK'

	*----- 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
	*-- SAFT (406) mereu activ in teste: exercita GetTaxCode/GetTaxCodeIdPart/taxcode pe randuri.
	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 goExecutor, goApp
	goExecutor = CREATEOBJECT('dummyexecutor')
	goApp = CREATEOBJECT('dummyapp')

	*----- poAct: antetul notei; dialogul mosteneste din el la Init -----
	PUBLIC poAct
	poAct = CREATEOBJECT('Custom')
	poAct.AddProperty('nume_val', '')
	poAct.AddProperty('curs', 1)
	poAct.AddProperty('proc_tva', 1.19)
	poAct.AddProperty('nnir', 0)
	poAct.AddProperty('id_valuta', 0)
	poAct.AddProperty('id_fdoc', 1)
	poAct.AddProperty('fdoc', 'Factura')
	poAct.AddProperty('id_partc', 500)
	poAct.AddProperty('partc', 'FURNIZOR ANTET SRL')
	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 (explicatii TVA): perechi REALE (Oracle dev, vjtva_coloane, 17.07.2026),
	*      regimul curent 21%/11% (post 01.08.2025) + import (DVI). id_tva pe baza leaga spre
	*      coloana T (aplica_explicatie_tva); explicatia T e IN TANDEM cu baza ("TVA " + baza). -----
	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)
	*-- achizitii interne 21% (id_tva pointeaza spre coloana T pereche, ca in aplica_explicatie_tva)
	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)
	*-- import (DVI: TVA achitat in vama) 21% - alta coloana decat achizitiile interne
	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)

	*----- saft_taxtable: coduri reale (vsaft_taxtable) - achizitii interne 21% vs import 21% -----
	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 ('301104-Achizitii de bunuri si servicii taxabile cu cota de 21%, altele decat importurile si cele supuse masurilor de simplificare', 301104, '', 21, 1, 0, 1, 0)
	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)

	*----- introdc (RecordSource Grid1) - porneste GOL, ca in fluxul real -----
	DO CreeazaIntrodc WITH 'introdc'

	*----- introdc_sablon: perechea-sablon (B 371/401 + T 4426/401) pe care do_adauga_factura o
	*      cloneaza. Randul T poarta cota implicita a sablonului (ca in fluxul real, unde sablonul
	*      vine din nota contabila configurata) - do_executa calculeaza TVA din T.ptva. Aici sablonul
	*      e deja configurat la 21% (aceeasi cota aleasa in dialog la toate scenariile de mai jos -
	*      cifrele de TVA raman corecte chiar daca aplica_explicatie_tva nu ajunge la randul T din
	*      cauza bugului doc_key); explicatia/taxcode pe T raman insa NEATINSE de cod - vezi
	*      VerificaTaxcodeTandem (B primeste taxcode corect, T ramane 0 - FAIL asteptat). -----
	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

	*----- rul_temp cu 1 rand INAINTE de instantiere: altfel import_nota.Init il recreeaza din
	*      Oracle (rul_temp gol => llRulTempPlin=.F.) si GridArt isi pierde coloanele (eroare 1925).
	*      Randul se sterge dupa Show => scenariile ruleaza cu 0 articole (sincronizeaza nu intra
	*      pe spargere/assign_analitic/Oracle). -----
	IF USED('rul_temp')
		USE IN ('rul_temp')
	ENDIF
	CREATE CURSOR rul_temp (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))
	INSERT INTO rul_temp (denumire, codmat, cant, pret, pret_lei, cont, cota_tva) ;
		VALUES ('PLACEHOLDER', 'PH', 1, 1, 1, '371', 19)

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

	*-- golesc placeholder-ul cu ZAP (nu DELETE ALL): DELETE ALL lasa 1 rand fizic sters si
	*-- pointerul la EOF, iar do_reface -> do_calculeaza_diferente face GO pe recno-ul de EOF
	*-- (eroare 5). ZAP => RECCOUNT=0, Recno()=1, do_calculeaza_diferente ia ramura LOCATE (sigura).
	SELECT rul_temp
	ZAP
	goObj.gridart.Refresh()
	DOEVENTS FORCE

	*========================= PAS 0: nota goala =========================
	DO HarnessStep WITH 0, 'import_nota afisat, introdc gol (' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri)'

	*========================= SCENARIU 1: factura in LEI =========================
	PUBLIC goDlg
	goDlg = CREATEOBJECT('import_adauga_factura', goObj)
	goDlg.cFelDoc = 'Factura'
	goDlg.nIdFdoc = 1
	goDlg.nNract = 5001
	goDlg.dDataAct = DATE()
	goDlg.nIdPartener = 501
	goDlg.cPartener = 'FURNIZOR INTERN SRL'
	goDlg.cExplicatia = 'Marfa achizitionata lei'
	goDlg.nSuma = 1000
	goDlg.nSumaLei = 0
	goDlg.nIdExplicatieTva = 208
	goDlg.cExplicatieTva = 'ACH. INT. 21%'
	goDlg.optTipTva.Value = 1
	goDlg.chkInValutaCont.Value = 0
	goDlg.chkParticipaValuta.Value = 1
	goDlg.WindowType = 0
	goDlg.Visible = .T.
	goDlg.Show()
	DOEVENTS FORCE
	DO HarnessStep WITH 1, 'dialog LEI completat (furnizor, nr 5001, suma 1000, TVA 21%)'
	*-- toDlg construit INLINE in programul PRINCIPAL (ADDPROPERTY da eroare 11 din proceduri in
	*-- acest runtime headless); valorile respecta exact dialog.construieste_todlg.
	PUBLIC goT
	DO AfLog WITH 'LEI: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
	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)
	DO AfLog WITH 'LEI: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
	goDlg.Hide()
	DOEVENTS FORCE
	DO VerificaPereche WITH 5001, 1, 1000, 210, 0, 0, ''
	DO VerificaTaxcodeTandem WITH 5001, 301104

	*========================= SCENARIU 2: factura in VALUTA (EUR curs 5) =========================
	goDlg = CREATEOBJECT('import_adauga_factura', goObj)
	goDlg.cFelDoc = 'Factura'
	goDlg.nIdFdoc = 1
	goDlg.nNract = 5002
	goDlg.dDataAct = DATE()
	goDlg.nIdPartener = 502
	goDlg.cPartener = 'FURNIZOR EXTERN GMBH'
	goDlg.cExplicatia = 'Marfa achizitionata valuta'
	goDlg.nSuma = 200
	goDlg.nSumaLei = 0
	goDlg.nCurs = 5
	goDlg.nIdValuta = 978
	goDlg.cValuta = 'EUR'
	goDlg.nIdExplicatieTva = 208
	goDlg.cExplicatieTva = 'ACH. INT. 21%'
	goDlg.optTipTva.Value = 1
	goDlg.chkInValutaCont.Value = 1
	goDlg.chkParticipaValuta.Value = 1
	goDlg.WindowType = 0
	goDlg.Visible = .T.
	goDlg.Show()
	DOEVENTS FORCE
	DO HarnessStep WITH 2, 'dialog VALUTA completat (EUR, suma 200, curs 5 => 1000 lei, TVA 21%)'
	DO AfLog WITH 'VALUTA: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
	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)
	DO AfLog WITH 'VALUTA: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
	goDlg.Hide()
	DOEVENTS FORCE
	*-- baza: suma lei = 200*5 = 1000, suma_val=200, in_valuta=1, curs=5, nume_val=EUR
	*--   TVA: suma lei = 1000*21% = 210, suma_val = 200*21% = 42
	DO VerificaPereche WITH 5002, 1, 1000, 210, 200, 42, 'EUR'
	DO VerificaTaxcodeTandem WITH 5002, 301104

	*========================= SCENARIU 3: factura cu TVA pe DVI (import extracomunitar) =========================
	goDlg = CREATEOBJECT('import_adauga_factura', goObj)
	goDlg.cFelDoc = 'Factura'
	goDlg.nIdFdoc = 1
	goDlg.nNract = 5003
	goDlg.dDataAct = DATE()
	goDlg.nIdPartener = 503
	goDlg.cPartener = 'FURNIZOR CHINA LTD'
	goDlg.cExplicatia = 'Import extracomunitar'
	goDlg.nSuma = 1000
	goDlg.nSumaLei = 0
	*-- ACH. IMP. 21% (id 220) - coloana de IMPORT, distincta de achizitiile interne (208):
	*-- domeniu corect pentru DVI (marfa din import, TVA platit in vama), nu ACH. INT.
	goDlg.nIdExplicatieTva = 220
	goDlg.cExplicatieTva = 'ACH. IMP. 21%'
	goDlg.optTipTva.Value = 2
	goDlg.chkInValutaCont.Value = 0
	goDlg.chkParticipaValuta.Value = 1
	*-- date DVI (TVA achitat in vama, alt document/partener/cont)
	goDlg.cSerieDvi = ''
	goDlg.nNractDvi = 7003
	goDlg.dDviData = DATE()
	goDlg.nIdFdocDVI = 2
	goDlg.cFelDocDvi = 'DVI'
	goDlg.nDviIdPartener = 900
	goDlg.cDviPartener = 'DIRECTIA VAMALA'
	goDlg.nDviTvaLei = 210
	goDlg.nDviTvaVal = 0
	*-- actualizeaza_stare_dvi() nu porneste singur din Value=2 (doar InteractiveChange, pe
	*-- interactiune reala) - il apelez explicit ca subrandul DVI sa fie vizibil in screenshot.
	goDlg.actualizeaza_stare_dvi()
	goDlg.WindowType = 0
	goDlg.Visible = .T.
	goDlg.Show()
	DOEVENTS FORCE
	DO HarnessStep WITH 3, 'dialog DVI completat (baza 1000 furnizor, TVA 210 pe DVI la VAMA, bifa DVI)'
	DO AfLog WITH 'DVI: valideaza (pe dialog) = ' + TRANSFORM(goDlg.valideaza())
	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)
	*-- ramura DVI din do_adauga_factura repozitioneaza pe randul T cu Go pe Recno() salvat la
	*-- creare (ointroduceri.prg ~10195), apoi il re-cheie pe VAMA (nract=dvi_nract, partc=DIRECTIA
	*-- VAMALA). TRY/CATCH local ramane ca plasa de siguranta, testul continua si raporteaza clar.
	LOCAL llDviEroare
	llDviEroare = .F.
	TRY
		DO AfLog WITH 'DVI: do_adauga_factura = ' + TRANSFORM(goObj.do_adauga_factura(goT))
	CATCH TO loExcDvi
		llDviEroare = .T.
		DO AfLog WITH 'DVI EROARE ' + TRANSFORM(loExcDvi.ErrorNo) + ' [' + loExcDvi.Message + '] in ' + ;
			loExcDvi.Procedure + ':' + TRANSFORM(loExcDvi.LineNo) + ' -> BUG REAL confirmat (doc_key), ' + ;
			'vezi docs\handoff_teste_ui_import.md (' + loExcDvi.LineContents + ')'
	ENDTRY
	goDlg.Hide()
	DOEVENTS FORCE
	DO HarnessStep WITH 4, 'DVI dupa do_adauga_factura: eroare=' + TRANSFORM(llDviEroare) + ' introdc=' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
	IF !llDviEroare
		*-- baza: partc furnizor, suma 1000, scd 371 (ramane pe nract=5003). TVA (DVI): randul T
		*-- re-cheiat pe documentul vamal (nract=dvi_nract=7003), partc VAMA, suma 210, scd 4426.
		DO VerificaDvi WITH 5003, 7003, 1000, 210
		DO VerificaTaxcodeTandem WITH 5003, 301204, 7003
		*-- anti-corupere: randul T al PRIMULUI document (5001, scenariul LEI) trebuie neatins de
		*-- override-ul DVI - bugul original (Locate For doc_key==calc_doc_key() degenerat) landa
		*-- pe primul rand T scanat din cursor si il corupea pe ACELA in loc de randul curent.
		DO VerificaRandNeatins WITH 5001, 210, 'FURNIZOR INTERN SRL'
		*-- DIAGNOSTIC (investigare, nu modifica cod aplicatie): scanez TOT introdc dupa DVI,
		*-- ca sa vad daca override-ul a corupt alt document (calc_doc_key() pe pointer gresit).
		DO AfLog WITH 'DIAG dump integral introdc dupa DVI:'
		SELECT introdc
		SCAN
			DO AfLog WITH '  recno=' + TRANSFORM(RECNO()) + ' nract=' + TRANSFORM(nract) + ' tip_rand=' + tip_rand + ;
				' scd=' + ALLTRIM(scd) + ' suma=' + TRANSFORM(suma) + ' partc=[' + ALLTRIM(NVL(partc,'')) + ;
				'] doc_key=[' + ALLTRIM(doc_key) + ']'
		ENDSCAN
	ELSE
		DO AfLog WITH 'DVI: VerificaDvi/VerificaTaxcodeTandem SARITE (do_adauga_factura a aruncat eroare - vezi mesajul de mai sus)'
	ENDIF

	DO AfLog WITH 'GATA - toate scenariile executate'
	DO HarnessStep WITH 5, 'final: introdc are ' + TRANSFORM(RECCOUNT_ACTIVE('introdc')) + ' randuri'
	DO HarnessDone WITH 'done'

CATCH TO loExc
	DO AfLog 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 CreeazaIntrodc
	*-- structura introdc (RecordSource Grid1 import_nota), identica pt. introdc si introdc_sablon
	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

PROCEDURE VerificaPereche
	*-- verifica perechea B+T adaugata (dupa nract): sume lei/valuta, valuta pe baza
	LPARAMETERS tnNract, tnPas, tnBazaLei, tnTvaLei, tnBazaVal, tnTvaVal, tcVal
	LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lnBSV, lcNV, lnInV
	lnSel = SELECT()
	SELECT introdc
	lcMsg = ''
	LOCATE FOR nract = tnNract AND tip_rand == 'B'
	llB = FOUND()
	IF llB
		lnBS = suma
		lnBSV = suma_val
		lcNV = ALLTRIM(NVL(nume_val,''))
		lnInV = in_valuta
	ENDIF
	LOCATE FOR nract = tnNract AND tip_rand == 'T'
	llT = FOUND()
	IF llT
		lnTS = suma
		lnTSV = suma_val
	ENDIF
	IF llB AND llT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 ;
			AND ABS(lnBSV - tnBazaVal) < 0.01 AND ALLTRIM(NVL(lcNV,'')) == tcVal
		lcMsg = 'PASS scenariu nract=' + TRANSFORM(tnNract) + ': B(suma=' + TRANSFORM(lnBS) + ' val=' + TRANSFORM(lnBSV) + ' ' + lcNV + ') + T(suma=' + TRANSFORM(lnTS) + ')'
	ELSE
		lcMsg = 'FAIL scenariu nract=' + TRANSFORM(tnNract) + ': B?=' + TRANSFORM(llB) + ' T?=' + TRANSFORM(llT) + ' bazaLei=' + TRANSFORM(IIF(llB,lnBS,-1)) + '(astept ' + TRANSFORM(tnBazaLei) + ') tvaLei=' + TRANSFORM(IIF(llT,lnTS,-1)) + '(astept ' + TRANSFORM(tnTvaLei) + ') bazaVal=' + TRANSFORM(IIF(llB,lnBSV,-1)) + '(astept ' + TRANSFORM(tnBazaVal) + ') val=[' + IIF(llB,lcNV,'?') + '](astept [' + tcVal + '])'
	ENDIF
	DO AfLog WITH lcMsg
	SELECT (lnSel)
ENDPROC

PROCEDURE VerificaDvi
	*-- DVI: baza pe furnizor (nract original, scd 371, suma). Randul T (scd 4426, suma TVA) e
	*-- re-cheiat de override pe documentul vamal (nract=tnNractDvi, partc=DIRECTIA VAMALA), prin
	*-- Go pe Recno() salvat la creare (linia ~10195), nu mai Locate For doc_key==calc_doc_key().
	LPARAMETERS tnNract, tnNractDvi, tnBazaLei, tnTvaLei
	LOCAL lnSel, lcMsg, llB, llT, lnBS, lnTS, lcTScd, lcTPartc, llVama, llRamasitaT
	lnSel = SELECT()
	SELECT introdc
	LOCATE FOR nract = tnNract AND tip_rand == 'B'
	llB = FOUND()
	IF llB
		lnBS = suma
	ENDIF
	*-- randul T al documentului vamal (scd 4426); citesc suma si partenerul ca sa vad daca override-ul a aplicat
	LOCATE FOR nract = tnNractDvi AND tip_rand == 'T'
	llT = FOUND()
	IF llT
		lnTS = suma
		lcTScd = ALLTRIM(scd)
		lcTPartc = ALLTRIM(NVL(partc,''))
		llVama = ('VAMAL' $ UPPER(lcTPartc))
	ENDIF
	*-- randul T NU trebuie sa mai existe sub nract-ul original al facturii (a fost re-cheiat, nu duplicat)
	LOCATE FOR nract = tnNract AND tip_rand == 'T'
	llRamasitaT = FOUND()
	IF llB AND llT AND !llRamasitaT AND ABS(lnBS - tnBazaLei) < 0.01 AND ABS(lnTS - tnTvaLei) < 0.01 AND llVama
		lcMsg = 'PASS scenariu DVI: B(furnizor nract=' + TRANSFORM(tnNract) + ', suma=' + TRANSFORM(lnBS) + ') + T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' scd=' + lcTScd + ' partc=' + lcTPartc + ' suma=' + TRANSFORM(lnTS) + ')'
	ELSE
		lcMsg = 'FAIL scenariu DVI: B(suma=' + TRANSFORM(IIF(llB,lnBS,-1)) + ', astept ' + TRANSFORM(tnBazaLei) + ') + T_DVI(nract=' + TRANSFORM(tnNractDvi) + ' scd=' + IIF(llT,lcTScd,'?') + ' suma=' + TRANSFORM(IIF(llT,lnTS,-1)) + ', astept ' + TRANSFORM(tnTvaLei) + ' partc=' + IIF(llT,lcTPartc,'?') + ', astept VAMA) ramasita T pe nract original=' + TRANSFORM(llRamasitaT) + ' (astept .F.)'
	ENDIF
	DO AfLog WITH lcMsg
	SELECT (lnSel)
ENDPROC

PROCEDURE VerificaRandNeatins
	*-- anti-corupere: verifica ca randul T al unui document ANTERIOR (deja adaugat) a ramas
	*-- neatins dupa un scenariu ulterior (ex. DVI). Regresie pentru bugul original: Locate For
	*-- doc_key==calc_doc_key() degenerat landa pe primul rand T scanat din cursor (nu neaparat
	*-- cel al documentului curent) si il corupea pe ACELA - fix: Go pe Recno() salvat la creare.
	LPARAMETERS tnNract, tnSumaAsteptata, tcPartcAsteptat
	LOCAL lnSel, lcMsg, llT, lnS, lcScd, lcPartc
	lnSel = SELECT()
	SELECT introdc
	LOCATE FOR nract = tnNract AND tip_rand == 'T'
	llT = FOUND()
	IF llT
		lnS = suma
		lcScd = ALLTRIM(scd)
		lcPartc = ALLTRIM(NVL(partc,''))
	ENDIF
	IF llT AND lcScd == '4426' AND ABS(lnS - tnSumaAsteptata) < 0.01 AND lcPartc == tcPartcAsteptat
		lcMsg = 'PASS anti-corupere randul T nract=' + TRANSFORM(tnNract) + ' neatins (scd=' + lcScd + ' suma=' + TRANSFORM(lnS) + ' partc=' + lcPartc + ')'
	ELSE
		lcMsg = 'FAIL anti-corupere randul T nract=' + TRANSFORM(tnNract) + ': gasit=' + TRANSFORM(llT) + ' scd=' + IIF(llT,lcScd,'?') + ' suma=' + TRANSFORM(IIF(llT,lnS,-1)) + ' partc=[' + IIF(llT,lcPartc,'?') + '] (astept scd=4426 suma=' + TRANSFORM(tnSumaAsteptata) + ' partc=[' + tcPartcAsteptat + '])'
	ENDIF
	DO AfLog WITH lcMsg
	SELECT (lnSel)
ENDPROC

PROCEDURE VerificaTaxcodeTandem
	*-- Taxcode SAFT (406) IN TANDEM baza+TVA, scris de aplica_explicatie_tva -> Thisform.
	*-- UpdateExplicatieSAFT() -> GetTaxCodeIdPart() (gl406=.T. obligatoriu, vezi oproceduri_comune.prg).
	*-- Randul B: Replace-ul + UpdateExplicatieSAFT ruleaza pe randul curent - taxcode corect.
	*-- Randul T: taxcode-ul se aplica INAINTE de eventuala re-cheiere pe DVI, dar identitatea
	*-- randului dupa do_adauga_factura se verifica pe nract-ul FINAL (tnNractT, implicit = tnNract
	*-- pentru facturi normale; = dvi_nract pentru scenariul DVI, vezi apelul cu 3 parametri).
	LPARAMETERS tnNract, tnTaxcodeAsteptat, tnNractT
	LOCAL lnSel, lcMsg, llB, llT, lnTaxB, lnTaxT, lnNractT
	lnSel = SELECT()
	lnNractT = IIF(PCOUNT() >= 3 AND tnNractT # 0, tnNractT, tnNract)
	SELECT introdc
	LOCATE FOR nract = tnNract AND tip_rand == 'B'
	llB = FOUND()
	IF llB
		lnTaxB = NVL(taxcode, -1)
	ENDIF
	LOCATE FOR nract = lnNractT AND tip_rand == 'T'
	llT = FOUND()
	IF llT
		lnTaxT = NVL(taxcode, -1)
	ENDIF
	IF llB AND lnTaxB = tnTaxcodeAsteptat
		lcMsg = 'PASS taxcode randul B (nract=' + TRANSFORM(tnNract) + '): taxcode=' + TRANSFORM(lnTaxB) + ' (SAFT corect, aplicat direct de UpdateExplicatieSAFT)'
	ELSE
		lcMsg = 'FAIL taxcode randul B (nract=' + TRANSFORM(tnNract) + '): gasit=' + TRANSFORM(llB) + ' taxcode=' + TRANSFORM(IIF(llB,lnTaxB,-1)) + ' (astept ' + TRANSFORM(tnTaxcodeAsteptat) + ')'
	ENDIF
	DO AfLog WITH lcMsg
	IF llT AND lnTaxT = tnTaxcodeAsteptat
		DO AfLog WITH 'PASS taxcode randul T (tandem, nract=' + TRANSFORM(lnNractT) + '): taxcode=' + TRANSFORM(lnTaxT)
	ELSE
		DO AfLog WITH 'FAIL taxcode randul T (tandem, nract=' + TRANSFORM(lnNractT) + '): gasit=' + TRANSFORM(llT) + ' taxcode=' + TRANSFORM(IIF(llT,lnTaxT,-1)) + ' (astept ' + TRANSFORM(tnTaxcodeAsteptat) + ')'
	ENDIF
	SELECT (lnSel)
ENDPROC

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

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

PROCEDURE AfLog
	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
		*-- update_jtva_coloane (SELECT * FROM vjtva_coloane ...): mock cu date reale (jtva_coloane,
		*-- jtva_coloane_taxcode - mod 6, cu campurile taxcode*) - vezi GetTaxCode/GetTaxCodeIdPart.
		IF 'VJTVA_COLOANE' $ UPPER(m.tcSql)
			DO CreeazaJtvaColoaneView WITH m.tcCursor
			RETURN 1
		ENDIF
		*-- rul_temp (recreat de import_nota.Init din vrul cand e gol): structura completa
		*-- ceruta de coloanele GridArt, altfel grila isi pierde coloanele (eroare 1925).
		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))
		ELSE
			CREATE CURSOR (m.tcCursor) (id_temp N(1))
		ENDIF
		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
		*-- GetCodFiscalPartenerById (oproceduri_comune.prg): cod fiscal gol => VERIFICA_RTVAI
		*-- vede llIsCIF=.F. si sare peste apelul PACK_ROARTVAI (fara Oracle real).
		LPARAMETERS tcSql, toValue
		toValue = ''
		RETURN 1
	ENDPROC
	PROCEDURE oReset
		*-- update_jtva_coloane() il apeleaza necondit dupa oExecute (updateserver.prg:611).
	ENDPROC
ENDDEFINE

PROCEDURE CreeazaJtvaColoaneView
	*-- Mock pentru "select * from vjtva_coloane ..." (update_jtva_coloane): perechi reale
	*-- (Oracle dev, 17.07.2026) achizitii interne 21% + import 21%, cu taxcode SAFT diferentiat
	*-- (301104 vs 301204) - vezi GetTaxCode.
	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
