D406 SAF-T: verificare coduri fiscale pe toata declaratia + erori validator ANAF

Stergere CNP-uri invalide:
- bucla de update nu rula niciodata (export2xlsx lasa pointerul pe EOF, iar SCAN WHILE
  are scope implicit REST) - GO TOP + SCAN, cu Exit la eroare
- candidatii se iau din cursoarele declaratiei, cu criteriile verificarii, nu dintr-un
  query separat pe balanta_parteneri

Verificare coduri fiscale (do_verifica_cui):
- acopera toti partenerii exportati in XML, nu doar cei cu is_activ = 1
- CodFiscalValidSaft: regulile de format ale validatorului ANAF (numai cifre, fara zero
  la inceput, 13 cifre la CNP, 2-10 la CUI) peste cifra de control; VALIDARE_CIF accepta
  litere la inceput si VALIDARE_CNP accepta prima cifra 0
- lista codurilor invalide in cursor + export xlsx (rand, partener, cod, CNP/CUI),
  mesaj cu defalcare CNP/CUI
- corectat "Variable 'LCTEXT' is not found" (m.lcText inexistent in procedura)

do_erori_partener_saft: extrage din fisierul de raspuns al validatorului codurile de
partener respinse (pagina Customers/Suppliers, randul, codul, partenerul) si le afiseaza
la finalul validarii, cu export xlsx optional.

changelog 2.11.65

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013dL9LNnmeY8nELjTLYiGJH
This commit is contained in:
2026-07-26 18:22:38 +03:00
parent 22ea278001
commit a284dd3530
2 changed files with 277 additions and 39 deletions

View File

