* 27.05.2022
* wSalesPurchaseInvoices corectare valoare InvoiceLineAmount (valoare in loc de pret unitar)

*!*	23.02.2023
*!*	oSalesInvoices - corectare cont venit pentru articolele din gestiune si facturare

*!*	10.05.2023
*!*	oPurchaseInvoices - includere bonuri fiscale

*!*	15.05.2023
*!*	do_genereaza_xml - se asteapta maxim 30 secunde pentru validare xml

*!*	07.07.2023
*!*	oSalesInvoices - se genereaza linii cu articole pentru notele contabile suplimentare fata de articolele din gestiune/facturare
*!* tratare cont 667 = 4111 la diferente contabilitate fata de gestiune/facturare

*!*	21.07.2023
*!*	oSalesInvoices - se genereaza linii cu diferente contabilitate - gestiune/facturare doar daca sunt diferente pe taxcode, nu si pe cont
*!*	se poate modifica contul in contabilitate, dar in facturare se citeste din nota contabila

*!*	31.08.2023
*!*	oPurchaseInvoices - se ia curs valutar, id_valuta din rulaj, in loc de RON

*!*	15.09.2023
*!*	oPurchaseInvoices - se includ si tip_doc = "INV" pentru facturile de achizitie din import

*!*	03.11.2023
*!*	oSalesInvoices - nu mai completez contul pe articole cu 707 daca nu gasesc in politici de preturi sau note contabile
*!* completez cu contul din registrul jurnal

*!*	19.12.2023
*!*	oSalesInvoices - se scade discountul unitar din pretul unitar

*!* 30.04.2024
*!* oAssets - calculare Amortizare precedenta la inceputul perioadei din prima inregistrare.
*!* calculare amortizare totala la sfarsitul perioadei din ultima inregistrare
*!* este posibil ca amortizarea precedenta sa se reevalueze, si amortizarea totala era diferita de amortizarea precedenta de la inceputul perioadei + amortizarea din perioada
*!* VerificareImobilizari: corectie verificare amortizare la inceputul perioadei, la sfarsitul perioadei
*!* VerificareImobilizari: aquisitionandproductioncostend nu era egala cu valoarea de inventar daca existau reevaluari (+ reevaluare pozitiva-reevaluare negativa)

*!* 04.10.2024
*!*	do_verifica_tva - se verifica inregistrarile contabile D406 conturi TVA 442x care au taxa. Nu trebuie sa aiba taxa

*!*	28.11.2024
*!* wSalesPurchaseInvoices - nu se mai scrie nimic daca sunt 0 facturi

*!*	21.01.2025
*!*	wGeneralLedgerEntries - completare customerId pentru contul 463

*!*	25.04.2025
*!*	wPayments - tratare caz fara plati

*!*	16.06.2025
*!*	CompletareCodTaxaPlata - se completeaza pentru perioada curenta (ex: trimestru) in loc de luna curenta

*!* 25.06.2025
*!* oSalesInvoices, oPurchaseInvoices - se iau doar facturile cu data inregistrarii din luna in care au fost emise
*!* la SAFT Trimestrial, aveam facturi cu TVA Incasare care apareau in mai multe luni si se duplicau

*!*	27.06.2025
*!*	wHeader - corectare nume firma cu caractere speciale

*!* 27.08.2025
*!*	wHeader - limitare nume firma la 70 caractere



*!*	30.01.2026
*!*	Robert
*!*	opayments - sa nu mai selecteze conturile de tip 512x/531x/542x/581 = 512x/531x/542x/581 
*!*	adaugat procedura do_verifica_solduri - face toate verificarile (balanta, registru jurnal, clienti, furnizori)

*!*	03.02.2026
*!*	do_verifica_plati - Mesaj randuri plati fara cont de terti - probabil nu sunt plati/incasari catre terti

*!*	21.05.2026
*!*	oAssets - am tratat o eroare la join cAmortizareLunara daca nu avea nici o inregistrare (firma fara imobilizari nu avea completat an si luna)
*!*	do_verifica_imobilizari - salvare in 4 fisiere xlsx, dar aleg o singura data directorul de salvare


*!* 01.072026
*!* oSalesInvoices - se facea join dublu vanzari - jv2007 in cazul facturilor cu tva la incasare

* saft_D406
Procedure viz_saft_d406
	loD406 = Createobject("D406")
	m.loD406.List()
Endproc && viz_saft_d406

Define Class d406 As Custom
	Perioada = 1
	oForm = Null && formular D406
	oUnitate = Null
	TipDescriere = 'LUNAR'
	Tip = 'L'
	SegmentIndex = 1
	TotalSegmentsInSequence = 1
	TaxAccountingBasis = 'A'
	TaxEntity = 'Company'

	CaleFisierPDF = '' && director fisier pdf

	Procedure List
		Local loFrm
		Local loDecl As Form
		Local lcPerioadaTVA, lcSelect, lcTip, lcTipDescriere, lnCustSupType
*!*		loFrm = CREATEOBJECT("frm_saft_d406")

		Private poResponsabil
		Private pounitate

		poResponsabil = Null

		lcSelect = Select()

		If Type('gofirma.codfiscalfro') = 'U'
			AddProperty(gofirma, 'codfiscalfro', ALLTRIM(Strtran(Alltrim(gofirma.cod_fiscal), 'RO', '')))
		Endif

		pounitate = Createobject("empty")
		AddProperty(m.pounitate, "tva_incasare", goCalendar.tva_incasare)

		AddProperty(m.pounitate, "an1", m.gnAn)
		AddProperty(m.pounitate, "an2", m.gnAn)
		AddProperty(m.pounitate, "luna1", m.gnLuna)
		AddProperty(m.pounitate, "luna2", m.gnLuna)

		lcPerioadaTVA = Upper(Nvl(citeste_optiune('PERIOADA_TVA'), ''))
		If Empty(m.lcPerioadaTVA)
			AMESSAGEBOX('Configurati optiunea "PERIOADA_TVA" in Definirea Companiei!', 0 + 48, _Screen.Caption)
			lcPerioadaTVA = 'LUNAR'
		Endif
		lcTipDescriere = Iif(!Inlist(m.lcPerioadaTVA, 'LUNAR', 'TRIMESTRIAL', 'ANUAL', 'LA CERERE'), 'LUNAR', m.lcPerioadaTVA)

		lcTip = Iif(lcTipDescriere = 'LUNAR', 'L', Iif(lcTipDescriere = 'TRIMESTRIAL', 'T', Iif(lcTipDescriere = 'ANUAL', 'A', Iif(lcTipDescriere = 'LA CERERE', 'C', 'L'))))
		AddProperty(m.pounitate, "perioada_tva", m.lcPerioadaTVA) && tip LUNAR/TRIMESTRIAL/SEMESTRIAL/ANUAL
		AddProperty(m.pounitate, "tip", m.lcTip) && tip L/T/A/C/NL/NT (Lunar/Trimestrial/Anual/Cerere/Nerezidenti lunar/Nerezidenti trimestrial)
		AddProperty(m.pounitate, "tipDescriere", m.lcTipDescriere) && tip lung

		AddProperty(m.pounitate, "codi", ALLTRIM(Strtran(Strtran(Alltrim(Upper(Nvl(gofirma.cod_fiscal, ''))), 'RO', ''), 'R', '')))
		AddProperty(m.pounitate, "deni", Nvl(Alltrim(gofirma.firma), ''))
		AddProperty(m.pounitate, "adr", Nvl(Alltrim(gofirma.adresa), ''))
		AddProperty(m.pounitate, "tel", Nvl(Alltrim(gofirma.telefon), ''))
		AddProperty(m.pounitate, "fax", Nvl(Alltrim(gofirma.fax), ''))
		AddProperty(m.pounitate, "email", Nvl(Alltrim(gofirma.email), ''))

		AddProperty(m.pounitate, "taraR", "")
		AddProperty(m.pounitate, "codiR", "")
		AddProperty(m.pounitate, "deniR", "")
		AddProperty(m.pounitate, "adrR", "")
		AddProperty(m.pounitate, "telR", "")
		AddProperty(m.pounitate, "faxR", "")
		AddProperty(m.pounitate, "emailR", "")

		AddProperty(m.pounitate, "numeD", "")
		AddProperty(m.pounitate, "functieD", "")

		AddProperty(m.pounitate, "tvaincasare", goCalendar.tva_incasare)
		lnCustSupType = INT(VAL(Alltrim(citeste_optiune('D406_CUST_SUP_TYPE'))))
		lnCustSupType = IIF(INLIST(m.lnCustSupType,9999,2020,2021,2022,2023,2024,2025), m.lnCustSupType, 9999) && 9999 = Toti clientii/furnizorii/ 2022 = Incepand cu anul 2022 (intreprinderi mari), 2023 = 2023 (intreprinderi mijlocii), 2025 = 2025 (intreprinderi mici)
		AddProperty(m.pounitate, "CustSupType", m.lnCustSupType) 
		
********************************
		AddProperty(m.pounitate, "FunctieContact", Alltrim(citeste_optiune('D406_FUNCTIE_CONTACT')))
		AddProperty(m.pounitate, "PrenumeContact", Alltrim(citeste_optiune('D406_PRENUME_CONTACT')))
		AddProperty(m.pounitate, "NumeContact", Alltrim(citeste_optiune('D406_NUME_CONTACT')))
		With m.pounitate
			.PrenumeContact = Iif(!Empty(Nvl(.PrenumeContact, '')), .PrenumeContact, Alltrim(Nvl(gofirma.prenume_declarant, '')))
			.NumeContact = Iif(!Empty(Nvl(.NumeContact, '')), .NumeContact, Alltrim(Nvl(gofirma.nume_declarant, '')))
			.FunctieContact = Iif(!Empty(Nvl(.FunctieContact, '')), .FunctieContact, Alltrim(Nvl(gofirma.functie, '')))
		Endwith
*******************************
		AddProperty(m.pounitate, "MasterFiles", .T.)
		AddProperty(m.pounitate, "GeneralLedgerEntries", .T.)
		AddProperty(m.pounitate, "SourceDocuments", .T.)

		AddProperty(m.pounitate, "GeneralLedgerAccounts", .F.)
		AddProperty(m.pounitate, "Customers", .F.)
		AddProperty(m.pounitate, "Suppliers", .F.)
		AddProperty(m.pounitate, "TaxTable", .F.)
		AddProperty(m.pounitate, "UOMTable", .F.)
		AddProperty(m.pounitate, "AnalysisTypeTable", .F.)
		AddProperty(m.pounitate, "MovementTypeTable", .F.)
		AddProperty(m.pounitate, "Products", .F.)
		AddProperty(m.pounitate, "PhysicalStock", .F.)
		AddProperty(m.pounitate, "Owners", .F.)
		AddProperty(m.pounitate, "Assets", .F.)

		AddProperty(m.pounitate, "SalesInvoices", .F.)
		AddProperty(m.pounitate, "PurchaseInvoices", .F.)
		AddProperty(m.pounitate, "Payments", .F.)
		AddProperty(m.pounitate, "MovementofGoods", .F.)
		AddProperty(m.pounitate, "AssetTransactions", .F.)


*****************************************************************************************************
*!*			AddProperty(pounitate, "TipRepr", Alltrim(citeste_optiune('D406_TIP_REPREZ')))
*!*			AddProperty(pounitate, "TelRepr", Alltrim(citeste_optiune('D406_TEL_REPREZ')))
*!*			AddProperty(pounitate, "FaxRepr", Alltrim(citeste_optiune('D406_FAX_REPREZ')))
*!*			AddProperty(pounitate, "EmailRepr", Alltrim(citeste_optiune('D406_EMAIL_REPREZ')))

*!*			AddProperty(pounitate, "DenIntocmit", Alltrim(citeste_optiune('D406_DEN_INTOCMIT')))
*!*			AddProperty(pounitate, "CuiIntocmit", Alltrim(citeste_optiune('D406_CUI_INTOCMIT')))
*!*			AddProperty(pounitate, "PJIntocmit", Int(Val(Nvl(citeste_optiune('D406_PJ_INTOCMIT'), '1'))) )
*!*			AddProperty(pounitate, "CalitateIntocmit", Alltrim(citeste_optiune('D406_CALITATE_INTOCMIT')))
*!*			AddProperty(pounitate, "Calitate2Intocmit", Alltrim(citeste_optiune('D406_CALITATE2_INTOCMIT')))
*!*			AddProperty(pounitate, "FunctieIntocmit", Alltrim(citeste_optiune('D406_FUNCTIE_INTOCMIT')))

		This.oUnitate = m.pounitate

		Do Form frm_decl406_saft Name m.loDecl Linked Noshow
		This.oForm = m.loDecl
		loDecl.oParent = This
		m.loDecl.Show()

		scrie_optiune('D406_FUNCTIE_CONTACT', pounitate.FunctieContact, 'D406 functie contact')
		scrie_optiune('D406_PRENUME_CONTACT', pounitate.PrenumeContact, 'D406 prenume contact')
		scrie_optiune('D406_NUME_CONTACT', pounitate.NumeContact, 'D406 nume contact')

		scrie_optiune('D406_CUST_SUP_TYPE', pounitate.CustSupType, 'D406 tip clienti, furnizori: 1=Toti;2=2022;3=2023;4=2025')

*!*			scrie_optiune('D406_TIP', pounitate.TIP, 'Tip declaratie 394: LUNAR/TRIMESTRIAL/SEMESTRIAL/ANUAL')
	Endproc && List


* Intoarce fragment xml
	Function wxml
		Lparameters tcTag, tcValue, tlForce
* tcTag: StreetName (obligatoriu)
* tcValue: alabala (optional)
* tlForce: (optional, implicit .F.) daca se scrie tag-ul indiferent daca exista sau nu valoarea
		Local lcText, lcValue, llValue, llForce
		llForce = m.tlForce
		lcText = ''
		IF ISNULL(tcValue)
			lcValue = ''
		ELSE
			lcValue = TRANSFORM(m.tcValue)	
		ENDIF 

		If !Empty(m.lcValue) Or m.tlForce
* daca s-a transmis parametrul valoare sau tag-ul trebuie afisat indiferent daca are sau nu valoare
			lcText = [<nsSAFT:] + m.tcTag + [>] + m.lcValue + [</nsSAFT:] + m.tcTag + [>]
		Endif
		Return m.lcText
	Endfunc && wxml

	Procedure do_genereaza_xml
		LPARAMETERS tlTest
		* tlTest: .T. D406T, .F. D406

		Local lcCustomers, lcGeneralLedgerAccounts, lcHeader, lcSuppliers, lcXML
		Local lcAnalysisTypeTable, lcMovementTypeTable, lcGeneralLedgerEntries, lcPayments, lcPurchaseInvoices, lcSalesInvoices
		Local lcTaxTable, lcTipDeclaratie
		LOCAL lnBytes, llSucces
		Local lcAssetTransactions, lcAssets, lcCaleFisier, lcComunPath, lcConfigDir, lcFileName
		Local lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock
		Local lcProducts, lcUOMTable, lcValidator, lcXMLTemp, lnFileHandle, lnSec, lcSufixCale, lcSufixFisier 
		LOCAL lcMessage, loChatBot
		LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2
		
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
				
		DO CASE 
			CASE goFirma.id_forma_juridica = 13
				This.TaxAccountingBasis = 'ONG' && asociatii, organizatii nonguvernamentale
			OTHERWISE 
				This.TaxAccountingBasis = 'A' && societati comertiale
		ENDCASE 
		
		lcCaleFisier = m.gcBasePath + IIF(m.tlTest, "D406T\", "D406\") && D:\ROA\D406\
		If !Directory(m.lcCaleFisier)
			Md (m.lcCaleFisier)
		Endif

		lcTip = UPPER(This.Tip) && L/T/A/C
		lcSufixCale = IIF(m.lcTip = 'A', 'anual\', IIF(m.lcTip = 'C', 'cerere\', ''))
		lcSufixFisier = IIF(m.lcTip = 'A', '_anual', IIF(m.lcTip = 'C', '_cerere', ''))

		lcCaleFisier = m.lcCaleFisier + Alltrim(Str(gnAn)) + "_" + Padl(Alltrim(Str(gnLuna)), 2, "0") + "\" && D:\ROA\D406\2022_01\
		If !Directory(m.lcCaleFisier)
			Md (m.lcCaleFisier)
		Endif

		lcCaleFisier = m.lcCaleFisier + Strtran(gcFirma, [ ], [_]) + "\" + m.lcSufixCale && D:\ROA\D406\2022_01\firma\
		If !Directory(m.lcCaleFisier)
			Md (m.lcCaleFisier)
		ENDIF
		
		lcNumeFisier = IIF(m.tlTest, 'd406t_', 'd406_') + gofirma.codfiscalfro + "_" + Alltrim(Str(gnAn)) + "_" + Padl(gnLuna, 2, "0")
		lcFileName = m.lcCaleFisier + lcNumeFisier + m.lcSufixFisier + '.xml'
		lcFisierRaspuns = m.lcFileName + '.txt'		

		IF FILE(m.lcFileName)
			DELETE FILE (m.lcFileName)
		ENDIF 

		IF FILE(m.lcFisierRaspuns)
			DELETE FILE (m.lcFisierRaspuns)
		ENDIF 
		
		WAIT WINDOW 'Generare Header ' NOWAIT 
		lcHeader = This.wHeader()

		WAIT WINDOW 'Generare GeneralLedgerAccounts' NOWAIT 
		lcGeneralLedgerAccounts = This.wGeneralLedgerAccounts()

		WAIT WINDOW 'Generare Customers ' NOWAIT 
		lcCustomers = This.wCustomersSuppliers('customers')

		WAIT WINDOW 'Generare Suppliers ' NOWAIT 
		lcSuppliers = This.wCustomersSuppliers('suppliers')

		WAIT WINDOW 'Generare TaxTable ' NOWAIT 
		lcTaxTable = This.wTaxTable()

		WAIT WINDOW 'Generare UOMTable ' NOWAIT 
		lcUOMTable = This.wUOMTable()
		
		WAIT WINDOW 'Generare AnalysysTypeTable ' NOWAIT 
		lcAnalysisTypeTable = This.wAnalysisTypeTable()

		WAIT WINDOW 'Generare GeneralLedgerEntries ' NOWAIT 
		lcGeneralLedgerEntries = This.wGeneralLedgerEntries()

		WAIT WINDOW 'Generare Sales Invoices ' NOWAIT 
		lcSalesInvoices = IIF(This.oUnitate.SalesInvoices, This.wSalesInvoices(), '')

		WAIT WINDOW 'Generare Purchase Invoices ' NOWAIT 
		lcPurchaseInvoices = IIF(This.oUnitate.PurchaseInvoices, This.wPurchaseInvoices(), '')

		WAIT WINDOW 'Generare Payments ' NOWAIT 
		lcPayments = IIF(This.oUnitate.Payments, This.wPayments(), '')

		WAIT WINDOW 'Generare MovementTypeTable ' NOWAIT 
		lcMovementTypeTable = IIF(This.oUnitate.MovementTypeTable, This.wMovementTypeTable(), '')

		WAIT WINDOW 'Generare Products ' NOWAIT 
		lcProducts = This.wProducts()
		IF EMPTY(m.lcProducts) And This.oUnitate.Products
			TEXT TO m.lcProducts NOSHOW 
			
			<nsSAFT:Product>	
				<nsSAFT:ProductCode>7493049347</nsSAFT:ProductCode>
				<nsSAFT:GoodsServicesID>01</nsSAFT:GoodsServicesID>
				<nsSAFT:Description>Product 1</nsSAFT:Description>
				<nsSAFT:ProductCommodityCode>25261000</nsSAFT:ProductCommodityCode>
				<nsSAFT:UOMBase>58</nsSAFT:UOMBase>
				<nsSAFT:UOMStandard>58</nsSAFT:UOMStandard>
				<nsSAFT:UOMToUOMBaseConversionFactor>1.0</nsSAFT:UOMToUOMBaseConversionFactor>
			</nsSAFT:Product>			
			
			ENDTEXT 			
		ENDIF 
		
		WAIT WINDOW 'Generare PhysicalStock ' NOWAIT 
		lcPhysicalStock = This.wPhysicalStock()
				
		WAIT WINDOW 'Generare MovementofGoods ' NOWAIT 
		lcMovementofGoods = This.wMovementofGoods()

		WAIT WINDOW 'Generare Owners ' NOWAIT 
		lcOwners = This.wOwners()

		WAIT WINDOW 'Generare Assets ' NOWAIT 
		lcAssets = This.wAssets()

		WAIT WINDOW 'Generare AssetTransactions ' NOWAIT 
		lcAssetTransactions = This.wAssetTransactions()

		
		lcTipDeclaratie = IIF(m.tlTest, 'd406t', 'd406')

		WAIT WINDOW 'Scriere XML Header...' NOWAIT 
		lcXML = ""

		lnFileHandle = FCREATE(m.lcFileName) 
	
		WAIT WINDOW 'Scriere XML Header...' NOWAIT 

		Text To m.lcXMLTemp Textmerge NOSHOW
<?xml version="1.0" encoding="UTF-8"?>
<nsSAFT:AuditFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:nsSAFT="mfp:anaf:dgti:<<m.lcTipDeclaratie>>:declaratie:v1">

	<<m.lcHeader>>
	<nsSAFT:MasterFiles>
		ENDTEXT 
		lcXML = m.lcXMLTemp
		
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)

		
		WAIT WINDOW 'Scriere XML GeneralLedgerAccounts...' NOWAIT 
		lcXMLTemp = [<nsSAFT:GeneralLedgerAccounts>] + CHR(13) + CHR(10) + m.lcGeneralLedgerAccounts + [</nsSAFT:GeneralLedgerAccounts>]
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)


		WAIT WINDOW 'Scriere XML Customers...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:Customers>])		
		IF This.oUnitate.Customers
			lnBytes = FPUTS(m.lnFileHandle, m.lcCustomers)
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:Customers>])		


		WAIT WINDOW 'Scriere XML Suppliers...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:Suppliers>])		
		IF This.oUnitate.Suppliers
			lnBytes = FPUTS(m.lnFileHandle, m.lcSuppliers)
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:Suppliers>])		

		
		WAIT WINDOW 'Scriere XML TaxTable...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:TaxTable>])
		IF This.oUnitate.TaxTable				
			lnBytes = FPUTS(m.lnFileHandle, m.lcTaxTable)	
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:TaxTable>])		
			
		
		WAIT WINDOW 'Scriere XML UOMTable...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:UOMTable>])
		IF This.oUnitate.UOMTable				
			lnBytes = FPUTS(m.lnFileHandle, m.lcUOMTable)	
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:UOMTable>])	
				
		
		WAIT WINDOW 'Scriere XML AnalysisTypeTable...' NOWAIT 
		lcXMLTemp = this.wxml("AnalysisTypeTable", m.lcAnalysisTypeTable, This.oUnitate.AnalysisTypeTable)
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)	
		
		WAIT WINDOW 'Scriere XML MovementTypeTable...' NOWAIT
		lcXMLTemp = this.wxml("MovementTypeTable", m.lcMovementTypeTable, .T.)
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)

		WAIT WINDOW 'Scriere XML Products...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:Products>])
		IF This.oUnitate.Products				
			lnBytes = FPUTS(m.lnFileHandle, m.lcProducts)	
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:Products>])	
			
		WAIT WINDOW 'Scriere XML PhysicalStock...' NOWAIT 
		IF This.oUnitate.PhysicalStock	
			lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:PhysicalStock>])	
			lnBytes = FPUTS(m.lnFileHandle, m.lcPhysicalStock)	
			lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:PhysicalStock>])
		ENDIF 		
			
		WAIT WINDOW 'Scriere Owners...' NOWAIT 					
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:Owners>])
		IF This.oUnitate.Owners
			lnBytes = FPUTS(m.lnFileHandle, m.lcOwners)	
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:Owners>])								
							
							
		WAIT WINDOW 'Scriere XML Assets...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:Assets>])
		IF This.oUnitate.Assets
			lnBytes = FPUTS(m.lnFileHandle, m.lcAssets)	
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:Assets>])	
				
		
		Text To m.lcXMLTemp Textmerge NOSHOW		
	</nsSAFT:MasterFiles>
		ENDTEXT 		
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)		
		
		WAIT WINDOW 'Scriere XML GeneralLedgerEntries...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:GeneralLedgerEntries>])		
		IF This.oUnitate.GeneralLedgerEntries
			lnBytes = FPUTS(m.lnFileHandle, m.lcGeneralLedgerEntries )
		ENDIF 	
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:GeneralLedgerEntries>])		

		
		WAIT WINDOW 'Scriere XML SourceDocuments...' NOWAIT 
		lcXMLTemp = '<nsSAFT:SourceDocuments>'
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)		
				
		WAIT WINDOW 'Scriere XML SalesInvoices...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:SalesInvoices>])		
		lnBytes = FPUTS(m.lnFileHandle, m.lcSalesInvoices)
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:SalesInvoices>])		
		
		WAIT WINDOW 'Scriere XML PurchaseInvoices...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:PurchaseInvoices>])		
		lnBytes = FPUTS(m.lnFileHandle, m.lcPurchaseInvoices)
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:PurchaseInvoices>])	
		
		WAIT WINDOW 'Scriere XML Payments...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:Payments>])		
		lnBytes = FPUTS(m.lnFileHandle, m.lcPayments)
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:Payments>])	

		WAIT WINDOW 'Scriere XML MovementOfGoods...' NOWAIT 
		lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:MovementOfGoods>])		
		lnBytes = FPUTS(m.lnFileHandle, m.lcMovementOfGoods)
		lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:MovementOfGoods>])				

		WAIT WINDOW 'Scriere XML AssetTransactions...' NOWAIT 
		IF this.oUnitate.AssetTransactions
			lnBytes = FPUTS(m.lnFileHandle, [<nsSAFT:AssetTransactions>])		
			lnBytes = FPUTS(m.lnFileHandle, m.lcAssetTransactions)
			lnBytes = FPUTS(m.lnFileHandle, [</nsSAFT:AssetTransactions>])				
		ENDIF 	

		Text To m.lcXMLTemp Textmerge NOSHOW			
	</nsSAFT:SourceDocuments>
