Німецький запит на інтеграцію Odoo майже завжди називає три сторони: податкового консультанта з DATEV, інтернет-магазин на Shopware або JTL і, з минулого року, електронний рахунок. Технічна частина підключення рідко буває проблемою. Проблема в тому, що кожна з трьох сторін чекає дані у формі, якої Odoo сам по собі не видає, і що на початку проєкту про це ніхто не каже.
Тож по порядку: що насправді є в стандартному образі, чого в ньому немає і які шви мені доводилося шити вручну.
Що Odoo дає для Німеччини - пораховано, а не припущено
У робочому образі Odoo 19 Community 659 модулів. Німецький серед них рівно один: l10n_de, план рахунків. Модулів із DATEV у назві немає взагалі. Європейський модуль one-stop-shop l10n_eu_oss на місці, як і список форматів електронних рахунків, у якому вже є XRechnung.
Одна ця цифра визначає форму будь-якого німецького проєкту. Бухгалтерський експорт - це або ваша власна робота, або чужий продукт. Незмінність проводок - налаштування, яке спершу треба знайти. Електронний рахунок ближче, ніж думає більшість. А все, що потрібно магазину, повністю залежить від конектора.
DATEV: експорт - ваша задача, і формат у ній - менша половина
Раз у коробці нічого немає, питання лише в тому, хто напише експорт: платний модуль, партнер чи я. Хто б не писав, складність не в CSV. DATEV потрібні проводки, а не документи: рахунок і кореспондентський рахунок, податковий ключ, номер документа, за яким звіряється ваш консультант, і дата, що потрапляє в правильний період. Odoo охоче віддасть усі чотири - щойно хтось вирішить, який рахунок Odoo відповідає якому номеру в плані рахунків консультанта і що робити з випадками, для яких номера немає зовсім.
Саме випадки без номера псують закриття місяця: повернення, що переходить через межу періоду, оплата, яка прийшла раніше за рахунок, виплата маркетплейсу одним рядком на двісті замовлень. Тому я прошу в консультанта проводки за минулий місяць ще до того, як напишу перший рядок коду експорту: цей файл каже про мапінг більше, ніж будь-яка нарада.
GoBD: незмінність - це перемикач, і вмикати його треба рано
Те, чого вимагають німецькі правила, в Odoo є, і за замовчуванням воно вимкнене. У журналів є restrict_mode_hash_table; якщо його ввімкнути, кожен проведений запис отримує inalterable_hash і secure_sequence_number, тож змінений рядок можна виявити. У компанії є restrictive_audit_trail для журналу змін, який не можна чистити.
Дві пастки. Перша: у журналу є ще й has_unhashed_entries - чесне визнання того, що все проведене до ввімкнення режиму лишилося поза ланцюжком, і жодне подальше налаштування цього не виправить. Вмикайте режим під час запуску системи, а не тоді, коли оголосили перевірку. Друга пастка - сама інтеграція: конектор, який «виправляє» проведений рахунок, бо в магазині змінили замовлення, ламає саме ту властивість, яку має доводити хеш. Виправлення - це нові документи, кредит-нота або сторно, і конектор треба писати так із першого дня.
Магазин: Shopware або JTL, і питання в тому, хто володіє даними
Обидва спілкуються достатньо вільно - Shopware через свій Admin API, JTL через власну базу й конектор, - і жодне з цього не причина, через яку проєкти йдуть шкереберть. Причина в тому, що залишки й ціни існують на обох сторонах, і обидві сторони вважають себе правими.
Одна таблиця вирішує це до будь-якого коду: ліворуч кожне поле, що перетинає межу, праворуч єдина система, якій дозволено його змінювати. Залишками володіє Odoo, магазину про них повідомляють. Ціни зазвичай належать магазину, бо там проходять акції. Будь-яке поле, для якого відповідь - «обидві», протягом кварталу перетвориться на звернення до підтримки.
Далі німецька деталь, яка забирає найбільше часу: магазини думають у цінах брутто, Odoo - у нетто. Відніміть дев’ятнадцять відсотків від 49,99 € і додайте назад, кілька тисяч разів, і різниця в центах проявиться в бухгалтерії нескінченним списком дрібних розбіжностей, яких ніхто не може пояснити. Один раз вирішіть, яка сторона головна для цифри, яку бачить покупець, передавайте її саме так, а інша сторона хай перераховує від неї.
Електронний рахунок: XRechnung уже в коробці
Від початку 2025 року німецькі компанії зобов’язані вміти приймати структуровані рахунки; обов’язок їх надсилати запроваджується поетапно. Добра новина: Odoo 19 уже підтримує формат - у картці клієнта в списку форматів рахунків є «Germany (XRechnung)» поруч із Factur-X і Peppol BIS 3.0. Сам доступ до Peppol живе в окремих модулях.
Для інтеграції це означає одне: рахунок, що залишає вашу систему, - це документ із полями, а не PDF з їхнім зображенням. Усе, що потрібно XML, - посилання покупця, розбивка податків, одиниця виміру - має бути в записі до запуску експорту, і зазвичай це повертає мене до конектора магазину збирати поля, які ніхто не зіставив.
З чого я починаю такий проєкт
Один дзвінок і три питання, від яких залежить оцінка: який план рахунків використовує ваш консультант і чи має експорт повторювати усталену практику проводок; чи ввімкнено режим хешування і з якого часу; яка система володіє залишками, ціною та карткою клієнта. Відповіді вміщаються на одну сторінку, і ця сторінка - специфікація інтеграції.
Якщо конектор у вас уже є і працює, корисне питання інше: що він робить, якщо його запустити двічі, і як ви дізнаєтеся, що минулої ночі він не запускався зовсім? Зазвичай мене кличуть саме через це.