SAF-T · 4 septembrie 2026

D406: erorile validatorului ANAF si ce inseamna fiecare

Notele de mai jos nu sunt scoase din documentatie. Sunt greselile pe care le-am facut construind generatorul de D406 din Socotila, in ordinea in care ni le-a aratat DUKIntegrator, si ce a fost nevoie sa schimbam ca sa treaca.

Schema SAF-T are peste 500 de campuri, iar documentatia oficiala nu spune tot. Validatorul ANAF, in schimb, spune exact ce nu-i place — daca stii sa-l citesti. Fiecare mesaj de mai jos e copiat din fisierul de erori.

„namespace lipsa sau incorect la sectiunea AuditFile"

eroare structura: namespace ('mfp:anaf:dgti:d406t:declaratie:v1') lipsa sau incorect la sectiunea AuditFile. Valoarea corecta este xmlns='mfp:anaf:dgti:d406:declaratie:v1'

Capcana cea mai devreme si cea mai suparatoare. Schema oficiala schema.xsd are targetNamespace="mfp:anaf:dgti:d406t:declaratie:v1", cu „t". Daca iei valoarea de acolo, fisierul e respins din prima.

Acel „t" e prefixul intern al schemei. Fisierul depus poarta namespace-ul fara „t":

<AuditFile xmlns="mfp:anaf:dgti:d406:declaratie:v1">

„elementul 'Journal' ar fi trebuit sa apara de minimum 1 ori"

Inseamna ca ai generat o luna in care nu exista nicio nota contabila. O luna fara inregistrari nu se poate depune: validatorul cere cel putin un jurnal in GeneralLedgerEntries, iar un jurnal cere cel putin o tranzactie. Soldurile reportate singure nu-i ajung.

Daca firma chiar n-a avut activitate, tot trebuie sa existe ceva — inregistrarile de inchidere, de exemplu. Verifica intai ca ai ales luna buna: e usor sa nimeresti luna curenta, care de obicei e goala.

Sectiuni care trebuie sa lipseasca, nu sa fie goale

F: SourceDocuments (1) sectiune PurchaseInvoices (1)
eroare structura: elementul ''lipsa'' ar fi trebuit sa apara de minimum 1 ori, dar apare efectiv de 0 ori

Aici regula e pe dos fata de cum te-ai astepta, si difera de la o sectiune la alta:

„elementul 'BaseRate' ar fi trebuit sa apara de minimum 1 ori"

In TaxCodeDetails, BaseRate e obligatoriu si se scrie ca fractie, nu ca procent. Deducere integrala inseamna:

<BaseRate>1.0000</BaseRate>

Nomenclatorul spune pe alocuri „standard este de 100", ceea ce induce in eroare. Schema limiteaza campul la 5 cifre cu 4 zecimale, deci 100 nici n-ar incapea.

„RegistrationNumber: formatul este invalid. Codul nu este numeric"

In antet, la Company, RegistrationNumber este codul fiscal, nu numarul de la registrul comertului. Un J23/1000/2020 pus acolo e respins. Se accepta cifrele, eventual prefixate cu RO.

„Pentru RegistrationNumber 00XXXXXXXX formatul este invalid" — la un cod care arata normal

Cea mai inselatoare dintre toate. Mesajul arata asa:

E: MasterFiles (1) sectiune Suppliers (1) sectiune Supplier (11)
sectiune CompanyStructure (1) sectiune RegistrationNumber (1)
  eroare regula: RegistrationNumber: Pentru RegistrationNumber
  0011111111 formatul este invalid

Primul gand e ca zerourile din fata sunt de vina si ca trebuie scoase. Nu sunt, si nu trebuie. Am incercat: o luna care dadea sase erori a dat o suta optzeci si doua dupa ce am scos prefixul. Cele doua cifre sunt tipul partenerului, cerut de schema, si fara ele pica toti partenerii, nu doar cei trei.

Cauza adevarata e cifra de control. ANAF nu se uita doar la forma codului: i-o si socoteste, dupa cheia 753217532. Un cod caruia ii lipseste o cifra, sau la care doua sunt schimbate intre ele, arata perfect normal si e respins — iar mesajul spune „format invalid", niciodata „cifra de control".