</nsSAFT:AuditFile>
		Endtext
		lnBytes = FPUTS(m.lnFileHandle, m.lcXMLTemp)
						
		WAIT WINDOW 'Salvare fisier XML...' NOWAIT 

		* scriu fisierul xml
		llSucces = FCLOSE(m.lnFileHandle)

		WAIT WINDOW 'Validare fisier ' + m.lcFileName NOWAIT 
				
		* validez xml
		lcComunPath = m.gcBasePath + Iif(gcAppName = "CONCONT", "COMUNCONTAFIN\", "COMUNROA\")
		lcValidator = m.lcComunPath + [dist] + IIF(m.tlTest, [406], []) + [\DUKIntegrator.jar] && ROA\COMUNROA\DIST[406]\DUKIntegrator.jar
		IF !FILE(m.lcValidator)
			open_default_app('https://static.anaf.ro/static/10/Anaf/Informatii_R/saf_t.htm')
			AMESSAGEBOX('Nu exista fisierul: "' + m.lcValidator + '"!' + CHR(13) + CHR(10) + ;
				'Pentru validare xml D406, instalati validatorul D406 in directorul: "' + JUSTPATH(m.lcValidator) + '"',0+48, _screen.Caption) 
		ELSE 
			lcConfigDir = 	m.lcComunPath + [dist] + IIF(m.tlTest, [406], []) + [\config]
			lcParams = ' -c "' + m.lcConfigDir + '" -v ' + IIF(m.tlTest, 'D406T', 'D406') + ' "' +  m.lcFileName + '" "' +  m.lcFisierRaspuns + '"' + " $ $ an=" + ALLTRIM(STR(m.lnAn2)) + " luna=" + ALLTRIM(STR(m.lnLuna2))

			_cliptext = m.lcValidator + " " + m.lcParams
				
			OPEN_DEFAULT_APP(m.lcValidator, m.lcParams)

			lnSec = 0
			DO WHILE !(File(m.lcFisierRaspuns) OR m.lnSec > 30)
				Wait Window Timeout 1 ""
				lnSec = lnSec + 1
			ENDDO 	
		
			If File(m.lcFisierRaspuns)
				IF LOWER(FILETOSTR(m.lcFisierRaspuns)) = "ok"
					AMESSAGEBOX('Validare fara erori fisier: ' + m.lcFileName,0+48,_screen.Caption)
					DELETE FILE(m.lcFisierRaspuns)
					
					* Lansare validator pentru creare PDF
				lcParams = ' "' +  m.lcFileName	+ '"'			
					OPEN_DEFAULT_APP(m.lcValidator, m.lcParams)
								
				ELSE 	
					IF AMESSAGEBOX('Validare cu erori fisier: ' + m.lcFileName + CHR(13) + CHR(10) + 'Doriti sa interogati chatbot-ul de suport tehnic?',0+4+48,_screen.Caption) = 6
						lcMessage = FILETOSTR(m.lcFisierRaspuns)
						loChatBot = CREATEOBJECT("oChatBotLaunch", m.lcMessage)
						loChatBot.Launch()
					ENDIF 
					OPEN_DEFAULT_APP(m.lcFisierRaspuns)
				ENDIF 
			ELSE
				AMESSAGEBOX('Nu s-a creat fisierul raspuns ' + m.lcFisierRaspuns + ' dupa validare!', 0+48,_screen.Caption)

				* Lansare validator pentru creare PDF
				lcParams = ' "' +  m.lcFileName	+ '"'
				OPEN_DEFAULT_APP(m.lcValidator, m.lcParams)				
			ENDIF 	
		ENDIF

		*** deschid explorer in directorul de export
		OPEN_DEFAULT_APP(m.lcCaleFisier)
		
		RETURN m.lcFileName 			
	Endproc && do_genereaza_xml

	* Rapoarte verificare

	*********************************
	* verific daca toate notele 512/531/542 si toate notele 4xx = x/ x = 4xx au cod plata		
	*********************************
	PROCEDURE do_verifica_plati
		Local lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnDif
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		* 1 = Inregistrarile tip 512/531/542 = x sau x = 512/531/542 fara Cod Plata
		* 2 = Inregistrari tip plati 40x/462/4xx = x sau x = 41x/461/4xx fara Cod Plata
		* 3 = Inregistrari cu cod plata diferit de cod plata implicit NU MAI VERIFIC - PREA MULTE FALS POZITIVE
		* 4 = Inregistrari cu cod plata, care nu reprezinta plati terti. Trebuie sters codul de plata de pe aceste note
		
		Text To m.lcSql Noshow Textmerge
select tip,
	   CAST(null as NUMBER(10)) as nrand,
       an,
       luna,
       fdoc,
       nract,
       dataact,
       partd,
       partc,
       scd,
       scc,
       suma,
       codplata,
       codplata_implicit
  from (SELECT 1             as tip,
               a.an,
               a.luna,
               a.fdoc,
               a.nract,
               a.dataact,
               partd,
               partc,
               a.scd,
               a.scc,
               a.suma,
               a.paymentname as codplata,
               a.paymentname as codplata_implicit
          FROM vact a
         WHERE a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and (SUBSTR(scd, 1, 3) in ('512', '531', '542') or
               SUBSTR(scc, 1, 3) in ('512', '531', '542')) 
               and not (SUBSTR(scd,1,3) = '581' or SUBSTR(scc,1,3) = '581')
               and not (partd like '%BANCA COMPENSARI%' or partc like '%BANCA COMPENSARI%')
           and a.paymentcode is null
        union all
        SELECT 2             as tip,
               a.an,
               a.luna,
               a.fdoc,
               a.nract,
               a.dataact,
               partd,
               partc,
               a.scd,
               a.scc,
               a.suma,
               a.paymentname as codplata,
               a.paymentname as codplata_implicit              
          FROM vact a
          join plcont p
            on a.scd = p.cont
           and p.an = a.an
           and p.acont is null
           and p.tip_sold = 'P'
           and substr(p.cont, 1, 2) in ('40', '41', '46') and p.cont <> '408'
         WHERE a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and (SUBSTR(scc, 1, 3) not in ('512', '531', '542', '581', '765'))
           and a.paymentcode is null
        union all
        SELECT 2             as tip,
               a.an,
               a.luna,
               a.fdoc,
               a.nract,
               a.dataact,
               partd,
               partc,
               a.scd,
               a.scc,
               a.suma,
               a.paymentname as codplata,
               a.paymentname as codplata_implicit
          FROM vact a
          join plcont p
            on a.scc = p.cont
           and p.an = a.an
           and p.acont is null
           and p.tip_sold = 'A'
           and substr(p.cont, 1, 2) in ('40', '41', '46') and p.cont <> '418'
         WHERE a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and (SUBSTR(scd, 1, 3) not in ('512', '531', '542', '581', '665'))
           and a.paymentcode is null)
		ENDTEXT
		
		llSucces = goExecutor.oExecuta(m.lcSql, 'cSAFTPlatiTemp2')
		If m.llSucces
			* Excludere din verificari plati
			* diferente de curs valutar, reevaluari solduri banca/casa in valuta nu trebuie declarate cu cod de plata
			DELETE FROM cSAFTPlatiTemp2 WHERE INLIST(SUBSTR(scd,1,3), '512', '531') AND scc like '765%'
			DELETE FROM cSAFTPlatiTemp2 WHERE INLIST(SUBSTR(scc,1,3), '512', '531') AND scd like '665%'

			* exclud platile din 542 pentru cheltuieli directe (ex: diurne), fara terti/furnizori
			DELETE FROM cSAFTPlatiTemp2 WHERE INLIST(SUBSTR(scc,1,3), '542') AND scd like '6%'
			
			* discount, scont, reduceri, inchidere avansuri
			DELETE FROM cSAFTPlatiTemp2 WHERE INLIST(SUBSTR(scd,1,2), '40', '46') AND INLIST(SUBSTR(scc,1,3), '609', '767', '409')
			DELETE FROM cSAFTPlatiTemp2 WHERE INLIST(SUBSTR(scc,1,2), '41', '46') AND INLIST(SUBSTR(scd,1,3), '709', '667', '419')
			
			* garantii retinute din factura. nu sunt plati
			DELETE FROM cSAFTPlatiTemp2 WHERE INLIST(SUBSTR(scc,1,3), '401', '404') AND SUBSTR(scd,1,3) = '167'
			
			* EXTRAG RANDURI FARA CONT - NU SUNT CONTURI DE TERTI SI PROBABIL NU SUNT PLATI/INCASARI CATRE TERTI
			lcLista4 = ''
			SELECT cPayments
			SCAN FOR EMPTY(NVL(cont, ''))
				SCATTER NAME loRec
				lnRand = RECNO('cPayments')

				WITH loRec
					Insert Into cSAFTPlatiTemp2 (tip, nrand, dataact, partd, suma, codplata);
						VALUES (4, m.lnRand, .dataact, .denumire, .suma, .paymentcode)
	
					lcLista4 = lcLista4 + IIF(!EMPTY(m.lcLista4), ', ', '') + ALLTRIM(STR(m.lnRand))
				ENDWITH 		
			ENDSCAN 

			     
			CALCULATE CNT() TO lnDif IN cSAFTPlatiTemp2
			IF m.lnDif > 0
				SELECT INT(tip) as tip, an, luna, nrand as rand, fdoc as fel_document, nract, TTOD(dataact) as dataact, partd, partc, scd, scc, suma, codplata, codplata_implicit FROM cSAFTPlatiTemp2 ORDER BY tip, an, luna, dataact, nract INTO CURSOR cSaftPlatiTemp

*!*					llOk = ExportExcelXml("cSAFTPlatiTemp", "plati_saft",'plati',.T.)
				goExport.export2xlsx("cSAFTPlatiTemp", "verificare_plati_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))

				USE IN (SELECT('cSAFTPlatiTemp'))   

				AMESSAGEBOX('Tip = 1 : Plati/incasari (512/531/542) care nu au completat Cod Plata SAFT (exclusiv 581, 665/765, BANCA COMPENSARI)' + CHR(13) + CHR(10) + ;
				'Tip = 2 : Plati/incasari 40x/462/4xx = x sau x = 41x/461/4xx  care nu au completat Cod Plata SAFT' + CHR(13) + CHR(10) + ;
				IIF(EMPTY(m.lcLista4), '', ;
				CHR(13) + CHR(10) + ;
				'Randurile urmatoare nu au conturi de terti dar au cod de plata in Registrul Jurnal: ' + m.lcLista4 + CHR(13) + CHR(10) + ;
				'Stergeti codul de plata daca nu sunt incasari/plati catre terti!'), 0+64, _screen.Caption)
			ELSE
				AMESSAGEBOX('Nu sunt diferente!' + CHR(13) + CHR(10) + ;
				'Tip = 1 : Plati/incasari (512/531/542) care nu au completat Cod Plata SAFT (exclusiv 581, 665/765, BANCA COMPENSARI)' + CHR(13) + CHR(10) + ;
				'Tip = 2 : Plati/incasari 40x/462/4xx = x sau x = 41x/461/4xx  care nu au completat Cod Plata SAFT', 0+64, _screen.Caption) 
			ENDIF 	
			USE IN (SELECT('cSAFTPlatiTemp2'))

		ENDIF                     
	ENDPROC && do_verifica_plati

	*********************************
	* verific daca toate notele cu explicatie TVA au cod taxa
	*********************************
	PROCEDURE do_verifica_tva
		Local lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		* 1 = Inregistrarile cu Explicatie TVA, dar fara TaxCode, inclusiv note TVA 4426/4427, fara 4428 ,exceptand Limitare deducere TVA)
		* 2 = Inregistrari cu TaxCode diferit fata de TaxCode implicit (bazat pe Explicatie TVA, data, furnizor TVAI)
		* 3 = Inregistrari 442x cu explicatie TVA baza in loc de TVA ???
		Text To m.lcSql Noshow Textmerge    
select 1              as tip,
       an,
       luna,
       nract,
       dataact,
       partd,
       partc,
       scd,
       scc,
       suma,
       explicatie_tva,
       taxname        as codtaxa,
       taxname        as codtaxa_implicit
  FROM vact a
 WHERE a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
   and NVL(a.id_jtva_coloana, 0) <> 0
   and a.taxcode is null
   and ((a.scd not in ('4428')
   and a.scc not in ('4428')) or a.id_jtva_coloana in (1001,1004,1005))
union all
SELECT b.tip,
       b.an,
       b.luna,
       b.nract,
       b.dataact,
       b.partd,
       b.partc,
       b.scd,
       b.scc,
       b.suma,
       b.explicatie_tva,
       b.taxname        as codtaxa,
       t.taxname        as codtaxa_implicit
  from (select 2 as tip,
               an,
               luna,
               nract,
               dataact,
               a.partd,
               a.partc,
               scd,
               scc,
               a.suma,
               explicatie_tva,
               taxname,
               taxcode,
               pack_saft.gettaxcode(a.an,
                                    a.luna,
                                    a.dataact,
                                    a.id_jtva_coloana,
									a.cod,
                                    nvl(a.id_partc, id_partd)) as taxcodex
          FROM vact a
         WHERE a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and NVL(a.id_jtva_coloana, 0) <> 0
           and a.taxcode is not null) b
  left join vsaft_taxtable t
    on b.taxcodex = t.taxcode
 where NVL(b.taxcode, 0) <> NVL(b.taxcodex, 0)
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cSAFTTaxaTemp2')

		If m.llSucces	
			* 3 = Inregistrari 442x cu explicatie TVA baza in loc de TVA ???		
			SELECT 3 as tip, m.gnAn as an, m.gnLuna as luna, nract, dataact, IIF(tipdc = 'D', cont, SPACE(4)) as scd, IIF(tipdc = 'C', cont, SPACE(4)) as scc, ;
				suma, explicatie_tva,taxname, taxcode ;
				FROM cGeneralLedgerEntries ;
				WHERE LEFT(cont, 3) = '442' AND taxa <> 0;
				ORDER BY dataact, nract ;
				INTO CURSOR cAct442x

			SELECT cSAFTTaxaTemp2
			APPEND FROM DBF('cAct442x')
			USE IN (SELECT('cAct442x'))
			
			IF RECCOUNT('cSAFTTaxaTemp2') > 0
				SELECT INT(tip) as tip, an, luna, nract, TTOD(dataact) as dataact, partd, partc, scd, scc, suma, explicatie_tva, codtaxa, codtaxa_implicit FROM cSAFTTaxaTemp2 ORDER BY tip, an, luna, dataact, nract INTO CURSOR cSAFTTaxaTemp

				* llOk = ExportExcelXml("cSAFTTaxaTemp", "taxa_tva_saft",'taxa',.T.)
				goExport.export2xlsx("cSAFTTaxaTemp", "verificare_taxa_tva_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))

				USE IN (SELECT('cSAFTTaxaTemp'))   

				AMESSAGEBOX('Tip = 1 : Note Reg. Jurnal - Explicatie TVA fara Cod Taxa SAFT' + CHR(13) + CHR(10) + ;
					'Tip = 2 : Note Reg. Jurnal - Cod Taxa SAFT diferit fata de Cod Taxa implicit' + CHR(13) + CHR(10) + ;
					'Tip = 3 : Note D406 - conturi TVA 442x care au suma TVA completata. Verificati Explicatia TVA in Reg. Jurnal', 0+64, _screen.Caption)
			ELSE
				AMESSAGEBOX('Nu sunt diferente!' + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
					'Tip = 1 : Note Reg. Jurnal - Explicatie TVA fara Cod Taxa SAFT' + CHR(13) + CHR(10) + ;
					'Tip = 2 : Note Reg. Jurnal - Cod Taxa SAFT diferit fata de Cod Taxa implicit' + CHR(13) + CHR(10) + ;
					'Tip = 3 : Note D406 - conturi TVA 442x care au suma TVA completata. Verificati Explicatia TVA in Reg. Jurnal', 0+64, _screen.Caption)
			ENDIF 		
			USE IN (SELECT('cSAFTTaxaTemp2'))
		ENDIF                     
	ENDPROC && do_verifica_tva


	*********************************
	* verific daca toate notele cu explicatie TVA au cod taxa
	*********************************
	PROCEDURE do_verifica_wht
		Local lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		* 1 = Inregistrarile 4423,4424,441,444,431,436,446,448, fara TaxCode
		* 2 = Inregistrari cu TaxCode diferit fata de TaxCode implicit 

		Text To m.lcSql Noshow Textmerge    
select 1              as tip,
       an,
       luna,
       nract,
       dataact,
       partd,
       partc,
       scd,
       scc,
       explicatie_tva,
       taxname        as codtaxa,
       taxname        as codtaxa_implicit
  FROM vact a
 WHERE a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
   and (a.scd in ('4423','4424') or SUBSTR(a.scd,1,3) in ('441','444','431','436','446','448')
   or a.scc in ('4423','4424') or SUBSTR(a.scc,1,3) in ('441','444','431','436','446','448'))
   and a.taxcode is null
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cSAFTTaxaTemp2')

		If m.llSucces
			IF RECCOUNT('cSAFTTaxaTemp2') > 0
				SELECT INT(tip) as tip, an, luna, nract, TTOD(dataact) as dataact, partd, partc, scd, scc, explicatie_tva, codtaxa, codtaxa_implicit FROM cSAFTTaxaTemp2 ORDER BY tip, an, luna, dataact, nract INTO CURSOR cSAFTTaxaTemp

				* llOk = ExportExcelXml("cSAFTTaxaTemp", "taxe_impozite_saft",'taxa',.T.)
				goExport.export2xlsx("cSAFTTaxaTemp", "verificare_taxe_impozite_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))

				USE IN (SELECT('cSAFTTaxaTemp'))   

				AMESSAGEBOX('Tip = 1 : Note din Registrul Jurnal (taxe si impozite) 4423,4424,441,444,431,436,446,448, care nu au completat Cod Taxa SAFT' + CHR(13) + CHR(10) + ;
					'Este obligatoriu sa aiba cod taxa notele care reprezinta impozite cu retinere la sursa', 0+64, _screen.Caption)
			ELSE
				AMESSAGEBOX('Nu sunt diferente' + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
					'Tip = 1 : Note din Registrul Jurnal (taxe si impozite) 4423,4424,441,444,431,436,446,448, care nu au completat Cod Taxa SAFT' + CHR(13) + CHR(10) + ;
					'Este obligatoriu sa aiba cod taxa notele care reprezinta impozite cu retinere la sursa', 0+64, _screen.Caption)
			ENDIF 		
			USE IN (SELECT('cSAFTTaxaTemp2'))
		ENDIF                     		
           
	ENDPROC && do_verifica_wht


	*************************************************
	* Verifica coduri fiscale cu serviciul web ANAF doar partnerii activi in perioada de raportare
	* verifica solduri cu balanta de parteneri
	*************************************************
	PROCEDURE do_verifica_cui
		LPARAMETERS tcCursor, tlSilent
		* tcCursor: cCustomers/cSuppliers

		#Define CRLF Chr(13) + Chr(10)
		
		LOCAL llSilent, lcMesaj, lcListaGol
		
		lcMesaj = ''
		
		llSilent = m.tlSilent
		
		Local lcCursor, lcSelect, lcSql, llClient, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()

		llClient = 'CUSTOMER'$Upper(Alltrim(m.tcCursor))
		lcCursor = m.tcCursor
		lcListaConturi = Iif(m.llClient, ['4111','4118','461','418', '419'], ['401','404','462','408','409'])

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
*!*			lnOptiune = XMENU('Verifica solduri; Verifica toti partenerii - ANAF')
		lnOptiune = 1
		If Empty(m.lnOptiune)
			Return
		Endif

		* Pot sa fac verificarea pentru un singur nume si cu formularul pentru mai multi parteneri, dar arata mai dragut informatia intr-un messagebox pentru unul singur
		If m.lnOptiune = 1 && verifica solduri

			* cursor solduri initiale, finale din vbalanta_parteneri
			TEXT TO m.lcSql TEXTMERGE NOSHOW 
select nvl(b1.id_part, b2.id_part) as id_part,
	NVL(b1.denumire, b2.denumire) as denumire,
    nvl(b1.cont, b2.cont) as cont,
    (case
      when b1.precdeb >= b1.preccred then
       b1.precdeb - b1.preccred
      else
       0
    end) as soldideb,
    (case
      when b1.preccred > b1.precdeb then
       b1.preccred - b1.precdeb
      else
       0
    end) as soldicred,
	(case
      when b2.solddeb >= b2.soldcred then
       b2.solddeb - b2.soldcred
      else
       0
    end) as soldfdeb,
    (case
      when b2.soldcred > b2.solddeb then
       b2.soldcred - b2.solddeb
      else
       0
    end) as soldfcred
   from (select id_part,
   				nume as denumire,
            cont,
            sum(precdeb) as precdeb,
            sum(preccred) as preccred
       from vbalanta_parteneri
      where an = <<m.lnAn1>>
        and luna = <<m.lnLuna1>>
        and cont in (<<m.lcListaConturi>>)
      group by id_part,nume,cont) b1
   full join (select id_part,
   					nume as denumire,
                cont,
			    SUM(solddeb) as solddeb,
			    SUM(soldcred) as soldcred
           from vbalanta_parteneri
          where an = <<m.lnAn2>>
            and luna = <<m.lnLuna2>>
			and cont in (<<m.lcListaConturi>>)
          group by id_part,nume,cont) b2
 on b1.id_part = b2.id_part
and b1.cont = b2.cont
			ENDTEXT 

			llSucces = goExecutor.oExecuta(m.lcSql, 'cBalPartTemp')
	
			If m.llSucces	
				SELECT NVL(a.id_part, b.id_part) as id_part, NVL(a.cont, b.cont) as cont, ;
					NVL(a.denumire, b.denumire) as denumire, ;
					IIF(m.llClient, a.soldideb - a.soldicred, a.soldicred-a.soldideb) as saft_soldi, ;
					IIF(m.llClient, a.soldfdeb - a.soldfcred, a.soldfcred-a.soldfdeb) as saft_soldf, ;
					IIF(m.llClient, b.soldideb - b.soldicred, b.soldicred-b.soldideb) as balp_soldi, ;
					IIF(m.llClient, b.soldfdeb - b.soldfcred, b.soldfcred-b.soldfdeb) as balp_soldf, ;
					IIF(m.llClient, a.soldideb - a.soldicred - (b.soldideb - b.soldicred), a.soldicred-a.soldideb - (b.soldicred-b.soldideb)) as diferenta ;
				FROM (m.lcCursor) a JOIN cBalPartTemp b ON a.id_part = b.id_part AND a.cont = b.cont ;
					WHERE NVL(a.soldideb,0) <> NVL(b.soldideb,0) OR ; 
					NVL(a.soldicred,0) <> NVL(b.soldicred,0) OR ;
					NVL(a.soldfdeb,0) <> NVL(b.soldfdeb,0) OR ;
					NVL(a.soldfcred,0) <> NVL(b.soldfcred,0) ;
					INTO CURSOR cPartDif


				* EXTRAG RANDURI FARA cod partener saft - probabil sunt persoane juridice fara cod fiscal sau persoane fizice marcate ca persoane juridice fara cod fiscal
				lcListaGol = ''
				IF m.llClient
					SELECT cCustomers
				ELSE
					SELECT cSuppliers
				ENDIF 	
				SCAN FOR !EMPTY(NVL(id_part,0)) AND EMPTY(NVL(saftpartid, ''))
					SCATTER NAME loRec
					lnRand = RECNO()
					lcListaGol = lcListaGol + IIF(!EMPTY(m.lcListaGol ), ', ', '') + ALLTRIM(STR(m.lnRand))
				ENDSCAN 					
				GO TOP 
				
				IF RECCOUNT('cPartDif') > 0
					*llOk = ExportExcelXml("cverifica_solduri", "solduri" + IIF(m.llClient, '_clienti', '_furnizori'),'solduri',.T.)
					goExport.export2xlsx("cverifica_solduri", "verificare_solduri" + IIF(m.llClient, '_clienti_', '_furnizori_') + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0') )
					
					lcMesaj = 'SOLDURI DIFERITE FATA DE BALANTA PARTENERI!'  + ;
						IIF(EMPTY(m.lcListaGol), '', CHR(13) + CHR(10) + SPACE(10) + 'Randuri cu ' + IIF(m.llClient, 'clienti', 'furnizori') + ' fara cod fiscal: ' + ALLTRIM(LEFT(m.lcListaGol, 50)))
					IF !m.llSilent
						AMESSAGEBOX(lcMesaj,0+64, _screen.Caption)
					ENDIF
					
				ELSE
					*!* lcMesaj ='Nu exista parteneri cu solduri in declaratie diferite fata de soldurile din balanta de parteneri'
					lcMesaj ='Nu sunt diferente fata de balanta parteneri' + ;
						IIF(EMPTY(m.lcListaGol), '', CHR(13) + CHR(10) + SPACE(10) + 'Randuri cu ' + IIF(m.llClient, 'clienti', 'furnizori') + ' fara cod fiscal: ' + ALLTRIM(LEFT(m.lcListaGol, 50)))
					IF !m.llSilent
						AMESSAGEBOX(lcMesaj + CHR(13) + CHR(10) + m.lcText,0+64,_screen.Caption)
					ENDIF
					
				ENDIF 							
			ENDIF 		
			USE IN (SELECT('cBalPartTemp'))
			USE IN (SELECT('cPartDif'))			
		Else
			llDontCloseCursor = .F.
			llExperimental = .F.
			llVerificarePlatitorTVA = .F. && verific VIES pentru toti partenerii
			llMFIN = .T. && verific MFIN pentru toata lumea
			llValidare = .T. && verific algoritmul codurilor fiscale
			llAutoVerificare = .T. && lanseaza verificarea automata la activate-ul formularului de verificare
			llServiciuWebANAF = .T.

			* verific is_activ = 1 (exista in JV/JC in perioada de raportare)
			lcFilter = Filter(m.tcCursor)
			lcWhere = [is_activ = 1 and (EMPTY(NVL(cod_tara,'')) OR cod_tara = 'RO') and ] + Iif(m.lnOptiune = 1, "recno() = " + Alltrim(Str(Recno())), Iif(!Empty(m.lcFilter), m.lcFilter, ".T."))
			Select Distinct id_part, cod_fiscal, denumire, Iif(Left(Upper(cod_fiscal), 2) = "RO", "RO", "  ") As ATRIBUT_FISCAL, .T. As IsCIF, .F. As codvalid ;
				From (m.tcCursor) ;
				Where &lcWhere ;
				Into Cursor crsCoduriFiscale ;
				Order By denumire, cod_fiscal  ;
				Readwrite


			Local lcXMLParteneri
			lcXMLParteneri = ""
			Cursortoxml('crsCoduriFiscale', "lcXMLParteneri", 1, 0, 0, "1")

			Do verificare_parteneri With m.lcXMLParteneri, m.llValidare, m.llMFIN, m.llVerificarePlatitorTVA, m.llAutoVerificare, m.llDontCloseCursor, m.llExperimental, m.llServiciuWebANAF

			USE IN (SELECT('crsCoduriFiscale'))
		Endif && x = 1
		
		RETURN lcMesaj
	ENDPROC && do_verifica_cui

	&& IAU SOLDURILE DIN BALANTA DE VERIFICARE PENTRU CONTURILE DE IMOBLIZARI SI AMORTIZARI
	&& SI LE COMPAR CU VALOAREA DE INVENTAR SI AMORTIZAREA TOTALA DIN IMOBILIZARI CORPORALE/NECORPORALE CONTABIL
	Procedure do_verifica_imobilizari
		LPARAMETERS tlSingleXLSX
		* tlSingleXLSX: .T. daca se exporta un singur xlsx cu toate verificarile
		
		Private pnAn, pnLuna, pcCond, pnFiscala, pnIdTipImobilizare
		Local lcSql, lnSucces, lcMesaj, lnAn, lnLuna, lnTipImobilizare, lcCondSucursala, lcBal, lcImob, lcDif
		LOCAL llSucces, llExperimental, llImobObiecteInventar, lnNrLuni1
		Local lcCursor, lcFisier, lcListaTabele, lcPath, llDiferenta, llDiferenta1, llDiferenta2
		Local llDiferenta3, llDiferenta4, lnAn1, lnAn2, lnLuna1, lnLuna2, lnPerioada, lnSoldAmortizare
		Local lnSoldInventar, lnSoldRamasBal01, lnSoldRamasBal12, lnSoldRamasImob01, lnSoldRamasImob12

		lcMesaj = ''
		llImobObiecteInventar = .F. && daca verific si contul 303 (obiecte de inventar)

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		lnNrLuni1 = m.lnAn1*12+m.lnLuna1
		
		* Verificare daca valoarea de inventar la inceputul perioadei + intrari - iesiri este diferita fata de valoare de inventar de la sfarsitul perioadei
		SELECT id_mf, accountId, assetid, description, acquisitionandproductioncostsbegin, assetaddition, transfers, assetdisposal, acquisitionandproductioncostsend, ;
				acquisitionandproductioncostsbegin + assetaddition - transfers - assetdisposal as valoareinv_final_calculat, ;
				acquisitionandproductioncostsbegin + assetaddition - transfers - assetdisposal - acquisitionandproductioncostsend as diferenta ;
			  FROM cAssets ;
			INTO CURSOR cAssetsInvDif
		
		* Solduri 2xx si 28x din balanta de verificare
		lnTipImobilizare = Iif(Type('tnTip') <> 'N', 1, Iif(Inlist(tnTip, 1, 2), tnTip, 1))
		pcCond = []
		pnFiscala = 0
		llImobObiecteInventar = (TYPE('gnIMOB_OBI') = 'N' and m.gnIMOB_OBI = 1)
		lcCondSucursala = Strtran(gcCondSucursala, "id_sucursala", "b.id_sucursala", 1, 1, 1)

		FOR lnPerioada = 1 TO 2
			IF m.lnPerioada = 1
				pnAn = m.lnAn1
				pnLuna = m.lnLuna1
				lcCursor = 'cConturiBalanta01'

				* soldurile la 1 ianuarie
				Text To lcSql Textmerge Noshow
select 1 as tip, c.cont, c.cont_amortizare,
  b.precdeb as sold
  from imob_conturi c
  left join <<Iif(glEMama,'vbalmama','vbal')>> b on c.cont = b.cont <<lcCondSucursala>> and b.an = ?pnAn and b.luna = ?pnLuna
  where c.id_tip_imobilizare in (1,2) and substr(c.cont,1,3) <> '303'
union
select 2 as tip, c.cont, c.cont_amortizare,
  b.preccred as sold
  from imob_conturi c
  left join <<Iif(glEMama,'vbalmama','vbal')>> b on c.cont_amortizare = b.cont <<lcCondSucursala>> and b.an = ?pnAn and b.luna = ?pnLuna
  where c.id_tip_imobilizare in (1,2) and substr(c.cont,1,3) <> '303'
order by 1,2
				ENDTEXT
				
				llSucces = goExecutor.oExecuta(lcSql, m.lcCursor)
				IF m.llSucces
					SELECT (m.lcCursor)
					CALCULATE SUM(sold) FOR tip = 1 TO lnSoldInventar
					
					* Contul 6811, 6812 ... apar de mai multe ori, pentru aceleasi conturi de imobilizari
					* Iau soldul doar o data
					SELECT distinct cont_amortizare, sold FROM (m.lcCursor) WHERE tip = 2 INTO CURSOR cSoldAmortizare
					SELECT cSoldAmortizare
					CALCULATE SUM(sold) TO lnSoldAmortizare
					USE IN (SELECT('cSoldAmortizare'))

					lnSoldRamasBal01 = m.lnSoldInventar - m.lnSoldAmortizare					
				ENDIF 		
	
				Select AccountId as Cont, Sum(acquisitionandproductioncostsbegin) As valinv, SUM(AccumulatedDepreciationBegin) As amorttot, SUM(bookvaluebegin) as valramas ;
					From cAssets ;
					Group By Cont ;
					Into Cursor cImobilizari01
					
				SELECT cImobilizari01
				CALCULATE SUM(valramas)	TO lnSoldRamasImob01
				
				* Diferente intre valori inventar si amortizare totala
				SELECT NVL(a.id_mf, b.id_mf) as id_mf, NVL(a.assetId, ALLTRIM(STR(b.id_tip_imobilizare)) + '_' + ALLTRIM(STR(b.nr_inventar))) as assetid, NVL(a.accountId, b.cont) as cont, NVL(a.description, b.denumire) as Denumire, ;
					a.acquisitionandproductioncostsBegin as valoare_saft, ;
					CAST(IIF(YEAR(NVL(b.data_pif, DATE()))*12+MONTH(NVL(b.data_pif, DATE())) >= m.lnNrLuni1, 0, c.valoare) as N(18,2)) as valoare_imobilizari, ;
					NVL(a.acquisitionandproductioncostsBegin, 0) - NVL(c.valoare, 0) as DiferentaValoareInventar, ;
					a.AccumulatedDepreciationBegin as amortizare_saft, ;
					b.amort_prec as amortizare_imobilizari, ;
					(NVL(a.AccumulatedDepreciationBegin, 0)) - NVL(b.amort_prec,0) as DiferentaAmortizare, ;
					NVL(b.iesit_din_gest, 0) as iesit_din_gestiune ;					
					FROM cAssets a FULL JOIN cAssets01 b ON a.id_mf = b.id_mf ;
					FULL JOIN cAssets00 c ON a.id_mf = c.id_mf ;
					ORDER BY 2 ;
					INTO CURSOR cVerValoriImob01 READWRITE 

					UPDATE cVerValoriImob01 SET DiferentaValoareInventar = valoare_Saft - valoare_imobilizari
									
			ELSE 
				pnAn = m.lnAn2
				pnLuna = m.lnLuna2
				lcCursor = 'cConturiBalanta12'

				* soldurile la 31 decembrie
				Text To lcSql Textmerge Noshow
select 1 as tip, c.cont, c.cont_amortizare,
  b.solddeb as sold
  from imob_conturi c
  left join <<Iif(glEMama,'vbalmama','vbal')>> b on c.cont = b.cont <<lcCondSucursala>> and b.an = ?pnAn and b.luna = ?pnLuna
  where c.id_tip_imobilizare in (1,2) and substr(c.cont,1,3) <> '303'
union
select 2 as tip, c.cont, c.cont_amortizare,
  b.soldcred as sold
  from imob_conturi c
  left join <<Iif(glEMama,'vbalmama','vbal')>> b on c.cont_amortizare = b.cont <<lcCondSucursala>> and b.an = ?pnAn and b.luna = ?pnLuna
  where c.id_tip_imobilizare in (1,2) and substr(c.cont,1,3) <> '303'
order by 1,2
				ENDTEXT
				
				llSucces = goExecutor.oExecuta(lcSql, m.lcCursor)

				IF m.llSucces
					SELECT (m.lcCursor)
					CALCULATE SUM(sold) FOR tip = 1 TO lnSoldInventar
					
					* Contul 6811, 6812 ... apar de mai multe ori, pentru aceleasi conturi de imobilizari
					* Iau soldul doar o data
					SELECT distinct cont_amortizare, sold FROM (m.lcCursor) WHERE tip = 2 INTO CURSOR cSoldAmortizare
					SELECT cSoldAmortizare
					CALCULATE SUM(sold) TO lnSoldAmortizare
					USE IN (SELECT('cSoldAmortizare'))
					
					lnSoldRamasBal12 = m.lnSoldInventar - m.lnSoldAmortizare					
				ENDIF 			
				
				* Nu iau amortizarea totala	pentru imobilizarile iesite din gestiune. In balanta soldul creditor 28x nu include amortizarea pentru imobilizarile iesite din gestiune
				Select a.AccountId, a.acquisitionandproductioncostsend, a.AppreciationForPeriod, a.AppreciationForPeriodMinus, ;
					CAST(IIF(NVL(b.iesit_din_gest,0) = 0, a.AccumulatedDepreciation, 0) as N(18,4)) as AccumulatedDepreciation, ;
					CAST(IIF(NVL(b.iesit_din_gest,0) = 0, a.bookvalueend, 0) as N(18,4)) as bookvalueend ;
					From cAssets a FULL JOIN cAssets12 b ON a.id_mf = b.id_mf ;
					Into Cursor cImobilizari12Temp

				Select AccountId as Cont, Sum(NVL(acquisitionandproductioncostsend,0) + NVL(AppreciationForPeriod, 0) - NVL(AppreciationForPeriodMinus, 0)) As valinv, SUM(AccumulatedDepreciation) As amorttot, SUM(bookvalueend) as valramas ;
					From cImobilizari12Temp ;
					Group By Cont ;
					Into Cursor cImobilizari12
				
				USE IN (SELECT('cImobilizari12Temp'))	


				SELECT cImobilizari12	
				CALCULATE SUM(valramas)	TO lnSoldRamasImob12

				* Diferente intre valori inventar si amortizare totala
				SELECT NVL(a.id_mf, b.id_mf) as id_mf, NVL(a.assetId, ALLTRIM(STR(b.id_tip_imobilizare)) + '_' + ALLTRIM(STR(b.nr_inventar))) as assetid, NVL(a.accountId, b.cont) as cont, NVL(a.description, b.denumire) as Denumire, ;
					NVL(a.acquisitionandproductioncostsEnd,0) + NVL(a.AppreciationForPeriod, 0) - NVL(a.AppreciationForPeriodMinus, 0) as valoare_saft, CAST(IIF(b.iesit_din_gest = 0, b.valoare, 0) as N(18,4)) as valoare_imobilizari, ;
					NVL(a.acquisitionandproductioncostsEnd,0) + NVL(a.AppreciationForPeriod, 0) - NVL(a.AppreciationForPeriodMinus, 0) - NVL(IIF(b.iesit_din_gest = 0, b.valoare, 0), 0) as DiferentaValoareInventar, ;
					a.AccumulatedDepreciation as amortizare_saft, b.amort_prec+b.rata as amortizare_imobilizari, NVL(a.AccumulatedDepreciation, 0) - (NVL(b.amort_prec,0) + NVL(b.rata,0)) as DiferentaAmortizare, ;
					NVL(b.iesit_din_gest, 0) as iesit_din_gestiune ;					
					FROM cAssets a FULL JOIN cAssets12 b ON a.id_mf = b.id_mf ;
					ORDER BY 2 ;
					INTO CURSOR cVerValoriImob12
				
			ENDIF 

			If !m.llSucces 
				EXIT 
			ENDIF
		ENDFOR 	

		If m.llSucces
			&& V.TIP: 1 = CONTURI IMOBILIZARI; 2 = CONTURI AMORTIZARI
			Select v.tip, v.Cont, Nvl(v.sold, Cast(0 As N(18, 4))) As bal_valoare, Nvl(i.valinv, Cast(0 As N(18, 4))) As imob_valoare;
				From cConturiBalanta01 v Full Join cImobilizari01 i On ALLTRIM(v.Cont) == ALLTRIM(i.Cont) ;
				Where v.tip = 1 ;
				Union ;
				Select v.tip, v.cont_amortizare As Cont, Nvl(v.sold, Cast(0 As N(18, 4))) As bal_valoare, Sum(Nvl(i.amorttot, Cast(0 As N(18, 4)))) As imob_valoare ;
				From cConturiBalanta01 v Full Join cImobilizari01 i On ALLTRIM(v.Cont) == ALLTRIM(i.Cont) ;
				Where v.tip = 2 ;
				Group By v.tip, v.cont_amortizare, v.sold ;
				Order By 1, 2 ;
				Into Cursor cVerificareImob01

			&& V.TIP: 1 = CONTURI IMOBILIZARI; 2 = CONTURI AMORTIZARI
			Select v.tip, v.Cont, Nvl(v.sold, Cast(0 As N(18, 4))) As bal_valoare, Nvl(i.valinv, Cast(0 As N(18, 4))) As imob_valoare;
				From cConturiBalanta12 v Full Join cImobilizari12 i On ALLTRIM(v.Cont) == ALLTRIM(i.Cont) ;
				Where v.tip = 1 ;
				Union ;
				Select v.tip, v.cont_amortizare As Cont, Nvl(v.sold, Cast(0 As N(18, 4))) As bal_valoare, Sum(Nvl(i.amorttot, Cast(0 As N(18, 4)))) As imob_valoare ;
				From cConturiBalanta12 v Full Join cImobilizari12 i On ALLTRIM(v.Cont) == ALLTRIM(i.Cont) ;
				Where v.tip = 2 ;
				Group By v.tip, v.cont_amortizare, v.sold ;
				Order By 1, 2 ;
				Into Cursor cVerificareImob12

				
			Use In (Select('cConturiBalanta01'))
			Use In (Select('cConturiBalanta12'))			
			Use In (Select('cImobilizari01'))
			Use In (Select('cImobilizari12'))

				
			* Diferente valori inventar, amortizare totala global SAFT fata de Balanta
			SELECT '1. Valoare inventar la inceputul perioadei' as ctip, cont, imob_valoare as saft, bal_valoare as balanta, imob_valoare - bal_valoare as diferenta ;
				FROM cVerificareImob01 ;
				WHERE tip = 1 AND (imob_valoare <> 0 OR bal_valoare <> 0) ;
			UNION ;
			SELECT '2. Amortizare totala la inceputul perioadei' as tip, cont, imob_valoare as saft, bal_valoare as balanta, imob_valoare - bal_valoare as diferenta ;
				FROM cVerificareImob01 ;
				WHERE tip = 2 AND (imob_valoare <> 0 OR bal_valoare <> 0)   ;
			UNION ;
			SELECT '3. Valoare inventar la sfarsitul perioadei' as tip, cont, imob_valoare as saft, bal_valoare as balanta, imob_valoare - bal_valoare as diferenta ;
				FROM cVerificareImob12 ;
				WHERE tip = 1 AND (imob_valoare <> 0 OR bal_valoare <> 0)  ;
			UNION ;
			SELECT '4. Amortizare totala la sfarsitul perioadei' as tip, cont, imob_valoare as saft, bal_valoare as balanta, imob_valoare - bal_valoare as diferenta ;
				FROM cVerificareImob12 ;
				WHERE tip = 2   AND (imob_valoare <> 0 OR bal_valoare <> 0) ;
			UNION ;
			SELECT '5. Valoare ramasa de amortizat la inceputul perioadei' as tip, SPACE(20) as cont, m.lnSoldRamasImob01 as saft, m.lnSoldRamasBal01 as balanta, m.lnSoldRamasImob01 - m.lnSoldRamasBal01 as diferenta ;
				FROM dual ;
			UNION ;	
			SELECT '6. Valoare ramasa de amortizat la sfarsitul perioadei' as tip, SPACE(20) as cont, m.lnSoldRamasImob12 as saft, m.lnSoldRamasBal12 as balanta, m.lnSoldRamasImob12 - m.lnSoldRamasBal12 as diferenta ;
				FROM dual ;
			ORDER BY 1, 2 ;	
			INTO CURSOR cAssetsDif

			Use In (Select('cVerificareImob01'))
			Use In (Select('cVerificareImob12'))			

			* Diferente valoare inventar, amortizare totala pe fiecare imobilizare SAFT fata de ROAIMOB
			SELECT '1. Valoare inventar la inceputul perioadei' as ctip, id_mf, AssetId, cont, Denumire, ;
					valoare_saft as saft, valoare_imobilizari as imobilizari, DiferentaValoareInventar as diferenta, iesit_din_gestiune ;
					FROM cVerValoriImob01 ;
			UNION ;
			select '2. Amortizare totala la inceputul perioadei' as ctip, id_mf, AssetId, cont, Denumire, ;		
					amortizare_saft as saft, amortizare_imobilizari as imobilizari, DiferentaAmortizare as diferenta, iesit_din_gestiune ;
					FROM cVerValoriImob01 ;
			UNION ;
			SELECT '3. Valoare inventar la sfarsitul perioadei' as ctip, id_mf, AssetId, cont, Denumire, ;
					valoare_saft as saft, valoare_imobilizari as imobilizari, DiferentaValoareInventar as diferenta, iesit_din_gestiune ;
					FROM cVerValoriImob12 ;
			UNION ;
			select '4. Amortizare totala la sfarsitul perioadei' as ctip, id_mf, AssetId, cont, Denumire, ;		
					amortizare_saft as saft, amortizare_imobilizari as imobilizari, DiferentaAmortizare as diferenta, iesit_din_gestiune ;
					FROM cVerValoriImob12 ;
			ORDER BY 1, 3 ;		
			INTO CURSOR cValoriImobDif
			
			USE IN (SELECT('cVerValoriImob01'))
			USE IN (SELECT('cVerValoriImob12'))
						
			* Verificare AssetTransactions				
			SELECT id_mf, denumire, ;
				SUM(AcquisitionAndProductionCostsOnTransaction) as AcquisitionAndProductionCosts, ;
				CAST(SUM(IIF(ALLTRIM(AssetTransactionType) = '30',BookValueOnTransaction, 0)) as N(18,4)) as amortizare, ;
				CAST(SUM(IIF(ALLTRIM(AssetTransactionType) = '10',BookValueOnTransaction, 0)) as N(18,4)) as intrare, ;
				CAST(SUM(IIF(INLIST(ALLTRIM(AssetTransactionType), '20', '40', '50'), BookValueOnTransaction, 0)) as N(18,4)) as iesire, ;
				CAST(SUM(IIF(ALLTRIM(AssetTransactionType) = '60',BookValueOnTransaction, 0)) as N(18,4)) as reevaluarenegativa, ;												
				CAST(SUM(IIF(ALLTRIM(AssetTransactionType) = '70',BookValueOnTransaction, 0)) as N(18,4)) as reevaluarepozitiva, ;						
				CAST(SUM(IIF(ALLTRIM(AssetTransactionType) = '130',BookValueOnTransaction, 0)) as N(18,4)) as altele ;										
				FROM cAssetTransactions ;
				GROUP BY id_mf, denumire ;
				INTO CURSOR cAssetTransactionsCum
			
			SELECT NVL(a.id_mf, b.id_mf) as id_mf, a.AssetId, NVL(a.description, b.denumire) as denumire, a.accountid as cont,;
				a.AssetAddition as aAssetAddition, b.intrare + b.altele as bAssetAddition, ;
				CAST(IIF(a.AssetDisposal <> 0, a.AssetDisposal - a.AccumulatedDepreciation, 0.00) as N(18,4)) as aAssetDisposal, b.iesire as bAssetDisposal, ;
				a.DepreciationForPeriod as aDepreciationForPeriod, b.amortizare as bDepreciationForPeriod, ;
				a.AppreciationForPeriod as aAppreciationForPeriod, b.reevaluarepozitiva as bAppreciationForPeriod ;
				FROM cAssets a JOIN cAssetTransactionsCum b ON a.id_mf = b.id_mf ;
				INTO CURSOR cAssetTransactionsDifTemp

			USE IN (SELECT('cAssetTransactionsCum'))	

			SELECT id_mf, AssetId, denumire, cont, ;
				'1. Intrari incl. majorari' as tip, aAssetAddition as saft_assets, bAssetAddition as saft_transactions, aAssetAddition - bAssetAddition as diferenta ;
				FROM cAssetTransactionsDifTemp ;
			UNION ;
			SELECT id_mf, AssetId, denumire, cont, ;			
				'2. Iesiri (valoare neta)' as tip, aAssetDisposal as saft_assets, bAssetDisposal as saft_transactions, aAssetDisposal - bAssetDisposal as diferenta ;
				FROM cAssetTransactionsDifTemp ;
			UNION ;
			SELECT id_mf, AssetId, denumire, cont, ;
				'3. Depreciere/Amortizare' as tip, aDepreciationForPeriod as saft_assets, bDepreciationForPeriod as saft_transactions, aDepreciationForPeriod - bDepreciationForPeriod as diferenta ;
				FROM cAssetTransactionsDifTemp ;
			UNION ;
			SELECT id_mf, AssetId, denumire, cont, ;
				'4. Apreciere/Reevaluare' as tip, aAppreciationForPeriod as saft_assets, bAppreciationForPeriod as saft_transactions, aAppreciationForPeriod - bAppreciationForPeriod as diferenta ;
				FROM cAssetTransactionsDifTemp ;
			ORDER BY 4, 2 ;
			INTO CURSOR cAssetTransactionsDif

			USE IN (SELECT('cAssetTransactionsDifTemp'))			
			llDiferenta = .F.
			llDiferenta1 = .F.
			llDiferenta2 = .F.
			llDiferenta3 = .F.
			llDiferenta4 = .F.
			SELECT cAssetsInvDif
			LOCATE FOR diferenta <> 0
			llDiferenta = FOUND()
			llDiferenta1 = FOUND()
			IF !m.llDiferenta
				SELECT cAssetsDif
				LOCATE FOR diferenta <> 0
				llDiferenta = FOUND()
				llDiferenta2 = FOUND()
			ENDIF 
			IF !m.llDiferenta
				SELECT cValoriImobDif
				LOCATE FOR diferenta <> 0
				llDiferenta = FOUND()
				llDiferenta3 = FOUND()
			ENDIF 
			IF !m.llDiferenta
				SELECT cAssetTransactionsDif
				LOCATE FOR diferenta <> 0
				llDiferenta = FOUND()
				llDiferenta4 = FOUND()
			ENDIF 
				
			IF m.tlSingleXLSX
				lcListaTabele = "cAssetsInvDif,cAssetsDif,cValoriImobDif,cAssetTransactionsDif"
				goExport.exportMultiTable2Xlsx(m.lcListaTabele, "verificare_assets_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)))				
			ELSE
			SET STEP ON 
				lcFisier = "verificare_assets1_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + '.xlsx'
				lcFisier = Putfile('Nume fisier:', m.lcFisier, 'xlsx')
				lcPath = ADDBS(JUSTPATH(m.lcFisier))	
				IF !EMPTY(m.lcFisier)
					goExport.export2xlsx("cAssetsInvDif", m.lcFisier)

					lcFisier = m.lcPath + "verificare_assets2_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + '.xlsx'
					goExport.export2xlsx("cAssetsDif", m.lcFisier)

					lcFisier = m.lcPath + "verificare_assets3_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + '.xlsx'
					goExport.export2xlsx("cValoriImobDif", m.lcFisier)
					
					lcFisier = m.lcPath + "verificare_assets4_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + '.xlsx'
					goExport.export2xlsx("cAssetTransactionsDif", m.lcFisier)

					open_default_app(m.lcPath)
				ENDIF 
			ENDIF 

			AMESSAGEBOX('A. ' + IIF(m.llDiferenta1, '', 'NU EXISTA ') + 'Diferente intre valoare inventar finala SAFT si valoare inventar initiala SAFT + intrari - iesiri' + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
				'B. ' + IIF(m.llDiferenta2, '', 'NU EXISTA ') + 'Diferente intre valorile Imobilizari SAFT si Balanta de verificare 2xx/28x' + CHR(13) + CHR(10) + ;
				'	1. Valoare inventar la inceputul perioadei' + CHR(13) + CHR(10) + ;
				'	2. Amortizare totala la inceputul perioadei' + CHR(13) + CHR(10) + ;
				'	3. Valoare inventar la sfarsitul perioadei' + CHR(13) + CHR(10) + ;
				'	4. Amortizare totala la sfarsitul perioadei' + CHR(13) + CHR(10) + ;
				'	5. Valoare ramasa de amortizat la inceputul perioadei' + CHR(13) + CHR(10) + ;
				'	6. Valoare ramasa de amortizat la sfarsitul perioadei' + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
				'C. ' + IIF(m.llDiferenta3, '', 'NU EXISTA ') + 'Diferente intre valoare inventar, amortizare SAFT si Registrul de imobilizari' + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;				
				'D. ' + IIF(m.llDiferenta4, '', 'NU EXISTA ') + 'Diferente intre Imobilizari SAFT si Tranzactii imobilizari SAFT' + CHR(13) + CHR(10) + ;
				'	1. Intrari' + CHR(13) + CHR(10) + ;
				'	2. Iesiri (valoare neta)' + CHR(13) + CHR(10) + ;					
				'	3. Depreciere/Amortizare' + CHR(13) + CHR(10) + ;
				'	4. Apreciere/Reevaluare', 0+64, _screen.Caption)

		ENDIF && llSucces		

		USE IN (SELECT('cAssetsDif'))
		USE IN (SELECT('cAssetsInvDif'))
		USE IN (SELECT('cValoriImobDif'))		
		USE IN (SELECT('cAssetTransactionsDif'))		
	Endproc && do_verifica_imobilizari


	*********************************
	* verific soldurile din GeneralLedgerAccounts cu soldurile din Balanta de Verificare, Registru jurnal, Clienti si Furnizori
	*********************************
	PROCEDURE do_verifica_solduri
		LPARAMETERS tlLunar
		
		LOCAL lcMesaj, lcMesajTotal, llSilent
		llSilent = .T. && apelare verificari silentios
		
		lcMesajTotal = ''
		lcMesaj = This.do_verifica_balanta(m.llSilent)
		lcMesajTotal = m.lcMesajTotal + '       1. ' + m.lcMesaj + CHR(13) + CHR(10) + CHR(13) + CHR(10)

		IF m.tlLunar
			* SAFT lunar/trimestrial se verifica solduri balanta, clienti, furnizori pe perioada
			* SAFT anual/cerere - se verifica doar solduri balanta pe perioada
			lcMesaj = This.do_verifica_jurnal(m.llSilent)
			lcMesajTotal = m.lcMesajTotal + '       2. '+ m.lcMesaj + CHR(13) + CHR(10) + CHR(13) + CHR(10)
			
			lcMesaj = This.do_verifica_cui('ccustomers', m.llSilent)  && verificare clienti
			lcMesajTotal = m.lcMesajTotal + '       3. Clienti: '+ m.lcMesaj + CHR(13) + CHR(10) + CHR(13) + CHR(10)
			
			lcMesaj = This.do_verifica_cui('csuppliers', m.llSilent) && verificare furnizori
			lcMesajTotal = m.lcMesajTotal + '       4. Furnizori: '+ m.lcMesaj + CHR(13) + CHR(10) + CHR(13) + CHR(10)
		ENDIF && m.tlLunar
		
		AMESSAGEBOX(lcMesajTotal)
		
	ENDPROC && do_verifica_solduri

		
	*********************************
	* verific soldurile din GeneralLedgerAccounts cu soldurile din Balanta de Verificare
	*********************************
	PROCEDURE do_verifica_balanta
		LPARAMETERS tlSilent
		
		* tlSilent (optional) : .T. = nu arata mesaje cu/fara diferente ci intoarce mesajul la procedura apelanta
		
		
		Local lcSelect, lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnDif, lcDif, lnTip, lcText, llNuContAlternativ
		LOCAL llSilent, lcMesaj
		
		lcMesaj = ''
		
		llSilent = m.tlSilent
		lcSelect = SELECT()
		
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		* Creez cursor balanta de verificare
		llNuContAlternativ = .T.
		Do make_tbalanta With .F., m.lnLuna1, m.lnAn1, m.lnLuna2, m.lnAn2, "bal", m.llNuContAlternativ

		&& BNIVEL  IN (4,6) : TOTALURI PE CONTURI SINTETICE - 4 = SUCURSALA/FIRMA INDEPENDENTA; 6 = CENTRALIZATA
		SELECT cont, SUM(precdeb) as precdeb, ;
			SUM(preccred) as preccred,;
			SUM(solddeb) as solddeb, ;
			SUM(soldcred) as soldcred ;
			FROM tBalanta ;
			WHERE (bnivel = 6 AND m.glEmama) OR (bnivel = 4 AND !m.glEmama) ;
			GROUP BY cont ;
			INTO CURSOR cBalantaTemp1


		SELECT cont, ;
			SUM(iif(precdeb>=preccred, abs(precdeb-preccred), 0.00)) as soldideb,;
			SUM(iif(precdeb<preccred, abs(precdeb-preccred),0.00)) as soldicred,;
			SUM(iif(solddeb>=soldcred, abs(solddeb-soldcred), 0.00)) as soldfdeb,;
			SUM(iif(solddeb<soldcred, abs(solddeb-soldcred),0.00)) as soldfcred;
			FROM cBalantaTemp1 ;
			GROUP BY cont ;
			INTO CURSOR cBalantaTemp


		SELECT NVL(b1.cont, b2.cont) as cont, ;
			NVL(b1.soldideb, 0.00) - NVL(b2.soldideb, 0.00) as soldidebd,;
			NVL(b1.soldicred, 0.00) - NVL(b2.soldicred, 0.00) as soldicredd,;
			NVL(b1.soldfdeb, 0.00) - NVL(b2.soldfdeb, 0.00) as soldfdebd,;
			NVL(b1.soldfcred, 0.00) - NVL(b2.soldfcred, 0.00) as soldfcredd ;
		FROM cGeneralLedgerAccounts b1 FULL JOIN cBalantaTemp b2 ON ALLTRIM(NVL(b1.cont,'')) == ALLTRIM(NVL(b2.cont,'')) ;
		INTO CURSOR cBalantaDiferente1

				
		SELECT cont, soldidebd, soldicredd, soldfdebd, soldfcredd ;
		FROM cBalantaDiferente1 ;
		WHERE soldidebd <> 0 OR soldicredd <> 0 OR soldfdebd <> 0 OR soldfcredd <> 0 ;
		ORDER BY cont ;
		INTO CURSOR cBalantaDiferente
		
		
		
		IF RECCOUNT('cBalantaDiferente') = 0	
			lcMesaj = 'Balanta de verificare: Nu sunt diferente'
			IF !m.llSilent
				AMESSAGEBOX(m.lcMesaj, 0+64, _screen.Caption)
			ENDIF 
		ELSE 	
			lcText = ''
			Select cBalantaDiferente
			SCAN
				lcCont = SPACE(20) + 'Cont: ' + PADR(ALLTRIM(NVL(cont,'')), 4, ' ')
				FOR lnTip = 1 TO 4
					DO CASE 
						CASE lnTip = 1
							lnDif = soldidebd
							lcDif = 'sold initial debit'
						CASE lnTip = 2
							lnDif = soldicredd
							lcDif = 'sold initial credit'
						CASE lnTip = 3
							lnDif = soldfdebd
							lcDif = 'sold final debit'							
						CASE lnTip = 4
							lnDif = soldfcredd
							lcDif = 'sold final credit'							
					ENDCASE 
					IF m.lnDif = 0 
						LOOP 
					ENDIF 

					lcText = m.lcText + m.lcCont + ' diferenta ' + m.lcDif + ' ' + ALLTRIM(TRANSFORM(m.lnDif,'999 999 999 999.99')) + CHR(13) + CHR(10)
				ENDFOR 
			ENDSCAN && cBalantaDiferente
			
			lcMesaj = 'Balanta de verificare: EXISTA DIFERENTE!' + CHR(13) + CHR(10) + m.lcText
			
			IF !m.llSilent
			   AMESSAGEBOX(lcMesaj,0+64,_screen.Caption)
			ENDIF
			
		ENDIF  && reccount
		
		USE IN (SELECT('tBalanta'))
		USE IN (SELECT('cBalantaTemp1'))
		USE IN (SELECT('cBalantaTemp'))
		USE IN (SELECT('cBalantaDiferente1'))
		USE IN (SELECT('cBalantaDiferente'))	

		SELECT (m.lcSelect)
		
		RETURN lcMesaj
	ENDPROC && do_verifica_balanta	

	*********************************
	* verific rulajele din GeneralLedgerEntries cu rulajele din Registrul Jurnal
	*********************************
	PROCEDURE do_verifica_jurnal
		
		LPARAMETERS tlSilent
		
		Local lcSelect, lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnDif, lcDif, lnTip, lcText, llNuContAlternativ
		
		LOCAL llSilent, lcMesaj
		
		lcMesaj = ''
		
		llSilent = m.tlSilent

		lcSelect = SELECT()
		
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
				
		SELECT cont, tipdc, SUM(suma) as suma, SUM(suma_val) as suma_val ;
			FROM cGeneralLedgerEntries ;
			GROUP BY cont, tipdc ;
			INTO CURSOR cGeneralLedgerEntriesTemp
			
		TEXT TO lcSql TEXTMERGE NOSHOW 
select scd as cont, 'D' as tipdc, SUM(suma) as suma, SUM(suma_val) as suma_val
  FROM act
 WHERE sters = 0 and an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
 and TO_NUMBER(SUBSTR(scd, 1, 1)) <= 7
 Group by scd
union  
select scc as cont, 'C' as tipdc, SUM(suma) as suma, SUM(suma_val) as suma_val
  FROM act
 WHERE sters = 0 and an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
 and TO_NUMBER(SUBSTR(scc, 1, 1)) <= 7
 Group by scc
		ENDTEXT 

		llSucces = goExecutor.oExecuta(m.lcSql, 'cActTemp')

		If m.llSucces		
			SELECT NVL(a1.cont, a2.cont) as cont, NVL(a1.tipdc, a2.tipdc) as tipdc, ;
				NVL(a1.suma, 0.00) - NVL(a2.suma, 0.00) as sumad,;
				NVL(a1.suma_val, 0.00) - NVL(a2.suma_val, 0.00) as suma_vald ;
				FROM cGeneralLedgerEntriesTemp a1 FULL JOIN cActTemp a2 ON ALLTRIM(NVL(a1.cont,'')) == ALLTRIM(NVL(a2.cont,''))  AND a1.tipdc = a2.tipdc ;
				ORDER BY 1, 2 ;
			INTO CURSOR cActDiferente1
			
			SELECT * FROM cActDiferente1 WHERE sumad <> 0 OR suma_vald <> 0 INTO CURSOR cActDiferente
			
			IF RECCOUNT('cActDiferente') = 0
				lcMesaj = 'Registru jurnal: Nu sunt diferente'
				IF !m.llSilent
					AMESSAGEBOX(0+64,_screen.Caption)
				ENDIF
				
			ELSE 	
				lcText = ''
				Select cActDiferente
				SCAN
					lcCont = 'Cont: ' + PADR(ALLTRIM(NVL(cont,'')), 4, ' ')
					lcTipDC = ALLTRIM(tipdc)
					FOR lnTip = 1 TO 2
						DO CASE 
							CASE lnTip = 1
								lnDif = sumad
								lcDif = 'lei'
							CASE lnTip = 2
								lnDif = suma_vald
								lcDif = 'valuta'
						ENDCASE 
						IF m.lnDif = 0 
							LOOP 
						ENDIF 

						lcText = m.lcText + m.lcCont + ' ' + m.lcTipDC + ' diferenta ' + m.lcDif + ' ' + TRANSFORM(m.lnDif,'999 999 999 999.99') + CHR(13) + CHR(10)
					ENDFOR 
				ENDSCAN && cActDiferente
				
				lcMesaj = 'Registrul Jurnal: EXISTA DIFERENTE!' + CHR(13) + CHR(10) + m.lcText
				IF !m.llSilent
					AMESSAGEBOX(lcMesaj,0+64,_screen.Caption)
				ENDIF
				
			ENDIF  && reccount
		ENDIF && llSucces
		
		USE IN (SELECT('cGeneralLedgerEntriesTemp'))
		USE IN (SELECT('cActTemp'))
		USE IN (SELECT('cActDiferente1'))
		USE IN (SELECT('cActDiferente'))

		SELECT (m.lcSelect)
		
		RETURN lcMesaj
	ENDPROC && do_verifica_jurnal

	*********************************
	* verific suma valorilor de pe articolele din facturi cu valoarea facturii din Jurnalele TVA
	* verific daca exista articole facturi fara taxcode
	*********************************
	PROCEDURE do_verifica_facturi
		Lparameters tcTip
		* tcTip: customers/suppliers

		Local lcSelect, lcText, lcJurnalTVA, lcExceptie
		Local lcCursor, lcCursorDup, lcCursorLines, lcSql, llClient, llSucces, lnAn1, lnAn2, lnLuna1
		Local lnLuna2, lnSuma, loFact, loRec

		lcText = ''
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		llClient = (Upper(Alltrim(m.tcTip)) = 'CUSTOMERS')
		lcCursor = Iif(m.llClient, 'cSalesInvoices', 'cPurchaseInvoices')
		lcCursorDup = Iif(m.llClient, 'cSalesInvoicesDup', 'cPurchaseInvoicesDup')
		lcJurnalTVA = Iif(m.llClient, 'jv2007', 'jc2007')		
		lcExceptie = Iif(m.llClient, 'a.scc = cont AND a.scd = cont_c', 'a.scd = cont AND a.scc = cont_c')				
		lcCursorLines = Iif(m.llClient, 'cSalesInvoicesLines', 'cPurchaseInvoicesLines')	

		CREATE CURSOR cverifica_facturi_saft (tip N(1), an N(4), luna N(2), nract N(20) null, dataact D null, denumire C(70) null, ;
			valoare_totala_factura N(20,2) null, valoare_totala_jurnal_tva N(20,2) null, diferenta_valoare_totala N(20,2) null, ;
			taxcode N(6) null, valoare_taxcode_factura N(20,2) null, valoare_taxcode_regjurnal N(20,2) NULL, diferenta_valoare_taxcode N(20,2) null)

		* Diferente valoare factura - valoare jurnal TVA > 0.5
		* taxa = valoarea taxei	(cantitate * pret * proc_tva/100)
		* Tratez facturile de achizitie de import , nu adun taxa, pentru ca taxa este platita la Biroul Vamal si apare separat de factura, pe DVI (taxcode = 301201, 301202, 301203)
		SELECT a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, a.totctva, ;
			SUM(b.cantitate * b.pret + IIF(!INLIST(b.taxcode, 301201, 301202, 301203), b.taxa, 0)) as valctva, SUM(IIF(EMPTY(NVL(b.taxcode,0)), 1, 0)) as ntaxcode ;
			FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
			GROUP BY a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, a.totctva ;
			INTO CURSOR cFacturiDiferente1

		SELECT an, luna, id_fact, nract, dataact, id_part, denumire, totctva, valctva, totctva-valctva as diferenta, ntaxcode ;
			FROM cFacturiDiferente1 ;
			WHERE ABS(totctva - valctva) > 0.5 ;
			ORDER BY an, luna, dataact, nract, denumire ;
			INTO CURSOR cFacturiDiferente

		INSERT INTO cverifica_facturi_saft(tip, an, luna, nract, dataact, denumire, valoare_totala_factura, valoare_totala_jurnal_tva, diferenta_valoare_totala)	;
			SELECT 1 as tip, an, luna, nract, dataact, denumire, NVL(valctva,0), NVL(totctva,0), NVL(diferenta,0) ;
				FROM cFacturiDiferente ;
				order by an, luna, dataact, nract
				

		* Diferente valori pe fiecare taxcode facturi.Taxcode = registrul jurnal.taxcode
		SELECT a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, ;
			SUM(b.cantitate * b.pret) as valoare, ;
			SUM(b.cantitate * b.pretv) as valoarev ;			
			FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
			GROUP BY a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode ;
			order by a.an, a.luna, a.dataact, a.nract ;
			INTO CURSOR cFacturiTaxCode1

		   			
		* suma din Registrul Jurnal fara TVA
		* tratez regularizare facturi nesosite/neintocmite 408=401, 4111=418
		TEXT TO lcSql TEXTMERGE NOSHOW 
select id_fact,
       taxcode,
       sum(decode(exceptie, 1, -1, 1) * suma) as suma,
       sum(decode(exceptie, 1, -1, 1) * suma_val) as suma_val
  from (select a.id_fact,
               (CASE when (a.scd = '408' AND a.scc like '4%') or (a.scd like '4%' AND a.scc = '418') then ROUND(a.suma * 100 / (100 + st.procent_taxa), 2) else a.suma end) as suma,
			   (CASE when (a.scd = '408' AND a.scc like '4%') or (a.scd like '4%' AND a.scc = '418')  then ROUND(a.suma_val * 100 / (100 + st.procent_taxa), 2) else a.suma_val end) as suma_val,                             
               a.taxcode,
               (SELECT DISTINCT 1 AS EXCEPTIE
                  FROM EXCEPTII_IREG
                 WHERE INVERS = 1
                   and <<lcExceptie>>) as exceptie
          from act a
          join <<m.lcJurnalTVA>> j
            on a.an = j.an
           and a.luna = j.luna
           and a.id_fact = j.id_fact
          join nom_fdoc f
            on j.id_fdoc = f.id_fdoc
          left join vsaft_taxtable st on a.taxcode = st.taxcode  
         where a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and a.sters = 0
           AND substr(a.scd, 1, 3) <> '442' and substr(a.scc, 1, 3) <> '442'
           and f.tip_doc in ('F', 'M'<<IIF(m.llClient, "", ",'C', 'INV'")>>))
 group by id_fact, taxcode		
		ENDTEXT 		
		
		llSucces = goExecutor.oExecuta(m.lcSql, 'cFacturiTaxCode2T')
		IF m.llSucces
			
			* Unific facturile cu acelasi numar, bagate din bucati - au id_fact diferite(contabilitate, gestiune, facturare)
			SELECT (m.lcCursorDup)
			SCAN 
				SCATTER NAME loFact
				UPDATE cFacturiTaxCode2T SET id_fact = loFact.id_fact2 WHERE id_fact = loFact.id_fact
			ENDSCAN 
			
			SELECT id_fact, taxcode, SUM(suma) as suma, SUM(suma_val) as suma_val FROM cFacturiTaxCode2T GROUP BY id_fact, taxcode INTO CURSOR cFacturiTaxCode2
			USE IN (SELECT('cFacturiTaxCode2T'))
					
			SELECT cFacturiTaxCode1
			SCAN 
				SCATTER NAME loRec
				SELECT cFacturiTaxCode2
				LOCATE FOR id_fact = loRec.id_fact AND NVL(taxcode,0) = NVL(loRec.taxcode,0)
				IF FOUND()
					lnSuma = suma
				ELSE
					lnSuma = 0	
				ENDIF 
				IF ABS(NVL(lorec.valoare,0) - NVL(m.lnSuma,0)) > 0.5
					INSERT INTO cverifica_facturi_saft(tip, an, luna, nract, dataact, denumire, taxcode, valoare_taxcode_factura, valoare_taxcode_regjurnal, diferenta_valoare_taxcode) ;
					VALUES (2, loRec.an, loRec.luna, loRec.nract, loRec.dataact, loRec.denumire, loRec.taxcode, NVL(loRec.valoare, 0), NVL(m.lnSuma, 0), NVL(loRec.valoare, 0) - NVL(m.lnSuma, 0))
				ENDIF 
			ENDSCAN 
		ENDIF && llSucces		

		* Facturi cu articole cu TVA, dar fara cod de taxa
		SELECT distinct 3 as tip, a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire ;
			FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
			WHERE EMPTY(NVL(b.taxcode,0)) ;
			order by a.an, a.luna, a.dataact, a.nract ;
			INTO CURSOR cFacturiTaxCode3

		SELECT cverifica_facturi_saft
		APPEND FROM DBF('cFacturiTaxCode3')
			
		IF RECCOUNT('cverifica_facturi_saft') > 0

			* llOk = ExportExcelXml("cverifica_facturi_saft", "facturi_saft" + IIF(m.llClient, '_vanzare', '_achizitie'),'facturi',.T.)
			goExport.export2xlsx("cverifica_facturi_saft", "verificare_facturi_saft" + IIF(m.llClient, '_vanzare_', '_achizitie_') + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))
			AMESSAGEBOX('Tip = 1 : Facturi cu valoare diferita fata de Jurnalul de TVA (> 0.5)' + CHR(13) + CHR(10) + ;
				'Tip = 2 : Facturi cu valoare pe coduri de taxa diferita fata de Registrul Jurnal (> 0.5)'+ CHR(13) + CHR(10) + ;
				'Tip = 3 : Facturi cu articole cu TVA, dar fara cod de taxa',0+64, _screen.Caption)
		ELSE
			AMESSAGEBOX('Nu sunt diferente fata de Jurnalul TVA si fata de Registrul Jurnal' + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
				'Tip = 1 : Facturi cu valoare diferita fata de Jurnalul de TVA (> 0.5)' + CHR(13) + CHR(10) + ;
				'Tip = 2 : Facturi cu valoare pe coduri de taxa diferita fata de Registrul Jurnal (> 0.5)'+ CHR(13) + CHR(10) + ;
				'Tip = 3 : Facturi cu articole cu TVA, dar fara cod de taxa',0+64,_screen.Caption)
		ENDIF 		
							
		USE IN (SELECT('cFacturiDiferente1'))
		USE IN (SELECT('cFacturiDiferente'))		
		USE IN (SELECT('cFacturiTaxCode1'))
		USE IN (SELECT('cFacturiTaxCode2'))
		USE IN (SELECT('cFacturiTaxCode3'))		
		USE IN (SELECT('cverifica_facturi_saft'))   
		
		SELECT (m.lcSelect)
	ENDPROC && do_verifica_facturi

	*********************************
	* verific soldurile din PhysicalStock cu soldurile din STOC
	*********************************
	PROCEDURE do_verifica_stocuri
		Local lcSelect, lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnDif, lcDif, lnTip, lcText

		lcSelect = SELECT()
		
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		* Creez cursor balanta de verificare
		TEXT TO lcSql TEXTMERGE NOSHOW 
select s.id_gestiune,
  			   s.cgest,
               s.id_articol,
               a.denumire,
               s.pret,
               s.cont,
               s.id_part_rez as id_part,
               p.denumire as partener,
               sum(s.canti) as canti,
               sum(s.cantf) as cantf,
               round(s.pret * sum(s.canti), 6) as vali,
               round(s.pret * sum(s.cantf), 6) as valf
          from (select s.id_gestiune, g.cgest, s.id_articol, decode(g.nr_pag, 6, s.pretv+s.tvav, s.pret) as pret, s.cont, s.id_part_rez, s.cants as canti, 0 as cantf
                  from stoc s join nom_gestiuni g on s.id_gestiune = g.id_gestiune
                 where s.an = <<m.lnAn1>> and s.luna = <<m.lnLuna1>> 
                 and not (SUBSTR(s.cont,1,3) = '303' or SUBSTR(s.cont,1,2) in ('32', '39'))
                union all
                select s.id_gestiune, g.cgest, s.id_articol, decode(g.nr_pag, 6, s.pretv+s.tvav, s.pret) as pret, s.cont, s.id_part_rez, 0 as canti, s.cants + s.cant - s.cante as cantf
                  from stoc s join nom_gestiuni g on s.id_gestiune = g.id_gestiune
                 where s.an = <<m.lnAn2>> and s.luna = <<m.lnLuna2>> 
                 and not (SUBSTR(s.cont,1,3) = '303' or SUBSTR(s.cont,1,2) in ('32', '39'))) s
            left join nom_parteneri p on s.id_part_rez = p.id_part
			left join nom_articole a on s.id_articol = a.id_articol
         group by s.id_gestiune, s.cgest, s.id_articol, a.denumire, s.pret, s.cont, s.id_part_rez, p.denumire
		ENDTEXT 
		llSucces = goExecutor.oExecuta(m.lcSql, 'cStocuriTemp')

		SELECT NVL(s1.cgest, s2.cgest) as cgest, ;
			NVL(s1.denumire, s2.denumire) as denumire, ;		
			NVL(s1.cont, s2.cont) as cont, ;
			NVL(s1.partener, s2.partener) as partener, ;					
			NVL(s1.pret, s2.pret) as pret, ;		
			NVL(s1.vali, 0.00) as vali1, ;			
			NVL(s2.vali, 0.00) as vali2, ;			
			NVL(s1.valf, 0.00) as valf1, ;			
			NVL(s2.valf, 0.00) as valf2, ;			
			NVL(s1.vali, 0.00) - NVL(s2.vali, 0.00) as valid,;
			NVL(s1.valf, 0.00) - NVL(s2.valf, 0.00) as valfd ;
		FROM cPhysicalStock s1 FULL JOIN cStocuriTemp s2 ON s1.id_gestiune = s2.id_gestiune AND s1.id_articol = s2.id_articol AND NVL(s1.cont, 'x') = NVL(s2.cont, 'x') AND s1.pret = s2.pret AND NVL(s1.id_part, 0) =  NVL(s2.id_part, 0) ;
		ORDER BY 1,2,3,4,5 ;
		INTO CURSOR cStocuriDiferente1

				
		SELECT cgest, denumire, cont, partener, pret, ;
			vali1 as valoare_initiala_saft, vali2 as valoare_initiala_stoc, valid as valoare_initiala_dif, ;
			valf1 as valoare_finala_saft, valf2 as valoare_finala_stoc, valfd as valoare_finala_dif ;
			FROM cStocuriDiferente1 ;
			WHERE valid <> 0 OR valfd <> 0 ;
			ORDER BY cgest, denumire, cont, pret ;
			INTO CURSOR cStocuriDiferente
		
		IF RECCOUNT('cStocuriDiferente') = 0
			AMESSAGEBOX('Nu sunt diferente fata de soldurile articolelor din stocuri (exclusiv 303, 32x, 39x)!',0+64,_screen.Caption)
		ELSE 	
			goExport.export2xlsx("cStocuriDiferente", "verificare_stocuri_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))
			
			AMESSAGEBOX('Diferente fata de soldurile articolelor din stocuri (exclusiv 303, 32x, 39x)!' + CHR(13) + CHR(10) + m.lcText,0+64,_screen.Caption)
		ENDIF  && reccount

		USE IN (SELECT('cStocuriDiferente1')) 		
		USE IN (SELECT('cStocuriDiferente')) 

		SELECT (m.lcSelect)
	ENDPROC && do_verifica_stocuri

	*********************************
	* verific rulajele din cMovementOfGoods cu RULL
	*********************************
	PROCEDURE do_verifica_rulaje
		Local lcSelect, lcSql, llOk, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnDif, lcDif, lnTip, lcText

		lcSelect = SELECT()
		
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		* Creez cursor balanta de verificare
		TEXT TO lcSql TEXTMERGE NOSHOW 
select a.id_articol, a.denumire, SUM(r.cant) as cant, SUM(r.cante) as cante, SUM(ROUND(decode(g.nr_pag, 6, r.pretv+r.tvav, r.pret) * (case when cant <> 0 then cant else cante end), <<m.gnPC>>)) as valoare 
       from rul r left join vnom_articole a on r.id_articol = a.id_articol 
       join nom_gestiuni g on r.id_gestiune = g.id_gestiune 
       where r.an * 12 + r.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>> and r.sters = 0
       and not (SUBSTR(r.cont,1,3) = '303' or SUBSTR(r.cont,1,2) in ('32'))
       group by a.id_articol, a.denumire
		ENDTEXT 
		llSucces = goExecutor.oExecuta(m.lcSql, 'cRulajeTemp')

		SELECT id_articol, denumire, SUM(cant) as cant, SUM(cante) as cante, SUM(valoare) as valoare ;
			from cMovementOfGoods ;
			GROUP BY id_articol, denumire ;
			INTO CURSOR cMovementOfGoodsTemp
		
       
		SELECT NVL(r1.denumire, r2.denumire) as denumire, ;		
			NVL(r1.cant, 0.00) as cant1, ;			
			NVL(r2.cant, 0.00) as cant2, ;			
			NVL(r1.cante, 0.00) as cante1, ;			
			NVL(r2.cante, 0.00) as cante2, ;			
			NVL(r1.valoare, 0.00) as valoare1, ;						
			NVL(r2.valoare, 0.00) as valoare2, ;					
			NVL(r1.valoare, 0.00) - NVL(r2.valoare, 0.00) as valoared ;
		FROM cMovementOfGoodsTemp r1 FULL JOIN cRulajeTemp r2 ON r1.id_articol = r2.id_articol ;
		ORDER BY 1 ;
		INTO CURSOR cRulajeDiferente1

				
		SELECT denumire, ;
			cant1 as intrari_saft, cant2 as intrari_rulaje, ;
			cante1 as iesiri_saft, cante2 as iesiri_rulaje, ;
			valoare1 as valoare_saft, valoare2 as valoare_rulaje, valoared as valoare_dif ;
			FROM cRulajeDiferente1 ;
			WHERE cant1 <> cant2 OR cante1 <> cante2 or valoare1 <> valoare2 ;
			ORDER BY denumire ;
			INTO CURSOR cRulajeDiferente
		
		IF RECCOUNT('cRulajeDiferente') = 0
			AMESSAGEBOX('Nu sunt diferente fata de rulaje (exclusiv 303, 32x)!',0+64,_screen.Caption)
		ELSE 	
			goExport.export2xlsx("cRulajeDiferente", "verificare_rulaje_saft_" + gofirma.codfiscalfro + '_' + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))
			
			AMESSAGEBOX('Diferente fata de rulajele articolelor (exclusiv 303, 32x)!' ,0+64,_screen.Caption)
		ENDIF  && reccount

		USE IN (SELECT('cMovementOfGoodsTemp')) 
		USE IN (SELECT('cRulajeDiferente1')) 		
		USE IN (SELECT('cRulajeDiferente')) 

		SELECT (m.lcSelect)
	ENDPROC && do_verifica_rulaje
			
	*************************************
	* Completare inregistrari (Registru Jurnal, Rulaje, Vanzari) care nu au coduri de taxa/plata SAF-T cu coduri de taxa/plata implicite		
	PROCEDURE CompletareCodTaxaPlata
		Local lcParola
		Local lcMesaj, lcSql, llSucces, lnOptiune
		PRIVATE pnAn1, pnLuna1, pnAn2, pnLuna2
*!*			lcParola = INPUTBOX('Parola','Parola','')
*!*			IF m.lcParola # TRANSFORM(YEAR(DATE())) + PADL(TRANSFORM(MONTH(DATE())),2,'0') + PADL(TRANSFORM(DAY(DATE())),2,'0')
*!*				RETURN
*!*			ENDIF 

		lnOptiune = xmenu('Completare cod taxa SAF-T;Completare cod plata SAF-T;\-;Completare coduri plata implicite pe documente;Corectare tip persoana fizica in nomenclatorul de parteneri')
		IF EMPTY(m.lnOptiune)
			RETURN 
		ENDIF 

		pnAn1 = This.oUnitate.an1
		pnLuna1 = This.oUnitate.luna1
		pnAn2 = This.oUnitate.an2
		pnLuna2 = This.oUnitate.luna2
		
		DO CASE 
			CASE m.lnOptiune = 1
				lcMesaj = 'Doriti sa completati inregistrarile din perioada curenta (Registrul Jurnal, Rulaj, Vanzari) care nu au coduri de taxa cu coduri de taxa implicite SAFT?'
				lcSql = [begin PACK_SAFT.UpdateTaxCode(?pnAn1, ?pnLuna1, ?pnAn2, ?pnLuna2); end;]
			CASE m.lnOptiune = 2
				lcMesaj = 'Doriti sa completati inregistrarile din perioada curenta (Registrul Jurnal) care nu au coduri de plata cu coduri de plata implicite SAFT?'
				lcSql = [begin PACK_SAFT.UpdatePaymentCode(?pnAn1, ?pnLuna1, ?pnAn2, ?pnLuna2); end;]
			CASE m.lnOptiune = 4
				lcMesaj = 'Doriti sa initializati codul de plata implicit in nomenclatorul "Fel document"?' + CHR(13) + CHR(10) + 'Dupa initializare, verificati asocierea codurilor de plata in Definirea Companiei > Nomenclatoare > Tip document'
				lcSql = [begin PACK_SAFT.UpdatePaymentCodeFdoc(?gnAn); end;]		
			CASE m.lnOptiune = 5
				lcMesaj = 'Doriti sa corectati tipul de persoana = "Fizica" pentru persoanele cu tip persoana = "Juridica" si cod fiscal 13 cifre?'
				lcSql = [begin PACK_SAFT.UpdateTipPersoanaFizica(); end;]		
				
		ENDCASE 

		IF AMESSAGEBOX(m.lcMesaj,4+32,_screen.Caption) = 6
			llSucces = goExecutor.oExecuta(m.lcSql)
			IF m.llSucces	
				AMESSAGEBOX('Completari efectuate cu succes!' + CHR(13) + CHR(10) + ;
				'Apasati pe 1. Citeste date pentru a actualiza datele din declaratie',0+64,_screen.Caption)
			ENDIF 
		ENDIF  	
	ENDPROC && CompletareCodTaxaPlata				
														
	***********************************
	* Creare cusoare din baza de date
	Function CitesteDate
		Local lcSelect, llSucces
		lcSelect = Select()
		llSucces = .T.

		If m.llSucces And This.oUnitate.GeneralLedgerAccounts
			WAIT WINDOW 'GeneralLedgerAccounts...' NOWAIT 
			llSucces = This.oGeneralLedgerAccounts()
		Endif

		If m.llSucces And This.oUnitate.Customers
			WAIT WINDOW 'Customers...' NOWAIT 
			llSucces = This.oCustomersSuppliers('customers')
		Endif

		If m.llSucces And This.oUnitate.Suppliers
			WAIT WINDOW 'Suppliers...' NOWAIT 		
			llSucces = This.oCustomersSuppliers('suppliers')
		Endif

		If m.llSucces And This.oUnitate.TaxTable
			WAIT WINDOW 'TaxTable...' NOWAIT 		
			llSucces = This.oTaxTable()
		Endif

		If m.llSucces And This.oUnitate.UOMTable
			WAIT WINDOW 'UOMTable...' NOWAIT 		
			llSucces = This.oUOMTable()
		Endif


		If m.llSucces And This.oUnitate.AnalysisTypeTable
			WAIT WINDOW 'AnalysisTypeTable...' NOWAIT 		
			llSucces = This.oAnalysisTypeTable()
		Endif

		If m.llSucces And This.oUnitate.GeneralLedgerEntries
			WAIT WINDOW 'GeneralLedgerEntries...' NOWAIT 		
			llSucces = This.oGeneralLedgerEntries()
		Endif

		If m.llSucces And This.oUnitate.SalesInvoices
			WAIT WINDOW 'SalesInvoices...' NOWAIT 		
			llSucces = This.oSalesInvoices()
		Endif

		If m.llSucces And This.oUnitate.PurchaseInvoices
			WAIT WINDOW 'PurchaseInvoices...' NOWAIT 		
			llSucces = This.oPurchaseInvoices()
		Endif

		If m.llSucces And This.oUnitate.Payments
			WAIT WINDOW 'Payments...' NOWAIT 			
			llSucces = This.oPayments()
		Endif

		If m.llSucces And This.oUnitate.Owners
			WAIT WINDOW 'Owners...' NOWAIT 			
			llSucces = This.oOwners()
		ENDIF
		
		If m.llSucces And This.oUnitate.Assets
			WAIT WINDOW 'Assets...' NOWAIT 			
			llSucces = This.oAssets()
		ENDIF
				
		If m.llSucces And This.oUnitate.MovementTypeTable
			WAIT WINDOW 'MovementTypeTable...' NOWAIT 			
			llSucces = This.oMovementTypeTable()
		ENDIF

		If m.llSucces And This.oUnitate.Products
			WAIT WINDOW 'Products...' NOWAIT 			
			llSucces = This.oProducts()
		ENDIF
		
		If m.llSucces And This.oUnitate.PhysicalStock
			WAIT WINDOW 'PhysicalStock...' NOWAIT 			
			llSucces = This.oPhysicalStock()
		ENDIF
		
		If m.llSucces And This.oUnitate.MovementOfGoods
			WAIT WINDOW 'MovementOfGoods...' NOWAIT 			
			llSucces = This.oMovementOfGoods()
		ENDIF
		
				
		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && CitesteDate

************************************************
* cursor cGeneralLedgerAccounts
************************************************
	Function oGeneralLedgerAccounts

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

* 26.04.2023
* am folosit bal full join plcont in loc de left join, pentru ca nu se afisau descrierile de la toate conturile din plcont. nu stiu de ce

* GeneralLedgerAccounts
		Text To m.lcSql Noshow Textmerge
SELECT b.cont,
       p.explicaties as denumire,
       DECODE(UPPER(NVL(p.tip_sold,'B')), 'A', 'Activ', 'P', 'Pasiv', 'Bifunctional') AS tip,
       nvl(b.soldideb, 0) as soldideb,
       nvl(b.soldicred, 0) as soldicred,
       nvl(b.soldfdeb, 0) as soldfdeb,
       nvl(b.soldfcred, 0) as soldfcred
  FROM (select  nvl(b1.cont, b2.cont) as cont,
                    (case
                      when precdeb >= preccred then
                       precdeb - preccred
                      else
                       0
                    end) as soldideb,
                    (case
                      when preccred > precdeb then
                       preccred - precdeb
                      else
                       0
                    end) as soldicred,
			       (case
			         when nvl(precdeb,0) + nvl(debit,0) >= nvl(preccred,0) + nvl(credit,0) then
			          nvl(precdeb,0) + nvl(debit,0) - nvl(preccred,0) - nvl(credit,0)
			         else
			          0
			       end) as soldfdeb,
			       (case
			         when nvl(preccred,0) + nvl(credit,0) > nvl(precdeb,0) + nvl(debit,0) then
			          nvl(preccred,0) + nvl(credit,0) - nvl(precdeb,0) - nvl(debit,0)
			         else
			          0
			       end) as soldfcred
			from (select cont,
                            sum(precdeb) as precdeb,
                            sum(preccred) as preccred
                       from bal
                      where an = <<m.lnAn1>>
                        and luna = <<m.lnLuna1>>
						and TO_NUMBER(SUBSTR(cont, 1, 1)) <= 7
                      group by cont) b1
               full join (select cont,
                                sum(ruldeb) as debit,
                                sum(rulcred) as credit
                           from bal
                          where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
						  and TO_NUMBER(SUBSTR(cont, 1, 1)) <= 7
                          group by cont) b2
                 on b1.cont = b2.cont) b
  FULL JOIN VPLCONT_SINTETIC p
    ON b.cont = p.cont
   AND p.an = <<m.lnAn2>>
  WHERE b.cont is not null
   order by b.cont 
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cGeneralLedgerAccounts')

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oGeneralLedgerAccounts

************************************************
* cursor cCustomers/cSuppliers
************************************************
	Function oCustomersSuppliers
		Lparameters tcTip
* tcTip: customers/suppliers

		Local lcCursor, lcSelect, lcSql, llClient, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()
		llClient = (Upper(Alltrim(m.tcTip)) = 'CUSTOMERS')
		lcCursor = Iif(m.llClient, 'cCustomers', 'cSuppliers')
		lcCont = Iif(m.llClient, '4111', '401')
		lcListaConturi = Iif(m.llClient, ['4111','4118','461','418', '419'], ['401','404','462','408','409'])
		lcTipCont = Iif(m.llClient, 'Activ', 'Pasiv')
		lcJTVA = Iif(m.llClient, 'jv2007', 'jc2007')

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		* Anul incepand cu care se iau clientii/furnizorii din balanta de parteneri
		* Poate nu vreau sa iau toti clientii/furnizorii, cu coduri fiscale eronate din istoric
		* Clientii/furnizorii din balanta de parteneri, dupa lista de conturi clienti/furnizori, in loc de jurnalul TVA vanzari/cumparari
		* Era posibil sa nu existe in Jurnalele de TVA, daca erau initializati doar in balantele de parteneri
		lnCustSupType = This.oUnitate.CustSupType && 9999 = Toti, 2022 = Incepand cu 2022, 2023 = 2023, 2025 = 2025
		lnAnInitial = IIF(m.lnCustSupType = 9999, 1900, m.lnCustSupType)
		
		Text To m.lcSql Noshow Textmerge
select p.id_part,
       NVL(TRIM(p.denumire), 'NEDEFINIT') as denumire,
       p.cod_fiscal,
       p.tip_persoana,
       p.sters,
       a.strada,
       a.numar,
       a.localitate,
       a.indicativ_judet,
       a.codpostal,
       a.cod_tara,
       (CASE when j.is_activ > 0 then 1 else 0 end) as is_activ,
       NVL(b.cont, '<<m.lcCont>>') as cont,
       '<<m.lcTipCont>>' as tip,
       nvl(b.soldideb, 0) as soldideb,
       nvl(b.soldicred, 0) as soldicred,
       nvl(b.soldfdeb, 0) as soldfdeb,
       nvl(b.soldfcred, 0) as soldfcred,
       CAST(null as varchar2(30)) as saftpartid
  FROM NOM_PARTENERI P
  left join (select id_part, SUM(case when an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>> then 1 else 0 end) as is_activ from <<m.lcJTVA>> 
  		group by id_part) j
    on p.id_part = j.id_part
  left join (select nvl(b1.id_part, b2.id_part) as id_part,
                    nvl(b1.cont, b2.cont) as cont,
                    (case
                      when nvl(precdeb,0) >= nvl(preccred,0) then
                       nvl(precdeb,0) - nvl(preccred,0)
                      else
                       0
                    end) as soldideb,
                    (case
                      when nvl(preccred,0) > nvl(precdeb,0) then
                       nvl(preccred,0) - nvl(precdeb,0)
                      else
                       0
                    end) as soldicred,
                    (case
                      when nvl(precdeb,0) + nvl(debit,0) >= nvl(preccred,0) + nvl(credit,0) then
                       nvl(precdeb,0) + nvl(debit,0) - nvl(preccred,0) - nvl(credit,0)
                      else
                       0
                    end) as soldfdeb,
                    (case
                      when nvl(preccred,0) + nvl(credit,0) > nvl(precdeb,0) + nvl(debit,0) then
                       nvl(preccred,0) + nvl(credit,0) - nvl(precdeb,0) - nvl(debit,0)
                      else
                       0
                    end) as soldfcred
               from (select id_part,
                            cont,
                            sum(precdeb) as precdeb,
                            sum(preccred) as preccred
                       from balanta_parteneri
                      where an = <<m.lnAn1>>
                        and luna = <<m.lnLuna1>>
                        and cont in (<<m.lcListaConturi>>)
                      group by id_part, cont) b1
               full join (select id_part,
                                cont,
                                sum(debit) as debit,
                                sum(credit) as credit
                           from balanta_parteneri
                          where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
							and cont in (<<m.lcListaConturi>>)
                          group by id_part, cont) b2
                 on b1.id_part = b2.id_part
                and b1.cont = b2.cont) b
    on p.id_part = b.id_part
  LEFT JOIN (SELECT ap.id_part,
                    ap.strada,
                    ap.numar,
                    l.localitate,
                    j.indicativ   as indicativ_judet,
                    ap.codpostal,
                    t.prescurtare as cod_tara
               FROM ADRESE_PARTENERI ap
               left join syn_nom_localitati l
                 on l.id_loc = ap.id_loc
               left join syn_nom_judete j
                 on j.id_judet = l.id_judet
               left join syn_nom_tari t
                 on t.id_tara = ap.id_tara
              WHERE ap.STERS = 0
                AND ap.PRINCIPALA = 1) a
    ON p.id_part = a.id_part   
  where exists (select id_part, sum(debit) as debit, sum(credit) as credit, sum(precdeb-preccred) as soldi from balanta_parteneri
            WHERE AN >= <<m.lnAnInitial>> and id_part = p.id_part and cont in (<<m.lcListaConturi>>) 
            group by id_part
            having (sum(debit) <> 0 or sum(credit) <> 0 or sum(precdeb-preccred) <> 0))
     or exists
      (select distinct id_part from ireg_parteneri
            WHERE AN >= <<m.lnAnInitial>> and id_part = p.id_part and cont in (<<m.lcListaConturi>>))    
    ORDER BY p.denumire 
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, m.lcCursor)

		IF m.llSucces
			lcCodUnitate = this.ounitATE.codi
			DELETE FROM (m.lcCursor) WHERE !EMPTY(NVL(sters,0)) && era si partenerul cu ID_PART = 0, STERS
			
			UPDATE (m.lcCursor) SET cod_fiscal = m.lcCodUnitate WHERE UPPER(ALLTRIM(cod_fiscal)) = 'ANULAT'
			UPDATE (m.lcCursor) SET SaftPartId = This.GenCustSupCode(id_part, cod_tara, tip_persoana, cod_fiscal) WHERE !EMPTY(NVL(id_part,0))
			SELECT (m.lcCursor)
			INDEX on id_part TAG id_part
			SET ORDER TO  
		ENDIF 
		GO TOP IN (m.lcCursor)
				
		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oCustomersSuppliers

	************************************************
	* cursor cTaxTable
	************************************************
	Function oTaxTable

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		Text To m.lcSql Noshow Textmerge
select * FROM vsaft_taxtable t WHERE to_char(taxcode) <> to_char(taxtype) || '000' AND exists (SELECT taxcode FROM act a WHERE sters = 0 AND an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>> and a.taxcode = t.taxcode) order by taxcode
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cTaxTable')
		If m.llSucces
*
		Endif

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oTaxTable


	************************************************
	* cursor cUOMTable
	************************************************
	Function oUOMTable

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		Text To m.lcSql Noshow Textmerge
select distinct u.cod_um_iso as UnitOfMeasure, u.um_iso as description
  from stoc s
  join nom_articole a
    on s.id_articol = a.id_articol
  join vnom_um u
    on a.um = u.um
 where  s.an * 12 + s.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
 and u.cod_um_iso is not null
 order by u.cod_um_iso
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cUOMTable')
		If m.llSucces
			* Da eroare la depunerea la ANAF daca nu are o inregistrare
			IF RECCOUNT('cUOMTable') = 0
				INSERT INTO cUOMTable (unitofmeasure, description) VALUES ('H87', 'bucata')
			ENDIF 
		Endif

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oUOMTable
	
	
************************************************
* cursor cGeneralLedgerEntries
************************************************
	Function oGeneralLedgerEntries

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()
		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		* GeneralLedgerEntries
		* 4428 este optional sa aiba taxcode
		* nu pun taxcode pentru 4428 pentru ca la exigibilizare TVA are un cod 380xxx diferit fata de 4428 301xxx si nu am 2 coduri pe aceeasi inregistrare in Registrul Jurnal
		Text To m.lcSql Noshow Textmerge
select c.an,
       c.luna,
       c.cod,
       c.id_fact,
       c.nract,
       c.dataact,
       c.dataireg,
       c.cont,
       c.tipdc,
       c.id_part,
       c.id_jtva_coloana,
       c.cota_taxa,
       c.explicatie_tva,
       c.tiptaxa,
       c.taxtype,
       c.taxcode,
       c.taxname,
       c.id_sectie,
       c.id_valuta,
       max(decode(c.n50, 0, 0, 1)) over(partition by id_fact) as n50,
       max(decode(c.n100, 0, 0, 1)) over(partition by id_fact) as n100,
       c.curs,
       c.suma,
       c.suma_val,
       c.taxa,
       c.taxa_val,
	   p.denumire,
       p.cod_fiscal,
       p.tip_persoana,
       t.prescurtare as cod_tara,
       nvl(v.nume_val2, 'RON') as cod_valuta,
       CAST(null as varchar2(20)) as saftpartid
  from (select an,
               luna,
               cod,
               id_fact,
               nract,
               dataact,
               dataireg,
               cont,
               tipdc,
               id_part,
               id_jtva_coloana,
               cota_taxa,
               explicatie_tva,
               tiptaxa,
               taxtype, 
               taxcode,
               taxname,
               id_sectie,
               id_valuta,
               curs,
               sum(n50) as n50,
               sum(n100) as n100,
               sum(suma) as suma,
               sum(suma_val) as suma_val,
               sum(nvl(round(suma * cota_taxa / 100, 2),0)) as taxa,
               sum(case when curs <> 0 and suma_val <> 0 then round(suma / curs * cota_taxa / 100, 2) else 0 end) as taxa_val
          from (select a.an,
                       a.luna,
                       a.cod,
                       a.id_fact,
                       a.nract,
                       a.dataact,
                       a.dataireg,
                       a.cont,
                       a.tipDC,
                       a.id_part,
                       a.id_sectie,
                       a.id_valuta,
                       a.curs,
                       a.n50,
                       a.n100,
                       a.suma,
                       a.suma_val,
                       case
                         when j.taxcode <> 0 and j.id_tva is null then
                          null
                         else
                          decode(NVL(a.id_jtva_coloana,0), 0, null, a.id_jtva_coloana)
                       end as id_jtva_coloana,
                       case
                         when j.taxcode <> 0 and j.id_tva is null then
                          0
                         else
                          decode(NVL(a.id_jtva_coloana,0), 0, 0, j.cota_tva)
                       end as cota_taxa, 
                       case
                         when j.taxcode <> 0 and j.id_tva is null then
                          null
                         else
                          decode(NVL(a.id_jtva_coloana,0), 0, null, j.denumire)
                       end as explicatie_tva,
                       j.id_tva,
                       case when j.taxcode is not null and tx.tva = 1 then 'TVA' when tx.wht = 1 then 'WHT' else '' end as tiptaxa,
                       cast(decode(j.taxcode, null, null, tx.taxtype) as Number) as taxtype, 
                       cast(decode(j.taxcode, null, null, a.taxcode) as number) as taxcode,
                       cast(decode(j.taxcode, null, null, tx.taxname) as varchar2(250)) as taxname  
                  from (SELECT an,
                               luna,
                               cod,
                               id_fact,
                               nract,
                               dataact,
                               dataireg,
                               case
                                 when substr(scd, 1, 2) in ('40', '41', '46') then
                                  id_partd
                                 else
                                  null
                               end as id_part,
                               scd as cont,
                               'D' AS tipDC,
                               case
                                 when scd in ('4426', '4427', '4428') and taxcode is not null then 
                                    ad.id_jtva_coloana
                                 when scd in ('4426', '4427', '4428') and taxcode is null then
                                  null
                                 when substr(scd, 1, 2) in
                                      ('40', '41', '44', '46') then
                                  ad.id_jtva_coloana
                                 else
                                  null
                               end as id_jtva_coloana,
                               decode(scd, '4428', cast(null as number(6)), taxcode) as taxcode,
                               id_sectie,
                               id_valuta,
                               curs,
                               decode(ad.id_jtva_coloana, 1004, 1, 0) as n50,
                               decode(ad.id_jtva_coloana, 1005, 1, 0) as n100,
                               SUM(suma) as suma,
                               sum(suma_val) as suma_val
                          FROM act ad
                         where ad.sters = 0
                           and ad.an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                           and TO_NUMBER(SUBSTR(ad.scd, 1, 1)) <= 7
                         group by ad.an,
                                  ad.luna,
                                  ad.cod,
                                  ad.id_fact,
                                  ad.nract,
                                  ad.dataact,
                                  ad.dataireg,
                                  ad.dataora,
                                  ad.scd,
                                  ad.id_partd,
                                  ad.id_jtva_coloana,
                                  ad.taxcode,
                                  ad.id_sectie,
                                  ad.id_valuta,
                                  ad.curs
                        union all
                        SELECT an,
                               luna,
                               cod,
                               id_fact,
                               nract,
                               dataact,
                               dataireg,
                               case
                                 when substr(scc, 1, 2) in ('40', '41', '46') then
                                  id_partc
                                 else
                                  null
                               end as id_part,
                               scc as cont,
                               'C' AS tipDC,
                               case
                                 when scc in ('4426', '4427', '4428') and taxcode is not null then 
                                    ac.id_jtva_coloana
                                 when scc in ('4426', '4427', '4428') and taxcode is null then
                                    null
                                 when substr(scc, 1, 2) in
                                      ('40', '41', '44', '46') then
                                  ac.id_jtva_coloana
                                 else
                                  null
                               end as id_jtva_coloana,
                               decode(scc, '4428', cast(null as number(6)), taxcode) as taxcode,
                               id_sectie,
                               id_valuta,
                               curs,
                               decode(ac.id_jtva_coloana, 1004, 1, 0) as n50,
                               decode(ac.id_jtva_coloana, 1005, 1, 0) as n100,
                               SUM(suma) as suma,
                               sum(suma_val) as suma_val
                          FROM act ac
                         where ac.sters = 0
                           and ac.an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                           and TO_NUMBER(SUBSTR(ac.scc, 1, 1)) <= 7
                         group by ac.an,
                                  ac.luna,
                                  ac.cod,
                                  ac.id_fact,
                                  ac.nract,
                                  ac.dataact,
                                  ac.dataireg,
                                  ac.dataora,
                                  ac.scc,
                                  ac.id_jtva_coloana,
                                  ac.taxcode,
                                  ac.id_partc,
                                  ac.id_sectie,
                                  ac.id_valuta,
                                  ac.curs) a
                  left join jtva_coloane j
                    on a.id_jtva_coloana = j.id_jtva_coloana
                    left join vsaft_taxtable tx on a.taxcode = tx.taxcode) b
         group by an,
                  luna,
                  cod,
                  id_fact,
                  nract,
                  dataact,
                  dataireg,
                  cont,
                  tipdc,
                  id_part,
                  id_jtva_coloana,
                  cota_taxa,
                  explicatie_tva,
                  tiptaxa,
                  taxtype, 
                  taxcode,   
                  taxname,              
                  id_sectie,
                  id_valuta,
                  curs) c
  left join nom_parteneri p
    on c.id_part = p.id_part
  left join adrese_parteneri ap
    on (p.id_part = ap.id_part and ap.sters = 0 and ap.principala = 1)
  left join syn_nom_tari t
    on t.id_tara = ap.id_tara
  left join vnom_valute v
    on c.id_valuta = v.id_valuta
 order by an,
          luna,
          dataact,
          cod,
          id_fact,
          nract,
          tipdc,
          cont,
          explicatie_tva
		Endtext
		llSucces = goExecutor.oExecuta(m.lcSql, 'cGeneralLedgerEntries')

		IF m.llSucces
			lcCodUnitate = this.ounitATE.codi
			UPDATE cGeneralLedgerEntries SET cod_fiscal = m.lcCodUnitate WHERE UPPER(ALLTRIM(cod_fiscal)) = 'ANULAT'
			UPDATE cGeneralLedgerEntries SET SaftPartId = This.GenCustSupCode(id_part, cod_tara, tip_persoana, cod_fiscal) WHERE !EMPTY(NVL(id_part,0))
			
			* Completez SAFTPARTID contribuabil raportor daca nu exista partener in Registrul TVA
			lcSaftPartId = '00' + This.oUnitate.codi
			UPDATE cGeneralLedgerEntries SET saftPartId = m.lcSaftPartId WHERE EMPTY(NVL(id_part,0))
		ENDIF 
		GO TOP IN cGeneralLedgerEntries
		
		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oGeneralLedgerEntries


	************************************************
	* cursor cSalesInvoices, cSalesInvoicesLines
	* din registrul jurnal iau doar inregistrarile care au taxcode pentru a genera articole. nu iau orice nota contabila	
	************************************************
	Function oSalesInvoices
		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lcCursor, lcCursorLines, lcCursorPartener, loFact
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		lcCursor = 'cSalesInvoices'
		lcCursorTemp = 'cSalesInvoicesTemp'
		lcCursorLines = 'cSalesInvoicesLines'
		lcCursorLinesTemp = 'cSalesInvoicesLinesTemp'
		lcCursorPartener = 'cCustomers'

Create Cursor cSalesInvoicesLines(;
	tip         N(1) null,;
	id_fact     N(20) null,;
	nrcrt		N(10) null,;
	cod         N(20) null,;
	descriere	C(100) null,;
	cantitate   N(20,6) null,;
    pret_cu_tva N(1) null,;
	pret        N(20,4) null,;
	pretv       N(20,4) null,;	
	valoare     N(20,4) null,;
	valoarev    N(20,4) null,;	
	taxa        N(20,4) null,;
	taxav       N(20,4) null,;
	id_valuta   N(5) null,;
	curs        N(14,4) null,;
	taxcode     N(6) null,;
	taxtype     N(3) null,;
	taxname     C(250) null,;
	proc_tva    N(5) null,;
	cod_valuta  C(5) null,;
	cont        C(4) null)
			
		Text To m.lcSql Noshow Textmerge
Select j2.an,
       j2.luna,
       j2.id_fact,
       j2.cod,
       j2.nract,
       j2.dataact,
       j2.id_part,
       p.denumire,
	   j2.totctva,
	   CAST(null as varchar2(30)) as saftpartid,
       CAST(null as varchar2(100)) as localitate,
       CAST(null as varchar2(100)) as cod_tara,
       CASE
       	when j2.invoicetype is not null then
       		j2.invoicetype
         when nvl(j2.autofactura, 0) = 1 then
          389
         when j2.totctva < 0 then
          381
         else
          380
       end as invoicetype,
       (CASE when j2.invoicetype = 389 or nvl(j2.autofactura, 0) = 1 then 389 ELSE 0 END) as autofactura,
       (select MAX(scd) as cont from act where cod = j2.cod and SUBSTR(scd, 1, 2) in ('41', '46')) as cont
  from (select an,
               luna,
               id_fact,
               cod,
               nract,
               dataact,
               id_part,
               totctva,
               (select max(isautofactura) as autofactura
                  from serii
                 where serie = j.serie_act) as autofactura,
               (select MAX(tip_saft) as tip_saft from vanzari where id_fact = j.id_fact) as invoicetype  
          from jv2007 j join nom_fdoc f on j.id_fdoc = f.id_fdoc
         where j.an * 12 + j.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
         and extract(year from j.dataireg) = j.an and extract(MONTH from j.dataireg) = j.luna         
         and f.tip_doc in ('F', 'M')
         and j.id_fact not in (select distinct id_fact from act where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>> and sters= 0 and id_set = 99996)) j2
	   left join nom_parteneri p on j2.id_part = p.id_part
	   order by j2.an, j2.luna, j2.dataact, j2.nract, p.denumire
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, m.lcCursorTemp)
		
		IF m.llSucces
			SELECT an, luna, id_fact, id_fact as id_fact2, cod, nract, TTOD(dataact) as dataact, id_part, denumire, totctva, saftpartid, localitate, cod_Tara, ;
				invoicetype, ;
				ALLTRIM(STR(invoicetype)) + ' - ' + IIF(invoicetype = 380, 'FACTURA INITIALA', IIF(invoicetype = 381, 'FACTURA STORNO', IIF(invoicetype = 384, 'FACTURA FINALA', IIF(invoicetype = 389, 'AUTOFACTURA', 'FACTURA INITIALA')))) as invoicetypet, ;
				INT(autofactura) as autofactura, cont ;
				FROM (m.lcCursorTemp) ;
				INTO CURSOR (m.lcCursor) READWRITE 

			USE IN (SELECT(m.lcCursorTemp))	 


			* Unific facturile introduse din mai multe bucati (gestiune, facturare, contabilitate)   			
			SELECT nract, dataact, id_part, MIN(id_fact) as id_fact, SUM(totctva) as totctva, COUNT(*) as nr ;
				FROM (m.lcCursor) ;
				group BY nract, dataact, id_part ;
				HAVING COUNT(*) > 1 ;
				INTO CURSOR cFacturiDup READWRITE 

			SELECT cFacturiDup
			SCAN 
				SCATTER NAME loFact
				UPDATE (m.lcCursor) SET id_fact2 = loFact.id_fact, totctva = loFact.totctva WHERE nract = loFact.nract AND dataact = loFact.dataact AND id_part = loFact.id_part
			ENDSCAN 
			USE IN (SELECT('cFacturiDup'))
			
			SELECT id_fact, id_fact2 FROM (m.lcCursor) WHERE id_fact <> id_fact2 INTO CURSOR cSalesInvoicesDup

												
			* Completez saftpartid, localitate, cod_tara din cCustomers/cSuppliers
			* UPDATE (m.lcCursor) SET SaftPartId = This.GetCustSupCode('CUSTOMERS', id_part) WHERE !EMPTY(NVL(id_part,0))

			SELECT distinct id_part FROM (m.lcCursor) INTO CURSOR cIdpartTemp
			SELECT cIdPartTemp
			SCAN
				lnIdPart = id_part
				IF !EMPTY(m.lnIdPart)
					IF SEEK(m.lnIdPart,m.lcCursorPartener,'id_part')
						lcSaftPartId = ALLTRIM(&lcCursorPartener..SaftPartId)
						lcLocalitate = ALLTRIM(&lcCursorPartener..localitate)
						lcCodTara = ALLTRIM(&lcCursorPartener..cod_Tara)
						UPDATE (m.lcCursor) SET saftPartId = m.lcSaftPartId, localitate =  m.lcLocalitate, cod_tara = m.lcCodTara WHERE id_part = m.lnIdPart
					ENDIF 
				ENDIF 	
			ENDSCAN 
			
			* Completez SAFTPARTID contribuabil raportor daca nu exista partener in Registrul TVA
			lcSaftPartId = '00' + This.oUnitate.codi
			UPDATE (m.lcCursor) SET saftPartId = m.lcSaftPartId WHERE EMPTY(NVL(id_part,0))
			
			USE IN (SELECT('cIdpartTemp'))
						
			* LINII FACTURI
			* Tip 1 = vanzari detalii
			* Tip = 2 articole facturi din gestiune (rul)
			* mai sunt diferente intre liniile din Rulaj si notele contabile, posibil din rotunjiri pe baza/TVA, pentru care s-au pus note suplimentare in Registrul Jurnal
			* Trebuie sa generez linie cu articol din nota din Registrul Jurnal 

			* Tip = 3 articole facturi din Contabilitate (act) - tratez cazul 4111 = 418 total cu TVA. Pun doar 100/119 din suma pe baza
			* Tip = 4 note din contabilitate (act) ex: cheltuieli rotunjire zecimale, transport, discount pentru facturile din gestiune 
			* Tip 4 se sterge si se lasa doar diferentele fata de Tip = 2			
			TEXT TO  m.lcSql NOSHOW textmerge
select 1 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       j.id_fact,
       j.cod,
       CAST(a.denumire as varchar2(100)) as descriere,
       vd.cantitate,
       vd.pret_cu_tva,     
	   ROUND(NVL(vc.curs, 1) * ROUND(decode(vd.pret_cu_tva, 0, NVL(vd.pret, 0)-NVL(vd.discount_unitar,0), (NVL(vd.pret, 0)-NVL(vd.discount_unitar,0)) / decode(NVL(vd.proc_tvav,0), 0, 1, vd.proc_tvav)), <<m.gnPPret>>) / NVL(vc.multiplicator, 1), 4) as pret,      
	   DECODE(v.in_valuta, 0, 0.00, ROUND(decode(vd.pret_cu_tva, 0, NVL(vd.pret, 0), NVL(vd.pret, 0) / decode(NVL(vd.proc_tvav,0), 0, 1, vd.proc_tvav)), <<m.gnPPretVal>>)) as pretv,
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,	   
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,	   
       DECODE(v.in_valuta, 0, 0, vd.id_valuta) as id_valuta,
       DECODE(v.in_valuta, 0, 0, nvl(v.curs, 0)) as curs,
       vd.taxcode,
       st.taxtype,
       st.taxname,
       (vd.proc_tvav - 1) * 100 as proc_tva,
       DECODE(v.in_valuta, 0, '', vi.iso_valuta) as cod_valuta,
       cast(NVL(NVL(cvc.cont_venit, decode(nc.scc, '4111', nc.scd, nc.scc)),'') as varchar2(4)) as cont             
  from vanzari_detalii vd
  join vanzari v
    on vd.id_vanzare = v.id_vanzare
  join jv2007 j
    on v.id_fact = j.id_fact
  join nom_fdoc f on j.id_fdoc = f.id_fdoc
  left join nom_articole a on vd.id_articol = a.id_articol  
  left join vanzari_cursuri vc on vd.id_vanzare = vc.id_vanzare and vd.id_valuta = vc.id_valuta  
  left join nom_valute nv
    on v.id_valuta = nv.id_valuta
  left join syn_nom_valute_iso vi
    on nv.id_valuta_iso = vi.id_valuta_iso
  left join CRM_POLITICI_PRETURI pp
    on vd.id_pol = pp.id_pol
  left join crm_note_vanzari nv2
    on pp.id_nota = nv2.id_nota
  left join note_contabile nc
    on nv2.id_set = nc.id_set
  left join vsaft_taxtable st on vd.taxcode = st.taxcode     
  left join CORESP_CONT_VENCHELT cvc on vd.cont = cvc.cont    
 where j.an * 12 + j.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
  and extract(year from j.dataireg)*12 + extract(MONTH from j.dataireg) between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
  and extract(year from j.dataireg) = j.an and extract(MONTH from j.dataireg) = j.luna
 and f.tip_doc in ('F', 'M')
 and v.sters = 0
union all
select 2 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       r.id_fact,
       r.cod,
       CAST(a.denumire as varchar2(100)) as descriere,       
       r.cante as cantitate,
       0 as pret_cu_tva,
       r.pretv as pret,
       0.00 as pretv,
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,       
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,	          
       0 as id_valuta,
       0 as curs,
       r.taxcode,
       st.taxtype,
       st.taxname,
       st.procent_taxa as proc_tva,
       'RON' as cod_valuta,
       NVL(vc.cont_venit, '707') as cont
  from rul r
  join jv2007 j
    on r.an = j.an
   and r.luna = j.luna
   and r.id_fact = j.id_fact
   join nom_fdoc f on j.id_fdoc = f.id_fdoc 
  left join nom_articole a on r.id_articol = a.id_articol 
  left join vsaft_taxtable st on r.taxcode = st.taxcode 
  left join CORESP_CONT_VENCHELT vc on r.cont = vc.cont
 where r.an * 12 + r.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
   and r.sters = 0
   and j.id_fact not in (select id_fact
                       from vanzari
                      where extract(year from data_act) * 12 +
                            extract(month from data_act) between
                            <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                            and id_fact is not null and sters = 0)
   and f.tip_doc in ('F', 'M')                            
union all
select 3 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       id_fact,
       cod,
       CAST(MAX(explicatia) as varchar2(100)) as descriere,
       1 as cantitate,
       0 as pret_cu_tva,       
       sum(decode(exceptie, 1, -1, 1) * suma) as pret,
       sum(decode(exceptie, 1, -1, 1) * suma_val) as pretv,
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,	                 
       id_valuta,
       curs,
       taxcode,
       taxtype,
       taxname,
       proc_tva,
       cod_valuta,
       decode(exceptie, 1, scd, scc) as cont
  from (select a.id_fact,
               a.cod,
               a.explicatia,
               (CASE when a.scd like '4%' AND a.scc = '418' then ROUND(a.suma * 100 / (100 + st.procent_taxa), 2) else a.suma end) as suma,
			   (CASE when a.scd like '4%' AND a.scc = '418' then ROUND(a.suma_val * 100 / (100 + st.procent_taxa), 2) else a.suma_val end) as suma_val,                 
               a.id_valuta,
               a.curs,
               a.taxcode,
               st.taxtype,
		       st.taxname,               
               st.procent_taxa as proc_tva,
               vi.iso_valuta as cod_valuta,
               a.scd,
               a.scc,
               (SELECT DISTINCT 1 AS EXCEPTIE
                  FROM EXCEPTII_IREG
                 WHERE INVERS = 1
                   AND CONT = a.scc and cont_c = a.scd) as exceptie
          from act a
          join jv2007 j
            on a.an = j.an
           and a.luna = j.luna
           and a.id_fact = j.id_fact
          join nom_fdoc f on j.id_fdoc = f.id_fdoc 
          left join nom_valute nv
            on a.id_valuta = nv.id_valuta
          left join syn_nom_valute_iso vi
            on nv.id_valuta_iso = vi.id_valuta_iso
		  left join vsaft_taxtable st on a.taxcode = st.taxcode             
         where a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and a.sters = 0
           and a.id_set <> 99996
           and a.taxcode is not null
           AND substr(a.scd, 1, 3) <> '442' and substr(a.scc, 1, 3) <> '442'           
           and a.id_fact not in
               (select id_fact
                  from vanzari
                 where extract(year from data_act) * 12 +
                       extract(month from data_act) between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                        and id_fact is not null and sters = 0
                union
                select id_fact
                  from rul
                 where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                      and id_fact is not null and sters = 0)
           and f.tip_doc in ('F', 'M'))
 group by id_fact,
          cod,
          id_valuta,
          curs,
          taxcode,
          taxtype,
          taxname,
          proc_tva,
          cod_valuta,
          decode(exceptie, 1, scd, scc)	
union all
select 4 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       id_fact,
       cod,
       CAST('VERIFICARE' as varchar2(100)) as descriere,
       1 as cantitate,
       0 as pret_cu_tva,       
       sum(decode(exceptie, 1, -1, 1) * suma) as pret,
       sum(decode(exceptie, 1, -1, 1) * suma_val) as pretv, 
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,             
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,       
       id_valuta,
       curs,
       taxcode,
       taxtype,
       taxname,
       proc_tva,
       cod_valuta,
       decode(exceptie, 1, scd, scc) as cont
  from (select a.id_fact,
               a.cod,
               a.explicatia,
               (CASE when a.scd like '4%' AND a.scc = '418' then ROUND(a.suma * 100 / (100 + st.procent_taxa), 2) else a.suma end) as suma,
			   (CASE when a.scd like '4%' AND a.scc = '418' then ROUND(a.suma_val * 100 / (100 + st.procent_taxa), 2) else a.suma_val end) as suma_val,               
               a.id_valuta,
               a.curs,
               a.taxcode,
               st.taxtype,
               st.taxname,
               st.procent_taxa as proc_tva,
               vi.iso_valuta as cod_valuta,
               a.scd,
               a.scc,
               (SELECT DISTINCT 1 AS EXCEPTIE
                  FROM EXCEPTII_IREG
                 WHERE INVERS = 1
                   AND CONT = a.scc and cont_c = a.scd) as exceptie
          from act a
          join jv2007 j
            on a.an = j.an
           and a.luna = j.luna
           and a.id_fact = j.id_fact
          join nom_fdoc f on j.id_fdoc = f.id_fdoc 
          left join nom_valute nv
            on a.id_valuta = nv.id_valuta
          left join syn_nom_valute_iso vi
            on nv.id_valuta_iso = vi.id_valuta_iso
		  left join vsaft_taxtable st on a.taxcode = st.taxcode             
         where a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and a.sters = 0
           and a.id_set <> 99996
           and a.taxcode is not null
           AND substr(a.scd, 1, 3) <> '442' and substr(a.scc, 1, 3) <> '442'   
           and j.id_fact in
               (select id_fact
                  from vanzari
                 where extract(year from data_act) * 12 +
                       extract(month from data_act) between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                        and id_fact is not null and sters = 0
                union
                select id_fact
                  from rul
                 where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                      and id_fact is not null and sters = 0)
           and f.tip_doc in ('F', 'M'))
 group by id_fact,
          cod,
          id_valuta,
          curs,
          taxcode,
          taxtype,
          taxname,
          proc_tva,
          cod_valuta,
          decode(exceptie, 1, scd, scc)	      		
			ENDTEXT 
			llSucces = goExecutor.oExecuta(m.lcSql, m.lcCursorLinesTemp)					
			
			IF m.llSucces
			
				SELECT (m.lcCursorLines)
				APPEND FROM DBF(m.lcCursorLinesTemp)
				USE IN (SELECT(m.lcCursorLinesTemp))


				* la Tip = 4 note din Registrul Jurnal aferente facturilor din gestiune
				* verific daca suma din gestiune pe taxcode = suma din registrul jurnal pe taxcode si las doar diferentele fata de rulaj
				* articolele preluate din gestiune au pretul in lei
				*******************************************

				* Diferente valori pe fiecare taxcode tip = 1, 2 (facturi din facturare, gestiune)
				SELECT a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont, ;
					SUM(ROUND(b.cantitate * b.pret,2)) as valoare, ;
					SUM(ROUND(b.cantitate * b.pretv,2)) as valoarev ;			
					FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
					WHERE INLIST(b.tip, 1, 2) ;
					GROUP BY a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont ;
					order by a.an, a.luna, a.dataact, a.nract ;
					INTO CURSOR cFacturiTaxCode2 READWRITE 

				SELECT a.id_fact, b.taxcode, ;
					SUM(ROUND(b.cantitate * b.pret,2)) as valoare, ;
					SUM(ROUND(b.cantitate * b.pretv,2)) as valoarev ;			
					FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
					WHERE INLIST(b.tip, 1, 2) ;
					GROUP BY a.id_fact, b.taxcode ;
					INTO CURSOR cFacturiTaxCode2a
					
				   			
				* suma din Registrul Jurnal fara TVA, pentru documentele introduse din gestiune
				* tratez regularizare facturi nesosite/neintocmite 408=401, 4111=418
				SELECT a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont, ;
					SUM(ROUND(b.cantitate * b.pret,2)) as valoare, ;
					SUM(ROUND(b.cantitate * b.pretv,2)) as valoarev ;			
					FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
					WHERE b.tip = 4 ;
					GROUP BY a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont ;
					order by a.an, a.luna, a.dataact, a.nract ;
					INTO CURSOR cFacturiTaxCode4

				SELECT a.id_fact, b.taxcode, ;
					SUM(ROUND(b.cantitate * b.pret,2)) as valoare, ;
					SUM(ROUND(b.cantitate * b.pretv,2)) as valoarev ;			
					FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
					WHERE b.tip = 4 ;
					GROUP BY a.id_fact, b.taxcode ;
					INTO CURSOR cFacturiTaxCode4a
					
				SELECT NVL(a.id_fact, b.id_fact) as id_fact, NVL(a.taxcode, b.taxcode) as taxcode, ;
					a.valoare as valoare2, b.valoare as valoare4, a.valoarev as valoarev2, b.valoarev as valoarev4 ;
					FROM cFacturiTaxCode2a a FULL JOIN cFacturiTaxCode4a b ON a.id_fact = b.id_fact AND a.taxcode = b.taxcode ;
					INTO CURSOR cFacturiTaxCode24a 
					
				USE IN (SELECT('cFacturiTaxCode2a'))	
				USE IN (SELECT('cFacturiTaxCode4a'))				

				SELECT cFacturiTaxCode4
				SCAN 
					SCATTER NAME loRec

					* Completez contul in liniile care nu au cont
					UPDATE (m.lcCursorLines) SET cont = loRec.cont WHERE id_fact = loRec.id_fact AND taxcode = loRec.taxcode AND EMPTY(NVL(cont,'')) AND INLIST(tip,1,2)
					UPDATE cFacturiTaxCode2  SET cont = loRec.cont WHERE id_fact = loRec.id_fact AND taxcode = loRec.taxcode AND EMPTY(NVL(cont,''))

					SELECT cFacturiTaxCode2
					LOCATE FOR id_fact = loRec.id_fact AND taxcode = loRec.taxcode AND cont = loRec.cont
					IF FOUND()
						lnSuma = valoare
						lnSumaV = valoarev
					ELSE
						lnSuma = 0	
						lnSumaV = 0
					ENDIF 
					lnDiferenta = NVL(lorec.valoare,0) - NVL(m.lnSuma,0)
					lnDiferentaV = NVL(lorec.valoarev,0) - NVL(m.lnSumaV,0)
	
					* Verific valoarea doar pe taxcode, fara cont (este posibil sa modifice contul in contabilitate)
					llDiferentaContabilitate = .F.
					SELECT cFacturiTaxCode24a
					LOCATE FOR id_fact = loRec.id_fact AND taxcode = loRec.taxcode
					IF FOUND()
						llDiferentaContabilitate = (ABS(valoare4-valoare2) > 0.05)
					ENDIF 

					* Daca este diferenta facturare+gestiune fata de contabilitate pe total taxcode si diferenta este mai mare de 0.05
					IF m.llDiferentaContabilitate AND ABS(m.lnDiferenta) > 0.05

						SELECT (m.lcCursorLines)
						LOCATE FOR id_fact = loRec.id_fact AND taxcode = loRec.taxcode AND cont = loRec.cont AND tip = 4
						IF FOUND()
							REPLACE pret WITH m.lnDiferenta, pretv WITH m.lnDiferentaV, descriere WITH 'DIFERENTA'
							IF SIGN(pret) = -1
								REPLACE cantitate WITH -1*cantitate, pret WITH ABS(pret), pretv WITH ABS(pretv)
							ENDIF 
							IF pretv = 0
								REPLACE id_valuta WITH null, cod_valuta WITH null, curs WITH null 
							ENDIF 
						ENDIF 	
					ENDIF 
				ENDSCAN 
				
				USE IN (SELECT('cFacturiTaxCode24a'))

				* Sterg liniile articolelor tip = 4 pe care nu le-am modificat cu diferenta fata de rulaj
				DELETE FROM (m.lcCursorLines) WHERE tip = 4 AND descriere = 'VERIFICARE'
				*******************************************
				
					
				* Completare Nr. Crt.
				lnIdFact = -1
				lnNrCrt = 0
				SELECT (m.lcCursorLines)
				SCAN 
					IF id_fact <> m.lnIdFact
						lnNrCrt = 0
						lnIdFact = id_fact
					ENDIF 
					lnNrCrt = lnNrCrt + 1
					REPLACE nrcrt WITH m.lnNrCrt
				ENDSCAN 

				UPDATE (m.lcCursorLines) SET taxa = ROUND(ROUND(cantitate * pret, 2) * proc_tva / 100, 2), ;
					taxav = ROUND(ROUND(cantitate * pretv, 2) * proc_tva / 100, 2), ;
					valoare = ROUND(cantitate * pret, 2), valoarev = ROUND(cantitate * pretv, 2)
					
				* Unificare elemente facturi de pe facturi duplicate (introduse din gestiune, contabilitate, facturare)
				SELECT (m.lcCursor)
				SCAN FOR id_fact <> id_fact2
					SCATTER NAME loFact
					UPDATE (m.lcCursorLines) SET id_fact = loFact.id_fact2 WHERE id_fact = loFact.id_fact
				ENDSCAN 
				DELETE FROM (m.lcCursor) WHERE id_fact <> id_fact2
			ENDIF 
		ENDIF && m.llSucces			
		
		GO TOP IN (m.lcCursor)

		SELECT (m.lcSelect)
		RETURN m.llSucces
	ENDFUNC 

	************************************************
	* cursor cPurchaseInvoice, cPurchaseInvoicesLines
	* din registrul jurnal iau doar inregistrarile care au taxcode pentru a genera articole. nu iau orice nota contabila
	************************************************
	Function oPurchaseInvoices
		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lcCursor, lcCursorLines, lcCursorPartener
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		lcCursor = 'cPurchaseInvoices'
		lcCursorTemp = 'cPurchaseInvoicesTemp'
		lcCursorLines = 'cPurchaseInvoicesLines'
		lcCursorLinesTemp = 'cPurchaseInvoicesLinesTemp'		
		lcCursorPartener = "cSuppliers"

		Create Cursor cPurchaseInvoicesLines(;
			tip         N(1) null,;
			id_fact     N(20) null,;
			nrcrt		N(10) null,;
			cod         N(20) null,;
			descriere	C(100) null,;	
			cantitate   N(20,6) null,;
		    pret_cu_tva N(1) null,;	
			pret        N(20,4) null,;
			pretv       N(20,4) null,;
			valoare     N(20,4) null,;
			valoarev    N(20,4) null,;			
			taxa       N(20,4) null,;	
			taxav       N(20,4) null,;	
			id_valuta   N(5) null,;
			curs        N(14,4) null,;
			taxcode     N(6) null,;
			taxtype     N(3) null,;
			taxname     C(250) null,;	
			proc_tva    N(5) null,;
			cod_valuta  C(5) null,;
			cont        C(4) null)
					
		Text To m.lcSql Noshow Textmerge
Select j2.an,
       j2.luna,
       j2.id_fact,
       j2.cod,
       j2.nract,
       j2.dataact,
       j2.id_part,
       p.denumire,
       j2.totctva,
	   CAST(null as varchar2(30)) as saftpartid,
       CAST(null as varchar2(100)) as localitate,
       CAST(null as varchar2(100)) as cod_tara,
       case
         when j2.tip_saft is not null then j2.tip_saft
         when j2.totctva < 0 then 381
         else 380
       end as invoicetype,
       decode(nvl(j2.autofactura, 0), 0, 0, 389) as autofactura,
       (select MAX(scc) as cont from act where cod = j2.cod and SUBSTR(scc, 1, 2) in ('40', '46')) as cont
  from (select j.an,
               j.luna,
               j.id_fact,
               j.cod,
               j.nract,
               j.dataact,
               j.id_part,
               j.totctva,
               d.tip_saft,
               0 as autofactura
          from jc2007 j join nom_fdoc f on j.id_fdoc = f.id_fdoc 
          left join documente d on j.id_fact = d.id_doc
         where j.an * 12 + j.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
         and extract(year from j.dataireg) = j.an and extract(MONTH from j.dataireg) = j.luna
         and f.tip_doc in ('F', 'M', 'C', 'INV')) j2   
         left join nom_parteneri p on j2.id_part = p.id_part
	   order by j2.an, j2.luna, j2.dataact, j2.nract, p.denumire         
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, m.lcCursorTemp)
	
		IF m.llSucces
			SELECT an, luna, id_fact, id_fact as id_fact2, cod, nract, TTOD(dataact) as dataact, id_part, denumire, totctva, saftpartid, localitate, cod_Tara, ;
				invoicetype, ;
				ALLTRIM(STR(invoicetype)) + ' - ' + IIF(invoicetype = 380, 'FACTURA INITIALA', IIF(invoicetype = 381, 'FACTURA STORNO', IIF(invoicetype = 384, 'FACTURA FINALA', IIF(invoicetype = 389, 'AUTOFACTURA', 'FACTURA INITIALA')))) as invoicetypet, ;
				INT(autofactura) as autofactura, cont ;
				FROM (m.lcCursorTemp) ;
				INTO CURSOR (m.lcCursor) READWRITE 

			USE IN (SELECT(m.lcCursorTemp))	 

			* Unific facturile introduse din mai multe bucati (gestiune, facturare, contabilitate)   			
			SELECT nract, dataact, id_part, MIN(id_fact) as id_fact, SUM(totctva) as totctva, COUNT(*) as nr ;
				FROM (m.lcCursor) ;
				group BY nract, dataact, id_part ;
				HAVING COUNT(*) > 1 ;
				INTO CURSOR cFacturiDup READWRITE 

			SELECT cFacturiDup
			SCAN 
				SCATTER NAME loFact
				UPDATE (m.lcCursor) SET id_fact2 = loFact.id_fact, totctva = loFact.totctva WHERE nract = loFact.nract AND dataact = loFact.dataact AND id_part = loFact.id_part
			ENDSCAN 
			USE IN (SELECT('cFacturiDup'))
			
			SELECT id_fact, id_fact2 FROM (m.lcCursor) WHERE id_fact <> id_fact2 INTO CURSOR cPurchaseInvoicesDup			
									
			* Completez saftpartid, localitate, cod_tara din cCustomers/cSuppliers
			* UPDATE (m.lcCursor) SET SaftPartId = This.GetCustSupCode('SUPPLIERS', id_part) WHERE !EMPTY(NVL(id_part,0))

			SELECT distinct id_part FROM (m.lcCursor) INTO CURSOR cIdpartTemp
			SELECT cIdPartTemp
			SCAN
				lnIdPart = id_part
				IF SEEK(m.lnIdPart, m.lcCursorPartener,'id_part')
					lcSaftPartId = ALLTRIM(&lcCursorPartener..SaftPartId)
					lcLocalitate = ALLTRIM(&lcCursorPartener..localitate)
					lcCodTara = ALLTRIM(&lcCursorPartener..cod_Tara)
					UPDATE (m.lcCursor) SET saftPartId = m.lcSaftPartId, localitate = m.lcLocalitate, cod_tara = m.lcCodTara WHERE id_part = m.lnIdPart
				ENDIF 
			ENDSCAN 
			USE IN (SELECT('cIdpartTemp'))

			* Completez SAFTPARTID contribuabil raportor daca nu exista partener in Registrul TVA
			lcSaftPartId = '00' + This.oUnitate.codi
			UPDATE (m.lcCursor) SET saftPartId = m.lcSaftPartId WHERE EMPTY(NVL(id_part,0))
								
			* LINII FACTURI
			* Tip 1 = vanzari detalii (nu se aplica)
			* Tip = 2 articole facturi din gestiune (rul)
			* mai sunt diferente intre liniile din Rulaj si notele contabile, posibil din rotunjiri pe baza/TVA, pentru care s-au pus note suplimentare in Registrul Jurnal
			* Trebuie sa generez linie cu articol din nota din Registrul Jurnal 

			* Tip = 3 articole facturi din Contabilitate (act) - tratez cazul 408 = 401 total cu TVA. Pun doar 100/119 din suma pe baza
			* Tip = 4 note din contabilitate (act) ex: cheltuieli rotunjire zecimale, transport, discount pentru facturile din gestiune 
			* Tip 4 se sterge si se lasa doar diferentele fata de Tip = 2
			TEXT TO  m.lcSql NOSHOW textmerge
select 2 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       r.id_fact,
       r.cod,
       CAST(a.denumire as varchar2(100)) as descriere,           
       r.cant as cantitate,
       0 as pret_cu_tva,
       r.pret as pret,
       r.pretd as pretv,
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,       
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,       
       r.id_valuta,
       r.curs,
       r.taxcode,
       st.taxtype,
       st.taxname,
	   st.procent_taxa as proc_tva,
       vi.iso_valuta as cod_valuta,
       r.cont
  from rul r
  join jc2007 j
    on r.an = j.an
   and r.luna = j.luna
   and r.id_fact = j.id_fact
  join nom_fdoc f on j.id_fdoc = f.id_fdoc  
  left join nom_valute nv
    on r.id_valuta = nv.id_valuta
  left join syn_nom_valute_iso vi
    on nv.id_valuta_iso = vi.id_valuta_iso 
  left join nom_articole a on r.id_articol = a.id_articol 
  left join vsaft_taxtable st on r.taxcode = st.taxcode    
 where r.an * 12 + r.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
   and f.tip_doc in ('F', 'M', 'C', 'INV')
   and r.sters = 0
union all
select 3 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       id_fact,
       cod,
       CAST(MAX(explicatia) as varchar2(100)) as descriere,
       1 as cantitate,
       0 as pret_cu_tva,       
       sum(decode(exceptie, 1, -1, 1) * suma) as pret,
       sum(decode(exceptie, 1, -1, 1) * suma_val) as pretv, 
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,             
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,       
       id_valuta,
       curs,
       taxcode,
       taxtype,
       taxname,
       proc_tva,
       cod_valuta,
       decode(exceptie, 1, scc, scd) as cont
  from (select a.id_fact,
               a.cod,
               a.explicatia,
               (CASE when a.scd = '408' AND a.scc like '4%' then ROUND(a.suma * 100 / (100 + st.procent_taxa), 2) else a.suma end) as suma,
			   (CASE when a.scd = '408' AND a.scc like '4%' then ROUND(a.suma_val * 100 / (100 + st.procent_taxa), 2) else a.suma_val end) as suma_val,               
               a.id_valuta,
               a.curs,
               a.taxcode,
               st.taxtype,
               st.taxname,
               st.procent_taxa as proc_tva,
               vi.iso_valuta as cod_valuta,
               a.scd,
               a.scc,
               (SELECT DISTINCT 1 AS EXCEPTIE
                  FROM EXCEPTII_IREG
                 WHERE INVERS = 1
                   AND CONT = a.scd and cont_c = a.scc) as exceptie
          from act a
          join jc2007 j
            on a.an = a.an
           and a.luna = j.luna
           and a.id_fact = j.id_fact
          join nom_fdoc f on j.id_fdoc = f.id_fdoc 
          left join nom_valute nv
            on a.id_valuta = nv.id_valuta
          left join syn_nom_valute_iso vi
            on nv.id_valuta_iso = vi.id_valuta_iso
		  left join vsaft_taxtable st on a.taxcode = st.taxcode             
         where a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and a.sters = 0
           and a.taxcode is not null
           AND substr(a.scd, 1, 3) <> '442' and substr(a.scc, 1, 3) <> '442'           
           and j.id_fact not in
               (select id_fact
                  from rul
                 where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                   and id_fact is not null and sters=0)
           and f.tip_doc in ('F', 'M', 'C', 'INV'))
 group by id_fact,
          cod,
          id_valuta,
          curs,
          taxcode,
          taxtype,
          taxname,
          proc_tva,
          cod_valuta,
          decode(exceptie, 1, scc, scd)	
union all
select 4 as tip,
	   CAST(0 as number(5,0)) as nrcrt,
       id_fact,
       cod,
       CAST('VERIFICARE' as varchar2(100)) as descriere,
       1 as cantitate,
       0 as pret_cu_tva,       
       sum(decode(exceptie, 1, -1, 1) * suma) as pret,
       sum(decode(exceptie, 1, -1, 1) * suma_val) as pretv, 
       CAST(0 as number(20,4)) as valoare,
       CAST(0 as number(20,4)) as valoarev,             
	   CAST(0 as number(20,4)) as taxa,
	   CAST(0 as number(20,4)) as taxav,       
       id_valuta,
       curs,
       taxcode,
       taxtype,
       taxname,
       proc_tva,
       cod_valuta,
       decode(exceptie, 1, scc, scd) as cont
  from (select a.id_fact,
               a.cod,
               a.explicatia,
               (CASE when a.scd = '408' AND a.scc like '4%' then ROUND(a.suma * 100 / (100 + st.procent_taxa), 2) else a.suma end) as suma,
			   (CASE when a.scd = '408' AND a.scc like '4%' then ROUND(a.suma_val * 100 / (100 + st.procent_taxa), 2) else a.suma_val end) as suma_val,              
               a.id_valuta,
               a.curs,
               a.taxcode,
               st.taxtype,
               st.taxname,
               st.procent_taxa as proc_tva,
               vi.iso_valuta as cod_valuta,
               a.scd,
               a.scc,
               (SELECT DISTINCT 1 AS EXCEPTIE
                  FROM EXCEPTII_IREG
                 WHERE INVERS = 1
                   AND CONT = a.scd and cont_c = a.scc) as exceptie
          from act a
          join jc2007 j
            on a.an = a.an
           and a.luna = j.luna
           and a.id_fact = j.id_fact
          join nom_fdoc f on j.id_fdoc = f.id_fdoc 
          left join nom_valute nv
            on a.id_valuta = nv.id_valuta
          left join syn_nom_valute_iso vi
            on nv.id_valuta_iso = vi.id_valuta_iso
		  left join vsaft_taxtable st on a.taxcode = st.taxcode             
         where a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
           and a.sters = 0
           and a.taxcode is not null
           AND substr(a.scd, 1, 3) <> '442' and substr(a.scc, 1, 3) <> '442'  
           and j.id_fact in
               (select id_fact
                  from rul
                 where an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                   and id_fact is not null and sters=0)
           and f.tip_doc in ('F', 'M', 'C', 'INV'))
 group by id_fact,
          cod,
          id_valuta,
          curs,
          taxcode,
          taxtype,
          taxname,
          proc_tva,
          cod_valuta,
          decode(exceptie, 1, scc, scd)             		       
			ENDTEXT 
			
			llSucces = goExecutor.oExecuta(m.lcSql, m.lcCursorLinesTemp)

		*5331938
			IF m.llSucces
				SELECT (m.lcCursorLines)
				APPEND FROM DBF(m.lcCursorLinesTemp)
				USE IN (SELECT(m.lcCursorLinesTemp))
				
				* la Tip = 4 note din Registrul Jurnal aferente facturilor din gestiune
				* verific daca suma din gestiune pe taxcode = suma din registrul jurnal pe taxcode si las doar diferentele fata de rulaj
				* articolele preluate din gestiune au pretul in lei
				*******************************************

				* Diferente valori pe fiecare taxcode tip = 2 (facturi din gestiune)
				SELECT a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont, ;
					SUM(b.cantitate * b.pret) as valoare, ;
					SUM(b.cantitate * b.pretv) as valoarev ;			
					FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
					WHERE b.tip = 2 ;
					GROUP BY a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont ;
					order by a.an, a.luna, a.dataact, a.nract ;
					INTO CURSOR cFacturiTaxCode2

				   			
				* suma din Registrul Jurnal fara TVA, pentru documentele introduse din gestiune, scd = 3xx, tip = 4
				* tratez regularizare facturi nesosite/neintocmite 408=401, 4111=418
				SELECT a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont, ;
					SUM(b.cantitate * b.pret) as valoare, ;
					SUM(b.cantitate * b.pretv) as valoarev ;			
					FROM (m.lcCursor) a LEFT JOIN (m.lcCursorLines) b ON a.id_fact = b.id_fact ;
					WHERE b.tip = 4 ;
					GROUP BY a.an, a.luna, a.id_fact, a.nract, a.dataact, a.id_part, a.denumire, b.taxcode, b.cont ;
					order by a.an, a.luna, a.dataact, a.nract ;
					INTO CURSOR cFacturiTaxCode4
							
				SELECT cFacturiTaxCode4
				SCAN 
					SCATTER NAME loRec
					SELECT cFacturiTaxCode2
					LOCATE FOR id_fact = loRec.id_fact AND taxcode = loRec.taxcode AND cont = loRec.cont
					IF FOUND()
						lnSuma = valoare
						lnSumaV = valoarev
					ELSE
						lnSuma = 0	
						lnSumaV = 0
					ENDIF 
					lnDiferenta = NVL(lorec.valoare,0) - NVL(m.lnSuma,0)
					lnDiferentaV = NVL(lorec.valoarev,0) - NVL(m.lnSumaV,0)
					IF ABS(m.lnDiferenta) > 0.05
						SELECT (m.lcCursorLines)
						LOCATE FOR id_fact = loRec.id_fact AND taxcode = loRec.taxcode AND cont = loRec.cont AND tip = 4
						IF FOUND()
							REPLACE pret WITH m.lnDiferenta, pretv WITH m.lnDiferentaV, descriere WITH 'DIFERENTA'
						ENDIF 	
					ENDIF 
				ENDSCAN 
				* Sterg liniile articolelor tip = 4 pe care nu le-am modificat cu diferenta fata de rulaj
				DELETE FROM (m.lcCursorLines) WHERE tip = 4 AND descriere = 'VERIFICARE'
				*******************************************
				
				* Completare Nr. Crt.
				lnIdFact = -1
				lnNrCrt = 0
				SELECT (m.lcCursorLines)
				SCAN 
					IF id_fact <> m.lnIdFact
						lnNrCrt = 0
						lnIdFact = id_fact
					ENDIF 
					lnNrCrt = lnNrCrt + 1
					REPLACE nrcrt WITH m.lnNrCrt
				ENDSCAN 
				
				UPDATE (m.lcCursorLines) SET taxa = ROUND(ROUND(cantitate * pret, 2) * proc_tva / 100, 2), ;
					taxav = ROUND(ROUND(cantitate * pretv, 2) * proc_tva / 100, 2), ;
					valoare = ROUND(cantitate * pret, 2), valoarev = ROUND(cantitate * pretv, 2)
					
				* Unificare elemente facturi de pe facturi duplicate (introduse din gestiune, contabilitate, facturare)
				SELECT (m.lcCursor)
				SCAN FOR id_fact <> id_fact2
					SCATTER NAME loFact
					UPDATE (m.lcCursorLines) SET id_fact = loFact.id_fact2 WHERE id_fact = loFact.id_fact
				ENDSCAN 
				DELETE FROM (m.lcCursor) WHERE id_fact <> id_fact2
				
				
			ENDIF 								
		ENDIF && m.llSucces			

		GO TOP IN (m.lcCursor)
				
		USE IN (SELECT('cFacturiTaxCode2'))
		USE IN (SELECT('cFacturiTaxCode4'))				

		SELECT (m.lcSelect)
		RETURN m.llSucces
	ENDFUNC 

************************************************
* cursor cPayments
* iau toate inregistrarile din act care au paymentcode completat
************************************************
	Function oPayments

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		Create Cursor cPayments(;
			an          N(6) null,;
			luna        N(4) null,;
			cod         N(20) null,;	
			id_fact     N(20) null,;
			dataact     T(8) null,;
			cont        C(4) null,;
			tipdc       C(4) null,;
			id_part     N(20) null,;
			saftpartid	C(30) null,;	
			taxtype     N(3) null,;
			taxcode     N(6) null,;
			taxname		C(250) null,;
			paymentcode C(9) null,;
			paymentname C(250) null,;
			methodcode C(10) NULL, ;
			id_valuta   N(7) null,;
			curs        N(14,6) null,;
			explicatia  C(250) null, ;
			suma        N(20,4) null,;
			suma_val    N(20,4) null,;
			denumire    C(250) null, ;
			cod_fiscal  C(30) null,;
			tip_persoana N(1) null,;
			cod_tara    C(5) null,;
			cod_valuta  C(3) null)
			
		Text To m.lcSql Noshow Textmerge
select c.an,
       c.luna,
       c.cod,
       c.id_fact,
       c.dataact,
       c.cont,
       c.tipdc,
       c.id_part,
       tx.taxtype,
       c.taxcode,
       tx.taxname,
       c.paymentcode,
       mp.paymentname, 
       mp.methodcode,      
       c.id_valuta,
       c.curs,
       decode(c.explicatia, NULL, decode(c.tipdc, 'D','INCASARE', 'PLATA'), c.explicatia) as explicatia,
       c.suma,
       c.suma_val,
       p.denumire,
       p.cod_fiscal,
       p.tip_persoana,
       t.prescurtare as cod_tara,
       nvl(v.nume_val2, 'RON') as cod_valuta,
       CAST(null as varchar2(30)) as saftpartid
  from (select an,
               luna,
               cod,
               id_fact,
               dataact,
               cont,
               tipdc,
               id_part,
               taxcode,
               paymentcode,
               id_valuta,
               curs,
               max(explicatia) as explicatia,
               sum(suma) as suma,
               sum(suma_val) as suma_val
          from (select a.an,
                       a.luna,
                       a.cod,
                       a.id_fact,
                       a.dataact,
                       case
                         when substr(a.scd, 1, 3) in ('512', '531', '508') then
                          scc
                         when substr(a.scc, 1, 3) in ('512', '531', '508') then
                          scd
                         when substr(a.scd, 1, 3) in
                              ('411',
                               '401',
                               '404',
                               '409',
                               '461',
                               '462',
                               '418',
                               '419',
                               '473') then
                          scd
                         when substr(a.scc, 1, 3) in
                              ('411',
                               '401',
                               '404',
                               '409',
                               '461',
                               '462',
                               '418',
                               '419',
                               '473') then
                          scc
                         when a.id_factd <> 0 then
                          scd
                         when a.id_factc <> 0 then
                          scc
                         else
                          cast(null as varchar2(4))
                       end as cont,
                       case
                         when substr(a.scd, 1, 3) in ('512', '531', '508') then
                          'D'
                         when substr(a.scc, 1, 3) in ('512', '531', '508') then
                          'C'
                         when substr(a.scd, 1, 3) in
                              ('411',
                               '401',
                               '404',
                               '409',
                               '461',
                               '462',
                               '418',
                               '419',
                               '473') then
                          'C'
                         when substr(a.scc, 1, 3) in
                              ('411',
                               '401',
                               '404',
                               '409',
                               '461',
                               '462',
                               '418',
                               '419',
                               '473') then
                          'D'
                         when a.id_factd <> 0 then
                          'C'
                         when a.id_factc <> 0 then
                          'D'
                         else
                          cast(null as varchar2(4))
                       end as tipdc,
                       case
                         when substr(a.scd, 1, 3) in ('512', '531', '508') then
                          id_partc
                         when substr(a.scc, 1, 3) in ('512', '531', '508') then
                          id_partd
                         when substr(a.scd, 1, 3) in
                              ('411',
                               '401',
                               '404',
                               '409',
                               '461',
                               '462',
                               '418',
                               '419',
                               '473') then
                          id_partd
                         when substr(a.scc, 1, 3) in
                              ('411',
                               '401',
                               '404',
                               '409',
                               '461',
                               '462',
                               '418',
                               '419',
                               '473') then
                          id_partc
                         when a.id_factd <> 0 then
                          id_partd
                         when a.id_factc <> 0 then
                          id_partc
                         else
                          cast(null as number(10))
                       end as id_part,
                       a.taxcode,
                       a.paymentcode,
                       a.id_valuta,
                       a.curs,
                       a.suma,
                       a.suma_val,
                       a.explicatia
                  from act a 
                 where a.sters = 0
                   and a.an * 12 + a.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
                   and a.paymentcode is not null and scd <> '581' and scc <> '581' and not (substr(a.scd, 1, 3) in ('512', '531', '542') and  substr(a.scc, 1, 3) in ('512', '531', '542'))) a
         group by an,
                  luna,
                  cod,
                  id_fact,
                  dataact,
                  cont,
                  tipdc,
                  id_part,
                  taxcode,
                  paymentcode,
                  id_valuta,
                  curs) c
  left join vsaft_taxtable tx
    on c.taxcode = tx.taxcode
  left join nom_parteneri p
    on c.id_part = p.id_part
  left join adrese_parteneri ap
    on (p.id_part = ap.id_part and ap.sters = 0 and ap.principala = 1)
  left join syn_nom_tari t
    on t.id_tara = ap.id_tara
  left join vnom_valute v
    on c.id_valuta = v.id_valuta
  left join vsaft_mecanisme_plati mp on c.paymentcode = mp.mechanismcode
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cPaymentsTemp')
		IF m.llSucces
			SELECT cPayments
			APPEND FROM DBF('cPaymentsTemp')
			USE IN (SELECT('cPaymentsTemp'))

			UPDATE cPayments SET SaftPartId = This.GenCustSupCode(id_part, cod_tara, tip_persoana, cod_fiscal) WHERE !EMPTY(NVL(id_part,0))
		ENDIF 
		GO TOP IN cPayments

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oPayments

************************************************
* cursor cAnalysisTypeTable
************************************************
	Function oAnalysisTypeTable

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()

* AnalysisTypeTable
		Text To m.lcSql Noshow Textmerge
select id_sectie,
       id_sucursala,
       'S' || CASE
         WHEN id_sucursala is NOT NULL THEN
          id_sucursala
         else
          0
       end || '-C' || id_sectie as cod,
       case
         when id_sucursala is not null then
          sucursala
         else
          'S0'
       end || '-' || sectie as descriere
  from vnom_sectii
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cAnalysisTypeTable')
		If m.llSucces
			Select cAnalysisTypeTable
			Index On Padl(Nvl(id_sucursala, 0), 20, '0') + Padl(Nvl(id_sectie, 0), 20, '0') Tag cod
		Endif

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oAnalysisTypeTable

	************************************************
	* cursor cOwners
	************************************************
	Function oOwners
		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		Text To m.lcSql Noshow Textmerge
SELECT s.id_part,
	   NVL(TRIM(p.denumire), 'NEDEFINIT') as denumire,
       p.cod_fiscal,
       p.tip_persoana,
       a.strada,
       a.numar,
       a.localitate,
       a.indicativ_judet,      
       a.cod_tara,
	   CAST(null as varchar2(30)) as saftpartid 
from (select distinct id_part_rez as id_part
		FROM stoc
		WHERE an * 12 + luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
		and SUBSTR(cont,1,2) = '35' and NVL(id_part_rez,0) <> 0) s 
	 join nom_parteneri p on s.id_part = p.id_part
	 LEFT JOIN (SELECT ap.id_part,
	                    ap.strada,
	                    ap.numar,
	                    l.localitate,
	                    j.indicativ   as indicativ_judet,
	                    ap.codpostal,
	                    t.prescurtare as cod_tara
	               FROM ADRESE_PARTENERI ap
	               left join syn_nom_localitati l
	                 on l.id_loc = ap.id_loc
	               left join syn_nom_judete j
	                 on j.id_judet = l.id_judet
	               left join syn_nom_tari t
	                 on t.id_tara = ap.id_tara
	              WHERE ap.STERS = 0
	                AND ap.PRINCIPALA = 1) a
	    ON p.id_part = a.id_part	
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cOwners')
		IF m.llSucces
			UPDATE cOwners SET SaftPartId = This.GenCustSupCode(id_part, cod_tara, tip_persoana, cod_fiscal) WHERE !EMPTY(NVL(id_part,0))
			SELECT cOwners
			INDEX on id_part TAG id_part
			SET ORDER TO  
		ENDIF 
		GO TOP IN cOwners
		* da eroare la validare pe anaf daca <owners> este gol
		IF RECCOUNT('cOwners') = 0
			APPEND BLANK 
			REPLACE saftpartid WITH '00' + This.oUnitate.codi, denumire WITH Alltrim(gofirma.firma), localitate WITH gofirma.localitate, cod_tara WITH gofirma.cod_tara, strada WITH goFirma.strada, numar WITH goFirma.numar, indicativ_judet WITH  goFirma.indicativ_judet	
		ENDIF 
		
		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oOwners
	
	************************************************
	* cursor cAssets, cAssetTransactions
	************************************************
	Function oAssets
		PRIVATE pdDataJ1, pdDataJ2
		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		Local lcCursor, lnFiscal, lnTip, lnAn, lnLuna, lcListaCursoare
		Local lnIdMf, lnIesire, lnIntrare, lnMajorare, lnNrLuni1, lnNrLuni2, lnReevaluare, lnIdOpPrec 
		Local lcCursorAssets, lcCursorAssetsFinal, lcCursorAssetsInitial, lnCursor
		Local lnNrLuna, lnNrLuni
		lcSelect = Select()

		CREATE CURSOR cAssets (id_mf I, AssetId C(35) null, AccountId C(20) null, DateOfAcquisition D null, StartUpDate D null, Description C(100) null, ;
			AssetValuationType C(20) null, ValuationClass C(20) null, AcquisitionAndProductionCostsBegin N(18,2) null, AcquisitionAndProductionCostsEnd N(18,2) null, InvestmentSupport N(18,2) null, ;
			AssetLifeYear N(18,4) null, DepreciationMethod C(20) null, DepreciationPercentage N(18,4) null, ;
			AssetAddition N(18,2) null, Transfers N(18,2) null, AssetDisposal N(18,2) null, BookValueBegin N(18,2) null,DepreciationForPeriod N(18,2) null, AppreciationForPeriod N(18,2) null,;
			ExtraordinaryDepreciationMethod C(35) null, ExtraordinaryDepreciationAmountForPeriod N(18,2) null,;
			AccumulatedDepreciation N(18,2) null, BookValueEnd N(18,2) null, tip_imobilizare C(30) null, ;
			AppreciationForPeriodMinus N(18,2) null, AccumulatedDepreciationBegin N(18,2) null)

		CREATE CURSOR cAssetTransactions (AssetTransactionID C(70) null, AssetID C(35) null, AssetTransactionType C(9) null, Description C(250) NULL, ;
			AssetTransactionDate D null, TransactionID C(70) null, AssetValuationType C(18) null, ;
			AcquisitionAndProductionCostsOnTransaction N(18,2) null, BookValueOnTransaction N(18,2) null, AssetTransactionAmount N(18,2) null, ;
			Denumire C(100) null, Tip_imobilizare C(30) null, id_mf I null)
			
		llSucces = .T.

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		lnNrLuni1 = m.lnAn1*12+m.lnLuna1
		lnNrLuni2 = m.lnAn2*12+m.lnLuna2
		lnNrLuni0 = m.lnNrLuni1 - 1 && decembrie anterior, pentru valoarea de inventar de la inceputul perioadei

		pdDataJ1 = Date(lnAn1, lnLuna1, 1)
		pdDataJ2 = GOMONTH(Date(lnAn2, lnLuna2, 1),1)-1
	
			
		* Obtin cursoare amortizari lunare
		lnFiscal = 0 && amortizarea contabila
		lnTip = 0 && toate imobilizarile
		lnNrLuna = 0

		FOR lnNrLuni = m.lnNrLuni0 TO m.lnNrLuni2
			lnNrLuna = m.lnNrLuna + 1
			lnAn = 0
			lnLuna = 0
			NrLuni2AnLuna(m.lnNrLuni, @lnAn, @lnLuna)
			* Luna inceput
			lcCursor = GET_CURSOR_AMORTIZARI(m.lnFiscal, m.lnAn, m.lnLuna, m.lnTip)
			llSucces = !Empty(lcCursor)
			lcCursorAssets = 'cAssets' + ALLTRIM(STR(m.lnNrLuna))
			
			IF m.llSucces
				* Selectez imobilizari corporale si necorporale, aflate in gestiune sau iesite din gestiune in perioada raportarii, fara terenuri cod_mf "0.0."
				SELECT * ;
				FROM (m.lcCursor) ;
				WHERE INLIST(id_tip_imobilizare,1,2) AND (IESIT_DIN_GEST = 0 OR (IESIT_DIN_GEST = 1 AND BETWEEN(YEAR(DATA_OPERATIE)*12+MONTH(data_operatie), m.lnNrLuni1, m.lnNrLuni2))) ;
				INTO CURSOR (m.lcCursorAssets)
			ENDIF 	
			* Deprecierea lunara (rata de amortizat)
			DO CASE 		
				CASE m.lnNrLuna = 1	&& luna decembrie anterioara, pentru valori initiale la inceputul perioadei
					SELECT m.lnNrLuni as nrluna, m.lnAn as an, m.lnLuna as luna, * FROM (m.lcCursorAssets) INTO CURSOR cAssets00
				CASE m.lnNrLuna = 2	&& luna ianuarie, prima luna din perioada
					SELECT m.lnNrLuni as nrluna, m.lnAn as an, m.lnLuna as luna, * FROM (m.lcCursorAssets) INTO CURSOR cAmortizareLunara READWRITE 
				OTHERWISE 
					SELECT m.lnNrLuni as nrluna, m.lnAn as an, m.lnLuna as luna, * FROM (m.lcCursorAssets) INTO CURSOR cAmortizareLunaraTemp READWRITE 
					
					SELECT cAmortizareLunara
					APPEND FROM DBF('cAmortizareLunaraTemp')
					USE IN (SELECT('cAmortizareLunaraTemp'))
			ENDCASE  	

			USE IN (select(m.lcCursor))
			USE IN (SELECT(m.lcCursorAssets))
		ENDFOR 	

		* Prima luna in care apare imobilizarea, ca sa citesc amortizarea precedenta cu care intra in perioada de raportare
		SELECT id_mf, MIN(nrluna) as nrluna ;
			FROM cAmortizareLunara ;
			GROUP BY id_mf ;
			INTO CURSOR cIdMfMin

		* Ultima luna in care apare imobilizarea
		SELECT id_mf, max(nrluna) as nrluna ;
			FROM cAmortizareLunara ;
			GROUP BY id_mf ;
			INTO CURSOR cIdMfMax

		SELECT a.* FROM cAmortizareLunara a JOIN cIdMfMin b ON a.id_mf = b.id_mf AND a.nrluna = b.nrluna INTO CURSOR cAssetsInitial && prima aparitie a imobilizarii intre ianuarie-decembrie
		SELECT a.* FROM cAmortizareLunara a JOIN cIdMfMax b ON a.id_mf = b.id_mf AND a.nrluna = b.nrluna INTO CURSOR cAssetsFinal && ultima aparitie a imobilizarii intre ianuarie-decembrie			
	
		SELECT a.* FROM cAmortizareLunara a WHERE a.nrluna = m.lnNrLuni1 INTO CURSOR cAssets01 && ianuarie
		SELECT a.* FROM cAmortizareLunara a WHERE a.nrluna = m.lnNrLuni2 INTO CURSOR cAssets12 && decembrie

		* Valori ale imobilizarilor existente la inceputul si/sau sfarsitul perioadei de raportare & existentei in imobilizari
		SELECT NVL(a1.id_mf, a2.id_mf) as id_mfa, CAST(ALLTRIM(STR(NVL(a1.id_tip_imobilizare, a2.id_tip_imobilizare))) + '_' + ALLTRIM(TRANSFORM(NVL(a1.nr_inventar, a2.nr_inventar))) as C(35)) as AssetId, ;
			NVL(a1.cont, a2.cont) as AccountId, ;
			TTOD(NVL(a1.data_achizitie, a2.data_achizitie)) as DateOfAcquisition, TTOD(NVL(a1.data_pif, a2.data_pif)) as StartUpDate, ;
			NVL(a1.denumire, a2.denumire) as Description, 'contabil' as AssetValuationType, NVL(a1.cod_mf, a2.cod_mf) as ValuationClass, ;
			CAST(IIF(YEAR(NVL(a1.data_pif, DATE()))*12+MONTH(NVL(a1.data_pif, DATE())) >= m.lnNrLuni1, 0, NVL(a00.valoare, 0)) as N(18,2)) as AcquisitionAndProductionCostsBegin, ;
			ROUND(NVL(a1.dns_luni, a2.dns_luni)/12,4) as AssetLifeYear, NVL(a1.tip_amortizare, a2.tip_amortizare) as DepreciationMethod, ;
			CAST(IIF(YEAR(NVL(a1.data_pif, DATE()))*12+MONTH(NVL(a1.data_pif, DATE())) >= m.lnNrLuni1, 0, NVL(a00.valoare,0)-NVL(a01.amort_prec,0)) as N(18,2))as BookValueBegin, ;
			NVL(a12.valoare,0)-NVL(a12.amort_prec,0) - NVL(a12.rata,0) as BookValueEnd, ;
			NVL(a1.tip_imobilizare, a2.tip_imobilizare) as tip_imobilizare ;
			from cAssetsInitial a1 FULL JOIN cAssetsFinal a2 ON a1.id_mf = a2.id_mf ;
			FULL JOIN cAssets00 a00 ON a1.id_mf = a00.id_mf ;
			FULL JOIN cAssets01 a01 ON a1.id_mf = a01.id_mf ;			
			FULL JOIN cAssets12 a12 ON a2.id_mf = a12.id_mf ;			
			INTO CURSOR cAssetsTemp1 READWRITE 
		
		USE IN (SELECT('cAssetsInitial'))	
		USE IN (SELECT('cAssetsFinal'))
		* USE IN (SELECT('cAssets01'))		
		* USE IN (SELECT('cAssets12'))

		* Amortizare precedenta
		SELECT a.id_mf, a.amort_prec, a.cota_an ;
			FROM cAmortizareLunara a JOIN cIdMfMin b ON a.id_mf = b.id_mf AND a.nrluna = b.nrluna ;
			INTO CURSOR cAmortizarePrec

		* Amortizare totala
		* daca amortizarea precedenta se modifica in perioada, amortizarea totala nu mai este egala cu amortizarea precedenta initiala + amortizarea in perioada
		* iau amortizarea precedenta din ultima luna + amortizarea din ultima luna
		SELECT a.id_mf, a.amort_prec + a.rata as amort_tot ;
			FROM cAmortizareLunara a JOIN cIdMfMax b ON a.id_mf = b.id_mf AND a.nrluna = b.nrluna ;
			INTO CURSOR cAmortizareTot
			
		USE IN (SELECT('cIdMfMin'))				
		USE IN (SELECT('cIdMfMax'))	
			
		* Amortizare in perioada
		SELECT id_mf, SUM(rata) as rata ;
			FROM cAmortizareLunara ;
			GROUP BY id_mf ;
			INTO CURSOR cAmortizareLuna
			

	SELECT NVL(a.id_mf, b.id_mf) as id_mf, CAST(NVL(a.rata, 0) as N(18,2)) as rata, CAST(NVL(b.amort_prec, 0) as N(18,2)) as amort_prec, CAST(NVL(b.cota_an, 0) as N(18,4)) as cota_an, ;
		CAST(NVL(c.amort_tot, 0) as N(18,2)) as amort_tot ;
		FROM cAmortizareLuna a FULL JOIN cAmortizarePrec b ON a.id_mf = b.id_mf ;
		FULL JOIN cAmortizareTot c ON a.id_mf = c.id_mf ;
		INTO CURSOR cAmortizarePerioada
		
	USE IN (SELECT('cAmortizareLuna'))	
	USE IN (SELECT('cAmortizarePrec'))	
	USE IN (SELECT('cAmortizareTot'))
	
	WAIT WINDOW 'Selectie operatii imobilizari ...' NOWAIT 

		* Operatii (intrare, iesire, majorare, reevaluare, transfer)
		TEXT TO lcSql TEXTMERGE NOSHOW 
select extract(year FROM data_operatie)*12+extract(month FROM data_operatie) as nrluna, id_tip_imobilizare, tip_imobilizare, 
	id_tip_operatie, id_tip_iesire, tip_operatie, id_operatie_mf, id_operatie_prec, data_operatie, 
	id_mf, denumire, id_calcul_rate, nr_inventar, valoare, valoare_ant, valoare_dif, valoare_ramasa, dns_ramas, valoare_iesire, rata, amort_prec 
	from imob_vjurnal_operatii_simplu 
	where (DATA_OPERATIE BETWEEN ?pdDataJ1 and ?pdDataJ2) and id_tip_imobilizare IN(1,2)
	ORDER BY ID_MF, ID_OPERATIE_MF
		ENDTEXT 
		
		llSucces = goExecutor.oExecuta(m.lcSql, "cJurnalImobTemp")

		* Valori jurnal cumulate pe id_mf (intrare, majorare, iesire, reevaluare)
		SELECT id_mf, ;
			CAST(SUM(IIF(INLIST(id_tip_operatie, 1, 2, 3), valoare_dif, 0)) as N(18,2)) as intrare, ;
			CAST(SUM(IIF(id_tip_operatie = 4, valoare, 0)) as N(18,2)) as iesire, ;
			CAST(SUM(IIF(INLIST(id_tip_operatie, 6, 12) OR (valoare_dif <> 0 AND !INLIST(id_tip_operatie, 1, 2, 3, 4, 5, 6, 7, 12, 15)), valoare_dif, 0)) as N(18,2)) as majorare, ;
			CAST(SUM(IIF(INLIST(id_tip_operatie, 7, 15) AND valoare_dif > 0, valoare_dif, 0)) as N(18,2)) as reevaluare, ;
			CAST(SUM(IIF(INLIST(id_tip_operatie, 7, 15) AND valoare_dif < 0, -valoare_dif, 0)) as N(18,2)) as reevaluareminus ;
			FROM cJurnalImobTemp ;
			GROUP BY id_mf ;
			INTO CURSOR cJurnalImobTemp2
				
		SELECT NVL(a.id_mfa, b.id_mf) as id_mfb, a.*, CAST(NVL(b.rata, 0) as N(18,2)) as DepreciationForPeriod, CAST(NVL(b.amort_tot,0) as N(18,2)) as AccumulatedDepreciation, ;
			CAST(NVL(b.amort_prec,0) as N(18,2)) as AccumulatedDepreciationBegin, ;
			CAST(NVL(b.cota_an,0) as N(18,4)) as DepreciationPercentage ;
			FROM cAssetsTemp1 a FULL JOIN cAmortizarePerioada b ON a.id_mfa = b.id_mf ;
			INTO CURSOR cAssetsTemp2
		USE IN (SELECT('cAmortizarePerioada'))
		USE IN (SELECT('cAssetsTemp1'))

		SELECT NVL(a.id_mfb, b.id_mf) as id_mf, a.*, ;
			CAST(NVL(a.AcquisitionAndProductionCostsBegin, 0.00) + NVL(b.intrare, 0.00) - NVL(b.iesire, 0.00) + NVL(b.majorare, 0.00) as N(18,2)) as AcquisitionAndProductionCostsEnd, ;
		 	CAST(NVL(b.intrare, 0.00) +  NVL(b.majorare, 0.00) as N(18,2)) as AssetAddition, ;
		 	CAST(NVL(b.iesire, 0.00) as N(18,2)) as AssetDisposal, ;
		 	CAST(NVL(b.reevaluare, 0.00) as N(18,2)) as AppreciationForPeriod, ;
		 	CAST(NVL(b.reevaluareminus, 0.00) as N(18,2)) as AppreciationForPeriodMinus ;		
	   	    FROM cAssetsTemp2 a FULL JOIN cJurnalImobTemp2 b ON a.id_mfb = b.id_mf ;
	   	    INTO CURSOR cAssetsTemp3

		USE IN (SELECT('cAssetsTemp2'))	
		USE IN (SELECT('cJurnalImobTemp2'))   	    
								
		SELECT cAssets
		APPEND FROM DBF('cAssetsTemp3')
		USE IN (SELECT('cAssetsTemp3'))

		SELECT cAssets
		INDEX on AssetId TAG assetid			
		UPDATE cAssets SET DepreciationPercentage = 0 WHERE DepreciationPercentage < 0
		GO TOP

		*********************
		* Asset Transactions
		*********************
		
		* Act.cod nota inchidere amortizare corporale id_set 90003, necorporale id_set 90009
		TEXT TO lcSql TEXTMERGE NOSHOW 
			SELECT an*12+luna as nrluna, decode(id_set, 90003, 1, 2) as id_tip_imobilizare, MAX(cod) as cod 
			FROM vact 
			WHERE an*12+luna between <<m.lnNrLuni1>> and <<m.lnNrLuni2>> and id_set in (90003, 90009)
			group by an*12+luna,decode(id_set, 90003, 1, 2)
		ENDTEXT 	
		llSucces = goExecutor.oExecuta(m.lcSql, 'cNoteInchideriAmortizare')

		* Daca firma nu are imobilizari, da eroare la join-ul de mai jos
		* adaug o linie goala
		IF RECCOUNT('cAmortizareLunara') = 0
			INSERT INTO cAmortizareLunara (an, luna) VALUES (m.gnAn, m.gnLuna)
		ENDIF 
		
		* Amortizari lunare, AssetTransactionType = 30
		SELECT CAST(ALLTRIM(STR(a.id_operatie_mf)) + '_' + ALLTRIM(STR(a.id_calcul_rate)) + '_' + ALLTRIM(STR(a.an)) + PADL(a.luna,2,'0') as C(70)) as AssetTransactionID, ;
		 CAST(ALLTRIM(STR(NVL(a.id_tip_imobilizare,'1'))) + '_' + ALLTRIM(TRANSFORM(a.nr_inventar)) as C(35)) as AssetID, '30' as AssetTransactionType, ;
		 'Amortizare' as Description, GOMONTH(DATE(a.an, a.luna, 1),1)-1 as AssetTransactionDate, ;
		 CAST(INT(NVL(b.cod, 0)) as C(70)) as TransactionID, 'contabila' as AssetValuationType, ;
		 0.00 as AcquisitionAndProductionCostsOnTransaction, a.rata as BookValueOnTransaction, a.rata as AssetTransactionAmount, ;
		 a.denumire, a.tip_imobilizare, a.id_mf ;
		 from cAmortizareLunara a LEFT JOIN cNoteInchideriAmortizare b ON a.id_tip_imobilizare = b.id_tip_imobilizare AND a.nrluna = b.nrluna ;
		 WHERE a.rata <> 0 ;
		 INTO CURSOR cAssetTransactionsTemp
		 
		SELECT cAssetTransactions
		APPEND FROM DBF('cAssetTransactionsTemp')
		USE IN (SELECT('cAssetTransactionsTemp'))

		* Operatii (intrare, iesire, majorare, reevaluare, modificare cu istoric)
		SELECT CAST(ALLTRIM(STR(a.id_operatie_mf)) + '_' + ALLTRIM(STR(a.id_calcul_rate)) + '_000000' as C(70)) as AssetTransactionID, ;
			CAST(ALLTRIM(STR(NVL(a.id_tip_imobilizare,'1'))) + '_' + ALLTRIM(TRANSFORM(a.nr_inventar)) as C(35)) as AssetID, '130' as AssetTransactionType, ;
			CAST(a.tip_operatie as C(70)) as Description, TTOD(a.data_operatie) as AssetTransactionDate, ;
		 CAST(INT(NVL(b.cod, 0)) as C(70)) as TransactionID, 'contabila' as AssetValuationType, ;			
		 id_operatie_prec, id_mf, nr_inventar, denumire, id_tip_operatie, id_tip_iesire, tip_imobilizare, ;
		 valoare, valoare_ant, valoare_dif, valoare_ramasa, valoare_iesire, ;
		 CAST(0 as N(18,2)) as AcquisitionAndProductionCostsOnTransaction,;
		 CAST(0 as N(18,2)) as BookValueOnTransaction,;
		 CAST(0 as N(18,2)) as AssetTransactionAmount ;		 
		 FROM cJurnalImobTemp a LEFT JOIN cNoteInchideriAmortizare b ON a.id_tip_imobilizare = b.id_tip_imobilizare AND a.nrluna = b.nrluna  ;
		 INTO CURSOR cAssetTransactionsTemp READWRITE 

  		 USE IN (SELECT('cNoteInchideriAmortizare'))
		 
		 SELECT cAssetTransactionsTemp
		 SCAN
		 	lnValoare = valoare
		 	lnValoareIesire = NVL(valoare_iesire, 0)
		 	IF m.lnValoareIesire = 0
		 		lnValoareIesire = valoare_ramasa
		 	ENDIF 
		 	lnValoareRamasa = valoare_ramasa
			lnValoareRamasaPrec = valoare_ramasa 
			lnValoareDif = valoare_dif && valoare - valoare_ant
			lnIdTipOperatie = id_tip_operatie
			lnIdTipIesire = NVL(id_tip_iesire,0)
			lnIdOpPrec = NVL(id_operatie_prec, 0)
			lnIdMf = NVL(id_mf, 0)
			
			DO CASE 
				CASE INLIST(lnIdTipOperatie, 1, 2, 3) && intrare, preluare, transformare in MF
					lcAssetTransactionType = '10'
					SELECT cAssetTransactionsTemp
					REPLACE AcquisitionAndProductionCostsOnTransaction WITH m.lnValoare, BookValueOnTransaction WITH m.lnValoare, AssetTransactionAmount WITH m.lnValoare, AssetTransactionType WITH m.lcAssetTransactionType

				CASE INLIST(lnIdTipOperatie, 4) && iesire
					lcAssetTransactionType = IIF(m.lnIdTipIesire = 1, '20', IIF(m.lnIdTipIesire = 2, '50', IIF(m.lnIdTipIesire = 5, '40', '50')))
					lcDescription = IIF(m.lnIdTipIesire = 1, 'Vanzare', IIF(m.lnIdTipIesire = 2, 'Casare', IIF(m.lnIdTipIesire = 5, 'Transfer', ALLTRIM(description))))
					SELECT cAssetTransactionsTemp
					REPLACE AcquisitionAndProductionCostsOnTransaction WITH 0, BookValueOnTransaction WITH m.lnValoareRamasa, AssetTransactionAmount WITH m.lnValoareIesire-m.lnValoareRamasa, AssetTransactionType WITH m.lcAssetTransactionType, Description WITH m.lcDescription

				CASE INLIST(lnIdTipOperatie, 6, 12) OR (m.lnValoareDif <> 0 AND !INLIST(id_tip_operatie, 1, 2, 3, 4, 5, 6, 7, 12, 15)) && majorare sau alta operatie cu diferenta de valoare inventar, in afara de reevaluari, intrari, iesiri
					lcAssetTransactionType = '130' && altele
					SELECT cAssetTransactionsTemp
					REPLACE AcquisitionAndProductionCostsOnTransaction WITH m.lnValoareDif, BookValueOnTransaction WITH m.lnValoareDif, AssetTransactionAmount WITH m.lnValoareDif, AssetTransactionType WITH m.lcAssetTransactionType

				CASE INLIST(lnIdTipOperatie, 7, 15) && reevaluare, reevaluare si modificare DNS
					lcAssetTransactionType = IIF(m.lnValoareDif < 0, '60', '70') && reevaluare negativa/pozitiva
					* aflare valoare_ramasa (Valoare neta) din luna anterioara reevaluarii
					SELECT MAX(nrluna) as nrluna FROM cAmortizareLunara WHERE id_mf = m.lnIdMf AND id_operatie_mf = m.lnIdOpPrec INTO CURSOR cMaxLuna
					lnNrLuna = NVL(cMaxLuna.nrluna, 0)
					IF !EMPTY(m.lnNrLuna)
						SELECT cAmortizareLunara
						LOCATE FOR id_mf = m.lnIdMf AND id_operatie_mf = m.lnIdOpPrec AND nrluna = m.lnNrLuna 
						IF FOUND()
							lnValoareRamasaPrec = valoare_ramasa
						ENDIF 
					ENDIF 						
					
					SELECT cAssetTransactionsTemp				
					REPLACE AcquisitionAndProductionCostsOnTransaction WITH 0, BookValueOnTransaction WITH m.lnValoareDif, AssetTransactionAmount WITH m.lnValoareRamasa - m.lnValoareRamasaPrec, AssetTransactionType WITH m.lcAssetTransactionType
			ENDCASE 
		 ENDSCAN 
		 			
		SELECT cAssetTransactions
		APPEND FROM DBF('cAssetTransactionsTemp')
		USE IN (SELECT('cAssetTransactionsTemp'))
				 			
		SELECT cAssetTransactions
		INDEX on AssetId + AssetTransactionID TAG Ord
		INDEX on assetid TAG assetid
		INDEX on id_mf TAG id_mf
		SET ORDER TO tag ord
		
		USE IN (SELECT('cAmortizareLunara'))
		USE IN (SELECT('cJurnalImobTemp'))		
		
		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oAssets


	************************************************
	* cursor cMovementTypeTable
	************************************************
	Function oMovementTypeTable

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()


		Text To m.lcSql Noshow Textmerge
select movementtype, description
  from saft_movementtypetable
  order by to_number(movementtype)
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cMovementTypeTable')
		If m.llSucces
			Select cMovementTypeTable
			Index On VAL(movementtype) Tag mtype
		Endif

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oMovementTypeTable

	************************************************
	* cursor cProducts
	************************************************
	* La sectiunea MF 2.9 Products [Produse] se vor declara toate produsele care au miscari pe conturile de clasa 3, cu exceptia conturilor 303 (Obiete de inventar) si 32x (Stocuri in curs de aprovizionare);
	* La sectiunea MF 2.10 PhysicalStock [Stocuri] se vor declara toate produsele existente in stoc la data raportarii cu exceptia valorilor inregistrate in conturile: Diferente de pret (308, 348 etc), Obiecte de inventar (303), Stocuri in curs de aprovizionare (32x), Ajustari (39xx)
	* La sectiunea SD 4.4 MovementOfGoods [Mi?cari Bunuri] se vor raporta toate miscarile inregistrate pe clasa 3, cu exceptia contului 303 (Obiecte de Inventar) si Stocuri in curs de aprovizionare (32x). Iar, pentru diferentele de pret si ajustari elementul Quantity va fi "0".
	Function oProducts

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		

		Text To m.lcSql Noshow Textmerge
select distinct s.id_articol, a.denumire, a.codnc8, a.um, a.cod_um_iso, a.um_iso, a.codbare, '01' as goodsorservicesid
	FROM stoc s join vnom_articole a on s.id_articol = a.id_articol
	WHERE s.an * 12 + s.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
		and not (SUBSTR(s.cont,1,3) = '303' or SUBSTR(s.cont,1,2) in ('32', '39'))
	order by a.denumire	
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cProducts')
		If m.llSucces
			*
		Endif

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oProducts

	************************************************
	* cursor cPhysicalStock
	************************************************
	Function oPhysicalStock

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		Local lcSaftPartId, lnIdPart
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2
		
		Text To m.lcSql Noshow Textmerge
select s.id_gestiune,
	   s.cgest,
       s.id_articol,
       s.pret,
       s.cont,
       s.id_part_rez as id_part,
       p.denumire as partener,
       s.canti,
       s.vali,
       s.cantf,
       s.valf,
       a.codnc8,
       a.um,
       a.cod_um_iso,
       a.denumire,
       CAST(null as varchar2(20)) as saftpartid
  from (select id_gestiune,
  			   cgest,
               id_articol,
               pret,
               cont,
               id_part_rez,
               sum(canti) as canti,
               sum(cantf) as cantf,
               round(pret * sum(canti), 6) as vali,
               round(pret * sum(cantf), 6) as valf
          from (select s.id_gestiune, g.cgest, s.id_articol, decode(g.nr_pag, 6, s.pretv+s.tvav, s.pret) as pret, s.cont, s.id_part_rez, s.cants as canti, 0 as cantf
                  from stoc s join nom_gestiuni g on s.id_gestiune = g.id_gestiune
                 where s.an = <<m.lnAn1>> and s.luna = <<m.lnLuna1>> 
                 and not (SUBSTR(s.cont,1,3) = '303' or SUBSTR(s.cont,1,2) in ('32', '39'))
                union all
                select s.id_gestiune, g.cgest, s.id_articol, decode(g.nr_pag, 6, s.pretv+s.tvav, s.pret) as pret, s.cont, s.id_part_rez, 0 as canti, s.cants + s.cant - s.cante as cantf
                  from stoc s join nom_gestiuni g on s.id_gestiune = g.id_gestiune
                 where s.an = <<m.lnAn2>> and s.luna = <<m.lnLuna2>> 
                 and not (SUBSTR(s.cont,1,3) = '303' or SUBSTR(s.cont,1,2) in ('32', '39')))
         group by id_gestiune, cgest, id_articol, pret, cont, id_part_rez) s        
  join vnom_articole a
    on s.id_articol = a.id_articol
  left join nom_parteneri p on s.id_part_rez = p.id_part
  order by s.cgest, a.denumire, s.pret, s.cont, p.denumire
		Endtext

		llSucces = goExecutor.oExecuta(m.lcSql, 'cPhysicalStock')
		IF m.llSucces
			* completez ownerId pentru contul 35x (stocuri la terti, cu partener rezervare)
			SELECT distinct id_part FROM cPhysicalStock WHERE !EMPTY(NVL(id_part, 0)) AND LEFT(cont,2) = '35' INTO CURSOR cIdpartTemp
			
			SELECT cIdPartTemp
			SCAN
				lnIdPart = id_part
				lcSaftPartId = This.GetOwnerCode(m.lnIdPart)
				IF !EMPTY(m.lcSaftPartId)
					UPDATE cPhysicalStock SET saftpartid = m.lcSaftPartId WHERE id_part = m.lnIdPart
				ENDIF 	
			ENDSCAN	&& cIdPartTemp

			USE IN (SELECT('cIdPartTemp'))	
		ENDIF 
		GO TOP IN cPhysicalStock
		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oPhysicalStock
	
	************************************************
	* cursor cMovementOfGoods
	************************************************
	Function oMovementOfGoods

		Local lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcSelect = Select()

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

Text To m.lcSql Noshow Textmerge
SELECT an, luna, id_rul, id_fact, dataact, nract, nnir, id_tip_rulaj, cont, cod, id_articol, denumire, cant, cante, pret, cod_um_iso,
	   taxcode, taxtype, procent_taxa, r1.movementtype, CAST(r1.movementtype || ' ' || m.description AS varchar2(200)) as movementtypename, customerid, supplierid, saftpartidc, saftpartids,
   	   (SELECT MAX(t.prescurtare) as cod_tara FROM ADRESE_PARTENERI ap left join syn_nom_tari t on t.id_tara = ap.id_tara WHERE ap.id_part = r1.customerId and ap.STERS = 0 AND ap.PRINCIPALA = 1) as cod_taraC,
	   (SELECT MAX(t.prescurtare) as cod_tara FROM ADRESE_PARTENERI ap left join syn_nom_tari t on t.id_tara = ap.id_tara WHERE ap.id_part = r1.supplierId and ap.STERS = 0 AND ap.PRINCIPALA = 1) as cod_taraS,
 		(select cod_fiscal from nom_parteneri where id_part = r1.customerId) as cod_fiscalC,
 		(select cod_fiscal from nom_parteneri where id_part = r1.SupplierId) as cod_fiscalS,
 		(select tip_persoana from nom_parteneri where id_part = r1.customerId) as tip_persoanaC,
 		(select tip_persoana from nom_parteneri where id_part = r1.SupplierId) as tip_persoanaS, 	
 		(select denumire from nom_parteneri where id_part = r1.customerId) as denumireC,
 		(select denumire from nom_parteneri where id_part = r1.supplierId) as denumireS,
 		(select MAX(f.fel_document) from act a join nom_fdoc f on a.id_fdoc = f.id_fdoc where a.cod = r1.cod) as fdoc
	   from (select r.an, r.luna, r.id_rul, r.id_fact, r.dataact, r.nract, r.nnir, r.id_tip_rulaj, r.cont, r.cod, r.id_articol, r.cant, r.cante, decode(g.nr_pag, 6, r.pretv+r.tvav, r.pret) as pret, a.cod_um_iso, a.denumire,
	   r.taxcode, t.taxtype, t.procent_taxa, 
      (case when r.id_tip_rulaj = 6 and r.cante < 0 then '110'
      when r.id_tip_rulaj = 6 and r.cante > 0 then '120' 
      when r.id_tip_rulaj = 0 and r.cant > 0 and g.nr_pag = 4 then '20'
      when r.id_tip_rulaj = 0 and r.cant > 0 then '10'
      when r.id_tip_rulaj = 0 and r.cante > 0 then '30'
      when r.id_tip_rulaj = 0 and r.cant < 0 then '50'
      when r.id_tip_rulaj = 0 and r.cante < 0 then '40'
      when r.id_tip_rulaj = 1 then '80'
      else '180' end) as movementtype,
      (select MAX(id_part) as id_part from jv2007 j where j.an = r.an and j.luna = r.luna and j.id_fact = r.id_fact) as customerId,
      (select MAX(id_part) as id_part from jc2007 j where j.an = r.an and j.luna = r.luna and j.id_fact = r.id_fact) as supplierId,
      CAST(null as varchar2(20)) as saftpartidc,
      CAST(null as varchar2(20)) as saftpartids
       from rul r left join vnom_articole a on r.id_articol = a.id_articol
       join nom_gestiuni g on r.id_gestiune = g.id_gestiune
	   left join saft_taxtable t on r.taxcode = t.taxcode       
       where r.an * 12 + r.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>> and r.sters = 0
       and not (SUBSTR(r.cont,1,3) = '303' or SUBSTR(r.cont,1,2) in ('32'))) r1 
       left join saft_movementtypetable m on r1.movementtype = m.movementtype
       order by dataact, nract, id_rul
		Endtext
 
		llSucces = goExecutor.oExecuta(m.lcSql, 'cMovementOfGoodsTemp')

		create cursor cMovementOfGoods ;
			(AN N(4) NULL, ;
			LUNA N(2) NULL, ;
			ID_RUL N(20) NULL , ;
			ID_FACT N(20) NULL, ;
			DATAACT D NULL, ;
			NRACT N(16) NULL, ;
			NNIR N(16) NULL, ;
			ID_TIP_RULAJ I NULL, ;
			CONT C(4) NULL, ;
			COD N(20) NULL, ;
			ID_ARTICOL N(20) NULL, ;
			DENUMIRE C(250) NULL, ;	
			CANT N(16,3) NULL, ;
			CANTE N(16,3) NULL, ;
			PRET N(18,4) NULL, ;
			VALOARE N(18,4) NULL, ;	
			TAXA N(18,4) NULL, ;		
			COD_UM_ISO C(5) NULL, ;
			TAXCODE N(6) NULL, ;
			TAXTYPE N(3) NULL, ;
			PROCENT_TAXA N(7,2) NULL, ;
			MOVEMENTTYPE C(9) NULL, ;
			MOVEMENTTYPENAME C(200) NULL, ;
			CUSTOMERID N(10) NULL, ;
			SUPPLIERID N(10) NULL, ;
			SAFTPARTIDC C(20) NULL, ;
			SAFTPARTIDS C(20) NULL, ;
			COD_TARAC C(5) NULL, ;
			COD_TARAS C(5) NULL, ;
			COD_FISCALC C(30) NULL, ;
			COD_FISCALS C(30) NULL, ;
			TIP_PERSOANAC N(1) NULL, ;
			TIP_PERSOANAS N(1) NULL, ;
			DENUMIREC C(200) NULL, ;
			DENUMIRES C(200) NULL, ;
			FDOC C(18) NULL)

		SELECT cMovementOfGoods
		APPEND FROM DBF('cMovementOfGoodsTemp')
		USE IN (SELECT('cMovementOfGoodsTemp'))

		IF m.llSucces
			UPDATE cMovementOfGoods SET valoare = ROUND(pret * IIF(cant <> 0, cant, cante), m.gnPC)
			UPDATE cMovementOfGoods SET taxa = ROUND(valoare * NVL(procent_taxa,0) / 100 , m.gnPC)

			* Corectez movementid in consum intern in loc de vanzare, daca nu exista client
			UPDATE cMovementOfGoods SET movementtype = '70', movementtypename = '70 Consum' WHERE ALLTRIM(movementtype) = '30' AND EMPTY(NVL(customerId,0))
			
				
			SELECT distinct customerId as id_part, cod_fiscalC as cod_fiscal, tip_persoanaC as tip_persoana, cod_taraC as cod_tara FROM cMovementOfGoods WHERE !EMPTY(NVL(customerId,0)) INTO CURSOR cPartIdTemp
			SELECT cPartIdTemp
			SCAN 
				lnIdPart = id_part
				lcCodTara = ALLTRIM(NVL(cod_Tara, 'RO'))
				lnTipPersoana = tip_persoana
				lcCodFiscal = ALLTRIM(NVL(cod_fiscal, ''))
				lcSaftPartId = This.GenCustSupCode(m.lnIdPart, m.lcCodTara, m.lnTipPersoana, m.lcCodFiscal)
				
				UPDATE cMovementOfGoods SET SaftPartIdC = m.lcSaftPartId WHERE customerId = m.lnIdPart
			ENDSCAN 
			USE IN (SELECT('cPartIdTemp'))
			
			SELECT distinct supplierId as id_part, cod_fiscalS as cod_fiscal, tip_persoanaS as tip_persoana, cod_taraS as cod_tara FROM cMovementOfGoods WHERE !EMPTY(NVL(supplierId,0)) INTO CURSOR cPartIdTemp
			SELECT cPartIdTemp
			SCAN 
				lnIdPart = id_part
				lcCodTara = ALLTRIM(NVL(cod_Tara, 'RO'))
				lnTipPersoana = tip_persoana
				lcCodFiscal = ALLTRIM(NVL(cod_fiscal, ''))
				lcSaftPartId = This.GenCustSupCode(m.lnIdPart, m.lcCodTara, m.lnTipPersoana, m.lcCodFiscal)
				
				UPDATE cMovementOfGoods SET SaftPartIdS = m.lcSaftPartId WHERE SupplierId = m.lnIdPart
			ENDSCAN 
			USE IN (SELECT('cPartIdTemp'))
						
		ENDIF 
		GO TOP IN cMovementOfGoods

		Select (m.lcSelect)
		Return m.llSucces

	Endfunc && oMovementOfGoods
				
************************************************
*** Fragment Header
************************************************
	Function wHeader
		Local lcData, lcSelect, lcText, lnAnF, lnAnI, lnLunaF, lnLunaI, lcTip, lcCompanyName
		lcText = ''
		lcSelect = Select()

		lcData = Dtos(Date())
		lcData = Left(m.lcData, 4) + '-' + Substr(m.lcData, 5, 2) + '-' + Right(m.lcData, 2)

		lnAnI = This.oUnitate.an1
		lnAnF = This.oUnitate.an2

		lnLunaI = This.oUnitate.luna1
		lnLunaF = This.oUnitate.luna2
		lcTip = This.oUnitate.Tip && L/T/C/A/NL/NT

		lcAddressStructure = This.wAddressStructure(gofirma.localitate,gofirma.cod_tara, goFirma.strada, goFirma.numar, goFirma.indicativ_judet)
		lcCompanyName = ALLTRIM(LEFT(XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(gofirma.firma, '')), .T.)),70))
		
		Set Textmerge On To Memvar m.lcText Noshow
