Часто возникает ситуация, когда нужно создавать заказ программно. В типовых конфигурациях предусмотрено много механизмов, чтобы заполнить все поля заказа нужными данными по аналогии тому, как это происходит при создании заказа из интерфейса. Однако, если компания использует программы лояльности с начислением и списанием бонусных баллов, разработчики 1С: УТ (11.5.17.234) почему-то забыли сделать механизм для программного заполнения бонусных баллов к списанию в строках товаров.
Эту несправедливость однажды пришлось исправлять мне в моей работе и сейчас я помогу исправить её вам, чтобы не пришлось лишний раз искать всё это в типовом коде.
На самом деле все механизмы по заполнению полей списания бонусных баллов уже прописаны в УТ, но они выполняются только на форме ОплатаБонуснымиБаллами. Всё, что нам нужно, это перенести и адаптировать уже существующий механизм из формы в общие модули, чтобы заполнение происходило при вызове одной команды.
Технически нужный нам функционал в данной форме разбит на 2 блока: в ПриСозданииНаСервере происходит инициализация данных и получение общей суммы оплаты. При закрытии формы происходит заполнение табличной заказа по этим данным в процедуре АдресВоВременномХранилище.
Некоторые вспомогательные данные при этом хранятся во временном хранилище между этими двумя событиями. При программном создании нам этого не нужно.
Чтобы сделать процедуру для программного заполнения строк ТЧ Товары СуммаБонусныхБалловКСписанию и СуммаБонусныхБалловКСписаниюВВалюте нам нужно объединить эти два механизма, убрав лишнее. Итоговая процедура будет такой:
Процедура ПрименитьОплатуБонуснымиБаллами(ЗаказОбъект, ДанныеКартыЛояльности)
ВыборкаБонуснаяПрограммаЛояльности = БонусныеБаллыСервер.БонуснаяПрограммаКартыЛояльности(ДанныеКартыЛояльности.Ссылка);
БонуснаяПрограммаЛояльности = ВыборкаБонуснаяПрограммаЛояльности.БонуснаяПрограммаЛояльности;
Партнер = ЗаказОбъект.Партнер;
ВалютаДокумента = ЗаказОбъект.Валюта;
ВалютаБонуснойПрограммы = ВыборкаБонуснаяПрограммаЛояльности.Валюта;
СтруктураКурсовВалютыДокумента = РаботаСКурсамиВалютУТ.ПолучитьКурсВалюты(ВалютаДокумента, ТекущаяДатаСеанса());
СтруктураКурсовВалютыБонуснойПрограммы = РаботаСКурсамиВалютУТ.ПолучитьКурсВалюты(ВалютаБонуснойПрограммы, ТекущаяДатаСеанса());
КурсКонвертацииБонусовВВалюту = ВыборкаБонуснаяПрограммаЛояльности.КурсКонвертацииБонусовВВалюту;
// Расчет максимальной суммы оплаты бонусами
ТабличнаяЧастьТовары = ЗаказОбъект.Товары.Выгрузить(); // ТабличнаяЧасть, ТаблицаЗначений
ТабличнаяЧастьТовары.Колонки.Добавить("МаксимальнаяСуммаОплаты", ОбщегоНазначенияУТ.ОписаниеТипаДенежногоПоля());
ТабличнаяЧастьТовары.Колонки.Добавить("МаксимальнаяСуммаОплатыВБаллах", ОбщегоНазначенияУТ.ОписаниеТипаДенежногоПоля());
Запрос = Новый Запрос("ВЫБРАТЬ
| Товары.НомерСтроки КАК НомерСтроки,
| Товары.КлючСвязи КАК КлючСвязи,
| ВЫРАЗИТЬ(Товары.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
| Товары.Характеристика КАК Характеристика,
| Товары.КоличествоУпаковок КАК КоличествоУпаковок,
| Товары.Цена КАК ЦенаЗаУпаковку,
| Товары.ПроцентАвтоматическойСкидки КАК ПроцентАвтоматическойСкидки,
| Товары.СуммаАвтоматическойСкидки КАК СуммаАвтоматическойСкидки
|ПОМЕСТИТЬ ВременнаяТаблицаТовары
|ИЗ
| &Товары КАК Товары
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Товары.НомерСтроки КАК НомерСтроки,
| Товары.КлючСвязи КАК КлючСвязи,
| Товары.Номенклатура КАК Номенклатура,
| Товары.Характеристика КАК Характеристика,
| Товары.КоличествоУпаковок КАК КоличествоУпаковок,
| ЕСТЬNULL(ЕСТЬNULL(ТабличнаяЧастьЦеновыеГруппы.МаксимальныйПроцентОплатыБонусами,
| БонусныеПрограммыЛояльности.МаксимальныйПроцентОплатыБонусами), 0) КАК МаксимальныйПроцентОплатыБонусами,
| Товары.КоличествоУпаковок * Товары.ЦенаЗаУпаковку КАК Сумма,
| Товары.ПроцентАвтоматическойСкидки КАК ПроцентАвтоматическойСкидки,
| Товары.СуммаАвтоматическойСкидки КАК СуммаАвтоматическойСкидки,
| ВЫБОР
| КОГДА БонусныеПрограммыЛояльности.СегментНоменклатуры <> ЗНАЧЕНИЕ(Справочник.СегментыНоменклатуры.ПустаяСсылка)
| ТОГДА ВЫБОР
| КОГДА НоменклатураСегмента.Сегмент = БонусныеПрограммыЛояльности.СегментНоменклатуры
| ТОГДА ИСТИНА
| ИНАЧЕ ЛОЖЬ
| КОНЕЦ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК ВходитВДоступныйСегмент,
| БонусныеПрограммыЛояльности.БезУчетаПредоставленныхСкидок
|ИЗ
| ВременнаяТаблицаТовары КАК Товары
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.БонусныеПрограммыЛояльности.ЦеновыеГруппы КАК ТабличнаяЧастьЦеновыеГруппы
| ПО (ТабличнаяЧастьЦеновыеГруппы.Ссылка = &БонуснаяПрограммаЛояльности)
| И (ТабличнаяЧастьЦеновыеГруппы.ЦеноваяГруппа = Товары.Номенклатура.ЦеноваяГруппа)
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.БонусныеПрограммыЛояльности КАК БонусныеПрограммыЛояльности
| ПО (БонусныеПрограммыЛояльности.Ссылка = &БонуснаяПрограммаЛояльности)
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НоменклатураСегмента КАК НоменклатураСегмента
| ПО Товары.Номенклатура = НоменклатураСегмента.Номенклатура
| И Товары.Характеристика = НоменклатураСегмента.Характеристика
| И НоменклатураСегмента.Сегмент = БонусныеПрограммыЛояльности.СегментНоменклатуры");
Запрос.УстановитьПараметр("Товары", ТабличнаяЧастьТовары);
Запрос.УстановитьПараметр("БонуснаяПрограммаЛояльности", БонуснаяПрограммаЛояльности);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если Не Выборка.МаксимальныйПроцентОплатыБонусами > 0 Тогда
Продолжить;
КонецЕсли;
Если Не Выборка.ВходитВДоступныйСегмент Тогда
Продолжить;
КонецЕсли;
Если Не Выборка.БезУчетаПредоставленныхСкидок
И Выборка.ПроцентАвтоматическойСкидки > Выборка.МаксимальныйПроцентОплатыБонусами Тогда
Продолжить;
КонецЕсли;
СтрокаТЧ = ТабличнаяЧастьТовары.Найти(Выборка.НомерСтроки, "НомерСтроки");
Если Выборка.БезУчетаПредоставленныхСкидок Тогда
СтрокаТЧ.МаксимальнаяСуммаОплаты = (Выборка.МаксимальныйПроцентОплатыБонусами / 100) * (Выборка.Сумма-Выборка.СуммаАвтоматическойСкидки);
Иначе
СтрокаТЧ.МаксимальнаяСуммаОплаты = ((Выборка.МаксимальныйПроцентОплатыБонусами - Выборка.ПроцентАвтоматическойСкидки) / 100) * Выборка.Сумма;
КонецЕсли;
СтрокаТЧ.МаксимальнаяСуммаОплатыВБаллах = РаботаСКурсамиВалютУТ.ПересчитатьПоКурсу(
СтрокаТЧ.МаксимальнаяСуммаОплаты,
СтруктураКурсовВалютыДокумента,
СтруктураКурсовВалютыБонуснойПрограммы) / КурсКонвертацииБонусовВВалюту;
КонецЦикла;
ОстаткиБонусныхБаллов = БонусныеБаллыСервер.ОстаткиИДвиженияБонусныхБаллов(БонуснаяПрограммаЛояльности, Партнер);
НачальныйОстатокВБаллах = ОстаткиБонусныхБаллов[0].Сумма;
НачальныйОстаток = РаботаСКурсамиВалютУТ.ПересчитатьПоКурсу(
НачальныйОстатокВБаллах * КурсКонвертацииБонусовВВалюту,
СтруктураКурсовВалютыБонуснойПрограммы,
СтруктураКурсовВалютыДокумента);
МаксимальнаяСуммаОплаты = Мин(ТабличнаяЧастьТовары.Итог("МаксимальнаяСуммаОплаты"), НачальныйОстаток);
МаксимальнаяСуммаОплатыВБаллах = Мин(ТабличнаяЧастьТовары.Итог("МаксимальнаяСуммаОплатыВБаллах"), НачальныйОстатокВБаллах);
СуммаОплаты = МаксимальнаяСуммаОплаты;
СуммаОплатыВБаллах = МаксимальнаяСуммаОплатыВБаллах;
//далее из другой функции
СуммаКРаспределению = СуммаОплатыВБаллах;
СуммаКРаспределениюВВалюте = СуммаОплаты;
МаксимальнаяСуммаОплатыВБаллах = ТабличнаяЧастьТовары.Итог("МаксимальнаяСуммаОплатыВБаллах");
Для каждого СтрокаТЧ Из ТабличнаяЧастьТовары Цикл
Если МаксимальнаяСуммаОплатыВБаллах <= 0 Тогда
Прервать;
КонецЕсли;
ТекСуммаБонусныхБалловКСписанию = СтрокаТЧ.МаксимальнаяСуммаОплатыВБаллах * (СуммаКРаспределению / МаксимальнаяСуммаОплатыВБаллах);
СтрокаТЧ.СуммаБонусныхБалловКСписанию = Мин(ТекСуммаБонусныхБалловКСписанию, СуммаКРаспределению);
ТекСуммаБонусныхБалловКСписаниюВВалюте = РаботаСКурсамиВалютУТ.ПересчитатьПоКурсу(
СтрокаТЧ.СуммаБонусныхБалловКСписанию * КурсКонвертацииБонусовВВалюту,
СтруктураКурсовВалютыБонуснойПрограммы,
СтруктураКурсовВалютыДокумента);
СтрокаТЧ.СуммаБонусныхБалловКСписаниюВВалюте = Мин(ТекСуммаБонусныхБалловКСписаниюВВалюте, СуммаКРаспределениюВВалюте);
СуммаКРаспределению = СуммаКРаспределению - СтрокаТЧ.СуммаБонусныхБалловКСписанию;
МаксимальнаяСуммаОплатыВБаллах = МаксимальнаяСуммаОплатыВБаллах - СтрокаТЧ.МаксимальнаяСуммаОплатыВБаллах;
СуммаКРаспределениюВВалюте = СуммаКРаспределениюВВалюте - СтрокаТЧ.СуммаБонусныхБалловКСписаниюВВалюте;
КонецЦикла;
ЗаказОбъект.Товары.Загрузить(ТабличнаяЧастьТовары);
КонецПроцедуры
Вставляете её вызов после всех обработок строк ТЧ и до вызова СкидкиНаценкиЗаполнениеСервер.Рассчитать и всё будет работать.
Вступайте в нашу телеграмм-группу Инфостарт
