Files
public/dadata_connector/TECHNICAL.md

11 KiB
Raw Blame History

DaData Connector

name: dadata_connector version: 19.0.2025.12.03 author: MK.Lab depends: base, web, contacts, account, l10n_ru_doc external_dependencies: dadata==21.10.1

Архитектура

Модуль состоит из трёх частей: серверная логика запроса к DaData и разбор ответа, визард подтверждения найденных данных, и OWL-компонент (виджет) который добавляет кнопку поиска к полям Tax ID (ИНН) и ОГРН прямо в форме.

dadata_connector
├── res.partner (расширение)          — запрос к DaData, разбор ответа
├── res.partner.auto_data.wizard      — диалог подтверждения данных
├── res.config.settings (расширение)  — хранение токена DaData
└── SearchField (OWL-компонент)       — виджет с кнопкой поиска в форме

Модели

res.partner — Расширение карточки контрагента

Файл: models/res_partner.py

Добавляет логику поиска и обработки данных из DaData. Новых полей в базу не добавляет — только методы и переопределение виджета.

Переопределение виджета (_get_view)

При загрузке формы контрагента метод _get_view программно устанавливает виджет dadata_search для поля vat (ИНН). Это сделано через код, а не через XML, чтобы установить приоритет над стандартным виджетом partner_autocomplete от Odoo. Он подключается к полю первым, и XML-переопределение его не вытесняет.

Для поля ogrn виджет устанавливается через XML (views/res_partner_views.xml).

Точка входа вызывается из JS-компонента при нажатии кнопки поиска. Выполняет три шага:

  1. Получает токен через get_dadata_token()
  2. Отправляет запрос в DaData: dadata.find_by_id("party", vat, branch_type="MAIN") — ищет только головные организации, без филиалов
  3. Разбирает ответ через _parse_dadata_response() и открывает визард подтверждения

Параметр widget=True означает режим работы через интерфейс (возвращает действие открытия визарда). При widget=False возвращает словарь с данными напрямую, что используется в тестах.

Метод get_dadata_token()

Читает токен из системных параметров (dadata_connector.dadata_token). Если токен не задан, возникает ValidationError с подсказкой, где его найти в настройках.

Метод _parse_dadata_response(data)

Разбирает JSON-ответ от DaData и возвращает два словаря:

  • wizard_data — данные для показа в диалоге подтверждения: статус организации, тип (юрлицо / ИП), название, полный адрес строкой
  • new_data — данные для записи в карточку контрагента: все поля ниже

Маппинг полей DaData → Odoo:

Поле Odoo Поле DaData Примечание
vat inn ИНН
ogrn ogrn ОГРН
kpp kpp Только для юрлиц
okpo okpo ОКПО
arceat okved Основной ОКВЭД
company_form opf.code → таблица okopf Код ОКОПФ переводится в тип: sp, plc, jsc и т.д.
sp_register_number documents.fts_registration Серия и номер через пробел
sp_register_date documents.fts_registration.issue_date Дата регистрации в налоговой
name name.short_with_opf (юрлицо) или fio (ИП)
country_id address.data.country_iso_code Поиск по коду страны
state_id address.data.region_iso_code Поиск по коду региона
city address.data.city
street Собирается из нескольких полей street_with_type, house_type_full, house, flat_type_full, flat через запятую
zip address.data.postal_code
management management.name и management.post Не поле, а вложенный словарь для создания контакта

Таблица ОКОПФ (словарь okopf в начале файла): переводит цифровые коды организационно-правовых форм в технические коды Odoo. Например, 50102sp (индивидуальный предприниматель), 12300plc (ООО).


res.partner.auto_data.wizard — Диалог подтверждения

Файл: wizard/res_partner_auto_data_wizard.py

Временная модель (TransientModel), работает только пока открыт диалог. Показывает пользователю найденные данные перед тем, как они будут применены к карточке.

Поле Тип Описание
partner_id Many2one → res.partner Контрагент, к которому применяются данные
status Selection Статус: active / liquidating / liquidated / bankrupt / reorganizing
organization_type Selection Тип: legal (юрлицо) / individual (ИП)
name Char Название организации
full_address Text Полный юридический адрес строкой

Форма открывается в режиме только для чтения (create="0" delete="0" edit="0"), редактировать данные в диалоге нельзя.

Метод button_yes() — при нажатии «Да» закрывает диалог и передаёт во фронтенд сигнал {"update": True}. JS-компонент перехватывает этот сигнал и применяет данные к карточке.


res.config.settings — Расширение настроек

Файл: models/res_config_settings.py

Добавляет одно поле в раздел «Интеграции» в настройках Odoo. Значение хранится в системных параметрах.

Поле Параметр Описание
dadata_token dadata_connector.dadata_token API-токен сервиса DaData

Файл: static/src/views/fields/search/search_field.js

Кастомный виджет для полей типа char. Визуально выглядит как стандартное текстовое поле с иконкой поиска справа. Зарегистрирован в реестре виджетов Odoo как dadata_search.

Вызывается при нажатии иконки поиска. Последовательность:

  1. Вызывает серверный метод res.partner.get_legal_entity_data() через ORM с текущим значением поля
  2. Получает в ответ действие открытия визарда подтверждения
  3. Открывает визард и ждёт его закрытия
  4. При закрытии проверяет флаг closeInfo.update:
    • Если True — применяет данные к карточке и сохраняет
    • Если False (нажали «Нет») — ничего не делает

Применение данных к карточке

Перед обновлением карточки фильтрует только те поля, которые реально существуют в модели (record.fields). Many2one-поля (например, country_id, state_id) конвертируются в формат [id, ""] — так требует OWL.

После обновления полей принудительно устанавливает company_type: "company" — контрагент всегда сохраняется как организация.

Создание контакта-руководителя

Если в ответе DaData есть данные об управляющем (management), компонент проверяет нет ли уже контакта с таким именем и должностью среди дочерних записей контрагента. Если нет — создаёт новый контакт через res.partner.create() с привязкой parent_id к текущему контрагенту.


Представления

Файл: views/res_partner_views.xml

Два расширения формы контрагента:

  • Расширение l10n_ru_doc.view_partner_ru_form — добавляет виджет dadata_search к полю ogrn
  • Расширение base.view_partner_form — добавляет виджет dadata_search к полю vat. Приоритет 2, но виджет также устанавливается программно через _get_view для гарантированного перебития partner_autocomplete

Файл: views/res_config_settings_view.xml

Добавляет поле токена в настройки.


Тесты

Файл: tests/

Файл Что покрывает
test_res_partner.py Запрос к DaData, разбор ответа, маппинг полей
test_wizard.py Создание визарда, отображение полей, кнопка подтверждения
common.py Общие фикстуры: клиент DaData, тестовый контрагент