При разработке системы складского учета в самописной конфигурации или при существенной доработке типовой одним из ключевых архитектурных вопросов является механизм резервирования товаров. На первый взгляд задача кажется простой: нужно пометить товар как «занятый», чтобы его не продал другой менеджер. Однако при росте нагрузки и усложнении бизнес-процессов неправильный выбор структуры данных может привести к фатальному замедлению системы. Рассмотрим подробнее основные варианты реализации, их плюсы и минусы.
Рассмотрим вариант, когда мы добавляем новое измерение (например, ЗаказПокупателя) непосредственно в существующий регистр накопления остатков товаров. На первый взгляд это кажется логичным: у нас есть общая таблица, где мы видим и свободный остаток (где измерение пустое), и зарезервированный (в разрезе конкретных заказов).
Плюсы:
Минусы (критические):
Заказ, и у вас будет 50 000 заказов, количество записей в таблице итогов может вырасти до миллионов. Это приведет к колоссальному замедлению получения остатков и проведения документов.Проанализируем подход с выделением резервирования в отдельную сущность. В этом случае у нас есть регистр ТоварыНаСкладах (физические остатки) и регистр ТоварыВРезерве (информация о том, сколько и под какой заказ забронировано).
Разберем по шагам, как это работает. При поступлении заказа менеджер делает движение «Приход» по регистру ТоварыВРезерве. При отгрузке документ делает «Расход» по физическим остаткам и одновременно «Расход» по резервам.
Преимущества этого метода:
Склад и Серия. В резервах же нам может быть не важно, из какой ячейки или какой серии будет взят товар, но важен Менеджер или ДатаСнятияРезерва. Разделение регистров позволяет не перегружать лишними данными основную таблицу остатков.Посмотрим на пример запроса для получения свободного остатка при такой архитектуре:
ВЫБРАТЬ
Остатки.Номенклатура КАК Номенклатура,
ЕСТЬNULL(Остатки.КоличествоОстаток, 0) - ЕСТЬNULL(Резервы.КоличествоОстаток, 0) КАК СвободныйОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК Остатки
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезерве.Остатки(&Период, ) КАК Резервы
ПО Остатки.Номенклатура = Резервы.Номенклатура
И Остатки.Склад = Резервы.Склад
Выясним, когда уместно использовать вариант с добавлением ресурса ВРезерве в основной регистр. В этом случае структура регистра выглядит так: Измерения (Номенклатура, Склад), Ресурсы (ВНаличии, Зарезервировано).
Этот вариант подходит для систем с «мягким» резервированием, где нам не нужно знать, под какой именно заказ зарезервирован товар в регистрах (эта информация может храниться в самих документах или отдельном справочнике). Свободный остаток в таком случае рассчитывается просто как разность двух ресурсов: ВНаличии - Зарезервировано.
Однако, если бизнес-процесс требует отслеживать сроки резервов, частичное снятие по конкретным заказам или перерезервирование между клиентами, этот метод быстро станет тупиковым из-за отсутствия аналитики по заказам.
Проанализируем ситуацию, когда данные о резервах вообще не пишутся в регистры накопления. Система может рассчитывать резерв «на лету», суммируя количество в документах ЗаказПокупателя, которые еще не закрыты и не отгружены.
Когда это эффективно: Если количество активных (невыполненных) заказов невелико. В этом случае мы экономим на дисковом пространстве и исключаем ошибки рассогласования регистров и документов.
Когда это опасно: Если заказов тысячи, запрос на расчет остатков с учетом резервов превратится в тяжелую операцию сканирования таблиц документов, что недопустимо для оперативной работы менеджера.
В современных ERP-системах часто требуется резервировать товар, которого еще нет на складе, но который уже заказан у поставщика. Реализовать это через измерение в регистре складских остатков невозможно, так как физический остаток еще не возник.
Рассмотрим архитектуру «Запасы и потребности». Это отдельный регистр, где учитываются:
Это наиболее продвинутый вариант, позволяющий реализовать схему Intercompany или резервирование под будущие даты поставки.
Подведем итог нашему анализу. Выбор метода зависит от сложности вашего бизнес-процесса:
При реализации не забывайте о контроле отрицательных остатков. При использовании двух регистров программа должна проверять, чтобы сумма резерва не превышала фактический остаток (если иное не предусмотрено бизнес-логикой, например, для возможности «торговли в минус»).
Для автоматизации снятия просроченных резервов рекомендуем создать регламентное задание, которое будет анализировать даты заказов в отдельном регистре и формировать корректирующие движения, освобождая товар для других покупателей.