В торговых компаниях часто возникает ситуация, когда один и тот же товар закупается разными партиями. Из-за колебаний курсов валют, изменения цен поставщиков или логистических затрат себестоимость единицы товара в разных поставках может существенно отличаться. Менеджеры по продажам, стремясь предоставить клиенту индивидуальную скидку или максимизировать прибыль, хотят видеть в интерфейсе подбора («Помощнике продаж») конкретные документы поступления, остатки по ним и точную себестоимость, чтобы вручную выбирать, из какого именно прихода списать товар.
В этой статье мы подробно разберем, как решить эту задачу в современных конфигурациях на платформе «1С:Предприятие 8.3» (таких как «1С:Управление торговлей 11», «1С:ERP» или «BAS Управление торговлей»). Мы проанализируем архитектурные ограничения системы, рассмотрим штатные (безпрограммные) альтернативы и детально опишем алгоритм программной доработки, если без изменения кода не обойтись.
Если вы ранее работали с конфигурациями старого поколения (например, «Управление торговлей 10.3» или решениями на платформе «1С:Предприятие 7.7»), то наверняка помните простой рецепт: добавить реквизит Партия (документ поступления) в табличную часть документа продажи, вывести его в подбор, а при проведении подставить этот документ в движения регистра партий. К сожалению, в современных редакциях «1С:Управление торговлей 11» (и родственных конфигурациях) этот подход не сработает.
В современной архитектуре ERP-систем 1С партионный учет работает по принципу отложенного расчета. В момент проведения документа продажи («Реализация товаров и услуг») система списывает товар только в количественном выражении по складским регистрам. Окончательное распределение партий (по методу FIFO или средней стоимости) и расчет финансового результата происходят в конце отчетного периода при запуске регламентной операции «Расчет себестоимости» в рамках закрытия месяца.
Если вы просто принудительно запишете партию в движения документа реализации при его проведении, процедура закрытия месяца и распределения затрат сотрет ваши ручные корректировки и пересчитает все движения по типовым алгоритмам FIFO. Поэтому стандартную логику распределения партий переписать «на лету» чрезвычайно сложно и крайне не рекомендуется.
Прежде чем приступать к доработке кода, давайте разберем штатные механизмы, которые разработчики фирмы «1С» заложили в систему для решения этой проблемы.
Для индивидуального учета каждой закупаемой партии товаров в системе предусмотрен мощный встроенный инструмент — серийный учет с контролем себестоимости. В данном сценарии «серия» используется не как серийный номер конкретного изделия, а как уникальный идентификатор партии закупки.
Рассмотрим по шагам, как настроить и использовать этот механизм:
Этот метод является наиболее рекомендуемым, поскольку он полностью штатный, не требует изменения типового кода конфигурации и гарантирует 100% корректность ведения партионного и финансового учета.
Если менеджеру требуется зафиксировать цену закупки под конкретную сделку, можно использовать обособленный учет себестоимости:
Если бизнес-процессы компании категорически не позволяют использовать серии (например, из-за нежелания закупщиков тратить время на ввод серий), и требуется именно программирование, рассмотрим, как правильно спроектировать такое решение.
Главная ошибка начинающих разработчиков при реализации этой задачи — попытка связать основной динамический список товаров с регистром остатков партий по левому соединению. Если у вас в базе десятки тысяч товаров, и по каждому есть множество документов прихода, то при попытке открыть «Помощник продаж» динамический список начнет сильно тормозить, и пользователи просто не смогут работать.
Как сделать правильно:
Оставляем основной динамический список номенклатуры без изменений. На форму подбора добавляем подчиненную (ведомую) таблицу «Остатки по партиям». При активизации строки в основном списке товаров мы будем программно отправлять быстрый запрос к базе данных и заполнять подчиненную таблицу остатками партий исключительно по текущему выбранному товару. Это обеспечит мгновенный отклик интерфейса.
Для получения актуальных остатков по партиям и документов оприходования нам понадобится обратиться к виртуальной таблице остатков регистра накопления ПартииТоваровОрганизаций. Напишем пример запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПартииОстатки.ДокументПоступления КАК ДокументРегистратор,
| ПартииОстатки.КоличествоОстаток КАК Количество,
| ПартииОстатки.СтоимостьОстаток КАК Стоимость,
| ПартииОстатки.НДСОстаток КАК НДС
|ИЗ
| РегистрНакопления.ПартииТоваровОрганизаций.Остатки(&Период, АналитикаУчетаНоменклатуры.Номенклатура = &Номенклатура) КАК ПартииОстатки
|ГДЕ
| ПартииОстатки.КоличествоОстаток > 0";
Запрос.УстановитьПараметр("Период", Новый Граница(КонецДня(ТекущаяДата()), ВидГраницы.Включая));
Запрос.УстановитьПараметр("Номенклатура", ВыбранныйТовар);
РезультатЗапроса = Запрос.Выполнить();
Этот запрос вернет нам список документов поступления (поле ДокументПоступления), количество доступного товара по этой партии и его стоимость, которую менеджер сможет увидеть на экране.
После того как менеджер выбрал партии в «Помощнике продаж», данные необходимо перенести в документ реализации. Допустим, клиенту требуется 10 единиц товара. На складе есть две подходящие партии: по первой осталось 3 штуки, по второй — 7 штук.
Проанализируем алгоритм заполнения документа:
ДокументПоступления (или Партия) с типом ссылки на документы поступления.Чтобы система списала именно выбранные партии, и закрытие месяца не пересчитало их по ФИФО, вам придется вмешаться в процедуру проведения документа. Для этого можно пойти двумя путями:
Путь А (Сложнее): Изменить логику формирования движений по регистру ПартииТоваровОрганизаций в модуле проведения документа. Если в строке табличной части заполнено поле Партия, система должна формировать движение расхода по партии принудительно, игнорируя стандартный механизм ФИФО.
Путь Б (Проще и чище): Программно использовать встроенный механизм назначения (обособления). При переносе строки с партией в документ можно автоматически создавать или подбирать служебное «Назначение», привязанное к этой партии закупки. Система на уровне платформы отработает обособленное списание и сохранит себестоимость без вмешательства в алгоритмы закрытия месяца.
Мы подробно проанализировали задачу вывода документов-регистраторов в помощнике подбора товаров. Прежде чем приступать к масштабному кодингу и изменять логику проведения документов, мы рекомендуем: