Привет, индустрия! Я бухгалтер‑калькулятор в общепите. Программа, с которой я работаю, называется StoreHouse5. Каждый день через мои руки проходят тонны первички, приходных накладных от поставщиков, чаще в бумажном виде.
Все вокруг кричат про тотальную цифровую трансформацию, маркировку и ЭДО. Наш ресторан купил красивое готовое решение для импорта документов/поставок, из ЕГАИС в StoreHouse, и импорт документов/поставок из ЭДО в StoreHouse, и другое.
Круто? Да, но только на бумаге.
Крупные федеральные поставщики присылают документы в ЭДО или ЕГАИС, каждый день. Эти документы спокойно импортируются в StoreHouse. А вот мелкие локальные контрагенты (крафтовые производители зелени, сыроварни, поставщики свежего мяса) до сих пор живут в прошлом веке. Им ЭДО не обязателен. Максимум, на что они способны — забить накладную в свой Excel и скинуть менеджеру в Telegram, самый плохой вариант — это мягкие накладные, написанные непонятным почерком.
Итог: каждый день бухгалтер‑калькулятор вынужден руками вбивать по 100–300 строк в StoreHouse. Глаза слезятся, время уходит, риск опечататься в ценах или количестве — огромный. В какой‑то момент мне это надоело, и я решил: хватит это терпеть, в век всеобщей цифровизации!
Я никогда не был программистом, один бы такое не написал. Взял в соавторы ИИ‑ассистента DeepSeek — китайская нейросеть с открытым исходным кодом, четко объяснил ему логику работы калькулятора, дал прочитать статьи разработчиков с их сайта. Арендовал у дилера сервер SH5 с WebApi, с правами администратора. И мы начали кодить и тестить. На разработку, тесты и полировку ушло 3 месяца неторопливого труда. По вечерам, дома, после работы, когда было желание покодить с нейросетью. Сегодня моя система работает, вместо 2 часов монотонного ада, внесения товаров из excel в StoreHouse, я нажимаю одну кнопку — и 100 строк ТОРГ-12 мгновенно улетают в StoreHouse.
Рассказываю, как устроен мой «Робот‑Бухгалтер».
Идея и архитектура: почему нельзя просто залить Excel в SH5
Каждый, кто хоть раз работал со словарями Store House 5, знает главную боль: разница в наименованиях.
У фермера в Excel написано «Сыр Моцарелла ф‑ма 1кг», а в номенклатуре SH5 этот товар заведен как «Сыр Моцарелла». SH5 в стандартном режиме не умеет импортировать справочники товаров из Excel напрямую.
По документации SH5 умеет загружать только документы, и то через сервис rkDExch — из почты. Прямой импорт товаров из Excel — только для видов алкоголя, и то с версии 5.153.811. Мне это не подходило. Мне нужно было решение, которое умеет сопоставлять товары, помнить эти связи и не плодить дубли. Мы с ИИ спроектировали классический ETL‑процесс (Extract‑Transform‑Load) и развернули безопасный контур:
Extract (Извлечение): Программа забирает Excel‑файл, присланный поставщиком из определенной папки.
Transform (Трансформация): Данные проверяются через промежуточную базу сопоставлений (PostgreSQL).
Load (Загрузка): Чистый, проверенный, распарсенный документ отправляется напрямую в систему, по json запросу.
Чтобы не рисковать работающей базой данных ресторана, я арендовал у нашего дилера R‑Keeper тестовый сервер StoreHouse 5 в облаке. Вся остальная экосистема крутилась локально на моем домашнем компьютере.
Стек технологий, или из чего собран Робот‑Бухгалтер
Весь софт написан на Python 3.12 и собран полностью из бесплатных библиотек с открытым исходным кодом:
Streamlit — моя главная находка. Он позволил мне, человеку без знаний HTML, CSS и JavaScript, развернуть полноценный, красивый и современный веб‑интерфейс прямо в браузере.
PostgreSQL — надежная база данных. Она стала тем самым «умным мостом», где хранятся связи между названиями товаров у поставщика и внутренними кодами StoreHouse. Также она хранит всю историю загрузок и детализацию по каждой накладной, что позволит в будущем, пользоваться аналитикой самого streamlit.
Pandas + openpyxl/xlrd — математическое ядро, которое за долю секунды парсит и переваривает любые таблицы.xls и.xlsx.
SH5 Web API + Requests — официальный шлюз, через который мой скрипт общается с сервером R‑Keeper с помощью HTTP‑запросов.
Как это работает на практике: победа над рутиной
Ежедневный процесс работы теперь выглядит модно и технологично:
Я сохраняю Excel‑файл ТОРГ-12 от поставщика из Telegram в папку IN, приложение смотрит эту папку.
Открываю браузер, где меня встречает лаконичная вебка моего приложения. Слева отображаются все файлы в папке для загрузки. Выбираю файл, указываю поставщика и склад получателя (если тот же поставщик, то выбирать уже не надо, вебка запоминает последнее действие). Отображается номер накладной, дата, и сумма. Если ТТН принята без расхождений нажимаю кнопку «Отправить в Store House 5». Если с расхождениями, то в этом же веб документе, меняю количество, сумма сама пересчитывается.
Я сохраняю Excel‑файл ТОРГ-12 от поставщика из Telegram в папку IN, приложение смотрит эту папку.
Открываю браузер, где меня встречает лаконичная вебка моего приложения. Слева отображаются все файлы в папке для загрузки. Выбираю файл, указываю поставщика и склад получателя (если тот же поставщик, то выбирать уже не надо, вебка запоминает последнее действие). Отображается номер накладной, дата, и сумма. Если ТТН принята без расхождений нажимаю кнопку «Отправить в StoreHouse 5». Если с расхождениями, то в этом же веб документе, меняю количество, сумма сама пересчитывается.

