11 KiB
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).
Метод get_legal_entity_data(vat, widget=True)
Точка входа вызывается из JS-компонента при нажатии кнопки поиска. Выполняет три шага:
- Получает токен через
get_dadata_token() - Отправляет запрос в DaData:
dadata.find_by_id("party", vat, branch_type="MAIN")— ищет только головные организации, без филиалов - Разбирает ответ через
_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. Например, 50102 → sp (индивидуальный предприниматель), 12300 → plc (ООО).
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 |
OWL-компонент: виджет dadata_search
Файл: static/src/views/fields/search/search_field.js
Кастомный виджет для полей типа char. Визуально выглядит как стандартное текстовое поле с иконкой поиска справа. Зарегистрирован в реестре виджетов Odoo как dadata_search.
Логика метода search()
Вызывается при нажатии иконки поиска. Последовательность:
- Вызывает серверный метод
res.partner.get_legal_entity_data()через ORM с текущим значением поля - Получает в ответ действие открытия визарда подтверждения
- Открывает визард и ждёт его закрытия
- При закрытии проверяет флаг
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, тестовый контрагент |