Base file: ОбщийМодуль_УправлениеМаркетинговымиАкциями.onec

Compared file: ОбщийМодуль_УправлениеМаркетинговымиАкциями.m000.onec

Generated by CSDiff on 27.03.2013 13:34  

 
//////// РАССЧЕТ СКИДОК ТАБЛИЧНОЙ ЧАСТИ ТОРГОВЫХ ДОКУМЕНТОВ

// Процедура получает ближайший день рождения для расчета скидок
//
// Параметры:
//  Получатель - физическое лицо получатель скидки
//
// Возвращаемое значение:
//  ДатаРождения - ближайшая дата Дня рождения получателя.
//
Функция ПолучитьБлижайшийДеньРождения(Получатель)
    Перем ДатаРождения;
    ДатаРождения = Дата('00010101000000');
    
    мТекущаяДата = ТекущаяДата();
    
    Если ТипЗнч(Получатель) = Тип("СправочникСсылка.ФизическиеЛица") Тогда
        Если ЗначениеЗаполнено(Получатель.ДатаРождения) Тогда
        
            ДатаТекущегоГода    = Дата(Год(мТекущаяДата),Месяц(Получатель.ДатаРождения),День(Получатель.ДатаРождения));
            ДатаПредыдущегоГода = ДобавитьМесяц(ДатаТекущегоГода,-12);
            ДатаСледующегоГода  = ДобавитьМесяц(ДатаТекущегоГода,12);
            
            Если мТекущаяДата < ДатаТекущегоГода Тогда
                Разность = ДатаТекущегоГода - мТекущаяДата;
            Иначе
                Разность = мТекущаяДата - ДатаТекущегоГода;
            КонецЕсли;
            
            Если Разность > (мТекущаяДата - ДатаПредыдущегоГода) Тогда
                ДатаРождения = ДатаПредыдущегоГода
            ИначеЕсли Разность > (ДатаСледующегоГода - мТекущаяДата) Тогда
                ДатаРождения = ДатаСледующегоГода
            Иначе
                ДатаРождения = ДатаТекущегоГода
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
    
    Возврат ДатаРождения
КонецФункции // ПолучитьБлижайшийДеньРождения()

// Возвращает массив получателей скидки 
//
// Параметры
//  ДисконтнаяКарта - Дисконтная карта
//  Получатель  - Контрагент или физическое лицо
//
// Возвращаемое значение:
//   Массив
//
Функция ПолучитьМассивПолучателей(ДисконтнаяКарта, Получатель)

    Получатели = Новый Массив;
    Если ЗначениеЗаполнено(ДисконтнаяКарта) Тогда
        Получатели.Добавить(ДисконтнаяКарта);
        Получатели.Добавить(ДисконтнаяКарта.ВидДисконтнойКарты)
    КонецЕсли;
    
    Если ЗначениеЗаполнено(Получатель)  Тогда
        Получатели.Добавить(Получатель);
        Получатели.Добавить(Получатель.ГруппаПолучателейСкидки)
    КонецЕсли;
    
    Возврат Получатели

КонецФункции // ПолучитьМассивПолучателей()


// Получает историю замен дисконтной карты, включаю даты и документы замены
//
// Параметры:
//  ДатаРасчета - дата рассчета;
//  ДисконтнаяКарта - карта для которой находим историю
//  ТолькоПредкиКарты - Булево.
//
// Возвращаемое значение:
//  Таблицу, включающую историю.
//
Функция ПолучитьРасширеннуюИсториюДисконтнойКарты(ДатаРасчета, ДисконтнаяКарта, ТолькоПредкиКарты) Экспорт

    ТаблицаРезультата = Новый ТаблицаЗначений;
    ТаблицаРезультата.Колонки.Добавить("ДатаЗамены");
    ТаблицаРезультата.Колонки.Добавить("Карта");
    ТаблицаРезультата.Колонки.Добавить("ДокументЗамены");

    СтрокаТаблицы = ТаблицаРезультата.Добавить();
    СтрокаТаблицы.ДатаЗамены = ДисконтнаяКарта.ДатаОткрытия;
    СтрокаТаблицы.Карта = ДисконтнаяКарта;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаИсточник,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаПриемник
    |ИЗ
    |   РегистрСведений.РегистрацияЗаменыКартПокупателей.СрезПоследних(
    |           &ДатаРасчета,
    |           КартаПриемник = &ДисконтнаяКарта
    |               ИЛИ (НЕ &ТолькоПредкиКарты)
    |                   И КартаИсточник = &ДисконтнаяКарта) КАК РегистрацияЗаменыКартПокупателейСрезПоследних";
    
    Запрос.УстановитьПараметр("ДатаРасчета"      , ДатаРасчета);
    Запрос.УстановитьПараметр("ДисконтнаяКарта"  , ДисконтнаяКарта);
    Запрос.УстановитьПараметр("ТолькоПредкиКарты", ТолькоПредкиКарты);
    
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда
        Возврат ТаблицаРезультата;
    КонецЕсли;
    
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаИсточник,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаПриемник,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.Период КАК ДатаЗамены,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.Регистратор КАК ДокументЗамены,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаИсточник.ДатаОткрытия КАК ДатаОткрытияИсточник,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаПриемник.ДатаОткрытия КАК ДатаОткрытияПриемник
    |ИЗ
    |   РегистрСведений.РегистрацияЗаменыКартПокупателей.СрезПоследних(&ДатаРасчета, ) КАК РегистрацияЗаменыКартПокупателейСрезПоследних";
    
    
    Результат = Запрос.Выполнить();
    ТаблицаЗапроса = Результат.Выгрузить();
    
    НашлиЭлемент         = Истина;
    СтрокаТаблицЗапроса  = Неопределено;
    ТекущийЭлементПоиска = ДисконтнаяКарта;
    
    Пока НашлиЭлемент Цикл
        
        СтрокаТаблицЗапроса = ТаблицаЗапроса.Найти(ТекущийЭлементПоиска, "КартаПриемник");
        
        Если СтрокаТаблицЗапроса = Неопределено
         ИЛИ НЕ ЗначениеЗаполнено(СтрокаТаблицЗапроса.КартаИсточник) Тогда
            Прервать; //Цепочка прервалась
        ИначеЕсли НЕ ТаблицаРезультата.Найти(СтрокаТаблицЗапроса.КартаИсточник, "Карта") = Неопределено Тогда
            Прервать; //Дополнительная проверка глухие на циклы
        Иначе
            СтрокаТаблицы.ДатаЗамены     = СтрокаТаблицЗапроса.ДатаЗамены;
            СтрокаТаблицы.ДокументЗамены = СтрокаТаблицЗапроса.ДокументЗамены;
            
            СтрокаТаблицы = ТаблицаРезультата.Вставить(0);
            СтрокаТаблицы.ДатаЗамены = СтрокаТаблицЗапроса.ДатаОткрытияИсточник;
            СтрокаТаблицы.Карта      = СтрокаТаблицЗапроса.КартаИсточник;
            
            ТекущийЭлементПоиска = СтрокаТаблицЗапроса.КартаИсточник;
        КонецЕсли;
        
    КонецЦикла;
    
    Если ТолькоПредкиКарты Тогда
        Возврат ТаблицаРезультата;
    КонецЕсли;
    
    ТекущийЭлементПоиска = ДисконтнаяКарта;
    
    Пока НашлиЭлемент Цикл
        
        СтрокаТаблицЗапроса = ТаблицаЗапроса.Найти(ТекущийЭлементПоиска, "КартаИсточник");
        
        Если СтрокаТаблицЗапроса = Неопределено
         ИЛИ НЕ ЗначениеЗаполнено(СтрокаТаблицЗапроса.КартаПриемник) Тогда
            Прервать; //Цепочка прервалась
        ИначеЕсли НЕ ТаблицаРезультата.Найти(СтрокаТаблицЗапроса.КартаПриемник, "Карта")= Неопределено Тогда
            Прервать; //Дополнительная проверка глухие на циклы
        Иначе
            СтрокаТаблицы = ТаблицаРезультата.Добавить();
            СтрокаТаблицы.ДатаЗамены     = СтрокаТаблицЗапроса.ДатаЗамены;
            СтрокаТаблицы.ДокументЗамены = СтрокаТаблицЗапроса.ДокументЗамены;
            СтрокаТаблицы.Карта          = СтрокаТаблицЗапроса.КартаПриемник;
            
            ТекущийЭлементПоиска = СтрокаТаблицЗапроса.КартаПриемник;
        КонецЕсли;
        
    КонецЦикла;
    
    Возврат ТаблицаРезультата;
    
    
    
КонецФункции // ПолучитьРасширеннуюИсториюДисконтнойКарты()


