Base file: Документ_ЧекККМ_ФормаРегистрацииПродаж.onec

Compared file: Документ_ЧекККМ_ФормаРегистрацииПродаж.m000.onec

Generated by CSDiff on 27.03.2013 13:34  

 
////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ МОДУЛЯ

// Хранит текущую дату документа - для проверки перехода документа в другой период установки номера
Перем мТекущаяДатаДокумента; 

// Ссылка на колонки табличного поля "Товары".
Перем мКолонкиТовары;

// Хранит информацию о сумме без скидки документа.
Перем мСуммаДокументаБезСкидок Экспорт;

// Хранит информацию о сумме НДС документа.
Перем мСуммаНДС Экспорт;


// Хранит ссылку на устройство торгового оборудования "Фискальный регистратор".
Перем мФР;

// Хранит ссылку на кассу ККМ, используемую в документах.
Перем мКассаККМ;


//Хранит значение необходимости использовать настройку РМК.
Перем мИспользоватьНастройкуРМК;

// Хранит значения настроек рабочего места кассира.
Перем мНастройкаРМК;

// Хранит значение настройки РМК отображения "текстового" подбора
// в правой части экрана, а не кнопок тач-панели.
Перем мОтображатьПодборВПравойЧастиЭкрана;

//Доступность кнопок на форме
Перем мРазрешитьСторнированиеТовара;

//Запрет изменения набранных строк
Перем мРазрешитьРедактироватьНабранныйЧек;

// Запрет изменения цены
Перем ИзменятьЦену;

// Хранит значение того, что в "текстовом" подборе был произведен
// поиск.
Перем мРежимПоискаВПодборе;

// Хранит значения акселераторов для клавиатуры.
Перем мСочетанияКлавиш;

// Хранит значение необходимости обновлять высоту подбора.
Перем мОбновитьВысотуПодбора;

// Хранит текстовое значение того, что в данный момент
// отображается на дисплее покупателя.
Перем мТекущиеСтрокиДисплеяПокупателя;

// Хранит дату, на которую расчитываются остатки.
Перем мДата;

// Хранит значение цвета, который будет присваиваться активной (нажатой)
// кнопке.
Перем мЦветАктивнойКнопки;

// Хранит значение нажатой кнопки (стрелки в подборе и клавиша "ввод").
Перем мНажатаяКнопка;

// Хранит значение текущих весов сеанса.
Перем мСписокВесов, мТекущиеВесы;

//Хранит имя компьютера
Перем мИмяКомпьютера;

//Хранит имя файла бэкапа чека
Перем мИмяФайлаБэкапа;

// Хранит API подбора
Перем мПодбор;

// Хранит номер чека
Перем мНомерЧекаККМ;

//Хранит количество кнопок в ряду кнопок
Перем МаксимальноеКоличествоКнопокВКонфигураторе;

//Хранит акселератор кнопки "Замена прав"
Перем АкселераторКнопкиЗаменыПрав;

// Хранит стандартную высоту кнопки Выход, если 0 что размер не менялся
Перем ВысотаКпонкиВыход;

// Если данная перемнная равна "Истина" то проверять характеристику еще не нуэно
Перем ТекущаяОперацияВыборНоменклатурыСХарактеристикой;

// Дисконтная карта ожидающая замены
Перем ДисконтнаяКартаДляЗамены;

//m000 Дополнительные функции

&НаСервере
Функция m000ПрочитатьДанныеПоДокументу(Реквизит)
    
    ДанныеПоДокументу = Документы.m000Скидка.НайтиПоРеквизиту("Документ", ЭтотОбъект.Ссылка);
    
    Если ДанныеПоДокументу <> Документы.m000Скидка.ПустаяСсылка() ТОгда
        
        Если Реквизит = "Сумма" ИЛИ Реквизит = "СуммаСкидки" ТОгда
            Возврат ДанныеПоДокументу.ТаблицаДвижений.Итог(Реквизит);   
        КонецЕсли;
        
        Возврат ДанныеПоДокументу[Реквизит];
    КонецЕсли;
    
    
    Возврат Неопределено;
КонецФункции

//m000/


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ И ФУНКЦИИ СОХРАНЕНИЯ И ВОССТАНОВЛЕНИЯ ЗНАЧЕНИЙ

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

КонецПроцедуры

// Процедура восстанавливает сохраненные значения пользователя
//
Процедура ВосстановитьЗначения()
    
    ЭлементыФормы.СписокВидовПоиска.Значение = ВосстановитьЗначение("ЧекКММ_СписокВидовПоиска");
    Если СокрЛП(ЭлементыФормы.СписокВидовПоиска.Значение) = "" Тогда
        ЭлементыФормы.СписокВидовПоиска.Значение = "Наименование";
    КонецЕсли;
    
    // Восстанавливает структуру параметров настройки подбора
    СтруктураПараметровПодбора = ВосстановитьЗначение("ЧекККМ_НастройкиПодбора");
    
    Если СтруктураПараметровПодбора <> Неопределено Тогда
        
        Если СтруктураПараметровПодбора.Свойство("ОтображатьЦены") Тогда
            ОтображатьЦены = СтруктураПараметровПодбора.ОтображатьЦены;
        КонецЕсли;
        
        Если СтруктураПараметровПодбора.Свойство("ОтображатьКоличество") Тогда
            ОтображатьКоличество = СтруктураПараметровПодбора.ОтображатьКоличество;
        КонецЕсли;
        
        Если СтруктураПараметровПодбора.Свойство("ОтображатьИнформацию") Тогда
            ОтображатьИнформацию = СтруктураПараметровПодбора.ОтображатьИнформацию;
        КонецЕсли;
        
        Если СтруктураПараметровПодбора.Свойство("ОтображатьИерархию") Тогда
            ОтображатьИерархию   = СтруктураПараметровПодбора.ОтображатьИерархию;
        КонецЕсли;
    Иначе
        
        ОтображатьЦены       = Истина;
        ОтображатьКоличество = Истина;
        ОтображатьИнформацию = Истина;
        ОтображатьИерархию   = Истина;
        
    КонецЕсли;
    
КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ И ФУНКЦИИ АВТОСОХРАНЕНИЯ ЧЕКОВ ККМ

// Процедура проверяет условия автосохранения документа
// при необходимости сохраняет его
Процедура АвтосохранениеЧекаККМ()

    Объект = ПолучитьАвтосохраненныйЧекККМ();
    
    Если ПолучитьХМLПредставление(Объект) = ПолучитьХМLПредставление(ЭтотОбъект) Тогда
        Возврат;
    КонецЕсли;
    
    // XML сериализация текущего объекта
    Попытка
        ЗаписьXML = Новый ЗаписьXML;
        ЗаписьXML.ОткрытьФайл(мИмяФайлаБэкапа, "UTF-16");
        ЗаписатьXML(ЗаписьXML, ЭтотОбъект);
        ЗаписьXML.Закрыть();
    Исключение
        ОчиститьАвтосохраненныеЧекиККМ();
    КонецПопытки;

КонецПроцедуры

// Процедура анализирует необходимость восстановления
// работы с чеком
Процедура ВосстановитьЧекККМ()
    
    Объект = ПолучитьАвтосохраненныйЧекККМ();
    
    Если Объект = Неопределено Тогда
        Возврат;
    КонецЕсли;

    Если Не ЗначениеЗаполнено(Объект.ЧекККМПродажа)
       И Не ЗначениеЗаполнено(Объект.ВладелецДисконтнойКарты)
       И Не ЗначениеЗаполнено(Объект.ДисконтнаяКарта)
       И Не ЗначениеЗаполнено(Объект.Продавец)
       И Объект.Товары.Количество() = 0 Тогда
        ОчиститьАвтосохраненныеЧекиККМ();
        Возврат;
    КонецЕсли;
    
    // Установка текущего чека
    ДокументОбъект = Объект;
    Дата           = НачалоДня(ТекущаяДата());
    
    мПодбор.мДата = ТекущаяДата();
КонецПроцедуры

// Процедура удаляет объект с диска.
//
Процедура ОчиститьАвтосохраненныеЧекиККМ()
    
    ФайлНаДиске = Новый Файл(мИмяФайлаБэкапа);

    Если ФайлНаДиске.Существует() Тогда
        УдалитьФайлы(мИмяФайлаБэкапа);
    КонецЕсли;
    
КонецПроцедуры

// Процедура получает объект с диска
//
Функция ПолучитьАвтосохраненныйЧекККМ()
    
    Результат = Неопределено;
    
    ФайлНаДиске = Новый Файл(мИмяФайлаБэкапа);
    Попытка
        Если ФайлНаДиске.Существует() Тогда
            
            ЧтениеXML = Новый ЧтениеXML;
            ЧтениеXML.ОткрытьФайл(мИмяФайлаБэкапа);
            Пока ВозможностьЧтенияXML(ЧтениеXML) Цикл
                Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента
                    И   ЧтениеXML.Имя     = "DocumentObject.ЧекККМ" Тогда
                    Попытка
                        Результат = ПрочитатьXML(ЧтениеXML);
                    Исключение
                        Результат = Неопределено;
                    КонецПопытки;
                КонецЕсли;
            КонецЦикла;
            ЧтениеXML.Закрыть();
            
        КонецЕсли;
    Исключение
        ОчиститьАвтосохраненныеЧекиККМ()
    КонецПопытки;
    
    Возврат Результат;
    
КонецФункции

// Процедура считывает текстовое представление
// сериализованного файла и сравнивает его с текстовым представлением
// текущего объекта
Функция ПолучитьХМLПредставление(Объект)
    
    Результат = "";
    
    //Сериализует текущий объект
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку("UTF-16");
    ЗаписатьXML(ЗаписьXML, Объект);
    Результат = ЗаписьXML.Закрыть();
    
    Возврат Результат;
    
КонецФункции


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ И ФУНКЦИИ ОБЩЕГО НАЗНАЧЕНИЯ

// Процедура обновляет отображение времени на
// форме
//
Процедура ВывестиВремя()

    ЭлементыФормы.Время.Заголовок = Формат(ТекущаяДата(),"ДЛФ=DT")+"  ";

КонецПроцедуры

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

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

    Возврат Отказ;
    
КонецФункции

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

КонецПроцедуры //ДобавитьНоменклатуруВТабЧасть()

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




//Производит закрытие чека на фискальном регистраторе и печать товарного чека.
//
// Параметры:
//  Печать - булево, признак необходимости печати товарного чека.
//
Процедура ЗакрытьЧек(Печать = Ложь, РучнойРежим = Ложь, ВыбратьДокументПечати = Ложь)
    Перем Отказ;
    
    Если ТолькоПросмотр Тогда
        Закрыть();
    КонецЕсли;
    
    Если (СтатусЧекаККМ <> Перечисления.СтатусыЧековККМ.Пробитый
     Или СтатусЧекаККМ <> Перечисления.СтатусыЧековККМ.Архивный
     Или СтатусЧекаККМ <> Перечисления.СтатусыЧековККМ.Аннулированный)
     И Товары.Количество() > 0 Тогда

        Оплата.Очистить();
        ФормаОплат = ПолучитьФорму("ФормаОплатЧека", ЭтаФорма);
        ФормаОплат.СуммаОплаты = ЭлементыФормы.ИнфНадписьТекущееЗначение.Значение;
        
        Результат  = ФормаОплат.ОткрытьМодально();

        ЭлементыФормы.ИнфНадписьТекущееЗначение.Значение = "";
        ЭлементыФормы.Панель3.ЦветФона = ЦветаСтиля.ЦветФонаФормы;

    КонецЕсли;
    
    Если Результат <> "Закрыть чек" Тогда
        Возврат;
    КонецЕсли;
    
    Отказ = Ложь;
    
    //Погашение сертификатами
    
    ТаблицаПогашения = ПодготовитьТаблицуПогашения();
    
    ПроверитьЗаполнениеТабличнойЧастиПогашения(ТаблицаПогашения, ЭтотОбъект, Отказ, "");

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

    Эквайринг.ПересчитатьТорговуюУступку(ДоговорЭквайринга, Оплата);
    ПересчитатьБанковскийКредит();
    
    ЗавершитьЗакрытиеЧека(Печать, РучнойРежим, ВыбратьДокументПечати);
    
КонецПроцедуры // ЗакрытьЧек()

// Определяет была ли оплата картой
//
// Параметры:
//  Нет
//
// Возвращаемое значение:
//   Булево
//
Функция ЕстьОплатаПлатежнойКартой()

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

КонецФункции // ЕстьОплатаПлатежнойКартой()


// Процедура закрывает чек в форме
//
Процедура ЗавершитьЗакрытиеЧека(Печать, РучнойРежим = Ложь, ВыбратьДокументПечати = Ложь) Экспорт

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

    Если НЕ НачалоДня(ДокументОбъект.Дата) = НачалоДня(ТекущаяДата()) Тогда
        ДокументОбъект.Дата = Дата(Год(ДокументОбъект.Дата), Месяц(ДокументОбъект.Дата), День(ДокументОбъект.Дата),
                                   Час(ТекущаяДата()), Минута(ТекущаяДата()), Секунда(ТекущаяДата()))
    КонецЕсли;

    ЭлементыФормы.ИнфНадписьТекущаяСумма.Заголовок = "";

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

                ВывестиИнформациюОбОшибке(ТекстСообщения);
            КонецЕсли;

            СоздатьНовыйДокумент();
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

