При программном расширении функционала типовых конфигураций, таких как 1С:Управление нашей фирмой (УНФ), разработчики часто сталкиваются с ситуацией, когда добавленные вручную суммы «зависают» на остатках. Вроде бы документ СборкаЗапасов провелся, в регистре мы видим нужные цифры, и даже отчет по себестоимости показывает правильный итог. Однако, как только дело доходит до последующей продажи или перемещения этого товара, добавленная сумма игнорируется системой. Разберем детально, почему так происходит и как заставить систему «видеть» вашу доп. стоимость как единое целое с основным товаром.
Для оперативного контроля можно использовать отчеты, показывающие валовую прибыль без закрытия месяца в учетных ценах.
Для начала проанализируем ситуацию. В 1С:УНФ основным «хранилищем» данных о стоимости товаров является регистр накопления Запасы и затраты (в зависимости от версии может называться просто Запасы). Когда мы программно добавляем строки в набор записей этого регистра при проведении документа СборкаЗапасов, мы ожидаем, что система просто сложит все суммы по конкретной номенклатуре. Но на практике 1С работает иначе: себестоимость списывается в разрезе измерений.
Если при перемещении товара сумма в 50 единиц остается на складе отправителя, это однозначно сигнализирует о том, что эта сумма числится на другом наборе измерений, отличном от того, который выбирает документ перемещения. Рассмотрим основные причины такого поведения.
Выясним причину, по которой строки не суммируются в запросе (в СКД или консоли запросов). Если вы используете предложение СГРУППИРОВАТЬ ПО, но в результате получаете две разные строки для одного и того же товара — значит, значения в полях, по которым идет группировка, различаются. Проанализируем, какие поля чаще всего становятся «камнем преткновения»:
ЗаказПокупателя или ЗаказНаПроизводство. Если основная номенклатура оприходована под заказ, а ваша доп. сумма — нет, они никогда не объединятся.СчетУчета или КорСчетУчета также разделяет записи. Часто расхождения в данных выявляются, когда проводится сравнение остатков и цен товаров между БП и УНФ.Чтобы точно понять, какое поле «разбивает» нашу себестоимость, недостаточно просто смотреть на наименования в отчете. Посмотрим на ситуацию глазами системы. Рекомендуется использовать следующий подход в консоли запросов:
Вместо простого выбора поля Номенклатура или Партия, мы будем выводить их внутренние ссылки и типы данных. Рассмотрим пример запроса для диагностики:
ВЫБРАТЬ
Запасы.Номенклатура КАК Номенклатура,
Запасы.Характеристика КАК Характеристика,
Запасы.Партия КАК Партия,
Запасы.КоличествоПриход КАК Количество,
Запасы.СуммаПриход КАК Сумма,
ТИПЗНАЧЕНИЯ(Запасы.Партия) КАК ТипПартии,
Запасы.Партия.УникальныйИдентификатор КАК ИД_Партии
ИЗ
РегистрНакопления.Запасы КАК Запасы
ГДЕ
Запасы.Регистратор = &СсылкаНаДокумент
Проанализируем результат. Если в колонке ИД_Партии для основной строки и для вашей строки с суммой 50 стоят разные значения (или одно из них пустое), то мы нашли виновника. Система считает их разными партиями товара.
Когда мы нашли отличия, нам нужно скорректировать код, который добавляет строки. Важно не просто создать новую строку в наборе записей, а максимально точно скопировать все измерения из эталонной строки прихода готовой продукции. Рассмотрим, как это сделать правильно в модуле проведения или в подписке на событие:
// Предположим, мы перебираем существующие движения, чтобы найти строку прихода товара
Для Каждого Движение Из НаборЗаписей Цикл
Если Движение.ВидДвижения = ВидДвиженияНакопления.Приход
И Движение.Номенклатура = ЦелевойТовар Тогда
// Создаем новую строку на основе существующей
НоваяСтрока = НаборЗаписей.ДобавитьПриход();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Движение);
// Устанавливаем только те значения, которые должны отличаться
НоваяСтрока.Количество = 0; // Нам нужно добавить только стоимость
НоваяСтрока.Сумма = 50;
НоваяСтрока.СуммаРег = 50; // Не забываем про управленческую и регламентированную суммы
// ВАЖНО: Убеждаемся, что Партия и Заказ скопированы точно
// НоваяСтрока.Партия = Движение.Партия; // Это уже сделает ЗаполнитьЗначенияСвойств
КонецЕсли;
КонецЦикла;
В УНФ существует перечисление ТипыЗапасов. Если ваша доп. сумма падает на строку, где ТипЗапаса установлен как «Материал», а основной товар — это «Запас», система может вести их учет по-разному в алгоритмах распределения затрат. Всегда проверяйте это скрытое поле в регистре Запасы и затраты.
Рассмотрим механизм документа ПеремещениеЗапасов. Он работает по принципу списания остатков. При проведении он делает запрос к остаткам регистра по ключу: Организация + Номенклатура + Характеристика + Партия + Склад. Если вы перемещаете 1 штуку товара с «Партией №1», документ заберет только ту стоимость, которая числится именно на этой комбинации. Ваша сумма в 50 единиц, если она лежит на «Пустой партии», останется нетронутой, так как документ перемещения про нее просто не «знает» — он не ищет остатки по другим партиям для этой номенклатуры.
Подведем итог нашему исследованию. Для исправления проблемы выполните следующие действия:
ЗаполнитьЗначенияСвойств, копируя данные из строки Движения основного выпускаемого изделия.Сумма, но и сопутствующие ресурсы (СуммаДоходов, СуммаРасходов), если логика вашего документа этого требует для баланса регистра.Соблюдение этих правил обеспечит «склейку» себестоимости, и ваши дополнительные затраты будут корректно следовать за товаром при любых его перемещениях по складам организации, в том числе при групповом перемещении товаров.