Версия: 2.0.0
Дата: 2025-12-24
Тип: Специалист
Базовый протокол: /CLAUDE.md
Коннектор: library/connectors/api/onec/
AI-ассистент для создания документов в 1С на основе данных из ERP.
Работает через OData API 1С:УНФ.
Принцип: 1С — генератор документов для отчётности. Учёт ведётся в нашей ERP.
1с, 1c, документ, накладная, счёт, создай в 1с, приходная, расходная
┌─────────────────────────────────────────────────────────────────┐
│ ТРЁХСЛОЙНАЯ АРХИТЕКТУРА │
├─────────────────────────────────────────────────────────────────┤
│ │
│ СЛОЙ 3: assistant.py — AI-обёртка │
│ ───────────────────────── │
│ • Понимает естественный язык │
│ • Распознаёт Intent (create_receipt, find_product...) │
│ • Вызывает Operations │
│ │ │
│ СЛОЙ 2: operations.py — Бизнес-операции │
│ ──────────────────────────── │
│ • create_receipt_from_order() │
│ • find_or_create_contractor() │
│ • Работа с ERP данными │
│ │ │
│ СЛОЙ 1: client.py — OData API │
│ ───────────────────── │
│ • HTTP запросы │
│ • CRUD справочников и документов │
│ • Чистые функции │
│ │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 1С-АССИСТЕНТ │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ВХОД: Команда на естественном языке │
│ "создай приход по заказу ЗП-00123" │
│ │
│ AI АГЕНТ: ┌─────────────────────────────────────┐ │
│ │ 1. Парсинг интента │ │
│ │ 2. Получение данных из ERP │ │
│ │ 3. Валидация │ │
│ │ 4. Формирование документа │ │
│ │ 5. Обработка ошибок │ │
│ └─────────────────────────────────────┘ │
│ │ │
│ КОННЕКТОР: ┌─────────────────────────────────────┐ │
│ │ OData API → 1С:УНФ (SaaS) │ │
│ │ • Справочники │ │
│ │ • Документы │ │
│ │ • Отчёты │ │
│ └─────────────────────────────────────┘ │
│ │ │
│ ВЫХОД: Номер документа + статус │
│ "Приходная накладная ПН-00456 создана" │
│ │
└─────────────────────────────────────────────────────────────────┘
| Документ | Триггеры | Источник ERP | 1С Документ |
|---|---|---|---|
| Заказ поставщику | "заказ поставщику", "закажи у" | erp_purchase_orders | Catalog_ЗаказПоставщику |
| Приходная накладная | "приход", "оприходуй" | erp_purchase_orders (received) | Document_ПриходнаяНакладная |
| Расходная накладная | "расход", "отгрузи" | erp_sales_orders (shipped) | Document_РасходнаяНакладная |
| Счёт на оплату | "счёт", "выстави счёт" | erp_sales_orders | Document_СчётНаОплату |
| Возврат товара | "возврат", "оформи возврат" | erp_returns | Document_ВозвратТоваровОтПокупателя |
| Корректировка | "корректировка", "исправь" | erp_adjustments | Document_КорректировкаЗаписейРегистров |
1. ПАРСИНГ КОМАНДЫ
─────────────────
Вход: "создай приходную накладную по заказу ЗП-00123"
Определить:
• Тип документа: Приходная накладная
• Связанный объект: Заказ поставщику ЗП-00123
• Дополнительные параметры: нет
2. ПОЛУЧЕНИЕ ДАННЫХ ИЗ ERP
────────────────────────
SELECT * FROM erp_purchase_orders WHERE order_number = 'ЗП-00123'
SELECT * FROM erp_purchase_order_lines WHERE order_id = ...
SELECT * FROM erp_suppliers WHERE id = ...
SELECT * FROM erp_products WHERE id IN (...)
3. ПРОВЕРКА КОНТРАГЕНТА В 1С
──────────────────────────
Найти по ИНН:
GET /Catalog_Контрагенты?$filter=ИНН eq '7712345678'
Если не найден → создать:
POST /Catalog_Контрагенты
{
"Description": "ООО Поставщик",
"ИНН": "7712345678",
"КПП": "771201001"
}
4. ПРОВЕРКА НОМЕНКЛАТУРЫ
──────────────────────
Для каждого товара:
GET /Catalog_Номенклатура?$filter=Артикул eq 'АРТ-001'
Если не найден → ошибка (товар должен быть в 1С)
5. ФОРМИРОВАНИЕ ДОКУМЕНТА
───────────────────────
POST /Document_ПриходнаяНакладная
{
"Date": "2025-12-24T10:00:00",
"Контрагент_Key": "...",
"Склад_Key": "...",
"Товары": [
{
"Номенклатура_Key": "...",
"Количество": 100,
"Цена": 150.00,
"Сумма": 15000.00
}
]
}
6. ОБНОВЛЕНИЕ ERP
───────────────
UPDATE erp_purchase_orders
SET doc_1c_id = '...', doc_1c_number = 'ПН-00456'
WHERE order_number = 'ЗП-00123'
7. ОТВЕТ
──────
"Приходная накладная ПН-00456 создана.
Сумма: 15 000 ₽
Поставщик: ООО Поставщик
Позиций: 5"
INTENTS = {
"create_purchase_order": {
"patterns": [
"создай заказ поставщику",
"закажи у {supplier}",
"сформируй заказ на закупку"
],
"params": ["supplier", "products", "quantities"]
},
"create_receipt": {
"patterns": [
"создай приход",
"приходная накладная",
"оприходуй заказ {order_number}",
"приход по {order_number}"
],
"params": ["order_number", "date"]
},
"create_shipment": {
"patterns": [
"создай расход",
"расходная накладная",
"отгрузи заказ {order_number}",
"оформи отгрузку"
],
"params": ["order_number", "date"]
},
"create_invoice": {
"patterns": [
"выстави счёт",
"счёт на оплату",
"сформируй счёт для {customer}"
],
"params": ["order_number", "customer"]
},
"create_return": {
"patterns": [
"оформи возврат",
"возврат товара",
"возврат от {customer}"
],
"params": ["order_number", "reason"]
},
"get_stock": {
"patterns": [
"остатки в 1с",
"проверь остатки",
"сколько на складе"
],
"params": ["sku", "warehouse"]
},
"sync_products": {
"patterns": [
"синхронизируй товары",
"обнови номенклатуру",
"загрузи товары в 1с"
],
"params": ["category", "brand"]
}
}
# system/config/1c.yaml
1c:
base_url: "https://saas.is1c.ru/UNF_200960100487/odata/standard.odata"
auth:
type: "basic"
username: "${1C_USERNAME}"
password: "${1C_PASSWORD}"
# Справочники
catalogs:
contractors: "Catalog_Контрагенты"
nomenclature: "Catalog_Номенклатура"
warehouses: "Catalog_Склады"
contracts: "Catalog_ДоговорыКонтрагентов"
# Документы
documents:
purchase_order: "Document_ЗаказПоставщику"
receipt: "Document_ПриходнаяНакладная"
shipment: "Document_РасходнаяНакладная"
invoice: "Document_СчётНаОплату"
return: "Document_ВозвратТоваровОтПокупателя"
# Настройки
settings:
default_warehouse: "00000000-0000-0000-0000-000000000001"
default_currency: "RUB"
retry_attempts: 3
timeout: 30
# library/connectors/api/1c/client.py
class Client1C:
"""Клиент к 1С OData API"""
async def find_contractor(self, inn: str) -> dict | None:
"""Найти контрагента по ИНН"""
url = f"{self.base}/Catalog_Контрагенты"
params = {"$filter": f"ИНН eq '{inn}'"}
return await self._get_one(url, params)
async def create_contractor(self, data: dict) -> str:
"""Создать контрагента"""
url = f"{self.base}/Catalog_Контрагенты"
result = await self._post(url, data)
return result["Ref_Key"]
async def find_nomenclature(self, article: str) -> dict | None:
"""Найти номенклатуру по артикулу"""
url = f"{self.base}/Catalog_Номенклатура"
params = {"$filter": f"Артикул eq '{article}'"}
return await self._get_one(url, params)
async def create_document(self, doc_type: str, data: dict) -> str:
"""Создать документ любого типа"""
url = f"{self.base}/{doc_type}"
result = await self._post(url, data)
return result["Ref_Key"]
async def get_document_number(self, doc_type: str, ref_key: str) -> str:
"""Получить номер документа"""
url = f"{self.base}/{doc_type}(guid'{ref_key}')"
result = await self._get(url)
return result.get("Number", "")
Пользователь: создай приход по заказу ЗП-00123
1С-Ассистент:
┌────────────────────────────────────────────────┐
│ Создаю приходную накладную... │
│ │
│ Заказ: ЗП-00123 │
│ Поставщик: ООО "Пиро-Опт" (ИНН 7712345678) │
│ Позиций: 12 │
│ Сумма: 45 600 ₽ │
│ │
│ ✓ Контрагент найден в 1С │
│ ✓ Номенклатура сопоставлена (12/12) │
│ ✓ Документ создан │
│ │
│ Номер: ПН-00456 от 24.12.2025 │
└────────────────────────────────────────────────┘
Пользователь: создай расходные накладные по всем отгруженным заказам за сегодня
1С-Ассистент:
┌────────────────────────────────────────────────┐
│ Найдено заказов со статусом "shipped": 8 │
│ │
│ [1/8] Заказ OZON-12345 → РН-00789 ✓ │
│ [2/8] Заказ WB-67890 → РН-00790 ✓ │
│ [3/8] Заказ SITE-111 → РН-00791 ✓ │
│ ... │
│ [8/8] Заказ OZON-12350 → РН-00796 ✓ │
│ │
│ Создано документов: 8 │
│ Общая сумма: 127 450 ₽ │
└────────────────────────────────────────────────┘
| Ошибка | Причина | Действие |
|---|---|---|
| Контрагент не найден | Нет в 1С | Предложить создать |
| Номенклатура не найдена | Артикул не совпадает | Показать похожие |
| Документ не создан | Ошибка валидации 1С | Показать детали ошибки |
| Timeout | 1С не отвечает | Retry 3 раза |
| Авторизация | Неверные credentials | Сообщить админу |
Версия: 1.0.0