Разберем интересную и довольно распространенную задачу, которая часто встречается на собеседованиях или при подготовке к экзамену «1С:Специалист по платформе», а также в реальной практике компаний, занимающихся сдачей оборудования в аренду.
Суть задачи: Имеется документ «Аренда мебели». Он должен списывать мебель со склада в момент выдачи (дата монтажа) и возвращать ее обратно в момент окончания аренды (дата демонтажа). Количество выданной мебели всегда равно количеству возвращенной. При этом даты выдачи и возврата, как правило, находятся в будущем относительно даты создания документа. Самая главная проблема — при проведении документа необходимо контролировать остатки на складе с учетом того, что в выбранный период могут существовать другие оформленные документы аренды (пересечение периодов).
Проанализируем ситуацию и рассмотрим несколько подходов к решению этой задачи, от лобовых до более методологически правильных.
Самый прямолинейный подход, который первым приходит на ум — заставить один документ делать движения по регистру накопления (например, ОстаткиТоваров) разными датами.
Посмотрим на алгоритм формирования движений:
Однако при таком подходе возникает сложность с контролем остатков. Обычный срез остатков на дату документа здесь не работает, так как движения происходят в будущем, и периоды разных документов могут накладываться друг на друга.
Как реализовать контроль остатков при таком подходе?
Нам необходимо вычислить нарастающий итог по всем движениям в будущем, чтобы убедиться, что ни в один из дней доступный остаток не уходит в минус. Разберем по шагам алгоритм проверки:
Этот метод рабочий, но имеет недостаток: запись движений будущим числом ломает механизм оперативных итогов платформы. В реальных высоконагруженных базах от такого подхода стараются уходить.
Чтобы не портить партионный учет и текущие остатки движениями из будущего, методологически правильнее разделить фактический складской учет и контур планирования (бронирования).
Рассмотрим подход с использованием непериодического регистра сведений для контроля занятости оборудования. Назовем его, например, ЗанятостьОборудования.
Структура регистра сведений:
Номенклатура (или конкретный инвентарный номер, если ведется пообъектный учет), ДокументРезерва.ДатаНачала, ДатаОкончания.Количество.При проведении документа «Аренда мебели» мы не трогаем регистры складских остатков, а делаем запись в наш регистр сведений, указывая период бронирования и количество.
Как контролировать остатки при наложении периодов?
В этом случае проверка становится гораздо элегантнее. Нам нужно найти все уже существующие брони, которые пересекаются с периодом нашего нового документа. Два периода пересекаются, если выполняется простое математическое условие:
ДатаНачалаВБазе < ДатаОкончанияНовойАренды И ДатаОкончанияВБазе > ДатаНачалаНовойАренды
Разберем алгоритм проведения с контролем по регистру сведений:
ЗанятостьОборудования с условием на пересечение дат, описанным выше.СвободныйОстаток - ПиковыйРезерв - КоличествоВДокументе < 0, выдаем отказ.Если задача требует именно механизмов регистров накопления, создадим отдельный регистр ОжидаемаяАренда (вид регистра — остатки).
В этом регистре мы будем хранить не текущие остатки, а график изменения свободных остатков.
При проведении документа делаем движения:
Контроль остатков в этом случае сводится к получению остатков по виртуальной таблице Остатки регистра ОжидаемаяАренда на каждую дату изменения в пределах периода нового документа. Это так называемая «новая методика» контроля остатков, но адаптированная под проверку нескольких временных срезов.
При решении задач с будущими периодами и арендой важно понимать, что запись движений будущим числом в основной товарный регистр — плохая практика для реальных конфигураций (таких как 1С:ERP или 1С:УТ). Для учебной задачи «в лоб» подойдет расчет нарастающего итога. Однако для качественной архитектуры мы рекомендуем выделять планирование в отдельные сущности: регистры сведений с периодами бронирования или обособленные регистры накопления для графиков доступности.