// Процедура - обработчик событий нажатия кнопок панели "КоманднаяПанельАкселераторы" 
// 
Процедура НажатиеКлавиши(Элемент)
    
    Если ТипЗнч(Элемент) = Тип("КнопкаКоманднойПанели")
    И НЕ Элемент.Доступность Тогда
        Возврат;
    КонецЕсли;
    
    ТекущаяНадпись = ЭлементыФормы.ИнфНадписьТекущееЗначение.Значение;
    
    ЦветБелый = Новый Цвет(255,255,255);
    
    Кнопки = ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки;
    
    Если Элемент = Кнопки.Клавиша0
        ИЛИ  Элемент = Кнопки.Клавиша1
        ИЛИ  Элемент = Кнопки.Клавиша2
        ИЛИ  Элемент = Кнопки.Клавиша3
        ИЛИ  Элемент = Кнопки.Клавиша4
        ИЛИ  Элемент = Кнопки.Клавиша5
        ИЛИ  Элемент = Кнопки.Клавиша6
        ИЛИ  Элемент = Кнопки.Клавиша7
        ИЛИ  Элемент = Кнопки.Клавиша8
        ИЛИ  Элемент = Кнопки.Клавиша9 Тогда
        
        Запятая = Сред(ТекущаяНадпись, СтрДлина(ТекущаяНадпись) - 3, 1);
        
        Если Не Запятая = "," тогда
            ТекущаяНадпись = ТекущаяНадпись + Элемент.Текст;
            ЭлементыФормы.ИнфНадписьТекущееЗначение.Значение = ТекущаяНадпись;
        КонецЕсли;
        
        ЭлементыФормы.Панель3.ЦветФона = ЦветБелый;
        
    ИначеЕсли Элемент = Кнопки.КлавишаТочка Тогда
        
        Если ТекущаяНадпись = "" Тогда
            ТекущаяНадпись = "0";
        КонецЕсли;
        
        ЧислоВхождений = СтрЧислоВхождений(ТекущаяНадпись, ",");
        
        Если Не ЧислоВхождений > 0 Тогда
            ЭлементыФормы.ИнфНадписьТекущееЗначение.Значение = ТекущаяНадпись + ",";
        КонецЕсли;
        
        ЭлементыФормы.Панель3.ЦветФона = ЦветБелый;
        
    ИначеЕсли Элемент = Кнопки.КлавишаСтереть Тогда
        
        ЭлементыФормы.ИнфНадписьТекущееЗначение.Значение = "";
        ЭлементыФормы.Панель3.ЦветФона = ЦветаСтиля.ЦветФонаФормы;
        
    ИначеЕсли Элемент = Кнопки.КлавишаОтменаСкидкаНаценка
     ИЛИ      Элемент = Кнопки.КлавишаСкидкаНаценка Тогда

        Если Товары.Количество() = 0 Тогда
            НажатиеКлавиши(Кнопки.КлавишаСтереть);
            Возврат;
        КонецЕсли;

        ТекущаяСтрока = ЭлементыФормы.Товары.ТекущаяСтрока;
        
        Если ТекущаяСтрока = Неопределено Тогда
            Возврат;
        КонецЕсли;
        
        Если Элемент = Кнопки.КлавишаСкидкаНаценка Тогда
            
            ФормаВводаСкидкиНаценки = ПолучитьФорму("ФормаВводаСкидкиНаценки", ЭтаФорма);
            ФормаВводаСкидкиНаценки.Значение = ЭлементыФормы.ИнфНадписьТекущееЗначение.Заголовок;
            
            НажатиеКлавиши(ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки.КлавишаСтереть);
            
            ЗначениеСкидкиНаценки = ФормаВводаСкидкиНаценки.ОткрытьМодально();
            Если Не ЗначениеЗаполнено(ЗначениеСкидкиНаценки) Тогда
                Возврат;
            КонецЕсли;
            
            ВидСкидкиНаценки      = ФормаВводаСкидкиНаценки.Вид;
            
            Если ВидСкидкиНаценки = "Процент" Тогда
                
                ТекущаяСтрока.ПроцентСкидкиНаценки = ЗначениеСкидкиНаценки;
                
            Иначе
                
                ОкруглятьПроцентСкидкиВБольшуюСторону = (мИспользоватьНастройкуРМК И мНастройкаРМК.ОкруглятьПроцентСкидкиВБольшуюСторону);
                ТекущийРежимОкругления = ?(ОкруглятьПроцентСкидкиВБольшуюСторону, РежимОкругления.Окр15как20, РежимОкругления.Окр15как10);
                
                ТекущаяСтрокаСумма     = ТекущаяСтрока.Сумма + (ТекущаяСтрока.Цена * ТекущаяСтрока.Количество * (ТекущаяСтрока.ПроцентСкидкиНаценки / 100));
                
                Если ТекущаяСтрока.Цена = 0 Тогда
                    ВывестиИнформациюОбОшибке("Цена текущей строки равна 0. Расчет скидки невозможен!");
                    НажатиеКлавиши(Кнопки.КлавишаСтереть);
                    Возврат;
                КонецЕсли;

                Если ТекущаяСтрокаСумма = 0 Тогда
                    ВывестиИнформациюОбОшибке("Сумма текущей строки равна 0. Расчет скидки невозможен!");
                    НажатиеКлавиши(Кнопки.КлавишаСтереть);
                    Возврат;
                КонецЕсли;
                
                Если ТекущаяСтрока.Количество = 0 Тогда
                    ВывестиИнформациюОбОшибке("Количество текущей строки равно 0. Расчет скидки невозможен!");
                    НажатиеКлавиши(Кнопки.КлавишаСтереть);
                    Возврат;
                КонецЕсли;

                СуммаСоСкидками = ТекущаяСтрокаСумма - ЗначениеСкидкиНаценки;
                СуммаБезСкидок  = ТекущаяСтрока.Цена * ТекущаяСтрока.Количество;
                ПроцентСкидки   = 100 - (СуммаСоСкидками * 100) / СуммаБезСкидок;
                ПроцентСкидкиНаценки = ПроцентСкидки;

                ПроцентСкидкиНаценки = Окр(ПроцентСкидкиНаценки, 2, ТекущийРежимОкругления);

                ТекущаяСтрока.ПроцентСкидкиНаценки = ПроцентСкидкиНаценки;

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

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

// Процедура осуществляет обработку считывания информационной карты
//
Процедура ОбработатьСчитываниеИнформационнойКарты(Карта)

    Если Карта.ТипКарты = Перечисления.ТипыИнформационныхКарт.Дисконтная Тогда
        ДисконтнаяКарта = Карта;
        Если мИспользоватьНастройкуРМК И мНастройкаРМК.ПроводитьАнкетирование Тогда
            УправлениеИнформационнымиКартами.ПровестиАнкетирование(Карта, Дата, Истина);
        КонецЕсли;
        ПриИзмененииДисконтнойКарты();

    ИначеЕсли Карта.ТипКарты = Перечисления.ТипыИнформационныхКарт.Регистрационная Тогда
        
        Если ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
            ВывестиИнформациюОбОшибке("В чеке возврата нельзя менять продавца!");
            Возврат;
        КонецЕсли;
        
        ТекущаяСтрока  = ЭлементыФормы.Товары.ТекущаяСтрока;
        ПродавецКарта  = УправлениеИнформационнымиКартами.ПолучитьФизическоеЛицоРегистрационнойКарты(Карта);
        Если Товары.Количество() = 0 Тогда
            Продавец = ПродавецКарта;
        Иначе
            Если ТекущаяСтрока <> Неопределено Тогда
                ТекущаяСтрока.Продавец = ПродавецКарта;
            КонецЕсли;
        КонецЕсли;

    КонецЕсли;

КонецПроцедуры


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


// Процедура пересчитывает процент банковского кредита
// в таблице Оплата
//
Процедура ПересчитатьБанковскийКредит()

    Для Каждого ТекОплата Из Оплата Цикл

        ТипОплаты = ТекОплата.ВидОплаты.ТипОплаты;

        Если ТипОплаты = Перечисления.ТипыОплатЧекаККМ.БанковскийКредит Тогда
            ТекОплата.ПроцентТорговойУступки = ТекОплата.ВидОплаты.ПроцентБанковскойКомиссии;
            ТекОплата.СуммаТорговойУступки   = ТекОплата.Сумма * ТекОплата.ПроцентТорговойУступки / 100;
        КонецЕсли;

    КонецЦикла;

КонецПроцедуры

// Процедура выполняет необходимые действия при изменении дисконтной карты.
//
Процедура ПриИзмененииДисконтнойКарты()
    
    ВладелецДисконтнойКарты = ДисконтнаяКарта.ВладелецКарты;
    
КонецПроцедуры // ПриИзмененииДисконтнойКарты()

// Процедура сохраняет текущий чек с указанным статусом 
// и создает новый документ.
// 
Процедура СоздатьНовыйДокумент(СтатусЧека = Неопределено)

    Если ЗначениеЗаполнено(СтатусЧека) Тогда
        СтатусЧекаККМ = СтатусЧека;
        Если СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Отложенный 
         ИЛИ СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Аннулированный Тогда

            Если Проведен Тогда
                Записать(РежимЗаписиДокумента.ОтменаПроведения);
            Иначе
                Записать(РежимЗаписиДокумента.Запись);
            КонецЕсли;
        Иначе
            Записать(РежимЗаписиДокумента.Запись);
        КонецЕсли;
    КонецЕсли;

    ОчиститьАвтосохраненныеЧекиККМ();
    
    Если СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Пробитый Тогда
        мНомерЧекаККМ = НомерЧекаККМ + 1;
    Иначе
        мНомерЧекаККМ = НомерЧекаККМ;
    КонецЕсли;

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

КонецПроцедуры

// Процедура устанавливает активный элемент формы.
//
Процедура УстановитьАктивныйЭлемент()
    
    Если Не мОтображатьПодборВПравойЧастиЭкрана
     И ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость
     И ЭлементыФормы.ПанельПодборБыстрыеТовары.ТекущаяСтраница = ЭлементыФормы.ПанельПодборБыстрыеТовары.Страницы.Подбор Тогда
        ТекущийЭлемент = ЭлементыФормы.ТаблицаПодборКлавиши;
    Иначе
        ТекущийЭлемент = ЭлементыФормы.Товары;
    КонецЕсли;
    
КонецПроцедуры

// Процедура устанавливает весы для сеанса.
//
Процедура УстановитьВесы()
    
    Весы = ПолучитьСерверТО().ПолучитьСписокУстройств(Перечисления.ВидыТорговогоОборудования.ЭлектронныеВесы);
    
    Если Весы.Количество() = 0 Тогда
        УстановитьДоступностьЭлементаФормы("КнопкаПолучитьВес", Ложь);
    Иначе
        УстановитьДоступностьЭлементаФормы("КнопкаПолучитьВес", Истина);

        мСписокВесов = РаботаСТорговымОборудованием.ПолучитьСписокУстройствТОДляВыбора(Весы);

        Если мСписокВесов.Количество() = 1 Тогда
            мТекущиеВесы = мСписокВесов[0].Значение;
        КонецЕсли;
    
    КонецЕсли;
    
КонецПроцедуры

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

// Процедура устанавливает доступность элементов форм документа,
// в зависимости от настроек прав пользователя
Процедура УстановитьДоступностьЭлементовФормДокумента() Экспорт
    
    Пользователь = глЗначениеПеременной("ПользовательИзмененныхПрав");
    Если Пользователь = Неопределено Тогда
        Пользователь = ПараметрыСеанса.ТекущийПользователь;
    КонецЕсли;

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

    ЭлементыФормы.КлавишаЦена.Доступность                                     = ИзменятьЦену;
    ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки.КлавишаЦена.Доступность  = ИзменятьЦену;
    ЭлементыФормы.КлавишаСторно.Доступность                                   = мРазрешитьСторнированиеТовара;
    ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки.КлавишаСторно.Доступность= мРазрешитьСторнированиеТовара;
    ЭлементыФормы.КнопкаВвестиЧекВозврата.Доступность                         = РазрешитьЧекВозврата;

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

    Для Каждого Кнопка Из ЭлементыФормы.КоманднаяПанельКнопкиФормыПоУмолчанию.Кнопки Цикл
        Кнопка.Доступность = ЭлементыФормы[Кнопка.Имя].Доступность;
    КонецЦикла;
    
    ИспользуетсяРасширеннаяНастройкаНижнейПанели = мИспользоватьНастройкуРМК И мНастройкаРМК.ИспользоватьРасширеннуюНастройкуКнопокНижнейПанели;
    Если НЕ ИспользуетсяРасширеннаяНастройкаНижнейПанели
          И ПроверитьНаличиеЭлементаФормы("КнопкаРежимОператора")
          И ПроверитьНаличиеЭлементаФормы("КнопкаВыход") Тогда
        
        Если Не РазрешитьПереключениеИнтерфейса И ВысотаКпонкиВыход = 0 Тогда
            КнопкаВыходВерх                              = ЭлементыФормы.КнопкаРежимОператора.Верх;
            КнопкаВыходНиз                               = ЭлементыФормы.КнопкаВыход.Верх + ЭлементыФормы.КнопкаВыход.Высота;
            ВысотаКпонкиВыход                            = ЭлементыФормы.КнопкаВыход.Высота;
            ЭлементыФормы.КнопкаРежимОператора.Видимость = Ложь;
            
            ЭлементыФормы.КнопкаВыход.Верх               = КнопкаВыходВерх;
            ЭлементыФормы.КнопкаВыход.Высота             = КнопкаВыходНиз - КнопкаВыходВерх;
        ИначеЕсли РазрешитьПереключениеИнтерфейса И ВысотаКпонкиВыход > 0 Тогда
            ЭлементыФормы.КнопкаРежимОператора.Видимость = Истина;
            
            КнопкаВыходНиз                               = ЭлементыФормы.КнопкаВыход.Верх + ЭлементыФормы.КнопкаВыход.Высота;
            КнопкаВыходВерх                              = КнопкаВыходНиз - ВысотаКпонкиВыход;
            ЭлементыФормы.КнопкаВыход.Высота             = ВысотаКпонкиВыход;
            ЭлементыФормы.КнопкаВыход.Верх               = КнопкаВыходВерх;
            ВысотаКпонкиВыход = 0;
        КонецЕсли;
    КонецЕсли;

    
КонецПроцедуры //УстановитьДоступностьЭлементовФормДокумента()

// Устанавливает соответстующие свойства поля ввода цены при изменении 
// номенклатуры в текущей строке табличной части.
// Для оптового склада или услуг в рознице цена редактируется,
// Для товаров на розничном складе выбирается из списка наличия в регистре.
//
// Параметры:
//  Номенклатура - ссылка на справочник, элемент номенклатуры, для которого будем устанавливать цену
//
Процедура УстановитьСвойстваПоляВводаЦены(Номенклатура)
    
    ТекущаяСтрока     = Номенклатура;
    ЭлементУправления = мКолонкиТовары.Цена.ЭлементУправления;
    
КонецПроцедуры // УстановитьСвойстваПоляВводаЦены()

// Устанавливает оформление элементов формы
//
Процедура УстановитьОформлениеЭлементовФормы()

    // Настройка кнопки "Заменить права"
    Если НЕ ПроверитьНаличиеЭлементаФормы("КнопкаЗаменитьПрава") Тогда
        Возврат;
    КонецЕсли;
    
    ПользовательИзмененныхПрав = глЗначениеПеременной("ПользовательИзмененныхПрав");
    Если ПользовательИзмененныхПрав <> Неопределено Тогда
        ЭлементыФормы.КнопкаЗаменитьПрава.Заголовок      = "Восстановить права" + АкселераторКнопкиЗаменыПрав;
        ЭлементыФормы.КнопкаЗаменитьПрава.ЦветФонаКнопки = Новый Цвет(234, 161, 158);
        
        ЭлементыФормы.Пользователь.Заголовок  = Строка(глЗначениеПеременной("глТекущийПользователь")) +
         " (права: " + Строка(ПользовательИзмененныхПрав) + ")";
        ЭлементыФормы.Пользователь.ЦветТекста = ЦветаСтиля.ЦветОсобогоТекста;
        
    Иначе
        
        ЭлементыФормы.КнопкаЗаменитьПрава.Заголовок      = "Заменить права" + АкселераторКнопкиЗаменыПрав;
        ЭлементыФормы.КнопкаЗаменитьПрава.ЦветФонаКнопки = ЦветаСтиля.ЦветФонаКнопки;
        
        ЭлементыФормы.Пользователь.Заголовок  = Строка(глЗначениеПеременной("глТекущийПользователь"));
        ЭлементыФормы.Пользователь.ЦветТекста = ЦветаСтиля.ЦветТекстаФормы;
        
    КонецЕсли;

КонецПроцедуры

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

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

    ФормаВыбора.ОткрытьМодально();
    ЧекККМПродажа = ФормаВыбора.ВыбранноеЗначение;

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

// Процедура осуществляет возврат в режим регистрации продажи
//
// Параметры
//  Нет
//
Процедура ЧекККМКонецВыбора()
    
    УстановитьВидОперации(Перечисления.ВидыОперацийЧекККМ.Продажа);
    
КонецПроцедуры // ЧекККМКонецВыбора()

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