\	<nsSAFT:Header >
\		<nsSAFT:AuditFileVersion>1.0</nsSAFT:AuditFileVersion>
\		<nsSAFT:AuditFileCountry>RO</nsSAFT:AuditFileCountry>
\		<nsSAFT:AuditFileDateCreated><<m.lcData>></nsSAFT:AuditFileDateCreated>
\		<nsSAFT:SoftwareCompanyName>ROMFAST SRL</nsSAFT:SoftwareCompanyName>
\		<nsSAFT:SoftwareID>ROA-SAFT</nsSAFT:SoftwareID>
\		<nsSAFT:SoftwareVersion>1.0.0</nsSAFT:SoftwareVersion>
\		<nsSAFT:Company>
\			<nsSAFT:RegistrationNumber><<Alltrim(STRTRAN(gofirma.cod_fiscal, ' ', '',1,10,1))>></nsSAFT:RegistrationNumber>
\			<nsSAFT:Name><<m.lcCompanyName>></nsSAFT:Name>
\			<<This.wxml("Address", m.lcAddressStructure)>>
\			<nsSAFT:Contact>
\				<nsSAFT:ContactPerson>
\					<<This.wxml("FirstName", Alltrim(This.oUnitate.PrenumeContact))>>
\					<<This.wxml("LastName", Alltrim(This.oUnitate.NumeContact))>>
\				</nsSAFT:ContactPerson>
\				<<This.wxml("Telephone", Alltrim(gofirma.telefon), .T.)>>
\				<<This.wxml("Email", Alltrim(gofirma.email))>>
\				<<This.wxml("Website", "")>>
\			</nsSAFT:Contact>
\			<nsSAFT:TaxRegistration>
\				<<This.wxml("TaxRegistrationNumber", Alltrim(gofirma.cod_fiscal))>>
\				<<This.wxml("TaxType", "100010")>>
\				<<This.wxml("TaxNumber", Alltrim(gofirma.cod_fiscal))>>
\				<<This.wxml("TaxAuthority", "ANAF")>>
\				<<This.wxml("TaxVerificationDate", m.lcData)>>
\			</nsSAFT:TaxRegistration>
\			<nsSAFT:BankAccount>
\				<<This.wxml("IBANNumber", STRTRAN(Alltrim(NVL(gofirma.cont_banca1,'')), ' ', '',1,20,1))>>
\			</nsSAFT:BankAccount>
\		</nsSAFT:Company>
\		<<This.wxml("DefaultCurrencyCode", "RON")>>
\		<nsSAFT:SelectionCriteria>
\			<<This.wxml("TaxReportingJurisdiction", "Romania")>>
\			<<This.wxml("CompanyEntity", m.lcCompanyName)>>
\			<<This.wxml("PeriodStart", m.lnLunaI)>>
\			<<This.wxml("PeriodStartYear", m.lnAnI)>>
\			<<This.wxml("PeriodEnd", m.lnLunaF)>>
\			<<This.wxml("PeriodEndYear", m.lnAnF)>>
\		</nsSAFT:SelectionCriteria>
\		<<This.wxml("HeaderComment", m.lcTip)>>
\		<<This.wxml("SegmentIndex", This.SegmentIndex)>>
\		<<This.wxml("TotalSegmentsInsequence", This.TotalSegmentsInSequence)>>
\		<<This.wxml("TaxAccountingBasis", This.TaxAccountingBasis)>>
\		<<This.wxml("TaxEntity", This.TaxEntity)>>
\	</nsSAFT:Header>
\
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wHeader


