Работа с маркированным алкоголем ставит перед бизнесом и автоматизаторами сложную дилемму. С одной стороны, тотальное сканирование каждой бутылки на приемке требует колоссальных временных и человеческих ресурсов, особенно когда речь идет о поставках в тысячи или десятки тысяч бутылок. С другой стороны, приемка «вслепую» (так называемая доверительная приемка) грозит пересортом марок, блокировкой продаж на кассовых узлах и суровыми штрафами от регулирующих органов.
В этой статье мы подробно проанализируем существующие подходы к сканированию алкогольной продукции (АП) при приемке, разберем аппаратные средства интеграции и выясним, как спроектировать и оптимизировать базу данных 1С, когда количество записей об акцизных марках начинает исчисляться десятками миллионов.
В зависимости от формата бизнеса (крупный опт, дистрибуция, розничная сеть или единичные магазины) применяются различные политики контроля поступающей продукции. Рассмотрим их подробнее:
Для мобильной работы на складе традиционно используются терминалы сбора данных (например, марки семейства Urovo, Honeywell, Zebra). Программное обеспечение ТСД работает в связке с WMS (системой управления складом) через web-сервисы в режиме реального времени (онлайн-обмен). Рассмотрим типичный сценарий проверки:
В момент сканирования штрихкода на складе мобильное приложение не обращается к глобальной системе ЕГАИС напрямую. ТСД отправляет запрос во внутреннюю WMS, где проверяется:
Если проверка проходит успешно, марка привязывается к документу поступления во внутренней базе данных 1С для последующей отправки подтверждения в ЕГАИС.
Когда оптовая или розничная компания работает с алкоголем длительное время, объем регистра сведений, хранящего статусы и движения акцизных марок, лавинообразно растет. Накопление 10–50 миллионов записей в периодическом регистре сведений может привести к драматическому падению производительности систем на платформе 1С:Предприятие 8.3.
Выясним причину замедления. Как правило, разработчики по умолчанию используют виртуальную таблицу СрезПоследних для проверки текущего состояния марки перед ее отгрузкой или продажей. При объемах базы в десятки миллионов записей СУБД (например, MS SQL Server или PostgreSQL) при обращении к СрезПоследних часто строит неоптимальный план запроса, генерируя тяжелые операции типа Table Spool (создание временных таблиц на диске), что приводит к зависанию проведения документов.
Разберем по шагам, как решить эту проблему и добиться проведения документов на 15 000–20 000 марок всего за несколько секунд:
Вместо использования виртуальной таблицы СрезПоследних для периодического регистра сведений рекомендуется применять соединение с временной таблицей максимальных дат (периодов), отобранных по конкретному списку марок. Это позволяет СУБД использовать наиболее эффективные индексы.
Проанализируем пример оптимального запроса для получения актуального статуса пакета марок:
// Помещаем список проверяемых марок во временную таблицу для ограничения выборки
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТЧ_Марки.Марка КАК Марка
|ПОМЕСТИТЬ ВТ_ПроверяемыеМарки
|ИЗ
| &ТаблицаМарок КАК ТЧ_Марки
|;
|////////////////////////////////////////////////////////////////////////////////
|// Выбираем максимальные даты движений только по интересующим нас маркам
|ВЫБРАТЬ
| СостоянияМарок.Марка КАК Марка,
| МАКСИМУМ(СостоянияМарок.Период) КАК МаксПериод
|ПОМЕСТИТЬ ВТ_МаксДаты
|ИЗ
| РегистрСведений.СостоянияМарок КАК СостоянияМарок
|ГДЕ
| СостоянияМарок.Марка В (ВЫБРАТЬ Марка ИЗ ВТ_ПроверяемыеМарки)
|ГРУППИРОВАТЬ ПО
| СостоянияМарок.Марка
|;
|////////////////////////////////////////////////////////////////////////////////
|// Соединяем полученные срезы с физической таблицей регистра для получения статусов
|ВЫБРАТЬ
| ВТ_МаксДаты.Марка КАК Марка,
| РегСостояния.Состояние КАК Состояние,
| РегСостояния.Регистратор КАК Регистратор
|ИЗ
| ВТ_МаксДаты КАК ВТ_МаксДаты
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияМарок КАК РегСостояния
| ПО ВТ_МаксДаты.Марка = РегСостояния.Марка
| И ВТ_МаксДаты.МаксПериод = РегСостояния.Период";
Этот подход гарантирует стабильно высокую скорость работы запроса вне зависимости от общего количества записей в регистре (хоть 5 миллионов, хоть 100 миллионов), так как поиск осуществляется строго по индексу ключевого поля марки.
Еще один проверенный метод оптимизации — разделение данных. Для оперативной проверки статусов марок при продаже и перемещении нам нужны только актуальные записи (те марки, которые сейчас физически находятся на остатках).
Мы можем создать плоский, непериодический регистр сведений РегистрСведений.АктуальныеМаркиНаОстатках, где ключом будет выступать сама Марка. В момент списания, продажи или выбытия марка просто удаляется из этого регистра. Для детального аудита и разбора спорных ситуаций все движения пишутся в параллельный, защищенный от частых транзакций архивный регистр истории движений марок.
В розничной сети крайне важно, чтобы кассир мог пробить чек мгновенно. Задержка даже в 2 секунды на проверку марки в центральной базе 1С по сети в час-пик создаст огромные очереди.
Для оптимизации этого процесса рекомендуется выгружать плоский список («белый список») разрешенных к продаже марок напрямую в локальную базу кассового софта (например, Frontol или специализированную локальную базу на СУБД SQLite/PostgreSQL). Касса моментально валидирует марку локально перед отправкой чека в ЕГАИС, минимизируя нагрузку на центральный сервер 1С.
Автоматизация приемки алкоголя — это всегда баланс между скоростью работы склада и минимизацией рисков получения штрафов. Комбинирование выборочного и тотального сканирования с помощью ТСД закрывает бизнес-риски пересорта. С технической стороны, грамотная работа с СУБД, отказ от стандартного использования СрезПоследних в пользу временных таблиц и разделение оперативного контура от архивного позволяют системе на базе 1С стабильно функционировать на базах любого масштаба.