@@ -256,7 +256,7 @@ Define Class d406 As Custom
Local lcAssetTransactions, lcAssets, lcCaleFisier, lcComunPath, lcConfigDir, lcFileName Local lcAssetTransactions, lcAssets, lcCaleFisier, lcComunPath, lcConfigDir, lcFileName
Local lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock Local lcFisierRaspuns, lcMovementofGoods, lcNumeFisier, lcOwners, lcParams, lcPhysicalStock
Local lcProducts, lcUOMTable, lcValidator, lcXMLTemp, lnFileHandle, lnSec, lcSufixCale, lcSufixFisier Local lcProducts, lcUOMTable, lcValidator, lcXMLTemp, lnFileHandle, lnSec, lcSufixCale, lcSufixFisier
LOCAL lcMessage, loChatBot LOCAL lcMessage, loChatBot, lcMesajErori
LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2 LOCAL lnAn1, lnAn2, lnLuna1, lnLuna2
lnAn1 = This.oUnitate.an1 lnAn1 = This.oUnitate.an1
@@ -556,6 +556,14 @@ Define Class d406 As Custom
OPEN_DEFAULT_APP(m.lcValidator, m.lcParams) OPEN_DEFAULT_APP(m.lcValidator, m.lcParams)
ELSE 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'))
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 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) lcMessage = FILETOSTR(m.lcFisierRaspuns)
loChatBot = CREATEOBJECT("oChatBotLaunch", m.lcMessage) loChatBot = CREATEOBJECT("oChatBotLaunch", m.lcMessage)
@@ -918,7 +926,8 @@ select 1 as tip,
#Define CRLF Chr(13) + Chr(10) #Define CRLF Chr(13) + Chr(10)
LOCAL llSilent, lcMesaj, lcListaGol LOCAL llSilent, lcMesaj, lcListaGol
LOCAL lcCod, lcListaInvalid, lcTextInvalid, llCnp, lnInvalid, loVerif LOCAL lcCod, lcListaInvalid, lcTextInvalid, llCnp, lnInvalid, lnInvalidCnp, loVerif
LOCAL lcContInv, lcDenumireInv, lnIdPartInv, lnRandInv, lnTipPersInv
lcMesaj = '' lcMesaj = ''
lcTextInvalid = '' lcTextInvalid = ''
@@ -1031,25 +1040,44 @@ and b1.cont = b2.cont
ENDSCAN ENDSCAN
GO TOP GO TOP
*!* 24.07.2026 verific validitatea codurilor fiscale (CNP/CUI) la partenerii cu activitate in perioada *!* 24.07.2026 verific validitatea codurilor fiscale (CNP/CUI) la toti partenerii exportati in declaratie (nu doar cei activi in perioada)
lcListaInvalid = '' lcListaInvalid = ''
lnInvalid = 0 lnInvalid = 0
lnInvalidCnp = 0
loVerif = CREATEOBJECT('VerificareCod') loVerif = CREATEOBJECT('VerificareCod')
SCAN FOR !EMPTY(NVL(id_part,0)) AND !EMPTY(NVL(cod_fiscal, '')) AND NVL(is_activ, 0) = 1 ; *!* 26.07.2026 retin codurile invalide intr-un cursor, ca sa poata fi exportate si corectate in nomenclator
CREATE CURSOR cCodInvalid (rand N(7), id_part N(10), denumire C(150), cod_fiscal C(30), tip_cod C(3), tip_persoana N(1), cont C(10))
SELECT (m.lcCursor)
SCAN FOR !EMPTY(NVL(id_part,0)) AND !EMPTY(NVL(cod_fiscal, '')) ;
AND INLIST(ALLTRIM(NVL(cod_tara, 'RO')), 'RO', '') AND INLIST(ALLTRIM(NVL(cod_tara, 'RO')), 'RO', '')
lcCod = ALLTRIM(cod_fiscal) lcCod = ALLTRIM(cod_fiscal)
llCnp = (NVL(tip_persoana, 1) = 2) OR (LEN(CHRTRAN(m.lcCod, '0123456789', '')) = 0 AND LEN(m.lcCod) > 10) llCnp = (NVL(tip_persoana, 1) = 2) OR (LEN(CHRTRAN(m.lcCod, '0123456789', '')) = 0 AND LEN(m.lcCod) > 10)
IF !IIF(m.llCnp, VALIDARE_CNP(m.lcCod, m.loVerif), VALIDARE_CIF(m.lcCod, m.loVerif)) IF !This.CodFiscalValidSaft(m.lcCod, m.llCnp, m.loVerif)
lnInvalid = m.lnInvalid + 1 lnInvalid = m.lnInvalid + 1
lnInvalidCnp = m.lnInvalidCnp + IIF(m.llCnp, 1, 0)
lcListaInvalid = m.lcListaInvalid + IIF(EMPTY(m.lcListaInvalid), '', ', ') + ALLTRIM(STR(RECNO())) lcListaInvalid = m.lcListaInvalid + IIF(EMPTY(m.lcListaInvalid), '', ', ') + ALLTRIM(STR(RECNO()))
lnRandInv = RECNO()
lnIdPartInv = id_part
lcDenumireInv = NVL(denumire, '')
lnTipPersInv = NVL(tip_persoana, 1)
lcContInv = NVL(cont, '')
INSERT INTO cCodInvalid (rand, id_part, denumire, cod_fiscal, tip_cod, tip_persoana, cont) ;
VALUES (m.lnRandInv, m.lnIdPartInv, m.lcDenumireInv, m.lcCod, IIF(m.llCnp, 'CNP', 'CUI'), m.lnTipPersInv, m.lcContInv)
SELECT (m.lcCursor)
ENDIF ENDIF
ENDSCAN ENDSCAN
GO TOP GO TOP
loVerif = .NULL. loVerif = .NULL.
IF m.lnInvalid > 0 IF m.lnInvalid > 0
lcTextInvalid = CRLF + SPACE(10) + 'ATENTIE! Randuri cu cod fiscal invalid (' + ALLTRIM(STR(m.lnInvalid)) + '): ' + ALLTRIM(LEFT(m.lcListaInvalid, 50)) + ; lcTextInvalid = CRLF + SPACE(10) + 'ATENTIE! Randuri cu cod fiscal invalid (' + ALLTRIM(STR(m.lnInvalid)) + ;
': CNP ' + ALLTRIM(STR(m.lnInvalidCnp)) + ', CUI ' + ALLTRIM(STR(m.lnInvalid - m.lnInvalidCnp)) + '): ' + ALLTRIM(LEFT(m.lcListaInvalid, 50)) + ;
CRLF + SPACE(10) + IIF(m.llSilent, 'Lista completa: apasati butonul "Verificare coduri fiscale" de pe clienti/furnizori', 'Lista completa in fisierul Excel exportat') + ;
CRLF + SPACE(10) + 'Stergeti CNP-urile din "Initializari cod taxa/plata" > "Stergere CNP-uri invalide", restul se corecteaza in nomenclatorul de parteneri' CRLF + SPACE(10) + 'Stergeti CNP-urile din "Initializari cod taxa/plata" > "Stergere CNP-uri invalide", restul se corecteaza in nomenclatorul de parteneri'
IF !m.llSilent
goExport.export2xlsx('cCodInvalid', 'coduri_fiscale_invalide' + IIF(m.llClient, '_clienti_', '_furnizori_') + ALLTRIM(STR(m.gnAn)) + PADL(m.gnLuna,2,'0'))
SELECT (m.lcCursor)
ENDIF
ENDIF ENDIF
IF RECCOUNT('cPartDif') > 0 IF RECCOUNT('cPartDif') > 0
@@ -1067,13 +1095,14 @@ and b1.cont = b2.cont
lcMesaj ='Nu sunt diferente fata de balanta 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))) + m.lcTextInvalid 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))) + m.lcTextInvalid
IF !m.llSilent IF !m.llSilent
AMESSAGEBOX(lcMesaj + CHR(13) + CHR(10) + m.lcText,0+64,_screen.Caption) AMESSAGEBOX(m.lcMesaj,0+64,_screen.Caption)
ENDIF ENDIF
ENDIF ENDIF
ENDIF ENDIF
USE IN (SELECT('cBalPartTemp')) USE IN (SELECT('cBalPartTemp'))
USE IN (SELECT('cPartDif')) USE IN (SELECT('cPartDif'))
USE IN (SELECT('cCodInvalid'))
Else Else
llDontCloseCursor = .F. llDontCloseCursor = .F.
llExperimental = .F. llExperimental = .F.
@@ -1106,6 +1135,182 @@ and b1.cont = b2.cont
RETURN lcMesaj RETURN lcMesaj
ENDPROC && do_verifica_cui ENDPROC && do_verifica_cui
*************************************************
* Validare cod fiscal dupa regulile validatorului ANAF pentru RegistrationNumber/CustomerID
* tlCnp: .T. = cod de persoana fizica (CNP), .F. = cod de persoana juridica (CUI)
* toVerif: obiect VerificareCod, optional (ca sa nu se instantieze la fiecare cod)
*************************************************
PROCEDURE CodFiscalValidSaft
LPARAMETERS tcCod, tlCnp, toVerif
LOCAL lcCod
lcCod = ALLTRIM(UPPER(NVL(m.tcCod, '')))
*!* la persoana juridica GenCustSupCode scoate atributul fiscal din codul SAF-T, la persoana fizica nu
IF !m.tlCnp AND LEFT(m.lcCod, 2) = 'RO'
lcCod = ALLTRIM(SUBSTR(m.lcCod, 3))
ENDIF
*!* 26.07.2026 ANAF cere numai cifre, fara zero la inceput, exact 13 la CNP si maxim 10 la CUI - validarea cifrei de control nu prinde asta
IF !EMPTY(CHRTRAN(m.lcCod, '0123456789', '')) OR LEFT(m.lcCod, 1) = '0' OR ;
IIF(m.tlCnp, LEN(m.lcCod) <> 13, !BETWEEN(LEN(m.lcCod), 2, 10))
RETURN .F.
ENDIF
RETURN IIF(m.tlCnp, VALIDARE_CNP(m.lcCod, m.toVerif), VALIDARE_CIF(m.lcCod, m.toVerif))
ENDPROC && CodFiscalValidSaft
*************************************************
* Extrage din fisierul de raspuns al validatorului ANAF erorile de cod partener
* (RegistrationNumber/CustomerID/SupplierID) si le pune in cursorul cEroriPartSaft
* Intoarce textul de afisat, gol daca nu sunt astfel de erori
*************************************************
PROCEDURE do_erori_partener_saft
LPARAMETERS tcFisierRaspuns
LOCAL lcCod, lcCursor, lcDenumire, lcId, lcLinie, lcLocatie, lcMesaj, lcPagina, lcRest, lcSelect, lcTag, lcTipCod, lcTipPart
LOCAL lnFile, lnI, lnIdPart, lnJ, lnNrErori, lnParteneri, lnPoz, lnRand
lcMesaj = ''
lcSelect = Select()
IF !FILE(m.tcFisierRaspuns)
RETURN m.lcMesaj
ENDIF
*!* fiecare eroare are 2 linii: localizarea "E: MasterFiles (1) sectiune Customers (1) sectiune Customer (162) ..."
*!* si regula " eroare regula: CustomerID: Pentru CustomerID 00I14770212 formatul este invalid"
CREATE CURSOR cErrTemp (saftpartid C(30), pagina C(10), rand N(7))
lnFile = FOPEN(m.tcFisierRaspuns, 0)
IF m.lnFile < 0
USE IN (SELECT('cErrTemp'))
SELECT (m.lcSelect)
RETURN m.lcMesaj
ENDIF
lcLocatie = ''
DO WHILE !FEOF(m.lnFile)
lcLinie = FGETS(m.lnFile, 8192)
IF LEFT(LTRIM(m.lcLinie), 2) == 'E:'
lcLocatie = m.lcLinie
LOOP
ENDIF
lnPoz = ATC('Pentru ', m.lcLinie)
IF m.lnPoz = 0
LOOP
ENDIF
lcRest = ALLTRIM(SUBSTR(m.lcLinie, m.lnPoz + 7))
lcTag = GETWORDNUM(m.lcRest, 1)
IF !INLIST(m.lcTag, 'RegistrationNumber', 'CustomerID', 'SupplierID')
LOOP
ENDIF
lcId = GETWORDNUM(m.lcRest, 2)
IF EMPTY(m.lcId)
LOOP
ENDIF
*!* pagina si randul din grid = sectiunea si indexul partenerului din MasterFiles ("sectiune Customer (162)")
lcPagina = ''
lnRand = 0
lnPoz = ATC('sectiune Customer (', m.lcLocatie)
IF m.lnPoz > 0
lcPagina = 'Customers'
ELSE
lnPoz = ATC('sectiune Supplier (', m.lcLocatie)
IF m.lnPoz > 0
lcPagina = 'Suppliers'
ENDIF
ENDIF
IF m.lnPoz > 0
lnRand = INT(VAL(SUBSTR(m.lcLocatie, m.lnPoz + 19)))
ENDIF
INSERT INTO cErrTemp (saftpartid, pagina, rand) VALUES (m.lcId, m.lcPagina, m.lnRand)
ENDDO
= FCLOSE(m.lnFile)
* Un cod poate aparea pe mai multe randuri (parteneri diferiti cu acelasi cod) si in sectiunile de documente
SELECT saftpartid, COUNT(*) AS nr_erori, MAX(rand) AS max_rand FROM cErrTemp GROUP BY 1 INTO CURSOR cErrCod
SELECT DISTINCT saftpartid, pagina, rand FROM cErrTemp WHERE rand > 0 ORDER BY 2, 3 INTO CURSOR cErrGrup
USE IN (SELECT('cErrTemp'))
* Identific partenerul dupa codul SAF-T, in cursoarele declaratiei
CREATE CURSOR cEroriPartSaft (pagina C(10), rand N(7), saftpartid C(30), tip_cod C(3), id_part N(10), denumire C(150), cod_fiscal C(30), tip_part C(9), nr_erori N(6))
SELECT cErrGrup
SCAN
lcId = ALLTRIM(cErrGrup.saftpartid)
lcPagina = cErrGrup.pagina
lnRand = cErrGrup.rand
lnNrErori = 0
SELECT cErrCod
LOCATE FOR ALLTRIM(cErrCod.saftpartid) == m.lcId
IF FOUND()
lnNrErori = cErrCod.nr_erori
ENDIF
lcTipPart = ''
lnIdPart = 0
lcDenumire = ''
lcCod = ''
FOR lnJ = 1 TO 2
lcCursor = IIF(m.lnJ = 1, 'cCustomers', 'cSuppliers')
IF !USED(m.lcCursor)
LOOP
ENDIF
SELECT (m.lcCursor)
LOCATE FOR ALLTRIM(NVL(saftpartid, '')) == m.lcId
IF FOUND()
lcTipPart = IIF(m.lnJ = 1, 'Client', 'Furnizor')
lnIdPart = NVL(id_part, 0)
lcDenumire = NVL(denumire, '')
lcCod = ALLTRIM(NVL(cod_fiscal, ''))
ENDIF
GO TOP
IF !EMPTY(m.lcTipPart)
EXIT
ENDIF
ENDFOR
lcTipCod = IIF(LEFT(m.lcId, 2) = '03', 'CNP', IIF(INLIST(LEFT(m.lcId, 2), '00', '01', '02'), 'CUI', ''))
INSERT INTO cEroriPartSaft (pagina, rand, saftpartid, tip_cod, id_part, denumire, cod_fiscal, tip_part, nr_erori) ;
VALUES (m.lcPagina, m.lnRand, m.lcId, m.lcTipCod, m.lnIdPart, m.lcDenumire, m.lcCod, m.lcTipPart, m.lnNrErori)
SELECT cErrGrup
ENDSCAN
USE IN (SELECT('cErrGrup'))
* Codurile semnalate numai in sectiunile de documente, fara rand in Customers/Suppliers
SELECT cErrCod
SCAN FOR cErrCod.max_rand = 0
lcId = ALLTRIM(cErrCod.saftpartid)
lcTipCod = IIF(LEFT(m.lcId, 2) = '03', 'CNP', IIF(INLIST(LEFT(m.lcId, 2), '00', '01', '02'), 'CUI', ''))
INSERT INTO cEroriPartSaft (pagina, rand, saftpartid, tip_cod, nr_erori) ;
VALUES ('', 0, m.lcId, m.lcTipCod, cErrCod.nr_erori)
SELECT cErrCod
ENDSCAN
USE IN (SELECT('cErrCod'))
lnParteneri = RECCOUNT('cEroriPartSaft')
IF m.lnParteneri = 0
USE IN (SELECT('cEroriPartSaft'))
SELECT (m.lcSelect)
RETURN m.lcMesaj
ENDIF
lcMesaj = 'Coduri de partener respinse de validatorul ANAF: ' + ALLTRIM(STR(m.lnParteneri))
lnI = 0
SELECT cEroriPartSaft
SCAN
lnI = m.lnI + 1
IF m.lnI > 10
lcMesaj = m.lcMesaj + CHR(13) + CHR(10) + SPACE(3) + '...'
EXIT
ENDIF
lcMesaj = m.lcMesaj + CHR(13) + CHR(10) + SPACE(3) + PADR(ALLTRIM(cEroriPartSaft.pagina), 11) + ;
PADL(IIF(cEroriPartSaft.rand > 0, ALLTRIM(STR(cEroriPartSaft.rand)), '-'), 5) + SPACE(2) + ;
PADR(ALLTRIM(cEroriPartSaft.saftpartid), 18) + PADR(ALLTRIM(cEroriPartSaft.tip_cod), 4) + ALLTRIM(cEroriPartSaft.denumire)
ENDSCAN
GO TOP
SELECT (m.lcSelect)
RETURN m.lcMesaj
ENDPROC && do_erori_partener_saft
&& IAU SOLDURILE DIN BALANTA DE VERIFICARE PENTRU CONTURILE DE IMOBLIZARI SI AMORTIZARI && 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 && SI LE COMPAR CU VALOAREA DE INVENTAR SI AMORTIZAREA TOTALA DIN IMOBILIZARI CORPORALE/NECORPORALE CONTABIL
Procedure do_verifica_imobilizari Procedure do_verifica_imobilizari
@@ -2077,48 +2282,59 @@ select a.id_articol, a.denumire, SUM(r.cant) as cant, SUM(r.cante) as cante, SUM
ENDPROC && CompletareCodTaxaPlata ENDPROC && CompletareCodTaxaPlata
************************************* *************************************
* Stergere cod fiscal la persoanele cu CNP invalid, din partenerii cu rulaje in perioada declaratiei * Stergere cod fiscal la persoanele cu CNP invalid, din clientii/furnizorii declaratiei
* Aceleasi randuri pe care le semnaleaza verificarea codurilor fiscale (do_verifica_cui)
PROCEDURE StergereCnpInvalid PROCEDURE StergereCnpInvalid
Local lcCod, lcLista, lcMesaj, lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnNr, lnRand Local lcCod, lcCursor, lcLista, lcMesaj, lcSelect, lcSql, llCnp, llSucces, lnAn2, lnI, lnLuna2, lnNr, lnRand, loVerif
Local lcCodInv, lcDenumireInv, lnIdPartInv, lnTipPersInv
lcSelect = Select() lcSelect = Select()
lnAn1 = This.oUnitate.an1
lnLuna1 = This.oUnitate.luna1
lnAn2 = This.oUnitate.an2 lnAn2 = This.oUnitate.an2
lnLuna2 = This.oUnitate.luna2 lnLuna2 = This.oUnitate.luna2
* Candidati: cod fiscal numeric, persoana fizica sau cod mai lung de 10 cifre (nu poate fi CUI), cu rulaje in perioada If !Used('cCustomers') And !Used('cSuppliers')
Text To m.lcSql Noshow Textmerge Amessagebox('Apasati intai pe 1. Citeste date!', 0+64, _Screen.Caption)
select p.id_part, p.denumire, p.cod_fiscal, p.tip_persoana
from nom_parteneri p
where nvl(p.sters, 0) = 0
and regexp_like(trim(p.cod_fiscal), '^[0-9]+$')
and (p.tip_persoana = 2 or length(trim(p.cod_fiscal)) > 10)
and exists (select 1
from balanta_parteneri b
where b.id_part = p.id_part
and b.an * 12 + b.luna between <<m.lnAn1*12+m.lnLuna1>> and <<m.lnAn2*12+m.lnLuna2>>
and (nvl(b.debit, 0) <> 0 or nvl(b.credit, 0) <> 0)
and b.cont in ('4111','4118','461','418','419','401','404','462','408','409'))
order by p.denumire
Endtext
llSucces = goExecutor.oExecuta(m.lcSql, 'cCnpTemp')
If !m.llSucces
Select (m.lcSelect) Select (m.lcSelect)
Return .F. Return .F.
Endif Endif
* Retin doar codurile care nu trec de validarea CNP (lungime + cifra de control) *!* 26.07.2026 candidatii se iau din cursoarele declaratiei, cu aceleasi criterii ca verificarea codurilor fiscale
Select id_part, denumire, cod_fiscal, tip_persoana ; Create Cursor cCnpTemp (id_part N(10), denumire C(150), cod_fiscal C(30), tip_persoana N(1))
loVerif = Createobject('VerificareCod')
For lnI = 1 To 2
lcCursor = Iif(m.lnI = 1, 'cCustomers', 'cSuppliers')
If !Used(m.lcCursor)
Loop
Endif
Select (m.lcCursor)
Scan For !Empty(Nvl(id_part, 0)) And !Empty(Nvl(cod_fiscal, '')) ;
And Inlist(Alltrim(Nvl(cod_tara, 'RO')), 'RO', '')
lcCod = Alltrim(cod_fiscal)
llCnp = (Nvl(tip_persoana, 1) = 2) Or (Len(Chrtran(m.lcCod, '0123456789', '')) = 0 And Len(m.lcCod) > 10)
If m.llCnp And !This.CodFiscalValidSaft(m.lcCod, .T., m.loVerif)
lnIdPartInv = id_part
lcDenumireInv = Nvl(denumire, '')
lcCodInv = m.lcCod
lnTipPersInv = Nvl(tip_persoana, 1)
Insert Into cCnpTemp (id_part, denumire, cod_fiscal, tip_persoana) ;
Values (m.lnIdPartInv, m.lcDenumireInv, m.lcCodInv, m.lnTipPersInv)
Select (m.lcCursor)
Endif
Endscan
Go Top
Endfor
loVerif = .NULL.
* Un partener apare pe cate un rand pentru fiecare cont, deci elimin dublurile
Select Distinct id_part, denumire, cod_fiscal, tip_persoana ;
From cCnpTemp ; From cCnpTemp ;
Where !ValidCNP(Alltrim(Nvl(cod_fiscal, ''))) ; Order By denumire ;
Into Cursor cCnpInvalid Into Cursor cCnpInvalid
Use In (Select('cCnpTemp')) Use In (Select('cCnpTemp'))
lnNr = Reccount('cCnpInvalid') lnNr = Reccount('cCnpInvalid')
If m.lnNr = 0 If m.lnNr = 0
Amessagebox('Nu sunt parteneri cu CNP invalid in perioada declaratiei!', 0+64, _Screen.Caption) Amessagebox('Nu sunt parteneri cu CNP invalid in declaratie!', 0+64, _Screen.Caption)
Use In (Select('cCnpInvalid')) Use In (Select('cCnpInvalid'))
Select (m.lcSelect) Select (m.lcSelect)
Return .T. Return .T.
@@ -2126,7 +2342,7 @@ select p.id_part, p.denumire, p.cod_fiscal, p.tip_persoana
goExport.export2xlsx('cCnpInvalid', 'cnp_invalide_saft_' + Alltrim(Str(m.lnAn2)) + Padl(m.lnLuna2, 2, '0')) goExport.export2xlsx('cCnpInvalid', 'cnp_invalide_saft_' + Alltrim(Str(m.lnAn2)) + Padl(m.lnLuna2, 2, '0'))
lcMesaj = 'S-au gasit ' + Alltrim(Str(m.lnNr)) + ' parteneri cu CNP invalid in perioada declaratiei.' + Chr(13) + Chr(10) + ; lcMesaj = 'S-au gasit ' + Alltrim(Str(m.lnNr)) + ' parteneri cu CNP invalid in declaratie.' + Chr(13) + Chr(10) + ;
'Doriti stergerea codului fiscal eronat si trecerea lor pe persoana fizica?' + Chr(13) + Chr(10) + ; 'Doriti stergerea codului fiscal eronat si trecerea lor pe persoana fizica?' + Chr(13) + Chr(10) + ;
'(la SAF-T persoanele fizice nu sunt obligate sa aiba CNP)' '(la SAF-T persoanele fizice nu sunt obligate sa aiba CNP)'
If Amessagebox(m.lcMesaj, 4+32, _Screen.Caption) <> 6 If Amessagebox(m.lcMesaj, 4+32, _Screen.Caption) <> 6
@@ -2140,7 +2356,9 @@ select p.id_part, p.denumire, p.cod_fiscal, p.tip_persoana
lnRand = 0 lnRand = 0
llSucces = .T. llSucces = .T.
Select cCnpInvalid Select cCnpInvalid
Scan While m.llSucces *!* 26.07.2026 exportul lasa pointerul pe EOF, deci pozitionez pe primul rand inainte de parcurgere
Go Top
Scan
lcLista = m.lcLista + Iif(Empty(m.lcLista), '', ',') + Alltrim(Str(cCnpInvalid.id_part)) lcLista = m.lcLista + Iif(Empty(m.lcLista), '', ',') + Alltrim(Str(cCnpInvalid.id_part))
lnRand = m.lnRand + 1 lnRand = m.lnRand + 1
If m.lnRand = 1000 Or Recno() = m.lnNr If m.lnRand = 1000 Or Recno() = m.lnNr
@@ -2149,11 +2367,15 @@ select p.id_part, p.denumire, p.cod_fiscal, p.tip_persoana
lcLista = '' lcLista = ''
lnRand = 0 lnRand = 0
Endif Endif
If !m.llSucces
Exit
Endif
Endscan Endscan
If m.llSucces If m.llSucces
Amessagebox('Stergere efectuata cu succes!' + Chr(13) + Chr(10) + ; Amessagebox('Stergere efectuata cu succes (' + Alltrim(Str(m.lnNr)) + ' parteneri)!' + Chr(13) + Chr(10) + ;
'Apasati pe 1. Citeste date pentru a actualiza datele din declaratie', 0+64, _Screen.Caption) 'Apasati pe 1. Citeste date pentru a actualiza datele din declaratie' + Chr(13) + Chr(10) + ;
'(pana la re-citire, verificarile arata tot codurile vechi)', 0+64, _Screen.Caption)
Endif Endif
Use In (Select('cCnpInvalid')) Use In (Select('cCnpInvalid'))

View File

@@ -1,3 +1,19 @@
<!--
26/07/2026
ROACONT - 2.11.65
:nou:
D406 SAF-T > Initializari cod taxa/plata > "Stergere CNP-uri invalide". Se sterg CNP-urile invalide de pe partenerii din Romania din declaratie, tip persoana fizica sau cu coduri fiscale mai lungi de 10 cifre.
:nou:
D406 SAF-T. Daca validarea XML se termina cu erori, codurile de partener respinse de validatorul ANAF se afiseaza intr-un mesaj si se pot exporta in Excel.
:modificare:
D406 SAF-T. Verificare Solduri clienti/furnizori. Se verifica codurile fiscale pentru toti partenerii din declaratie si aplica regulile de format ale validatorului ANAF (numai cifre, fara zero la inceput, exact 13 cifre la CNP, maxim 10 la CUI), pe langa cifra de control.
Mesajul arata separat cate coduri sunt CNP si cate CUI, iar butonul "Verificare coduri fiscale" exporta lista completa in Excel, pentru corectarea lor in nomenclatorul de parteneri.
-->
<!-- <!--
24/07/2026 24/07/2026
ROACONT - 2.11.64 ROACONT - 2.11.64