Сверка с базой Система мгновенно считывает строки и сверяет их с базой PostgreSQL.
Интерфейс подсвечивает статус визуальными анкорами:
🟢 Зеленый маркер: Товар системе известен, связь подтверждена.
❌ Красный маркер: Поставщик привез новинку, которой еще нет в базе сопоставлений.
Если есть «красные» позиции, я прямо в веб‑интерфейсе один раз вписываю внутренний код (RID) товара из SH5 и нажимаю «Сохранить связи». PostgreSQL запоминает эту связку навсегда. В следующий раз автоматика сделает всё сама.
Так в этом же окне веб интерфейса, можно пересчитать товары, которые поставщик привозит штучно, а в SH5 они весом, или на оборот, в поле «пересчет» проставляю «как есть», «умножить», «разделить».
Вот как выглядит ядро робота сопоставлений в PostgreSQL.

Каждая строка — связка: как называет товар поставщик > какой RID у него в SH5.
Вишня свежая > 3752.
Алыча свежая > 3703.
Кедровые орехи > 726.
Если завтра поставщик напишет Вишня св — робот найдёт связь и подставит тот же RID.
Робот ведёт журнал загрузок — кто, когда, куда, на какую сумму
Каждая отправка пишется в историю: номер накладной, дата, поставщик, склад, сумма, количество товаров, статус. Это основа будущей аналитики — после каждой выгрузки можно посмотреть динамику закупок или обороты по поставщикам.

А вот детализация — что именно было в накладной
Здесь каждая строка каждой накладной: товар, RID, количество, цена, сумма. Именно отсюда можно достать информацию: цена моркови вчера vs сегодня или среднюю цену на арбузы за лето.

