# Интеграция с 1С:УНФ 3.0 (1С-Фреш) > Дата исследования: 04.06.2026 > Статус: ИССЛЕДОВАНИЕ (код не написан) --- ## 1. Краткое описание Документ описывает доступные API для интеграции сервисного портала AegisOne с 1С:УНФ 3.0, работающей в облаке 1С-Фреш. **Цель:** Синхронизация данных между 1С:УНФ и порталом — клиенты, заказы, контактные лица. --- ## 2. Доступные интерфейсы 1С-Фреш | Интерфейс | Назначение | Чтение | Запись | Сложность | |-----------|-----------|--------|--------|-----------| | **OData** | Стандартный интерфейс платформы 1С | ✅ | ✅ | Средняя | | **REST API** | Портал 1С:ITS Fresh-Integration | ✅ | ✅ | Средняя | | **HTTP-сервис** | УниверсальнаяИнтеграция (UniversalIntegration) | ✅ | ✅ | Высокая | | **Система взаимодействия** | Вебхуки (внешние → 1С) | ❌ | ✅ | Низкая | ### Главный вывод **OData** — основной и самый доступный способ интеграции. Через OData доступны практи­чески все объекты 1С:УНФ 3.0: справочники, документы, регистры. --- ## 3. OData интерфейс ### 3.1 Формат URL ``` https:///a/unf//odata/standard.odata/ ``` | Параметр | Описание | Пример | |----------|----------|--------| | `server` | Адрес сервера 1С-Фреш | `https://xxx.1cfresh.com` | | `app` | Код приложения | `unf` (для УНФ) | | `tenant` | Номер области данных | `34` | | `Entity` | Имя объекта метаданных | `Catalog_Контрагенты` | ### 3.2 Аутентификация ``` Authorization: Basic ``` Используется сервисный пользователь 1С-Фреш с правами доступа к OData. ### 3.3 Формат ответа ``` ?$format=json — JSON ?$format=atom — Atom/XML (по умолчанию) ?$format=json;odata=nometadata — JSON без метаданных ``` --- ## 4. Доступные сущности 1С:УНФ 3.0 ### 4.1 Справочники (Catalogs) | OData URL | Описание | Приоритет для нас | |-----------|----------|-------------------| | `Catalog_Контрагенты` | Покупатели, поставщики, прочие контрагенты | 🔴 Высокий → **Клиенты** | | `Catalog_КонтактныеЛица` | Контактные лица контрагентов | 🔴 Высокий → **Контакты** | | `Catalog_Номенклатура` | Услуги, товары, работы | 🟡 Средний → Каталог услуг | | `Catalog_Договоры` | Договоры с контрагентами | 🟡 Средний → Привязка к клиенту | | `Catalog_Проекты` | Проекты | 🟡 Средний → Связь с заказами | | `Catalog_Организации` | Наши организации | 🟢 Низкий → Контекст | | `Catalog_БанковскиеСчета` | Расчётные счета | 🟢 Низкий | ### 4.2 Документы (Documents) | OData URL | Описание | Приоритет для нас | |-----------|----------|-------------------| | `Document_ЗаказКлиента` | Заказ покупателя | 🔴 Высокий → **Заказ/Лид** | | `Document_РеализацияТоваровУслуг` | Реализация товаров и услуг | 🟡 Средний → История работ | | `Document_АктВыполненныхРабот` | Акт выполненных работ | 🟡 Средний → Подтверждение | | `Document_СчетНаОплату` | Счёт на оплату | 🟡 Средний → Финансы | | `Document_ПоступлениеТоваров` | Поступление товаров | 🟢 Низкий → Закупки | | `Document_СчетНаОплатуПоставщика` | Счёт от поставщика | 🟢 Низкий | ### 4.3 Регистры сведений | OData URL | Описание | |-----------|----------| | `InformationRegister_ЦеныНоменклатурыДокументов` | Цены номенклатуры | | `InformationRegister_КурсыВалют` | Курсы валют | | `InformationRegister_НастройкиСистемыНалогообложения` | Учётная политика | ### 4.4 Табличные части Доступны через суффикс имени: ``` Document_ЗаказКлиента_Товары — табличная часть «Товары» Document_ЗаказКлиента_Услуги — табличная часть «Услуги» Catalog_Контрагенты_КонтактнаяИнформация — контактная информация ``` --- ## 5. Примеры запросов ### 5.1 Все контрагенты (покупатели) ```http GET /odata/standard.odata/Catalog_Контрагенты?$format=json &$select=Ref_Key,Description,ИНН,КПП,РегистрационныйНомер &$filter=not (IsFolder) &$orderby=Description &$top=100 Authorization: Basic ``` ### 5.2 Поиск контрагента по ИНН ```http GET /odata/standard.odata/Catalog_Контрагенты?$format=json &$select=Ref_Key,Description,ИНН,КПП &$filter=(ИНН eq '2310031540') Authorization: Basic ``` ### 5.3 Поиск контрагента по наименованию ```http GET /odata/standard.odata/Catalog_Контрагенты?$format=json &$select=Ref_Key,Description,ИНН &$filter=like(Description, 'Аегис%') Authorization: Basic ``` ### 5.4 Заказы конкретного клиента ```http GET /odata/standard.odata/Document_ЗаказКлиента?$format=json &$expand=Контрагент &$select=Ref_Key,Number,Date,СуммаДокумента,Статус,Контрагент/Description &$filter=Контрагент_Key eq guid'...' &$orderby=Date desc Authorization: Basic ``` ### 5.5 Контактные лица контрагента ```http GET /odata/standard.odata/Catalog_КонтактныеЛица?$format=json &$select=Ref_Key,Description,Должность,Владелец_Key &$filter=Владелец_Key eq guid'...' Authorization: Basic ``` ### 5.6 Номенклатура (услуги) ```http GET /odata/standard.odata/Catalog_Номенклатура?$format=json &$expand=ЕдиницаИзмерения &$select=Ref_Key,Description,Артикул,ВидНоменклатуры &$filter=not (IsFolder) &$orderby=Description Authorization: Basic ``` ### 5.7 Создание нового контрагента (POST) ```http POST /odata/standard.odata/Catalog_Контрагенты Content-Type: application/json Authorization: Basic { "Description": "ООО Ромашка", "ИНН": "2310031540", "КПП": "231001001", "ЮридическоеФизическоеЛицо": "ЮридическоеЛицо" } ``` ### 5.8 Обновление контрагента (PATCH) ```http PATCH /odata/standard.odata/Catalog_Контрагенты(guid'...') Content-Type: application/json Authorization: Basic { "Description": "ООО Ромашка (обновлено)" } ``` --- ## 6. Маппинг сущностей 1С:УНФ → Наш портал ### 6.1 Контрагенты → Клиенты | Поле 1С:УНФ | Поле портала | Тип маппинга | |-------------|-------------|--------------| | `Ref_Key` | `onec_id` (UUID) | Прямой | | `Description` | `company_name` | Прямой | | `ИНН` | `inn` | Прямой (ключ дедупликации) | | `КПП` | `kpp` | Прямой | | `Телефон` | `phone` | Нормализация | | `Email` | `email` | Прямой | | `Адрес` | `address` | Прямой | ### 6.2 Заказ клиента → Лид/Заказ | Поле 1С:УНФ | Поле портала | Тип маппинга | |-------------|-------------|--------------| | `Ref_Key` | `onec_order_id` (UUID) | Прямой | | `Number` | `number` | Прямой | | `Date` | `created_at` | Конвертация | | `СуммаДокумента` | `amount` | Прямой | | `Статус` | `status` | Маппинг статусов | | `Контрагент_Key` | `customer_id` | FK (по onec_id) | ### 6.3 Статусы заказов | Статус 1С:УНФ | Статус портала | |---------------|---------------| | В работе | `in_progress` | | Закрыт | `completed` | | Отменён | `cancelled` | --- ## 7. Стратегия интеграции ### Фаза 0: Настройка доступа (отдельная задача) 1. **Получить от пользователя:** - URL базы в 1С-Фреш (типа `https://xxx.1cfresh.com/a/unf/`) - Логин/пароль сервисного пользователя - Номер области данных (tenant) 2. **Проверить доступность:** - Выполнить тестовый запрос к `$metadata` - Убедиться в наличии нужных сущностей - Проверить права доступа 3. **Создать таблицу настроек:** ```sql CREATE TABLE onec_settings ( id SERIAL PRIMARY KEY, base_url VARCHAR(500) NOT NULL, tenant VARCHAR(50) NOT NULL, login VARCHAR(100) NOT NULL, password_encrypted TEXT NOT NULL, -- fernet last_sync_at TIMESTAMP, is_active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT NOW() ); ``` ### Фаза 1: Синхронизация контрагентов → клиенты 1. **Миграция:** Таблица `onec_sync_log` для логирования ```sql CREATE TABLE onec_sync_log ( id SERIAL PRIMARY KEY, entity_type VARCHAR(50) NOT NULL, -- 'contragent', 'order', etc. onec_id UUID NOT NULL, portal_id INTEGER, action VARCHAR(20) NOT NULL, -- 'create', 'update', 'skip' details JSONB, synced_at TIMESTAMP DEFAULT NOW() ); ``` 2. **Задача синхронизации:** - Читаем `Catalog_Контрагенты` из 1С - Дедупликация по ИНН (точное совпадение) - Если ИНН нет — по наименованию + ИНН КПП - Создаём/обновляем в таблице `customers` - Логируем каждое действие 3. **Периодичность:** Раз в день (ночью) или по требованию ### Фаза 2: Синхронизация заказов 1. **Миграция:** Поле `onec_order_id` в `leads` или новая таблица 2. **Задача синхронизации:** - Читаем `Document_ЗаказКлиента` из 1С - Привязка к клиенту по `Контрагент_Key` - Маппинг статусов - Логирование ### Фаза 3 (опционально): Обратная запись - Создание заказа в портале → создание в 1С - Требует аккуратной обработки ошибок - **Рекомендация:** Только после стабильности фаз 1-2 --- ## 8. Технические детали ### 8.1 Python-клиент для OData Рекомендуемая библиотека: `pyodata` или `requests` (raw OData). ```python import base64 import httpx class OneCFreshClient: """Клиент для работы с 1С-Фреш через OData.""" def __init__(self, base_url: str, tenant: str, login: str, password: str): self.base_url = base_url.rstrip('/') self.tenant = tenant self.auth = base64.b64encode(f"{login}:{password}".encode()).decode() async def get_contragents(self, top: int = 100, skip: int = 0) -> list: """Получить список контрагентов.""" url = f"{self.base_url}/a/unf/{self.tenant}/odata/standard.odata/Catalog_Контрагенты" params = { "$format": "json;odata=nometadata", "$select": "Ref_Key,Description,ИНН,КПП", "$filter": "not (IsFolder)", "$top": str(top), "$skip": str(skip), } headers = {"Authorization": f"Basic {self.auth}"} async with httpx.AsyncClient() as client: resp = await client.get(url, params=params, headers=headers) resp.raise_for_status() return resp.json().get("value", []) async def get_contragent_by_inn(self, inn: str) -> dict | None: """Найти контрагента по ИНН.""" url = f"{self.base_url}/a/unf/{self.tenant}/odata/standard.odata/Catalog_Контрагенты" params = { "$format": "json;odata=nometadata", "$select": "Ref_Key,Description,ИНН,КПП", "$filter": f"(ИНН eq '{inn}')", } headers = {"Authorization": f"Basic {self.auth}"} async with httpx.AsyncClient() as client: resp = await client.get(url, params=params, headers=headers) resp.raise_for_status() items = resp.json().get("value", []) return items[0] if items else None ``` ### 8.2 Ограничения | Ограничение | Описание | Решение | |-------------|----------|---------| | **Multi-tenancy** | Каждая база в своей области данных | Указать tenant в URL | | **Публикация OData** | Должна быть включена в конфигурации | Проверить через `$metadata` | | **Права доступа** | Сервисный пользователь должен иметь права на чтение | Настроить роли в 1С | | **Пагинация** | Большие выборки — через `$top`/`$skip` | Построчная загрузка | | **Rate limits** | Возможны ограничения на частоту запросов | Очередь задач, retry | ### 8.3 Проверка доступности ```bash # Тестовый запрос метаданных curl -u "login:password" \ "https://xxx.1cfresh.com/a/unf/34/odata/standard.odata/$metadata" # Тестовый запрос контрагентов curl -u "login:password" \ "https://xxx.1cfresh.com/a/unf/34/odata/standard.odata/Catalog_Контрагенты?\$format=json&\$top=5" ``` --- ## 9. Сравнение с webhook (Система взаимодействия) | Критерий | OData | Webhook | |----------|-------|---------| | **Чтение данных** | ✅ Да | ❌ Нет (только запись) | | **Запись данных** | ✅ Да | ✅ Да (только в 1С) | | **Направление** | Bidirectional | One-way (внешнее → 1С) | | **Формат** | JSON (стандартный OData) | JSON (свой формат) | | **Аутентификация** | Basic Auth | URL + логин/пароль | | **Сложность** | Средняя | Низкая | | **Использование** | Синхронизация данных | Уведомления, сообщения | **Вывод:** OData — для синхронизации данных. Webhook — для отправки уведомлений в 1С. --- ## 10. Рекомендации ### Приоритет implementation 1. **OData синхронизация контрагентов** — самый важный функционал 2. **OData синхронизация заказов** — расширение функционала 3. **Webhook уведомления** — опционально, для двусторонней связи ### Вопросы к пользователю (для фазы 0) 1. URL базы в 1С-Фреш? 2. Логин/пароль сервисного пользователя? 3. Номер области данных (tenant)? 4. Какие данные в приоритете: контрагенты, заказы, или всё сразу? 5. Направление синхронизации: только из 1С → портал, или bidirectional? ### Рекомендация **Начать с read-only синхронизации контрагентов** — самый безопасный и быстрый способ: - Не требует записи обратно - Минимальные риски - Быстро даёт результат (клиенты из 1С появляются в портале) - Потом можно расширять до заказов и bidirectional --- ## 11. Ссылки - [Документация 1С-Фреш: OData](https://its.1c.ru/db/fresh/content/19956692/hdoc) - [Платформа 1С: REST интерфейс](https://v8.1c.ru/platforma/rest-interfeys/) - [OData: правила формирования имени ресурса](https://42clouds.com/ru-ru/manuals/interfeys-odata-pravila-formirovaniya-imeni-resursa/) - [Работа с 1С через OData (Infostart)](https://infostart.ru/1c/articles/1570140/) - [odata1c-client (GitHub)](https://github.com/Dakword/odata1c-client) — PHP-клиент с примерами - [Контрагенты и контактные лица в 1С:УНФ](https://unf4you.ru/publ/kontragenty_i_kontaktnye_lica/1-1-0-407) - [Заказ покупателя в 1С:УНФ](https://estart1c.ru/unf-30/189-kak-v-1sroznice-i-1sunf-sozdat-i-ispolzovat-zakaz-pokupatelja.html)