От фото накладной до приходной в 1С:УНФ за 3 секунды

Содержание
  1. Проблема
  2. Как обычно
  3. Как это работает в ScanFlow
  4. Что важно учесть
  5. FAQ
  6. Что дальше

Сценарий, ради которого мы вообще делаем ScanFlow, звучит просто: сфотографировал накладную — увидел приходную в 1С:УНФ. Без ручного ввода контрагента, без построчного выбора номенклатуры, без перепечатывания цены и количества. Эта статья — про то, что лежит между «фото» и «документом проведён»: какой REST-контракт мы предлагаем 1С, как сопоставляется номенклатура и почему НДС считается по дате документа, а не по сегодняшней ставке.

Если вас интересует, что происходит до этого этапа — как из фотографии получается структурированный JSON — у нас есть отдельный разбор OCR-пайплайна. Здесь мы исходим из того, что данные уже распознаны и лежат в нашей базе. Дальше — интеграция.

Проблема: ручной ввод накладных съедает час в день

В небольшом оптовом бизнесе бухгалтер обрабатывает 20-50 накладных в день. На каждую в 1С:УНФ уходит от одной до трёх минут: открыть скан, найти контрагента (или создать нового), выбрать тип документа, заполнить шапку, построчно ввести позиции, сверить итог. Умножаем: от 30 минут до 2.5 часов чистого времени ежедневно уходит на перенос букв и цифр с бумаги в систему.

Это не редкая ситуация. Это норма для любой розницы и опта, где приёмка идёт по бумаге — а в России это до сих пор большинство случаев. Транспортные компании, общепит, продуктовые магазины, мелкооптовые поставщики стройматериалов: все они работают с физическими накладными, потому что водитель не несёт в кабине ноутбук, а кладовщик не подписывает приёмку планшетом.

Час в день — это не «недопустимо», это просто не масштабируется. Когда поток вырастает с 30 до 80 накладных, бухгалтер либо начинает работать вечерами, либо нанимается второй человек на ту же ручную операцию. Оба варианта — линейный рост издержек на нелинейный рост ошибок: чем больше ввода вручную, тем чаще опечатки.

Как обычно: бухгалтер открывает скан и набивает в УНФ

Классический маршрут одной накладной в 1С:УНФ выглядит так:

  1. Открыть скан или фото на втором мониторе (или вообще на телефоне).
  2. В 1С — раздел ДокументыПриходная накладнаяСоздать.
  3. В шапке: ввести номер и дату документа поставщика, выбрать организацию-получателя, склад.
  4. Найти контрагента в Справочник.Контрагенты. Если поставщик новый — создать карточку, заполнить ИНН/КПП/наименование, желательно подгрузить реквизиты по ИНН (отдельный сервис ФНС или DaData).
  5. В табличной части — построчно: Подбор по Справочник.Номенклатура, ввод количества, цены, проверка суммы.
  6. Сверить ИТОГО и НДС с тем, что в накладной.
  7. Записать, провести, прикрепить скан.

На каждом шаге есть человек, и каждый человек ошибается. Категории ошибок, которые мы видим в потоке клиентов до подключения автоматизации:

  • Опечатки в количестве и цене. Особенно при переключении между раскладками и при двусмысленных цифрах в рукописных правках. «12» вместо «1,2» — банально, но катастрофично для остатков.
  • Переставленные местами цифры. «3 482» → «3 842». Никакая визуальная проверка не ловит это надёжно: глаз привыкает к шаблону и пропускает перестановки в середине числа.
  • Не та ставка НДС. Бухгалтер по привычке ставит 20%, хотя накладная датирована 2025+ годом и должна идти с 22% — или наоборот, документ из 2018 года с 18% ставится с актуальной ставкой.
  • Неправильный контрагент. «ИП Иванов» в системе оказывается тремя разными карточками — потому что разные люди заводили их с разными вариантами ИНН/наименования. Дальше отчётность по поставщику собирается частями.
  • Перепутанная номенклатура. «Молоко 3.2%» в накладной поставщика и «Молоко 3.2%» в карточке 1С — это могут быть две разные SKU с разной фасовкой. Если в подборе выбрали «соседа» — остатки начнут уезжать.

Каждая из этих ошибок — это либо потерянное время на сверку через неделю, либо неправильные остатки и не сошедшийся учёт в конце месяца. Цена ошибки тихо растёт.

Как это работает в ScanFlow

Архитектурно мы решаем эту задачу не «плагином внутри 1С», а связкой веб-сервис + внешняя обработка. ScanFlow занимается распознаванием и хранением структурированных данных. 1С забирает их по REST и сама создаёт документы — потому что только сама 1С знает, как правильно заполнить движения по регистрам, провести налоговые расчёты и проставить аналитику.

Внешняя обработка `.epf`

После регистрации в личном кабинете пользователь скачивает внешнюю обработку .epf для 1С:УНФ (редакция 1.6 и новее). Открывает в 1С через Файл → Открыть (или в режиме предприятия — Сервис → Доп. отчёты и обработки) и нажимает кнопку «Загрузить». На этом ручная работа заканчивается.