// Получает историю замен дисконтной карты
//
// Параметры:
//  ДатаРасчета - дата рассчета;
//  ДисконтнаяКарта - карта для которой находим историю
//  ТолькоПредкиКарты - Булево.
//
// Возвращаемое значение:
//   Массив карт, включающий саму карту.
//
Функция ПолучитьИсториюДисконтнойКарты(ДатаРасчета, ДисконтнаяКарта, ТолькоПредкиКарты) Экспорт

    МассивКарт = Новый Массив;
    // Быстрая проверка на наличие истории
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаИсточник,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаПриемник
    |ИЗ
    |   РегистрСведений.РегистрацияЗаменыКартПокупателей.СрезПоследних(
    |           &ДатаРасчета,
    |           КартаПриемник = &ДисконтнаяКарта
    |               ИЛИ (НЕ &ТолькоПредкиКарты)
    |                   И КартаИсточник = &ДисконтнаяКарта) КАК РегистрацияЗаменыКартПокупателейСрезПоследних";
    
    Запрос.УстановитьПараметр("ДатаРасчета"      , ДатаРасчета);
    Запрос.УстановитьПараметр("ДисконтнаяКарта"  , ДисконтнаяКарта);
    Запрос.УстановитьПараметр("ТолькоПредкиКарты", ТолькоПредкиКарты);
    
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда
        МассивКарт.Добавить(ДисконтнаяКарта);
        Возврат МассивКарт;
    КонецЕсли;
    
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаИсточник,
    |   РегистрацияЗаменыКартПокупателейСрезПоследних.КартаПриемник
    |ИЗ
    |   РегистрСведений.РегистрацияЗаменыКартПокупателей.СрезПоследних(&ДатаРасчета, ) КАК РегистрацияЗаменыКартПокупателейСрезПоследних";
    
    
    Результат = Запрос.Выполнить();
    ТаблицаЗапроса = Результат.Выгрузить();
    
    НашлиЭлемент         = Истина;
    СтрокаТаблицЗапроса  = Неопределено;
    ТекущийЭлементПоиска = ДисконтнаяКарта;
    
    Пока НашлиЭлемент Цикл
        
        СтрокаТаблицЗапроса = ТаблицаЗапроса.Найти(ТекущийЭлементПоиска, "КартаПриемник");
        
        Если СтрокаТаблицЗапроса = Неопределено
         ИЛИ НЕ ЗначениеЗаполнено(СтрокаТаблицЗапроса.КартаИсточник) Тогда
            Прервать; //Цепочка прервалась
        ИначеЕсли НЕ МассивКарт.Найти(СтрокаТаблицЗапроса.КартаИсточник) = Неопределено Тогда
            Прервать; //Дополнительная проверка глухие на циклы
        Иначе
            МассивКарт.Добавить(СтрокаТаблицЗапроса.КартаИсточник);
            
            ТекущийЭлементПоиска = СтрокаТаблицЗапроса.КартаИсточник;
        КонецЕсли;
        
    КонецЦикла;
    
    МассивКарт.Добавить(ДисконтнаяКарта);
    
    Если ТолькоПредкиКарты Тогда
        Возврат МассивКарт;
    КонецЕсли;
    
    ТекущийЭлементПоиска = ДисконтнаяКарта;
    
    Пока НашлиЭлемент Цикл
        
        СтрокаТаблицЗапроса = ТаблицаЗапроса.Найти(ТекущийЭлементПоиска, "КартаИсточник");
        
        Если СтрокаТаблицЗапроса = Неопределено
         ИЛИ НЕ ЗначениеЗаполнено(СтрокаТаблицЗапроса.КартаПриемник) Тогда
            Прервать; //Цепочка прервалась
        ИначеЕсли НЕ МассивКарт.Найти(СтрокаТаблицЗапроса.КартаПриемник) = Неопределено Тогда
            Прервать; //Дополнительная проверка глухие на циклы
        Иначе
            МассивКарт.Добавить(СтрокаТаблицЗапроса.КартаПриемник);
            
            ТекущийЭлементПоиска = СтрокаТаблицЗапроса.КартаПриемник;
        КонецЕсли;
        
    КонецЦикла;
    
    Возврат МассивКарт;
    
КонецФункции // ПолучитьИсториюДисконтнойКарты()