************************************************
*** Fragment GeneralLedgerAccounts
************************************************
	Function wGeneralLedgerAccounts
		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()


		If !Used('cGeneralLedgerAccounts')
			Return m.lcText
		Endif

		Set Textmerge On To Memvar m.lcText Noshow
\
		Select cGeneralLedgerAccounts
		Set Filter To (soldideb <> 0 Or soldicred <> 0 Or soldfdeb <> 0 Or soldfcred <> 0)
		Scan
\			<nsSAFT:Account>
\				<nsSAFT:AccountID><<Alltrim(Cont)>></nsSAFT:AccountID>
\				<nsSAFT:AccountDescription><<Alltrim(denumire)>></nsSAFT:AccountDescription>
\				<nsSAFT:AccountType><<Alltrim(Tip)>></nsSAFT:AccountType>
			Do Case
				Case soldideb <> 0 And soldicred = 0
\				<nsSAFT:OpeningDebitBalance><<Round(soldideb,2)>></nsSAFT:OpeningDebitBalance>
				Case soldicred <> 0 And soldideb = 0
\				<nsSAFT:OpeningCreditBalance><<Round(soldicred,2)>></nsSAFT:OpeningCreditBalance>
				Otherwise
					Do Case
						Case Alltrim(Tip) = 'Activ'
