Verificare ANAF la alegerea partenerului
ocautare.prg - miezul functionalitatii: - anaf_verif_cautare: verdictul ANAF pe randul curent din formularul de cautare (label sub grid), la data documentului; discordantele si codurile fiscale invalide cu rosu; F4 sau click deschide detaliile. - ANAF_StarePartener, cu cache pe sesiune, excludere parteneri externi si persoane fizice; ANAF_ValidareCod pentru CIF/CNP. - ANAF_NivelVerificare: cascada RC_ANAF_VERIF_SELECTIE (kill-switch settings.ini > optiuni utilizator > optiuni firma > implicit 1), cu cache invalidat la schimbarea firmei sau utilizatorului; ANAF_ComutaVerificare pentru punctul de meniu. - Detalii: alegerea variantei corecte de partener din perechea RO / fara RO, cu discriminator "are documente in perioada"; dupa Da sau Nu se inchide cautarea si se revine in formular cu partenerul ales (AplicaInlocuirePartenerANAF). - ANAF_CaData: data documentului poate veni si ca DateTime (tact.dataact). - Banda proprie sub grid pentru label: formularul creste cu 54, gridul isi pierde ancorarea de jos si primeste inaltimea din AjusteazaBanda, legata de Resize si Activate - formularul isi reaseaza gridul dupa Show, deci Activate e momentul util. validare.prg: ANAF_VerificaCuiSingle, wrapper single-CUI peste serviciul ANAF, cu data verificarii si o singura eroare logata pe sesiune. cauta_alfa.prg: hook generic - ataseaza poVerifAlegere pe formularul de cautare inainte de Show si il detaseaza dupa. Apelanti opt-in (lVerificaANAF): baza.vc2 (lookup-ul generic de partener din formularele actbaza/actbaza2007 lansate din meniuri), onote_contabile.vc2 (partener debit/credit), omodificari.vc2 (do_cauta din cele trei clase de modificare, cu data notei), ofacturare.vc2 (client, furnizor). Casa/banca ramane in afara: acolo partenerul se alege pentru imperecherea facturilor. cauta_alfa_forms.vc2: F4 deschide detaliile, iar terminarea cautarii trece prin VerificaAlegere. Teste: suita headless pentru fluxul de verificare (utile/Teste/partener_anaf/), cu mock pentru apelul ANAF si pentru dialoguri. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019H3r66sVojGhgaKq5niu1u
This commit is contained in:
@@ -55,6 +55,10 @@
|
||||
*!* marius.mutu
|
||||
*!* ANAF_SincronWebService_PlatitorTva api v9
|
||||
|
||||
*!* 25.07.2026
|
||||
*!* marius.mutu
|
||||
*!* NormalizeazaCUI + ANAF_VerificaCuiSingle (verificare la alegerea partenerului, la data documentului)
|
||||
|
||||
*!* http://ec.europa.eu/taxation_customs/vies/viesquer.do
|
||||
*!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CIF/1879855/MFIN
|
||||
*!* http://localhost/contafinupdate/verificarecod.aspx/verificarecod/verificare/CNP/1810228134187
|
||||
@@ -1546,6 +1550,123 @@ Define Class VerificareCod As Custom
|
||||
Endfunc && GetEmptyMfinObj
|
||||
Enddefine
|
||||
|
||||
*************************************
|
||||
*** Normalizeaza un cod fiscal: UPPER, fara spatii, fara prefixul RO daca restul e numeric
|
||||
*************************************
|
||||
Function NormalizeazaCUI
|
||||
Lparameters tcCui
|
||||
|
||||
Local lcCui, lcRest, lnI, llNumeric
|
||||
lcCui = Upper(Strtran(Alltrim(Nvl(m.tcCui, '')), ' ', ''))
|
||||
If Left(m.lcCui, 2) = 'RO'
|
||||
lcRest = Substr(m.lcCui, 3)
|
||||
llNumeric = !Empty(m.lcRest)
|
||||
For lnI = 1 To Len(m.lcRest)
|
||||
If !Isdigit(Substr(m.lcRest, lnI, 1))
|
||||
llNumeric = .F.
|
||||
Exit
|
||||
Endif
|
||||
Endfor
|
||||
If m.llNumeric
|
||||
lcCui = m.lcRest
|
||||
Endif
|
||||
Endif
|
||||
|
||||
Return m.lcCui
|
||||
Endfunc && NormalizeazaCUI
|
||||
|
||||
*************************************
|
||||
*** Wrapper single-CUI peste VerificareANAF: tdData = data documentului (lipsa -> data curenta), degradare tacuta (.NULL.)
|
||||
*************************************
|
||||
Function ANAF_VerificaCuiSingle
|
||||
Lparameters tcCui, tdData
|
||||
|
||||
Local lcCuiNormalizat, loHTTP, loEx As Exception, loResult, lcServer, lcSend, lcJsonString, lcDataFormatted, ldData
|
||||
Local loVerificareANAF As "VerificareANAF", loCol As "empty", laCoduri[1], lcAliasTemp, lnReccountTemp, lnI, llValid
|
||||
|
||||
If Type('gvANAF_EroareLogataSesiune') = 'U'
|
||||
Public gvANAF_EroareLogataSesiune
|
||||
gvANAF_EroareLogataSesiune = .F.
|
||||
Endif
|
||||
|
||||
lcCuiNormalizat = NormalizeazaCUI(m.tcCui)
|
||||
llValid = !Empty(m.lcCuiNormalizat)
|
||||
If m.llValid
|
||||
For lnI = 1 To Len(m.lcCuiNormalizat)
|
||||
If !Isdigit(Substr(m.lcCuiNormalizat, lnI, 1))
|
||||
llValid = .F.
|
||||
Exit
|
||||
Endif
|
||||
Endfor
|
||||
Endif
|
||||
If !m.llValid
|
||||
Return .Null.
|
||||
Endif
|
||||
|
||||
loResult = .Null.
|
||||
lcAliasTemp = "crsANAFSingleTemp"
|
||||
|
||||
Try
|
||||
loVerificareANAF = Createobject("VerificareANAF") && incarca nfjsonread/nfjsoncreate (Init)
|
||||
|
||||
Try
|
||||
loHTTP = Createobject('winHTTP.winHTTPrequest.5.1')
|
||||
If Pemstatus(m.loHTTP, 'SetTimeouts', 5)
|
||||
loHTTP.SetTimeouts(3000, 3000, 5000, 5000) && rezolvare/conectare 3s, trimitere/primire 5s - de revizuit dupa masuratori (Tema)
|
||||
Endif
|
||||
Catch To loEx
|
||||
loHTTP = Createobject('Microsoft.XMLHTTP')
|
||||
Endtry
|
||||
|
||||
ldData = Iif(Vartype(m.tdData) = 'D' And !Empty(m.tdData), m.tdData, Date())
|
||||
lcDataFormatted = Left(Dtos(m.ldData), 4) + "-" + Substr(Dtos(m.ldData), 5, 2) + "-" + Substr(Dtos(m.ldData), 7, 2)
|
||||
|
||||
loCol = Createobject("empty")
|
||||
Addproperty(loCol, "cui", Int(Val(m.lcCuiNormalizat)))
|
||||
Addproperty(loCol, "data", m.lcDataFormatted)
|
||||
laCoduri[1] = loCol
|
||||
lcSend = nfjsoncreate(@laCoduri)
|
||||
|
||||
lcServer = 'https://webservicesp.anaf.ro/api/PlatitorTvaRest/v9/tva'
|
||||
|
||||
lcJsonString = ''
|
||||
loHTTP.Open('POST', lcServer, .F.)
|
||||
loHTTP.setRequestHeader("Content-Type", "application/json;")
|
||||
loHTTP.Send(lcSend)
|
||||
If loHTTP.Status = 200
|
||||
lcJsonString = Alltrim(loHTTP.responseText)
|
||||
Endif
|
||||
|
||||
If !Empty(m.lcJsonString) And Left(m.lcJsonString, 1) = '{'
|
||||
Use In (Select(m.lcAliasTemp))
|
||||
loVerificareANAF.ParseJsonANAFv8(nfjsonread(m.lcJsonString), m.lcAliasTemp)
|
||||
If Used(m.lcAliasTemp)
|
||||
Select (m.lcAliasTemp)
|
||||
lnReccountTemp = Reccount()
|
||||
If m.lnReccountTemp = 1 And !Empty(denumire)
|
||||
loResult = Createobject("empty")
|
||||
Addproperty(loResult, "cui", cui)
|
||||
Addproperty(loResult, "scpTVA", Nvl(scpTVA, .F.))
|
||||
Addproperty(loResult, "statusInactivi", Nvl(statusInactivi, .F.))
|
||||
Addproperty(loResult, "denumire", Nvl(denumire, ""))
|
||||
Addproperty(loResult, "mesaj", Nvl(mesaj, ""))
|
||||
Endif
|
||||
Use In (Select(m.lcAliasTemp))
|
||||
Endif
|
||||
Endif
|
||||
Catch To loEx
|
||||
If !gvANAF_EroareLogataSesiune
|
||||
If Type('goLog') = 'O'
|
||||
goLog.Log('ANAF_VerificaCuiSingle: ' + loEx.Message, 'ANAF_VerificaCuiSingle')
|
||||
Endif
|
||||
gvANAF_EroareLogataSesiune = .T.
|
||||
Endif
|
||||
loResult = .Null.
|
||||
Endtry
|
||||
|
||||
Return m.loResult
|
||||
Endfunc && ANAF_VerificaCuiSingle
|
||||
|
||||
*********************************************
|
||||
*** Verificare coduri fiscale folosind serviciul web ANAF, cate 500 de coduri per interogare
|
||||
*********************************************
|
||||
@@ -1717,7 +1838,6 @@ Define Class VerificareANAF As Custom
|
||||
goLog.Log('lcJsonString: ' + m.lcJsonString, 'ANAF_SincronWebService_PlatitorTva')
|
||||
|
||||
*
|
||||
SET STEP ON
|
||||
If Not Empty(m.lcJsonString)
|
||||
TRY
|
||||
loJsonObject = nfjsonread(m.lcJsonString) && nfJson from http://vfpx.codeplex.com/
|
||||
|
||||
Reference in New Issue
Block a user