В конфигурации 1С:Управление производственным предприятием (УПП) при использовании расширенной аналитики учета затрат (РАУЗ) часто возникает задача детализации резервов. Стандартный регистр накопления РезервыТоваровНаСкладах хранит информацию в разрезе складов, номенклатуры и заказов, но он не содержит в себе измерения «Документ резервирования». Это означает, что если в рамках одного заказа было сделано несколько документов Резервирование товаров, а затем часть резерва была снята, система покажет лишь общий остаток по заказу.
В данной статье мы разберем, как с помощью программных методов и механизмов запросов вычислить, какие именно документы «наполняют» текущий остаток резерва, используя логику FIFO (First In, First Out).
Проанализируем ситуацию: в регистре РезервыТоваровНаСкладах движения по приходу делают документы резервирования, а движения по расходу — документы снятия резерва или реализации. Поскольку в измерениях нет ссылки на конкретную партию резерва, нам необходимо сопоставить хронологию событий. Если на текущий момент по заказу числится 14 единиц товара, а документов резервирования было на 20 единиц, нам нужно «отсечь» первые 6 единиц, которые были сняты или проданы ранее.
Рассмотрим по шагам, как реализовать этот механизм в запросе.
Для начала нам необходимо получить таблицу всех движений (приходов и расходов) по интересующей номенклатуре и заказу. Важно упорядочить эти данные по моменту времени, чтобы соблюсти хронологию FIFO.
Выясним причину, по которой обычный срез последних здесь не поможет: нам нужны не только итоговые цифры, но и вся цепочка событий. Мы будем использовать таблицу движений РегистрНакопления.РезервыТоваровНаСкладах.
ВЫБРАТЬ
Резервы.Период КАК Период,
Резервы.Регистратор КАК Регистратор,
Резервы.Номенклатура КАК Номенклатура,
Резервы.Заказ КАК Заказ,
ВЫБОР
КОГДА Резервы.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход)
ТОГДА Резервы.Количество
ИНАЧЕ 0
КОНЕЦ КАК КоличествоПриход,
ВЫБОР
КОГДА Резервы.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияНакопления.Расход)
ТОГДА Резервы.Количество
ИНАЧЕ 0
КОНЕЦ КАК КоличествоРасход,
Резервы.МоментВремени КАК МоментВремени
ПОМЕСТИТЬ ВТ_Движения
ИЗ
РегистрНакопления.РезервыТоваровНаСкладах КАК Резервы
ГДЕ
Резервы.Номенклатура = &Номенклатура
И Резервы.Заказ = &Заказ
;
Теперь проанализируем ситуацию с накоплением. Чтобы понять, какие документы прихода еще «живы», нам нужно рассчитать нарастающий итог для каждого прихода и сравнить его с общей суммой всех расходов по этому же заказу.
Рассмотрим подробнее логику: документ прихода считается закрытым, если сумма всех предшествующих ему расходов больше или равна сумме этого прихода и всех приходов до него. Это классическая задача на FIFO в запросе.
ВЫБРАТЬ
Т1.Регистратор КАК ДокументРезервирования,
Т1.КоличествоПриход КАК КоличествоВДокументе,
СУММА(Т2.КоличествоПриход) КАК НакопленныйПриход,
(ВЫБРАТЬ СУММА(ИтогоРасход.КоличествоРасход) ИЗ ВТ_Движения КАК ИтогоРасход) КАК ОбщийРасход
ПОМЕСТИТЬ ВТ_Сопоставление
ИЗ
ВТ_Движения КАК Т1
ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Движения КАК Т2
ПО Т1.Номенклатура = Т2.Номенклатура
И Т1.Заказ = Т2.Заказ
И Т1.МоментВремени >= Т2.МоментВремени
ГДЕ
Т1.КоличествоПриход > 0
ГРУППИРОВАТЬ ПО
Т1.Регистратор,
Т1.КоличествоПриход,
Т1.МоментВремени
;
На заключительном этапе нам нужно вычислить, какая часть количества из каждого документа Резервирование товаров входит в итоговый остаток. Для этого мы вычитаем из накопленного прихода общий расход. Если результат отрицательный — документ полностью погашен расходом. Если результат больше нуля, но меньше количества в самом документе — документ погашен частично.
Посмотрим на пример расчета в запросе:
ВЫБРАТЬ
Т.ДокументРезервирования,
ВЫБОР
КОГДА Т.НакопленныйПриход <= Т.ОбщийРасход
ТОГДА 0
КОГДА Т.НакопленныйПриход - Т.КоличествоВДокументе >= Т.ОбщийРасход
ТОГДА Т.КоличествоВДокументе
ИНАЧЕ Т.НакопленныйПриход - Т.ОбщийРасход
КОНЕЦ КАК ОстатокРезерваПоДокументу
ИЗ
ВТ_Сопоставление КАК Т
ГДЕ
(ВЫБОР
КОГДА Т.НакопленныйПриход <= Т.ОбщийРасход
ТОГДА 0
КОГДА Т.НакопленныйПриход - Т.КоличествоВДокументе >= Т.ОбщийРасход
ТОГДА Т.КоличествоВДокументе
ИНАЧЕ Т.НакопленныйПриход - Т.ОбщийРасход
КОНЕЦ) > 0
При работе с этим алгоритмом в 1С:УПП следует учитывать несколько критически важных моментов:
МоментВремени для сравнения в соединениях. Использование только даты (периода) приведет к ошибкам, если в одну секунду было проведено несколько документов.Корректировка записей регистров могут вносить приходы и расходы без прямой логики резервирования. Убедитесь, что ваш запрос учитывает все виды движений по регистру РезервыТоваровНаСкладах.Мы разобрали, как получить данные о документах-основаниях резерва, когда типовой функционал предоставляет только общие остатки. Метод FIFO в запросе является наиболее надежным способом восстановления цепочки событий в учетных системах 1С. Реализовав подобную логику, вы сможете не только видеть остатки, но и контролировать сроки резервов, вычислять их «возраст» и вовремя снимать просроченные брони.