\				<nsSAFT:OpeningDebitBalance><<Round(soldideb,2)>></nsSAFT:OpeningDebitBalance>
						Otherwise
\				<nsSAFT:OpeningCreditBalance><<Round(soldicred,2)>></nsSAFT:OpeningCreditBalance>
					Endcase
			Endcase
			Do Case
				Case soldfdeb <> 0 And soldfcred = 0
\				<nsSAFT:ClosingDebitBalance><<Round(soldfdeb,2)>></nsSAFT:ClosingDebitBalance>
				Case soldfcred <> 0 And soldfdeb = 0
\				<nsSAFT:ClosingCreditBalance><<Round(soldfcred,2)>></nsSAFT:ClosingCreditBalance>
				Otherwise
					Do Case
						Case Alltrim(Tip) = 'Activ'
\				<nsSAFT:ClosingDebitBalance><<Round(soldfdeb,2)>></nsSAFT:ClosingDebitBalance>
						Otherwise
\				<nsSAFT:ClosingCreditBalance><<Round(soldfcred,2)>></nsSAFT:ClosingCreditBalance>
					Endcase

			Endcase
\			</nsSAFT:Account>
		Endscan && c406Bal
\
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText
	Endfunc && xGeneralLedgerAccounts

********************************************
*** Fragment Customers/Suppliers
********************************************
	Function wCustomersSuppliers
		Lparameters tcTip
		* tcTip: customers/suppliers

		Local lcCodFiscal, lcCodP, lcCodTara, lcCont, lcCursor, lcDenumire
		Local lcIdPart, lcLocalitate, lcNumar, lcPartId, lcRegistrationNumber, lcRegiune, lcSelect, lcStrada, lcIndicativJudet
		Local lcTag, lcTagId, lcTags, lcText, lcTipCont, llClient, llEU, lnSoldFCred, lnSoldFDeb
		Local lnSoldICred, lnSoldIDeb, lnTipPersoana

		lcText = ''
		lcSelect = Select()
		llClient = (Upper(Alltrim(m.tcTip)) = 'CUSTOMERS')
		lcCursor = Iif(m.llClient, 'cCustomers', 'cSuppliers')

		lcTag = Iif(m.llClient, 'Customer', 'Supplier')
		lcTagId = Iif(m.llClient, 'CustomerID', 'SupplierID')

		If !Used(m.lcCursor)
			Return m.lcText
		Endif

		Set Textmerge On To Memvar m.lcText Noshow