// Заполняет кпонки табличной панели
//
// Параметры:
//  Нет
//
Процедура ЗаполнитьКнопкиНижнейПанели()

    АкселераторКнопкиЗаменыПрав = " (Alt+F4)";
    
    Если мИспользоватьНастройкуРМК И мНастройкаРМК.ИспользоватьРасширеннуюНастройкуКнопокНижнейПанели И мНастройкаРМК.КнопкиНижнейПанели.Количество() > 0 Тогда
        // Очистить кпонки
        ПолученыПараметрыКнопки = Ложь;
        Для Каждого Кнопка Из ЭлементыФормы.КоманднаяПанельКнопкиФормыПоУмолчанию.Кнопки Цикл
            Если Не ПолученыПараметрыКнопки Тогда
                ВысотаКпонки = ЭлементыФормы[Кнопка.Имя].Высота;
                ПолученыПараметрыКнопки = Истина;
                ШиринаКпонки = ЭлементыФормы[Кнопка.Имя].Ширина;
            Иначе
                ШиринаКпонки = Мин(ЭлементыФормы[Кнопка.Имя].Ширина , ШиринаКпонки);
            КонецЕсли;
            
            ЭлементыФормы.Удалить(ЭлементыФормы[Кнопка.Имя]);
        КонецЦикла;
        
        ЭлементыФормы.КоманднаяПанельКнопкиФормыПоУмолчанию.Кнопки.Очистить();
        
        
        // Расчитать ширину кнопки 
        СтандартныйОтступ = 6;
        ШиринаПанели = ЭлементыФормы.КнопкиФормыПоУмолчанию.Ширина;
        
        Если мНастройкаРМК.МаксимальноеКоличествоКнопокВОдномРяду > 0 Тогда
            МаксимальноеКоличествоКнопок = мНастройкаРМК.МаксимальноеКоличествоКнопокВОдномРяду;
        Иначе 
            МаксимальноеКоличествоКнопок = МаксимальноеКоличествоКнопокВКонфигураторе;
        КонецЕсли;
        
        Если мНастройкаРМК.КнопкиНижнейПанели.Количество() >= МаксимальноеКоличествоКнопокВКонфигураторе И мНастройкаРМК.МаксимальноеКоличествоКнопокВОдномРяду = 0 Тогда
            РасчетнаяШиринаКнопки = ШиринаКпонки
        Иначе
            РасчетнаяШиринаКнопки = Цел((ШиринаПанели + СтандартныйОтступ) / Мин(мНастройкаРМК.КнопкиНижнейПанели.Количество(),МаксимальноеКоличествоКнопок)) - СтандартныйОтступ;
            РасчетнаяШиринаКнопки = Мин(РасчетнаяШиринаКнопки, ШиринаКпонки * 1.5)
        КонецЕсли;
        
        // Расчитать высоту панели
        КоличествоРядовКнопок = Цел(мНастройкаРМК.КнопкиНижнейПанели.Количество()/МаксимальноеКоличествоКнопок);
        
        Если Не Цел(мНастройкаРМК.КнопкиНижнейПанели.Количество()/МаксимальноеКоличествоКнопок) = (мНастройкаРМК.КнопкиНижнейПанели.Количество()/МаксимальноеКоличествоКнопок) Тогда
            КоличествоРядовКнопок = КоличествоРядовКнопок + 1;
        КонецЕсли;
        
        // Применить к панели
        ВысотаПанели = СтандартныйОтступ * (КоличествоРядовКнопок + 1) + ВысотаКпонки * КоличествоРядовКнопок + 2;
        
        ЭлементыФормы.КнопкиФормыПоУмолчанию.Высота = СтандартныйОтступ * 3;
        
        ВерхПанели = ЭтаФорма.Высота - 1 - ВысотаПанели;
        
        ЭлементыФормы.КнопкиФормыПоУмолчанию.Верх   = ВерхПанели;
        ЭлементыФормы.КнопкиФормыПоУмолчанию.Высота = ВысотаПанели;
        
        // Заполнить кнопки
        СочетаниеКлавишF2 = Новый СочетаниеКлавиш(Клавиша.F2, Ложь, Ложь, Ложь);
        НайденАкселераторF2 = Ложь;
        
        Для каждого СтрокаНастройкиКнопок Из мНастройкаРМК.КнопкиНижнейПанели Цикл
            
            ИмяКнопки = СтрокаНастройкиКнопок.ИмяКнопки;
            НомерСтрокиНастройки = СтрокаНастройкиКнопок.НомерСтроки;
            Ряд          = Цел((НомерСтрокиНастройки - 1) / МаксимальноеКоличествоКнопок) + 1;
            ПозицияВРяду = НомерСтрокиНастройки - МаксимальноеКоличествоКнопок * Цел((МаксимальноеКоличествоКнопок * Ряд-1)/МаксимальноеКоличествоКнопок);
            ЛевоКпонки = (ПозицияВРяду - 1)* (РасчетнаяШиринаКнопки+ СтандартныйОтступ);
            ВерхКпонки = СтандартныйОтступ + (Ряд - 1) * (ВысотаКпонки + СтандартныйОтступ);
            ЗаголовокКнопки = СтрокаНастройкиКнопок.ЗаголовокКнопки;

            // Создать кнопку
            ЭлементыФормы.Добавить(Тип("Кнопка"), ИмяКнопки, , ЭлементыФормы.КнопкиФормыПоУмолчанию);
            ЭлементыФормы[ИмяКнопки].Лево = 0;
            ЭлементыФормы[ИмяКнопки].Верх = 6;
            ЭлементыФормы[ИмяКнопки].Высота = ВысотаКпонки;
            ЭлементыФормы[ИмяКнопки].Ширина = РасчетнаяШиринаКнопки;
            ЭлементыФормы[ИмяКнопки].Лево = ЛевоКпонки;
            ЭлементыФормы[ИмяКнопки].Верх = ВерхКпонки;
            
            ЭлементыФормы[ИмяКнопки].Заголовок = ЗаголовокКнопки;
            
            ДействиеКнопки = Новый Действие(СтрокаНастройкиКнопок.ПроцедураКнопки);
            ЭлементыФормы[ИмяКнопки].УстановитьДействие("Нажатие", ДействиеКнопки);
            
            ЭлементыФормы[ИмяКнопки].УстановитьПривязку(ГраницаЭлементаУправления.Лево, ЭлементыФормы.КнопкиФормыПоУмолчанию, ГраницаЭлементаУправления.Лево, ЭлементыФормы.КнопкиФормыПоУмолчанию, ГраницаЭлементаУправления.Право);
            ЭлементыФормы[ИмяКнопки].УстановитьПривязку(ГраницаЭлементаУправления.Право, ЭлементыФормы.КнопкиФормыПоУмолчанию, ГраницаЭлементаУправления.Лево, ЭлементыФормы.КнопкиФормыПоУмолчанию, ГраницаЭлементаУправления.Право);
            
            ЭлементыФормы[ИмяКнопки].МногострочныйРежим = Истина;
            
            // Создать кнопку командной панели
            ЭлементыФормы.КоманднаяПанельКнопкиФормыПоУмолчанию.Кнопки.Добавить(ИмяКнопки, ТипКнопкиКоманднойПанели.Действие);
            
            СочетаниеКлавиш = Новый СочетаниеКлавиш(Клавиша[СтрокаНастройкиКнопок.Клавиша], СтрокаНастройкиКнопок.АкселераторAlt, СтрокаНастройкиКнопок.АкселераторCtrl, СтрокаНастройкиКнопок.АкселераторShift);
            ЭлементыФормы.КоманднаяПанельКнопкиФормыПоУмолчанию.Кнопки[ИмяКнопки].СочетаниеКлавиш = СочетаниеКлавиш;
            
            Если ИмяКнопки = "КнопкаЗаменитьПрава" Тогда
                АкселераторКнопкиЗаменыПрав = СтрЗаменить(ЗаголовокКнопки, "Заменить права", "");
            КонецЕсли;
            
            Если СочетаниеКлавишF2 = СочетаниеКлавиш Тогда
                НайденАкселераторF2 = Истина;
            КонецЕсли;
        КонецЦикла;
        
        Если Не НайденАкселераторF2 Тогда
            ЭлементыФормы.КоманднаяПанельНевидимыеКнопки.Кнопки.ПустоеДействие.СочетаниеКлавиш = СочетаниеКлавишF2;
        КонецЕсли;
    КонецЕсли;

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


// Проверяет наличие элемента формы
//
// Параметры:
//  ИмяЭлемента - Имя элемента формы
//
// Возвращаемое значение:
//  Истина
//
Функция ПроверитьНаличиеЭлементаФормы(ИмяЭлемента)
    
    Возврат НЕ ЭлементыФормы.Найти(ИмяЭлемента) = Неопределено;
    
КонецФункции // ПроверитьНаличиеЭлементаФормы()

// <Описание процедуры>
//
// Параметры
//  ИмяЭлемента - Имя элемента формы
//  Доступность - Булево
//
Процедура УстановитьДоступностьЭлементаФормы(ИмяЭлемента, Доступность)
    
    Если ПроверитьНаличиеЭлементаФормы(ИмяЭлемента) Тогда
        ЭлементыФормы.Найти(ИмяЭлемента).Доступность = Доступность;
    КонецЕсли;
    
КонецПроцедуры // УстановитьДоступностьЭлементаФормы()


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

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ

