Fichier INSTAT XML de l'état récapitulatif TVA
Fichier INSTAT XML de l'état récapitulatif TVA
Le module erpnext/regional/france/intra_eu/instat_xml.py écrit le fichier XML INSTAT des déclarations de biens intra-UE, au format DEBWEB2 DTI+ défini par le manuel XML de la DGDDI (version 1.3.9 du 24/02/2022).
Le module écrit seulement l'état récapitulatif TVA : declarationTypeCode 4, flowCode D (sorties), régimes 21, 25 et 26. L'EMEBI (types 1 et 5, flux A) n'est pas encore pris en charge : toute autre combinaison type/flux est refusée. L'enveloppe, l'écriture générique des items (add_group) et l'ordre complet des enfants d'Item (ITEM_ORDER) servent déjà à ce format.
Le module est pur : il ne lit ni n'écrit la base de données. Chaque fichier est validé contre le schéma XSD officiel et contre les règles du manuel que le XSD ne peut pas exprimer ; tout écart lève une frappe.ValidationError.
Pour déclarer depuis Dokos, suivez la page utilisateur Déclarations intra-UE.
Format du fichier
- Déclaration XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>, encodage UTF-8. - Indentation de 2 espaces, fins de ligne LF, un retour à la ligne final.
- Fichier déterministe : la date et l'heure d'écriture (
DateTime) sont passées en paramètre (created_at), jamais prises sur l'horloge système. - Un fichier contient une seule
Declaration(un mois, un flux, un type), qui contient au moins unItem. functionCodevautO(la douane n'accepte que les déclarations originales) etcurrencyCodevautEUR.
Exemple (état récapitulatif TVA, flux D) :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<INSTAT>
<Envelope>
<envelopeId>A1B2</envelopeId>
<DateTime>
<date>2026-04-08</date>
<time>10:30:00</time>
</DateTime>
<Party partyType="PSI" partyRole="sender">
<partyId>FR4012345682400017</partyId>
<partyName>Atelier Durand</partyName>
</Party>
<softwareUsed>Dokos</softwareUsed>
<Declaration>
<declarationId>260303</declarationId>
<referencePeriod>2026-03</referencePeriod>
<PSIId>FR4012345682400017</PSIId>
<Function>
<functionCode>O</functionCode>
</Function>
<declarationTypeCode>4</declarationTypeCode>
<flowCode>D</flowCode>
<currencyCode>EUR</currencyCode>
<Item>
<itemNumber>1</itemNumber>
<invoicedAmount>2340</invoicedAmount>
<partnerId>BE0123456749</partnerId>
<statisticalProcedureCode>21</statisticalProcedureCode>
</Item>
<Item>
<itemNumber>2</itemNumber>
<invoicedAmount>15000</invoicedAmount>
<partnerId>DE123456789</partnerId>
<statisticalProcedureCode>21</statisticalProcedureCode>
</Item>
<Item>
<itemNumber>3</itemNumber>
<invoicedAmount>120</invoicedAmount>
<partnerId>DE123456789</partnerId>
<statisticalProcedureCode>25</statisticalProcedureCode>
</Item>
</Declaration>
</Envelope>
</INSTAT>
API
build_instat_file(envelope, declaration, items, created_at=None)
Signature : build_instat_file(envelope: dict, declaration: dict, items: list[dict], created_at: datetime | None = None) -> bytes.
Construit le fichier d'une déclaration, le valide, et le retourne en bytes.
envelope (l'enveloppe) :
| Clé | Obligatoire | Description |
|---|---|---|
envelope_id | oui | Numéro d'habilitation (envelopeId). |
party_id | oui | Numéro de TVA FR du déclarant (partyId). |
party_name | oui | Nom déclaré (partyName). |
party_type | non | PSI (déclarant, défaut) ou TDP (tiers déclarant). |
party_role | non | sender (défaut). |
software_used | non | Logiciel auteur (softwareUsed), Dokos par défaut. |
declaration :
| Clé | Obligatoire | Description |
|---|---|---|
declaration_id | oui | Identifiant de déclaration (declarationId). |
reference_period | oui | Période de référence AAAA-MM. |
psi_id | oui | Numéro de TVA FR du redevable (PSIId). |
type_code | oui | Type de déclaration : 4 (état récapitulatif TVA) uniquement. |
flow_code | oui | Flux : D (sorties) uniquement. |
function_code | non | O (défaut). |
currency_code | non | EUR (défaut). |
items : liste de dictionnaires produits par ertva_item, écrits dans l'ordre donné.
created_at : datetime écrit dans DateTime ; l'heure actuelle est utilisée par défaut.
ertva_item(line)
Transforme une ligne d'état récapitulatif TVA (issue de l'agrégation des déclarations) en item INSTAT :
| Élément XML | Clé de la ligne |
|---|---|
itemNumber | line_number |
invoicedAmount | value |
partnerId | partner_vat |
statisticalProcedureCode | regime |
declaration_id(year, month, kind, flow)
Retourne l'identifiant YYMM suivi du suffixe 03 pour l'état récapitulatif TVA en sorties. Le suffixe est une proposition : la douane exige seulement un numéro unique par période, numéro de TVA et flux. Lève une frappe.ValidationError pour toute autre nature ou tout autre flux.
instat_file_name(psi_id, year, month, kind, flow)
Retourne le nom de fichier ERTVA_<PSIId>_<AAAA-MM>_D.xml. La douane ne publie aucune règle de nommage.
validate_instat_file(content)
Valide un fichier (bytes) contre codes/instat.xsd, puis contre les règles du manuel que le schéma ne peut pas exprimer. Lève une frappe.ValidationError en cas d'écart. Le schéma est mis en cache par get_instat_schema().
Règles de validation
Le XSD officiel type presque toutes les valeurs comme des chaînes ; les règles suivantes sont vérifiées en complément, après validation XSD :
| Élément | Règle |
|---|---|
envelopeId | 1 à 4 lettres ou chiffres. |
partyId, PSIId | FR, puis la clé TVA (2 caractères), le SIREN (9) et le NIC du SIRET (5), en majuscules. |
partyName | 1 à 14 caractères. |
softwareUsed | s'il est présent, 1 à 14 caractères. |
declarationId | 6 chiffres. |
referencePeriod | AAAA-MM. |
Function/functionCode | O uniquement. |
declarationTypeCode | 4 uniquement (état récapitulatif TVA). |
flowCode | D uniquement (sorties). |
currencyCode | EUR uniquement. |
| Numérotation des items | itemNumber égal à la position, à partir de 1, sans trou. |
invoicedAmount | nombre entier d'euros, de 1 à 99 999 999 999. |
statisticalProcedureCode | régime autorisé pour le type et le flux (21, 25 et 26 pour l'état récapitulatif TVA en sorties). |
| Item de type 4 | seuls itemNumber, invoicedAmount, partnerId et statisticalProcedureCode ; partnerId obligatoire. |
| Nombre d'items | 999 999 maximum. |
L'élément Party porte les attributs partyType (PSI ou TDP) et partyRole (sender).
Schéma officiel
erpnext/regional/france/intra_eu/codes/instat.xsd est la copie conforme du XSD publié par la DGDDI avec le manuel DEBWEB2 DTI+ XML (version 1.3.9 du 24/02/2022), y compris son BOM UTF-8. Ne le modifiez pas et ne le reformatez pas : le test test_the_official_schema_is_unchanged compare son SHA-256 (3a1caf25b80e515a2daa73eb8eeac1076a889a0ff67f85549fd9964d010f480d, 5360 octets) avec la valeur enregistrée dans codes/README.md. Pour le mettre à jour, téléchargez le nouveau fichier officiel, remplacez la copie et mettez à jour la source, la date, la taille et le SHA-256 dans ce README.
Constantes
TYPE_CODES:{DECLARATION_ERTVA: "4"}— seul l'état récapitulatif TVA est écrivable.FLOW_CODES:{FLOW_DISPATCH: "D"}— seules les sorties sont écrivables.FILE_PREFIXES:{DECLARATION_ERTVA: "ERTVA"}.FUNCTION_ORIGINAL = "O",CURRENCY = "EUR",SOFTWARE = "Dokos".MAX_ITEMS = 999999,MAX_AMOUNT = 99999999999.ITEM_ORDER: ordre des enfants deItemselon le XSD, utilisé aussi pour les items de l'EMEBI.ERTVA_ITEM_TAGS: les quatre éléments autorisés dans un item d'état récapitulatif TVA.
Tests
erpnext/regional/france/tests/test_intra_eu_instat_xml.py couvre le writer sans base de données, avec le fichier de référence erpnext/regional/france/tests/data/instat_ertva_dispatch.xml : en-tête et déterminisme, tiers déclarant, identifiant et nom de fichier, refus des données invalides (montants, régimes, identifiants, périodes, codes), unicité du type 4 / flux D, structure des items et intégrité du schéma.
Limites connues
- Seul l'état récapitulatif TVA (type 4, flux D) est écrit . L'EMEBI (types 1 et 5, flux A) n'est pas pris en charge.
- Le
statisticalProcedureCodeest déduit du tableau « non nécessaire pour une déclaration de TVA » du manuel de fichier plat ; cette correspondance n'est pas vérifiée. - Le suffixe
03de l'identifiant de déclaration et le gabarit de nom de fichier sont des propositions, sans règle douanière établie.