// Функция возвращает дерево значений, выгруженное из результата запроса по скидкам.
//
// Параметры:
//  ДокументОбъект - Документ в котором рассчитываем автоматические скидки
//  ТаблицаТоваров - Таблица значений в которую выгружена таблица товаров из документа
//  ДатаСкидок - дата, на которую необходимо рассчитать скидки.
//  СтруктураПараметров - Параметры для расчета
//  Магазин - магазин, в котором рассчитываем скидки
//  ЕстьТЧПодарки - булево, определяет необходимость расчета скидок подарков
//
// Возвращаемое значение:
//  ДеревоЗначений.
//
Функция ЗапросПоСкидкам(ДокументОбъект,ТаблицаТоваров, ДатаСкидок, СтруктураПараметров, Магазин, ЕстьТЧПодарки)
    Перем ВидРеализации, СуммаДокумента, ДисконтнаяКарта, ВидыОплат;
    Перем Получатель, НомерЧека, БлижайшийДеньРождения, Купоны;
    Перем МоментПроверкиСообщений, ТолькоСообщения;

    СтруктураПараметров.Свойство("ВидРеализации" , ВидРеализации);
    СтруктураПараметров.Свойство("СуммаДокумента", СуммаДокумента);
    СтруктураПараметров.Свойство("Получатель"    , Получатель);
    СтруктураПараметров.Свойство("Карта"         , ДисконтнаяКарта);
    СтруктураПараметров.Свойство("ВидыОплат"     , ВидыОплат);
    СтруктураПараметров.Свойство("НомерЧека"     , НомерЧека);
    СтруктураПараметров.Свойство("Купоны"        , Купоны);
    
    Если НЕ СтруктураПараметров.Свойство("ТолькоСообщения"        , ТолькоСообщения) Тогда
        ТолькоСообщения = Ложь;
    КонецЕсли;
    
    СтруктураПараметров.Свойство("МоментПроверкиСообщений", МоментПроверкиСообщений);
    Если ЗначениеЗаполнено(МоментПроверкиСообщений)  Тогда
        ПроверкаСообщений = Истина;
    Иначе
        ПроверкаСообщений = Ложь;
    КонецЕсли;
    

    Если НЕ ЗначениеЗаполнено(НомерЧека) Тогда
        НомерЧека = 1;
    КонецЕсли;

    
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ
    |   ТаблицаТовары.Номенклатура,
    |   ТаблицаТовары.ХарактеристикаНоменклатуры,
    |   ТаблицаТовары.СуммаБезСкидки,
    |   ТаблицаТовары.Количество,
    |   ТаблицаТовары.Коэффициент,
    |   ТаблицаТовары.Цена
    |ПОМЕСТИТЬ ТаблицаТовары
    |ИЗ
    |   &ТаблицаТовары КАК ТаблицаТовары";
    
    Запрос.УстановитьПараметр("ТаблицаТовары", ТаблицаТоваров);
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    Результат = Запрос.Выполнить();
    
    
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   ВложенныйЗапрос.Номенклатура,
    |   ВложенныйЗапрос.ХарактеристикаНоменклатуры,
    |   ВложенныйЗапрос.СуммаБезСкидки,
    |   ВложенныйЗапрос.Количество * ВложенныйЗапрос.Коэффициент / ВложенныйЗапрос.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент КАК Количество
    |ПОМЕСТИТЬ ТаблицаВЗапросе
    |ИЗ
    |   (ВЫБРАТЬ
    |       ВЫРАЗИТЬ(ТаблицаТовары.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
    |       ТаблицаТовары.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
    |       ТаблицаТовары.СуммаБезСкидки КАК СуммаБезСкидки,
    |       ТаблицаТовары.Количество КАК Количество,
    |       ТаблицаТовары.Коэффициент КАК Коэффициент
    |   ИЗ
    |       ТаблицаТовары КАК ТаблицаТовары) КАК ВложенныйЗапрос";

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

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

    
    Запрос.Текст = ТекстЗапроса;
    
    Возврат Запрос.Выполнить().Выгрузить();

КонецФункции // ЗапросПоСкидкам()

//  Функция рассчиттывает значение скидки по строке
//
// Параметры:
//  СтрокаСкидки - Строка информации о скидке
//  СтрокаТоваров - Строка табличной части Товары
//  Магазин - Магазин в котором рассчитывается скидка
//  ДатаДокумента - Дата документа необходима для расчета скидки по цене
//  СуммаБезСкидки - Число, сумма от которой рассчитавается скидка;
//
// Возвращаемое значение:
//  Скидка - сумма скидки
//
Функция РассчитатьЗначениеСкидки(СтрокаСкидки, СтрокаТоваров, Магазин, ДатаДокумента, СуммаБезСкидки, ПрименитьОрганичениеЦеныПоМагазину = Истина)

    Скидка = 0;
    Если СтрокаСкидки.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.Процент Тогда
        Скидка = СуммаБезСкидки * СтрокаСкидки.ЗначениеСкидкиНаценки/100;
    ИначеЕсли СтрокаСкидки.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.Сумма Тогда
        Скидка = Мин(СуммаБезСкидки,СтрокаСкидки.ЗначениеСкидкиНаценки);
    ИначеЕсли СтрокаСкидки.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.ТипЦен Тогда
        Если Магазин.ТипЦенРозничнойТорговли = СтрокаСкидки.ЗначениеСкидкиНаценки Тогда
            Цена = Ценообразование.ПолучитьЦенуНоменклатурыВРознице(ДатаДокумента, Магазин, СтрокаТоваров.Номенклатура, СтрокаТоваров.ХарактеристикаНоменклатуры, СтрокаТоваров.ЕдиницаИзмерения);
        Иначе
            Цена = Ценообразование.ПолучитьЦенуНоменклатурыПоТипуЦен(ДатаДокумента, СтрокаСкидки.ЗначениеСкидкиНаценки, СтрокаТоваров.Номенклатура, СтрокаТоваров.ХарактеристикаНоменклатуры, СтрокаТоваров.ЕдиницаИзмерения);
        КонецЕсли;
        
        Если ЗначениеЗаполнено(Цена) Тогда
            Скидка = СуммаБезСкидки - СтрокаТоваров.Количество*Цена;
        КонецЕсли;
    КонецЕсли;
    
    Если Скидка>0 И ЗначениеЗаполнено(СтрокаСкидки.ЗначениеОграничения) Тогда
        МаксимальнаяСкидка = СтрокаСкидки.ЗначениеОграничения;
        Скидка = Мин(Скидка, МаксимальнаяСкидка);
        
    КонецЕсли;
    
    Если ПрименитьОрганичениеЦеныПоМагазину И Скидка > 0 Тогда
        Цена = СтрокаТоваров.МинимальнаяЦена;
        
        Если ЗначениеЗаполнено(Цена) Тогда
            МаксимальнаяСкидка = СуммаБезСкидки - СтрокаТоваров.Количество*Цена;
            Скидка = Мин(Скидка, МаксимальнаяСкидка);
        КонецЕсли;
    КонецЕсли;

    Возврат Скидка;

КонецФункции // РассчитатьЗначениеСкидки()

// Рекурсивно обходит дерево и рассчитывает скидки
//
// Параметры:
//  СтрокиДерева  - Массив скидок, по которым выполнилось условие
//  ВариантСовместногоПримененияСкидокНаценок - Вариант совместного применения
//  Корень - Булево. Признак верхнего уровня
//  СтрокаТоваров - Строка таблицы значений с данными из документа
//  Магазин - Магазин в котором рассчитывается скидка
//  ДатаДокумента - Дата документа необходима для расчета скидки по цене
//  ПрименитьОрганичениеЦеныПоМагазину - При расчете скидки суммой на чек, органичение цены по магазину не применяется.
//  ВытеснениеПрименено - Булево, показывает применено вытеснение. Используется для скидок суммой на сегмент (чек)
//
// Возвращаемое значение:
//  Сумма скидки
//
Функция ПолучитьРассчитатьСкидкиВДереве(СтрокиДерева, ВариантСовместногоПримененияСкидокНаценок, Корень, СтрокаТоваров, Магазин, ДатаДокумента, ПрименитьОрганичениеЦеныПоМагазину, ВытеснениеПрименено)
    
    Скидка = 0;
    
    Для каждого СтрокаДерева Из СтрокиДерева Цикл
        Если СтрокаДерева.ЭтоГруппа Тогда
            СтрокаДерева.Значение = ПолучитьРассчитатьСкидкиВДереве(СтрокаДерева.Строки, СтрокаДерева.ВариантСовместногоПримененияСкидокНаценок, Ложь, СтрокаТоваров, Магазин, ДатаДокумента, ПрименитьОрганичениеЦеныПоМагазину, ВытеснениеПрименено)
        Иначе
            Если ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Умножение 
                И СтрокаДерева.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.Процент Тогда
                СтрокаДерева.Значение = 0;
            Иначе
                Если СтрокаТоваров = Неопределено Тогда
                    СтрокаДерева.Значение = РассчитатьЗначениеСкидки(СтрокаДерева, СтрокаТоваров, Магазин, ДатаДокумента, СтрокаДерева.ЗначениеСкидкиНаценки, ПрименитьОрганичениеЦеныПоМагазину);
                Иначе   
                    СтрокаДерева.Значение = РассчитатьЗначениеСкидки(СтрокаДерева, СтрокаТоваров, Магазин, ДатаДокумента, СтрокаТоваров.СуммаБезСкидки, ПрименитьОрганичениеЦеныПоМагазину);
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Если ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Минимум Тогда
        СтрокиДерева.Сортировать("Значение Возр");
        Скидка = СтрокиДерева[0].Значение;
        СтрокиДерева[0].Использование = Истина;
    ИначеЕсли ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Максимум Тогда
        СтрокиДерева.Сортировать("Значение Убыв");
        Скидка = СтрокиДерева[0].Значение;
        СтрокиДерева[0].Использование = Истина;
    ИначеЕсли ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Вытеснение Тогда
        Если Не ВытеснениеПрименено Тогда
            СтрокиДерева.Сортировать("ПорядокПрименения Возр, Значение Возр");
            Скидка = СтрокиДерева[0].Значение;
            СтрокиДерева[0].Использование = Истина;
        Иначе
            Скидка = СтрокиДерева.Итог("Значение");
            Для каждого СтрокаДерева Из СтрокиДерева Цикл
                СтрокаДерева.Использование = Истина;
            КонецЦикла;
        КонецЕсли; 
    ИначеЕсли ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Сложение Тогда
        Скидка = СтрокиДерева.Итог("Значение");
        Для каждого СтрокаДерева Из СтрокиДерева Цикл
            СтрокаДерева.Использование = Истина;
        КонецЦикла;
    ИначеЕсли ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Умножение Тогда
        СтрокиДерева.Сортировать("ПорядокПрименения Возр");
        ИндексСтроки = 0;
        Для каждого СтрокаДерева Из СтрокиДерева Цикл
            Если СтрокаДерева.ЭтоГруппа Тогда
                Скидка = Скидка + СтрокаДерева.Значение;
            ИначеЕсли СтрокаДерева.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.Процент Тогда
                СтрокаДерева.Значение = РассчитатьЗначениеСкидки(СтрокаДерева, СтрокаТоваров, Магазин, ДатаДокумента, СтрокаТоваров.СуммаБезСкидки-Скидка, ПрименитьОрганичениеЦеныПоМагазину);
                Скидка = Скидка + СтрокаДерева.Значение;
            ИначеЕсли СтрокаДерева.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.Сумма Тогда
                Скидка = Скидка + СтрокаДерева.Значение;
            ИначеЕсли СтрокаДерева.ТипПреимуществаПоСкидке = Перечисления.ТипыПреимуществПоСкидкам.ТипЦен Тогда
                Скидка = СтрокаДерева.Значение;
                Для Индекс = 0 По ИндексСтроки Цикл
                    СтрокиДерева[Индекс].Использование = Ложь;
                КонецЦикла;
            КонецЕсли;
            СтрокаДерева.Использование = Истина;
            ИндексСтроки = ИндексСтроки + 1;
        КонецЦикла;
    КонецЕсли;
    
    Если ПрименитьОрганичениеЦеныПоМагазину И Корень И Скидка>0 Тогда
        
        Цена = Ценообразование.ПолучитьМинимальнуюЦенуНоменклатурыВРознице(ДатаДокумента, Магазин,СтрокаТоваров.Номенклатура, СтрокаТоваров.ХарактеристикаНоменклатуры, СтрокаТоваров.ЕдиницаИзмерения);
        
        Если ЗначениеЗаполнено(Цена) Тогда
            МаксимальнаяСкидка = СтрокаТоваров.СуммаБезСкидки - СтрокаТоваров.Количество*Цена;
            Скидка = Мин(Скидка, МаксимальнаяСкидка);
        КонецЕсли;
    КонецЕсли;
    
    Возврат Скидка;
КонецФункции // ПолучитьРассчитатьСкидкиВДереве()

// Заполняет таблицу, примененных скидок по дереву значений
//
// Параметры:
//  СтрокиДерева  - Массив скидок, по которым выполнилось условие
//  ТаблицаПримененныхСкидок - таблица, в которую помещаем примененные скидки
//
Процедура  ЗаполнитьТаблицуПримененныхСкидок(СтрокиДерева, ТаблицаПримененныхСкидок)
    
    Для каждого СтрокаДерева Из СтрокиДерева Цикл
        Если ЗначениеЗаполнено(СтрокаДерева.Использование) И СтрокаДерева.Использование Тогда
            Если СтрокаДерева.ЭтоГруппа Тогда
                ЗаполнитьТаблицуПримененныхСкидок(СтрокаДерева.Строки, ТаблицаПримененныхСкидок)
            Иначе
                СтрокаПримененнойСкидки = ТаблицаПримененныхСкидок.Добавить();
                ЗаполнитьЗначенияСвойств(СтрокаПримененнойСкидки, СтрокаДерева);
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры // ЗаполнитьПримененныеСкидки()

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

// Заполняет данными таблицы, табличнуб часть скидки
//
// Параметры
//  ТаблицаПримененныхСкидок - таблица, в которое находятся данные о примененных скидках
//  ТабличнаяЧастьСкидки       - табличная часть скидок,
//
Процедура ЗаполнитьТабличнуюЧастьСкидки(ТаблицаПримененныхСкидок, ТабличнаяЧастьСкидки, КлючСтрокиТоваров)

    пТаблицаПримененныхСкидок = ТаблицаПримененныхСкидок.Скопировать();
    пТаблицаПримененныхСкидок.Колонки.Значение.Имя = "Сумма";
    пТаблицаПримененныхСкидок.Колонки.Добавить("КлючСтроки");
    пТаблицаПримененныхСкидок.ЗаполнитьЗначения(КлючСтрокиТоваров,"КлючСтроки");
    
    ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(пТаблицаПримененныхСкидок, ТабличнаяЧастьСкидки);
    
КонецПроцедуры // ЗаполнитьТабличнуюЧастьСкидки()

// Из общей таблицы возвращает таблицу подарков или скидок сумм на чек
//
// Параметры:
//  ТаблицаСкидок - таблица всех скидок
//  СкидкиПодарки - Булево, флга возврата или подарков или сумм на чек
//
// Возвращаемое значение:
//  Таблица значений
//
Функция ОпределитьТаблицуНаСегменты(ТаблицаСкидок, СкидкиПодарки = Истина)

    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТаблицаСкидок.СкидкаНаценка,
    |   ТаблицаСкидок.ЗначениеСкидкиНаценки,
    |   ТаблицаСкидок.ТипПреимуществаПоСкидке,
    |   ТаблицаСкидок.ЗначениеОграничения,
    |   ТаблицаСкидок.СегментБазыРасчетаСкидки,
    |   ТаблицаСкидок.ЕстьБазаРасчета,
    |   ТаблицаСкидок.СегментНоменклатуры,
    |   ТаблицаСкидок.СегментИсключаемойНоменклатуры,
    |   ТаблицаСкидок.СкидкаНаЕдиныйКомплект,
    |   ТаблицаСкидок.НакопительнаяСкидка,
    |   ТаблицаСкидок.ЭтоПодарок,
    |   ТаблицаСкидок.УсловиеПредоставленияСкидки,
    |   ТаблицаСкидок.ЗначениеУсловия,
    |   ТаблицаСкидок.Позиционная,
    |   ТаблицаСкидок.ПодарокИзСписка,
    |   ТаблицаСкидок.ПодарокИзКорзиныПокупателя,
    |   ТаблицаСкидок.КоличествоПодарковИзКорзиныПокупателя,
    |   ТаблицаСкидок.УчитыватьПодарокКакПродажу,
    |   ТаблицаСкидок.СкидкаСуммойНаЧек
    |ПОМЕСТИТЬ ТаблицаСкидокПодарков
    |ИЗ
    |   &ТаблицаСкидок КАК ТаблицаСкидок
    |ГДЕ
    |   ВЫБОР
    |           КОГДА &СкидкиПодарки
    |               ТОГДА ТаблицаСкидок.ЭтоПодарок
    |           ИНАЧЕ ТаблицаСкидок.СкидкаСуммойНаЧек
    |       КОНЕЦ
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ РАЗЛИЧНЫЕ
    |   ТаблицаСкидокПодарков.СкидкаНаценка,
    |   ВЫБОР
    |       КОГДА (НЕ ТаблицаСкидокПодарков.ЗначениеОграничения = 0)
    |               И ТаблицаСкидокПодарков.ЗначениеОграничения < ТаблицаСкидокПодарков.ЗначениеСкидкиНаценки
    |           ТОГДА ТаблицаСкидокПодарков.ЗначениеОграничения
    |       ИНАЧЕ ТаблицаСкидокПодарков.ЗначениеСкидкиНаценки
    |   КОНЕЦ КАК ЗначениеСкидкиНаценки,
    |   ТаблицаСкидокПодарков.ТипПреимуществаПоСкидке,
    |   ТаблицаСкидокПодарков.ЗначениеОграничения,
    |   ТаблицаСкидокПодарков.СегментБазыРасчетаСкидки,
    |   ТаблицаСкидокПодарков.ЕстьБазаРасчета,
    |   ТаблицаСкидокПодарков.СегментНоменклатуры,
    |   ТаблицаСкидокПодарков.СегментИсключаемойНоменклатуры,
    |   ТаблицаСкидокПодарков.СкидкаНаЕдиныйКомплект,
    |   ТаблицаСкидокПодарков.НакопительнаяСкидка,
    |   ТаблицаСкидокПодарков.ЭтоПодарок,
    |   ТаблицаСкидокПодарков.УсловиеПредоставленияСкидки,
    |   ТаблицаСкидокПодарков.ЗначениеУсловия,
    |   ТаблицаСкидокПодарков.Позиционная,
    |   ТаблицаСкидокПодарков.ПодарокИзСписка,
    |   ТаблицаСкидокПодарков.ПодарокИзКорзиныПокупателя,
    |   ТаблицаСкидокПодарков.КоличествоПодарковИзКорзиныПокупателя,
    |   ТаблицаСкидокПодарков.УчитыватьПодарокКакПродажу,
    |   ТаблицаСкидокПодарков.СкидкаСуммойНаЧек
    |ИЗ
    |   ТаблицаСкидокПодарков КАК ТаблицаСкидокПодарков";
    
    Запрос.УстановитьПараметр("ТаблицаСкидок", ТаблицаСкидок);
    Запрос.УстановитьПараметр("СкидкиПодарки", СкидкиПодарки);
    
    Результат = Запрос.Выполнить();
    
    Возврат Результат.Выгрузить();

КонецФункции // ОпределитьТаблицуПодарков()


// Удаляет скидку из таблицы
//
// Параметры
//  ТаблицаСкидок - таблица всех скидок
//  СкидкаНаценка - удаляемая скидка
//  Номенклатура - для скидок по строке удаляется только эта номенклатура
//  ХарактеристикаНоменклатуры  - для скидок по строке удаляется только Характистика
//
Процедура УдалитьСкидкуИзТаблицы(ТаблицаСкидок, СкидкаНаценка, Номенклатура = Неопределено, ХарактеристикаНоменклатуры = Неопределено)

    СтруктураПоиска = Новый Структура;
    СтруктураПоиска.Вставить("СкидкаНаценка", СкидкаНаценка);
    
    Если Не Номенклатура = Неопределено Тогда
        СтруктураПоиска.Вставить("Номенклатура", Номенклатура);
        СтруктураПоиска.Вставить("ХарактеристикаНоменклатуры", ХарактеристикаНоменклатуры);
    КонецЕсли;
    
    СтрокиТаблицыСкидок = ТаблицаСкидок.НайтиСтроки(СтруктураПоиска);
    Для каждого СтрокаТаблицыСкидок Из СтрокиТаблицыСкидок Цикл
        ТаблицаСкидок.Удалить(СтрокаТаблицыСкидок);
    КонецЦикла;

КонецПроцедуры // УдалитьСкидкуИзТаблицы()



// Вытесняет строки в таблице скидок
//
// Параметры
//  ТаблицаСкидок - Таблица скидок, применяющихся скидок
//  СтрокиДерева  - Массив скидок, по которым выполнилось условие
//  ВариантСовместногоПримененияСкидокНаценок - Вариант совместного применения
//
Процедура ПрименитьВытеснениеВДереве(ТаблицаСкидок, СтрокиДерева, ВариантСовместногоПримененияСкидокНаценок, УдаляемВсеСтроки)
    
    ПерваяСтрока = Истина;
    
    Для каждого СтрокаДерева Из СтрокиДерева Цикл
        Если УдаляемВсеСтроки Тогда
            Если СтрокаДерева.ЭтоГруппа Тогда
                ПрименитьВытеснениеВДереве(ТаблицаСкидок, СтрокаДерева.Строки, СтрокаДерева.ВариантСовместногоПримененияСкидокНаценок, Истина)
            ИначеЕсли СтрокаДерева.Строки[0].СкидкаНаГруппуСтрок Тогда
                УдалитьСкидкуИзТаблицы(ТаблицаСкидок, СтрокаДерева.СкидкаНаценка)
            Иначе
                //Скидка на строку
                УдалитьСкидкуИзТаблицы(ТаблицаСкидок, СтрокаДерева.СкидкаНаценка, СтрокаДерева.Строки[0].Номенклатура, СтрокаДерева.Строки[0].ХарактеристикаНоменклатуры)
            КонецЕсли;
        Иначе
            Если ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Вытеснение Тогда
                Если ПерваяСтрока Тогда
                    ПерваяСтрока = Ложь;
                    Если СтрокаДерева.ЭтоГруппа Тогда
                        ПрименитьВытеснениеВДереве(ТаблицаСкидок, СтрокаДерева.Строки, СтрокаДерева.ВариантСовместногоПримененияСкидокНаценок, Ложь)
                    КонецЕсли;
                Иначе
                    Если СтрокаДерева.ЭтоГруппа Тогда
                        ПрименитьВытеснениеВДереве(ТаблицаСкидок, СтрокаДерева.Строки, СтрокаДерева.ВариантСовместногоПримененияСкидокНаценок, Истина)
                    ИначеЕсли СтрокаДерева.Строки[0].СкидкаНаГруппуСтрок Тогда
                        УдалитьСкидкуИзТаблицы(ТаблицаСкидок, СтрокаДерева.СкидкаНаценка)
                    Иначе
                        //Скидка на строку
                        УдалитьСкидкуИзТаблицы(ТаблицаСкидок, СтрокаДерева.СкидкаНаценка, СтрокаДерева.Строки[0].Номенклатура, СтрокаДерева.Строки[0].ХарактеристикаНоменклатуры)
                    КонецЕсли;
                КонецЕсли;
            Иначе
                ПерваяСтрока = Ложь;
                Если СтрокаДерева.ЭтоГруппа Тогда
                    ПрименитьВытеснениеВДереве(ТаблицаСкидок, СтрокаДерева.Строки, СтрокаДерева.ВариантСовместногоПримененияСкидокНаценок, УдаляемВсеСтроки)
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры // ПрименитьВытеснениеВДереве()


// Вытесняет скидки по правилам пересечения
//
// Параметры
//  ТаблицаСкидок - Таблица скидок, применяющихся скидок
//  ТаблицаНеПрименяемыхПодарков - Таблица подарков не прошедших условия.
//
Процедура ВытеснитьСкидкиНаСегментНоменклатуры(ТаблицаСкидок, ТаблицаНеПрименяемыхПодарков)

    //Удаляем не нужные скидки
    
    Для каждого СтрокаТаблицы Из ТаблицаНеПрименяемыхПодарков Цикл
        УдалитьСкидкуИзТаблицы(ТаблицаСкидок, СтрокаТаблицы.СкидкаНаценка)
    КонецЦикла;
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТаблицаСкидок.Номенклатура КАК Номенклатура,
    |   ТаблицаСкидок.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
    |   ВЫРАЗИТЬ(ТаблицаСкидок.СкидкаНаценка КАК Справочник.СкидкиНаценки) КАК СкидкаНаценка,
    |   ТаблицаСкидок.СкидкаСуммойНаЧек,
    |   ТаблицаСкидок.ЭтоПодарок
    |ПОМЕСТИТЬ ТаблицаСкидок
    |ИЗ
    |   &ТаблицаСкидок КАК ТаблицаСкидок
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ РАЗЛИЧНЫЕ
    |   ТаблицаСкидок.Номенклатура КАК Номенклатура,
    |   ТаблицаСкидок.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
    |ИЗ
    |   ТаблицаСкидок КАК ТаблицаСкидок";
    
    Запрос.УстановитьПараметр("ТаблицаСкидок", ТаблицаСкидок);
    Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
    
    Результат = Запрос.Выполнить();
    ТаблицаНоменклатуры = Результат.Выгрузить();
    Для каждого СтрокаТаблицы Из ТаблицаНоменклатуры Цикл
    
        Запрос.Текст = 
        "ВЫБРАТЬ
        |   ТаблицаСкидок.Номенклатура КАК Номенклатура,
        |   ТаблицаСкидок.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
        |   ТаблицаСкидок.СкидкаНаценка КАК СкидкаНаценка,
        |   ТаблицаСкидок.СкидкаНаценка.ЭтоГруппа КАК ЭтоГруппа,
        |   ВЫБОР
        |       КОГДА ТаблицаСкидок.СкидкаСуммойНаЧек
        |               ИЛИ ТаблицаСкидок.ЭтоПодарок
        |           ТОГДА ИСТИНА
        |       ИНАЧЕ ЛОЖЬ
        |   КОНЕЦ КАК СкидкаНаГруппуСтрок,
        |   ТаблицаСкидок.СкидкаНаценка.ВариантСовместногоПримененияСкидокНаценок КАК ВариантСовместногоПримененияСкидокНаценок
        |ИЗ
        |   ТаблицаСкидок КАК ТаблицаСкидок
        |ГДЕ
        |   ТаблицаСкидок.Номенклатура = &Номенклатура
        |   И ТаблицаСкидок.ХарактеристикаНоменклатуры = &ХарактеристикаНоменклатуры
        |
        |УПОРЯДОЧИТЬ ПО
        |   ТаблицаСкидок.СкидкаНаценка.ПорядокПрименения
        |ИТОГИ ПО
        |   СкидкаНаценка ИЕРАРХИЯ";
        
        Запрос.УстановитьПараметр("Номенклатура", СтрокаТаблицы.Номенклатура);
        Запрос.УстановитьПараметр("ХарактеристикаНоменклатуры", СтрокаТаблицы.ХарактеристикаНоменклатуры);
        
        Результат = Запрос.Выполнить();
        ДеревоВытеснения = Результат.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
        
        ПрименитьВытеснениеВДереве(ТаблицаСкидок, ДеревоВытеснения.Строки, Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Максимум, Ложь)
    КонецЦикла;

КонецПроцедуры // ВытеснитьСкидкиНаСегментНоменклатуры()


// Из Таблицы скидок удаляем сообщения, помещаем их в таблицу сообщений, и подготавливаем эту таблицу
//
// Параметры
//  ТаблицаСкидок - Таблица скидок, применяющихся скидок
//  ТаблицаСообщений - Возвращаемая таблица сообщений
//
Процедура ОбработатьТаблицуСообщений(ТаблицаСкидок, ТаблицаСообщений)

    
    ТаблицаСообщений = ТаблицаСкидок.СкопироватьКолонки("СкидкаНаценка");
    
    СтруктураПоиска = Новый Структура;
    СтруктураПоиска.Вставить("ТипПреимуществаПоСкидке", Перечисления.ТипыПреимуществПоСкидкам.Сообщение);
    
    Для каждого СтрокаТаблицыСкидок Из ТаблицаСкидок.НайтиСтроки(СтруктураПоиска) Цикл
        
        
        СтрокаТаблицыСообщений = ТаблицаСообщений.Добавить();
        ЗаполнитьЗначенияСвойств(СтрокаТаблицыСообщений, СтрокаТаблицыСкидок);
        
        ТаблицаСкидок.Удалить(СтрокаТаблицыСкидок);
        
    КонецЦикла;
    
    ТаблицаСообщений.Свернуть("СкидкаНаценка");
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |   ВЫРАЗИТЬ(ТаблицаСообщений.СкидкаНаценка КАК Справочник.СкидкиНаценки) КАК СкидкаНаценка
    |ПОМЕСТИТЬ ТаблицаСообщений
    |ИЗ
    |   &ТаблицаСообщений КАК ТаблицаСообщений
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |   ТаблицаСообщений.СкидкаНаценка,
    |   ТаблицаСообщений.СкидкаНаценка.ТекстСообщения КАК ТекстСообщения
    |ИЗ
    |   ТаблицаСообщений КАК ТаблицаСообщений
    |ГДЕ
    |   (ТаблицаСообщений.СкидкаНаценка.Родитель = ЗНАЧЕНИЕ(Справочник.скидкиНаценки.ПустаяСсылка)
    |           ИЛИ ТаблицаСообщений.СкидкаНаценка.Родитель.ВариантСовместногоПримененияСкидокНаценок <> ЗНАЧЕНИЕ(Перечисление.ВариантыСовместногоПримененияСкидокНаценок.Вытеснение))
    |
    |ОБЪЕДИНИТЬ ВСЕ
    |
    |ВЫБРАТЬ
    |   ВложенныйЗапрос.СкидкаНаценка,
    |   ВложенныйЗапрос.СкидкаНаценка.ТекстСообщения
    |ИЗ
    |   (ВЫБРАТЬ
    |       ТаблицаСообщений.СкидкаНаценка КАК СкидкаНаценка
    |   ИЗ
    |       (ВЫБРАТЬ
    |           ТаблицаСообщений.СкидкаНаценка.Родитель КАК Родитель,
    |           МИНИМУМ(ТаблицаСообщений.СкидкаНаценка.ПорядокПрименения) КАК ПорядокПрименения
    |       ИЗ
    |           ТаблицаСообщений КАК ТаблицаСообщений
    |       ГДЕ
    |           ТаблицаСообщений.СкидкаНаценка.Родитель.ВариантСовместногоПримененияСкидокНаценок = ЗНАЧЕНИЕ(Перечисление.ВариантыСовместногоПримененияСкидокНаценок.Вытеснение)
    |       
    |       СГРУППИРОВАТЬ ПО
    |           ТаблицаСообщений.СкидкаНаценка.Родитель) КАК ТаблицаМинимумовПоРодителю
    |           ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаСообщений КАК ТаблицаСообщений
    |           ПО ТаблицаМинимумовПоРодителю.Родитель = ТаблицаСообщений.СкидкаНаценка.Родитель
    |               И ТаблицаМинимумовПоРодителю.ПорядокПрименения = ТаблицаСообщений.СкидкаНаценка.ПорядокПрименения) КАК ВложенныйЗапрос";
    
    Запрос.УстановитьПараметр("ТаблицаСообщений", ТаблицаСообщений);
    
    Результат = Запрос.Выполнить();
    ТаблицаСообщений = Результат.Выгрузить();
    
КонецПроцедуры // ОбработатьТаблицуСообщений()


// Процедура рассчитывает скидки в документе.
//
// Параметры:
//  ДокументОбъект             - документ, для которого рассчитываем скидки,
//  ТабличнаяЧастьНоменклатуры - табличная часть номенклатуры документа,
//  ТабличнаяЧастьСкидки       - табличная часть скидок,
//  СтруктураПараметров        - структура, содержащая дополнительные параметря, необходимые для расчета скидок.
//  ТаблицаСообщений           - Таблица в которую помещаются сообщения кассиру
//
Процедура РассчитатьСкидкиПриПродаже(ДокументОбъект, ТабличнаяЧастьНоменклатуры, ТабличнаяЧастьСкидки, ТабличнаяЧастьПодарки,
                                     СтруктураПараметров, ТаблицаСообщений = Неопределено) Экспорт

    Перем УчитыватьНДС, СуммаВключаетНДС, ДатаСкидок, Магазин;
    Перем ФлагИзмененияТабличнойЧастиТоваров;

    Если ТабличнаяЧастьНоменклатуры.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    Если ТипЗнч (ТабличнаяЧастьНоменклатуры) = Тип("ТаблицаЗначений") Тогда
        ТаблицаТоваров = ТабличнаяЧастьНоменклатуры.Скопировать();
        ЕстьПодарки    = НЕ ТабличнаяЧастьНоменклатуры.Колонки.Найти("ПродажаПодарка") = Неопределено;
    Иначе
        ЕстьПодарки    = НЕ ТабличнаяЧастьНоменклатуры.ВыгрузитьКолонки().Колонки.Найти("ПродажаПодарка") = Неопределено;
        ТаблицаТоваров = ТабличнаяЧастьНоменклатуры.Выгрузить();
    КонецЕсли;
    
    Если ЕстьПодарки Тогда
        ОтборПодарки = Новый Структура;
        ОтборПодарки.Вставить("ПродажаПодарка", Истина);
        СтрокиПодарки = ТабличнаяЧастьНоменклатуры.НайтиСтроки(ОтборПодарки);
        
        Для каждого СтрокаПодарок Из СтрокиПодарки Цикл
            
            ТабличнаяЧастьНоменклатуры.Удалить(СтрокаПодарок);
            
        КонецЦикла;
        
    КонецЕсли;
    
    ЕстьТЧСкидки = Не ТабличнаяЧастьСкидки = Неопределено;
    Если ЕстьТЧСкидки Тогда
        ТабличнаяЧастьСкидки.Очистить();
    КонецЕсли;
    
    ЕстьТЧПодарки = НЕ ТабличнаяЧастьПодарки = Неопределено;
    Если ЕстьТЧПодарки Тогда
        ТабличнаяЧастьПодарки.Очистить();
    КонецЕсли;
    
    СтруктураПараметров.Свойство("ДатаСкидок"                    , ДатаСкидок);
    СтруктураПараметров.Свойство("УчитыватьНДС"                  , УчитыватьНДС);
    СтруктураПараметров.Свойство("СуммаВключаетНДС"              , СуммаВключаетНДС);

    УчитыватьНДС     = ?(УчитыватьНДС     = Неопределено, Ложь, УчитыватьНДС);
    СуммаВключаетНДС = ?(СуммаВключаетНДС = Неопределено, Ложь, СуммаВключаетНДС);
    

    ТекущаяДата = ТекущаяДата();
    ДатаСкидок = ?(НЕ ЗначениеЗаполнено(ДатаСкидок), ДокументОбъект.Дата, ДатаСкидок);
    ДатаСкидок = ?(НачалоДня(ДатаСкидок) = ДатаСкидок,
                             Дата(
                             Год(    ДокументОбъект.Дата),
                             Месяц(  ДокументОбъект.Дата),
                             День(   ДокументОбъект.Дата),
                             Час(    ТекущаяДата),
                             Минута( ТекущаяДата),
                             Секунда(ТекущаяДата))
                             , ДатаСкидок);
    
    МетаданныеДокумента = ДокументОбъект.Метаданные();
    Магазин = Справочники.Магазины.ПустаяСсылка();
    Если ОбщегоНазначения.ЕстьРеквизитДокумента("КассаККМ", МетаданныеДокумента) Тогда
        Магазин = ДокументОбъект.КассаККМ.Магазин;
    ИначеЕсли ОбщегоНазначения.ЕстьРеквизитДокумента("Склад", МетаданныеДокумента) Тогда
        Магазин = ДокументОбъект.Склад.Магазин;
    КонецЕсли;
    
    ТаблицаТоваров.Колонки.Добавить("СуммаБезСкидки", Новый ОписаниеТипов("Число"));

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

    //Восстановим распределение скидки из документа
    Если НЕ ДокументСкидки =  Документы.m000Скидка.ПустаяСсылка() Тогда 
        Для Каждого СтрокаДокумента Из  ДокументСкидки.ТаблицаДвижений Цикл
            Для Каждого СтрокаТоваров Из  ТаблицаТоваров Цикл
                Если СтрокаДокумента.Номенклатура = СтрокаТоваров.Номенклатура Тогда
                     СтрокаТоваров.Сумма = СтрокаТоваров.СуммаБезСкидки - СтрокаДокумента.СуммаСкидки;              
                КонецЕсли;
            КонецЦикла;
        КонецЦикла;     
    КонецЕсли;
    
    
    
    //Восстановим распределение скидки в табличной части скидки
    
    Если НЕ ДокументСкидки =  Документы.m000Скидка.ПустаяСсылка() Тогда 
        Для Каждого СтрокаДокумента Из  ДокументСкидки.ТаблицаДвижений Цикл
            Для Каждого СтрокаТоваров Из  ТабличнаяЧастьСкидки Цикл
                Если СтрокаДокумента.НомерСтроки = СтрокаТоваров.КлючСтроки 
                И СтрокаТоваров.СкидкаНаценка.Наименование = m000Сервер.ПолучитьНастройку("Префикс") Тогда
                     СтрокаТоваров.Сумма = СтрокаДокумента.СуммаСкидки;
                 КонецЕсли;
            КонецЦикла;
        КонецЦикла;     
    КонецЕсли;                            

    //m000//
    
    
    ТабличнаяЧастьНоменклатуры.ЗагрузитьКолонку(ТаблицаТоваров.ВыгрузитьКолонку("Сумма"), "Сумма");
    
    Если УчитыватьНДС Тогда // рассчитаем сумму НДС строки таблицы значений
        Для Каждого СтрокаТЧ ИЗ ТаблицаТоваров Цикл
            СтрокаТЧ.СуммаНДС = Ценообразование.РассчитатьСуммуНДС(СтрокаТЧ.Сумма, 
                                                                   УчитыватьНДС, 
                                                                   ИСТИНА,
                                                                   Ценообразование.ПолучитьСтавкуНДС(СтрокаТЧ.СтавкаНДС));
            
            Если НЕ СуммаВключаетНДС Тогда
                СтрокаТЧ.Сумма = СтрокаТЧ.Сумма - СтрокаТЧ.СуммаНДС;
            КонецЕсли;
        КонецЦикла;
        ТабличнаяЧастьНоменклатуры.ЗагрузитьКолонку(ТаблицаТоваров.ВыгрузитьКолонку("СуммаНДС"), "СуммаНДС");
        Если НЕ СуммаВключаетНДС Тогда
            ТабличнаяЧастьНоменклатуры.ЗагрузитьКолонку(ТаблицаТоваров.ВыгрузитьКолонку("Сумма"), "Сумма");
        КонецЕсли;
    КонецЕсли;
    
    Если ЕстьТЧПодарки Тогда
        //Скидки подарки
        ТаблицаСкидокПодарковПослеВытеснения = ОпределитьТаблицуНаСегменты(ТаблицаСкидок);
        
        Если ТаблицаСкидокПодарковПослеВытеснения.Количество()>0 Тогда
            
            
            КолвоЭлементовКоллекции = ТаблицаСкидокПодарков.Количество();
            Для ОбратныйИндекс = 1 По КолвоЭлементовКоллекции Цикл
                ЭлементКоллекции = ТаблицаСкидокПодарков[КолвоЭлементовКоллекции - ОбратныйИндекс];
                
                СтрокаТаблицыПодарковПослеВытеснения = ТаблицаСкидокПодарковПослеВытеснения.Найти(ЭлементКоллекции.СкидкаНаценка, "СкидкаНаценка");
                Если СтрокаТаблицыПодарковПослеВытеснения = Неопределено Тогда
                    ТаблицаСкидокПодарков.Удалить(ЭлементКоллекции);
                КонецЕсли;
            КонецЦикла;
            
            Если ТаблицаСкидокПодарков.Количество() > 0 Тогда
                ЗаполнитьТаблицуПодарков(ТаблицаСкидокПодарков, ТаблицаТоваров, ТабличнаяЧастьСкидки, ТабличнаяЧастьПодарки, Магазин, ФлагИзмененияТабличнойЧастиТоваров);
                
                Если ФлагИзмененияТабличнойЧастиТоваров Тогда
                    ТабличнаяЧастьНоменклатуры.ЗагрузитьКолонку(ТаблицаТоваров.ВыгрузитьКолонку("Сумма"), "Сумма");
                    
                    Если УчитыватьНДС Тогда // рассчитаем сумму НДС строки таблицы значений
                        Для Каждого СтрокаТЧ ИЗ ТаблицаТоваров Цикл
                            СтрокаТЧ.СуммаНДС = Ценообразование.РассчитатьСуммуНДС(СтрокаТЧ.Сумма, 
                                                                                   УчитыватьНДС, 
                                                                                   СуммаВключаетНДС,
                                                                                   Ценообразование.ПолучитьСтавкуНДС(СтрокаТЧ.СтавкаНДС));
                        КонецЦикла;
                        ТабличнаяЧастьНоменклатуры.ЗагрузитьКолонку(ТаблицаТоваров.ВыгрузитьКолонку("СуммаНДС"), "СуммаНДС");
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
    
    Если ЕстьТЧСкидки Тогда
        ТаблицаСкидок = ТабличнаяЧастьСкидки.Выгрузить();
        ТаблицаСкидок.Свернуть("КлючСтроки, СкидкаНаценка","Сумма");
        ТабличнаяЧастьСкидки.Загрузить(ТаблицаСкидок);
    КонецЕсли;
КонецПроцедуры // РассчитатьСкидкиПриПродаже()

// Процедура рассчитывает скидки в документе.
//
// Параметры:
//  ДокументОбъект             - документ, для которого рассчитываем скидки,
//  ТабличнаяЧастьНоменклатуры - табличная часть номенклатуры документа,
//  ТабличнаяЧастьСкидки       - табличная часть скидок,
//  СтруктураПараметров        - структура, содержащая дополнительные параметря, необходимые для расчета скидок.
//  ТаблицаСообщений           - Таблица в которую помещаются сообщения кассиру
//
Процедура РассчитатьСообщенияПриПродаже(ДокументОбъект, ТабличнаяЧастьНоменклатуры, ТабличнаяЧастьСкидки, ТабличнаяЧастьПодарки,
                                     СтруктураПараметров, ТаблицаСообщений ) Экспорт

    Перем УчитыватьНДС, СуммаВключаетНДС, ДатаСкидок, Магазин;
    Перем ФлагИзмененияТабличнойЧастиТоваров;

    Если ТабличнаяЧастьНоменклатуры.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    Если ТипЗнч (ТабличнаяЧастьНоменклатуры) = Тип("ТаблицаЗначений") Тогда
        ТаблицаТоваров = ТабличнаяЧастьНоменклатуры.Скопировать();
        ЕстьПодарки    = НЕ ТабличнаяЧастьНоменклатуры.Колонки.Найти("ПродажаПодарка") = Неопределено;
    Иначе
        ЕстьПодарки    = НЕ ТабличнаяЧастьНоменклатуры.ВыгрузитьКолонки().Колонки.Найти("ПродажаПодарка") = Неопределено;
        ТаблицаТоваров = ТабличнаяЧастьНоменклатуры.Выгрузить();
    КонецЕсли;
    
    
    ЕстьТЧСкидки  = НЕ ТабличнаяЧастьСкидки = Неопределено;
    ЕстьТЧПодарки = НЕ ТабличнаяЧастьПодарки = Неопределено;

    СтруктураПараметров.Свойство("ДатаСкидок"                    , ДатаСкидок);
    СтруктураПараметров.Свойство("УчитыватьНДС"                  , УчитыватьНДС);
    СтруктураПараметров.Свойство("СуммаВключаетНДС"              , СуммаВключаетНДС);

    УчитыватьНДС     = ?(УчитыватьНДС     = Неопределено, Ложь, УчитыватьНДС);
    СуммаВключаетНДС = ?(СуммаВключаетНДС = Неопределено, Ложь, СуммаВключаетНДС);
    

    ТекущаяДата = ТекущаяДата();
    ДатаСкидок = ?(НЕ ЗначениеЗаполнено(ДатаСкидок), ДокументОбъект.Дата, ДатаСкидок);
    ДатаСкидок = ?(НачалоДня(ДатаСкидок) = ДатаСкидок,
                             Дата(
                             Год(    ДокументОбъект.Дата),
                             Месяц(  ДокументОбъект.Дата),
                             День(   ДокументОбъект.Дата),
                             Час(    ТекущаяДата),
                             Минута( ТекущаяДата),
                             Секунда(ТекущаяДата))
                             , ДатаСкидок);
    
    МетаданныеДокумента = ДокументОбъект.Метаданные();
    Магазин = Справочники.Магазины.ПустаяСсылка();
    Если ОбщегоНазначения.ЕстьРеквизитДокумента("КассаККМ", МетаданныеДокумента) Тогда
        Магазин = ДокументОбъект.КассаККМ.Магазин;
    ИначеЕсли ОбщегоНазначения.ЕстьРеквизитДокумента("Склад", МетаданныеДокумента) Тогда
        Магазин = ДокументОбъект.Склад.Магазин;
    КонецЕсли;
    
    ТаблицаТоваров.Колонки.Добавить("СуммаБезСкидки", Новый ОписаниеТипов("Число"));

    Для Каждого СтрокаТаблицы Из ТаблицаТоваров Цикл
        Если УчитыватьНДС и НЕ СуммаВключаетНДС Тогда
            СтрокаТаблицы.СуммаБезСкидки = (СтрокаТаблицы.Количество * СтрокаТаблицы.Цена) * (1 + Ценообразование.ПолучитьСтавкуНДС(СтрокаТаблицы.СтавкаНДС) / 100);
        Иначе
            СтрокаТаблицы.СуммаБезСкидки = СтрокаТаблицы.Количество * СтрокаТаблицы.Цена;
        КонецЕсли;
        СтрокаТаблицы.Сумма = СтрокаТаблицы.СуммаБезСкидки *(100 - СтрокаТаблицы.ПроцентСкидкиНаценки)/100;
    КонецЦикла;
    
    ТаблицаСкидок = ЗапросПоСкидкам(ДокументОбъект,ТаблицаТоваров, ДатаСкидок, СтруктураПараметров, Магазин, ЕстьТЧПодарки);
    
    ОбработатьТаблицуСообщений(ТаблицаСкидок, ТаблицаСообщений);
    
КонецПроцедуры // РассчитатьСообщенияПриПродаже()


// Рекурсивно обходит дерево и вытесянет скидки подарки
//
// Параметры:
//  СтрокиДерева  - Массив скидок, по которым выполнилось условие
//  ВариантСовместногоПримененияСкидокНаценок - Вариант совместного применения
//  Таблица скидок - Таблица значений скидки подарки
//
Процедура ПрименитьПравилаВытеснениеСкидокПодарковВДереве(СтрокиДерева, ВариантСовместногоПримененияСкидокНаценок, ТаблицаСкидок)


    Если ТаблицаСкидок.Количество()<= 1 Тогда
        Возврат;
    КонецЕсли;
    
    ТаблицаВозможныхСкидок = Новый ТаблицаЗначений;
    ТаблицаВозможныхСкидок.Колонки.Добавить("ЭтоГруппа");
    ТаблицаВозможныхСкидок.Колонки.Добавить("СкидкаНаценка");
    ТаблицаВозможныхСкидок.Колонки.Добавить("ПорядокПрименения");
    
    Для каждого СтрокаДерева Из СтрокиДерева Цикл
        Если СтрокаДерева.ЭтоГруппа Тогда
            ПрименитьПравилаВытеснениеСкидокПодарковВДереве(СтрокаДерева.Строки, СтрокаДерева.ВариантСовместногоПримененияСкидокНаценок, ТаблицаСкидок);
        КонецЕсли;
        СтрокаТаблицыВозможныхСкидок = ТаблицаВозможныхСкидок.Добавить();
        СтрокаТаблицыВозможныхСкидок.ЭтоГруппа               = СтрокаДерева.ЭтоГруппа;
        СтрокаТаблицыВозможныхСкидок.СкидкаНаценка           = СтрокаДерева.СкидкаНаценка;
        СтрокаТаблицыВозможныхСкидок.ПорядокПрименения       = СтрокаДерева.ПорядокПрименения;
    КонецЦикла;
    
    Если ТаблицаВозможныхСкидок.Количество() > 1 Тогда
        Если ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Минимум
            ИЛИ ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Максимум 
            ИЛИ ВариантСовместногоПримененияСкидокНаценок = Перечисления.ВариантыСовместногоПримененияСкидокНаценок.Вытеснение Тогда
            ТаблицаВозможныхСкидок.Сортировать("ПорядокПрименения Возр");
            
            МассивСкидок = ТаблицаВозможныхСкидок.ВыгрузитьКолонку("СкидкаНаценка");
            МассивСкидок.Удалить(0);
            
            Запрос = Новый Запрос;
            Запрос.Текст = 
            "ВЫБРАТЬ
            |   ТаблицаСкидок.СкидкаНаценка,
            |   ТаблицаСкидок.УсловиеПредоставленияСкидки,
            |   ТаблицаСкидок.ЗначениеУсловия,
            |   ТаблицаСкидок.Позиционная,
            |   ТаблицаСкидок.СегментНоменклатуры,
            |   ТаблицаСкидок.СегментИсключаемойНоменклатуры,
            |   ТаблицаСкидок.СкидкаНаЕдиныйКомплект,
            |   ТаблицаСкидок.ПодарокИзСписка,
            |   ТаблицаСкидок.НакопительнаяСкидка,
            |   ТаблицаСкидок.ПодарокИзКорзиныПокупателя,
            |   ТаблицаСкидок.УчитыватьПодарокКакПродажу,
            |   ТаблицаСкидок.КоличествоПодарковИзКорзиныПокупателя
            |ПОМЕСТИТЬ ТаблицаСкидок
            |ИЗ
            |   &ТаблицаСкидок КАК ТаблицаСкидок
            |;
            |
            |////////////////////////////////////////////////////////////////////////////////
            |ВЫБРАТЬ
            |   ТаблицаСкидок.СкидкаНаценка,
            |   ТаблицаСкидок.УсловиеПредоставленияСкидки,
            |   ТаблицаСкидок.ЗначениеУсловия,
            |   ТаблицаСкидок.Позиционная,
            |   ТаблицаСкидок.СегментНоменклатуры,
            |   ТаблицаСкидок.СегментИсключаемойНоменклатуры,
            |   ТаблицаСкидок.СкидкаНаЕдиныйКомплект,
            |   ТаблицаСкидок.ПодарокИзСписка,
            |   ТаблицаСкидок.НакопительнаяСкидка,
            |   ТаблицаСкидок.ПодарокИзКорзиныПокупателя,
            |   ТаблицаСкидок.УчитыватьПодарокКакПродажу,
            |   ТаблицаСкидок.КоличествоПодарковИзКорзиныПокупателя
            |ИЗ
            |   ТаблицаСкидок КАК ТаблицаСкидок
            |ГДЕ
            |   (НЕ ТаблицаСкидок.СкидкаНаценка В ИЕРАРХИИ (&МассивСкидок))";
            
            Запрос.УстановитьПараметр("МассивСкидок" , МассивСкидок);
            Запрос.УстановитьПараметр("ТаблицаСкидок", ТаблицаСкидок);
            Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
            
            Результат = Запрос.Выполнить();
            
            ТаблицаСкидок = Результат.Выгрузить();
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры // ПрименитьПравилаВытеснениеСкидокПодарковВДереве()

// Определяет по таблице скидок подарков количество подарков
//
// Параметры:
//  ТаблицаСкидок - Таблица значений скидки подарки
//  ТаблицаТоваров - Таблица значений, в которую выгружена таблица товаров из документа
//  Магазин - магазин, в котором рассчитываем скидки
//  ТаблицаНеПрименяемыхПодарков - Таблица значений, служит для возврата не используемых подарков
//
Процедура ОпределитьКоличествоПодарков(ТаблицаСкидок, ТаблицаТоваров, Магазин, ТаблицаНеПрименяемыхПодарков = Неопределено)

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

    ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПозиционныхСкидокПоКоличеству, ТаблицаСкидок);
    
    КолвоЭлементовКоллекции = ТаблицаСкидок.Количество();
    ТаблицаНеПрименяемыхПодарков = Новый ТаблицаЗначений;
    ТаблицаНеПрименяемыхПодарков.Колонки.Добавить("СкидкаНаценка");
    Для ОбратныйИндекс = 1 По КолвоЭлементовКоллекции Цикл
        ЭлементКоллекции = ТаблицаСкидок[КолвоЭлементовКоллекции - ОбратныйИндекс];
        
        Если ЭлементКоллекции.КоличествоПодарков <= 0  Тогда
            Если ТаблицаПозиционныхСкидокПоКоличеству.Найти(ЭлементКоллекции.СкидкаНаценка, "СкидкаНаценка") = Неопределено Тогда
                СтрокаТаблицы = ТаблицаНеПрименяемыхПодарков.Добавить();
                СтрокаТаблицы.СкидкаНаценка = ЭлементКоллекции.СкидкаНаценка;
            КонецЕсли; 
            ТаблицаСкидок.Удалить(ЭлементКоллекции);
        КонецЕсли;
    КонецЦикла;
    