8. Далее, нажимаю кнопку «Сохранить связи» и «Отправить в StoreHouse 5». Скрипт формирует JSON‑запрос, передает заголовки, склады, корреспондентов, рассчитывает коэффициенты и единицы измерения, после чего вызывает процедуру InsGDoc0 через Web API.
30 Секунд — и накладная на 100 строк со 100% точностью цен уже лежит в журнале приходных документов Store House, в неактивном виде. Без ручного ввода, без опечаток.
9. Но путь был нелёгким. Вот лишь несколько проблем, через которые мы прошли:
Ошибка 183 — «нет прав». Думали, что у пользователя нет доступа к складам. Оказалось — накладная ложилась на склад по умолчанию, потому что мы передавали ID склада не в то поле. Как только поменяли 172\1 на 105#1\1 — всё заработало.
Ошибка 37 — «объект не найден». Оказалось, что поле 105#1\1 (склад‑получатель) на боевом сервере и на тестовом — разные ID. Мы хардкодили значение с тестового, а на боевом оно просто не существовало.
Ошибка 84 — «нарушение целостности». Цена и сумма — это разные поля. Мы передавали цену в поле, которое SH5 считает суммой. Итог: накладная создавалась, но цены в ней были пересчитаны неверно. Поменяли — и всё сошлось.
Ошибка 1007 — «бизнес‑логика». Товар передавался в единицах измерения, которые ему не назначены. Например, абрикос в SH5 измеряется в килограммах, а мы передали штуки. Пришлось сделать функцию get_good_unit_rid, которая сама подтягивает правильную единицу измерения для каждого товара.
Пример того, как мы вайбкодили: 3 месяца диалога с нейросетью
Я не программист и не знаю синтаксис Python, не умею писать циклы, функции и классы. Но умею ставить задачи и отсылать логи обратно (копипастить).
DeepSeek умеет писать код. Мы работали в цикле:
Я описываю проблему. «Накладная создаётся, но ложится не на тот склад. Вот лог ошибки».
DeepSeek пишет скрипт. Присылает json запрос в теле чата, что вставить в test.py, который проверяет разные варианты.
Я запускаю в консоле python test.py
Копирую вывод обратно. «Ошибка 37. Вот что вернулось».
DeepSeek анализирует. «Значит, поле 105#1\1 — это склад. Попробуй передать RID‑склада».
Я запускаю снова. «Получилось!»
Пример общения ниже. Это мы создавали две тестовые накладные, дата, номер, поставщик, склад приемщик, без позиций и цен.
import requests import json SH5_API_URL = "сервер:порт/api/sh5exec" SH5_USER = "имя" SH5_PASS = "пароль" # Создаём тестовую накладную БЕЗ указания склада print("=== Создаём TEST-DELETE-1 (без склада) ===") payload = { "UserName": SH5_USER, "Password": SH5_PASS, "procName": "InsGDoc0", "Input": [ { "head": "111", "original": ["33", "31", "100\\1", "34", "35", "105\\1", "105#1\\1", "3"], "values": [ [0], ["2026-10-06"], [0], [1], [1], [213], [RID-склада2], ["TEST-DELETE-1"] ] }, { "head": "112", "original": ["210\\1", "210\\206\\1", "212\\9", "213\\9", "31", "40", "41", "42", "32"], "values": [ [3629], [5], [0], [0], [10], [1500], [0], [0], [0] ] } ] } r = requests.post(SH5_API_URL, json=payload, timeout=30) data = r.json() print(json.dumps(data, indent=2, ensure_ascii=False)[:500]) # Создаём тестовую накладную на Кухню ресторана print("\n=== Создаём TEST-DELETE-2 (Кухня ресторана) ===") payload2 = { "UserName": SH5_USER, "Password": SH5_PASS, "procName": "InsGDoc0", "Input": [ { "head": "111", "original": ["33", "31", "100\\1", "34", "35", "105\\1", "105#1\\1", "3"], "values": [ [0], ["2026-10-06"], [0], [1], [1], [213], [RID-склада], ["TEST-DELETE-2"] ] }, { "head": "112", "original": ["210\\1", "210\\206\\1", "212\\9", "213\\9", "31", "40", "41", "42", "32"], "values": [ [3629], [5], [0], [0], [10], [1500], [0], [0], [0] ] } ] } r2 = requests.post(SH5_API_URL, json=payload2, timeout=30) data2 = r2.json() print(json.dumps(data2, indent=2, ensure_ascii=False)[:500])
Когда команда отработала, я выделил все сообщение и переслал обратно в чат с DeepSeek.
(venv) F:\SH5_test>python test.py === Создаём TEST-DELETE-1 (без склада) === { "errorCode": 0, "errMessage": "OK", "Version": "1.12", "UserName": "Имя", "actionName": "InsGDoc0", "actionType": "Execute", "shTable": [ { "head": "111", "recCount": 1, "original": [ "4", "33", "31", "111\\1", "100\\1", "100\\2", "34", "35", "38", "117\\1", "117\\5", "117\\3", "117\\31", "179\\1", "179\\3", "172\\1", === Создаём TEST-DELETE-2 (Кухня ресторана) === { "errorCode": 0, "errMessage": "OK", "Version": "1.12", "UserName": "Имя", "actionName": "InsGDoc0", "actionType": "Execute", "shTable": [ { "head": "111", "recCount": 1, "original": [ "4", "33", "31", "111\\1", "100\\1", "100\\2", "34", "35", "38", "117\\1", "117\\5", "117\\3", "117\\31", "179\\1", "179\\3", "172\\1", (venv) F:\SH5_test>
В самом начале, когда только прочли статьи разработчиков, процесс шел медленнее. Мог 10 раз за вечер, методом перебора, присылать ему ответы консоли с ошибками, он думал где мы не правильно ставили риды, присылал новые запросы. Но каждый раз мы становились на шаг ближе.
Это и есть вайбкодинг. Не «ИИ написал программу», а «ИИ + эксперт = результат». Я знаю бизнес‑логику, ИИ знает синтаксис. Вместе — сделали то, что я один не потянул бы.
Вместо вывода: ИИ не заменит человека, он заменит рутину
Когда я только начинал, я сомневался, сможет ли — обычный бухгалтер — создать что‑то подобное. Но ИИ‑ассистенты помогли мне понять важную вещь: в современном мире не обязательно зубрить синтаксис языков программирования. Самое главное открытие: ИИ не требует от тебя быть программистом. Он требует быть экспертом в своей области. Я знаю, как работает бухгалтерия — ИИ знает, как работает Python. Вместе мы закрыли эту дыру.
Проект работает, развивается, и у меня уже есть планы на будущее: расширить внутреннюю аналитику цен в веб‑интерфейсе и полностью автоматизировать приход и списание.
Профессиональные разработчики наверняка найдут в моей архитектуре кучу костылей и дыр. Но для бизнеса важен результат: система работает, она обошлась в небольшую сумму за аренду облачного сервера StoreHouse 5.
Зато экономит вагон времени.
Коллеги‑рестораторы и бухгалтеры, сталкиваетесь ли вы с такой же проблемой «ручных» накладных от мелких поставщиков? Как решаете её у себя? Давайте обсудим в комментариях!