Исходники этой обработки лежат в нашем репозитории в 1c/КНД_ЗагрузкаНакладныхСканер/ в EDT-формате — её можно открыть в 1С:EDT, изучить логику или собрать свою сборку под нестандартную конфигурацию. Это часть нашей политики прозрачности: всё, что 1С делает с вашими данными, можно прочитать в коде.

REST контракт: `/api/invoices/pending` + `/confirm`

Контракт намеренно простой — два endpoint'а и заголовок аутентификации.

1. Обработка опрашивает GET /api/invoices/pending с заголовком X-API-Key (ключ выдаётся каждому пользователю при регистрации и хранится в нашей таблице users). В ответ приходит массив накладных, у которых поднят флаг approved_for_1c = 1: оператор подтвердил их в дашборде ScanFlow, и они готовы к выгрузке. Каждая накладная — это объект с полем items[], реквизитами поставщика, датами, итогами и ссылкой на исходное фото.

2. После того как 1С создала Документы.ПриходнаяНакладная, она вызывает POST /api/invoices/:id/confirm — это коммит: «документ создан, не возвращай мне его в следующем pending». На стороне ScanFlow мы помечаем строку как sent_at = NOW() и больше не показываем её в очереди.

Цены в payload передаются с НДС — это наша конвенция (vision-LLM проще обучить считывать колонку «с НДС», она ярче выделена в типичных накладных). 1С при создании документа ставит флаг СуммаВключаетНДС = Истина и сама корректно раскладывает суммы по проводкам.

Маппинг номенклатуры: Fuse.js fuzzy + Claude LLM

Самая хитрая часть пайплайна — превратить строку «мол. 3.2% Простоквашино» из накладной в конкретный элемент Справочник.Номенклатура с кодом «00-00000123» и единицей «шт». Это нельзя сделать на стороне 1С: там нет ни fuzzy-поиска, ни понимания, что «мол.» — это «Молоко». Поэтому маппинг живёт у нас.

Алгоритм двухступенчатый:

  1. Fuse.js fuzzy match по локальному кешу справочника номенклатуры 1С (мы синхронизируем его через отдельную ручку и держим в таблице onec_nomenclature). Если score ниже порога — высокая уверенность, маппинг проставляется автоматически.
  2. Claude LLM как fallback. Если fuzzy не уверен — отдаём LLM кандидаты из каталога и распознанное название с просьбой выбрать (или сказать «нет совпадения»). Модель видит контекст и обычно справляется там, где Levenshtein путается.

Все подтверждённые маппинги остаются в таблице nomenclature_mappings — индивидуально на пользователя. После первого ручного подтверждения «мол. 3.2% Простоквашино → Молоко питьевое 3.2% Простоквашино 1л» этот же поставщик с этим же написанием больше не задаёт вопросов. Пайплайн учится на каждом операторе и через 2-3 недели работы автоматически справляется с 90%+ номенклатурных позиций знакомых поставщиков.

НДС по дате: `Справочники.СтавкиНДС` — почему важно

В России ставка НДС менялась несколько раз: 18% (до 2019), 20% (2019-2024), 22% (с 2025). Для корректного учёта мы должны проставить в документ ту ставку, которая действовала на дату накладной, а не сегодняшнюю. Это особенно важно при поздней загрузке: если бухгалтер вводит в январе 2026 накладную с декабря 2024 — там должно быть 20%, не 22%.

В 1С:УНФ есть готовый помощник: Справочники.СтавкиНДС.СтавкаНДС(ВидСтавки, Period). Он принимает вид ставки (основная / пониженная / без НДС) и дату — и возвращает ту запись справочника, которая актуальна на этот период. Это правильный путь: историчность ставки решается метаданными конфигурации, а не зашитыми в код константами.

НДС — это не «20% поставить и забыть». Это историчная характеристика документа, и единственный достоверный источник — справочник в самой 1С на дату накладной.

Если жёстко прописать в обработке СтавкаНДС20 — на накладных из 2018 года получится ошибочный расчёт. Если оставить «по умолчанию» — конфигурация может изменить дефолт и сломать историчные документы. Поэтому мы всегда резолвим через справочник.

Что важно учесть

Эти грабли мы наступили в первые месяцы интеграции с 1С:УНФ. Каждая стоила нам ночной отладки. Если будете делать свою обработку — берите готовое решение.

Прикреплять фото через `РаботаСФайлами.ДобавитьФайл`

В старых конфигурациях УНФ есть реквизит ФайлХранилище у документа — кажется, что можно просто записать туда двоичные данные фото. Не делайте этого.

Подводный камень из нашей истории: при записи фото напрямую в ФайлХранилище через ДвоичныеДанные файл сохраняется, но при попытке пользователя открыть его позже из карточки документа 1С показывает ошибку «двоичные данные были удалены». Это известная проблема в современных редакциях УНФ: реквизит формально не deprecated, но его жизненный цикл не совпадает с подсистемой «Работа с файлами», и интерфейс просмотра ищет файл не там.

