From 22ea27800111ffe0489555940ec83858cc6dd535 Mon Sep 17 00:00:00 2001 From: Marius Mutu Date: Fri, 24 Jul 2026 22:20:10 +0300 Subject: [PATCH] D406 SAF-T: stergere CNP-uri invalide + verificare coduri fiscale - optiune noua in meniul "Initializari cod taxa/plata": "Stergere CNP-uri invalide la persoanele fizice din declaratie" -> StergereCnpInvalid() - StergereCnpInvalid(): selecteaza partenerii cu rulaje in perioada declaratiei si cod fiscal numeric (persoana fizica sau peste 10 cifre), filtreaza cu ValidCNP(), exporta lista in xlsx, cere confirmare si sterge codul fiscal eronat (tip_persoana = 2), in transe de 1000 de id_part - do_verifica_cui(): la butonul "2. Verifica" se valideaza si codurile fiscale ale partenerilor activi in perioada (CNP prin VALIDARE_CNP, CUI prin VALIDARE_CIF) si se completeaza mesajul cu numarul de randuri invalide si modul de corectare Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_016PUq4G8Yzfij6Dz5AuZGT2 --- Programe/saft_d406.prg | 137 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 12 deletions(-) diff --git a/Programe/saft_d406.prg b/Programe/saft_d406.prg index 341e654..7956cb6 100644 --- a/Programe/saft_d406.prg +++ b/Programe/saft_d406.prg @@ -918,8 +918,10 @@ select 1 as tip, #Define CRLF Chr(13) + Chr(10) LOCAL llSilent, lcMesaj, lcListaGol - + LOCAL lcCod, lcListaInvalid, lcTextInvalid, llCnp, lnInvalid, loVerif + lcMesaj = '' + lcTextInvalid = '' llSilent = m.tlSilent @@ -1026,15 +1028,36 @@ and b1.cont = b2.cont SCATTER NAME loRec lnRand = RECNO() lcListaGol = lcListaGol + IIF(!EMPTY(m.lcListaGol ), ', ', '') + ALLTRIM(STR(m.lnRand)) - ENDSCAN - GO TOP - + ENDSCAN + GO TOP + + *!* 24.07.2026 verific validitatea codurilor fiscale (CNP/CUI) la partenerii cu activitate in perioada + lcListaInvalid = '' + lnInvalid = 0 + loVerif = CREATEOBJECT('VerificareCod') + SCAN FOR !EMPTY(NVL(id_part,0)) AND !EMPTY(NVL(cod_fiscal, '')) AND NVL(is_activ, 0) = 1 ; + 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 !IIF(m.llCnp, VALIDARE_CNP(m.lcCod, m.loVerif), VALIDARE_CIF(m.lcCod, m.loVerif)) + lnInvalid = m.lnInvalid + 1 + lcListaInvalid = m.lcListaInvalid + IIF(EMPTY(m.lcListaInvalid), '', ', ') + ALLTRIM(STR(RECNO())) + ENDIF + ENDSCAN + GO TOP + loVerif = .NULL. + + IF m.lnInvalid > 0 + lcTextInvalid = CRLF + SPACE(10) + 'ATENTIE! Randuri cu cod fiscal invalid (' + ALLTRIM(STR(m.lnInvalid)) + '): ' + ALLTRIM(LEFT(m.lcListaInvalid, 50)) + ; + CRLF + SPACE(10) + 'Stergeti CNP-urile din "Initializari cod taxa/plata" > "Stergere CNP-uri invalide", restul se corecteaza in nomenclatorul de parteneri' + ENDIF + 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))) + 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 AMESSAGEBOX(lcMesaj,0+64, _screen.Caption) ENDIF @@ -1042,7 +1065,7 @@ and b1.cont = b2.cont 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))) + 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 AMESSAGEBOX(lcMesaj + CHR(13) + CHR(10) + m.lcText,0+64,_screen.Caption) ENDIF @@ -2013,7 +2036,7 @@ select a.id_articol, a.denumire, SUM(r.cant) as cant, SUM(r.cante) as cante, SUM *!* 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') + 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;Stergere CNP-uri invalide la persoanele fizice din declaratie') IF EMPTY(m.lnOptiune) RETURN ENDIF @@ -2035,9 +2058,14 @@ select a.id_articol, a.denumire, SUM(r.cant) as cant, SUM(r.cante) as cante, SUM 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 + lcSql = [begin PACK_SAFT.UpdateTipPersoanaFizica(); end;] + + *!* 24.07.2026 stergere CNP-uri invalide (persoane fizice) la partenerii cu rulaje in perioada declaratiei + CASE m.lnOptiune = 6 + This.StergereCnpInvalid() + RETURN + + ENDCASE IF AMESSAGEBOX(m.lcMesaj,4+32,_screen.Caption) = 6 llSucces = goExecutor.oExecuta(m.lcSql) @@ -2046,8 +2074,93 @@ select a.id_articol, a.denumire, SUM(r.cant) as cant, SUM(r.cante) as cante, SUM 'Apasati pe 1. Citeste date pentru a actualiza datele din declaratie',0+64,_screen.Caption) ENDIF ENDIF - ENDPROC && CompletareCodTaxaPlata - + ENDPROC && CompletareCodTaxaPlata + + ************************************* + * Stergere cod fiscal la persoanele cu CNP invalid, din partenerii cu rulaje in perioada declaratiei + PROCEDURE StergereCnpInvalid + Local lcCod, lcLista, lcMesaj, lcSelect, lcSql, llSucces, lnAn1, lnAn2, lnLuna1, lnLuna2, lnNr, lnRand + + lcSelect = Select() + lnAn1 = This.oUnitate.an1 + lnLuna1 = This.oUnitate.luna1 + lnAn2 = This.oUnitate.an2 + 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 + Text To m.lcSql Noshow Textmerge +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 <> and <> + 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) + Return .F. + Endif + + * Retin doar codurile care nu trec de validarea CNP (lungime + cifra de control) + Select id_part, denumire, cod_fiscal, tip_persoana ; + From cCnpTemp ; + Where !ValidCNP(Alltrim(Nvl(cod_fiscal, ''))) ; + Into Cursor cCnpInvalid + Use In (Select('cCnpTemp')) + + lnNr = Reccount('cCnpInvalid') + If m.lnNr = 0 + Amessagebox('Nu sunt parteneri cu CNP invalid in perioada declaratiei!', 0+64, _Screen.Caption) + Use In (Select('cCnpInvalid')) + Select (m.lcSelect) + Return .T. + Endif + + 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) + ; + '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)' + If Amessagebox(m.lcMesaj, 4+32, _Screen.Caption) <> 6 + Use In (Select('cCnpInvalid')) + Select (m.lcSelect) + Return .F. + Endif + + * Actualizez in transe de 1000 de coduri (limita listei IN din Oracle) + lcLista = '' + lnRand = 0 + llSucces = .T. + Select cCnpInvalid + Scan While m.llSucces + lcLista = m.lcLista + Iif(Empty(m.lcLista), '', ',') + Alltrim(Str(cCnpInvalid.id_part)) + lnRand = m.lnRand + 1 + If m.lnRand = 1000 Or Recno() = m.lnNr + lcSql = [update nom_parteneri set cod_fiscal = null, tip_persoana = 2 where id_part in (] + m.lcLista + [)] + llSucces = goExecutor.oExecuta(m.lcSql) + lcLista = '' + lnRand = 0 + Endif + Endscan + + If m.llSucces + Amessagebox('Stergere efectuata cu succes!' + Chr(13) + Chr(10) + ; + 'Apasati pe 1. Citeste date pentru a actualiza datele din declaratie', 0+64, _Screen.Caption) + Endif + + Use In (Select('cCnpInvalid')) + Select (m.lcSelect) + Return m.llSucces + ENDPROC && StergereCnpInvalid + *********************************** * Creare cusoare din baza de date Function CitesteDate