// Процедура - обработчик события "ПередОткрытием" формы
//
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
    
    РезультатПодключенияТО = ПолучитьСерверТО().ПодключитьКлиента(ЭтаФорма);
    
    Если ЗначениеЗаполнено(РезультатПодключенияТО) Тогда
        
        ТекстОшибки = "Ошибка подключения оборудования"
        + Символы.ПС + "Одно или несколько устройств не были подключены к компьютеру!"
        + Символы.ПС + "Обратитесь к системному администратору для разрешения проблемы."
        + Символы.ПС + "Продолжение работы не гарантирует корректной обработки чеков.";
        
        ВывестиИнформациюОбОшибке(ТекстОшибки);
        
    КонецЕсли;

    мФР = глЗначениеПеременной("мФР");

    Если мФР = Неопределено
       И Не РаботаСТорговымОборудованием.ПолучитьПроверитьПараметрыДляПробитияЧека(мФР, Истина) Тогда

        Результат = ПроверитьИУстановитьКассуККМ();

        Если Не Результат Тогда
            ВывестиИнформациюОбОшибке("Не установлен фискальный регистратор!
            |Продолжение работы невозможно.");
            
            
            ПолучитьСерверТО().ОтключитьКлиента(ЭтаФорма);
            Отказ = Истина;
            
            РМК.ОткрытьМеню();
        КонецЕсли;
    Иначе
        мКассаККМ = ПолучитьСерверТО().ПолучитьКассуККМ(мФР);
    КонецЕсли;

    Если мФР <> глЗначениеПеременной("мФР") Тогда
        глЗначениеПеременнойУстановить("мФР", мФР, Истина);
    КонецЕсли;

    ЗаполнитьКнопкиНижнейПанели();

КонецПроцедуры

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

// Процедура - обработчик события "При открытии" формы.
//
// Параметры:
//  Нет.
//
Процедура ПриОткрытии()

    
    ВосстановитьЧекККМ();
    
    // Подключает весы
    УстановитьВесы();
    
    УстановитьНастройкиПоУмолчанию();

    //КОЛОНКИ
    СтруктураКолонок = Новый Структура();

    // Установить колонки, видимостью которых пользователь управлять не может.

    СтруктураКолонок.Вставить("Номенклатура");

    СтруктураКолонок.Вставить("ХарактеристикаНоменклатуры");
    СтруктураКолонок.Вставить("Количество");

    СтруктураКолонок.Вставить("Цена");

    СтруктураКолонок.Вставить("Сумма");

    СтруктураКолонок.Вставить("ЕдиницаИзмерения");

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

    //Видимость автоматических скидок.

    

    // Запомнить текущие значения реквизитов формы.

    мТекущаяДатаДокумента = Дата;

    
    //Сумма документа
    мСуммаДокументаБезСкидок = Ценообразование.ПолучитьСуммуДокументаБезСкидки(Товары);
    
    мСуммаНДС = Ценообразование.ПолучитьСуммуНДСДокумента(Товары);
    
    Если СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Пробитый
     Или СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Архивный
     Или СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Аннулированный Тогда

        ТолькоПросмотр = Истина;

    КонецЕсли;

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

    Если Не КассаККМ.Организация.РозничнаяТорговляОблагаетсяЕНВД
       И КассаККМ.ФормироватьНефискальныеЧеки Тогда
        ВывестиИнформациюОбОшибке("Организация """ + КассаККМ.Организация + """ не облагается ЕНВД! Формирование нефискальных чеков ККМ невозможно.
            |Для изменения настроек кассы ККМ обратитесь к администратору системы.");
    КонецЕсли;

КонецПроцедуры

// Процедрура подгоняет информацию под 2 строки на основании Информации о товаре и продавце
//
// Параметры
//  СтрокаИнформацииОТоваре  - Строка - <описание параметра>
//                 <продолжение описания параметра>
//  Параметр2  - Строка - <описание параметра>
//                 <продолжение описания параметра>
//
Процедура ПолучитьСтрокуИнформацииОТоваре(СтрокаИнформацииОТоваре, СтрокаПродавца)
    
    Пробелы = "";
    Ширина = Окр(ЭлементыФормы.ИнфНадписьТекущийТовар.Ширина/14) - 2;
    Если Ширина > 2 Тогда
        n = Цел(Ширина/50);
        Для Счетчик = 0 По n Цикл
            Пробелы = Пробелы +"                                                  ";
        КонецЦикла;
        Пробелы = Лев(Пробелы, Ширина);
    КонецЕсли;
    
    ШаблонТекста = Новый ТекстовыйДокумент;
    ШаблонТекста.ДобавитьСтроку("#Область Надпись");
    ШаблонТекста.ДобавитьСтроку("["+Пробелы+"]" + "#Поля НадписьТекущийТовар");
    ШаблонТекста.ДобавитьСтроку("<"+Пробелы+">" + "#Поля НадписьТекущийТовар");
    ШаблонТекста.ДобавитьСтроку("#КонецОбласти");
    
    ОбластьМакета = ШаблонТекста.ПолучитьОбласть("Надпись");
    ОбластьМакета.Параметры.НадписьТекущийТовар = СтрокаИнформацииОТоваре + СтрокаПродавца;
    ИтоговаяНадпись = Новый ТекстовыйДокумент;
    ИтоговаяНадпись.Вывести(ОбластьМакета);
    
    Если ИтоговаяНадпись.КоличествоСтрок() > 2 Тогда
        КоличествоСимволов = 0;
        Для Счетчик = 3 По ИтоговаяНадпись.КоличествоСтрок() Цикл
            КоличествоСимволов = КоличествоСимволов + СтрДлина(СокрЛП(ИтоговаяНадпись.ПолучитьСтроку(Счетчик)));
        КонецЦикла;
        СтрокаИнформацииОТоваре = Лев(СтрокаИнформацииОТоваре, СтрДлина(СтрокаИнформацииОТоваре) - (КоличествоСимволов + 3))+"...";
    КонецЕсли;
    
КонецПроцедуры // ПолучитьСтрокуИнформацииОТоваре()

// Процедура - обработчик события "ОбновлениеОтображения" формы.
//
Процедура ОбновлениеОтображения()

    ТекущаяСтрока = ЭлементыФормы.Товары.ТекущиеДанные;

    СуммаВсего               = Товары.Итог("Сумма");
    мСуммаНДС                = Товары.Итог("СуммаНДС");
    мСуммаДокументаБезСкидок = Ценообразование.ПолучитьСуммуДокументаБезСкидки(Товары);

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

    ЭлементыФормы.СкидкиИтогоСумма.Заголовок = ОбщегоНазначения.ФорматСумм(мСуммаДокументаБезСкидок - СуммаВсего, "" ,"0,00");
    ЭлементыФормы.НадписьСумма.Заголовок     = ОбщегоНазначения.ФорматСумм(мСуммаДокументаБезСкидок, "" ,"0,00");
    ЭлементыФормы.НадписьНДС.Заголовок       = ОбщегоНазначения.ФорматСумм(мСуммаНДС, "" ,"0,00");
    ЭлементыФормы.НадписьКОплате.Заголовок   = ОбщегоНазначения.ФорматСумм(СуммаВсего, "","0,00");

    Если ТекущаяСтрока = Неопределено Тогда
        СуммаТовара = 0;
        ЭлементыФормы.ИнфНадписьТекущийТовар.Заголовок = "";
    Иначе
        СуммаТовара = ТекущаяСтрока.Цена * ТекущаяСтрока.Количество;
        
        ИнформацияОТоваре = СокрЛП(ТекущаяСтрока.Номенклатура);
        Если ТекущаяСтрока.Номенклатура.ВестиСерийныеНомера Тогда
            СтруктураПоиска = Новый Структура;
            СтруктураПоиска.Вставить("КлючСтроки", ТекущаяСтрока.КлючСтроки);
            ИнформацияОСерийныхНомерах = "";
            СтрокиСерийныхНомеров = СерийныеНомера.НайтиСтроки(СтруктураПоиска);
            Для каждого СтрокаСерийныхНомеров Из СтрокиСерийныхНомеров Цикл
                ИнформацияОСерийныхНомерах = ИнформацияОСерийныхНомерах +", "+СтрокаСерийныхНомеров.СерийныйНомер;
            КонецЦикла;
            
            Если ЗначениеЗаполнено(ИнформацияОСерийныхНомерах)  Тогда
                ИнформацияОСерийныхНомерах = "№№ " + Прав(ИнформацияОСерийныхНомерах,СтрДлина(ИнформацияОСерийныхНомерах) - 2);
            Иначе
                ИнформацияОСерийныхНомерах = "№№ ?????"
            КонецЕсли;
            ИнформацияОТоваре = ИнформацияОТоваре + " - " + ИнформацияОСерийныхНомерах;
        КонецЕсли;
        
        ИнформацияОПродавце = ?(ЗначениеЗаполнено(ТекущаяСтрока.Продавец)," (продавец: " + Строка(ТекущаяСтрока.Продавец) +")","");
        
        ПолучитьСтрокуИнформацииОТоваре(ИнформацияОТоваре, ИнформацияОПродавце);
        
        ЭлементыФормы.ИнфНадписьТекущийТовар.Заголовок = ИнформацияОТоваре
        + ИнформацияОПродавце;
        
    КонецЕсли;

    Если СуммаТовара = 0 Тогда
        ЭлементыФормы.ИнфНадписьТекущаяСумма.Заголовок = "";
    Иначе
        ПредставлениеТекущейСтроки = ОбщегоНазначения.ФорматСумм(ТекущаяСтрока.Цена, "","0,00")
        + " Х " + СокрЛП(ТекущаяСтрока.Количество)
        + " "   + СокрЛП(ТекущаяСтрока.ЕдиницаИзмерения);
        
        Скидка = ТекущаяСтрока.Цена * ТекущаяСтрока.Количество - ТекущаяСтрока.Сумма;
        Если (Скидка > 0.01 ИЛИ Скидка < -0.01) И Не(ТекущаяСтрока.Цена * ТекущаяСтрока.Количество = 0)Тогда
            ОбщийПроцентСкидки = Окр(100*Скидка / (ТекущаяСтрока.Цена * ТекущаяСтрока.Количество),2,1);
            
            ПредставлениеСкидки = ?(Скидка>0," - " + ОбщегоНазначения.ФорматСумм(Скидка,,"0,00")
                                    ," + "+ ОбщегоНазначения.ФорматСумм(-Скидка,,"0,00"));
            ПредставлениеСкидки = ПредставлениеСкидки + " ( "+Строка(ОбщийПроцентСкидки)+"% ) ";
            
            ПредставлениеТекущейСтроки = ПредставлениеТекущейСтроки + ПредставлениеСкидки;
        КонецЕсли;
        
        ЭлементыФормы.ИнфНадписьТекущаяСумма.Заголовок = ПредставлениеТекущейСтроки
        + " = " + ОбщегоНазначения.ФорматСумм(ТекущаяСтрока.Сумма,,"0,00");
        
    КонецЕсли;

    Если Не мОтображатьПодборВПравойЧастиЭкрана Тогда

        // Условие вызывается при открытии формы, и развертывании ее на весь экран
        Если мОбновитьВысотуПодбора Тогда

            ЭлементыФормы.Товары.ТолькоПросмотр = Истина;

            Если Не ЭлементыФормы.ПанельПодборКлавиши.ТекущаяСтраница = ЭлементыФормы.ПанельПодборКлавиши.Страницы.Клавиши Тогда
                ЭлементыФормы.ПанельПодборКлавиши.ТекущаяСтраница = ЭлементыФормы.ПанельПодборКлавиши.Страницы.Клавиши;
            КонецЕсли;
            

            ОтобразитьПодбор = ВосстановитьЗначение("ФормаРегистрацииПродаж_ОтображатьПодбор");

            Если ОтобразитьПодбор = Неопределено Тогда
                ОтобразитьПодбор = Ложь;
            КонецЕсли;

            Если ОтобразитьПодбор Тогда
                ОтобразитьТаблицаПодборКлавиши(Ложь);
            Иначе
                ЗакрытьПанельПодборБыстрыеТовары();
            КонецЕсли;

            УстановитьАктивныйЭлемент();

        КонецЕсли;
        
    Иначе

        Если Не ЭлементыФормы.ПанельПодборКлавиши.ТекущаяСтраница = ЭлементыФормы.ПанельПодборКлавиши.Страницы.Подбор Тогда
            ЭлементыФормы.ПанельПодборКлавиши.ТекущаяСтраница = ЭлементыФормы.ПанельПодборКлавиши.Страницы.Подбор;
        КонецЕсли;

        // Условие вызывается при открытии формы, и развертывании ее на весь экран
        Если мОбновитьВысотуПодбора Тогда
        
            // Управление подбором номенклатуры
            УстановитьВидимостьПараметрыНоменклатуры();
            
            ЗакрытьПанельПодборБыстрыеТовары();
            
            УстановитьВидимостьИнформации();
            
            УстановитьВидимостьИерархии();
            
        КонецЕсли;
        
    КонецЕсли;
    
    // Настраиваем панели формы
    Если мОбновитьВысотуПодбора Тогда
    
        Если Не (мИспользоватьНастройкуРМК И мНастройкаРМК.ОткрыватьПравуюПанельПриЗапуске) Тогда
            ОтобразитьСкрытьПравуюПанель(Неопределено);
        КонецЕсли;
        
        Если Не (мИспользоватьНастройкуРМК И мНастройкаРМК.ОткрыватьНижнююПанельПриЗапуске) Тогда
            ОтобразитьСкрытьНижнююПанель(Неопределено);
        КонецЕсли;
        
    КонецЕсли;
    
    мОбновитьВысотуПодбора = Ложь;

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

        ТекущаяСтрока1 = мТекущиеСтрокиДисплеяПокупателя[0].Текст;
        Строка1 = ?(ТекущаяСтрока1 = ТаблицаДляВыводаНаДисплей[0].Текст, "", ТаблицаДляВыводаНаДисплей[0].Текст);
        ТекущаяСтрока2 = мТекущиеСтрокиДисплеяПокупателя[1].Текст;
        Строка2 = ?(ТекущаяСтрока2 = ТаблицаДляВыводаНаДисплей[1].Текст, "", ТаблицаДляВыводаНаДисплей[1].Текст);

        Если Не (Строка1 = "" И Строка2 = "") Тогда
            ВывестиИнформациюНаДисплейПокупателя(СоздатьТаблицуДляВыводаНаДисплейПокупателя(Строка1, Строка2));
            мТекущиеСтрокиДисплеяПокупателя = ТаблицаДляВыводаНаДисплей;
        КонецЕсли;

    КонецЕсли;

КонецПроцедуры

// Процедура - обработчик внешнего события, которое возникает при посылке
// внешним приложением сообщения, сформированного в специальном формате.
// Внешнее событие сначала обрабатывается всеми открытыми формами, имеющими
// обработчик этого события, а затем может быть обработано в процедуре модуля
// приложения с именем ОбработкаВнешнегоСобытия().
//
// Параметры:
//  Источник - <Строка>
//           - Источник внешнего события.
//
//  Событие  - <Строка>
//           - Наименование события.
//
//  Данные   - <Строка>
//           - Данные для события.
//
Процедура ВнешнееСобытие(Источник, Событие, Данные)
    
    Если Не ВводДоступен() Тогда
        Возврат;
    КонецЕсли;
    
    ПолучитьСерверТО().ОбработатьВнешнееСобытие(Источник, Событие, Данные, ЭтаФорма);
    
КонецПроцедуры // ВнешнееСобытие()


// Процедура - обработчик события "ПередЗакрытием" формы.
//
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;

    Если Не Товары.Количество() = 0 Тогда
        ВывестиИнформациюОбОшибке("Перед выходом необходимо пробить, аннулировать или отложить чек!");
        Отказ = Истина;
    КонецЕсли;
    
    Если мОтображатьПодборВПравойЧастиЭкрана И
     Не  ОтображатьИнформацию Тогда

        ОтображатьИнформацию = Истина;
        УстановитьВидимостьИнформации();
        ОтображатьИнформацию = Ложь;

    КонецЕсли;

КонецПроцедуры

// Процедура - обработчик события "При закрытии" формы.

//

// Параметры:

//  Нет.

//

Процедура ПриЗакрытии()


    СохранитьЗначения();

    ОчиститьАвтосохраненныеЧекиККМ();

    РежимРМК = Ложь;

    ПолучитьСерверТО().ОтключитьКлиента(ЭтаФорма);


КонецПроцедуры // ПриЗакрытии()



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

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ДЕЙСТВИЯ КНОПОК ШАПКИ ФОРМЫ

// Процедура - обработчик события "Нажатие" гиперссылки "ВладелецДисконтнойКарты".
//
Процедура ВладелецДисконтнойКартыНажатие(Элемент)
    
    Если ЗначениеЗаполнено(ВладелецДисконтнойКарты) Тогда
        ФормаВладельца = ВладелецДисконтнойКарты.ПолучитьФорму(, ЭтаФорма);
        ФормаВладельца.ТолькоПросмотр = Истина;
        ФормаВладельца.Открыть();
    КонецЕсли;
    
КонецПроцедуры // ВладелецДисконтнойКартыНажатие()

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


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

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

// Процедура вызывается при нажатии на кнопку "Подбор" формы.
//
Процедура ОтобразитьСкрытьПравуюПанель(Элемент)
    
    Если ЭлементыФормы.ПанельПодборКлавиши.Свертка = РежимСверткиЭлементаУправления.Право Тогда
        
        ЭлементыФормы.ПанельПодборКлавиши.Свертка  = РежимСверткиЭлементаУправления.Нет;
        ЭлементыФормы.Разделитель.Свертка          = РежимСверткиЭлементаУправления.Нет;
        
        ЭлементыФормы.Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, Панель, ГраницаЭлементаУправления.Лево, Панель, ГраницаЭлементаУправления.Право);
        ЭлементыФормы.ПанельПодборКлавиши.УстановитьПривязку(ГраницаЭлементаУправления.Лево, ЭлементыФормы.Разделитель, ГраницаЭлементаУправления.Право);
        
    Иначе
        
        ЭлементыФормы.ПанельПодборКлавиши.УстановитьПривязку(ГраницаЭлементаУправления.Лево);
        ЭлементыФормы.Разделитель.УстановитьПривязку(ГраницаЭлементаУправления.Право, ЭлементыФормы.ПанельПодборКлавиши, ГраницаЭлементаУправления.Лево);
        
        ЭлементыФормы.ПанельПодборКлавиши.Свертка  = РежимСверткиЭлементаУправления.Право;
        ЭлементыФормы.Разделитель.Свертка          = РежимСверткиЭлементаУправления.Право;
        
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры

// Процедура вызывается при нажатии на кнопку "Кнопки" формы.
//
Процедура ОтобразитьСкрытьНижнююПанель(Элемент)
    
    Если ЭлементыФормы.КнопкиФормыПоУмолчанию.Свертка = РежимСверткиЭлементаУправления.Низ Тогда
        ЭлементыФормы.КнопкиФормыПоУмолчанию.Свертка = РежимСверткиЭлементаУправления.Нет;
    Иначе
        ЭлементыФормы.КнопкиФормыПоУмолчанию.Свертка = РежимСверткиЭлементаУправления.Низ;
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры



////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ДЕЙСТВИЯ КНОПОК ПОДВАЛА ФОРМЫ

// Процедура - обработчик события "Нажатие" кнопки "ВвестиСкидкуНаценкуНаТовар".
//
Процедура КнопкаВвестиСкидкуНаценкуНаТоварНажатие(Элемент)
    
    Кнопки = ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки;
    
    Если Товары.Количество() = 0
        И Не мОтображатьПодборВПравойЧастиЭкрана Тогда
        НажатиеКлавиши(Кнопки.КлавишаСтереть);
        УстановитьАктивныйЭлемент();
        Возврат;
    КонецЕсли;
    
    ТекущаяСтрока = ЭлементыФормы.Товары.ТекущаяСтрока;
    
    Если ТекущаяСтрока = Неопределено Тогда
        УстановитьАктивныйЭлемент();
        Возврат;
    ИначеЕсли ТекущаяСтрока.Номенклатура.ПодарочныйСертификат Тогда
        СтрокаСообщения = "Изменение цены на подарочные сертификаты запрещено";
        ОбщегоНазначения.СообщитьОбОшибке(СтрокаСообщения);
        Возврат;
    КонецЕсли;
    
    ФормаВводаСкидкиНаценки          = ПолучитьФорму("ФормаВводаСкидкиНаценки", ЭтаФорма);
    Если Не мОтображатьПодборВПравойЧастиЭкрана Тогда
        ФормаВводаСкидкиНаценки.Значение = ЭлементыФормы.ИнфНадписьТекущееЗначение.Заголовок;
        НажатиеКлавиши(Кнопки.КлавишаСтереть);
    КонецЕсли;
    
    ЗначениеСкидкиНаценки = ФормаВводаСкидкиНаценки.ОткрытьМодально();
    Если Не ЗначениеЗаполнено(ЗначениеСкидкиНаценки) Тогда
        УстановитьАктивныйЭлемент();
        Возврат;
    КонецЕсли;
    
    ВидСкидкиНаценки      = ФормаВводаСкидкиНаценки.Вид;
    
    Если ВидСкидкиНаценки = "Процент" Тогда
        
        ТекущаяСтрока.ПроцентСкидкиНаценки = ЗначениеСкидкиНаценки;
        
    Иначе
        
        ОкруглятьПроцентСкидкиВБольшуюСторону = (мИспользоватьНастройкуРМК И мНастройкаРМК.ОкруглятьПроцентСкидкиВБольшуюСторону);
        ТекущийРежимОкругления = ?(ОкруглятьПроцентСкидкиВБольшуюСторону, РежимОкругления.Окр15как20, РежимОкругления.Окр15как10);
        
        ТекущаяСтрокаСумма     = ТекущаяСтрока.Сумма + (ТекущаяСтрока.Цена * ТекущаяСтрока.Количество * (ТекущаяСтрока.ПроцентСкидкиНаценки / 100));
        
        Если ТекущаяСтрока.Цена = 0 Тогда
            ВывестиИнформациюОбОшибке("Цена текущей строки равна 0. Расчет скидки невозможен!");
            Если Не мОтображатьПодборВПравойЧастиЭкрана Тогда
                НажатиеКлавиши(Кнопки.КлавишаСтереть);
            КонецЕсли;
            УстановитьАктивныйЭлемент();
            Возврат;
        КонецЕсли;
        
        Если ТекущаяСтрокаСумма = 0 Тогда
            ВывестиИнформациюОбОшибке("Сумма текущей строки равна 0. Расчет скидки невозможен!");
            Если Не мОтображатьПодборВПравойЧастиЭкрана Тогда
                НажатиеКлавиши(Кнопки.КлавишаСтереть);
            КонецЕсли;
            УстановитьАктивныйЭлемент();
            Возврат;
        КонецЕсли;
        
        СуммаСоСкидками = ТекущаяСтрокаСумма - ЗначениеСкидкиНаценки;
        СуммаБезСкидок  = ТекущаяСтрока.Цена * ТекущаяСтрока.Количество;
        ПроцентСкидки   = 100 - (СуммаСоСкидками * 100) / СуммаБезСкидок;
        ПроцентСкидкиНаценки = ПроцентСкидки ;
        
        ПроцентСкидкиНаценки = Окр(ПроцентСкидкиНаценки, 2, ТекущийРежимОкругления);
        
        ТекущаяСтрока.ПроцентСкидкиНаценки = ПроцентСкидкиНаценки;
        
    КонецЕсли;
    
    ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(ТекущаяСтрока, ЭтотОбъект);
    ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(ТекущаяСтрока, ЭтотОбъект);
    
    Если Не мОтображатьПодборВПравойЧастиЭкрана Тогда
        НажатиеКлавиши(Кнопки.КлавишаСтереть);
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры

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

    УстановитьАктивныйЭлемент();

КонецПроцедуры

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

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

    ФормаВыбора.ОткрытьМодально();
    РезультатВыбора = ФормаВыбора.ВыбранноеЗначение;
    
    Если Не ЗначениеЗаполнено(РезультатВыбора) Тогда
        УстановитьАктивныйЭлемент();
        Возврат;
    КонецЕсли;
    
    Объект = РезультатВыбора.ПолучитьОбъект();
    
    Попытка
        Объект.Заблокировать();
        ДокументОбъект = Объект;
        Дата           = НачалоДня(ТекущаяДата());
        НомерЧекаККМ = мНомерЧекаККМ;
        РежимРМК = Истина;
        СтатусЧекаККМ  = Перечисления.СтатусыЧековККМ.ПустаяСсылка();
        РаботаСДиалогами.УстановитьВидимостьКолонокХарактеристикаНоменклатурыПриОткрытии(Товары, мКолонкиТовары.ХарактеристикаНоменклатуры);
    Исключение
        ТекстОшибки = "Ошибка загрузки чека."
        + Символы.ПС + "Возникла ошибка при попытке загрузить отложенный чек!"
        + Символы.ПС + ОписаниеОшибки();
        ВывестиИнформациюОбОшибке(ТекстОшибки);
    КонецПопытки;
    
    Обновить();
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры

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

// Процедура - обработчик события "Нажатие" кнопки "БыстрыеТовары".
//
Процедура КнопкаБыстрыеТоварыНажатие(Элемент)

    ОтобразитьТаблицаПодборКлавиши(Истина);
    
    УстановитьАктивныйЭлемент();

КонецПроцедуры

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

        ТоварыПриИзмененииКоличества(ТекущиеДанные);

    Иначе
        
        Текст = ПолучитьСерверТО().ПолучитьТекстОшибкиЭВТО(Результат);
        Если мСписокВесов.Количество() > 1 Тогда
            мТекущиеВесы = Неопределено;
        КонецЕсли;
        
        ТекстОшибки = "Ошибка работы с весами Online!"
        + Символы.ПС + "Ошибка получения значения веса!"
        + Символы.ПС + СокрЛП(Текст);
        
        ВывестиИнформациюОбОшибке(ТекстОшибки);
        
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры

// Процедура - обработчик события "Нажатие" кнопки "КнопкаПродавец".
//
Процедура КнопкаПродавецНажатие(Элемент)
    
    ФормаВыбора = Справочники.ФизическиеЛица.ПолучитьФормуВыбора();
    ВыбранныйПродавец = ФормаВыбора.ОткрытьМодально();
    
    Если Не ЗначениеЗаполнено(ВыбранныйПродавец) Тогда
        УстановитьАктивныйЭлемент();
        Возврат;
    КонецЕсли;
    
    ТекущаяСтрока = ЭлементыФормы.Товары.ТекущаяСтрока;
    Если Товары.Количество() = 0 Тогда
        Продавец = ВыбранныйПродавец;
    Иначе
        Если ТекущаяСтрока <> Неопределено Тогда
            ТекущаяСтрока.Продавец = ВыбранныйПродавец;
        КонецЕсли;
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры

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

            ТекстОшибки = ОбщегоНазначения.ФорматСумм(Сумма)
            + Символы.ПС + "Ошибка внесения денег в кассу!"
            + Символы.ПС + СокрЛП(ПолучитьСерверТО().ПолучитьТекстОшибкиТО(Результат));
            ВывестиИнформациюОбОшибке(ТекстОшибки);

        КонецЕсли;
        
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры //КнопкаВвестиВнесениеДенег

// Процедура - обработчик события "Нажатие" кнопки "КнопкаВвестиИзъятиеДенег".
//
Процедура КнопкаВвестиИзъятиеДенегНажатие(Кнопка)

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

    Если ЗначениеЗаполнено(Сумма) Тогда
        
        Результат = ПолучитьСерверТО().ВнестиСумму(мФР, -Сумма);
        Если ЗначениеЗаполнено(Результат) Тогда

            ТекстОшибки = ОбщегоНазначения.ФорматСумм(Сумма)
            + Символы.ПС + "Ошибка изъятия денег из кассы!"
            + Символы.ПС + СокрЛП(ПолучитьСерверТО().ПолучитьТекстОшибкиТО(Результат));
            ВывестиИнформациюОбОшибке(ТекстОшибки);

        КонецЕсли;
    КонецЕсли;

    УстановитьАктивныйЭлемент();

КонецПроцедуры //КнопкаВвестиИзъятиеДенегНажатие()

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

// Процедура - обработчик события "Нажатие" кнопки "КнопкаВвестиСкидкуНаценку".
// Назначает ручную скидку на позиции товара.
//
Процедура КнопкаВвестиСкидкуНаценкуНажатие(Кнопка)

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

    // Получает специализированную форму ввода скидки/наценки,
    // устанавливает значения реквизитов формы
    ФормаВводаСкидкиНаценки = ПолучитьФорму("ФормаВводаСкидкиНаценки", ЭтаФорма);
    ФормаВводаСкидкиНаценки.Значение = ЭлементыФормы.ИнфНадписьТекущееЗначение.Заголовок;
    НажатиеКлавиши(ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки.КлавишаСтереть);
    
    ЗначениеСкидкиНаценки = ФормаВводаСкидкиНаценки.ОткрытьМодально();
    Если Не ЗначениеЗаполнено(ЗначениеСкидкиНаценки) Тогда
        Возврат;
    КонецЕсли;

    // Очищает все текущие скидки, вызывая обработчик нажатия кнопки "КнопкаОтменаСкидкиНаценки"
    ОчиститьРучныеСкидки();

    //Получает вид скидки, установленный в форме выбора скидки / наценки
    ВидСкидкиНаценки = ФормаВводаСкидкиНаценки.Вид;

    Если ВидСкидкиНаценки = "Процент" Тогда

        //Обработка ввода процентного значения скидки.

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

    Иначе

        //Обработка ввода суммового значения скидки. Преобразование к процентному значению.

        ОкруглятьПроцентСкидкиВБольшуюСторону = (мИспользоватьНастройкуРМК И мНастройкаРМК.ОкруглятьПроцентСкидкиВБольшуюСторону);
        ТекущийРежимОкругления = ?(ОкруглятьПроцентСкидкиВБольшуюСторону, РежимОкругления.Окр15как20, РежимОкругления.Окр15как10);

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

        Для каждого СтрокаТабличнойЧастиТовары Из Товары Цикл
            Если НЕ СтрокаТабличнойЧастиТовары.Номенклатура.ПодарочныйСертификат Тогда
                СуммаБезСкидок  = СтрокаТабличнойЧастиТовары.Цена * СтрокаТабличнойЧастиТовары.Количество;

                ТекущаяСумма = СтрокаТабличнойЧастиТовары.Сумма + (СтрокаТабличнойЧастиТовары.Цена * СтрокаТабличнойЧастиТовары.Количество * (СтрокаТабличнойЧастиТовары.ПроцентСкидкиНаценки / 100));

                Дельта       = ЕдиницаРаспределения * ТекущаяСумма;

                // Проверим текущую сумму на максимум.
                Если ТекущаяСумма > МаксимальнаяСумма Тогда
                    МаксимальнаяСумма       = ТекущаяСумма;
                    СтрокаМаксимальнойСуммы = СтрокаТабличнойЧастиТовары;
                КонецЕсли;

                ПроцентСкидкиНаценки = Дельта / (ТекущаяСумма / 100);
                ПроцентСкидкиНаценки = Окр(ПроцентСкидкиНаценки, 2, ТекущийРежимОкругления);

                СуммаСоСкидками = ТекущаяСумма - Дельта;
                ПроцентСкидки   = 100 - (СуммаСоСкидками * 100) / СуммаБезСкидок;
                ПроцентСкидкиНаценки = ПроцентСкидки;
                
                ПроцентСкидкиНаценки = Окр(ПроцентСкидкиНаценки, 2, ТекущийРежимОкругления);

                СтрокаТабличнойЧастиТовары.ПроцентСкидкиНаценки = ПроцентСкидкиНаценки;

                // Остаток нераспределенной суммы надо уменьшать на дельту реального изменения
                НепогашеннаяСумма = НепогашеннаяСумма - Дельта;

                ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТабличнойЧастиТовары, ЭтотОбъект);
                ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧастиТовары, ЭтотОбъект);
            КонецЕсли;
        КонецЦикла;

        // Если что-то осталось, кидаем на строку с максимальной суммой.

        Если НепогашеннаяСумма <> 0 И СтрокаМаксимальнойСуммы <> Неопределено Тогда

            СуммаБезСкидок  = СтрокаМаксимальнойСуммы.Цена * СтрокаМаксимальнойСуммы.Количество;
            ТекущаяСумма = СтрокаМаксимальнойСуммы.Сумма + (СтрокаМаксимальнойСуммы.Цена * СтрокаМаксимальнойСуммы.Количество * (СтрокаМаксимальнойСуммы.ПроцентСкидкиНаценки / 100));

            ПроцентСкидкиНаценки = НепогашеннаяСумма / (ТекущаяСумма / 100);
            ПроцентСкидкиНаценки = Окр(ПроцентСкидкиНаценки, 2, ТекущийРежимОкругления);

            СтрокаМаксимальнойСуммы.ПроцентСкидкиНаценки = СтрокаМаксимальнойСуммы.ПроцентСкидкиНаценки + ПроцентСкидкиНаценки;

            ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаМаксимальнойСуммы, ЭтотОбъект);
            ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаМаксимальнойСуммы, ЭтотОбъект);

        КонецЕсли;

    КонецЕсли;

    УстановитьАктивныйЭлемент();

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

// Процедура - обработчик события "Нажатие" кнопки "КнопкаОтменаСкидкиНаценки".
//
Процедура КнопкаОтменаСкидкиНаценкиНажатие(Элемент)
    
    ОчиститьРучныеСкидки();
    
КонецПроцедуры //КнопкаОтменаСкидкиНажатие()

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

                Форма = ПолучитьФорму("Обработка.m000_02.Форма", ПараметрыФормы );
                
                
                резФорма = Форма.ОткрытьМодально();
                
                Если резФорма <> Неопределено Тогда             

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

    УстановитьАктивныйЭлемент();

КонецПроцедуры //КнопкаВвестиШтрихкод

// Процедура - обработчик события "Нажатие" кнопки "КнопкаВвестиИнформационнуюКарт".
//
Процедура КнопкаВвестиИнформационнуюКартуНажатие(Элемент)

    ВыбратьИнформационнуюКарту();

    УстановитьАктивныйЭлемент();

КонецПроцедуры //КнопкаВвестиДисконтнуюКартуНажатие()

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

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

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

                Результат = ПолучитьСерверТО().АннулироватьЧек(мФР);
                Если ЗначениеЗаполнено(Результат) Тогда
                    ВывестиИнформациюОбОшибке("Ошибка аннулирования чека!" + Символы.ПС + ПолучитьСерверТО().ПолучитьТекстОшибкиТО(Результат));
                    УстановитьАктивныйЭлемент();
                    Возврат;
                КонецЕсли;
            КонецЕсли;

            Дата = ТекущаяДата();
            СоздатьНовыйДокумент(Перечисления.СтатусыЧековККМ.Аннулированный);
            
        КонецЕсли;
    КонецЕсли;
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры //КнопкаВвестиАннулированиеНажатие()

// Процедура - обработчик события "Нажатие" кнопки "ВвестиВозвратТовараОтРозничногоПокупателя".
//
Процедура КнопкаВвестиВозвратТовараОтРозничногоПокупателяНажатие(Кнопка)

    Обработка       = Обработки.ВозвратТоваровОтРозничногоПокупателя.Создать();
    Обработка.Касса = КассаККМ;

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

    Форма = Обработка.ПолучитьФорму();
    Форма.ОткрытьМодально();

    УстановитьАктивныйЭлемент();

КонецПроцедуры //КнопкаВвестиВозвратТовараОтРозничногоПокупателяНажатие

// Процедура - обработчик события "Нажатие" кнопки "КнопкаРежимОператора".
//
Процедура КнопкаРежимОператораНажатие(Элемент)

    глЗначениеПеременнойУстановить("мФР", мФР, Истина);
    
    ПараметрыСеанса.РежимРегистрацииПродаж    = Ложь;
    ПараметрыСеанса.ОткрытРежимМенеджераИзРМК = Истина;

    ЭтаФорма.Закрыть("ЗапуститьРежимОператора");

КонецПроцедуры //КнопкаРежимОператораНажатие()

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

        Если ЗначениеЗаполнено(Результат) Тогда
            Ошибка = ПолучитьСерверТО().ПолучитьТекстОшибкиТО(Результат);
            ВывестиИнформациюОбОшибке(Ошибка);
        КонецЕсли;
    КонецЕсли;
    
КонецПроцедуры

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


// Процедура - обработчик события "Нажатие" кнопки "КнопкаВыход".
//
Процедура КнопкаВыходНажатие(Кнопка)

    Отказ = Ложь;

    Если Товары.Количество() > 0 Тогда
        ВывестиИнформациюОбОшибке("Перед выходом необходимо пробить, аннулировать или отложить чек!");
        Отказ = Истина;
    КонецЕсли;

    Если Не Отказ Тогда
        
        ПараметрыСеанса.РежимРегистрацииПродаж    = Ложь;
        ПараметрыСеанса.ОткрытРежимМенеджераИзРМК = Ложь;
        
        глЗначениеПеременнойУстановить("мФР", мФР, Истина);
        РМК.ОткрытьМеню();
        Закрыть();
        
    КонецЕсли;

    УстановитьАктивныйЭлемент();

КонецПроцедуры

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


// Процедура - обработчик события "Нажатие" кнопки "Расчет скидок".
//
Процедура КнопкаРасчетСкидокНажатие(Элемент)
    
    ПересчитатьАвтоматическиеСкидки();
    
КонецПроцедуры

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

        ФормаВыбора.ОткрытьМодально();
        ЧекККМНеПробитый = ФормаВыбора.ВыбранноеЗначение;

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

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

// Процедура - обработчик события "Нажатие" кнопки "ЗаменаКарты".
//
Процедура КоманднаяПанельНевидимыеКнопкиЗаменаКарты(Кнопка)
    
    ДокументЗаменыКарты = Документы.ЗаменаКартПокупателей.СоздатьДокумент();
    ДокументЗаменыКарты.Магазин = Магазин;
    
    Если ЗначениеЗаполнено(ДисконтнаяКарта)  Тогда
        СтрокаДокументаЗамены = ДокументЗаменыКарты.КартыПокупателей.Добавить();
        СтрокаДокументаЗамены.КартаИсточник = ДисконтнаяКарта;
    ИначеЕсли Товары.Количество() = 0 И ЗначениеЗаполнено(ДисконтнаяКартаДляЗамены) Тогда
        СтрокаДокументаЗамены = ДокументЗаменыКарты.КартыПокупателей.Добавить();
        СтрокаДокументаЗамены.КартаИсточник = ДисконтнаяКартаДляЗамены;
    КонецЕсли;
    
    ФормаДокументаЗаменаОднойКарты = ДокументЗаменыКарты.ПолучитьФорму("ФормаДокументаЗаменаОднойКарты");
    ФормаДокументаЗаменаОднойКарты.ОткрытьМодально();
    
    Если ЗначениеЗаполнено(ДисконтнаяКарта) И ДокументЗаменыКарты.Проведен Тогда
        ОбработатьСчитываниеИнформационнойКарты(ДокументЗаменыКарты.КартыПокупателей[0].КартаПриемник)
    КонецЕсли;
    
    ДисконтнаяКартаДляЗамены = "";
    
КонецПроцедуры



// Процедура - обработчик события "Нажатие" кнопки "ПустоеДействие".
// Процедура используется для перекрывания клавиши F2
//
Процедура КоманднаяПанельНевидимыеКнопкиПустоеДействие(Кнопка)
    
    Акселератор = Клавиша.F2;
КонецПроцедуры


// Процедура - обработчик события "ОбработкаВыбора" таблицы "Товары"
// колонки "Номенклатура"
//
Процедура ТоварыНоменклатураОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    
    Если Не ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
    
КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ КОММАНДНОЙ ПАНЕЛИ "Быстрые товары"

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


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ ТАБЛИЧНОЙ ЧАСТИ "ТОВАРЫ"

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


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

// Процедура - обработчик события "ПриНачалеРедактирования" табличной части
// "Товары".
//
Процедура ТоварыПриНачалеРедактирования(Элемент, НоваяСтрока)
    
    СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущиеДанные;
    
    // Установим способ редактирования цены.
    Если СтрокаТабличнойЧасти <> Неопределено Тогда
        УстановитьСвойстваПоляВводаЦены(СтрокаТабличнойЧасти.Номенклатура);
    КонецЕсли;
    
    Если НоваяСтрока Тогда
        Элемент.ТекущиеДанные.КлючСтроки = УправлениеЗапасами.ПолучитьНовыйКлючСтроки(ЭтотОбъект);
        
        СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущиеДанные;
        Если ЗначениеЗаполнено(СтрокаТабличнойЧасти.Номенклатура) Тогда
            // Ввод состава набора
            УправлениеЗапасами.ДобавитьСоставНабора(СтрокаТабличнойЧасти, ЭтотОбъект);
        КонецЕсли;
        
    КонецЕсли;  
    
    // Для элемента управления поля "Характеристика номенклатуры" произведем установку признака автоматической подсветки незаполненного значения
    Элемент.Колонки.ХарактеристикаНоменклатуры.ЭлементУправления.ОтметкаНезаполненного     = ЛОЖЬ;
    Элемент.Колонки.ХарактеристикаНоменклатуры.ЭлементУправления.АвтоОтметкаНезаполненного = ОбщегоНазначения.ПолучитьФлагУчетаХарактеристик(Элемент.ТекущаяСтрока.Номенклатура.ВидНоменклатуры);
    
КонецПроцедуры // ТоварыПриНачалеРедактирования()

// Процедура - обработчик события "ПередОкончаниемРедактирования" табличной части
// "Товары".
//
Процедура ТоварыПередОкончаниемРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования, Отказ)

    ТекущаяСтрока = ЭлементыФормы.Товары.ТекущаяСтрока;
    
    Если НЕ ТекущаяСтрока = Неопределено Тогда
        // Получим признак возможности завершить редактирование строки
        Отказ = Отказ ИЛИ (НЕ ЗначениеЗаполнено(ТекущаяСтрока.Номенклатура));
        Отказ = Отказ ИЛИ (НЕ ЗначениеЗаполнено(ТекущаяСтрока.ХарактеристикаНоменклатуры)) И ОбщегоНазначения.ПолучитьФлагУчетаХарактеристик(ТекущаяСтрока.Номенклатура.ВидНоменклатуры);

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

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

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


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


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

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

// Процедура обрабатывает изменение номенклатуры в ТЧ товары. Для обращений извне.
//
Процедура ТоварыПриИзмененииНоменклатуры(СтрокаТабличнойЧасти, ПерейтиНаКоличество = Ложь) Экспорт

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

    // Выполнить общие действия для всех документов при изменении номенклатуры.

    ОбработкаТабличныхЧастей.ПриИзмененииНоменклатурыТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);

    
    СтрокаТабличнойЧасти.Склад = ОбработкаТабличныхЧастей.ПолучитьСкладПродажиНоменклатуры(СтрокаТабличнойЧасти.Номенклатура, КассаККМ);
    
    ОбработкаТабличныхЧастей.СформироватьСтавкуНДСВЧекеККМ(Дата, СтрокаТабличнойЧасти, глЗначениеПеременной("глТекущийПользователь"));
    
    // Определим признак необходимости выполнить получение цены
    ВыполнитьУстановкуЦены = ПерейтиНаКоличество ИЛИ (НЕ ОбщегоНазначения.ПолучитьФлагУчетаХарактеристик(СтрокаТабличнойЧасти.Номенклатура.ВидНоменклатуры));
    
    // Производим получение цены товара
    Если ВыполнитьУстановкуЦены Тогда
        
        ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуЦенуТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
        
        // Установим способ редактирования цены.
        УстановитьСвойстваПоляВводаЦены(СтрокаТабличнойЧасти.Номенклатура);
        
        Если СтрокаТабличнойЧасти.Цена = 0
            И СтрокаТабличнойЧасти.Номенклатура <> Неопределено Тогда
            
            Если мИспользоватьНастройкуРМК И мНастройкаРМК.НазначатьЦенуТоварамСНулевойЦеной 
            И НЕ СтрокаТабличнойЧасти.Номенклатура.ПодарочныйСертификат Тогда
                
                Цена = 0;
                ВвестиЧисло(Цена, "Введите цену товара",15,2);
                СтрокаТабличнойЧасти.Цена = Цена;
                Если Цена = 0 Тогда
                    ВывестиИнформациюОбОшибке("Цена не установлена!");
                КонецЕсли;
                
            Иначе
                
                ВывестиИнформациюОбОшибке("На товар " + СтрокаТабличнойЧасти.Номенклатура 
                + УниверсальныеМеханизмы.ПредставлениеХарактеристик(СтрокаТабличнойЧасти) 
                + " не назначена цена!");
                
            КонецЕсли;
            
        КонецЕсли;
        
        Если СтрокаТабличнойЧасти.Склад.ТипСклада = Перечисления.ТипыСкладов.ТорговыйЗал Тогда
            РазрешитьНулевыеЦены = УправлениеПользователями.РазрешитьНулевыеЦеныДляТорговогоЗала();
        Иначе
            РазрешитьНулевыеЦены = УправлениеПользователями.РазрешитьНулевыеЦеныДляСкладов();
        КонецЕсли;
        
        Если Не РазрешитьНулевыеЦены И СтрокаТабличнойЧасти.Цена = 0 Тогда
            Товары.Удалить(СтрокаТабличнойЧасти);
            Возврат;
        КонецЕсли;
        
        Если СтрокаТабличнойЧасти.Количество = 0 Тогда
            СтрокаТабличнойЧасти.Количество = 1;
        КонецЕсли;
        
        ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);

        ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
        

    КонецЕсли;
    
    СтрокаТабличнойЧасти.Продавец = Продавец;

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

КонецПроцедуры


// Процедура обрабатывает изменение характеристики номенклатуры в ТЧ товары. Для обращений извне.
//
Процедура ТоварыПриИзмененииХарактеристикиНоменклатуры(СтрокаТабличнойЧасти) Экспорт

    // Активизировать ячейку табличного поля можно только в случае когда редактирование последнего разрешено
    Если НЕ ЭлементыФормы.Товары.ТолькоПросмотр Тогда
        
        //Активизирует колонку "Количество"
        РаботаСДиалогами.АктивизироватьЯчейкуТабличногоПоля(ЭлементыФормы.Товары, СтрокаТабличнойЧасти, мКолонкиТовары.Количество);
        
    КонецЕсли;
    
    ОбработкаТабличныхЧастей.ЗаполнитьЕдиницуЦенуТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
    
    // Установим способ редактирования цены.
    УстановитьСвойстваПоляВводаЦены(СтрокаТабличнойЧасти.Номенклатура);
    
    Если СтрокаТабличнойЧасти.Цена = 0
        И СтрокаТабличнойЧасти.Номенклатура <> Неопределено Тогда
        
        Если мИспользоватьНастройкуРМК и мНастройкаРМК.НазначатьЦенуТоварамСНулевойЦеной Тогда
            
            Цена = 0;
            ВвестиЧисло(Цена, "Введите цену товара",15,2);
            СтрокаТабличнойЧасти.Цена = Цена;
            Если Цена = 0 Тогда
                ВывестиИнформациюОбОшибке("Цена не установлена!");
            КонецЕсли;
            
        Иначе
            
            ВывестиИнформациюОбОшибке("На товар " + СтрокаТабличнойЧасти.Номенклатура 
                                                   + УниверсальныеМеханизмы.ПредставлениеХарактеристик(СтрокаТабличнойЧасти) 
                                                   + " не назначена цена!");
        
        КонецЕсли;
        
    КонецЕсли;
    
    Если СтрокаТабличнойЧасти.Склад.ТипСклада = Перечисления.ТипыСкладов.ТорговыйЗал Тогда
        РазрешитьНулевыеЦены = УправлениеПользователями.РазрешитьНулевыеЦеныДляТорговогоЗала();
    Иначе
        РазрешитьНулевыеЦены = УправлениеПользователями.РазрешитьНулевыеЦеныДляСкладов();
    КонецЕсли;
    
    Если Не РазрешитьНулевыеЦены И СтрокаТабличнойЧасти.Цена = 0 Тогда
        Товары.Удалить(СтрокаТабличнойЧасти);
        Возврат;
    КонецЕсли;
    
    Если СтрокаТабличнойЧасти.Количество = 0 Тогда
        СтрокаТабличнойЧасти.Количество = 1;
    КонецЕсли;

    СтрокаТабличнойЧасти.Продавец = Продавец;

    ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
    ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);
    
    // Ввод состава набора
    УправлениеЗапасами.ДобавитьСоставНабора(СтрокаТабличнойЧасти, ЭтотОбъект);

КонецПроцедуры // ТоварыПриИзмененииХарактеристикиНоменклатуры()

// Процедура обрабатывает изменение количество в ТЧ товары. Для обращений извне.
//
Процедура ТоварыПриИзмененииКоличества(СтрокаТабличнойЧасти) Экспорт

    

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

    ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(СтрокаТабличнойЧасти, ЭтотОбъект);

    
КонецПроцедуры


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

// Процедура - обработчик события "ПриИзменении" поля ХарактеристикаНоменклатуры
// в строке табличной части "Товары".
//
Процедура ТоварыХарактеристикаНоменклатурыПриИзменении(Элемент)
    
    СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущиеДанные;
    
    ТоварыПриИзмененииХарактеристикиНоменклатуры(СтрокаТабличнойЧасти);
    
КонецПроцедуры

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

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

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

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

// Процедура - обработчик события "ПриИзменении" поля ввода количества
// в строке табличной части "Товары".
//
Процедура ТоварыКоличествоПриИзменении(Элемент)
    
    СтрокаТабличнойЧасти = ЭлементыФормы.Товары.ТекущиеДанные;
    
    ТоварыПриИзмененииКоличества(СтрокаТабличнойЧасти);
    
КонецПроцедуры // ТоварыКоличествоПриИзменении()

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

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

// Процедура - обработчик события "Очистка" поля ввода цены
// в строке табличной части "Товары".
Процедура ТоварыЦенаОчистка(Элемент, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
КонецПроцедуры // ТоварыЦенаПриИзменении()


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

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

// Процедура - обработчик события "ПриИзменении" поля Склад ТЧ товары.
//
Процедура ТоварыСкладПриИзменении(Элемент)
    
    ТекСтрока = ЭлементыФормы.Товары.ТекущаяСтрока;
    ТекСтрока.СтавкаНДС = Ценообразование.СформироватьСтавкуНДС(Дата, ТекСтрока.Склад, ТекСтрока.Номенклатура);
    ОбработкаТабличныхЧастей.РассчитатьСуммуТабЧасти(ТекСтрока, ЭтотОбъект);
    ОбработкаТабличныхЧастей.РассчитатьСуммуНДСТабЧасти(ТекСтрока, ЭтотОбъект, Истина, Истина);
    
КонецПроцедуры

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

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


////////////////////////////////////////////////////////////////////////////////
// ПОДБОР: ПРОЦЕДУРЫ И ФУНКЦИИ ОБЩЕГО НАЗНАЧЕНИЯ
//

// Процедура добавляет выбранную номенклатуру и характеристику в табличную часть документа
//
Процедура ВыбратьНоменклатуру(НоменклатураСсылка, ХарактеристикаНоменклатурыСсылка) Экспорт
    
    Если НоменклатураСсылка.ЭтоГруппа Тогда
        
        ВывестиИнформациюОбОшибке("В состав табличной части могут включаться только элементы номенклатуры!");
        
    Иначе
        
        СШКНоменклатура(НоменклатураСсылка, ХарактеристикаНоменклатурыСсылка, НоменклатураСсылка.ЕдиницаХраненияОстатков, 1);
        
    КонецЕсли;
    
КонецПроцедуры

// Процедура производит поиск номенклатуры
// по значению поиска
 Процедура НайтиНоменклатуру(ЗначениеПоиска) Экспорт
    Перем СписокХарактеристик;
    
    Если ЗначениеПоиска = "" Тогда
        Возврат;
    КонецЕсли;
    
    НоменклатураСписок.Отбор.Сбросить();
    НоменклатураСписок.Отбор.Ссылка.Использование = Ложь;
    
    ПоискВ = ЭлементыФормы.СписокВидовПоиска.Значение;
    
    Если ПоискВ = "Штрихкод" Тогда
        СписокОтбора = УправлениеНоменклатурой.НайтиПоШтрихкоду(ЗначениеПоиска,,СписокХарактеристик);
    ИначеЕсли ПоискВ = "Везде" Тогда
        СписокОтбора = УправлениеНоменклатурой.НайтиВезде(ЗначениеПоиска,,СписокХарактеристик);
    Иначе
        
        НоменклатураСписок.Отбор[ПоискВ].ВидСравнения  = ВидСравнения.Содержит;
        НоменклатураСписок.Отбор[ПоискВ].Значение      = ЗначениеПоиска;
        НоменклатураСписок.Отбор[ПоискВ].Использование = Истина;

    КонецЕсли;
    
    Если ПоискВ = "Штрихкод" ИЛИ ПоискВ = "Везде" Тогда
        
        НоменклатураСписок.Отбор.Ссылка.ВидСравнения  = ВидСравнения.ВСписке;
        НоменклатураСписок.Отбор.Ссылка.Значение      = СписокОтбора;
        НоменклатураСписок.Отбор.Ссылка.Использование = Истина;
        
        Если НЕ СписокОтбора.Количество()=0 Тогда
            
            ЭлементыФормы.НоменклатураСписок.ТекущаяСтрока = СписокОтбора.Получить(0).Значение;
            
        КонецЕсли;
        
        // Если найден один товар и несколько соответствующих ему характеристик, то переходим на закладку характеристик
        Если (НЕ СписокХарактеристик.Количество()=0) И СписокОтбора.Количество()=1 Тогда
            
            // Формируем таблицу характеристик
            мПодбор.АктивизироватьТаблицуСХарактеристиками(ЭтаФорма, ЭлементыФормы.Характеристики, СписокОтбора.Получить(0).Значение, СписокХарактеристик);
            
            // Устанавливаем текущую строку
            ЭлементыФормы.Характеристики.ТекущаяСтрока = Характеристики.Найти(СписокХарактеристик.Получить(0).Значение, "ХарактеристикаНоменклатуры");
            
        Иначе
            
            ТекущийЭлемент = ЭлементыФормы.НоменклатураСписок;
            
        
        КонецЕсли;
        
    КонецЕсли;
    
    
    Если ОтображатьИерархию Тогда
        ОтображатьИерархию = Не ОтображатьИерархию;
        УстановитьВидимостьИерархии();
    КонецЕсли;
    
    ПодключитьОбработчикОжидания("ОбработчикОжиданияОбновитьПараметрыНоменклатурыПоСписку", 0.1, Истина);

КонецПроцедуры

// Процедура обработчик ожидания формы для "ПараметрыНоменклатуры"
//
Процедура ОбработчикОжиданияОбновитьПараметрыНоменклатурыПоСписку()


    // Использует API подбора
    мПодбор.ОбновитьПараметрыНоменклатуры(ЭтаФорма, ЭлементыФормы.ПараметрыНоменклатуры, ЭлементыФормы.НоменклатураСписок, ЭлементыФормы.Характеристики, ЭлементыФормы.ПанельНоменклатурыХарактеристик);



КонецПроцедуры

// Функция вызывается при нажатии на кнопки управления видимостью панели "ПанельИнформация" формы.
//
Процедура ИзменитьВидимостьИнформации(Элемент)
    
    ОтображатьИнформацию = Не ОтображатьИнформацию;
    
    УстановитьВидимостьИнформации();
    
    ТекущийЭлемент = ЭлементыФормы.НоменклатураСписок;
    
КонецПроцедуры

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

    Иначе
        ЭлементыФормы.КартинкаИнформация.Картинка = БиблиотекаКартинок.ПанельВниз;
        ЭлементыФормы.НадписьУстановитьВидимостьИнформации.Заголовок = "Показать информацию";
    КонецЕсли;
    
    РаботаСДиалогами.ИзменитьВидимостьПанелиПоВертикалиНиз(ЭтаФорма, ОтображатьИнформацию, "ПанельПодборКлавиши", "ПанельНоменклатурыХарактеристик", "ПараметрыНоменклатуры");
    
КонецПроцедуры

// Функция вызывается при нажатии на кнопки управления видимостью панели формы.
//
Процедура ИзменитьВидимостьИерархииПросмотра(Элемент)
    
    ОтображатьИерархию = Не ОтображатьИерархию;
    
    УстановитьВидимостьИерархии();
    
    ТекущийЭлемент = ЭлементыФормы.НоменклатураСписок;
    
КонецПроцедуры

// Функция устанавливает видимость панели "ПанельИнформация".
//
Процедура УстановитьВидимостьИерархии()
    
    ЭлементыФормы.НоменклатураСписок.ИерархическийПросмотр = ОтображатьИерархию;
    
    Если ОтображатьИерархию Тогда
        ЭлементыФормы.НоменклатураСписок.ПросмотрГруппИЭлементов   = ИспользованиеГруппИЭлементов.ГруппыИЭлементы;
        ЭлементыФормы.КартинкаИерархическийПросмотр.Рамка = Новый Рамка(ТипРамкиЭлементаУправления.Одинарная);
    Иначе
        ЭлементыФормы.НоменклатураСписок.ПросмотрГруппИЭлементов   = ИспользованиеГруппИЭлементов.Элементы;
        ЭлементыФормы.КартинкаИерархическийПросмотр.Рамка = Новый Рамка(ТипРамкиЭлементаУправления.БезРамки);
    КонецЕсли;
    
    УстановитьНадписьПутьВИерархии();
    
КонецПроцедуры

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

////////////////////////////////////////////////////////////////////////////////
// ПОДБОР: ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ Панели "ПанельПодборКлавиши"
//

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

// Процедура - обработчик событий нажатия клавиш панели "ПанельПодборКлавиши" 
// на странице "Клавиши"
//
Процедура НажатиеКлавишиПанелиПодборКлавиши(Элемент)
    
    НажатиеКлавиши(ЭлементыФормы.КоманднаяПанельАкселераторы.Кнопки[Элемент.Имя]);
    
    УстановитьАктивныйЭлемент();
    
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ПОДБОР: ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ ШАПКИ

// Процедура обработчик события "ПриИзменении" поля "СписокВидовПоиска"
//
Процедура СписокВидовПоискаПриИзменении(Элемент)
    
    ПолеПоискаОткрытие(ЭлементыФормы.ПолеПоиска, Ложь);
    
КонецПроцедуры

// Процедура - обработчик события "Открытие" элемента формы "ПолеПоиска".
//
Процедура ПолеПоискаОткрытие(Элемент, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;
    НайтиНоменклатуру(Элемент.Значение);

КонецПроцедуры

// Процедура - обработчик события "Открытие" элемента формы "ПриИзменении".
//
Процедура ПолеПоискаПриИзменении(Элемент)
    
    НайтиНоменклатуру(Элемент.Значение);
    
КонецПроцедуры

// Процедура - обработчик события "Очистка" элемента формы "ПолеПоиска".
//
Процедура ПолеПоискаОчистка(Элемент, СтандартнаяОбработка)

    НоменклатураСписок.Отбор.Сбросить();
    НоменклатураСписок.Отбор.Ссылка.Использование = Ложь;
    ТекущийЭлемент = ЭлементыФормы.НоменклатураСписок;
    УстановитьВидимостьИерархии();
    
    мРежимПоискаВПодборе = Ложь;

КонецПроцедуры


// Процедура обработчик события "ПриИзменении" флажка "ОтображатьЦены"
//
Процедура ОтображатьЦеныПриИзменении(Элемент)

    УстановитьВидимостьПараметрыНоменклатуры();

    // Использует API подбора
    мПодбор.НоменклатураПриАктивизацииСтроки(ЭтаФорма, ЭлементыФормы.НоменклатураСписок);

КонецПроцедуры

// Процедура обработчик события "ПриИзменении" флажка "ОтображатьКоличество"
//
Процедура ОтображатьКоличествоПриИзменении(Элемент)
    
    УстановитьВидимостьПараметрыНоменклатуры();
    
КонецПроцедуры

// Процедура управляет видимостью колонок табличного поля "ПараметрыНоменклатуры"
//
Процедура УстановитьВидимостьПараметрыНоменклатуры()

    ЭлементыФормы.ПараметрыНоменклатуры.Колонки.Количество.Видимость = ОтображатьКоличество;
    
    ЭлементыФормы.ПараметрыНоменклатуры.Колонки.Цена.Видимость       = ОтображатьЦены;

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ПОДБОР: ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ ТЧ "НоменклатураСписок"
// /В подборе используются общие API функции обработки "ПодборНоменклатуры"/

// Процедура - обработчик события "Выбор" табличной части "НоменклатураСписок".
//
Процедура НоменклатураСписокВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)

    // Использует API подбора
    мПодбор.НоменклатураВыбор(ЭтаФорма, ЭлементыФормы.Характеристики, ЭтотОбъект, ВыбраннаяСтрока, СтандартнаяОбработка);

КонецПроцедуры

// Процедура - обработчик события "ПриАктивизацииСтроки" табличной части "НоменклатураСписок".
//
Процедура НоменклатураСписокПриАктивизацииСтроки(Элемент)
    
    УстановитьНадписьПутьВИерархии();
    
    // Использует API подбора
    мПодбор.НоменклатураПриАктивизацииСтроки(ЭтаФорма, ЭлементыФормы.НоменклатураСписок);
    
КонецПроцедуры

// Процедура - обработчик события "ПриПолученииДанных" табличной части "НоменклатураСписок".
//
Процедура НоменклатураСписокПриПолученииДанных(Элемент, ОформленияСтрок)

    // Использует API подбора
    мПодбор.НоменклатураПриПолученииДанных(ЭтаФорма, ОформленияСтрок, ЭлементыФормы.НоменклатураСписок.Колонки.Картинка);

КонецПроцедуры

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


////////////////////////////////////////////////////////////////////////////////
// ПОДБОР: ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ ТЧ "ХарактеристикиНоменклатуры"

// Процедура - обработчик события "Выбор" табличной части "Характеристики".
//
Процедура ХарактеристикиВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
    
    // Использует API подбора
    мПодбор.ХарактеристикиНоменклатурыВыбор(ЭтаФорма, ЭлементыФормы.НоменклатураСписок, ЭлементыФормы.Характеристики, ВыбраннаяСтрока, СтандартнаяОбработка);
    
КонецПроцедуры

// Процедура - обработчик события "ПриАктивизацииСтроки" табличной части "Характеристики".
//
Процедура ХарактеристикиПриАктивизацииСтроки(Элемент)

    мПодбор.ХарактеристикиНоменклатурыПриАктивизацииСтроки(ЭтаФорма);

КонецПроцедуры

// Процедура - обработчик события "ПриПолученииДанных" табличной части "Характеристики".
//
Процедура ХарактеристикиПриПолученииДанных(Элемент, ОформленияСтрок)

    мПодбор.ХарактеристикиНоменклатурыПриПолученииДанных(ОформленияСтрок, "ХарактеристикаНоменклатуры");

КонецПроцедуры

// Процедура - обработчик события "ПерейтиВКорень" табличной части "Характеристики".
//
Процедура КоманднаяПанельХарактеристикиПерейтиКНоменклатуре(Кнопка)
    
    ЭлементыФормы.Характеристики.ТекущаяСтрока = Характеристики[0];
    ЭлементыФормы.ПанельНоменклатурыХарактеристик.ТекущаяСтраница = ЭлементыФормы.ПанельНоменклатурыХарактеристик.Страницы.Номенклатура;
    
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ПОДБОР: ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ ПАНЕЛИ "ПанельНоменклатурыХарактеристик"

// Процедура - обработчик события "ПриСменеСтраницы" панели "ПанельНоменклатурыХарактеристик".
//
Процедура ПанельНоменклатурыПриСменеСтраницы(Элемент, ТекущаяСтраница)
    
    // Использует API подбора
    мПодбор.ПанельНоменклатурыПриСменеСтраницы(ЭтаФорма, ЭлементыФормы.ПанельНоменклатурыХарактеристик, ЭлементыФормы.НоменклатураСписок);
    
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ ТЧ "ПараметрыНоменклатуры"

// Процедура - обработчик события "ПриВыводеСтроки" 
// табличной части "ПараметрыНоменклатуры".
//
Процедура ПараметрыНоменклатурыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    
    мПодбор.ПараметрыПриВыводеСтроки(ОформлениеСтроки, ДанныеСтроки);
    
КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ панели "ПанельПодборБыстрыеТовары"
//

// Процедура открывает панель "ПанельПодборБыстрыеТовары"
//
Процедура ОткрытьПанельПодборБыстрыеТовары(ОтрыватьНаВесьЭкран, СтраницаОткрытия)
    
    Если ОтрыватьНаВесьЭкран Тогда
        
        ВерхПодбора   = ЭлементыФормы.Товары.Верх;
        ВысотаПодбора = ЭлементыФормы.Товары.Высота;
        
        ЭлементыФормы.ПанельПодборБыстрыеТовары.УстановитьПривязку(ГраницаЭлементаУправления.Верх, Панель, ГраницаЭлементаУправления.Верх);
        
        ЭлементыФормы.ПанельПодборБыстрыеТовары.Верх   = ВерхПодбора;
        ЭлементыФормы.ПанельПодборБыстрыеТовары.Высота = ВысотаПодбора;
        
        ЭлементыФормы.Товары.Видимость                          = Ложь;
        ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость       = Истина;
        
    Иначе
        
        ВысотаТовары  = Цел(ЭлементыФормы.Товары.Высота / 2);
        ВерхПодбора   = Цел(ЭлементыФормы.Товары.Верх + ВысотаТовары + 6);
        ВысотаПодбора = Цел(ЭлементыФормы.Товары.Высота - ВысотаТовары - 6);
        
        ЭлементыФормы.Товары.Высота = ВысотаТовары;
        
        Если ЭлементыФормы.ПанельПодборБыстрыеТовары.Верх = ЭлементыФормы.Товары.Верх Тогда
            ЭлементыФормы.ПанельПодборБыстрыеТовары.Высота = ВысотаПодбора;
            ЭлементыФормы.ПанельПодборБыстрыеТовары.Верх   = ВерхПодбора;
        Иначе
            ЭлементыФормы.ПанельПодборБыстрыеТовары.Верх   = ВерхПодбора;
            ЭлементыФормы.ПанельПодборБыстрыеТовары.Высота = ВысотаПодбора;
        КонецЕсли;
        
        ЭлементыФормы.Товары.Видимость                    = Истина;
        ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость = Истина;
        
        ЭлементыФормы.ПанельПодборБыстрыеТовары.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ЭлементыФормы.Товары, ГраницаЭлементаУправления.Низ);

        
    КонецЕсли;
    
    ЭлементыФормы.ПанельПодборБыстрыеТовары.ТекущаяСтраница = СтраницаОткрытия;

КонецПроцедуры

// Процедура закрывает панель "ПанельПодборБыстрыеТовары"
//
Процедура ЗакрытьПанельПодборБыстрыеТовары()
    
    Если Не ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость Тогда
        Возврат;
    КонецЕсли;
    
    ПанельОткрытаНаВесьЭкран = (Не ЭлементыФормы.Товары.Видимость);
    
    Если ПанельОткрытаНаВесьЭкран Тогда
        
        ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость = Ложь;
        ЭлементыФормы.Товары.Видимость                    = Истина;
        
        ВерхПодбора   = ЭлементыФормы.Товары.Верх;
        ВысотаПодбора = ЭлементыФормы.КнопкиФормыПоУмолчанию.Верх - ЭлементыФормы.Товары.Верх - 5;
        
        ЭлементыФормы.Товары.Верх   = ВерхПодбора;
        ЭлементыФормы.Товары.Высота = ВысотаПодбора;
        
    Иначе
        
        ВерхТовары    = ЭлементыФормы.ПанельИнформации.Верх + ЭлементыФормы.ПанельИнформации.Высота + 6;
        ВысотаТовары  = ЭлементыФормы.КнопкиФормыПоУмолчанию.Верх - ЭлементыФормы.Товары.Верх - 5;
        
        ЭлементыФормы.Товары.Верх      = ВерхТовары;
        ЭлементыФормы.Товары.Высота    = ВысотаТовары;
        
        ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость = Ложь;
        ЭлементыФормы.Товары.Видимость               = Истина;
        
        ЭлементыФормы.ПанельПодборБыстрыеТовары.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ЭлементыФормы.КнопкиФормыПоУмолчанию, ГраницаЭлементаУправления.Верх);
        
    КонецЕсли;

    ЭлементыФормы.КлавишаПодбор.ЦветФонаКнопки       = Цветастиля.ЦветФонаКнопки;
    Если ПроверитьНаличиеЭлементаФормы("КнопкаБыстрыеТовары") Тогда
        ЭлементыФормы.КнопкаБыстрыеТовары.ЦветФонаКнопки = Цветастиля.ЦветФонаКнопки;
    КонецЕсли;

    УстановитьАктивныйЭлемент();

КонецПроцедуры

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

    Если ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость
     И ЭлементыФормы.ПанельПодборБыстрыеТовары.ТекущаяСтраница = ЭлементыФормы.ПанельПодборБыстрыеТовары.Страницы.БыстрыеТовары Тогда
        
        Если ПроверитьНаличиеЭлементаФормы("КнопкаБыстрыеТовары") Тогда
            ЭлементыФормы.КнопкаБыстрыеТовары.ЦветФонаКнопки  = мЦветАктивнойКнопки;
        КонецЕсли;
        
        УстановитьВидКнопокБыстрыеТовары();
        
        ТекущийЭлемент = ЭлементыФормы.Товары;
        
    КонецЕсли;
    
    Если ЭлементыФормы.ПанельПодборБыстрыеТовары.Видимость
     И ЭлементыФормы.ПанельПодборБыстрыеТовары.ТекущаяСтраница = ЭлементыФормы.ПанельПодборБыстрыеТовары.Страницы.Подбор Тогда
    
        ЭлементыФормы.КлавишаПодбор.ЦветФонаКнопки  = мЦветАктивнойКнопки;
        
        УстановитьОтборТаблицыПодборКлавиши();
        
        ТекущийЭлемент = ЭлементыФормы.ТаблицаПодборКлавиши;
        
    КонецЕсли;

КонецПроцедуры

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

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

////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ СОБЫТИЙ РЕКВИЗИТОВ таблицы "ТаблицаПодборКлавиши"
//

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

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

// Процедура - обработчик событий ПередУстановкойПометкиУдаления
// таблицы "ТаблицаПодборКлавиши" 
//
Процедура ТаблицаПодборКлавишиПередУстановкойПометкиУдаления(Элемент, Отказ)
    Отказ = Истина;
КонецПроцедуры

// Процедура - обработчик событий ПередУдалением
// таблицы "ТаблицаПодборКлавиши" 
//
Процедура ТаблицаПодборКлавишиПередУдалением(Элемент, Отказ)
    Отказ = Истина;
КонецПроцедуры


////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ - ОБРАБОТЧИКИ НАЖАТИЯ КНОПОК ПЕРЕМЕЩЕНИЯ ПО СПИСКУ ПОДБОРА

// Процедура - обработчик события "Нажатие" кнопки " КнопкаВверх".
//
Процедура КнопкаВверхНажатие(Элемент)
    
    мНажатаяКнопка = "Вверх";
    ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ТаблицаПодборКлавиши;
    
КонецПроцедуры

// Процедура - обработчик события "Нажатие" кнопки "КнопкаВниз".
//
Процедура КнопкаВнизНажатие(Элемент)
    
    мНажатаяКнопка = "Вниз";
    ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ТаблицаПодборКлавиши;
    
КонецПроцедуры

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

КонецПроцедуры


///////////////////////////////////////////////////////////////////////////////
//// ФУНКЦИИ ВЗАИМОДЕЙСТВИЯ С ТОРГОВЫМ ОБОРУДОВАНИЕМ (ОБЩИЕ ФУНКЦИИ API)

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

///////////////////////////////////////////////////////////////////////////////
//// ФУНКЦИИ ВЗАИМОДЕЙСТВИЯ С ТОРГОВЫМ ОБОРУДОВАНИЕМ (ОБРАБОТЧИКИ СОБЫТЙ)

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

// Процедура осуществляет обработку полученного кода 
// информационной карты от считывателя магнитных карт
//
// Параметры:
//  КодКарты - <Строка>
//           - Код, считанной магнитной карты
//
Процедура СМКОбработатьДанныеКарты(КодКарты) Экспорт
    
    УправлениеИнформационнымиКартами.ОбработатьВведенныеДанныеКарты(КодКарты, ЭтаФорма,,Истина);
    
КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////
//// ФУНКЦИИ ВЗАИМОДЕЙСТВИЯ С ТОРГОВЫМ ОБОРУДОВАНИЕМ (СКАНЕР ШТРИХКОДА)

// Функция осуществляет обработку считывания штрих-кода номенклатуры
//
// Параметры:
//  Номенклатура                - <СправочникСсылка.Номенклатура>
//                              - Номенклатура, штрих-код которой был отсканирован.
//
//  ХарактеристикаНоменклатуры  - <СправочникСсылка.ХарактеристикаНоменклатуры>
//                              - Характеристика номенклатуры отсканированной номенклатуры.
//
//  Единица                     - <СправочникСсылка.ЕдиницыИзмерения>
//                              - Единица измерения отсканированной номенклатуры.
//
//  Количество                  - <Число>
//                              - Количество отсканированной номенклатуры.
//
// Возвращаемое значение:
//  <Булево>                    - Данная ситуация обработана.
//
Функция СШКНоменклатура(Номенклатура, ХарактеристикаНоменклатуры, Единица, Количество) Экспорт
    
    Если Не ЗначениеЗаполнено(Единица) Тогда
        пЕдиницаИзмерения = Номенклатура.ЕдиницаХраненияОстатков;
    Иначе
        пЕдиницаИзмерения = Единица;
    КонецЕсли;
    
    // Вызываем форму визуального выбора характеристики, в случае если характеристики для номенклатуры назначены
    Если (НЕ ЗначениеЗаполнено(ХарактеристикаНоменклатуры)) И ОбщегоНазначения.ПолучитьФлагУчетаХарактеристик(Номенклатура.ВидНоменклатуры) Тогда
        
        ФормаВыбораХарактеристики = ПолучитьФорму("ФормаВыбораХарактеристикНоменклатуры", Этаформа, ЭтаФорма);
        ФормаВыбораХарактеристики.Отбор.Владелец.Установить(ОбщегоНазначения.ПолучитьВладельцаХарактеристики(Номенклатура));
        
        ФормаВыбораХарактеристики.Номенклатура = Номенклатура;
        ФормаВыбораХарактеристики.Магазин      = КассаККМ.Магазин;
        
        ФормаВыбораХарактеристики.ОткрытьМодально();
        
        // Обработаем результат выбора характеристики
        Если ЗначениеЗаполнено(ФормаВыбораХарактеристики.ВыбранноеЗначение) Тогда
            ХарактеристикаНоменклатуры = ФормаВыбораХарактеристики.ВыбранноеЗначение;
        Иначе
            Возврат ИСТИНА;
        КонецЕсли;
        
    КонецЕсли;
    
    ДобавитьНоменклатуруВТабЧасть(Номенклатура, ХарактеристикаНоменклатуры, пЕдиницаИзмерения, Количество, Истина);
    
    Возврат Истина;
    
КонецФункции // СШКНоменклатура()

// Функция осуществляет обработку считывания штрих-кода серийного номера
//
// Параметры:
//  Карта    - <СправочникСсылка.ИнформационныеКарты>
//           - Отсканированная информационная карта.
//
//  СШК      - <Строка>
//           - Идентификатор сканера штрих-кода, с которым связано данное
//             событие.
//
// Возвращаемое значение:
//  <Булево> - Данная ситуация обработана.
//
Функция СШКСерийныйНомер(СерийныйНомерСчитанный) Экспорт

    Номенклатура = СерийныйНомерСчитанный.Владелец;
    ХарактеристикаНоменклатуры = Справочники.ХарактеристикиНоменклатуры.ПустаяСсылка();
    Единица = Номенклатура.ЕдиницаХраненияОстатков;
    Количество = 1;
    
    
    ДобавитьНоменклатуруВТабЧасть(Номенклатура, ХарактеристикаНоменклатуры, Единица, Количество, Истина, СерийныйНомерСчитанный);
    
    Возврат Истина;
КонецФункции // СШКСерийныйНомер()

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

// Функция осуществляет обработку считывания штрихового кода, который не был
// зарегистрирован.
//
// Параметры:
//  Штрихкод - <Строка>
//           - Считанный код.
//
//  ТипКода  - <ПланыВидовХарактеристикСсылка.ТипыШтрихкодов>
//           - Тип штрихкода. Пустая ссылка в случае, если тип определить не
//             представляется возможным.
//
//  СШК      - <Строка>
//           - Идентификатор сканера штрих-кода, с которым связано данное
//             событие.
//
// Возвращаемое значение:
//  <Булево> - Данная ситуация обработана.
//
Функция СШКНеизвестныйКод(Штрихкод, ТипКода) Экспорт
    
    Возврат Ложь;
    
КонецФункции // СШКНеизвестныйКод()

// Процедура осуществляет обработку ошибки, произошедшей при работе со сканером
// штрих-кода.
//
// Параметры:
//  Ошибка    - <ПеречислениеСсылка.ТООшибки*>
//            - Возникшая ошибка.
//
//  Штрихкод  - <Строка>
//            - Считанный штрихкод или пустая строка, если штрихкод не был
//              считан.
//
//  ТипШК     - <ПланыВидовХарактеристикСсылка.ТипыШтрихкодов>
//            - Тип штрихкода или пустая ссылка в случае, если тип не определён.
//
//  СШК       - <Строка>
//            - Идентификатор сканера штрих-кода, с которым связано данное
//              событие.
//
Процедура СШКОшибка(Ошибка, Штрихкод, ТипШК) Экспорт
    
    Текст = ПолучитьСерверТО().ПолучитьТекстОшибкиСШКТО(Ошибка, Штрихкод, ТипШК);
    
    ТекстОшибки = Штрихкод + Символы.ПС + Текст;
    
    ВывестиИнформациюОбОшибке(ТекстОшибки);
    
КонецПроцедуры // СШКОшибка()

///////////////////////////////////////////////////////////////////////////////
//// ФУНКЦИИ ВЗАИМОДЕЙСТВИЯ С ТОРГОВЫМ ОБОРУДОВАНИЕМ (СЧИТЫВАТЕЛЬ МАГНИТНЫХ КАРТ)

// Функция осуществляет обработку считывания серийного номера.
//
// Параметры:
//  СерийныйНомерСчитанный    - <СправочникСсылка.СерийныеНомера>
//                            - Считанная ридером серийный номер.
//
// Возвращаемое значение:
//  <Булево> - Данная ситуация обработана.
//
Функция СМКСерийныйНомер(СерийныйНомерСчитанный) Экспорт

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

КонецФункции // СМКСерийныйНомер()

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

    Результат = Истина;

    Если ТолькоПросмотр Тогда
        Возврат Результат;
    КонецЕсли;
    
    ОбработатьСчитываниеИнформационнойКарты(Карта);

    Возврат Результат;

КонецФункции // СМКИнформационнаяКарта()

// Функция осуществляет обработку считывания незарегистрированной магнитной карты.
//
// Параметры:
//  Код      - <Строка>
//           - Считанный код.
//
//  СМК      - <Строка>
//           - Идентификатор считывателя, с которым связано данное событие.
//
// Возвращаемое значение:
//  <Булево> - Данная ситуация обработана.
//
//
Функция СМКНеизвестныйКод(Код) Экспорт

    Результат = Истина;

    ВывестиИнформациюОбОшибке("Карта с кодом: """ + Код + """ не зарегистрирована в системе!");

    Возврат Результат;

КонецФункции // СМКНеизвестныйКод()

// Процедура осуществляет обработку ошибки, произошедшей при работе с устройством
// для считывания магнитных карт.
//
// Параметры:
//  Ошибка    - <ПеречислениеСсылка.ТООшибки*>
//            - Возникшая ошибка.
//
//  КодКарты - <Строка>
//           - Считанный код карты.
//
//  СМК      - <Строка>
//           - Идентификатор считывателя, с которым связано данное событие.
//
Процедура СМКОшибка(Ошибка, КодКарты) Экспорт

    Текст = ПолучитьСерверТО().ПолучитьТекстОшибкиСМКТО(Ошибка, КодКарты);

    ТекстОшибки = КодКарты + Символы.ПС + Текст;
    
    ВывестиИнформациюОбОшибке(ТекстОшибки);

КонецПроцедуры // СМКОшибка()

///////////////////////////////////////////////////////////////////////////////
//// ФУНКЦИИ ВЗАИМОДЕЙСТВИЯ С ТОРГОВЫМ ОБОРУДОВАНИЕМ (ДИСПЛЕЙ ПОКУПАТЕЛЯ)

// Процедура осуществляет вывод информации на дисплей покупателя.
//
// Параметры:
//  Нет.
//
Процедура ВывестиИнформациюНаДисплейПокупателя(Данные) Экспорт

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

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

// Функция формирует и возвращает строку для вывода на дисплей покупателя.
//
// Возвращаемое значение:
//  Строка - строка для вывода на дисплей покупателя.
//
Функция ПолучитьТаблицуДляВыводаНаДисплейПокупателя()
    
    Перем Строка1;
    Перем Строка2;
    
    Если Товары.Количество() = 0 Тогда
        Строка1 = "Здравствуйте!";
        Строка2 = Магазин.Наименование;
    Иначе
        ПоследняяСтрокаТовары = Товары[Товары.Количество()-1];
    КонецЕсли;
    
    Если ЭлементыФормы.ПанельИтог.ТекущаяСтраница = ЭлементыФормы.ПанельИтог.Страницы.Сдача Тогда
        Строка1 = "Спасибо за покупку!";
        Строка2 = "Сдача: " + ЭлементыФормы.НадписьСдача.Заголовок + " руб.";
    Иначе
        Если ПоследняяСтрокаТовары <> Неопределено Тогда
            
            ПредставлениеЦены = Формат(ПоследняяСтрокаТовары.Цена, "ЧДЦ=2; ЧРГ=' '; ЧН=0");
            ДлинаЦены         = СтрДлина(ПредставлениеЦены);
            
            Строка1 = Лев(СокрЛП(ПоследняяСтрокаТовары.Номенклатура), 18 - ДлинаЦены) + ": " + ПредставлениеЦены;
            Строка2 = "Итого: " + Формат(Товары.Итог("Сумма"), "ЧЦ=15; ЧДЦ=2; ЧРГ=' '; ЧГ=3,0") + " руб"
            
        КонецЕсли;
    КонецЕсли;
    
    ТаблицаРезультат = СоздатьТаблицуДляВыводаНаДисплейПокупателя(Строка1, Строка2);
    
    Возврат ТаблицаРезультат;
    
КонецФункции // ПолучитьСтрокиДляВыводаНаДисплейПокупателя()

// Функция формирует таблицу для вывода на дисплей покупателя
//
// ПАРАМЕТРЫ
//  Строка1            - <Строка>
//                       Строка 1-ой строчки дисплея
//  Строка2            - <Строка>
//                       Строка 2-ой строчки дисплея
// 
Функция СоздатьТаблицуДляВыводаНаДисплейПокупателя(Строка1, Строка2)

    ТаблицаРезультат = Новый ТаблицаЗначений();
    ТаблицаРезультат.Колонки.Добавить("Текст");
    ТаблицаРезультат.Колонки.Добавить("БегущаяСтрока");
    
    НовСтрокаТаблицаРезультат = ТаблицаРезультат.Добавить();
    НовСтрокаТаблицаРезультат.Текст = Строка1;
    НовСтрокаТаблицаРезультат.БегущаяСтрока  = Ложь;
    
    НовСтрокаТаблицаРезультат = ТаблицаРезультат.Добавить();
    НовСтрокаТаблицаРезультат.Текст = Строка2;
    НовСтрокаТаблицаРезультат.БегущаяСтрока  = Ложь;

    Возврат ТаблицаРезультат;

КонецФункции

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


// Проверка и установки кассы ККМ для РМК при отсутствии ФР
// Работа без фискального регистратора доступна при включенном режиме 
// "Розничная торговля облагается ЕНВД" и "Формировать нефискальные чеки"
//
Функция ПроверитьИУстановитьКассуККМ()

    СписокКассККМ        = Новый СписокЗначений();
    Результат            = Ложь;
    РабочееМестоКассыККМ = ВРег(ИмяКомпьютера());

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

    Выборка =Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
    Если Выборка.Следующий() Тогда
        ВыборкаКасс = Выборка.Выбрать();
        Пока ВыборкаКасс.Следующий() Цикл
            СписокКассККМ.Добавить(ВыборкаКасс.Ссылка);
        КонецЦикла;

        Пока Истина Цикл
            Если СписокКассККМ.Количество() = 0 Тогда
                Прервать;
            ИначеЕсли СписокКассККМ.Количество() = 1 Тогда
                мКассаККМ = СписокКассККМ[0].Значение;
                Результат = Истина;
            Иначе
                // Необходимо выбрать одну из касс ККМ.
                ЭлементСписка = СписокКассККМ.ВыбратьЭлемент("Выберите кассу ККМ");

                Если ЭлементСписка <> Неопределено Тогда
                    мКассаККМ = ЭлементСписка.Значение;
                    Результат = Истина;
                Иначе
                    Прервать;
                КонецЕсли;
            КонецЕсли;

            Если мКассаККМ.РабочееМестоККМ = "" Тогда
                Ответ = Вопрос("Касса """ + мКассаККМ + """ не привязана ни к одному рабочему месту.
                |Установить для данной кассы ККМ рабочее место """ + РабочееМестоКассыККМ +"""?", РежимДиалогаВопрос.ДаНетОтмена);

                Если Ответ = КодВозвратаДиалога.Да Тогда
                    Попытка
                        ОбъектСправочника = мКассаККМ.ПолучитьОбъект();
                        ОбъектСправочника.РабочееМестоККМ = РабочееМестоКассыККМ;
                        ОбъектСправочника.Записать();
                    Исключение
                        ВывестиИнформациюОбОшибке(ОписаниеОшибки());
                        Результат = Ложь;
                    КонецПопытки;

                    Прервать;
                ИначеЕсли Ответ = КодВозвратаДиалога.Нет Тогда
                    Результат = Ложь;
                    Если СписокКассККМ.Количество() = 1 Тогда
                        Прервать;
                    КонецЕсли;
                Иначе
                    Результат = Ложь;
                    Прервать;
                КонецЕсли;
            Иначе
                Прервать;
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;

    Возврат Результат;

КонецФункции



////////////////////////////////////////////////////////////////////////////////
// ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ

мКолонкиТовары = ЭлементыФормы.Товары.Колонки;

мНастройкаРМК             = РМК.ПолучитьНастройкуРМККомпьютера();
мИспользоватьНастройкуРМК = ЗначениеЗаполнено(мНастройкаРМК);

мЦветАктивнойКнопки = Новый Цвет(235,214,138);

мМенеджерВременныхТаблиц = Неопределено;


мОбновитьВысотуПодбора = Истина;

мДата = ТекущаяДата();

мНажатаяКнопка = "";

мИмяКомпьютера = ИмяКомпьютера();

мПодбор = Обработки.ПодборНоменклатуры.Создать();
мПодбор.мДата = мДата;

мИмяФайлаБэкапа = РаботаСФайлами.ПолучитьИмяКаталога() + "\OrdrBack.xml";

мНомерЧекаККМ = 1;

МаксимальноеКоличествоКнопокВКонфигураторе = 11;

ВысотаКпонкиВыход = 0;

ТекущаяОперацияВыборНоменклатурыСХарактеристикой = Ложь;