\
		Select(m.lcCursor)
		Scan
			lnIdPart = Nvl(id_part, 0)
			lcCodFiscal = Upper(Alltrim(Nvl(cod_fiscal, '')))
			lcCodTara = Alltrim(Upper(Nvl(cod_tara, 'RO')))
			lcDenumire = ALLTRIM(LEFT(XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(denumire, '')), .T.)), 70))
			lcStrada = XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(Left(strada, 70), '')), .T.))
			lcNumar = XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(numar, '')), .T.))
			lcCodP = XmlSpecialCharacters(RemoveCharacters(Iif(Empty(Nvl(codpostal, 0)), '', Alltrim(Str(codpostal))), .T.))
			lcLocalitate = XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(Nvl(localitate, 'BUCURESTI'), '')), .T.))
			lcIndicativJudet = Alltrim(Nvl(indicativ_judet, ''))
			lnTipPersoana = Nvl(tip_persoana, 1) && 1 = juridica, 2 = fizica
			lcCont = ALLTRIM(NVL(cont,'')) 
			lnSoldIDeb = soldideb
			lnSoldICred = soldicred
			lnSoldFDeb = soldfdeb
			lnSoldFCred = soldfcred

			* lcPartId = Iif(!Empty(m.lnIdPart), This.GenCustSupCode(m.lnIdPart, m.lcCodTara, m.lnTipPersoana, m.lcCodFiscal), 'NULL')
			lcPartId = Iif(!Empty(m.lnIdPart), ALLTRIM(NVL(Saftpartid,'')), 'NULL')
			lcRegistrationNumber = m.lcPartId
			
			lcAddressStructure = This.wAddressStructure(m.lcLocalitate, m.lcCodTara, m.lcStrada, m.lcNumar, m.lcIndicativJudet)
			
