На самом деле может быть более логично поместить процедуру для начисления скидки клиенту в модуле объекта. Потому что начисление скидки – это часть прикладной логики самого документа ОказаниеУслуги.
Изменим процедуру НачислитьСкидку() в модуле формы документа следующим образом (листинг 4.61).
Листинг 4.61. Процедура «НачислитьСкидку()»
&НаСервере
Процедура НачислитьСкидку()
Документ = РеквизитФормыВЗначение("Объект");
Документ.НачислитьСкидкуКлиенту();
ЗначениеВРеквизитФормы(Документ, "Объект");
КонецПроцедуры
В этой процедуре мы сначала получаем объект, отображающийся в форме. Для этого преобразуем основной реквизит формы в объект – документ ОказаниеУслуги. Затем выполняем экспортируемый метод объекта НачислитьСкидкуКлиенту() и выполняем обратное преобразование объекта в реквизит формы Объект.
Затем откроем модуль объекта и поместим в нем процедуру для начисления скидки клиенту (листинг 4.62).
Листинг 4.62. Процедура «НачислитьСкидкуКлиенту()»
Процедура НачислитьСкидкуКлиенту() Экспорт
СуммаСкидки = ЦенаУслуги * Клиент.Скидка / 100;
СуммаУслуги = ЦенаУслуги - СуммаСкидки;
КонецПроцедуры
В этой процедуре мы реализуем тот же алгоритм пересчета, что и в предыдущем варианте, но только пересчитываем не данные формы, а данные самого объекта. Эти изменения после преобразования объекта в основной реквизит формы отобразятся в форме документа.
ПРИМЕЧАНИЕ
Этот пример можно посмотреть в демонстрационной конфигурации «12 (вар. 2) Реализация пересчета данных объекта в модуле объекта или в модуле формы в зависимости от логики объекта».
Запустим «1С:Предприятие», создадим документ об оказании услуги, выберем услугу и внесем цену услуги. При этом сумма услуги становится равной цене услуги. Затем выберем клиента. После этого, если в списке клиентов указан процент скидки, предоставляемой клиенту, сумма скидки рассчитывается как этот процент от цены услуги. При этом сумма услуги рассчитывается как цена услуги за вычетом суммы скидки (рис. 4.73).
Посмотрим теперь на показатели производительности. При выборе клиента произойдет один вызов сервера (рис. 4.75).

Рис. 4.75. Показатели производительности
Этот вызов происходит при выполнении контекстной серверной процедуры модуля формы НачислитьСкидку(), а из нее вызывается экспортируемый метод документа НачислитьСкидкуКлиенту().
ПРИМЕЧАНИЕ
Заметим, что здесь, так же как и в предыдущем варианте, при первом выборе клиента может быть лишний серверный вызов за счет кеширования платформой необходимой информации в списке выбора.
Итак, мы поместили процедуру для начисления скидки клиенту в модуле объекта. Тем самым мы предоставили доступ к данному методу документа ОказаниеУслуги из других мест конфигурации: форм, обработок и т. д. Таким образом, в данном решении мы посчитали процедуру начисления скидки частью прикладной логики объекта.
Данная функциональность документа доступна, например, из формы списка документов об оказании услуг. То есть мы можем изменить клиенту процент скидки, затем выделить документ об оказании услуги и пересчитать по нему скидку, не открывая документа.
Для этого создадим форму списка документа ОказаниеУслуги и ее команду НачислитьСкидку. Перетащим команду в командную панель формы. Обработчик команды НачислитьСкидку заполним следующим образом (листинг 4.63).
Листинг 4.63. Обработчик команды «Начислить скидку»
&НаКлиенте
Процедура НачислитьСкидку(Команда)
НачислитьСкидкуНаСервере(Элементы.Список.ТекущаяСтрока);
КонецПроцедуры
В этом обработчике мы вызываем внеконтекстную серверную процедуру модуля формы НачислитьСкидкуНаСервере() и передаем в нее ссылку на текущий документ (листинг 4.64).
Листинг 4.64. Процедура «НачислитьСкидкуНаСервере»
&НаСервереБезКонтекста
Процедура НачислитьСкидкуНаСервере(СсылкаНаДокумент)
Документ = СсылкаНаДокумент.ПолучитьОбъект();
Документ.НачислитьСкидкуКлиенту();
Документ.Записать();
КонецПроцедуры
В этой процедуре по переданной ссылке на документ мы получаем объект, выполняем экспортируемый метод объекта НачислитьСкидкуКлиенту() и записываем документ.
Запустим «1С:Предприятие», откроем список клиентов и изменим процент скидки, предоставляемой какому-либо клиенту. Затем откроем список документов об оказании услуг, выделим документ для данного клиента и нажмем кнопку Начислить скидку. Сумма скидки и сумма услуги в документе пересчитаются по заданному алгоритму (рис. 4.76).

Рис. 4.76. Начисление скидки клиенту из формы списка документов
Можно организовать начисление скидки для документов в цикле и т. д.