В процессе работы с партионным учетом часто возникает задача, выходящая за рамки стандартного списания по методу ФИФО (First-In, First-Out). Представим ситуацию: необходимо провести реализацию товаров, где для части позиций менеджер явно указывает, из какой партии их нужно списать, а для остальных — списание должно пройти по стандартному принципу "первым пришел — первым ушел". Такая задача требует разработки комбинированного алгоритма, который бы сочетал ручное управление и автоматический подбор. Прежде чем приступать к кодингу, полезно провести анализ позиций товаров в документе реализации, чтобы точно понимать историю движений по каждой номенклатуре.
В этой статье мы подробно разберем, как спроектировать и реализовать такой механизм, с какими сложностями можно столкнуться и почему такая задача имеет большую практическую ценность.
Основная сложность заключается в правильном определении последовательности действий. Из обсуждения на форуме и общей логики бизнес-процессов вырисовывается четкий двухэтапный алгоритм, который необходимо реализовать:
Такой подход логичен и соответствует ожиданиям пользователя: сначала выполняются его прямые указания, а затем включается автоматика.
Прежде чем приступать к реализации, проанализируем потенциальные проблемы, которые могут возникнуть.
1. Некорректная сортировка партий при ФИФО
Классическая ошибка, на которую часто наталкиваются начинающие разработчики. Если партии имеют строковые наименования вида "П1", "П2", ..., "П10", "П11", то простая сортировка по наименованию приведет к неверному результату. При алфавитной (строковой) сортировке "П11" будет идти раньше, чем "П2".
2. Реализация всей логики одним запросом
Для оптимизации производительности и избежания медленной обработки данных в циклах 1С, подобные задачи принято решать в одном пакетном запросе. Это позволяет минимизировать количество обращений к базе данных. Такой подход требует уверенного владения языком запросов, в частности, использования временных таблиц (ВТ) и объединений (ОБЪЕДИНИТЬ ВСЕ).
Рассмотрим по шагам, как можно построить запрос для решения нашей задачи. Будем активно использовать временные таблицы для хранения промежуточных результатов.
Нам понадобятся две основные временные таблицы:
ВТ_ТоварыКСписанию — таблица, содержащая номенклатуру, характеристику и количество из табличной части документа-регистратора. Важно добавить поле Партия, которое будет заполнено для строк с ручным указанием и пустым для остальных.ВТ_ОстаткиПартий — таблица с актуальными остатками товаров в разрезе партий. Логика её получения во многом опирается на остатки товаров организаций с себестоимостью и датами последних закупок. Обязательно получаем поле МоментВремени документа-партии и сортируем эту таблицу по нему для последующего использования в ФИФО.Теперь реализуем первую часть нашего алгоритма.
ВТ_СписаниеУказанныхПартий.ВТ_ТоварыКСписанию (только строки, где Партия заполнена) с ВТ_ОстаткиПартий по номенклатуре и партии.ВЫБОР:
Остаток >= Требуется, Тогда списываем Требуется.Остаток.На этом этапе мы формируем общую потребность для списания по ФИФО и обновляем остатки партий.
ВТ_ПотребностьФИФО, куда попадают остатки нераспределенного товара.ВТ_ОстаткиДляФИФО. В нее помещаем остатки партий, вычитая те количества, которые мы списали на шаге 2.Это самый сложный этап. Основная идея — рассчитать накопительный итог по остаткам партий и сопоставить его с потребностью. Эффективно реализовать движения товаров с резервами нарастающим итогом можно через функции СКД или сложные соединения в запросе.
ВТ_СписаниеФИФО).Финальный шаг — собрать все результаты воедино.
ВЫБРАТЬ
Номенклатура,
Партия,
Количество
ИЗ
ВТ_СписаниеУказанныхПартий
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Номенклатура,
Партия,
Количество
ИЗ
ВТ_СписаниеФИФО
Этот итоговый запрос вернет полный список движений.
Несмотря на то, что такая задача может показаться усложненной, она имеет прямое отношение к реальным бизнес-процессам:
Таким образом, разработка гибкого механизма списания — это полезный инструмент, повышающий управляемость и прозрачность складского учета.