\			<nsSAFT:<<m.lcTag>>>
\				<nsSAFT:CompanyStructure>
\					<<This.wxml("RegistrationNumber", m.lcRegistrationNumber)>>
\					<<This.wxml("Name", m.lcDenumire)>>
\					<<This.wxml("Address", m.lcAddressStructure)>>
\				</nsSAFT:CompanyStructure>
\				<<This.wxml(m.lcTagId, m.lcPartId)>>
\					<<This.wxml("SelfBillingIndicator", 0, .T.)>>
\					<<This.wxml("AccountID", m.lcCont)>>
			Do Case
				Case soldideb <> 0 And soldicred = 0
\				<<This.wxml("OpeningDebitBalance", This.FormatValue(soldideb))>>				
				Case soldicred <> 0 And soldideb = 0
\				<<This.wxml("OpeningCreditBalance", This.FormatValue(soldicred))>>								
				Otherwise
					Do Case
						Case Alltrim(Tip) = 'Activ'
\				<<This.wxml("OpeningDebitBalance", This.FormatValue(soldideb))>>							
						OTHERWISE
\				<<This.wxml("OpeningCreditBalance", This.FormatValue(soldicred))>>								
					Endcase
			Endcase
			Do Case
				Case soldfdeb <> 0 And soldfcred = 0
\				<<This.wxml("ClosingDebitBalance", This.FormatValue(soldfdeb))>>					
				Case soldfcred <> 0 And soldfdeb = 0
\				<<This.wxml("ClosingCreditBalance", This.FormatValue(soldfcred))>>									
				Otherwise
					Do Case
						Case Alltrim(Tip) = 'Activ'
\				<<This.wxml("ClosingDebitBalance", This.FormatValue(soldfdeb))>>						
						OTHERWISE
\				<<This.wxml("ClosingCreditBalance", This.FormatValue(soldfcred))>>						
					Endcase
			Endcase
\			</nsSAFT:<<m.lcTag>>>
		Endscan && cCustomers/cSuppliers
\		
		Set Textmerge To


		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wCustomersSuppliers

	Function wTaxTable
		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()


		If !Used('cTaxTable')
			Return m.lcText
		Endif

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		Set Textmerge On To Memvar m.lcText Noshow
		SELECT distinct taxtype, LEFT(typename,250) as typename FROM cTaxTable INTO CURSOR cTaxTypeTemp
		SELECT cTaxTypeTemp
		SCAN
			lnTaxType = taxtype 
			lcTypeName = ALLTRIM(NVL(typename, ''))
\
\			<nsSAFT:TaxTableEntry>
\				<nsSAFT:TaxType><<m.lnTaxType>></nsSAFT:TaxType>
\				<nsSAFT:Description><<m.lcTypeName>></nsSAFT:Description>
			SELECT cTaxTable
			SCAN FOR taxtype = m.lnTaxType AND RIGHT(ALLTRIM(STR(taxcode)), 3) <> '000' && fara codurile de taxa non-wht, adaugate in ROA
\				<nsSAFT:TaxCodeDetails>
\					<nsSAFT:TaxCode><<taxcode>></nsSAFT:TaxCode>
\					<nsSAFT:Description><<ALLTRIM(UPPER(NVL(descriere,'')))>></nsSAFT:Description>
\					<nsSAFT:TaxPercentage><<procent_taxa>></nsSAFT:TaxPercentage>
\					<nsSAFT:BaseRate>0</nsSAFT:BaseRate>
\					<nsSAFT:Country>RO</nsSAFT:Country>
\				</nsSAFT:TaxCodeDetails>
			ENDSCAN 
\			</nsSAFT:TaxTableEntry>
		ENDSCAN 
\		
		Set Textmerge To
		
		USE IN (SELECT('cTaxTypeTemp'))
		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wTaxTable

	Function wUOMTable
		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()


		If !Used('cUOMTable')
			Return m.lcText
		Endif

		Set Textmerge On To Memvar m.lcText Noshow
		SELECT cUOMTable
		SCAN
			lcUnitOfMeasure = ALLTRIM(NVL(unitofmeasure, ''))
			lcDescription = ALLTRIM(NVL(description, ''))
\
\			<nsSAFT:UOMTableEntry>
\				<<This.wXML('UnitOfMeasure', m.lcUnitOfMeasure)>>
\				<<This.wXML('Description', m.lcDescription)>>
\			</nsSAFT:UOMTableEntry>
		ENDSCAN 
\		
		Set Textmerge To
		
		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wUOMTable

************************************************
*** Fragment GeneralLedgerEntries
************************************************
	Function wGeneralLedgerEntries
		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()


		If !Used('cGeneralLedgerEntries')
			Return m.lcText
		Endif

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		Select Count(*) As nr, Sum(Iif(tipdc = 'D', suma, 0.00)) As debit, Sum(Iif(tipdc = 'D', suma, 0.00)) As credit From cGeneralLedgerEntries Into Cursor cEntriesTotals
		Select cEntriesTotals
		lnTotalDebit = debit
		lnTotalCredit = credit
		lnNumberOfEntries = nr
		Use In (Select('cEntriesTotal'))

		Set Textmerge On To Memvar m.lcText Noshow
\
\		<nsSAFT:NumberOfEntries><<m.lnNumberOfEntries>></nsSAFT:NumberOfEntries>
\		<nsSAFT:TotalDebit><<This.FormatValue(m.lnTotalDebit)>></nsSAFT:TotalDebit>
\		<nsSAFT:TotalCredit><<This.FormatValue(m.lnTotalCredit)>></nsSAFT:TotalCredit>
\		<nsSAFT:Journal>
\			<nsSAFT:JournalID>1</nsSAFT:JournalID>
\			<nsSAFT:Description>Jurnal contabil</nsSAFT:Description>
\			<nsSAFT:Type>1</nsSAFT:Type>
	
		Select cGeneralLedgerEntries
		Scan
			lcCodTara = Alltrim(Nvl(cod_tara, ''))
			lnTipPersoana = Nvl(tip_persoana, 1) && 1 = juridica, 2 = fizica
			lcCodFiscal = Alltrim(Nvl(cod_fiscal, ''))
			lcCustomerId = '0'
			lcSupplierId = '0'
			lnIdPart = Nvl(id_part, 0)
			lcCont = Alltrim(Nvl(Cont, ''))
			lcPartId = ALLTRIM(NVL(saftpartid,''))
			If !Empty(m.lnIdPart)
				* lcPartId = This.GenCustSupCode(m.lnIdPart, m.lcCodTara, m.lnTipPersoana, m.lcCodFiscal)
				Do Case
					Case Left(m.lcCont, 2) = '41' OR INLIST(LEFT(m.lcCont,3), '461', '463')
						lcCustomerId = 	m.lcPartId
					Case Left(m.lcCont, 2)	= '40' OR INLIST(LEFT(m.lcCont,3), '462', '467')
						lcSupplierId = 	m.lcPartId
*!*						OTHERWISE 						
*!*							lcCustomerId = '00' + This.oUnitate.codi
*!*							lcSupplierId = '00' + This.oUnitate.codi					
				ENDCASE
			ELSE
				lcCustomerId = IIF(!EMPTY(m.lcPartId), m.lcPartId, '00' + This.oUnitate.codi)
				lcSupplierId = IIF(!EMPTY(m.lcPartId), m.lcPartId, '00' + This.oUnitate.codi)
			Endif
			lnIdFact = id_fact
			lcCont = Alltrim(Nvl(Cont, ''))
			lcTipDC = Alltrim(tipdc)
			lnSuma = suma
			lcCodValuta = Nvl(cod_valuta, 'RON')
			lnSumaValuta = suma_val
			lnCurs = Iif(Empty(Nvl(Curs, 0)), 1, Curs)
			lnTaxa = taxa
			lnTaxaValuta = taxa_val
			lcAmountStructure = This.wAmountStructure(m.lnSuma, m.lcCodValuta, m.lnSumaValuta, m.lnCurs)
			lcTaxAmountStructure = This.wAmountStructure(m.lnTaxa, m.lcCodValuta, m.lnTaxaValuta, m.lnCurs)

			lcTaxType = '000'
			lcTaxCode = '000000'
*!*				llN50 = (n50=1) && achizitii nedeductibile 50%
*!*				llN100 = (n100=1) && achizitii nedeductibile 100%
			llTVA = Alltrim(Nvl(tiptaxa, '')) = 'TVA'	 && taxa = TVA
			llWHT = Alltrim(Nvl(tiptaxa, '')) = 'WHT'	 && taxa = WHT impozit cu retinere la sursa
*!*				llRegularizare = !BETWEEN(YEAR(dataact)*12 + MONTH(dataact), m.lnAn1*12+m.lnLuna1, m.lnAn2*12+m.lnLuna2)
			lcPerioadaTVA = This.oUnitate.perioada_tva

			Do Case
				Case m.llTVA
* Cred ca este singurul TaxType pentru LedgerEntries
* 301-304 se folosesc la plata TVA lunar/trimestrial in Payments
* Dupa verificare trebuie sa sterg ramurile 301-304
					lcTaxType = '300'
				Case m.llTVA And m.lcPerioadaTVA = 'LUNAR'
					lcTaxType = '301'
				Case m.llTVA And m.lcPerioadaTVA = 'TRIMESTRIAL'
					lcTaxType = '302'
				Case m.llTVA And m.lcPerioadaTVA = 'SEMESTRIAL'
					lcTaxType = '303'
				Case m.llTVA And m.lcPerioadaTVA = 'ANUAL'
					lcTaxType = '304'
				Case m.llWHT And !Empty(Nvl(taxtype, 0))
					lcTaxType = Alltrim(Str(taxtype))
			Endcase
			lcTaxCode = Iif(!Empty(Nvl(taxcode, 0)), Alltrim(Str(taxcode)), m.lcTaxCode)

			* Am creat taxcode suplimentar pentru taxtype care nu aveau corespondent in taxtable: ex: 390000,410000 Pun taxcode = 000000
			* Facturile de achizitie import trebuie trecute cu TaxCode 000000. Am introdus cod taxa 300000
			IF m.lcTaxCode == '0' OR RIGHT(lcTaxCode,3) = '000' && ex: 410000
				lcTaxCode = '000000'
			ENDIF 
			
\			<nsSAFT:Transaction>
\				<<This.wxml("TransactionID", cod)>>
\				<<This.wxml("Period", luna)>>
\				<<This.wxml("PeriodYear", an)>>
\				<<This.wxml("TransactionDate", This.FormatDate(dataact))>>
\				<<This.wxml("Description", "Nota")>>
\				<<This.wxml("SystemEntryDate", This.FormatDate(dataireg))>>
\				<<This.wxml("GLPostingDate", This.FormatDate(dataireg))>>
\				<<This.wxml("CustomerID", m.lcCustomerId, .T.)>>
\				<<This.wxml("SupplierID", m.lcSupplierId, .T.)>>
\				<nsSAFT:TransactionLine>
\				<<This.wxml("RecordID", m.lnIdFact)>>
\				<<This.wxml("AccountID", m.lcCont)>>
\					<<This.wxml("CustomerID", m.lcCustomerId, .T.)>>
\					<<This.wxml("SupplierID", m.lcSupplierId, .T.)>>
\					<<This.wxml("Description", 'NOTA')>>
\					<<This.wxml(Iif(m.lcTipDC = "D", "DebitAmount", "CreditAmount"), m.lcAmountStructure)>>
\					<nsSAFT:TaxInformation>
\						<<This.wxml("TaxType", m.lcTaxType)>>
\						<<This.wxml("TaxCode", m.lcTaxCode)>>
\						<<This.wxml("TaxAmount", m.lcTaxAmountStructure)>>
\					</nsSAFT:TaxInformation>
\				</nsSAFT:TransactionLine>
\			</nsSAFT:Transaction>
		Endscan && cGeneralLedgerEntries

\		</nsSAFT:Journal>
\
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wGeneralLedgerEntries

	Function wAnalysisTypeTable
		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()


		If !Used('cAnalysisTypeTable')
			Return m.lcText
		Endif

		Set Textmerge On To Memvar m.lcText Noshow
\
		Select cAnalysisTypeTable
		Scan
\			<nsSAFT:AnalysisTypeTableEntry>
\				<nsSAFT:AnalysisType>CC</nsSAFT:AnalysisType>
\				<nsSAFT:AnalysisTypeDescription>Centre de cost</nsSAFT:AnalysisTypeDescription>
\				<nsSAFT:AnalysisID><<Alltrim(cod)>></nsSAFT:AnalysisID>
\				<nsSAFT:AnalysisIDDescription><<Alltrim(descriere)>></nsSAFT:AnalysisIDDescription>
\			</nsSAFT:AnalysisTypeTableEntry>
		Endscan
\
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText

	Endfunc && wAnalysisTypeTable


	************************************************
	*** Fragment SalesInvoices
	************************************************
	FUNCTION wSalesInvoices
		RETURN This.wSalesPurchaseInvoices('customers')
	ENDFUNC && wSalesInvoices

	************************************************
	*** Fragment PurchaseInvoices
	************************************************
	FUNCTION wPurchaseInvoices
		RETURN This.wSalesPurchaseInvoices('suppliers')
	ENDFUNC && wSalesInvoices

	************************************************
	*** Fragment SalesInvoices / PurchaseInvoices
	************************************************
	Function wSalesPurchaseInvoices
		Lparameters tcTip
		* tcTip: customers/suppliers

		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()

		llClient = (Upper(Alltrim(m.tcTip)) = 'CUSTOMERS')
		lcCursor = Iif(m.llClient, 'cSalesInvoices', 'cPurchaseInvoices')
		lcCursorLines = Iif(m.llClient, 'cSalesInvoicesLines', 'cPurchaseInvoicesLines')		
		lcCursorParteneri = Iif(m.llClient, 'cCustomers', 'cSuppliers')
		lcTagInfo = Iif(m.llClient, 'CustomerInfo', 'SupplierInfo')
		lcTagId = Iif(m.llClient, 'CustomerID', 'SupplierID')

		If !Used(m.lcCursor)
			Return m.lcText
		ENDIF
		

		If !Used(m.lcCursor)
			Return m.lcText
		Endif

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		* Clientii au sume pe credit? (contul din liniile de articole cu valoare)
		IF m.llClient	
			SELECT SUM(valoare) as debit, 0 as credit FROM (m.lcCursorLines) Into Cursor cEntriesTotals
		ELSE
			SELECT 0 as debit, SUM(valoare) as credit FROM (m.lcCursorLines) Into Cursor cEntriesTotals		
		ENDIF 	
		
		Select cEntriesTotals
		lnTotalDebit = debit
		lnTotalCredit = credit
		lnNumberOfEntries = RECCOUNT(m.lcCursor)

		Use In (Select('cEntriesTotals'))


		Set Textmerge On To Memvar m.lcText Noshow
		IF m.lnNumberOfEntries > 0
\
\			<<This.wxml("NumberOfEntries", m.lnNumberOfEntries)>>	
\			<<This.wxml("TotalDebit", This.FormatValue(m.lnTotalDebit))>>	
\			<<This.wxml("TotalCredit", This.FormatValue(m.lnTotalCredit))>>	
		ENDIF 
		
		SELECT (m.lcCursorLines)
		lcFilterLines = FILTER()
		SET FILTER TO 
			
		SELECT (m.lcCursor)
		Scan		
			lnNumarFactura = nract
			lcDataFactura = This.FormatDate(dataact)		
			lcPartId = ALLTRIM(NVL(SaftPartId,''))
			lnIdPart = id_part
			lnIdFact = id_fact
*!*				lcAddressStructure = This.GetStructuraAdresaPartener(m.tcTip, m.lnIdPart)
			lcLocalitate = ALLTRIM(NVL(localitate, ''))
			lcCodTara = ALLTRIM(NVL(cod_tara, ''))
			lcAddressStructure = This.wAddressStructure(m.lcLocalitate, m.lcCodTara)
			
			lcCont = IIF(m.llClient, '4111', '401')
			lnLuna = luna
			lnAn = an
			lnInvoiceType = invoicetype
			lnSelfBillingIndicator = autofactura
			
\			<nsSAFT:Invoice>
\				<<This.wxml("InvoiceNo", m.lnNumarFactura)>>
\				<nsSAFT:<<m.lcTagInfo>>>
\					<<This.wxml(m.lcTagId, m.lcPartId)>>										
\					<<This.wxml("BillingAddress", m.lcAddressStructure)>>					
\				</nsSAFT:<<m.lcTagInfo>>>
\				<<This.wxml("AccountID", m.lcCont)>>
\				<<This.wxml("Period", m.lnLuna)>>
\				<<This.wxml("PeriodYear", m.lnAn)>>
\				<<This.wxml("InvoiceDate", m.lcDataFactura)>>
\				<<This.wxml("InvoiceType", m.lnInvoiceType)>>
\				<<This.wxml("SelfBillingIndicator", m.lnSelfBillingIndicator, .T.)>>

			lnLineNumber = 0
			SELECT (m.lcCursorLines)
			SCAN FOR id_fact = m.lnIdFact
				lnLineNumber = lnLineNumber + 1
				lcCont = ALLTRIM(NVL(cont,''))
				lnCantitate = cantitate
				lcDescriere = XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(NVL(descriere, 'DIVERSE'), '')), .T.))
				lnPret = pret				
				lnSuma = valoare
				lcCodValuta = Nvl(cod_valuta, 'RON')
				lnCurs = Iif(Empty(Nvl(Curs, 0)), 1, Curs)
				lnSumaValuta = valoarev && IIF(m.lcCodValuta <> 'RON', ROUND(m.lnSuma / m.lnCurs, 2), 0)
				lnTaxa = taxa && ROUND(m.lnSuma * proc_tva / 100, 2)
				lnTaxaValuta = taxav && IIF(m.lcCodValuta <> 'RON', ROUND(m.lnTaxa / m.lnCurs, 2), 0)
				
				lcAmountStructure = This.wAmountStructure(m.lnSuma, m.lcCodValuta, m.lnSumaValuta, m.lnCurs)			
				lcTaxAmountStructure = This.wAmountStructure(m.lnTaxa, m.lcCodValuta, m.lnTaxaValuta, m.lnCurs)
				lcTipDC = IIF(m.llClient, 'D', 'C')

				* Facturile achizitie import au Taxcode 0 (000000)
				lcTaxType = IIF(EMPTY(NVL(taxtype,0)), '000', ALLTRIM(STR(taxtype)))
				lcTaxCode = IIF(EMPTY(NVL(taxcode,0)), '000000', ALLTRIM(STR(taxcode)))
				
				* Facturi de import 				
				* Pentru importul efectuat, in aceasta subsectiune se va raporta factura de import, iar la TaxType se va completa 000 (3 de zero), TaxCode 0000000(6 de zero).
				lcTaxType = IIF(EMPTY(NVL(taxtype,0)), '000', ALLTRIM(STR(taxtype)))
				IF INLIST(NVL(taxcode,0), 301201, 301202, 301203)
					lcTaxType = '000'
					lcTaxCode = '000000'
				ENDIF 								
				* Am creat taxcode suplimentar pentru taxtype care nu aveau corespondent in taxtable: ex: 390000,410000 Pun taxcode = 000000
				* Facturile de achizitie import trebuie trecute cu TaxCode 000000. Am introdus cod taxa 300000
				IF m.lcTaxCode == '0' OR RIGHT(lcTaxCode,3) = '000' && ex: 410000
					lcTaxCode = '000000'
				ENDIF 				

\				<nsSAFT:InvoiceLine>
\					<<This.wxml("LineNumber", m.lnLineNumber)>>
\					<<This.wxml("AccountID", m.lcCont)>>
\					<<This.wxml("Quantity", This.FormatQuantity(m.lnCantitate))>>
\					<<This.wxml("UnitPrice", This.FormatValue(m.lnPret))>>
\					<<This.wxml("TaxPointDate", m.lcDataFactura)>>
\					<<This.wxml("Description", m.lcDescriere)>>
\					<<This.wxml("InvoiceLineAmount", m.lcAmountStructure)>>
\					<<This.wxml("DebitCreditIndicator", m.lcTipDC)>>
\					<nsSAFT:TaxInformation>
\						<<This.wxml("TaxType", m.lcTaxType)>>
\						<<This.wxml("TaxCode", m.lcTaxCode)>>
\						<<This.wxml("TaxAmount", m.lcTaxAmountStructure)>>
\					</nsSAFT:TaxInformation>
\				</nsSAFT:InvoiceLine>
			ENDSCAN && cSalesInvoicesLines/cPurchaseInvoicesLines
\			</nsSAFT:Invoice>

		ENDSCAN && cSalesInvoices/cPurchaseInvoices	
\			
		Set Textmerge To

		SELECT (m.lcCursorLines)
		SET FILTER TO &lcFilterLines
		
		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wSalesInvoices

************************************************
*** Fragment Payments
************************************************
	Function wPayments
		Local lcSelect, lcText
		Local lcAmountStructure, lcCodValuta, lcCont, lcDescription, lcPaymentMethod, lcPerioadaTVA
		Local lcTaxAmountStructure, lcTaxCode, lcTaxType, lcTipDC, llTVA, lnAn1, lnAn2, lnCurs, lnLuna1
		Local lnLuna2, lnNumberOfEntries, lnSuma, lnSumaValuta, lnTaxa, lnTaxaValuta, lnTotalCredit
		Local lnTotalDebit
		lcText = ''
		lcSelect = Select()

		If !Used('cPayments')
			Return m.lcText
		Endif

		lnAn1 = This.oUnitate.an1
		lnLuna1 = This.oUnitate.luna1
		lnAn2 = This.oUnitate.an2
		lnLuna2 = This.oUnitate.luna2

		Select Count(*) As nr, Sum(Iif(tipdc = 'D', suma, 0.00)) As debit, Sum(Iif(tipdc = 'D', suma, 0.00)) As credit From cPayments Into Cursor cEntriesTotals
		Select cEntriesTotals
		lnTotalDebit = debit
		lnTotalCredit = credit
		lnNumberOfEntries = nr
		Use In (Select('cEntriesTotal'))

		lcPerioadaTVA = This.oUnitate.perioada_tva

		IF m.lnNumberOfEntries = 0
			RETURN m.lcText
		ENDIF 
		
		Set Textmerge On To Memvar m.lcText Noshow