Se recunoaste usor: ia codurile semnalate si treci-le prin formula oficiala. La noi, din cincizeci si opt de parteneri cu cod fiscal, exact trei aveau cifra de control gresita — si exact acelea erau cele semnalate. Celelalte, tot de opt cifre si tot cu 00 in fata, treceau.

CustomerID si SupplierID nu pot fi ambele „0"

Ambele sunt obligatorii pe fiecare tranzactie si pe fiecare linie, iar regula spune ca nu pot fi zero in acelasi timp. Problema apare la notele care n-au partener: salarii, amortizare, inchidere de luna.

Codurile se formeaza cu doua cifre de tip in fata: 00 plus CUI pentru firme romanesti, 03 plus CNP pentru persoane fizice, 01 plus tara si codul de TVA pentru firme din Uniune. Atentie, la tipul 00 nu se pune atributul „RO".

Pentru persoanele fizice care nu-si declara CNP-ul — clientul care cumpara o poarta si nu-ti da nimic — ANAF prevede tipul 04, urmat de un cod de client atribuit de tine. Nu e o carpeala: e scris in nomenclator. Noi folosim contul analitic, care e oricum unic.

Conturile se scriu ca numere intregi

Regula pentru AccountID spune „contul trebuie sa fie un numar intreg diferit de 0". Analiticul 401.00004 devine 40100004, iar sinteticul intra separat, in StandardAccountID.

Notele care n-au legatura cu taxele

TaxInformation e obligatoriu pe fiecare linie contabila, chiar si acolo unde nu e vorba de nicio taxa. Pentru acele linii se raporteaza:

<TaxType>000</TaxType>
<TaxCode>000000</TaxCode>

Regula e scrisa chiar in nomenclatorul ANAF, la campul S.TI.1.

Doua lucruri despre validatorul insusi

SAF-T are kitul lui. DUKIntegrator-ul cu care validezi declaratia 112 nu stie de D406 si raspunde cu cod eroare=-5. Iti trebuie arhiva duk_SAFT_an_luna, separata, de pe portalul ANAF.

Perioada se da in linia de comanda, nu se deduce din fisier:

java -jar DUKIntegrator.jar -v D406 fisier.xml "!erori.txt" $ an=2026 luna=7

Si inca ceva: D406 nu are PDF. Se depune chiar XML-ul. Cerut cu -p, validatorul raspunde „fisier zip specificat dar nepermis in acest document". Se cheama cu -v.

Arhiva ANAF vine cu Java in ea, in dist/jre8, deci validarea merge si pe un calculator fara Java instalat.

Trimestriala are alt namespace decat lunara

Nu scrie in documentatie. Fisierul trimestrial validat cu D406T raspunde:

eroare structura: namespace ('mfp:anaf:dgti:d406:declaratie:v1') lipsa sau incorect la sectiunea AuditFile. Valoarea corecta este xmlns='mfp:anaf:dgti:d406t:declaratie:v1'

Deci: d406 pentru lunara, d406t pentru trimestriala. Si kitul are doua validatoare, D406 si D406T — trimis codul gresit, raspunde ca declaratia nu e cea asteptata, si se cauta in fisier.

Inca ceva, care trece de validare si tot e gresit: fiecare Transaction isi poarta propria luna in Period. Intr-un trimestru sunt trei. Scrise toate cu luna dintai, fisierul e valid si datele sunt mutate.

Tipul declaratiei

Se pune in HeaderComment, unde nu te-ai astepta: L lunara, T trimestriala, A anuala, C la cerere.

De ce scriem astea. Le-am platit noi, ca sa treaca D406 din Socotila validarea pe cinci luni de date reale. Daca iti sunt de folos si nu vinzi programe de contabilitate, ia-le si foloseste-le. Daca vinzi, tot ia-le: obligatia e a tuturor si nu se rezolva cu nimeni pe dinafara.

Programul care le face pe toate astea

Socotila genereaza D406 lunara si o trece prin acelasi validator, dintr-un buton. Spune dinainte ce lipseste — parteneri fara cod fiscal, luna fara inregistrari — in loc sa te lase sa apesi si sa primesti eroarea de la ANAF.

Incearca 30 de zile