D406 SAF-T: raport erori validator pe intelesul utilizatorului

La validarea cu erori se genereaza <xml>_explicat.txt: un rand pe eroare
(pagina, pozitie, partener/cont identificat, explicatie) + sectiunea
"Cum rezolvati". Erorile fictive TaxCode "nu se afla in lista" (bug
DUKIntegrator) sunt separate si ignorabile. Se deschid ambele fisiere,
raportul explicat deasupra; chatbot-ul primeste doar erorile reale.
Mesajul separat de parteneri respinsi + exportul Excel eliminate din flux.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ExTWMJbKantwNvL6AtEwzH
This commit is contained in:
2026-07-27 20:18:49 +03:00
parent 1ae9d3f14a
commit 0c9255842d
2 changed files with 367 additions and 13 deletions

View File

@@ -81,6 +81,10 @@
*!* 01.072026
*!* oSalesInvoices - se facea join dublu vanzari - jv2007 in cazul facturilor cu tva la incasare
*!* 27.07.2026
*!* do_erori_saft, do_ident_saft - raport erori validator pe intelesul utilizatorului (fisierul <xml>_explicat.txt): pagina, pozitie, partener/cont identificat, explicatie scurta si sectiunea "Cum rezolvati"
*!* erorile fictive TaxCode "nu se afla in lista" (bug DUKIntegrator) sunt separate si ignorabile; chatbot-ul primeste doar erorile reale; mesajul separat de parteneri respinsi (do_erori_partener_saft) eliminat din flux
* saft_D406
Procedure viz_saft_d406
loD406 = Createobject("D406")
@@ -254,10 +258,10 @@ Define Class d406 As Custom
Local lcTaxTable, lcTipDeclaratie
LOCAL lnBytes, llSucces
Local lcAssetTransactions, lcAssets, lcCaleFisier, lcComunPath, lcConfigDir, lcFileName
Local lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock
Local lcFisierExplicat, lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock
Local lcProducts, lcUOMTable, lcValidator, lcXMLTemp, lnFileHandle, lnSec, lcSufixCale, lcSufixFisier
LOCAL lcMessage, loChatBot, lcMesajErori
LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2
LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2, lnEroriFictive, lnEroriReale
lnAn1 = This.oUnitate.an1
lnLuna1 = This.oUnitate.luna1
@@ -556,20 +560,23 @@ Define Class d406 As Custom
OPEN_DEFAULT_APP(m.lcValidator, m.lcParams)
ELSE
*!* 26.07.2026 scot din fisierul de erori codurile de partener respinse de validator
lcMesajErori = This.do_erori_partener_saft(m.lcFisierRaspuns)
IF !EMPTY(m.lcMesajErori)
IF AMESSAGEBOX(m.lcMesajErori + CHR(13) + CHR(10) + CHR(13) + CHR(10) + 'Doriti exportul listei in Excel?',0+4+48,_screen.Caption) = 6
goExport.export2xlsx('cEroriPartSaft', 'erori_cod_partener_saft_' + ALLTRIM(STR(m.lnAn2)) + PADL(m.lnLuna2, 2, '0'))
ENDIF
USE IN (SELECT('cEroriPartSaft'))
*!* 27.07.2026 un singur raport compact cu erorile explicate si identificate, erorile fictive de TaxCode (bug DUKIntegrator) separate
lnEroriReale = 0
lnEroriFictive = 0
lcMesajErori = ''
lcFisierExplicat = This.do_erori_saft(m.lcFisierRaspuns, @lnEroriReale, @lnEroriFictive, @lcMesajErori)
OPEN_DEFAULT_APP(m.lcFisierRaspuns)
IF !EMPTY(m.lcFisierExplicat)
OPEN_DEFAULT_APP(m.lcFisierExplicat)
ENDIF
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)
IF AMESSAGEBOX('Validare cu erori fisier: ' + m.lcFileName + CHR(13) + CHR(10) + ;
'Erori de rezolvat: ' + ALLTRIM(STR(m.lnEroriReale)) + ;
IIF(m.lnEroriFictive > 0, ' (+' + ALLTRIM(STR(m.lnEroriFictive)) + ' fictive - bug validator, se pot ignora)', '') + CHR(13) + CHR(10) + CHR(13) + CHR(10) + ;
'Doriti sa interogati chatbot-ul de suport tehnic?',0+4+48,_screen.Caption) = 6
lcMessage = EVL(m.lcMesajErori, FILETOSTR(m.lcFisierRaspuns))
loChatBot = CREATEOBJECT("oChatBotLaunch", m.lcMessage)
loChatBot.Launch()
ENDIF
OPEN_DEFAULT_APP(m.lcFisierRaspuns)
ENDIF
ENDIF
ELSE
AMESSAGEBOX('Nu s-a creat fisierul raspuns ' + m.lcFisierRaspuns + ' dupa validare!', 0+48,_screen.Caption)
@@ -1311,6 +1318,338 @@ and b1.cont = b2.cont
RETURN m.lcMesaj
ENDPROC && do_erori_partener_saft
*************************************************
* Parseaza fisierul de raspuns al validatorului ANAF, grupeaza erorile cu
* explicatii pe intelesul utilizatorului si separa erorile fictive de TaxCode
* (bug DUKIntegrator: apar cand exista alta eroare reala, pentru coduri valide)
* Scrie raportul in <fisier>_explicat.txt si intoarce calea lui, gol la esec
*************************************************
PROCEDURE do_erori_saft
LPARAMETERS tcFisierRaspuns, tnReale, tnFictive, tcMesajChat
LOCAL lcActiune, lcCRLF, lcCod, lcFisierExplicat, lcIdent, lcLegenda, lcLinie, lcLocatie, lcMarker
LOCAL lcMesaj, lcMesajChat, lcPagina, lcProblema, lcRaport, lcSelect, lcValoare, llFictiv, lnCateg
LOCAL lnFictive, lnFile, lnI, lnPoz, lnRand, lnReale
lcFisierExplicat = ''
lcCRLF = CHR(13) + CHR(10)
lcSelect = SELECT()
IF !FILE(m.tcFisierRaspuns)
RETURN m.lcFisierExplicat
ENDIF
*!* o eroare = linia de localizare "E:/F: sectiune ... (N)" + linia de mesaj; erorile fatale de parsare sunt pe o singura linie
CREATE CURSOR cErrSaft (categ N(3), pagina C(30), rand N(7), valoare C(30), mesaj C(240), brut M)
lnFile = FOPEN(m.tcFisierRaspuns, 0)
IF m.lnFile < 0
USE IN (SELECT('cErrSaft'))
SELECT (m.lcSelect)
RETURN m.lcFisierExplicat
ENDIF
lcLocatie = ''
DO WHILE !FEOF(m.lnFile)
lcLinie = FGETS(m.lnFile, 8192)
IF INLIST(LEFT(LTRIM(m.lcLinie), 2), 'E:', 'F:')
lcLocatie = m.lcLinie
LOOP
ENDIF
IF ATC('Eroare fatala de parsare', m.lcLinie) > 0
INSERT INTO cErrSaft (categ, pagina, rand, valoare, mesaj, brut) VALUES (11, '', 0, '', LEFT(ALLTRIM(m.lcLinie), 240), m.lcLinie)
lcLocatie = ''
LOOP
ENDIF
lcMesaj = ALLTRIM(m.lcLinie)
IF EMPTY(m.lcMesaj) OR EMPTY(m.lcLocatie)
LOOP
ENDIF
* pagina din aplicatie, dupa sectiunea din linia de localizare
DO CASE
CASE ATC('PurchaseInvoices', m.lcLocatie) > 0
lcPagina = 'Facturi achizitie'
CASE ATC('SalesInvoices', m.lcLocatie) > 0
lcPagina = 'Facturi vanzare'
CASE ATC('Payments', m.lcLocatie) > 0
lcPagina = 'Plati'
CASE ATC('MovementOfGoods', m.lcLocatie) > 0
lcPagina = 'Miscari bunuri'
CASE ATC('AssetTransactions', m.lcLocatie) > 0
lcPagina = 'Tranzactii active'
CASE ATC('GeneralLedgerEntries', m.lcLocatie) > 0
lcPagina = 'Inregistrari contabile'
CASE ATC('GeneralLedgerAccounts', m.lcLocatie) > 0
lcPagina = 'Conturi contabile'
CASE ATC('Customers', m.lcLocatie) > 0
lcPagina = 'Clienti'
CASE ATC('Suppliers', m.lcLocatie) > 0
lcPagina = 'Furnizori'
CASE ATC('TaxTable', m.lcLocatie) > 0
lcPagina = 'Nomenclator coduri taxa'
CASE ATC('Products', m.lcLocatie) > 0
lcPagina = 'Articole'
CASE ATC('PhysicalStock', m.lcLocatie) > 0
lcPagina = 'Stocuri'
CASE ATC('Assets', m.lcLocatie) > 0
lcPagina = 'Active'
CASE ATC('Header', m.lcLocatie) > 0
lcPagina = 'Definirea Companiei'
OTHERWISE
lcPagina = ''
ENDCASE
* pozitia din grid = indexul elementului de nivel document din localizare
lnRand = 0
FOR lnI = 1 TO 8
lcMarker = 'sectiune ' + GETWORDNUM('Transaction,Invoice,Payment,Customer,Supplier,Account,Asset,Product', m.lnI, ',') + ' ('
lnPoz = ATC(m.lcMarker, m.lcLocatie)
IF m.lnPoz > 0
lnRand = INT(VAL(SUBSTR(m.lcLocatie, m.lnPoz + LEN(m.lcMarker))))
EXIT
ENDIF
ENDFOR
lcValoare = ''
DO CASE
CASE ATC('formatul este invalid', m.lcMesaj) > 0 AND (ATC('CustomerID', m.lcMesaj) > 0 OR ATC('SupplierID', m.lcMesaj) > 0 OR ATC('RegistrationNumber', m.lcMesaj) > 0)
lnCateg = 1
CASE ATC('nu se afla in lista', m.lcMesaj) > 0 AND ATC('TaxCode (', m.lcLocatie) > 0
lnCateg = 12
lcValoare = STREXTRACT(m.lcMesaj, [valoarea '], ['])
CASE ATC('vid nepermis', m.lcMesaj) > 0 AND (ATC('CustomerID (', m.lcLocatie) > 0 OR ATC('SupplierID (', m.lcLocatie) > 0)
lnCateg = 2
CASE ATC([elementul 'AccountID'], m.lcMesaj) > 0 AND ATC('Payments', m.lcLocatie) > 0
lnCateg = 3
CASE ATC([elementul 'InvoiceLine'], m.lcMesaj) > 0
lnCateg = 4
CASE ATC([elementul 'RegistrationNumber'], m.lcMesaj) > 0 OR (ATC('vid nepermis', m.lcMesaj) > 0 AND ATC('RegistrationNumber (', m.lcLocatie) > 0)
lnCateg = 5
CASE ATC('planul de conturi', m.lcMesaj) > 0
lnCateg = 6
lcValoare = STREXTRACT(m.lcMesaj, '[', ']')
CASE ATC('vid nepermis', m.lcMesaj) > 0 AND ATC('AccountDescription', m.lcLocatie) > 0
lnCateg = 7
CASE ATC('BankAccount_choice', m.lcMesaj) > 0
lnCateg = 8
CASE ATC('SupplierInfo_choice', m.lcMesaj) > 0
lnCateg = 9
CASE ATC([elementul 'Transaction'], m.lcMesaj) > 0
lnCateg = 10
OTHERWISE
lnCateg = 13
ENDCASE
INSERT INTO cErrSaft (categ, pagina, rand, valoare, mesaj, brut) ;
VALUES (m.lnCateg, m.lcPagina, m.lnRand, LEFT(m.lcValoare, 30), IIF(m.lnCateg = 13, LEFT(m.lcMesaj, 240), ''), m.lcLocatie + m.lcCRLF + m.lcLinie)
lcLocatie = ''
ENDDO
= FCLOSE(m.lnFile)
IF RECCOUNT('cErrSaft') = 0
USE IN (SELECT('cErrSaft'))
SELECT (m.lcSelect)
RETURN m.lcFisierExplicat
ENDIF
*!* erorile fictive TaxCode (bug DUKIntegrator): codul semnalat exista de fapt in nomenclator
SELECT DISTINCT valoare FROM cErrSaft WHERE categ = 12 INTO CURSOR cCodTaxaVerif
SELECT cCodTaxaVerif
SCAN
lcCod = ALLTRIM(cCodTaxaVerif.valoare)
IF EMPTY(m.lcCod) OR LEN(CHRTRAN(m.lcCod, '0123456789', '')) > 0
LOOP
ENDIF
llFictiv = .F.
IF USED('cTaxTable')
SELECT cTaxTable
LOCATE FOR ALLTRIM(STR(taxcode)) == m.lcCod
llFictiv = FOUND()
ELSE
IF goExecutor.oExecuta('SELECT taxcode FROM vsaft_taxtable WHERE taxcode = ' + m.lcCod, 'cTaxVerifTmp')
llFictiv = (RECCOUNT('cTaxVerifTmp') > 0)
USE IN (SELECT('cTaxVerifTmp'))
ENDIF
ENDIF
IF m.llFictiv
UPDATE cErrSaft SET categ = 90 WHERE categ = 12 AND ALLTRIM(valoare) == m.lcCod
ENDIF
SELECT cCodTaxaVerif
ENDSCAN
USE IN (SELECT('cCodTaxaVerif'))
SELECT cErrSaft
COUNT FOR categ = 90 TO lnFictive
*!* textul pentru chatbot: erorile brute, fara cele fictive (bug validator)
lcMesajChat = ''
SELECT cErrSaft
SCAN FOR categ < 90
lcMesajChat = m.lcMesajChat + brut + m.lcCRLF
ENDSCAN
*!* dedup: aceeasi problema pe aceeasi pozitie o singura data (ex: CustomerID + RegistrationNumber pe acelasi client)
SELECT DISTINCT categ, pagina, valoare, mesaj, rand FROM cErrSaft WHERE categ < 90 ORDER BY 1, 2, 5 INTO CURSOR cErrPoz
lnReale = RECCOUNT('cErrPoz')
lcRaport = 'ERORI VALIDARE D406 SAF-T - ' + JUSTFNAME(m.tcFisierRaspuns) + m.lcCRLF + ;
'Erori de rezolvat: ' + ALLTRIM(STR(m.lnReale)) + ' | Fictive (bug validator, se pot ignora): ' + ALLTRIM(STR(m.lnFictive)) + m.lcCRLF + ;
REPLICATE('=', 110) + m.lcCRLF
lcLegenda = ''
SELECT cErrPoz
SCAN
lcIdent = This.do_ident_saft(ALLTRIM(cErrPoz.pagina), cErrPoz.rand)
lcActiune = ''
DO CASE
CASE cErrPoz.categ = 1
lcProblema = 'cod partener SAF-T invalid (CUI/CNP gresit sau tip PJ/PF gresit)'
lcActiune = 'Parteneri: corectati tip persoana / cod fiscal in Initializare > Entitati; CNP-uri invalide in masa: Initializari cod taxa/plata > Stergere CNP-uri invalide'
CASE cErrPoz.categ = 2
lcProblema = 'partener fara cod fiscal pe plata (sau nota nu e plata catre terti)'
lcActiune = 'Plati: completati codul fiscal al partenerului (partener virtual: CUI-ul firmei) sau stergeti codul de plata de pe notele care nu sunt plati catre terti, in Registrul Jurnal'
CASE cErrPoz.categ = 3
lcProblema = 'plata fara cont contabil (nota nu e plata catre terti)'
lcActiune = 'Plati: completati codul fiscal al partenerului (partener virtual: CUI-ul firmei) sau stergeti codul de plata de pe notele care nu sunt plati catre terti, in Registrul Jurnal'
CASE cErrPoz.categ = 4
lcProblema = 'factura fara articole (probabil document sters)'
lcActiune = 'Facturi fara articole: Refacere Registru TVA Cumparari/Vanzari, apoi regenerati D406'
CASE cErrPoz.categ = 5
lcProblema = 'PJ fara cod fiscal sau PF marcata ca PJ'
lcActiune = 'Parteneri: corectati tip persoana / cod fiscal in Initializare > Entitati; CNP-uri invalide in masa: Initializari cod taxa/plata > Stergere CNP-uri invalide'
CASE cErrPoz.categ = 6
lcProblema = 'contul ' + ALLTRIM(cErrPoz.valoare) + ' nu exista in planul de conturi'
lcActiune = 'Conturi: corectati contul in notele din Registrul Jurnal sau completati planul de conturi al firmei'
CASE cErrPoz.categ = 7
lcProblema = 'cont fara denumire (nu exista in planul de conturi al firmei)'
lcActiune = 'Conturi: corectati contul in notele din Registrul Jurnal sau completati planul de conturi al firmei'
CASE cErrPoz.categ = 8
lcProblema = 'lipseste contul bancar (IBAN) al firmei'
lcActiune = 'Cont bancar: completati IBAN-ul in Definirea Companiei'
CASE cErrPoz.categ = 9
lcProblema = 'adresa furnizorului incompleta (judet/localitate) sau document sters'
lcActiune = 'Adresa furnizor: dublu click pe furnizor in Facturi achizitie; daca e document sters cu valoare 0: Refacere Registru TVA Cumparari'
CASE cErrPoz.categ = 10
lcProblema = 'nu exista note contabile in perioada'
lcActiune = 'Registru gol: introduceti o nota cu valoare 0 (ex: 371 = 371)'
CASE cErrPoz.categ = 11
lcProblema = ALLTRIM(cErrPoz.mesaj)
lcActiune = 'Caracter nepermis: inlocuiti & cu "si" in campul sursa (denumire/adresa) si regenerati D406'
CASE cErrPoz.categ = 12
lcProblema = 'cod taxa ' + ALLTRIM(cErrPoz.valoare) + ' inexistent in nomenclatorul SAF-T'
lcActiune = 'Cod taxa: corectati codul de taxa pe notele din Registrul Jurnal'
OTHERWISE
lcProblema = ALLTRIM(cErrPoz.mesaj)
ENDCASE
IF !EMPTY(m.lcActiune) AND ATC(m.lcActiune, m.lcLegenda) = 0
lcLegenda = m.lcLegenda + '- ' + m.lcActiune + m.lcCRLF
ENDIF
lcRaport = m.lcRaport + PADR(ALLTRIM(cErrPoz.pagina), 20) + ' ' + ;
PADR(IIF(cErrPoz.rand > 0, 'poz.' + ALLTRIM(STR(cErrPoz.rand)), ''), 8) + ' ' + ;
IIF(EMPTY(m.lcIdent), '', PADR(m.lcIdent, 45) + ' ') + '- ' + m.lcProblema + m.lcCRLF
ENDSCAN
USE IN (SELECT('cErrPoz'))
IF m.lnReale = 0
lcRaport = m.lcRaport + 'Niciuna.' + m.lcCRLF
ENDIF
IF !EMPTY(m.lcLegenda)
lcRaport = m.lcRaport + m.lcCRLF + 'CUM REZOLVATI:' + m.lcCRLF + m.lcLegenda
ENDIF
IF m.lnFictive > 0
lcIdent = ''
SELECT valoare, COUNT(*) AS nr FROM cErrSaft WHERE categ = 90 GROUP BY 1 ORDER BY 1 INTO CURSOR cErrFictivSaft
SELECT cErrFictivSaft
SCAN
lcIdent = m.lcIdent + IIF(EMPTY(m.lcIdent), '', ', ') + ALLTRIM(cErrFictivSaft.valoare) + ' (' + ALLTRIM(STR(cErrFictivSaft.nr)) + 'x)'
ENDSCAN
USE IN (SELECT('cErrFictivSaft'))
lcRaport = m.lcRaport + m.lcCRLF + 'FICTIVE - BUG VALIDATOR ANAF (se pot ignora): cod taxa ' + m.lcIdent + m.lcCRLF + ;
'Codurile sunt valide (exista in nomenclator); erorile apar doar cand exista alta eroare reala si dispar dupa rezolvarea ei.' + m.lcCRLF
ENDIF
lcRaport = m.lcRaport + m.lcCRLF + 'Erorile brute: ' + m.tcFisierRaspuns + m.lcCRLF
lcFisierExplicat = ADDBS(JUSTPATH(m.tcFisierRaspuns)) + JUSTSTEM(m.tcFisierRaspuns) + '_explicat.txt'
IF FILE(m.lcFisierExplicat)
DELETE FILE (m.lcFisierExplicat)
ENDIF
= STRTOFILE(m.lcRaport, m.lcFisierExplicat)
IF !FILE(m.lcFisierExplicat)
lcFisierExplicat = ''
ENDIF
USE IN (SELECT('cErrSaft'))
SELECT (m.lcSelect)
tnReale = m.lnReale
tnFictive = m.lnFictive
tcMesajChat = m.lcMesajChat
RETURN m.lcFisierExplicat
ENDPROC && do_erori_saft
*************************************************
* Identificatorul de afisat pentru pozitia tnRand din cursorul paginii tcPagina
* (sectiunile XML se scriu prin SCAN secvential, deci pozitia din eroare este
* a tnRand-a inregistrare vizibila; la Conturi ramane activ filtrul writer-ului)
*************************************************
PROCEDURE do_ident_saft
LPARAMETERS tcPagina, tnRand
LOCAL lcAlias, lcIdent, lcSelect, lnRecno
lcIdent = ''
IF m.tnRand <= 0
RETURN m.lcIdent
ENDIF
DO CASE
CASE m.tcPagina == 'Clienti'
lcAlias = 'cCustomers'
CASE m.tcPagina == 'Furnizori'
lcAlias = 'cSuppliers'
CASE m.tcPagina == 'Conturi contabile'
lcAlias = 'cGeneralLedgerAccounts'
CASE m.tcPagina == 'Inregistrari contabile'
lcAlias = 'cGeneralLedgerEntries'
CASE m.tcPagina == 'Plati'
lcAlias = 'cPayments'
CASE m.tcPagina == 'Facturi vanzare'
lcAlias = 'cSalesInvoices'
CASE m.tcPagina == 'Facturi achizitie'
lcAlias = 'cPurchaseInvoices'
OTHERWISE
lcAlias = ''
ENDCASE
IF EMPTY(m.lcAlias) OR !USED(m.lcAlias)
RETURN m.lcIdent
ENDIF
lcSelect = SELECT()
SELECT (m.lcAlias)
lnRecno = RECNO()
GO TOP
IF m.tnRand > 1 AND !EOF()
SKIP m.tnRand - 1
ENDIF
IF !EOF()
DO CASE
CASE INLIST(m.lcAlias, 'cCustomers', 'cSuppliers')
lcIdent = ALLTRIM(NVL(saftpartid, '')) + ' ' + ALLTRIM(NVL(denumire, ''))
CASE m.lcAlias == 'cGeneralLedgerAccounts'
lcIdent = 'cont ' + ALLTRIM(NVL(cont, '')) + ' ' + ALLTRIM(NVL(denumire, ''))
CASE m.lcAlias == 'cGeneralLedgerEntries'
lcIdent = 'nota ' + ALLTRIM(TRANSFORM(cod)) + IIF(EMPTY(dataact), '', ' / ' + DTOC(dataact)) + ' cont ' + ALLTRIM(NVL(cont, '')) + ' ' + ALLTRIM(NVL(saftpartid, ''))
CASE m.lcAlias == 'cPayments'
lcIdent = IIF(TYPE('denumire') = 'C', ALLTRIM(NVL(denumire, '')) + ' ', '') + LEFT(ALLTRIM(NVL(explicatia, '')), 40)
OTHERWISE
lcIdent = 'fact. ' + ALLTRIM(TRANSFORM(nract)) + IIF(EMPTY(dataact), '', ' / ' + DTOC(dataact)) + ' ' + ALLTRIM(NVL(saftpartid, ''))
ENDCASE
ENDIF
IF BETWEEN(m.lnRecno, 1, RECCOUNT(m.lcAlias))
GO m.lnRecno
ENDIF
SELECT (m.lcSelect)
RETURN LEFT(ALLTRIM(m.lcIdent), 45)
ENDPROC && do_ident_saft
&& 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