Как правильно добавить срок годности в документ поступления и связать его с движениями по партиям в 1С

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При автоматизации учета товаров с ограниченным сроком хранения часто возникает задача: зафиксировать дату окончания срока годности непосредственно в документе поступления и сделать так, чтобы эти данные отражались в отчетах по остаткам. Рассмотрим, с какими сложностями можно столкнуться при попытке напрямую добавить реквизит в регистр накопления, где именно формируются движения в конфигурации 1С:Управление производственным предприятием и какие существуют архитектурно грамотные пути решения задачи.

Архитектурные ограничения регистров накопления

Проанализируем структуру регистра накопления и то, как платформа 1С обрабатывает различные типы полей:

  1. Реквизиты регистра накопления: служат исключительно для хранения дополнительной справочной информации по конкретной записи (строке движения). Они не индексируются и не участвуют в формировании виртуальных таблиц Остатки и ОстаткиИОбороты. Соответственно, стандартный отчет, построенный по виртуальным таблицам остатков, не сможет сгруппировать количество товара по сроку годности. Получить остатки в разрезе реквизита можно только «тяжелым» запросом к физической таблице движений, что крайне негативно сказывается на производительности системы.
  2. Измерения регистра накопления: образуют разрез хранения остатков. Если добавить дату как измерение, виртуальные таблицы остатков заработают, однако любое изменение структуры типовых регистров накопления (таких как ПартииТоваровНаСкладах) приводит к существенному разрастанию таблиц итогов, рискам блокировок при проведении и необходимости менять все типовые алгоритмы списания (партионный учет, ФИФО/ЛИФО/FEFO).
  3. Режим РАУЗ: если на предприятии включена расширенная аналитика учета затрат, регистры партий вообще не формируются, а учет ведется по регистру УчетЗатрат через аналитики номенклатуры.

Где в коде УПП формируются движения по партиям

Если в конфигурации используется традиционный партионный учет, разберем механизм трансляции данных из табличной части документа в движения регистра:

  1. В модуле документа поступления (например, ПоступлениеТоваровУслуг) за сборку исходных данных отвечает процедура ПодготовитьТаблицыДокумента(). В ней вызывается метод формирования таблицы номенклатуры (ДвиженияНоменклатуры.СформироватьТаблицуНоменклатуры()), куда передаются колонки табличной части.
  2. Непосредственное заполнение наборов записей партионных регистров происходит в общих модулях ДвиженияНоменклатуры и ПартионныйУчет. При оприходовании структура колонок формируется на основе переданной таблицы.
  3. Следует помнить о механизме отложенного проведения: если в базе настроено регламентное проведение по партиям, движения формируются не в момент проведения документа, а отдельной обработкой ПроведениеПоПартиям, которая считывает данные документа по собственным алгоритмам.

Решение 1. Автоматизация типового механизма серий (рекомендуемый способ)

В типовых конфигурациях 1С задача учета сроков годности уже заложена в механизм серийного учета. В справочнике СерииНоменклатуры присутствуют реквизиты ГоденДо и СрокГодности, а регистры партий и складских остатков содержат измерение СерияНоменклатуры.

Чтобы избавить пользователей от необходимости вручную заводить серии, автоматизируем этот процесс при вводе произвольной даты в табличную часть:

  1. В табличную часть Товары документа добавляем реквизит СрокГодности (тип Дата).
  2. На форме документа выводим эту колонку для ввода даты пользователем.
  3. В модуле объекта или в обработчике события перед проведением программно находим или создаем серию с указанным сроком и подставляем ее в типовой реквизит СерияНоменклатуры.

Посмотрим на пример функции для автоматического подбора и создания серии:


Функция ПолучитьИлиСоздатьСерию(Номенклатура, СрокГодности) Экспорт
    Если Не ЗначениеЗаполнено(СрокГодности) Тогда
        Возврат Справочники.СерииНоменклатуры.ПустаяСсылка();
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	Серии.Ссылка КАК Ссылка
        |ИЗ
        |	Справочник.СерииНоменклатуры КАК Серии
        |ГДЕ
        |	Серии.Владелец = &Владелец
        |	И Серии.ГоденДо = &ГоденДо";
    Запрос.УстановитьПараметр("Владелец", Номенклатура);
    Запрос.УстановитьПараметр("ГоденДо", СрокГодности);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        Возврат Выборка.Ссылка;
    Иначе
        НоваяСерия = Справочники.СерииНоменклатуры.СоздатьЭлемент();
        НоваяСерия.Владелец = Номенклатура;
        НоваяСерия.ГоденДо = СрокГодности;
        НоваяСерия.Наименование = "Годен до " + Формат(СрокГодности, "ДФ=dd.MM.yyyy");
        НоваяСерия.Записать();
        Возврат НоваяСерия.Ссылка;
    КонецЕсли;
КонецФункции

Преимущества подхода: структура регистров накопления не меняется, типовые отчеты по остаткам и срокам годности работают «из коробки», алгоритмы списания партий функционируют без сбоев.

Решение 2. Использование независимого регистра сведений

Если политика предприятия запрещает включение серийного учета, альтернативным безопасным вариантом является хранение сроков годности в отдельном регистре сведений:

  1. Создаем непериодический регистр сведений СрокиГодностиНоменклатуры.
  2. Задаем измерения: Номенклатура (СправочникСсылка.Номенклатура), ДокументОприходования (ДокументСсылка.ПоступлениеТоваровУслуг) и при необходимости НомерСтроки (Число).
  3. Задаем ресурс: СрокГодности (Дата).
  4. В процедуре ОбработкаПроведения документа поступления или в подписке на событие формируем записи в этот регистр сведений.

Пример кода записи в регистр сведений:


ДвиженияРегистра = Движения.СрокиГодностиНоменклатуры;
Для Каждого Стр Из ТаблицаТовары Цикл
    Если ЗначениеЗаполнено(Стр.СрокГодности) Тогда
        Запись = ДвиженияРегистра.Добавить();
        Запись.Номенклатура = Стр.Номенклатура;
        Запись.ДокументОприходования = Ссылка;
        Запись.СрокГодности = Стр.СрокГодности;
    КонецЕсли;
КонецЦикла;

Для отображения данных в отчетах остатки из регистра партий связываются через левое соединение (LEFT JOIN) с созданным регистром сведений по полям номенклатуры и документа партии, что не нарушает целостность типовых механизмов учета.

← На главную