При работе с конфигурацией 1С:Управление торговлей 11.4 часто возникает необходимость кастомизации типовых механизмов. Одной из популярных задач является изменение алгоритма расчета итоговой суммы в строке документа при подборе товаров. В стандартной логике УТ 11 сумма рассчитывается как (Цена * Количество) - Скидка. Однако бизнес-процессы некоторых компаний требуют, чтобы скидка напрямую влияла на цену за единицу товара еще на этапе подбора, превращая её в так называемую «чистую цену».
В этой статье мы подробно разберем, как реализовать подобную задачу, используя механизм расширений конфигурации, и на какие архитектурные особенности системы стоит обратить внимание.
Для начала проанализируем, как происходит перенос данных. Когда пользователь завершает подбор номенклатуры, форма подбора возвращает массив структур или таблицу значений в форму документа. Основная обработка этих данных происходит в процедуре ОбработкаВыбора формы документа (например, ЗаказКлиента).
Далее цепочка вызовов обычно ведет в общий модуль или модуль формы, где вызывается процедура заполнения документа. Основная сложность заключается в том, что после добавления строки система запускает типовые механизмы пересчета, которые могут «затереть» ваши ручные корректировки. Чтобы этого не произошло, нам нужно правильно вклиниться в процесс с помощью расширения.
Разберем по шагам, как подготовить среду для разработки:
ЗаказКлиента и его форму ФормаДокумента.ЗаполнитьДокументИзПодобраныхТоваров или вызовы в ОбработкаВыбора.&Перед, &После или &Вместо.Для нашей задачи оптимальным выбором будет аннотация &После (&After), так как она позволяет выполнить стандартный код 1С, а затем скорректировать результат под наши требования, не нарушая логику системы.
Выясним причину, по которой стандартный расчет нам не подходит. В типовом решении скидка — это сумма, вычитаемая из общего произведения. Нам же нужно, чтобы Цена = Цена - (Скидка / Количество). Посмотрим на пример реализации кода в модуле расширения:
&После("ЗаполнитьДокументИзПодобраныхТоваров")
Процедура Расш1_ЗаполнитьДокументИзПодобраныхТоваров(ПодобраннаяНоменклатура)
Для Каждого СтрокаТовара Из Объект.Товары Цикл
// Проверяем, что скидка заполнена и количество больше нуля
Если СтрокаТовара.СуммаСкидкиНаценки <> 0 И СтрокаТовара.Количество <> 0 Тогда
// Вычисляем новую цену, где скидка уже учтена в цене единицы
НоваяЦена = СтрокаТовара.Цена - (СтрокаТовара.СуммаСкидкиНаценки / СтрокаТовара.Количество);
// Устанавливаем новую цену
СтрокаТовара.Цена = НоваяЦена;
// Обнуляем сумму скидки, так как мы её уже "включили" в цену
СтрокаТовара.СуммаСкидкиНаценки = 0;
// Принудительно взводим флаг ручной корректировки,
// чтобы автоматические скидки не пересчитали строку обратно
СтрокаТовара.СтатусУказанияСерий = 1; // Условный пример, в УТ 11 используется спец. поле
// Вызываем типовой пересчет строки для коррекции НДС и итогов
ОбработкаТабличнойЧастиКлиент.РассчитатьСуммуТЧ(СтрокаТовара, Объект);
ОбработкаТабличнойЧастиКлиент.ПересчитатьНДСВСтрокеТЧ(СтрокаТовара, Объект);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Проанализируем важный нюанс: в УТ 11.4 встроена мощная система автоматических скидок. Если вы программно изменили цену, но не указали системе, что это «ручное» изменение, при любой записи документа или изменении количества программа вызовет фоновый пересчет и вернет цену к прайсовой.
Рассмотрим подробнее, как это обойти. В табличной части Товары существуют скрытые реквизиты, отвечающие за фиксацию скидок. Нам необходимо убедиться, что реквизит, отвечающий за ручную скидку (например, СкидкаУстановленаВручную), установлен в значение Истина.
Также важно помнить про параметр «Цена включает НДС». Если ваша новая цена рассчитывается динамически, обязательно используйте функцию ОбработкаТабличнойЧастиКлиент.ПересчитатьНДСВСтрокеТЧ, иначе сумма налога в документе будет неверной, что приведет к ошибкам в печатных формах счетов-фактур и УПД.
Если задача требует, чтобы расчет был виден пользователю еще в самой форме подбора (до переноса в документ), нам придется расширить и саму форму подбора (обычно это обработка ПодборНоменклатуры).
В форме подбора нужно перехватить событие ПриИзменении для полей «Цена» или «Скидка». Разберем ситуацию: пользователь вводит скидку 500 рублей на торт стоимостью 5000 рублей. В этот момент мы должны программно обновить колонку «Цена» в корзине подобранных товаров.
&НаКлиенте
Процедура Расш1_КоличествоПриИзмененииПосле(Элемент)
ТекущиеДанные = Элементы.СписокПодобранныхТоваров.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Логика мгновенного пересчета в форме подбора
ТекущиеДанные.Цена = ТекущиеДанные.Цена - (ТекущиеДанные.СуммаСкидки / ТекущиеДанные.Количество);
КонецЕсли;
КонецПроцедуры
Для грамотной реализации доработки в 1С:Управление торговлей 11.4 придерживайтесь следующих правил:
&После: Это наиболее безопасный способ корректировки данных после отработки стандартных механизмов.ОбработкаТабличнойЧастиКлиент).Таким образом, мы рассмотрели полный цикл задачи: от захвата процедуры в расширение до тонкостей работы с типовыми механизмами пересчета. Подобный подход гарантирует стабильную работу системы и корректность ведения управленческого учета.