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:
-
In
SourceDocuments, o sectiune prezenta trebuie sa aiba continut. Luna fara cumparari nu are delocPurchaseInvoices, nu una goala. La fel pentruSalesInvoicessiPayments. -
In
MasterFiles, invers:UOMTable,AnalysisTypeTable,MovementTypeTable,Products,OwnerssiAssetstrebuie sa existe, si pot fi goale. -
MovementOfGoodse cazul aparte: trebuie sa existe, dar complet goala. Pusa cu contoarele pe zero, validatorul raspunde caNumberOfMovementLines„a depasit numarul maxim de aparitii (0)".
„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.
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.