КонецПроцедуры // ОпределитьКоличествоПодарков()

// Заполняет таблицу подарки по скидкам
//
// Параметры:
//  ТаблицаСкидок - Таблица значений скидки подарки
//  ТаблицаТоваров - Таблица значений, в которую выгружена таблица товаров из документа
//  ТабличнаяЧастьСкидки       - табличная часть скидок,
//  ТабличнаяЧастьПодарки - табличная часть "Подарки" документа.
//  Магазин - магазин, в котором рассчитываем скидки
//  ФлагИзмененияТабличнойЧастиТоваров - Булево, показывает изменилась ли ТЧ Товаров;
//
Процедура ЗаполнитьТаблицуПодарков(ТаблицаСкидок, ТаблицаТоваров, ТабличнаяЧастьСкидки, ТабличнаяЧастьПодарки, Магазин, ФлагИзмененияТабличнойЧастиТоваров)

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

КонецПроцедуры // ЗаполнитьТаблицуПодарки()

// Функция распределяет сумму скидки по строкам товаров
//
// Параметры
//  ТабличнаяЧастьНоменклатуры - табличная часть номенклатуры документа,
//  ТабличнаяЧастьСкидки       - табличная часть скидок,
//  Магазин - Магазин в котором совершается продажа
//  СтрокаРаспределяемойСкидки - строка таблицы значений или выборка, с данными по скидке
//  СуммаРаспределения - Распределяемая сумма 
//
// Возвращаемое значение
//  Булево - если смогли распределить
//
Функция РаспределитьСуммуСкидкиПоСтрокамТоваров(ТабличнаяЧастьНоменклатуры, ТабличнаяЧастьСкидки, Магазин, СтрокаРаспределяемойСкидки, СуммаРаспределения)

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

