Files
site_aegisone/other/1C_UNF_INTEGRATION.md
T

18 KiB
Raw Blame History

Интеграция с 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://<server>/a/unf/<tenant>/odata/standard.odata/<Entity>
Параметр Описание Пример
server Адрес сервера 1С-Фреш https://xxx.1cfresh.com
app Код приложения unf (для УНФ)
tenant Номер области данных 34
Entity Имя объекта метаданных Catalog_Контрагенты

3.2 Аутентификация

Authorization: Basic <base64(login:password)>

Используется сервисный пользователь 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 Все контрагенты (покупатели)

GET /odata/standard.odata/Catalog_Контрагенты?$format=json
    &$select=Ref_Key,Description,ИНН,КПП,РегистрационныйНомер
    &$filter=not (IsFolder)
    &$orderby=Description
    &$top=100
Authorization: Basic <auth>

5.2 Поиск контрагента по ИНН

GET /odata/standard.odata/Catalog_Контрагенты?$format=json
    &$select=Ref_Key,Description,ИНН,КПП
    &$filter=(ИНН eq '2310031540')
Authorization: Basic <auth>

5.3 Поиск контрагента по наименованию

GET /odata/standard.odata/Catalog_Контрагенты?$format=json
    &$select=Ref_Key,Description,ИНН
    &$filter=like(Description, 'Аегис%')
Authorization: Basic <auth>

5.4 Заказы конкретного клиента

GET /odata/standard.odata/Document_ЗаказКлиента?$format=json
    &$expand=Контрагент
    &$select=Ref_Key,Number,Date,СуммаДокумента,Статус,Контрагент/Description
    &$filter=Контрагент_Key eq guid'...'
    &$orderby=Date desc
Authorization: Basic <auth>

5.5 Контактные лица контрагента

GET /odata/standard.odata/Catalog_КонтактныеЛица?$format=json
    &$select=Ref_Key,Description,Должность,Владелец_Key
    &$filter=Владелец_Key eq guid'...'
Authorization: Basic <auth>

5.6 Номенклатура (услуги)

GET /odata/standard.odata/Catalog_Номенклатура?$format=json
    &$expand=ЕдиницаИзмерения
    &$select=Ref_Key,Description,Артикул,ВидНоменклатуры
    &$filter=not (IsFolder)
    &$orderby=Description
Authorization: Basic <auth>

5.7 Создание нового контрагента (POST)

POST /odata/standard.odata/Catalog_Контрагенты
Content-Type: application/json
Authorization: Basic <auth>

{
    "Description": "ООО Ромашка",
    "ИНН": "2310031540",
    "КПП": "231001001",
    "ЮридическоеФизическоеЛицо": "ЮридическоеЛицо"
}

5.8 Обновление контрагента (PATCH)

PATCH /odata/standard.odata/Catalog_Контрагенты(guid'...')
Content-Type: application/json
Authorization: Basic <auth>

{
    "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. Создать таблицу настроек:

    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 для логирования

    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).

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 Проверка доступности

# Тестовый запрос метаданных
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. Ссылки