\
\		<nsSAFT:NumberOfEntries><<m.lnNumberOfEntries>></nsSAFT:NumberOfEntries>
\		<nsSAFT:TotalDebit><<This.FormatValue(m.lnTotalDebit)>></nsSAFT:TotalDebit>
\		<nsSAFT:TotalCredit><<This.FormatValue(m.lnTotalCredit)>></nsSAFT:TotalCredit>

		Select cPayments
		Scan
			lcTipDC = Alltrim(tipdc) && D = incasare ; C = plata
			lnSuma = suma
			lcSuma = This.FormatValue(suma)
			lcCodValuta = Nvl(cod_valuta, 'RON')
			lnSumaValuta = suma_val
			lnCurs = Iif(Empty(Nvl(Curs, 0)), 1, Curs)
			lnTaxa = IIF(!EMPTY(NVL(taxcode,0)), suma, 0)
			lnTaxaValuta = IIF(!EMPTY(NVL(taxcode,0)), suma_val, 0)
			lcPaymentMethod = ALLTRIM(NVL(methodcode,''))
			llTVA = .F.
			lcDescription = STRTRAN(ALLTRIM(explicatia),CHR(2), '',1,10,1) && scot CHR(2) = STX start of text, probabil copiat dintr-un extras de cont
			lcDescription = ALLTRIM(XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(m.lcDescription, '')), .T.)))
			
			lcTaxType = Iif(Empty(Nvl(taxtype, 0)), '000', Alltrim(Str(taxtype)))
			lcTaxCode = Iif(Empty(Nvl(taxcode, 0)), '000000', Alltrim(Str(taxcode)))
			
			Do Case
				Case m.llTVA And m.lcPerioadaTVA = 'LUNAR'
					lcTaxType = '301'
				Case m.llTVA And m.lcPerioadaTVA = 'TRIMESTRIAL'
					lcTaxType = '302'
				Case m.llTVA And m.lcPerioadaTVA = 'SEMESTRIAL'
					lcTaxType = '303'
				Case m.llTVA And m.lcPerioadaTVA = 'ANUAL'
					lcTaxType = '304'
			ENDCASE

			* Am creat taxcode suplimentar pentru taxtype care nu aveau corespondent in taxtable: ex: 390000,410000
			* Pun taxcode = 000000
			IF RIGHT(lcTaxCode,3) = '000' && ex: 410000
				lcTaxCode = '000000'
			ENDIF 
			* Am creat taxcode suplimentar pentru taxtype care nu aveau corespondent in taxtable: ex: 390000,410000 Pun taxcode = 000000
			* Facturile de achizitie import trebuie trecute cu TaxCode 000000. Am introdus cod taxa 300000
			IF m.lcTaxCode == '0' OR RIGHT(lcTaxCode,3) = '000' && ex: 410000
				lcTaxCode = '000000'
			ENDIF 
						
			lcCodTara = Alltrim(Nvl(cod_tara, ''))
			lnTipPersoana = Nvl(tip_persoana, 1) && 1 = juridica, 2 = fizica
			lcCodFiscal = Alltrim(Nvl(cod_fiscal, ''))
			lcCustomerId = '0' && unul dintre CustomerId sau SupplierId trebuie sa fie "0"
			lcSupplierId = '0'
			lnIdPart = Nvl(id_part, 0)
			lcCont = Alltrim(Nvl(Cont, ''))

			*lcPartId = IIF(EMPTY(m.lnIdPart), This.oUnitate.codi, This.GenCustSupCode(m.lnIdPart, m.lcCodTara, m.lnTipPersoana, m.lcCodFiscal))
			lcPartId = IIF(EMPTY(m.lnIdPart), '00' + This.oUnitate.codi, ALLTRIM(saftpartid))
			Do Case
				Case lcTipDC = 'D'
					lcCustomerId = 	m.lcPartId
				OTHERWISE 
					lcSupplierId = 	m.lcPartId
			ENDCASE

			lcAmountStructure = This.wAmountStructure(m.lnSuma, m.lcCodValuta, m.lnSumaValuta, m.lnCurs)
			lcTaxAmountStructure = This.wAmountStructure(m.lnTaxa, m.lcCodValuta, m.lnTaxaValuta, m.lnCurs)
		
			
\			<nsSAFT:Payment>
\				<<This.wxml("PaymentRefNo", id_fact)>>
\				<<This.wxml("Period", luna)>>
\				<<This.wxml("PeriodYear", an)>>
\				<<This.wxml("TransactionDate", This.FormatDate(dataact))>>
\				<<This.wxml("PaymentMethod", m.lcPaymentMethod)>>
\				<<This.wxml("Description", m.lcDescription)>>
\				<nsSAFT:PaymentLine>
\					<<This.wxml("AccountID", m.lcCont)>>
\					<<This.wxml("CustomerID", m.lcCustomerId, .T.)>>
\					<<This.wxml("SupplierID", m.lcSupplierId, .T.)>>
\					<<This.wxml("DebitCreditIndicator", m.lcTipDC)>>
\					<<This.wxml("PaymentLineAmount", m.lcAmountStructure)>>
\					<nsSAFT:TaxInformation>
\						<<This.wxml("TaxType", m.lcTaxType)>>
\						<<This.wxml("TaxCode", m.lcTaxCode)>>
\						<<This.wxml("TaxAmount", m.lcTaxAmountStructure)>>
\					</nsSAFT:TaxInformation>
\				</nsSAFT:PaymentLine>
\				<nsSAFT:PaymentDocumentTotals>
\					<<This.wxml("GrossTotal", m.lcSuma)>>
\				</nsSAFT:PaymentDocumentTotals>
\			</nsSAFT:Payment>
		Endscan && cPayments
\
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wPayments


	Function wOwners
		Local lcSelect, lcText
		Local lcCompanyStructure, lcSaftPartId
		lcText = ''
		lcSelect = Select()

		If !Used('cOwners')
			Return m.lcText
		Endif
  
		Set Textmerge On To Memvar m.lcText Noshow
\
		Select cOwners
		SCAN
			lcSaftPartId = ALLTRIM(NVL(saftpartid, ''))
			lcCompanyStructure = This.wCompanyStructure(saftpartid, denumire, localitate, cod_tara, strada, numar, indicativ_judet)
\			<nsSAFT:Owner>
\				<<This.wXML('CompanyStructure', m.lcCompanyStructure)>>
\				<<This.wXML('OwnerID', m.lcSaftPartId)>>
\				<<This.wXML('AccountID', '8038')>>
\			</nsSAFT:Owner>

		Endscan
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wOwners

	Function wAssets
		Local lcSelect, lcText
		Local lcDescription, lnAn1, lnAn2, lnLuna1, lnLuna2
		lcText = ''
		lcSelect = Select()

		If !Used('cAssets')
			Return m.lcText
		Endif
		
		Set Textmerge On To Memvar m.lcText Noshow
\
		Select cAssets
		SCAN
			lcDescription = ALLTRIM(XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(description, '')), .T.)))
			lcExtraordinaryDepreciationMethod = IIF(!EMPTY(NVL(ExtraordinaryDepreciationMethod,'')), ALLTRIM(ExtraordinaryDepreciationMethod), 'NULL')
			
\			<nsSAFT:Asset>
\				<<This.wxml("AssetID", ALLTRIM(assetid))>>
\				<<This.wxml("AccountID", ALLTRIM(accountId))>>
\				<<This.wxml("Description", m.lcDescription)>>
\				<<This.wxml("DateOfAcquisition", This.FormatDate(DateOfAcquisition))>>
\				<<This.wxml("StartUpDate", This.FormatDate(StartUpDate))>>
\				<nsSAFT:Valuations>
\					<nsSAFT:Valuation>
\						<<This.wxml("AssetValuationType", ALLTRIM(AssetValuationType))>>
\						<<This.wxml("ValuationClass", ALLTRIM(NVL(ValuationClass, '0')))>>
\						<<This.wxml("AcquisitionAndProductionCostsBegin", This.FormatValue(NVL(AcquisitionAndProductionCostsBegin,0)))>>
\						<<This.wxml("AcquisitionAndProductionCostsEnd", This.FormatValue(NVL(AcquisitionAndProductionCostsEnd,0)))>>
\						<<This.wxml("InvestmentSupport", This.FormatValue(NVL(InvestmentSupport,0)))>>
\						<<This.wxml("AssetLifeYear", this.FormatVal(AssetLifeYear, 18, 4))>>
\						<<This.wxml("AssetAddition", This.FormatValue(AssetAddition))>>
\						<<This.wxml("Transfers", This.FormatValue(Transfers))>>
\						<<This.wxml("AssetDisposal", This.FormatValue(AssetDisposal))>>
\						<<This.wxml("BookValueBegin", This.FormatValue(BookValueBegin))>>
\						<<This.wxml("DepreciationMethod", ALLTRIM(DepreciationMethod))>>
\						<<This.wxml("DepreciationPercentage",This.FormatVal(DepreciationPercentage,18,4))>>
\						<<This.wxml("DepreciationForPeriod", This.FormatValue(DepreciationForPeriod))>>
\						<<This.wxml("AppreciationForPeriod", This.FormatValue(AppreciationForPeriod))>>
\						<nsSAFT:ExtraordinaryDepreciationsForPeriod>
\							<nsSAFT:ExtraordinaryDepreciationForPeriod>
\								<<This.wxml("ExtraordinaryDepreciationMethod", m.lcExtraordinaryDepreciationMethod)>>
\								<<This.wxml("ExtraordinaryDepreciationAmountForPeriod", This.FormatValue(ExtraordinaryDepreciationAmountForPeriod))>>
\							</nsSAFT:ExtraordinaryDepreciationForPeriod>
\						</nsSAFT:ExtraordinaryDepreciationsForPeriod>
\						<<This.wxml("AccumulatedDepreciation", This.FormatValue(AccumulatedDepreciation))>>
\						<<This.wxml("BookValueEnd", This.FormatValue(BookValueEnd))>>
\					</nsSAFT:Valuation>
\				</nsSAFT:Valuations>
\			</nsSAFT:Asset>
		ENDSCAN && cAssets
\		
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText
	Endfunc && wAssets
	
	FUNCTION wAssetTransactions
		Local lcSelect, lcText
		Local lnNumberOfAssetTransactions
		lcText = ''

		lcSelect = Select()

		If !Used('cAssetTransactions')
			Return m.lcText
		ENDIF
		
		SET TEXTMERGE ON TO memvar lcText NOSHOW 
\
		Select cAssetTransactions
		lnNumberOfAssetTransactions = RECCOUNT()
\			<<This.wxml("NumberOfAssetTransactions", m.lnNumberOfAssetTransactions)>>
		SCAN
\			<nsSAFT:AssetTransaction>
\				<<This.wxml("AssetTransactionID", ALLTRIM(AssetTransactionID))>>
\				<<This.wxml("AssetID", ALLTRIM(AssetID))>>
\				<<This.wxml("AssetTransactionType", ALLTRIM(AssetTransactionType))>>
\				<<This.wxml("Description", ALLTRIM(Description))>>
\				<<This.wxml("AssetTransactionDate", This.FormatDate(AssetTransactionDate))>>
\				<<This.wxml("TransactionID", ALLTRIM(TransactionID))>>
\				<nsSAFT:AssetTransactionValuations>
\					<nsSAFT:AssetTransactionValuation>
\						<<This.wxml("AssetValuationType", ALLTRIM(AssetValuationType))>>
\						<<This.wxml("AcquisitionAndProductionCostsOnTransaction", This.FormatValue(AcquisitionAndProductionCostsOnTransaction))>>
\						<<This.wxml("BookValueOnTransaction", This.FormatValue(BookValueOnTransaction))>>
\						<<This.wxml("AssetTransactionAmount", This.FormatValue(AssetTransactionAmount))>>
\					</nsSAFT:AssetTransactionValuation>
\				</nsSAFT:AssetTransactionValuations>
\			</nsSAFT:AssetTransaction>
		ENDSCAN
\		
	SET TEXTMERGE TO 	
		Select (m.lcSelect)

		Return m.lcText
	ENDFUNC && wAssetTransactions
		
	Function wMovementTypeTable
		Local lcSelect, lcText
		lcText = ''
		lcSelect = Select()

		If !Used('cMovementTypeTable')
			Return m.lcText
		Endif

		Set Textmerge On To Memvar m.lcText Noshow
\
		Select cMovementTypeTable
		Scan
\			<nsSAFT:MovementTypeTableEntry>
\				<nsSAFT:MovementType><<ALLTRIM(movementtype)>></nsSAFT:MovementType>
\				<nsSAFT:Description><<ALLTRIM(description)>></nsSAFT:Description>
\			</nsSAFT:MovementTypeTableEntry>
		ENDSCAN
\		
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText

	Endfunc && wMovementTypeTable

	Function wProducts
		Local lcSelect, lcText
		Local lcCodBare, lcCodUMISO, lcDenumire, lcGoodsOrServiceId, lcProductCommodityCode, lnIdArticol
		lcText = ''
		lcSelect = Select()


		If !Used('cProducts')
			Return m.lcText
		Endif

		Set Textmerge On To Memvar m.lcText Noshow
\
		Select cProducts
* s.id_articol, a.denumire, a.codnc8, a.cod_um, a.cod_um_iso
		SCAN
			lnIdArticol = id_articol
			lcGoodsOrServicesId = ALLTRIM(goodsorservicesid) && 01 = goods, 02 = services 
			lcDenumire = XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(denumire, '')), .T.))
			lcProductCommodityCode = IIF(!EMPTY(ALLTRIM(NVL(codnc8,''))), ALLTRIM(codnc8), '00000000')
			lcCodBare = ALLTRIM(NVL(codbare, ''))
			lcCodUMISO = ALLTRIM(NVL(cod_um_iso, 'H87'))			
\			<nsSAFT:Product>
\				<<This.wXML('ProductCode', m.lnIdArticol)>>
\				<<This.wXML('GoodsServicesID', m.lcGoodsOrServicesId)>>
\				<<This.wXML('Description', m.lcDenumire)>>
\				<<This.wXML('ProductCommodityCode', m.lcProductCommodityCode)>>
\				<<This.wXML('ProductNumberCode', m.lcCodBare)>>
\				<<This.wXML('UOMBase', m.lcCodUMISO)>>
\				<<This.wXML('UOMStandard', m.lcCodUMISO)>>
\				<<This.wXML('UOMToUOMBaseConversionFactor', '1.0')>>
\			</nsSAFT:Product>
		ENDSCAN
\		
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText

	Endfunc && wProducts

	Function wPhysicalStock
		Local lcSelect, lcText
		Local lcCodUMISO, lcCont, lcCont2, lcOwnerId, lcProductType, lcStockAccountCommodityCode
		Local lnIdArticol, lnIdGestiune, lnPret, lnStocF, lnStocI, lnValF, lnValI, lcSaftPartIdUnitate
		lcText = ''
		lcSelect = Select()


		If !Used('cPhysicalStock')
			Return m.lcText
		Endif

* select s.id_gestiune,s.id_articol,s.pret,s.cont,s.id_part_rez,s.canti,s.vali,s.cantf,s.valf,a.codnc8,a.um,a.cod_um_iso

		lcSaftPartIdUnitate = '00' + This.oUnitate.codi       

		Set Textmerge On To Memvar m.lcText Noshow
		Select cPhysicalStock
		SCAN
			lnIdGestiune = id_gestiune
			lnIdArticol = id_articol
			lcCont = ALLTRIM(NVL(cont,''))
			lcCont2 = SUBSTR(cont,1,2)
*!*				lcProductType = IIF(m.lcCont2 = '30','MATERII PRIME', ;
*!*					IIF(m.lcCont2 = '32','IN CURS DE APROVIZIONARE', ;
*!*					IIF(m.lcCont2 = '33','IN CURS DE EXECUTIE', ;
*!*					IIF(m.lcCont2 = '34','PRODUSE', ;
*!*					IIF(m.lcCont2 = '35','LA TERTI', ;
*!*					IIF(m.lcCont2 = '36','ACTIVE BIOLOGICE', ;
*!*					IIF(m.lcCont2 = '37','MARFURI', ;
*!*					IIF(m.lcCont2 = '38','AMBALAJE', ;
*!*					IIF(m.lcCont2 = '39','AJUSTARI', 'MATERII PRIME')))))))))
			lcProductType = m.lcCont
							
			lcStockAccountCommodityCode	= IIF(!EMPTY(ALLTRIM(NVL(codnc8,''))), ALLTRIM(codnc8), '00000000')
			lcOwnerId = IIF(!EMPTY(ALLTRIM(NVL(saftpartid, ''))), ALLTRIM(saftpartid), m.lcSaftPartIdUnitate)
			
			lcCodUMISO = ALLTRIM(NVL(cod_um_iso,'H87')) 
			lnPret = pret
			lnStocI = canti
			lnValI = vali
			lnStocF = cantf
			lnValF = valf
\
\			<nsSAFT:PhysicalStockEntry>
\				<<This.wxml("WarehouseID", m.lnIdGestiune)>>
\				<<This.wxml("ProductCode", m.lnIdArticol)>>
\				<<This.wxml("ProductType", m.lcProductType)>>
\				<<This.wxml("StockAccountCommodityCode", m.lcStockAccountCommodityCode, .T.)>>
\				<<This.wxml("OwnerID", m.lcOwnerId, .T.)>>
\				<<This.wxml("UOMPhysicalStock", m.lcCodUMISO)>>
\				<<This.wxml("UOMToUOMBaseConversionFactor", "1.0")>>
\				<<This.wxml("UnitPrice", This.FormatValue(m.lnPret))>>
\				<<This.wxml("OpeningStockQuantity", This.FormatQuantity(m.lnStocI))>>
\				<<This.wxml("OpeningStockValue", This.FormatValue(m.lnValI))>>
\				<<This.wxml("ClosingStockQuantity", This.FormatQuantity(m.lnStocF))>>
\				<<This.wxml("ClosingStockValue", This.FormatValue(m.lnValF))>>
\				<nsSAFT:StockCharacteristics>
\					<<This.wxml("StockCharacteristic", "NULL")>>
\					<<This.wxml("StockCharacteristicValue", 0)>>
\				</nsSAFT:StockCharacteristics>
\			</nsSAFT:PhysicalStockEntry>
		ENDSCAN
\		
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText

	Endfunc && wPhysicalStock

	Function wMovementOfGoods
		Local lcSelect, lcText
		Local lcCodValuta, lcCont, lcCustomerId, lcSaftPartIdUnitate, lcSupplierId, lcTaxCode
		Local lcTaxInformationStructure, lcTaxType, lcUnitOfMeasure, lnCantitate, lnCurs, lnLineNumber
		Local lnMovementType, lnNumberOfMovementLines, lnProductCode, lnTaxa, lnTaxaValuta
		Local lnTotalQuantityIssued, lnTotalQuantityReceived, lnValoare
		Local ldDataAct, lnIdFact
		lcText = ''
		lcSelect = Select()

		If !Used('cMovementOfGoods')
			Return m.lcText
		ENDIF
		IF RECCOUNT('cMovementOfGoods') = 0
			Return m.lcText
		ENDIF 			

		lcSaftPartIdUnitate = '00' + This.oUnitate.codi      
		
		Select Count(*) As nr, Sum(cant) As cant, Sum(cante) As cante From cMovementofGoods Into Cursor cEntriesTotals
		Select cEntriesTotals
		lnNumberOfMovementLines = nr
		lnTotalQuantityReceived = cant
		lnTotalQuantityIssued = cante
		Use In (Select('cEntriesTotal'))

		Set Textmerge On To Memvar m.lcText Noshow
\<<''>>
		IF m.lnNumberOfMovementLines > 0
\			<nsSAFT:NumberOfMovementLines><<m.lnNumberOfMovementLines>></nsSAFT:NumberOfMovementLines>
\			<nsSAFT:TotalQuantityReceived><<This.FormatQuantity(m.lnTotalQuantityReceived)>></nsSAFT:TotalQuantityReceived>
\			<nsSAFT:TotalQuantityIssued><<This.FormatQuantity(m.lnTotalQuantityIssued)>></nsSAFT:TotalQuantityIssued>
		ENDIF 
		
	
		SELECT distinct id_fact, dataact, nract, fdoc, MAX(movementtype) as movementtype ;
			FROM cMovementofGoods ;
			GROUP BY id_fact, dataact, nract, fdoc ;
			ORDER BY dataact, nract ;
			INTO CURSOR cDocumenteTemp
			
		Select cDocumenteTemp
		SCAN
			lnIdFact = id_fact
			ldMovementDate = dataact
			lcMovementType = ALLTRIM(NVL(movementtype, ''))
			lcDocumentType = ALLTRIM(NVL(fdoc, 'ALTE'))
			lnDocumentNumber = nract
			
\			<nsSAFT:StockMovement>
\				<<This.wXml('MovementReference', id_fact)>>
\				<<This.wXml('MovementDate', This.FormatDate(m.ldMovementDate))>>
\				<<This.wXml('MovementType', m.lcMovementType)>>		
\				<nsSAFT:DocumentReference>
\					<<This.wXml('DocumentType', m.lcDocumentType)>>
\					<<This.wXml('DocumentNumber', m.lnDocumentNumber)>>
\				</nsSAFT:DocumentReference>			
			lnLineNumber = 0
			SELECT cMovementOfGoods
			SCAN FOR id_fact = m.lnIdFact AND dataact = m.ldMovementDate AND nract = m.lnDocumentNumber
				lnLineNumber = m.lnLineNumber + 1
				lcCont = ALLTRIM(NVL(cont, ''))

				lcCustomerId = '0'
				lcSupplierId = '0'
				DO CASE 
					CASE !EMPTY(ALLTRIM(NVL(saftPartIdC,'')))
						lcCustomerId = ALLTRIM(saftPartIdC)
					CASE !EMPTY(ALLTRIM(NVL(saftPartIdS,'')))
						lcSupplierId = ALLTRIM(saftPartIdS)
					OTHERWISE 
						lcCustomerId = m.lcSaftPartIdUnitate
						lcSupplierId = m.lcSaftPartIdUnitate					
				ENDCASE 		
				lnProductCode = id_articol
				lnCantitate = IIF(cant <> 0, cant, cante)
				lcUnitOfMeasure = ALLTRIM(NVL(cod_um_iso, 'H87'))
				lnValoare = valoare
				lcMovementType = ALLTRIM(NVL(movementType,''))
				lnTaxa = taxa
				lcCodValuta = 'RON'
				lnTaxaValuta = 0
				lnCurs = 1
				lcTaxType = ALLTRIM(STR(taxtype))
				lcTaxCode = ALLTRIM(STR(taxcode))
				lcTaxInformationStructure = This.wTaxInformationStructure(m.lnTaxa, m.lcCodValuta, m.lnTaxaValuta, m.lnCurs, m.lcTaxType, m.lcTaxCode)
			
\				<nsSAFT:StockMovementLine>
\					<<This.wXml('LineNumber', m.lnLineNumber)>>
\					<<This.wXml('AccountID', m.lcCont)>>
\					<<This.wXml('TransactionID', cod)>>
\					<<This.wXml('CustomerID', m.lcCustomerId)>>
\					<<This.wXml('SupplierID', m.lcSupplierId)>>
\					<<This.wXml('ProductCode', lnProductCode)>>
\					<<This.wXml('Quantity', This.FormatQuantity(m.lnCantitate))>>
\					<<This.wXml('UnitOfMeasure', m.lcUnitOfMeasure)>>
\					<<This.wXml('UOMToUOMPhysicalStockConversionFactor', 1.0)>>
\					<<This.wXml('BookValue', This.FormatValue(m.lnValoare))>>
\					<<This.wXml('MovementSubType', m.lcMovementType)>>
				IF !EMPTY(m.lcTaxCode) 
\					<<m.lcTaxInformationStructure>>
				ENDIF 	
\				</nsSAFT:StockMovementLine>
			ENDSCAN && cMovementOfGoods	
\			</nsSAFT:StockMovement>		
		ENDSCAN && cDocumenteTemp
		USE IN (SELECT('cDocumenteTemp'))	
\		
		Set Textmerge To

		Select (m.lcSelect)

		Return m.lcText

	Endfunc && wMovementOfGoods
				
	**************************
	* Structura AmountStructure
	**************************
	Function wAmountStructure
		Lparameters tnSuma, tcCodValuta, tnSumaValuta, tnCurs

		Local lcText
		lcText = Chr(13) + Chr(10) + ;
			Space(24) + [<nsSAFT:Amount>] + This.FormatValue(m.tnSuma) + [</nsSAFT:Amount>] + Chr(13) + Chr(10) + ;
			Space(24) + [<nsSAFT:CurrencyCode>] + Alltrim(NVL(m.tcCodValuta,'')) + [</nsSAFT:CurrencyCode>] + Chr(13) + Chr(10) + ;
			Space(24) + [<nsSAFT:CurrencyAmount>] + This.FormatValue(m.tnSumaValuta) + [</nsSAFT:CurrencyAmount>] + Chr(13) + Chr(10) + ;
			Space(24) + [<nsSAFT:ExchangeRate>] + This.FormatCurs(m.tnCurs) + [</nsSAFT:ExchangeRate>] + Chr(13) + Chr(10)

		Return m.lcText
	Endfunc && wAmountStructure

	**************************
	* Structura AddressStructure
	**************************
	FUNCTION wAddressStructure
		LPARAMETERS tcLocalitate, tcCodTara, tcStrada, tcNumar, tcIndicativJudet
		Local lcText, lcLocalitate, lcCodTara, lcStrada, lcNumar, lcRegiune

		lcLocalitate = XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(Nvl(m.tcLocalitate, 'BUCURESTI'), '')), .T.))
		lcCodTara = Alltrim(Upper(Nvl(m.tcCodTara, 'RO')))
		lcStrada = LEFT(IIF(!EMPTY(m.tcStrada) and !ISNULL(m.tcStrada), XmlSpecialCharacters(RemoveCharacters(Alltrim(Nvl(m.tcStrada, '')), .T.)), ''), 70)
		lcNumar = IIF(!EMPTY(m.tcNumar) and !ISNULL(m.tcNumar), ALLTRIM(TRANSFORM(m.tcNumar)), '')
		IF EMPTY(m.lcLocalitate)
			lcLocalitate = 'BUCURESTI'
		ENDIF 
		IF EMPTY(m.lcCodTara)
			lcCodTara = 'RO'
		ENDIF 
		lcRegiune = Iif(m.lcCodTara = 'RO' and !EMPTY(NVL(m.tcIndicativJudet, '')), m.lcCodTara + '-' + Alltrim(UPPER(m.tcIndicativJudet)), '')		
		lcText = Chr(13) + Chr(10) + ;
			IIF(!EMPTY(m.lcStrada), Space(50) + [<nsSAFT:StreetName>] + m.lcStrada + [</nsSAFT:StreetName>] + Chr(13) + Chr(10), '') + ;
			IIF(!EMPTY(m.lcNumar), Space(50) + [<nsSAFT:Number>] + m.lcNumar + [</nsSAFT:Number>] + Chr(13) + Chr(10), '') + ;
			Space(50) + [<nsSAFT:City>] + Alltrim(NVL(m.lcLocalitate,'')) + [</nsSAFT:City>] + Chr(13) + Chr(10) + ;
			IIF(!EMPTY(m.lcRegiune), Space(50) + [<nsSAFT:Region>] + m.lcRegiune + [</nsSAFT:Region>] + Chr(13) + Chr(10), '') + ;
			Space(50) + [<nsSAFT:Country>] + Alltrim(NVL(m.lcCodTara,'')) + [</nsSAFT:Country>] + Chr(13) + Chr(10)
		Return m.lcText				
	ENDFUNC && wAddressStructure

	**************************
	* Structura CompanyStructure
	**************************	
	FUNCTION wCompanyStructure
		LPARAMETERS tcSaftPartId, tcDenumire, tcLocalitate, tcCodTara, tcStrada, tcNumar, tcIndicativJudet

		Local lcAddressStructure, lcDenumire, lcRegistrationNumber, lcText
		
		lcRegistrationNumber = Iif(!Empty(NVL(m.tcSaftPartId, '')), ALLTRIM(m.tcSaftPartId), 'NULL')
		lcDenumire = ALLTRIM(NVL(m.tcDenumire, ''))
		lcAddressStructure = This.wAddressStructure(m.tcLocalitate, m.tcCodTara, m.tcStrada, m.tcNumar, m.tcIndicativJudet)
			
		lcText = Chr(13) + Chr(10) + ;
'					' + This.wxml("RegistrationNumber", m.lcRegistrationNumber) + CHR(13) + CHR(10) + ;
'					' + This.wxml("Name", m.lcDenumire) + CHR(13) + CHR(10) + ;
'					' + This.wxml("Address", m.lcAddressStructure) + CHR(13) + CHR(10)
		RETURN m.lcText 
	ENDFUNC 

	**************************
	* Structura TaxInformationStructure
	**************************		
	FUNCTION wTaxInformationStructure	
		LPARAMETERS tnTaxa, tcCodValuta, tnTaxaValuta, tnCurs, tcTaxType, tcTaxCode
		LOCAL lcTaxAmountStructure, lcTaxType, lcTaxCode
		
		lcTaxAmountStructure = This.wAmountStructure(m.tnTaxa, m.tcCodValuta, m.tnTaxaValuta, m.tnCurs)
		lcTaxType = IIF(!EMPTY(ALLTRIM(NVL(m.tcTaxType, ''))), ALLTRIM(m.tcTaxType), '000')
		lcTaxCode = IIF(!EMPTY(ALLTRIM(NVL(m.tcTaxCode, ''))), ALLTRIM(m.tcTaxCode), '000000')
		lcText = Chr(13) + Chr(10) + ;
'					<nsSAFT:TaxInformation>' + CHR(13) + CHR(10) + ;
'						' + This.wxml("TaxType", m.lcTaxType) + CHR(13) + CHR(10) + ;
'						' + This.wxml("TaxCode", m.lcTaxCode) + CHR(13) + CHR(10) + ;
'						' + This.wxml("TaxAmount", m.lcTaxAmountStructure) + CHR(13) + CHR(10) + ;
'					</nsSAFT:TaxInformation>'
		RETURN m.lcText 
	ENDFUNC && wTaxInformationStructure
	
	
	**************************
	* Intoarce id din AnalysisTypeTable pe baza id_sectie, id_sucursala
	**************************
	Function GetAnalysisId
		Lparameters tnIdSucursala, tnIdSectie
		lcCod = ''
		If !Empty(Nvl(tnIdSectie, 0))
			lcCod = 'S' + Alltrim(Str(Nvl(tnIdSucursala, 0))) + '-C' + Alltrim(Str(tnIdSectie))
		Endif
		Return m.lcCod
	Endfunc && GetAnalysisId

	* Intorce o structura cu adresa partenerului dupa ID_PART
	FUNCTION GetStructuraAdresaPartener
		LPARAMETERS tcCursor, tnIdPart 
		* tcCursor: cCUSTOMERS/cSUPPLIERS/cOwners
		
		lcSelect = SELECT()
		lcAdressStructure = ''

		SELECT (m.tcCursor)
		IF SEEK(m.tnIdPart, m.tcCursor, 'id_part')
			lcLocalitate = localitate
			lcCodTara = cod_tara
			lcStrada = strada
			lcNumar = numar
			lcIndicativJudet = indicativ_judet
			lcAdressStructure = This.wAddressStructure(m.lcLocalitate, m.lcCodTara, m.lcStrada, m.lcNumar, m.lcIndicativJudet)
		ENDIF 

		SELECT (m.lcSelect)
		RETURN m.lcAdressStructure
	ENDFUNC 
	
	**********************************************************
	* Intoarce codul client/furnizor/owner dupa Id Part din cCustomers/cSuppliers/cOwners
	**********************************************************
	FUNCTION GetCustomerCode
		LPARAMETERS tnIdPart
		RETURN This.GetCustSupCode('cCustomers', m.tnIdPart)
	ENDFUNC 

	FUNCTION GetSupplierCode
		LPARAMETERS tnIdPart
		RETURN This.GetCustSupCode('cSuppliers', m.tnIdPart)
	ENDFUNC 
	
	FUNCTION GetOwnerCode
		LPARAMETERS tnIdPart
		RETURN This.GetCustSupCode('cOwners', m.tnIdPart)
	ENDFUNC 		

	FUNCTION GetCustSupCode
		LPARAMETERS tcCursor, tnIdPart
		* tcCursor: cCustomers/cSuppliers/cOwners

		Local lcCursor, lcSelect, lcSaftPartId
		lcSelect = Select()
		lcCursor = m.tcCursor
		lcSaftPartId = ''
		IF SEEK(m.tnIdPart, m.lcCursor, 'id_part')
			lcSaftPartId = ALLTRIM(&lcCursor..SaftPartId)
		ENDIF 	
		
		SELECT (m.lcSelect)
		RETURN m.lcSaftPartId
	ENDFUNC && GetcustSupCode
	
	**********************************************************
	* Genereaza codul client/furnizor
	**********************************************************
	Function GenCustSupCode
		Lparameters tnIdPart, tcCodTara, tnTipPersoana, tcCodFiscal
* tcCodTara = nom_tari.prescurtare
* tnTipPersoana: 1 = PJ, 2 = FIZICA
* tcCodFiscal: cu sau fara cod tara

		Local lcCodTara, llPJ, lcCodFiscal, lcAtributFiscal, lcCodFiscalFRO, llEU, lcCustSupCode, llRO
		llPJ = (Nvl(m.tnTipPersoana, 1) = 1)
		lcCodFiscal = Alltrim(Transform(m.tcCodFiscal))
		lcCodTara = Alltrim(Nvl(m.tcCodTara, 'RO'))
		lcCodTara = Iif(!Empty(NVL(m.lcCodTara,'')), ALLTRIM(m.lcCodTara), 'RO')
		lcIdPart = Alltrim(Transform(m.tnIdPart))

		lcAtributFiscal = Substr(Trim(Upper(m.lcCodFiscal)), 1, 2)
		IF !ISALPHA(m.lcAtributFiscal)
			lcAtributFiscal = ''
		ENDIF 
		lcCodFiscalFRO = Strtran(m.lcCodFiscal, m.lcCodTara, '', 1, 1, 1)
		lcCodFiscalFRO = Strtran(m.lcCodFiscalFRO, m.lcAtributFiscal, '', 1, 1, 1) && in caz ca atributul fiscal <> codul de tara (GR <> EL)
		lcCodFiscalFRO = Strtran(Strtran(Strtran(m.lcCodFiscalFRO, ' ', ''), 'RO', ''), 'R', '')
		lcCodFiscalFRO = ALLTRIM(m.lcCodFiscalFRO)
		
		llEU = Inlist(m.lcCodTara, 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'EL', 'ES', 'FI', 'FR', 'HR', 'GR') Or Inlist(m.lcCodTara, 'HU', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'SE', 'SI', 'SK')
		llRO = (m.lcCodTara = 'RO')
		
		lcCustSupCode = '08' + '0000000000000'
		Do Case
			Case m.llPJ And m.lcCodTara = 'RO' And !Empty(m.lcCodFiscalFRO)
				lcCustSupCode = '00' + m.lcCodFiscalFRO

			Case m.llPJ And !Empty(m.lcAtributFiscal) And m.llEU
				lcCustSupCode = '01'  + m.lcCodTara + m.lcCodFiscalFRO

			Case m.llPJ And !Empty(m.lcAtributFiscal) And !m.llEU AND !m.llRO
				lcCustSupCode = '02' + m.lcCodTara + m.lcCodFiscalFRO

			Case m.llPJ And Empty(m.lcAtributFiscal) And m.llEU AND !m.llRO
				lcCustSupCode = '05' + m.lcCodTara + m.lcIdPart

			Case m.llPJ And Empty(m.lcAtributFiscal) And !m.llEU AND !m.llRO
				lcCustSupCode = '06' + m.lcCodTara + m.lcIdPart

			CASE m.llPJ AND EMPTY(m.lcCodFiscal)
				lcCustSupCode = '' && Nu ar trebui sa se intample. O sa dea eroare la verificare

			Case !m.llPJ
				If !Empty(m.lcCodFiscal)
					If m.lcCodTara = 'RO'
						lcCustSupCode = '03' + m.lcCodFiscal
					Endif
				Else
					lcCustSupCode = '04' + STRTRAN(m.lcIdPart,'-', '0',1,1,1) && inlocuiesc -1000 din id_part cu 01000
				Endif
		Endcase

		Return m.lcCustSupCode

	Endfunc && GenCustSupCode

	*******************************************
	* Formateaza data conform ISO8601
	* aaaa-ll-zz
	*******************************************
	Function FormatDate
		Lparameters tdData

		Local lcData
		lcData = ''
		If !Empty(Nvl(m.tdData, {}))
			lcData = Dtos(m.tdData)
			lcData = Left(m.lcData, 4) + '-' + Substr(m.lcData, 5, 2) + '-' + Right(m.lcData, 2)
		Endif
		Return m.lcData
	Endfunc && FormatDate

	*******************************************
	* Formateaza valoare cu 2 zecimale
	* 1234.65
	*******************************************	
	FUNCTION FormatValue
		LPARAMETERS tnValoare

		RETURN This.FormatVal(m.tnValoare, 20,2)
	ENDFUNC && FormatValue

	*******************************************
	* Formateaza curs cu 4 zecimale
	* 4.9492
	*******************************************	
	FUNCTION FormatCurs
		LPARAMETERS tnCurs
		
		RETURN This.FormatVal(m.tnCurs, 14,4)
	ENDFUNC && FormatCurs
	
	*******************************************
	* Formateaza cantitate cu 6 zecimale
	*******************************************	
	FUNCTION FormatQuantity
		LPARAMETERS tnCantitate
		
		RETURN This.FormatVal(tnCantitate, 22,6)
	ENDFUNC && 	
	
	*******************************************
	* Formateaza valoare cu zecimale
	*******************************************	
	FUNCTION FormatVal
		LPARAMETERS tnValue, tnDigits, tnDecimals
		
		RETURN Alltrim(STR(NVL(m.tnValue,0), tnDigits, tnDecimals))	
	ENDFUNC && FormatVal
	
	
		
Enddefine
                         