Правильный способ — использовать стандартную подсистему БСП:

// 1. Двоичные данные фото получаем по URL из ScanFlow
АдресВовременном = ПолучитьИмяВременногоФайла("jpg");
ДвоичныеДанные.Записать(АдресВовременном);

// 2. Передаём в подсистему «Работа с файлами»
Параметры = РаботаСФайламиКлиентСервер.ПараметрыДобавленияФайла();
Параметры.ВладелецФайла = ДокументСсылка;
Параметры.ИмяФайла = "накладная-" + Номер + ".jpg";
РаботаСФайлами.ДобавитьФайл(Параметры, АдресВовременном);

После этого фото видно в карточке документа через стандартный гипершлинк «Файлы (1)», скачивается обратно, индексируется поиском — всё работает как ожидается.

Очерёдность сохранения: сначала контрагент, потом документ

Когда поставщик новый и его нет в Справочник.Контрагенты, нельзя одной транзакцией создать карточку и сразу указать ссылку на неё в шапке накладной. То есть технически можно, но при записи документа 1С спросит ссылку на ещё не записанного контрагента — и упадёт с «ссылка не найдена».

Правильная последовательность:

  1. Проверить Справочник.Контрагенты по ИНН (он у нас есть из распознавания).
  2. Если карточка найдена — взять её ссылку.
  3. Если нет — создать новую: подгрузить реквизиты через DaData по ИНН, заполнить наименование/КПП/банковские реквизиты, записать.
  4. Только после этого создавать Документы.ПриходнаяНакладная и подставлять ссылку на контрагента в шапку.

Это очевидно, когда знаешь — но первая версия обработки делала «всё одной транзакцией» и падала на каждом новом поставщике. Симптом неочевидный: ошибка возникала только при первой накладной от поставщика, при второй уже всё работало (карточка успела создаться при предыдущей итерации).

Что делать с расхождением сумм

В каждой накладной мы кросс-валидируем sum(items.total) и invoice.total_sum. Если расходятся больше чем на 1% — поднимаем флаг items_total_mismatch = 1 и не показываем эту накладную в /api/invoices/pending. Она остаётся в дашборде ScanFlow, оператор разбирается вручную и подтверждает заново.

Соблазн — «пусть автоматически уходит, бухгалтер потом сверит». Никогда не делайте так. Молчаливое расхождение в учётной системе — это балансы, которые не сходятся через неделю, и три часа ретроспективы, чтобы найти, какая накладная виновата. Лучше явный отказ от автозагрузки на этапе, где есть оригинал фото и понятный UX для исправления.

💡

Расписание опроса. В обработке мы рекомендуем запускать /api/invoices/pending по регламентному заданию каждые 5-15 минут — это даёт ощущение «реального времени» без избыточной нагрузки. Чаще одного раза в минуту опрашивать смысла нет: оператор всё равно тратит несколько секунд на нажатие «подтвердить» в дашборде, а 1С при каждом запросе делает локальные проверки и пишет в журнал регистрации.

FAQ

Какая версия УНФ нужна?

1С:Управление нашей фирмой редакции 1.6 и новее. На 1.5 интеграция не поддерживается — там нет нужных методов работы с прикреплёнными файлами через подсистему БСП, а реализовывать собственный обход ФайлХранилище мы сознательно не стали (см. предупреждение выше). Большинство наших клиентов на 1.6.x — это конфигурация, актуальная с 2017 года, до сих пор поддерживаемая и обновляемая.

Что если у меня не УНФ, а ERP или Бухгалтерия?

Из коробки — только УНФ. Но REST-контракт открытый, документация приходит после регистрации, и при желании можно написать свою внешнюю обработку под Бухгалтерию предприятия 3.0, Управление торговлей или ERP 2. Структура документа «Приходная (поступление товаров)» в этих конфигурациях концептуально та же; меняется маппинг полей и подсистема файлов (в БСП-конфигурациях она тоже есть, но называется по-разному). Если у вас стоит такая задача — напишите нам, поделимся уже накопленным шаблоном кода.

Куда смотреть логи если что-то пошло не так?

Два места. На стороне ScanFlow — это PM2: pm2 logs scanflow на нашем сервере, видны конкретные запросы от 1С с timestamp, статусом и payload. В дашборде у каждой накладной есть кнопка «Показать логи»: она показывает события именно по этому документу — когда распознан, когда подтверждён, когда отдан в 1С, когда подтверждена создание. На стороне 1С — журнал регистрации (Все функции → Журнал регистрации), отфильтрованный по нашей обработке. Большинство проблем — это либо неправильный API-ключ (видно по 401), либо проблема с прикреплением фото (видно в журнале 1С).

Что дальше

Накладная теперь приходная в 1С — это половина истории. Вторая половина — оплатить эту накладную поставщику, не открывая интернет-банк руками. Об этом — следующая статья.

Если хотите попробовать пайплайн на своих документах — регистрируйтесь, сейчас бесплатно во время беты, обработка для 1С:УНФ скачивается прямо из личного кабинета.