КонецФункции // РаспределитьСуммуСкидкиПоСтрокамТоваров()

// Процедура переносит из табличной части Подарки в табличную часть Товары
// Подарки для скидки, котороых установлен реквизит "УчитыватьПодарокКакПродажу" в значение Истина
//
// Параметры
//  ДокументОбъект             - документ, для которого рассчитываем скидки,
//  ТабличнаяЧастьНоменклатуры - табличная часть номенклатуры документа,
//  ТабличнаяЧастьСкидки       - табличная часть скидок,
//  ТабличнаяЧастьПодарки      - табличная часть "Подарки" документа.
//  Магазин - Магазин в котором совершается продажа
//  ТаблицаПеренесенныхПодарков - Таблица значений, в которой запоминаем перенесенные строки;
//
Процедура ПеренестиПодаркиВТовары(ДокументОбъект, ТабличнаяЧастьНоменклатуры, ТабличнаяЧастьСкидки,ТабличнаяЧастьПодарки, Магазин, ТаблицаПеренесенныхПодарков = Неопределено) Экспорт

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

КонецПроцедуры // ПеренестиПодаркиВТовары()


// Дополняет информацию в заголовке по периоду акции и отбору по акции
//
// Параметры:
//  Результат - Табличный документв котором содержиться заполненный отчет
//  КомпоновщикНастроек - компоновщик настроек отчета
//  МаркетинговаяАкция - маркетинговая акция
//
Процедура ДополнитьЗаголовокОтчета(Результат, КомпоновщикНастроек, МаркетинговаяАкция) Экспорт

    ТекстОтбора = Результат.Область("R2C1:R2C1").Текст;
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.УстановитьТекст(ТекстОтбора);
    
    // Период
    ЗначениеПараметраПериод = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Период"));
    ЗначениеПараметраНачалоПериода = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПериодНачалаАкции"));
    ЗначениеПараметраКонецПериода = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("ПериодОкончанияАкции"));
    ОписаниеПериода = "";
    
    Если ЗначениеПараметраНачалоПериода <> Неопределено 
       И ЗначениеПараметраКонецПериода <> Неопределено Тогда
        НачалоПериода = ?(ТипЗнч(ЗначениеПараметраНачалоПериода.Значение) = Тип("СтандартнаяДатаНачала"), ЗначениеПараметраНачалоПериода.Значение.Дата, ЗначениеПараметраНачалоПериода.Значение);
        КонецПериода = ?(ТипЗнч(ЗначениеПараметраКонецПериода.Значение) = Тип("СтандартнаяДатаНачала"), ЗначениеПараметраКонецПериода.Значение.Дата, ЗначениеПараметраКонецПериода.Значение);
        Если НачалоПериода = '00010101' И КонецПериода = '00010101' Тогда
            ОписаниеПериода = НСтр("ru='Период не установлен'");
        ИначеЕсли НачалоПериода = '00010101' ИЛИ КонецПериода = '00010101' Тогда
            ОписаниеПериода = Формат(НачалоПериода, "ДФ = дд.ММ.гггг; ДП = ...") + " - " + Формат(КонецПериода, "ДФ = дд.ММ.гггг; ДП = ...");
        ИначеЕсли НачалоПериода <= КонецПериода Тогда
            ОписаниеПериода = ПредставлениеПериода(НачалоДня(НачалоПериода), КонецДня(КонецПериода), "ФП = Истина");
        Иначе
            ОписаниеПериода = НСтр("ru='Неправильно задан период!'");
        КонецЕсли;
    ИначеЕсли ЗначениеПараметраПериод <> Неопределено Тогда
        Период = ЗначениеПараметраПериод.Значение;
        Если Период = '00010101' Тогда
            ОписаниеПериода = НСтр("ru='на '") + Формат(ТекущаяДата(), "ДП = ...");
        Иначе
            ОписаниеПериода = НСтр("ru='на конец дня '") + Формат(Период, "ДФ = дд.ММ.гггг; ДП = ...");
        КонецЕсли;
    Иначе
        ОписаниеПериода = "";
    КонецЕсли;
    Если Не ПустаяСтрока(ОПисаниеПериода) Тогда
        ОписаниеПериода = "Период акции: " + ОписаниеПериода;
    КонецЕсли;
    
    ТекстовыйДокумент.ВставитьСтроку(2,ОписаниеПериода);
    
    Если ЗначениеЗаполнено(МаркетинговаяАкция)  Тогда
        ОписаниеАкции = "Отбор заполнен по акции: "+МаркетинговаяАкция.НаименованиеАкции + " ("+МаркетинговаяАкция+").";
        ТекстовыйДокумент.ДобавитьСтроку(ОписаниеАкции);
    КонецЕсли;
    
    Результат.Область("R2C1:R2C1").Текст = ТекстовыйДокумент.ПолучитьТекст();
    
КонецПроцедуры // ДополнитьЗаголовокОтчета()