Введение
В типовых конфигурациях, таких как Управление торговлей 11 или Комплексная автоматизация 2, для товара можно заводить наборы упаковок, например:
- Штука;
- Коробка (90 штук);
- Паллета (540 штук или 6 коробок);
Такие упаковки удобно использовать при продажах, особенно клиентам, которые могу оперировать как штучным количеством, так и упаковками одного и того же товара. Например, клиент может попросить оформить ему 360 штук товара, а потом подумав сказать, что ему надо еще две коробки. В таком случае удобно, что система перевела количество в коробки и оператор добавил еще две, нежели пересчитывать коробки в штуки в голове и прибавлять к исходному количеству.
Что происходит в стандартном механизме? Указывая 360 штук и меняя единицу измерения Штука на Коробку, количество остается равным 360 и в строке у нас получается 360 Коробок, в описанном случае такой механизм работы не удобен. В нашем случае надо, чтобы система пересчитала Штуки в Коробки и получилось 360 / 90 = 4 Коробки.
Добиться указанного поведения можно, сделав необходимое расширение конфигурации, однако сделать его так, чтобы не затрагивались формы и при обновлении было минимум проблем, оказалось нетривиальной задачей.
Технические моменты
При изменение колонок табличной части запускается процедура изменения данных, для которой указывается, что необходимо выполнить, например, при изменении количества работает примерно такой код:
ТекущаяСтрока = Элементы.Товары.ТекущиеДанные;
СтруктураДействий = Новый Структура;
СтруктураДействий.Вставить("ПересчитатьКоличествоЕдиниц");
СтруктураДействий.Вставить("ПересчитатьСуммуНДС", СтруктураПересчетаСуммы);
//.....
СтруктураДействий.Вставить("ПересчитатьСуммуСУчетомАвтоматическойСкидки", Новый Структура("Очищать", Истина));
СтруктураДействий.Вставить("ЗаполнитьДубликатыЗависимыхРеквизитов", ЗависимыеРеквизиты());
ОбработкаТабличнойЧастиКлиент.ОбработатьСтрокуТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения);
где СтруктураДействий и есть список операций. Нашей точкой для переопределения является операция ПересчитатьКоличествоЕдиниц, процедура, которая обрабатывает этот ключ, находится в модуле ОбработкаТабличнойЧастиКлиентСервер и имеет вид:
Процедура ПересчитатьКоличествоЕдиницВСтрокеТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения) Экспорт
Перем УпаковкаНоменклатура;
Если СтруктураДействий.Свойство("ПересчитатьКоличествоЕдиниц", УпаковкаНоменклатура) Тогда
ПараметрыПересчета = НормализоватьПараметрыПересчетаЕдиниц(ТекущаяСтрока, УпаковкаНоменклатура);
ДанныеУпаковки = ПолучитьКоэффициентУпаковки(ПараметрыПересчета.Упаковка, КэшированныеЗначения, ПараметрыПересчета.Номенклатура);
Количество = ТекущаяСтрока.КоличествоУпаковок * ДанныеУпаковки.Коэффициент;
Если ДанныеУпаковки.НужноОкруглятьКоличество
И ПараметрыПересчета.НужноОкруглять Тогда
ТекущаяСтрока.Количество = Окр(Количество, 0 ,РежимОкругления.Окр15как20);
Иначе
ТекущаяСтрока.Количество = Количество;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура пересчитывает всегда поле Количество, которое скрыто от пользователя, а работает пользователь с полем КоличествоУпаковок, меняя в нем количество, это поле нам и необходимо пересчитать, а поле Количество, которое отвечает за количество в единицах хранения, изменять не надо. Однако пересчитывать надо поле КоличествоУпаковок, только когда меняется единица измерения. Этот момент удалось определить по операциям в СтруктуреДействий, при изменении упаковки присутствует операция ПересчитатьЦенуЗаУпаковку, которой нет в других случаях.
Расширяем общий модуль ОбработкаТабличнойЧастиКлиентСервер, получаем следующий код:
&Вместо("ПересчитатьКоличествоЕдиницВСтрокеТЧ")
Процедура Расш1_ПересчитатьКоличествоЕдиницВСтрокеТЧ(ТекущаяСтрока, СтруктураДействий, КэшированныеЗначения) Экспорт
Перем УпаковкаНоменклатура;
Если СтруктураДействий.Свойство("ПересчитатьКоличествоЕдиниц", УпаковкаНоменклатура) Тогда
// вставка для пересчета упаковок
Если СтруктураДействий.Свойство("ПересчитатьЦенуЗаУпаковку") Тогда
ПараметрыПересчета = НормализоватьПараметрыПересчетаЕдиниц(ТекущаяСтрока, УпаковкаНоменклатура);
ДанныеУпаковки = ПолучитьКоэффициентУпаковки(ПараметрыПересчета.Упаковка, КэшированныеЗначения, ПараметрыПересчета.Номенклатура);
ТекущаяСтрока.Цена = ТекущаяСтрока.Цена / (ТекущаяСтрока.Количество / ТекущаяСтрока.КоличествоУпаковок) * ДанныеУпаковки.Коэффициент;
ТекущаяСтрока.КоличествоУпаковок = ТекущаяСтрока.Количество / ДанныеУпаковки.Коэффициент;
// -------------------------------
Иначе
ПараметрыПересчета = НормализоватьПараметрыПересчетаЕдиниц(ТекущаяСтрока, УпаковкаНоменклатура);
ДанныеУпаковки = ПолучитьКоэффициентУпаковки(ПараметрыПересчета.Упаковка, КэшированныеЗначения, ПараметрыПересчета.Номенклатура);
Количество = ТекущаяСтрока.КоличествоУпаковок * ДанныеУпаковки.Коэффициент;
Если ДанныеУпаковки.НужноОкруглятьКоличество
И ПараметрыПересчета.НужноОкруглять Тогда
ТекущаяСтрока.Количество = Окр(Количество, 0 ,РежимОкругления.Окр15как20);
Иначе
ТекущаяСтрока.Количество = Количество;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В итоге получаем достаточно простую доработку, которую легко поддерживать.
К статье приложено расширение для конфигурации:
- 1С:Комплексная автоматизация 2, тестировалось на версии 2.5.10.52, Платформа 8.3.22.1709.
- 1С: Управление торговлей 11, тестировалось на версии 11.5.9.135, Платформа 8.3.22.1709.