For companies operating in Germany, Austria, and Switzerland, aligning Odoo with national accounting standards isn't optional. Odoo handles daily sales, procurement, and inventory well on its own, but tax advisors (Steuerberater) almost universally work in DATEV for tax filing, annual financial statements (Jahresabschluss), and audit compliance — so at some point your Odoo accounting data has to get there cleanly.
A properly configured DATEV integration bridges native Odoo accounting entries with DATEV Enterprise Online (DATEV Unternehmen online), which is what actually eliminates the manual re-entry, tax code mismatches, and GoBD compliance risk (Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern, Aufzeichnungen und Unterlagen in elektronischer Form) that I see come up constantly in DATEV-related consulting work.
Strategic Pillars of DATEV-Odoo Integration
Connecting Odoo Accounting with DATEV involves four critical operational steps:
- Standard Chart (SKR) Alignment
- Tax Code & BU Key Map
- Automated CSV Export Formatting
- Document & Belegfeld Archiving
- Chart of Accounts Standardization (SKR03 / SKR04): Map Odoo
account.accountstructures strictly to standard German charts of accounts (Standardkontenrahmen SKR03 or SKR04). - Tax Code & BU Key Mapping: Translate Odoo tax tags into DATEV Automatic Tax Keys (Automatikkonten) and Tax Steering Keys (BU-Schlüssel).
- Structured Export Format (DATEV CSV / ASCII Format): Format headers, field lengths, number formats, and date formats strictly according to official DATEV interface specs.
- Audit-Proof Document Linking (Beleglink): Attach digital invoice PDFs directly to exported journal entries so auditors and tax consultants can view original documents in DATEV.
System Comparison: Native Odoo Export vs. Dedicated DATEV Interface
Understanding export approaches helps determine whether native tools meet your compliance requirements or if extended customization is needed.
| Feature / Metric | Standard Odoo Export | Dedicated DATEV Module | Direct API / Middleware Integration |
|---|---|---|---|
| Chart Support | Manual SKR mapping | Pre-configured SKR03 / SKR04 | Automated mapping rules |
| GoBD Compliance | Basic record tracking | Complete change-log audit trails | Enterprise audit logging |
| Tax Key (BU Key) Handling | Manual configuration | Native tax key conversion | Automated dynamic tax tagging |
| Digital Attachment Sync | Export CSV only | Includes Belegfeld & Document Link | Direct cloud upload to DATEV online |
| Setup Overhead | Low | Low to Moderate | High |
Technical Setup: Mapping Odoo to DATEV Architecture
1. Account Number Alignment
In DATEV, partner account numbers follow specific length constraints (typically 5-digit subledger accounts):
- Debtors / Customers (Debitorenkonten): Range
10000–69999 - Creditors / Vendors (Kreditorenkonten): Range
70000–99999
In Odoo, set up customer and vendor sequences under Accounting > Configuration > Master Data to ensure partner account IDs fall within these standard ranges.
2. Tax Mapping Table (UST / VSt)
Ensure each Odoo tax record (account.tax) is mapped to its corresponding DATEV tax key:
| Odoo Tax Label | Tax Rate | DATEV BU Key | Account (SKR03) | Account (SKR04) |
|---|---|---|---|---|
| Umsatzsteuer 19% | 19% | Default (Auto) | 8400 | 4400 |
| Umsatzsteuer 7% | 7% | Default (Auto) | 8300 | 4300 |
| Vorsteuer 19% | 19% | 9 | 1576 | 1406 |
| Innergemeinschaftlicher Erwerb 19% | 19% | 19 | 3125 | 5425 |
Implementation Code Example: DATEV ASCII/CSV Exporter
Below is a Python snippet demonstrating how to format Odoo journal items (account.move.line) into DATEV-compliant CSV structure in accordance with official header parameters:
import csv
import io
from odoo import models, fields, api
class DatevExportWizard(models.TransientModel):
_name = 'datev.export.wizard'
_description = 'Odoo to DATEV ASCII Export Wizard'
date_from = fields.Date(string="Start Date", required=True)
date_to = fields.Date(string="End Date", required=True)
target_journal_ids = fields.Many2many('account.journal', string="Journals")
def generate_datev_csv(self):
output = io.StringIO()
writer = csv.writer(output, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL)
# 1. Mandatory DATEV Header Header Structure (Version 700 / Format Spec)
header_row_1 = [
"EXTF", "700", "21", "Buchungsstapel", "9", "", "", "", "", "",
"1000", "1000", "20260101", "4", self.date_from.strftime('%Y%m%m'),
self.date_to.strftime('%Y%m%d'), "RE", "", "", "", "", "", "", "", "", ""
]
# 2. Field Names Header
column_headers = [
"Umsatz (ohne Soll/Haben-Kennzeichen)", "Soll/Haben-Kennzeichen",
"WKZ", "Kurs", "Basis-Umsatz", "WKZ Basis-Umsatz", "Konto",
"Gegenkonto (ohne SS-Kennzeichen)", "BU-Schlüssel", "Belegdatum",
"Belegfeld 1", "Belegfeld 2", "Skonto", "Buchungstext"
]
writer.writerow(header_row_1)
writer.writerow(column_headers)
# 3. Fetch Validated Journal Lines from Odoo
domain = [
('date', '>=', self.date_from),
('date', '<=', self.date_to),
('move_id.state', '=', 'posted')
]
if self.target_journal_ids:
domain.append(('journal_id', 'in', self.target_journal_ids.ids))
lines = self.env['account.move.line'].search(domain)
for line in lines:
if line.debit == 0 and line.credit == 0:
continue
amount = abs(line.balance)
sh_code = "S" if line.balance > 0 else "H"
doc_date = line.date.strftime('%d%m') # DATEV uses DDMM format
ref = line.move_id.name[:12] if line.move_id.name else ""
writer.writerow([
f"{amount:.2f}".replace('.', ','), # German decimal format
sh_code,
"EUR",
"",
"",
"",
line.account_id.code,
line.partner_id.ref or "",
"",
doc_date,
ref,
"",
"",
line.name or "Odoo Export"
])
return output.getvalue()
Best Practices for GoBD Compliance in Odoo
To maintain full compliance during German financial audits (Betriebsprüfung):
- Lock Accounting Periods: Enable system lock dates in Odoo (Accounting > Actions > Lock Dates) after exporting files to prevent retroactive edits.
- Immutable Sequences: Enforce chronological invoice and bill sequences. Odoo prevents deletion of posted moves, satisfying GoBD non-alterability rules.
- Audit Trail Logging: Retain Odoo tracking chatter logs for all financial edits and approval steps.
- Store Original Receipts: Use digital archiving tools to retain original vendor bill PDFs alongside transaction records.
Getting this wrong is rarely a one-time fix — most of the compliance risk I see comes from the export drifting out of sync with the GDPR and data-handling requirements that apply to the same records. If you'd rather have this audited and set up correctly the first time than debug it during a Betriebsprüfung, get in touch — this is exactly the kind of custom Odoo development work I do.
By Shahid Malik