Когда перед нами встает задача распределения транспортно-заготовительных расходов (ТЗР) на себестоимость товаров пропорционально их объему или весу, мы ожидаем, что система 1С:Управление торговлей (УТ 11) выполнит эту операцию автоматически. Мы скрупулезно заполняем весогабаритные характеристики (ВГХ) в справочнике упаковок, указываем эти упаковки в документах поступления, но при попытке распределить услуги в документе ПриобретениеУслугИПрочихАктивов сталкиваемся с неприятным сюрпризом: программа выдает нулевые значения или распределяет суммы некорректно. При этом, если те же самые данные заполнить непосредственно в карточке номенклатуры, расчет проходит успешно.
Выясним причину такого поведения системы, проанализируем архитектурные особенности решений на платформе 1С:Предприятие 8.3 (таких как УТ 11, КА 2 и ERP 2) и разберем практические способы решения этой проблемы — как методические, так и программные.
Для того чтобы понять, почему система игнорирует весогабаритные характеристики упаковок, нам необходимо обратиться к архитектуре регистров накопления и логике проведения документов в конфигурациях ERP-семейства.
Рассмотрим, в каком виде хранятся данные о складских остатках и себестоимости. Любое движение товаров регистрируется в базовых единицах хранения (например, в штуках, килограммах или литрах). Когда мы проводим документ ПриобретениеТоваровУслуг, в котором указана упаковка (например, «Коробка 20 шт.»), система делает записи в регистры накопления (такие как СебестоимостьТоваров или ДвиженияНоменклатураДоходыРасходы), автоматически пересчитывая количество в базовую единицу. Информация о том, что товар физически приехал в коробках или на паллетах, на уровне регистров учета затрат фактически нивелируется.
Когда мы открываем документ ПриобретениеУслугИПрочихАктивов и выбираем вариант распределения «Пропорционально объему» (или «Пропорционально весу»), программа инициирует сложный алгоритм расчета базы распределения. Этот алгоритм работает по следующей схеме:
Вес и Объем, расположенным непосредственно в справочнике Номенклатура (то есть к свойствам самой карточки товара, соответствующим его базовой единице).КоличествоВБазовыхЕдиницах * ОбъемБазовойЕдиницы.Важный вывод: Обращение к табличной части исходного документа поступления для выяснения того, в какой именно упаковке пришел товар, в типовом коде распределения не предусмотрено. Соответственно, если в самой карточке номенклатуры объем базовой единицы равен нулю, то и итоговый объем для распределения будет равен нулю, даже если в карточке используемой упаковки все данные заполнены идеально. Как метко выразились разработчики на форуме, «типовой механизм на упаковки кладет болт».
Если мы хотим остаться в рамках полностью типового функционала и избежать программирования, нам придется пересмотреть подход к ведению весогабаритных характеристик. Нам нужно пересчитать физические показатели упаковок и перенести их на уровень базовой единицы хранения в справочнике Номенклатура.
Проанализируем этот процесс на конкретном примере:
Мы закупаем товар «Кабель электрический». Базовая единица хранения — «метр». Товар поступает в упаковках — «Бухта 100 метров». Объем одной бухты составляет 0,2 кубических метра ($m^3$).
Чтобы распределение работало корректно, мы должны рассчитать объем одного метра кабеля:
0,2 м³ / 100 метров = 0,002 м³.
Именно это значение — 0,002 — мы должны внести в поле «Объем» в карточке номенклатуры. Когда в документе поступления пользователь укажет 3 бухты (что эквивалентно 300 метрам), алгоритм распределения расходов умножит 300 метров на 0,002 м³ и получит верную базу распределения — 0,6 м³.
Важное ограничение метода: В 1С все стандартные показатели объема хранятся в кубических метрах (м³). Если наш товар очень мелкий (например, флакон лекарства или микросхема), то объем одной единицы в кубических метрах будет представлять собой число со множеством знаков после запятой (например, 0,000005 м³). Из-за ограничений точности представления чисел в стандартных реквизитах конфигурации (обычно это 3 или 4 знака после запятой для объема) программа округлит это значение до нуля. В этом случае методический подход не сработает, и нам придется прибегнуть к программным доработкам.
Разберем, каким образом программист может кастомизировать систему под требования бизнеса, когда распределение ТЗР должно происходить строго на основании упаковок, указанных в первичных документах поступления.
Этот вариант является наиболее изящным, так как он не снимает конфигурацию с поддержки и сохраняет автоматическое распределение при расчете себестоимости и закрытии месяца.
Нам необходимо перехватить процедуру расчета базы распределения расходов в общем модуле, отвечающем за расчет себестоимости или распределение расходов. Наша задача — модифицировать запрос, который собирает весогабаритные характеристики.
Вместо связи только со справочником Номенклатура, мы должны левым соединением связать таблицу распределяемых товаров с табличной частью исходного документа поступления и справочником УпаковкиНоменклатуры.
Посмотрим на пример логики построения такого запроса:
// Пример модифицированного запроса для расчета базы распределения по упаковкам
ВЫБРАТЬ
ТаблицаТоваров.Номенклатура КАК Номенклатура,
ТаблицаТоваров.Количество КАК КоличествоВБазовыхЕдиницах,
ВЫБОР
КОГДА ТаблицаТоваров.Упаковка <> ЗНАЧЕНИЕ(Справочник.УпаковкиНоменклатуры.ПустаяСсылка)
ТОГДА ТаблицаТоваров.Упаковка.Объем * (ТаблицаТоваров.Количество / ТаблицаТоваров.Упаковка.Числитель)
ИНАЧЕ ТаблицаТоваров.Номенклатура.Объем * ТаблицаТоваров.Количество
КОНЕЦ КАК ИтоговыйОбъем
ИЗ
Документ.ПриобретениеТоваровУслуг.Товары КАК ТаблицаТоваров
ГДЕ
ТаблицаТоваров.Ссылка В (&МассивДокументовПоступления)
Этот запрос проверяет: если в документе поступления была указана конкретная упаковка, то система берет объем этой упаковки, делит общее количество базовых единиц на коэффициент упаковки (реквизит Числитель в справочнике УпаковкиНоменклатуры) и умножает на объем упаковки. Если упаковка не указана, система откатывается к стандартному поведению и берет объем из карточки номенклатуры.
Если мы хотим избежать вмешательства в код проведения документов и механизмы закрытия месяца, мы можем пойти путем создания внешней обработки заполнения для документа ПриобретениеУслугИПрочихАктивов.
Пользователь будет действовать по следующей схеме:
Упаковка, вычисляет реальные физические объемы строк, рассчитывает коэффициенты распределения и пропорционально заполняет суммы в табличной части документа услуг.Этот способ безопасен с точки зрения обновлений конфигурации, однако требует от пользователей дисциплины: им необходимо не забывать нажимать кнопку обработки при каждом оформлении документов распределения расходов.
Если проблема распределения мелких товаров упирается в разрядность кубических метров, мы можем обойти это ограничение без радикального изменения логики упаковок:
Число с высокой точностью) или «Вес в граммах».Проанализируем, изменилось ли что-то в более новых редакциях программных продуктов 1С. Начиная с версии УТ 11.5.7, разработчики изменили структуру хранения правил распределения расходов. Теперь они настраиваются в рамках отдельного справочника «Правила распределения и показатели».
Тем не менее, сама концепция осталась неизменной: показатели «Объем товаров» и «Вес товаров» по-прежнему собираются на основе характеристик базовой единицы из карточки номенклатуры. Штатной возможности переключить логику распределения на «ВГХ фактически указанных в документах упаковок» разработчики 1С так и не добавили. Поэтому все описанные выше архитектурные выводы и методы решения остаются на 100% актуальными как для УТ 11.4, так и для УТ 11.5, КА 2.5 и ERP 2.5.