Tooling for DAC7
Project description
DAC7 (France report for 2024 earnings)
[!CAUTION] All content shared in this repository is provided "as is" without any warranty of any kind from its authors. Users are responsible for verifying their own compliance with DAC7 obligations.
Quick-start
poetry install
# Build a XML declaration from dedicated JSON files
dac7 build -E PROD -f XML \
-p platform_operator.json \
-o other_platform_operators.json \
-e entity_sellers.json \
-i individual_sellers.json \
> declaration.xml
# Rename the file according to the specification
filename=$(dac7 name declaration.xml)
mv declaration.xml ${filename}
# Validate a XML declaration, both name and content
dac7 validate ${filename}
# Compress and encrypt. Require GnuPG to be installed
dac7 encrypt -z -E PROD ${filename} > ${filename}.gz.gpg
Contents of the repository
This repository is focused on the French version of DAC7, the requirements of which have been published by the Direction générale des Finances publiques, or DGFiP, on October 24, 2024 (cahier des charges v1.4, schema v1.1 :fr:). They differ from the original OECD standard on a couple of points that are small yet enough to break compatibility (see below).
[!NOTE] Please open an issue, or even better a PR, if you would like to extend this repository to cover other tax authorities.
This repository contains:
- a revised XSD schema based on one released by DGFiP, implementing additional checks
- a Python CLI to build an XML declaration and encrypt it according to the DGFiP requirements
Revised XML schema
The DGFiP specification :fr: is not compatible with the OECD standard v1 on at least the following points:
- The URIs for the XML namespaces
dpiandstfends with:v1in the OECD schema and not in the DGFiP schema - The DGFiP schema uses
TaxesQnelements instead of theTaxQnrequired by the OECD schema
For this reason, the French tax authority has provided its own XSD schema. Unfortunately, its version v1.1 :fr: does not implement all the requirements stated in the specification document :fr: released at the same time.
For this reason, we provide a revised version of the French schema in the schemas/xml folder that includes the following additional checks:
- The
versionattribute of the<dpi:DPI_OECD>element is mandatory, and its value must be1.0, even in the version v1.1 of the DGFiP schema - The value in a
<dpi:MessageRefId>element must have between 1 and 88 characters and contain the SIREN of the platform - The value in a
<ConsQn>,<NumbQn>,<FeesQn>, or<TaxesQn>element must be greater or equal to zero - The value in a
<dpi:ResCountryCode>element must be a country covered by DAC7, i.e. within the EU
Those schemas are adapted from the schemas included in the DGFiP specification documents (Cahier des charges DPI-DAC7), which are published under the Etalab-2.0 license.
Python CLI
This repository also includes a Python CLI dac7 that can be used to:
- Encrypt a French DAC7 declaration using the DGFiP keys
- Get the name an XML declaration should have to match the naming convention :fr: issued by DGFiP
- Check the conformity of an XML declaration with both the revised schema and the naming convention
- Build an XML declaration from dedicated flat JSON files:
- A file for the main digital platform information
- A file for the entity sellers
- A file for the individual sellers
- If applicable, a file for the platform assuming the declaration in place of the main platform, or the platforms whose declaration is assumed by it
The corresponding JSON schemas are included in the schemas/json folder.
How-To
Install and prerequisites
To run the dac7 CLI, you need:
- Python 3.11 or 3.12 or 3.13
- GnuPG, if you want to encrypt the declaration file
It may work with other versions, maybe. Don't hesitate to open a PR to update the documentation and/or the code!
pipx install dac7
Then you can explore all the available dac7 commands with
dac7 --help
Compress and encrypt an XML declaration
[!NOTE] You need GnuPG to be installed on your system to be able to encrypt the file
The DGFiP test and prod platforms expect a compressed-then-encrypted file, using the corresponding test and prod encryption keys.
The encrypt command can do both in one go:
dac7 encrypt -z -E PROD declaration.xml > declaration.xml.gz.gpg
Or, for a test file,
dac7 encrypt -z -E TEST declaration.xml > declaration.xml.gz.gpg
To get more help,
dac7 encrypt --help
Validate an XML declaration
To check both the content of the file and its name,
dac7 validate declaration.xml
To get more help,
dac7 validate --help
Get the expected name of an XML declaration file
If you already have a file declaration.xml, you can get the name it should have to match
the DGFiP naming convention :fr:
with
dac7 name declaration.xml
Build an XML declaration from dedicated flat JSON files
The DAC7 schema is not always very practicable.
It is indeed very nested: for instance, the <dpi:Address> element contains the
country code in a <dpi:CountryCode> element and the rest of the address in
<dpi:AddressFix>.
When the data comes flat from a relational database, nesting it the right way
is cumbersome.
Furthermore, a DAC7 declaration mixes different elements in one file:
- The platform operator data, which is small and almost never changes
- Entity sellers, which are companies and require specific information
- Individual sellers, which require very different information
We propose to split those elements between different flat JSON files, and then assemble them together to produce the expected XML file:
dac7 build -E PROD -f XML \
-p platform_operator.json \
[-o other_platform_operators.json] \
[-e entity_sellers.json] \
[-i individual_sellers.json] \
> declaration.xml
Compared to the XML validation performed by dac7 validate, some additional
2nd-level validation rules from the DGFiP specification are performed
when using dac7 build:
- Rule 2: one quarterly consideration is less than zero, or a seller's overall consideration is zero
- Rule 12: the birthplace of an individual seller is mandatory if they don't have a Tax Identification Number
- Rule 33: any seller needs to report at least one relevant activity
- Rule 34-1 and 34-2: a
NOTINvalue is not allowed for a platform or seller among other proper Tax Identification Numbers
To get more help,
dac7 build --help
To get the JSON schemas for each of the input files,
dac7 schemas build --help
Examples
In the examples folder, we provide files adapted from the examples included in the DGFiP specification documents (Cahier des charges DPI-DAC7), which are published under the Etalab-2.0 license.
1. Entity and individual sellers for immovable properties
Example 1 is an initial declaration for a platform operator with one entity seller and one individual seller, both for immovable properties.
You can rebuild the XML declaration with
dac7 build -E PROD \
-p examples/1_initial_immovable_properties/input/platform_operator.json \
-e examples/1_initial_immovable_properties/input/entity_sellers.json \
-i examples/1_initial_immovable_properties/input/individual_sellers.json \
> declaration.xml
2. Entity and individual sellers for sale of goods
Example 2 is an initial declaration for a platform operator with two entity sellers and one individual sellers, all for the sale of goods.
You can rebuild the XML declaration with
dac7 build -E PROD \
-p examples/2_initial_sale_of_goods/input/platform_operator.json \
-e examples/2_initial_sale_of_goods/input/entity_sellers.json \
-i examples/2_initial_sale_of_goods/input/individual_sellers.json \
> declaration.xml
3. Additional individual seller
Example 3 is an additional declaration for one individual seller that was missing from the initial declaration.
You can rebuild the XML declaration with
dac7 build -E PROD \
-p examples/3_additional/input/platform_operator.json \
-i examples/3_additional/input/individual_sellers.json \
> declaration.xml
4. Correction for platform operator and individual seller
Example 4 is a corrective declaration for both the platform operator and one individual seller.
You can rebuild the XML declaration with
dac7 build -E PROD \
-p examples/4_corrective/input/platform_operator.json \
-i examples/4_corrective/input/individual_sellers.json \
> declaration.xml
5. Platform operator assuming the declaration of another
Example 5 is the initial declaration for a platform operator with individual sellers, that also assumes the declaration of another operator.
You can rebuild the XML declaration with
dac7 build -E PROD \
-p examples/5_initial_assuming/input/platform_operator.json \
-o examples/5_initial_assuming/input/other_platform_operators.json \
-i examples/5_initial_assuming/input/individual_sellers.json \
> declaration.xml
6. Platform operator assumed by another
Example 6 is the initial declaration for a platform operator whose declaration is assumed by another operator.
You can rebuild the XML declaration with
dac7 build -E PROD \
-p examples/6_initial_assumed/input/platform_operator.json \
-o examples/6_initial_assumed/input/other_platform_operators.json \
> declaration.xml
Development
PRs are welcome! But please take notice of the code of conduct.
Use the make command to set up your local environment and run the tests:
# Creates the virtual environment with poetry
# Install the project and all the dependencies
# Configure the pre-commit hook
make init
# Run all the tests
make test
# Regenerate the schemas
make schemas
Links
- Original DPI Schema (v1.0) published by the OECD
- Directive 2021/514 of March 22, 2021 amending Directive 2011/16 of February 15, 2011 (consolidated)
- Regulation 2022/1467 of September 5, 2022 amending Regulation 2015/2378 of December 15, 2015 (consolidated), which includes the OECD schema
- French specification for DPI-DAC7 data transfer :fr: published by DGFiP, which includes
- a human-readable specification document
- a schema for the content of the XML file
- a "naming convention" for the file
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dac7-2024.2.2.tar.gz.
File metadata
- Download URL: dac7-2024.2.2.tar.gz
- Upload date:
- Size: 40.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.0.1 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e12574f4219504588c32e5c08b37d565f68437e8f39375c8cedef22abb1d383
|
|
| MD5 |
3d404f6d98bc9ca38bd46be3567be201
|
|
| BLAKE2b-256 |
0e7385724dc3dd0b4b8c5463d634d22678fb5265dfa8aa9919f846a3440aa2fc
|
Provenance
The following attestation bundles were made for dac7-2024.2.2.tar.gz:
Publisher:
pypi.yml on backmarket-oss/dac7
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dac7-2024.2.2.tar.gz -
Subject digest:
0e12574f4219504588c32e5c08b37d565f68437e8f39375c8cedef22abb1d383 - Sigstore transparency entry: 155199323
- Sigstore integration time:
-
Permalink:
backmarket-oss/dac7@da18a16ec5677667c245aa95ed6775397c113cff -
Branch / Tag:
refs/tags/2024.2.2 - Owner: https://github.com/backmarket-oss
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@da18a16ec5677667c245aa95ed6775397c113cff -
Trigger Event:
push
-
Statement type:
File details
Details for the file dac7-2024.2.2-py3-none-any.whl.
File metadata
- Download URL: dac7-2024.2.2-py3-none-any.whl
- Upload date:
- Size: 38.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.0.1 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92903e76b9440d55db3539efded3ac7beef68cf362958be73b31928e89ee49bc
|
|
| MD5 |
b47aacc76738ddccff8feeda7774a01f
|
|
| BLAKE2b-256 |
53ad962dbe350215722eb4b1ab4e11236ec7e740c973cdb1e7b0138a21fb2763
|
Provenance
The following attestation bundles were made for dac7-2024.2.2-py3-none-any.whl:
Publisher:
pypi.yml on backmarket-oss/dac7
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dac7-2024.2.2-py3-none-any.whl -
Subject digest:
92903e76b9440d55db3539efded3ac7beef68cf362958be73b31928e89ee49bc - Sigstore transparency entry: 155199324
- Sigstore integration time:
-
Permalink:
backmarket-oss/dac7@da18a16ec5677667c245aa95ed6775397c113cff -
Branch / Tag:
refs/tags/2024.2.2 - Owner: https://github.com/backmarket-oss
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@da18a16ec5677667c245aa95ed6775397c113cff -
Trigger Event:
push
-
Statement type: