Base file: Документ_ЧекККМ_МодульОбъекта.onec
Compared file: Документ_ЧекККМ_МодульОбъекта.m000.onec
////////////////////////////////////////////////////////////////////////////////
// ПЕРЕМЕННЫЕ МОДУЛЯ
// Переменная, указывающая что проведение чека производится из
// режима регистрации продаж
Перем РежимРМК Экспорт;
// Переменная определяет режим в котором происходит запись документа
Перем мЗакрытиеСмены;
Перем КонтролироватьОстаткиТоваровПриЗакрытииЧека Экспорт;
Перем мСоответствиеТиповСкладов;
//m000 Запись документ для возврата
&НаСервере
Процедура ЗаписатьДанныеПоДокументуВозврат(АМассивТоваров, АСсылкаНаОснование, АСсылкаНаДвижение)
//АМассивТоваров список товаров к возврату (Код транзакции отсутствует)
//АСсылкаНаОснование документ - основание, т.е. ЧекККМ продажи
ВыборкаДокументовДвиженияПокупка = Документы.m000Скидка.НайтиПоРеквизиту("Документ", АСсылкаНаОснование);
Если ВыборкаДокументовДвиженияПокупка.Ссылка <> Документы.m000Скидка.ПустаяСсылка() Тогда
ДокументДвиженияПокупка = ВыборкаДокументовДвиженияПокупка.ПолучитьОбъект();
КонецЕсли;
ВыборкаДокументовДвиженияВозврат = Документы.m000Скидка.НайтиПоРеквизиту("Документ", ЭтотОбъект.Ссылка);
Если ВыборкаДокументовДвиженияВозврат.Ссылка <> Документы.m000Скидка.ПустаяСсылка() Тогда
ДокументДвиженияВозврат = ВыборкаДокументовДвиженияВозврат.ПолучитьОбъект();
Иначе
ДокументДвиженияВозврат = Документы.m000Скидка.СоздатьДокумент();
КонецЕсли;
ДокументДвиженияВозврат = Документы.m000Скидка.СоздатьДокумент();
ДокументДвиженияВозврат.Документ = ЭтотОбъект.Ссылка;
ДокументДвиженияВозврат.Дата = ЭтотОбъект.Дата;
ДокументДвиженияВозврат.Акция = ДокументДвиженияПокупка.Акция;
ДокументДвиженияВозврат.Пользователь = ДокументДвиженияПокупка.Пользователь;
ДокументДвиженияВозврат.ДисконтнаяКарта = ДокументДвиженияПокупка.ДисконтнаяКарта;
ДокументДвиженияВозврат.Сумма = ДокументДвиженияПокупка.Сумма;
ДокументДвиженияВозврат.СуммаСкидки = ДокументДвиженияПокупка.СуммаСкидки;
ДокументДвиженияВозврат.Начислено = Ложь;
ДокументДвиженияВозврат.ТаблицаДвижений.Очистить();
Для Каждого СтрокаТоваров Из АМассивТоваров Цикл
Для Каждого СтрокаТоваровПокупка Из ДокументДвиженияПокупка.ТаблицаДвижений Цикл
Если СтрокаТоваров.Номенклатура.Ссылка = СтрокаТоваровПокупка.Номенклатура.Ссылка Тогда
НоваяСтрока = ДокументДвиженияВозврат.ТаблицаДвижений.Добавить();
НоваяСтрока.Акция = СтрокаТоваровПокупка.Акция;
НоваяСтрока.Номенклатура = СтрокаТоваровПокупка.Номенклатура;
НоваяСтрока.Сумма = СтрокаТоваров.Сумма;
НоваяСтрока.СуммаСкидки = 0; //Скидка уже в сумме
НоваяСтрока.КодТранзакции= СтрокаТоваровПокупка.КодТранзакции;
КонецЕсли;
КонецЦикла;
КонецЦикла;
ДокументДвиженияВозврат.Записать(РежимЗаписиДокумента.Запись);
АСсылкаНаДвижение = ДокументДвиженияВозврат.Ссылка;
КонецПроцедуры
//m000/
////////////////////////////////////////////////////////////////////////////////
// ЭКСПОРТНЫЕ ПРОЦЕДУРЫ И ФУНКЦИИ ДОКУМЕНТА
#Если Клиент Тогда
// Процедура осуществляет печать документа. Можно направить печать на
// экран или принтер, а также распечатать необходмое количество копий.
//
// Название макета печати передается в качестве параметра,
// по переданному названию находим имя макета в соответствии.
//
// Параметры:
// НазваниеМакета - строка, название макета.
//
Процедура Печать(ИмяМакета, КоличествоЭкземпляров = 1, НаПринтер = Ложь) Экспорт
ПечататьВозвратныеЗаявления = Ложь;
Если ЭтоНовый() Тогда
Предупреждение("Документ можно распечатать только после его записи");
Возврат;
ИначеЕсли Не УправлениеПользователями.РазрешитьПечатьНепроведенныхДокументов(Проведен) Тогда
Предупреждение("Недостаточно полномочий для печати непроведенного документа!");
Возврат;
КонецЕсли;
Если Не РаботаСДиалогами.ПроверитьМодифицированность(ЭтотОбъект) Тогда
Возврат;
КонецЕсли;
Если ИмяМакета = "Чек" Тогда
Если Не ЗначениеЗаполнено(КассаККМ.Магазин) тогда
Если Не ЗначениеЗаполнено(КассаККМ) Тогда
НачалоСообщенияОбОшибке = "Не выбрана касса ККМ."
Иначе
НачалоСообщенияОбОшибке = "Выбранной кассе ККМ не назначен Магазин.";
КонецЕсли;
Предупреждение(НачалоСообщенияОбОшибке + Символы.ПС + "Печать чека невозможна.");
Возврат;
КонецЕсли;
// Получить экземпляр документа на печать.
ТабДокумент = ПечатьЧека();
ИначеЕсли ИмяМакета = "ТоварныйЧекДляПД" Тогда
Если Не ЗначениеЗаполнено(КассаККМ.Магазин) тогда
Если Не ЗначениеЗаполнено(КассаККМ) Тогда
НачалоСообщенияОбОшибке = "Не выбрана касса ККМ."
Иначе
НачалоСообщенияОбОшибке = "Выбранной кассе ККМ не назначен Магазин.";
КонецЕсли;
Предупреждение(НачалоСообщенияОбОшибке + Символы.ПС + "Печать чека невозможна.");
Возврат;
КонецЕсли;
// Получить экземпляр документа на печать.
ТабДокумент = ПечатьТоварногоЧекаДляПД();
ИначеЕсли ИмяМакета = "КМ3" Тогда
Если ЭтотОбъект.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
ТабДокумент = ПечатьКМ3();
ПечататьВозвратныеЗаявления = Истина;
Иначе
Предупреждение("Данная печатная форма предназначена только для чеков возврата");
Возврат;
КонецЕсли;
ИначеЕсли ТипЗнч(ИмяМакета) = Тип("ДвоичныеДанные") Тогда
ТабДокумент = УниверсальныеМеханизмы.НапечататьВнешнююФорму(Ссылка, ИмяМакета);
Если ТабДокумент = Неопределено Тогда
Возврат;
КонецЕсли;
КонецЕсли;
УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент, КоличествоЭкземпляров, НаПринтер, ОбщегоНазначения.СформироватьЗаголовокДокумента(ЭтотОбъект, ЭтотОбъект.Метаданные().Представление()), Ссылка,,,РежимРМК);
Если ПечататьВозвратныеЗаявления Тогда
ПечатьВозвратныеЗаявления();
КонецЕсли;
КонецПроцедуры // Печать()
// Функция формирует табличный документ с печатной формой.
//
// Возвращаемое значение:
// ТабличныйДокумент - печатная форма.
//
Функция ПечатьЧека()
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТекущийДокумент", ЭтотОбъект.Ссылка);
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.Текст = "
|ВЫБРАТЬ
| ДокЧек.Номер,
| ДокЧек.Дата,
| ДокЧек.Дата КАК ДатаДокумента,
| ДокЧек.КассаККМ.Магазин КАК Магазин,
| ДокЧек.КассаККМ,
| ДокЧек.КассаККМ.Организация КАК Организация,
| ДокЧек.КассаККМ.Организация.ЮрФизЛицо КАК ЮрФизЛицо,
| ДокЧек.КассаККМ.Организация.ИндивидуальныйПредприниматель,
| ВЫБОР КОГДА ДокЧек.КассаККМ.Организация.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ЮрЛицо)
| ТОГДА ПРЕДСТАВЛЕНИЕ(ДокЧек.КассаККМ.Организация)
| ИНАЧЕ ""ИП "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Фамилия, """") = """"
| ТОГДА """"
| ИНАЧЕ
| ФИОФизЛицСрезПоследнихИП.Фамилия + "" "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Имя, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследнихИП.Имя КАК СТРОКА(1)) + "". ""
| КОНЕЦ
| +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Отчество, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследнихИП.Отчество КАК СТРОКА(1)) + "".""
| КОНЕЦ
| КОНЕЦ
| + """"
| КОНЕЦ КАК НаименованиеОрганизации,
| ДокЧек.СуммаДокумента,
| ДокЧек.ВидОперации,
| ДокЧек.Товары.(
| НомерСтроки,
| Номенклатура,
| Номенклатура.Представление КАК Товар,
| Номенклатура.НаименованиеПолное КАК ТоварПолноеНаименование,
| Номенклатура.Код КАК Код,
| Номенклатура.Артикул КАК Артикул,
| Количество,
| ЕдиницаИзмерения.Представление КАК ЕдиницаИзмерения,
| Цена,
| Сумма,
| ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
| ),
| ДокЧек.Оплата.(
| НомерСтроки,
| ВидОплаты,
| Сумма
| ),
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Фамилия, """") = """"
| ТОГДА """"
| ИНАЧЕ
| ФИОФизЛицСрезПоследних.Фамилия + "" "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Имя, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследних.Имя КАК СТРОКА(1)) + "". ""
| КОНЕЦ
| +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Отчество, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследних.Отчество КАК СТРОКА(1)) + "".""
| КОНЕЦ
| КОНЕЦ КАК ФИО
|ИЗ
| Документ.ЧекККМ КАК ДокЧек
|ЛЕВОЕ СОЕДИНЕНИЕ
| Справочник.Пользователи КАК Пользователи
|ПО
| Пользователи.Ссылка = ДокЧек.Ответственный
|ЛЕВОЕ СОЕДИНЕНИЕ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ПО
| Пользователи.ФизЛицо = ФизическиеЛица.Ссылка
|ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрСведений.ФИОФизЛиц.СрезПоследних(&Дата) КАК ФИОФизЛицСрезПоследних
|ПО
| ФизическиеЛица.Ссылка = ФИОФизЛицСрезПоследних.ФизЛицо
|ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрСведений.ФИОФизЛиц.СрезПоследних(&Дата) КАК ФИОФизЛицСрезПоследнихИП
|ПО
| ДокЧек.КассаККМ.Организация = ФИОФизЛицСрезПоследнихИП.ФизЛицо
|ГДЕ
| ДокЧек.Ссылка = &ТекущийДокумент
|УПОРЯДОЧИТЬ ПО
| ДокЧек.Товары.НомерСтроки,
| ДокЧек.Оплата.НомерСтроки
|";
Шапка = Запрос.Выполнить().Выбрать();
Шапка.Следующий();
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_Чек_Накладная";
Макет = ПолучитьМакет("Накладная");
// Выводим шапку накладной.
ОбластьМакета = Макет.ПолучитьОбласть("Заголовок");
Если Шапка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
ОбластьМакета.Параметры.ТекстЗаголовка = ОбщегоНазначения.СформироватьЗаголовокДокумента(Шапка, "Товарный чек (возврат)");
Иначе
ОбластьМакета.Параметры.ТекстЗаголовка = ОбщегоНазначения.СформироватьЗаголовокДокумента(Шапка, "Товарный чек");
КонецЕсли;
ТабДокумент.Вывести(ОбластьМакета);
СведенияОПоставщике = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(Шапка.Организация, Шапка.ДатаДокумента);
ОбластьМакета = Макет.ПолучитьОбласть("Поставщик");
Если Шапка.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо Тогда
ОбластьМакета.Параметры.ПредставлениеПоставщика = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОПоставщике,"ПолноеНаименование,");
Иначе
ОбластьМакета.Параметры.ПредставлениеПоставщика = Шапка.НаименованиеОрганизации;
КонецЕсли;
ОбластьМакета.Параметры.Поставщик = Шапка.Организация;
ТабДокумент.Вывести(ОбластьМакета);
ОбластьМакета = Макет.ПолучитьОбласть("ИНН");
ОбластьМакета.Параметры.ИНН = СведенияОПоставщике.ИНН;
ТабДокумент.Вывести(ОбластьМакета);
ОбластьМакета = Макет.ПолучитьОбласть("Магазин");
ОбластьМакета.Параметры.ПредставлениеМагазина = Шапка.Магазин;
ОбластьМакета.Параметры.Магазин = Шапка.Магазин;
ТабДокумент.Вывести(ОбластьМакета);
ЕстьСкидки = Ложь;
ВыборкаСтрокТовары = Шапка.Товары.Выбрать();
Пока ВыборкаСтрокТовары.Следующий() Цикл
Если ВыборкаСтрокТовары.Цена * ВыборкаСтрокТовары.Количество - ВыборкаСтрокТовары.Сумма <> 0 Тогда
ЕстьСкидки = Истина;
КонецЕсли;
КонецЦикла;
ДопКолонка = Константы.ДополнительнаяКолонкаПечатныхФормДокументов.Получить();
Если ДопКолонка = Перечисления.ДополнительнаяКолонкаПечатныхФормДокументов.Артикул Тогда
ВыводитьКоды = Истина;
Колонка = "Артикул";
ИначеЕсли ДопКолонка = Перечисления.ДополнительнаяКолонкаПечатныхФормДокументов.Код Тогда
ВыводитьКоды = Истина;
Колонка = "Код";
Иначе
ВыводитьКоды = Ложь;
КонецЕсли;
ОбластьНомера = Макет.ПолучитьОбласть("ШапкаТаблицы|НомерСтроки");
ОбластьКодов = Макет.ПолучитьОбласть("ШапкаТаблицы|КолонкаКодов");
ОбластьДанных = Макет.ПолучитьОбласть("ШапкаТаблицы|Данные");
ОбластьСкидок = Макет.ПолучитьОбласть("ШапкаТаблицы|Скидка");
ОбластьСуммы = Макет.ПолучитьОбласть("ШапкаТаблицы|Сумма");
ТабДокумент.Вывести(ОбластьНомера);
Если ВыводитьКоды Тогда
ОбластьКодов.Параметры.ИмяКолонкиКодов = Колонка;
ТабДокумент.Присоединить(ОбластьКодов);
КонецЕсли;
ТабДокумент.Присоединить(ОбластьДанных);
Если ЕстьСкидки Тогда
ТабДокумент.Присоединить(ОбластьСкидок);
КонецЕсли;
ТабДокумент.Присоединить(ОбластьСуммы);
ОбластьКолонкаТовар = Макет.Область("Товар");
Если Не ВыводитьКоды Тогда
ОбластьКолонкаТовар.ШиринаКолонки = ОбластьКолонкаТовар.ШиринаКолонки
+ Макет.Область("КолонкаКодов").ШиринаКолонки;
КонецЕсли;
Если Не ЕстьСкидки Тогда
ОбластьКолонкаТовар.ШиринаКолонки = ОбластьКолонкаТовар.ШиринаКолонки
+ Макет.Область("СуммаБезСкидки").ШиринаКолонки
+ Макет.Область("СуммаСкидки").ШиринаКолонки;
КонецЕсли;
ОбластьНомера = Макет.ПолучитьОбласть("Строка|НомерСтроки");
ОбластьКодов = Макет.ПолучитьОбласть("Строка|КолонкаКодов");
ОбластьДанных = Макет.ПолучитьОбласть("Строка|Данные");
ОбластьСкидок = Макет.ПолучитьОбласть("Строка|Скидка");
ОбластьСуммы = Макет.ПолучитьОбласть("Строка|Сумма");
Сумма = 0;
ВсегоСкидок = 0;
ВсегоБезСкидок = 0;
ВыборкаСтрокТовары = Шапка.Товары.Выбрать();
Пока ВыборкаСтрокТовары.Следующий() Цикл
Если НЕ ЗначениеЗаполнено(ВыборкаСтрокТовары.Номенклатура) Тогда
Сообщить("В одной из строк не заполнено значение номенклатуры - строка при печати пропущена.", СтатусСообщения.Важное);
Продолжить;
КонецЕсли;
ОбластьНомера.Параметры.Заполнить(ВыборкаСтрокТовары);
ТабДокумент.Вывести(ОбластьНомера);
Если ВыводитьКоды Тогда
Если Колонка = "Артикул" Тогда
ОбластьКодов.Параметры.Артикул = ВыборкаСтрокТовары.Артикул;
Иначе
ОбластьКодов.Параметры.Артикул = ВыборкаСтрокТовары.Код;
КонецЕсли;
ТабДокумент.Присоединить(ОбластьКодов);
КонецЕсли;
ОбластьДанных.Параметры.Заполнить(ВыборкаСтрокТовары);
ОбластьДанных.Параметры.Товар = ?(Не ЗначениеЗаполнено(ВыборкаСтрокТовары.ТоварПолноеНаименование),
ВыборкаСтрокТовары.Товар,
ВыборкаСтрокТовары.ТоварПолноеНаименование)
+ УниверсальныеМеханизмы.ПредставлениеХарактеристик(ВыборкаСтрокТовары);
ТабДокумент.Присоединить(ОбластьДанных);
Скидка = ВыборкаСтрокТовары.Цена * ВыборкаСтрокТовары.Количество - ВыборкаСтрокТовары.Сумма;
Если ЕстьСкидки Тогда
ОбластьСкидок.Параметры.Скидка = Скидка;
ОбластьСкидок.Параметры.СуммаБезСкидки = ВыборкаСтрокТовары.Сумма + Скидка;
ТабДокумент.Присоединить(ОбластьСкидок);
КонецЕсли;
ОбластьСуммы.Параметры.Заполнить(ВыборкаСтрокТовары);
ТабДокумент.Присоединить(ОбластьСуммы);
Сумма = Сумма + ВыборкаСтрокТовары.Сумма;
ВсегоСкидок = ВсегоСкидок + Скидка;
ВсегоБезСкидок = Сумма + ВсегоСкидок;
КонецЦикла;
// Вывести Итого.
ОбластьНомера = Макет.ПолучитьОбласть("Итого|НомерСтроки");
ОбластьКодов = Макет.ПолучитьОбласть("Итого|КолонкаКодов");
ОбластьДанных = Макет.ПолучитьОбласть("Итого|Данные");
ОбластьСкидок = Макет.ПолучитьОбласть("Итого|Скидка");
ОбластьСуммы = Макет.ПолучитьОбласть("Итого|Сумма");
ТабДокумент.Вывести(ОбластьНомера);
Если ВыводитьКоды Тогда
ТабДокумент.Присоединить(ОбластьКодов);
КонецЕсли;
ТабДокумент.Присоединить(ОбластьДанных);
Если ЕстьСкидки Тогда
ОбластьСкидок.Параметры.ВсегоСкидок = ВсегоСкидок;
ОбластьСкидок.Параметры.ВсегоБезСкидок = ВсегоБезСкидок;
ТабДокумент.Присоединить(ОбластьСкидок);
КонецЕсли;
ОбластьСуммы.Параметры.Всего = Сумма;
ТабДокумент.Присоединить(ОбластьСуммы);
// Вывести Сумму прописью.
ОбластьМакета = Макет.ПолучитьОбласть("СуммаПрописью");
ОбластьМакета.Параметры.ИтоговаяСтрока = "Всего наименований " + ВыборкаСтрокТовары.Количество()
+ ", на сумму " + ОбщегоНазначения.ФорматСумм(Шапка.СуммаДокумента);
ОбластьМакета.Параметры.СуммаПрописью = ОбщегоНазначения.СформироватьСуммуПрописью(Шапка.СуммаДокумента);
ТабДокумент.Вывести(ОбластьМакета);
// Вывести Оплату и Сдачу.
СуммаОплат = 0;
СуммаБезналичныхОплат = 0;
СписокОплат = Новый Соответствие();
ВыборкаОплат = Шапка.Оплата.Выбрать();
Пока ВыборкаОплат.Следующий() Цикл
Если Шапка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат
И ВыборкаОплат.ВидОплаты.ТипОплаты <> Перечисления.ТипыОплатЧекаККМ.Наличные Тогда
СуммаБезналичныхОплат = СуммаБезналичныхОплат + ВыборкаОплат.Сумма;
КонецЕсли;
ЗаписьОплаты = СписокОплат.Получить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты));
Если ЗаписьОплаты = Неопределено Тогда
СписокОплат.Вставить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты), ВыборкаОплат.Сумма);
Иначе
СписокОплат.Вставить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты), ЗаписьОплаты + ВыборкаОплат.Сумма);
КонецЕсли;
СуммаОплат = СуммаОплат + ВыборкаОплат.Сумма;
КонецЦикла;
//Отдельная подготовка наличной оплаты для чека возврата
Если Шапка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
СписокОплат.Вставить(Строка(Перечисления.ТипыОплатЧекаККМ.Наличные), Шапка.СуммаДокумента - СуммаБезналичныхОплат);
КонецЕсли;
ОбластьМакета = Макет.ПолучитьОбласть("Оплата");
ОплатаДобавлена = Ложь;
Для Каждого ЗнПеречисления Из Перечисления.ТипыОплатЧекаККМ Цикл
ЗаписьОплаты = СписокОплат.Получить(Строка(ЗнПеречисления));
Если ЗаписьОплаты <> Неопределено Тогда
ОбластьМакета.Параметры.Оплата = ?(ОплатаДобавлена, ОбластьМакета.Параметры.Оплата + Символы.ПС, "")
+ Строка(ЗнПеречисления) + ": " + Формат(ЗаписьОплаты, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
ОплатаДобавлена = Истина;
КонецЕсли;
КонецЦикла;
Если Шапка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Продажа Тогда
ОбластьМакета.Параметры.Сдача = Формат(СуммаОплат - Шапка.СуммаДокумента, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
Иначе
ОбластьМакета.Параметры.Сдача = "0.00";
КонецЕсли;
ТабДокумент.Вывести(ОбластьМакета);
// Вывести подписи.
ОбластьМакета = Макет.ПолучитьОбласть("Подписи");
ОбластьМакета.Параметры.Заполнить(Шапка);
ТабДокумент.Вывести(ОбластьМакета);
Возврат ТабДокумент;
КонецФункции // ПечатьЧека()
// Функция формирует табличный документ с печатной формой узкого чека для печати на принтерах с чековой лентой.
Функция ПечатьТоварногоЧекаДляПД()
ДокументЧекККМ = Новый ТабличныйДокумент();
МассивСтрокЧека = Новый Массив();
// Получение макета
МакетЧекаККМ = Документы.ЧекККМ.ПолучитьМакет("ТоварныйЧекДляПД");
ОбластьШапкаЧека = МакетЧекаККМ.ПолучитьОбласть("ШапкаЧека|_" + КассаККМ.ШиринаЛенты);
ОбластьТелоЧека = МакетЧекаККМ.ПолучитьОбласть("ТелоЧека|_" + КассаККМ.ШиринаЛенты);
ОбластьТелоЧекаСкидка = МакетЧекаККМ.ПолучитьОбласть("ТелоЧекаСкидка|_" + КассаККМ.ШиринаЛенты);
ОбластьТелоЧекаОтступ = МакетЧекаККМ.ПолучитьОбласть("ТелоЧекаОтступ|_" + КассаККМ.ШиринаЛенты);
ОбластьПодвалЧека = МакетЧекаККМ.ПолучитьОбласть("ПодвалЧека|_" + КассаККМ.ШиринаЛенты);
ОбластьПодвалЧекаОплата = МакетЧекаККМ.ПолучитьОбласть("ПодвалЧекаОплата|_" + КассаККМ.ШиринаЛенты);
ОбластьПодвалЧекаОстаток = МакетЧекаККМ.ПолучитьОбласть("ПодвалЧекаОстаток|_" + КассаККМ.ШиринаЛенты);
// Получение данных документа
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТекущийДокумент", ЭтотОбъект.Ссылка);
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.Текст = "
|ВЫБРАТЬ
| ДокЧек.Номер,
| ДокЧек.Дата,
| ДокЧек.КассаККМ,
| ДокЧек.КассаККМ.Организация КАК Организация,
| ВЫБОР КОГДА ДокЧек.КассаККМ.Организация.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ЮрЛицо)
| ТОГДА ПРЕДСТАВЛЕНИЕ(ДокЧек.КассаККМ.Организация)
| ИНАЧЕ ""ИП "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Фамилия, """") = """"
| ТОГДА """"
| ИНАЧЕ
| ФИОФизЛицСрезПоследнихИП.Фамилия + "" "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Имя, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследнихИП.Имя КАК СТРОКА(1)) + "". ""
| КОНЕЦ
| +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Отчество, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследнихИП.Отчество КАК СТРОКА(1)) + "".""
| КОНЕЦ
| КОНЕЦ
| + """"
| КОНЕЦ КАК НаименованиеОрганизации,
| ДокЧек.СуммаДокумента,
| ДокЧек.ВидОперации,
| ДокЧек.Товары.(
| НомерСтроки,
| Номенклатура,
| Номенклатура.Представление КАК Товар,
| Номенклатура.НаименованиеПолное КАК ТоварПолноеНаименование,
| Номенклатура.Код КАК Код,
| Номенклатура.Артикул КАК Артикул,
| Количество,
| ЕдиницаИзмерения.Представление КАК ЕдиницаИзмерения,
| Цена,
| Сумма,
| ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
| ),
| ДокЧек.Оплата.(
| НомерСтроки,
| ВидОплаты,
| Сумма
| ),
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Фамилия, """") = """"
| ТОГДА """"
| ИНАЧЕ
| ФИОФизЛицСрезПоследних.Фамилия + "" "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Имя, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследних.Имя КАК СТРОКА(1)) + "". ""
| КОНЕЦ
| +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Отчество, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследних.Отчество КАК СТРОКА(1)) + "".""
| КОНЕЦ
| КОНЕЦ КАК ФИО
|ИЗ
| Документ.ЧекККМ КАК ДокЧек
|ЛЕВОЕ СОЕДИНЕНИЕ
| Справочник.Пользователи КАК Пользователи
|ПО
| Пользователи.Ссылка = ДокЧек.Ответственный
|ЛЕВОЕ СОЕДИНЕНИЕ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ПО
| Пользователи.ФизЛицо = ФизическиеЛица.Ссылка
|ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрСведений.ФИОФизЛиц.СрезПоследних(&Дата) КАК ФИОФизЛицСрезПоследних
|ПО
| ФизическиеЛица.Ссылка = ФИОФизЛицСрезПоследних.ФизЛицо
|ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрСведений.ФИОФизЛиц.СрезПоследних(&Дата) КАК ФИОФизЛицСрезПоследнихИП
|ПО
| ДокЧек.КассаККМ.Организация = ФИОФизЛицСрезПоследнихИП.ФизЛицо
|ГДЕ
| ДокЧек.Ссылка = &ТекущийДокумент
|УПОРЯДОЧИТЬ ПО
| ДокЧек.Товары.НомерСтроки,
| ДокЧек.Оплата.НомерСтроки
|";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Ответ = "Пустой чек не может быть пробит на устройстве!";
Отказ = Истина;
Результат = Ложь;
Возврат Результат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
// Формирование чека
// ШАПКА
Если Выборка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
ОбластьШапкаЧека.Параметры.Заголовок = ОбщегоНазначения.СформироватьЗаголовокДокумента(Выборка, "Чек (возврат)");
Иначе
ОбластьШапкаЧека.Параметры.Заголовок = ОбщегоНазначения.СформироватьЗаголовокДокумента(Выборка, "Чек");
КонецЕсли;
ОбластьШапкаЧека.Параметры.Организация = Строка(Выборка.НаименованиеОрганизации);
ОбластьШапкаЧека.Параметры.ИНН = "ИНН: " + Выборка.Организация.ИНН;
ДокументЧекККМ.Вывести(ОбластьШапкаЧека);
// ТЕЛО
ВыборкаТоваров = Выборка.Товары.Выбрать();
Пока ВыборкаТоваров.Следующий() Цикл
ОбластьТелоЧека.Параметры.НаименованиеТовара = ВыборкаТоваров.ТоварПолноеНаименование
+ "(" + ВыборкаТоваров.ЕдиницаИзмерения + ")";
ОбластьТелоЧека.Параметры.КоличествоЦена = Формат(ВыборкаТоваров.Количество, "ЧЦ=17; ЧДЦ=3; ЧРД=.; ЧН=; ЧГ=0")
+ " х "
+ Формат(ВыборкаТоваров.Цена, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
КонечнаяСкидка = ВыборкаТоваров.Количество * ВыборкаТоваров.Цена - ВыборкаТоваров.Сумма;
ДокументЧекККМ.Вывести(ОбластьТелоЧека);
Если КонечнаяСкидка <> 0 Тогда
ОбластьТелоЧекаСкидка.Параметры.ЗагСкидка = ?(КонечнаяСкидка > 0, "Скидка:", "Надбавка:");
ОбластьТелоЧекаСкидка.Параметры.Скидка = Формат(?(КонечнаяСкидка > 0, КонечнаяСкидка, -КонечнаяСкидка), "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
ДокументЧекККМ.Вывести(ОбластьТелоЧекаСкидка);
КонецЕсли;
ДокументЧекККМ.Вывести(ОбластьТелоЧекаОтступ);
КонецЦикла;
//ДокументЧекККМ.УдалитьСтроку(ДокументЧекККМ.КоличествоСтрок());
// ПОДВАЛ
ОбластьПодвалЧека.Параметры.Итог = Формат(Выборка.СуммаДокумента, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
ДокументЧекККМ.Вывести(ОбластьПодвалЧека);
СуммаОплат = 0;
СуммаБезналичныхОплат = 0;
СписокОплат = Новый Соответствие();
ВыборкаОплат = Выборка.Оплата.Выбрать();
Пока ВыборкаОплат.Следующий() Цикл
Если Выборка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат
И ВыборкаОплат.ВидОплаты.ТипОплаты <> Перечисления.ТипыОплатЧекаККМ.Наличные Тогда
СуммаБезналичныхОплат = СуммаБезналичныхОплат + ВыборкаОплат.Сумма;
КонецЕсли;
ЗаписьОплаты = СписокОплат.Получить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты));
Если ЗаписьОплаты = Неопределено Тогда
СписокОплат.Вставить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты), ВыборкаОплат.Сумма);
Иначе
СписокОплат.Вставить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты), ЗаписьОплаты + ВыборкаОплат.Сумма);
КонецЕсли;
СуммаОплат = СуммаОплат + ВыборкаОплат.Сумма;
КонецЦикла;
//Отдельная подготовка наличной оплаты для чека возврата
Если Выборка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
СписокОплат.Вставить(Строка(Перечисления.ТипыОплатЧекаККМ.Наличные), Выборка.СуммаДокумента - СуммаБезналичныхОплат);
КонецЕсли;
ОплатаДобавлена = Ложь;
Для Каждого ЗнПеречисления Из Перечисления.ТипыОплатЧекаККМ Цикл
ЗаписьОплаты = СписокОплат.Получить(Строка(ЗнПеречисления));
Если ЗаписьОплаты <> Неопределено Тогда
ОбластьПодвалЧекаОплата.Параметры.ТипОплаты = Строка(ЗнПеречисления) + ":";
ОбластьПодвалЧекаОплата.Параметры.Оплата = Формат(ЗаписьОплаты, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
//ОплатаДобавлена = Истина;
ДокументЧекККМ.Вывести(ОбластьПодвалЧекаОплата);
КонецЕсли;
КонецЦикла;
Если Выборка.ВидОперации <> Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
ОбластьПодвалЧекаОстаток.Параметры.Сдача = Формат(СуммаОплат - Выборка.СуммаДокумента, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
КонецЕсли;
ОбластьПодвалЧекаОстаток.Параметры.Сотрудник = Выборка.ФИО;
ДокументЧекККМ.Вывести(ОбластьПодвалЧекаОстаток);
Возврат ДокументЧекККМ;
КонецФункции
// Функция формирует табличный документ с печатной формой КМ3
//
// Возвращаемое значение:
// ТабличныйДокумент - печатная форма.
//
Функция ПечатьКМ3()
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТекущийДокумент", ЭтотОбъект.Ссылка);
Запрос.Текст =
"ВЫБРАТЬ
| ДокЧек.Номер КАК Номер,
| ДокЧек.Дата КАК ДатаДокумента,
| ДокЧек.КассаККМ,
| ДокЧек.КассаККМ.Представление КАК Покупатель,
| ДокЧек.Ответственный.ФизЛицо КАК КассирККМ,
| ДокЧек.КассаККМ.Организация КАК Организация,
| ДокЧек.КассаККМ.Организация КАК Руководители,
| ДокЧек.КассаККМ.Организация.Представление КАК Поставщик,
| ДокЧек.КассаККМ.СерийныйНомер КАК СерийныйНомерККМ,
| ДокЧек.КассаККМ.РегистрационныйНомер КАК РегистрационныйНомерККМ,
| ДокЧек.ЧекККМПродажа.НомерЧекаККМ КАК НомерЧека,
| ДокЧек.СуммаДокумента КАК СуммаДокумента
|ИЗ
| Документ.ЧекККМ КАК ДокЧек
|ГДЕ
| ДокЧек.Ссылка = &ТекущийДокумент
|";
Шапка = Запрос.Выполнить().Выбрать();
Шапка.Следующий();
ЗапросККМ = Новый Запрос;
ЗапросККМ.УстановитьПараметр("КассаККМ", Шапка.КассаККМ);
ЗапросККМ.Текст = "ВЫБРАТЬ
| регТорговоеОборудование.Модель.Модель КАК ПредставлениеККМ
|ИЗ
| РегистрСведений.ТорговоеОборудование КАК регТорговоеОборудование
|ГДЕ
| регТорговоеОборудование.КассаККМ = &КассаККМ";
РезультатККМ = ЗапросККМ.Выполнить().Выбрать();
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_Чек_КМ3";
Макет = ПолучитьОбщийМакет("КМ3");
ОбластьМакета = Макет.ПолучитьОбласть("ОбластьАкта");
Если РезультатККМ.Следующий() Тогда
ОбластьМакета.Параметры.Заполнить(РезультатККМ);
КонецЕсли;
ОбластьМакета.Параметры.Заполнить(Шапка);
СведенияОбОрганизации = УправлениеКонтактнойИнформацией.СведенияОЮрФизЛице(Шапка.Организация, Шапка.ДатаДокумента);
ОбластьМакета.Параметры.ПредставлениеОрганизации = ФормированиеПечатныхФорм.ОписаниеОрганизации(СведенияОбОрганизации, "ПолноеНаименование,ИНН,ЮридическийАдрес,Телефоны");
ОбластьМакета.Параметры.СуммаПрописью = ОбщегоНазначения.СформироватьСуммуПрописью(Шапка.СуммаДокумента);
ОбластьМакета.Параметры.НомерДокумента = "";
ОбластьМакета.Параметры.ОрганизацияПоОКПО = СведенияОбОрганизации.КодПоОКПО;
ОбластьМакета.Параметры.ОрганизацияИНН = СведенияОбОрганизации.ИНН;
ОбластьМакета.Параметры.ВидДеятельностиПоОКДП = "";
Руководители = ФормированиеПечатныхФорм.ОтветственныеЛицаОрганизаций(Шапка.Руководители, Шапка.ДатаДокумента);
Руководитель = Руководители.Руководитель;
СтаршийКассир = Руководители.Кассир;
ДолжностьРуководителя = Руководители.РуководительДолжность;
Если ЗначениеЗаполнено(Шапка.КассирККМ) Тогда
СтруктураФИОКассираККМ = ФормированиеПечатныхФорм.ФамилияИмяОтчество(Шапка.КассирККМ, Шапка.ДатаДокумента);
ФИОКассираОперациониста = ФормированиеПечатныхФорм.ФамилияИнициалыФизЛица(Ложь,
СтруктураФИОКассираККМ.Фамилия,
СтруктураФИОКассираККМ.Имя,
СтруктураФИОКассираККМ.Отчество);
КонецЕсли;
ОбластьМакета.Параметры.ФИОКассираОрганизации = СтаршийКассир;
ОбластьМакета.Параметры.ФИОРуководителя = Руководитель;
ОбластьМакета.Параметры.ФИОКассираОперациониста = ФИОКассираОперациониста;
ОбластьМакета.Параметры.ДолжностьРуководителя = ДолжностьРуководителя;
ТабДокумент.Вывести(ОбластьМакета);
Возврат ТабДокумент;
КонецФункции
// Функция осуществляет печать чека.
//
// Параметры:
// Идентификатор - <Строка>
// - Идентификатор фискального регистратора.
//
// НомерЧека - <Число>
// - Выходной параметр; номер чека.
//
// НомерСмены - <Число>
// - Выходной параметр; номер смены.
//
// ОписаниеЧека - <ТаблицаЗначений>
// - Описание чека. Таблица имеет следующие колонки:
// Наименование - <Строка>
// - Наименование позиции.
// НомерСекции - <Число>
// - Номер секции.
// Цена - <Число>
// - Цена за единицу.
// Количество - <Число>
// - Количество единиц.
// Скидка - <Число>
// - Процент скидки (>0) или наценки (<0).
//
// СуммаНал - <Число>
// - Сумма наличными (принятая, или выданная).
//
// СуммаБезнал - <Число>
// - Сумма безналичными (принятая, или выданная).
//
// ПризнакВозврата - <Булево>
// - Признак необходимости печати чека на возврат.
//
// Возвращаемое значение:
// <ПеречислениеСсылка.ТООшибки*> - Результат работы функции
//
Функция ПечатьЧекаККМ(Идентификатор, НомерЧека, НомерСмены,
ОписаниеЧека, СуммаНал, СуммаБезнал, ПризнакВозврата)
СтруктрураШаблона = КассаККМ.ШаблонЧекККМ.Шаблон.Получить();
Если СтруктрураШаблона <> Неопределено Тогда
Параметры = Новый Структура();
Параметры.Вставить("СхемаКомпоновкиДанных", Неопределено);
Параметры.Вставить("КомпоновщикМакета", Неопределено);
Параметры.Вставить("КэшМакетов", Неопределено);
СтруктрураШаблона.Вставить("Шаблон", ПроцедурыПечатиФискальныхЧеков.ПолучитьМакетФискальногоЧекаДокументаЧекККМ(Ссылка, СтруктрураШаблона.Шаблон, СтруктрураШаблона.ШиринаЧека, Параметры));
СтруктрураШаблона.Вставить("СоставнойМассив", Новый Массив);
СтруктрураШаблона.Вставить("Идентификатор", Идентификатор);
КонецЕсли;
Результат = ПолучитьСерверТО().ОткрытьЧек(Идентификатор, "", ПризнакВозврата, НомерЧека, НомерСмены);
Если НЕ ЗначениеЗаполнено(Результат) Тогда
Результат = ПроцедурыПечатиФискальныхЧеков.НапечататьСтроки(СтруктрураШаблона, "Шапка");
Если ЗначениеЗаполнено(Результат) Тогда
Возврат Результат;
КонецЕсли;
Позиция = Неопределено;
Для Каждого Позиция Из ОписаниеЧека Цикл
Результат = ПроцедурыПечатиФискальныхЧеков.НапечататьСтроки(СтруктрураШаблона, "ТелоШапка_"+ОписаниеЧека.Индекс(Позиция));
Если ЗначениеЗаполнено(Результат) Тогда
Возврат Результат;
КонецЕсли;
ЗначениеСкидки = Позиция.Количество * Позиция.Цена * Позиция.Скидка * 0.01;
СуммаСоСкидкой1С = Окр(Позиция.Количество * Позиция.Цена - ЗначениеСкидки, 2);
СуммаСоСкидкойФР = Окр(Позиция.Количество * Позиция.Цена - Окр(ЗначениеСкидки, 2), 2);
Если НЕ (СтруктрураШаблона <> Неопределено И СтруктрураШаблона.ОднаФискальнаяСтрока) Тогда
Если СуммаСоСкидкой1С = СуммаСоСкидкойФР Тогда
СтрокаЧека = Новый Структура("Наименование, Количество, Цена, Скидка, НомерСекции, СтавкаНДС");
СтрокаЧека.Наименование = ?(СтруктрураШаблона = Неопределено,Позиция.Наименование,"");
СтрокаЧека.Количество = Позиция.Количество;
СтрокаЧека.Цена = Позиция.Цена;
СтрокаЧека.Скидка = Позиция.Скидка;
СтрокаЧека.НомерСекции = Позиция.НомерСекции;
СтрокаЧека.СтавкаНДС = Позиция.СтавкаНДС;
Результат = ПолучитьСерверТО().ПечатьСтрокиЧека(Идентификатор, СтрокаЧека);
Иначе
СтрокаЧека = Новый Структура("Наименование, Количество, Цена, Скидка, НомерСекции, СтавкаНДС");
СтрокаЧека.Наименование = ?(СтруктрураШаблона = Неопределено,Позиция.Наименование,"");
СтрокаЧека.Количество = 1;
СтрокаЧека.Цена = СуммаСоСкидкой1С;
СтрокаЧека.Скидка = 0;
СтрокаЧека.НомерСекции = Позиция.НомерСекции;
СтрокаЧека.СтавкаНДС = Позиция.СтавкаНДС;
Результат = ПолучитьСерверТО().ПечатьСтрокиЧека(Идентификатор, СтрокаЧека);
КонецЕсли;
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Возврат Результат;
КонецЕсли;
Результат = ПроцедурыПечатиФискальныхЧеков.НапечататьСтроки(СтруктрураШаблона, "ТелоПодвал_"+ОписаниеЧека.Индекс(Позиция));
Если ЗначениеЗаполнено(Результат) Тогда
Возврат Результат;
КонецЕсли;
КонецЦикла;
Результат = ПроцедурыПечатиФискальныхЧеков.НапечататьСтроки(СтруктрураШаблона, "Подвал");
Если ЗначениеЗаполнено(Результат) Тогда
Возврат Результат;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Результат) Тогда
Если СтруктрураШаблона <> Неопределено И СтруктрураШаблона.ОднаФискальнаяСтрока Тогда
МассивСтрокДляПечати = ПроцедурыПечатиФискальныхЧеков.ПреобразоватьМассивСоответствийВМассивТекстовыхСтрок(СтруктрураШаблона.СоставнойМассив);
Результат = ПОлучитьСерверТО().ПечатьТекста(Идентификатор, МассивСтрокДляПечати, СтруктрураШаблона.ШиринаЧека);
Если ЗначениеЗаполнено(Результат) Тогда
Возврат Результат;
КонецЕсли;
СтрокаЧека = Новый Структура("Наименование, Количество, Цена, Скидка, НомерСекции, СтавкаНДС");
СтрокаЧека.Наименование = "Всего:";
СтрокаЧека.Количество = 1;
СтрокаЧека.Цена = Товары.Итог("Сумма");
СтрокаЧека.Скидка = 0;
СтрокаЧека.СтавкаНДС = 0;
СтрокаЧека.НомерСекции = Позиция.НомерСекции;
Результат = ПолучитьСерверТО().ПечатьСтрокиЧека(Идентификатор, СтрокаЧека);
КонецЕсли;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Результат) Тогда
Результат = ПолучитьСерверТО().ЗакрытьЧек(Идентификатор, СуммаНал, СуммаБезнал);
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПечатьЧека()
Процедура ПечатьВозвратныеЗаявления();
Обработка = Обработки.ВозвратТоваровОтРозничногоПокупателя.Создать();
Обработка.Товары.Загрузить(ЭтотОбъект.Товары.Выгрузить());
Для Каждого СтрокаТабличнойЧасти Из Обработка.Товары Цикл
СтрокаТабличнойЧасти.ДокументПродажи = ЭтотОбъект.ЧекККМПродажа;
КонецЦикла;
Обработка.Касса = ЭтотОбъект.КассаККМ;
Обработка.ЧекНомер = ЭтотОбъект.ЧекККМПродажа.НомерЧекаККМ;
Обработка.ЧекДата = ЭтотОбъект.ЧекККМПродажа.Дата;
Обработка.ХозяйственнаяОперация = ЭтотОбъект.ХозяйственнаяОперация;
ФормаВозврата = Обработка.ПолучитьФорму();
КомманднаяПанельКнопки = ФормаВозврата.ЭлементыФормы.ОсновныеДействияФормы.Кнопки;
КомманднаяПанельКнопки.Удалить(КомманднаяПанельКнопки.Найти("ОсновныеДействияФормыВыполнить"));
КомманднаяПанельКнопки.Удалить(КомманднаяПанельКнопки.Найти("Разделитель"));
КомманднаяПанельКнопки.Печать.Кнопки.Удалить(КомманднаяПанельКнопки.Печать.Кнопки.Найти("ПечатьРКО"));
КомманднаяПанельКнопки.Печать.Кнопки.Удалить(КомманднаяПанельКнопки.Печать.Кнопки.Найти("Печать"));
ФормаВозврата.ЭлементыФормы.КоманднаяПанельТовары.Доступность = Ложь;
ФормаВозврата.ЭлементыФормы.Товары.Доступность = Ложь;
ФормаВозврата.ЭлементыФормы.Контрагент.Доступность = Ложь;
ФормаВозврата.ЭлементыФормы.Склад.Доступность = Ложь;
ФормаВозврата.ЭлементыФормы.Основание.Доступность = Ложь;
ФормаВозврата.ЭлементыФормы.ХозяйственнаяОперация.Доступность = Ложь;
ФормаВозврата.Открыть();
КонецПроцедуры
// Функция осуществляет проведение документа и печать чека на ФР.
//
// Параметры:
// Ответ - <Строка>
// - Выходной параметр; описание произошедшей ошибки.
//
// Отказ - <Булево>
// - Выходной параметр; признак отказа от выполнения операции.
//
// Возвращаемое значение:
// <Булево> - Истина в случае успешного завершения операции.
//
Функция ПровестиИРаспечататьЧек(Ответ, Отказ, ФормаДокумента, ПечатьПакетаДокументовВозврат = Ложь, РучнойРежимПечати = Ложь) Экспорт
Результат = Истина;
Ответ = "";
Попытка
Если НачалоДня(Дата) = НачалоДня(ТекущаяДата())
И Метаданные().ОперативноеПроведение = Метаданные.СвойстваОбъектов.ОперативноеПроведение.Разрешить Тогда
Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный);
Иначе
Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный);
КонецЕсли;
Если ПечатьПакетаДокументовВозврат Тогда
Печать("КМ3");
КонецЕсли;
Исключение
Ответ = "Ошибка при попытке проведения документа!";
Отказ = Истина;
Результат = Ложь;
Возврат Результат;
КонецПопытки;
Если СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Пробитый Тогда
Возврат Результат;
КонецЕсли;
Если РежимРМК
И КассаККМ.Организация.РозничнаяТорговляОблагаетсяЕНВД
И КассаККМ.ФормироватьНефискальныеЧеки
И КассаККМ.РучнойРежимФормированияЧека
И Не РучнойРежимПечати Тогда
Возврат Результат;
КонецЕсли;
ФР = глЗначениеПеременной("мФР");
Если ФР = Неопределено Тогда
МассивФР = ПолучитьСерверТО().ПолучитьСписокУстройств(
Перечисления.ВидыТорговогоОборудования.ФискальныйРегистратор,
КассаККМ);
КоличествоФР = МассивФР.Количество();
Если КоличествоФР = 0 Тогда
Ответ = ?((КассаККМ.Организация.РозничнаяТорговляОблагаетсяЕНВД И КассаККМ.ФормироватьНефискальныеЧеки),
?(РежимРМК, "", "Используется нефискальный режим формирования чеков и фискальный регистратор или принтер документов не подключены.
|Возможно формирование только товарного чека."),
"Чек не пробит, т.к. не подключен фискальный регистратор!");
Отказ = Истина;
Результат = Истина;
Возврат Результат;
ИначеЕсли КоличествоФР = 1 Тогда
ФР = МассивФР[0];
Иначе
СписокФР = РаботаСТорговымОборудованием.ПолучитьСписокУстройствТОДляВыбора(МассивФР);
ФР = СписокФР.ВыбратьЭлемент("Необходимо выбрать фискальный регистратор");
Если ФР = Неопределено Тогда
Ответ = "Операция отменена пользователем.";
Отказ = Истина;
Результат = Ложь;
Если РежимРМК Тогда
ТекстОшибки = "Операция отменена!" + Символы.ПС +
"Фискальный регистратор для печати чека выбран не был!" + Символы.ПС +
"Возможны расхождения данных в информационной базе и фискальном регистраторе (принтере чеков).";
ВывестиИнформациюОбОшибке(ТекстОшибки);
КонецЕсли;
Возврат Результат;
Иначе
ФР = ФР.Значение;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ОшибкаТО = Перечисления.ТООшибкиОбщие.ПустаяСсылка();
Если (КассаККМ.Организация.РозничнаяТорговляОблагаетсяЕНВД
И КассаККМ.ФормироватьНефискальныеЧеки) Тогда
ДокументЧекККМ = Новый ТекстовыйДокумент();
МассивСтрокЧека = Новый Массив();
// Получение макета
МакетЧекаККМ = Документы.ЧекККМ.ПолучитьМакет("ЧекПокупателя");
ОбластьШапкаЧека = МакетЧекаККМ.ПолучитьОбласть("ШапкаЧека" + КассаККМ.ШиринаЛенты);
ОбластьТелоЧека = МакетЧекаККМ.ПолучитьОбласть("ТелоЧека" + КассаККМ.ШиринаЛенты);
ОбластьПодвалЧека = МакетЧекаККМ.ПолучитьОбласть("ПодвалЧека" + КассаККМ.ШиринаЛенты);
// Получение данных документа
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТекущийДокумент", ЭтотОбъект.Ссылка);
Запрос.УстановитьПараметр("Дата", Дата);
Запрос.Текст = "
|ВЫБРАТЬ
| ДокЧек.Номер,
| ДокЧек.Дата,
| ДокЧек.КассаККМ,
| ДокЧек.Магазин,
| ДокЧек.КассаККМ.Организация КАК Организация,
| ВЫБОР КОГДА ДокЧек.КассаККМ.Организация.ЮрФизЛицо = ЗНАЧЕНИЕ(Перечисление.ЮрФизЛицо.ЮрЛицо)
| ТОГДА ПРЕДСТАВЛЕНИЕ(ДокЧек.КассаККМ.Организация)
| ИНАЧЕ ""ИП "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Фамилия, """") = """"
| ТОГДА """"
| ИНАЧЕ
| ФИОФизЛицСрезПоследнихИП.Фамилия + "" "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Имя, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследнихИП.Имя КАК СТРОКА(1)) + "". ""
| КОНЕЦ
| +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследнихИП.Отчество, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследнихИП.Отчество КАК СТРОКА(1)) + "".""
| КОНЕЦ
| КОНЕЦ
| + """"
| КОНЕЦ КАК НаименованиеОрганизации,
| ДокЧек.ДисконтнаяКарта,
| ДокЧек.СуммаДокумента,
| ДокЧек.ВидОперации,
| ДокЧек.Товары.(
| НомерСтроки,
| Номенклатура,
| Номенклатура.Представление КАК Товар,
| Номенклатура.НаименованиеПолное КАК ТоварПолноеНаименование,
| Номенклатура.Код КАК Код,
| Номенклатура.Артикул КАК Артикул,
| Количество,
| ЕдиницаИзмерения.Представление КАК ЕдиницаИзмерения,
| Цена,
| Сумма,
| ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры
| ),
| ДокЧек.Оплата.(
| НомерСтроки,
| ВидОплаты,
| Сумма
| ),
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Фамилия, """") = """"
| ТОГДА """"
| ИНАЧЕ
| ФИОФизЛицСрезПоследних.Фамилия + "" "" +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Имя, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследних.Имя КАК СТРОКА(1)) + "". ""
| КОНЕЦ
| +
| ВЫБОР КОГДА ЕСТЬNULL(ФИОФизЛицСрезПоследних.Отчество, """") = """"
| ТОГДА """"
| ИНАЧЕ ВЫРАЗИТЬ(ФИОФизЛицСрезПоследних.Отчество КАК СТРОКА(1)) + "".""
| КОНЕЦ
| КОНЕЦ КАК ФИО
|ИЗ
| Документ.ЧекККМ КАК ДокЧек
|ЛЕВОЕ СОЕДИНЕНИЕ
| Справочник.Пользователи КАК Пользователи
|ПО
| Пользователи.Ссылка = ДокЧек.Ответственный
|ЛЕВОЕ СОЕДИНЕНИЕ
| Справочник.ФизическиеЛица КАК ФизическиеЛица
|ПО
| Пользователи.ФизЛицо = ФизическиеЛица.Ссылка
|ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрСведений.ФИОФизЛиц.СрезПоследних(&Дата) КАК ФИОФизЛицСрезПоследних
|ПО
| ФизическиеЛица.Ссылка = ФИОФизЛицСрезПоследних.ФизЛицо
|ЛЕВОЕ СОЕДИНЕНИЕ
| РегистрСведений.ФИОФизЛиц.СрезПоследних(&Дата) КАК ФИОФизЛицСрезПоследнихИП
|ПО
| ДокЧек.КассаККМ.Организация = ФИОФизЛицСрезПоследнихИП.ФизЛицо
|ГДЕ
| ДокЧек.Ссылка = &ТекущийДокумент
|УПОРЯДОЧИТЬ ПО
| ДокЧек.Товары.НомерСтроки,
| ДокЧек.Оплата.НомерСтроки
|";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Ответ = "Пустой чек не может быть пробит на устройстве!";
Отказ = Истина;
Результат = Ложь;
Возврат Результат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
/////
// Формирование чека
// ШАПКА
ОбластьШапкаЧека.Параметры.Заголовок = ОбщегоНазначения.СформироватьЗаголовокДокумента(Выборка,
?(Выборка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат, "Чек (возврат)", "Чек"));
ОбластьШапкаЧека.Параметры.Организация = Строка(Выборка.НаименованиеОрганизации);
ОбластьШапкаЧека.Параметры.ИНН = "ИНН: " + Выборка.Организация.ИНН;
ДокументЧекККМ.Вывести(ОбластьШапкаЧека);
// ТЕЛО
ВыборкаТоваров = Выборка.Товары.Выбрать();
Пока ВыборкаТоваров.Следующий() Цикл
ОбластьТелоЧека.Параметры.НаименованиеТовара = ВыборкаТоваров.ТоварПолноеНаименование
+ "(" + ВыборкаТоваров.ЕдиницаИзмерения + ")";
ОбластьТелоЧека.Параметры.КоличествоЦена = Формат(ВыборкаТоваров.Количество, "ЧЦ=17; ЧДЦ=3; ЧРД=.; ЧН=; ЧГ=0")
+ " х "
+ Формат(ВыборкаТоваров.Цена, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
КонечнаяСкидка = ВыборкаТоваров.Количество * ВыборкаТоваров.Цена - ВыборкаТоваров.Сумма;
Если КонечнаяСкидка <> 0 Тогда
ОбластьТелоЧека.Параметры.ЗагСкидка = ?(КонечнаяСкидка > 0, "Скидка:", "Надбавка:");
ОбластьТелоЧека.Параметры.Скидка = Формат(?(КонечнаяСкидка > 0, КонечнаяСкидка, -КонечнаяСкидка), "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
КонецЕсли;
ДокументЧекККМ.Вывести(ОбластьТелоЧека);
КонецЦикла;
ДокументЧекККМ.УдалитьСтроку(ДокументЧекККМ.КоличествоСтрок());
// ПОДВАЛ
ОбластьПодвалЧека.Параметры.Итог = Формат(Выборка.СуммаДокумента, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
СуммаОплат = 0;
СуммаБезналичныхОплат = 0;
СписокОплат = Новый Соответствие();
ВыборкаОплат = Выборка.Оплата.Выбрать();
Пока ВыборкаОплат.Следующий() Цикл
Если Выборка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат
И ВыборкаОплат.ВидОплаты.ТипОплаты <> Перечисления.ТипыОплатЧекаККМ.Наличные Тогда
СуммаБезналичныхОплат = СуммаБезналичныхОплат + ВыборкаОплат.Сумма;
КонецЕсли;
ЗаписьОплаты = СписокОплат.Получить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты));
Если ЗаписьОплаты = Неопределено Тогда
СписокОплат.Вставить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты), ВыборкаОплат.Сумма);
Иначе
СписокОплат.Вставить(Строка(ВыборкаОплат.ВидОплаты.ТипОплаты), ЗаписьОплаты + ВыборкаОплат.Сумма);
КонецЕсли;
СуммаОплат = СуммаОплат + ВыборкаОплат.Сумма;
КонецЦикла;
//Отдельная подготовка наличной оплаты для чека возврата
Если Выборка.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
СписокОплат.Вставить(Строка(Перечисления.ТипыОплатЧекаККМ.Наличные), Выборка.СуммаДокумента - СуммаБезналичныхОплат);
КонецЕсли;
ОплатаДобавлена = Ложь;
Для Каждого ЗнПеречисления Из Перечисления.ТипыОплатЧекаККМ Цикл
ЗаписьОплаты = СписокОплат.Получить(Строка(ЗнПеречисления));
Если ЗаписьОплаты <> Неопределено Тогда
ОбластьПодвалЧека.Параметры.Оплата = ?(ОплатаДобавлена, ОбластьПодвалЧека.Параметры.Оплата + Символы.ПС, "")
+ Строка(ЗнПеречисления) + ": " + Формат(ЗаписьОплаты, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
ОплатаДобавлена = Истина;
КонецЕсли;
КонецЦикла;
Если Выборка.ВидОперации <> Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
ОбластьПодвалЧека.Параметры.Сдача = "СДАЧА: " + Формат(СуммаОплат - Выборка.СуммаДокумента, "ЧЦ=15; ЧДЦ=2; ЧРД=.; ЧН=; ЧГ=0");
КонецЕсли;
ОбластьПодвалЧека.Параметры.Сотрудник = Выборка.ФИО;
ДокументЧекККМ.Вывести(ОбластьПодвалЧека);
Если ДокументЧекККМ.КоличествоСтрок() > 0 Тогда
Для Индекс = 1 По ДокументЧекККМ.КоличествоСтрок() Цикл
МассивСтрокЧека.Добавить(ДокументЧекККМ.ПолучитьСтроку(Индекс));
КонецЦикла;
// Открыть нефискальный чек
ОшибкаТО = ПолучитьСерверТО().ОткрытьЧек(ФР, "",
ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат,
НомерЧекаККМ, НомерСменыККМ, Ложь);
Если Не ЗначениеЗаполнено(ОшибкаТО) Тогда
// Напечатать строки полученного из макета чека
ОшибкаТО = ПолучитьСерверТО().ПечатьТекста(ФР, МассивСтрокЧека, КассаККМ.ШиринаЛенты);
// Закрыть чек
ОшибкаТО = ПолучитьСерверТО().ЗакрытьЧек(ФР, 0, 0);
КонецЕсли;
КонецЕсли;
Иначе
Запрос = Новый Запрос(
"ВЫБРАТЬ
| ТчТовары.Номенклатура.Представление КАК Номенклатура,
| ТчТовары.ХарактеристикаНоменклатуры.Представление КАК ХарактеристикаНоменклатуры,
| ТчТовары.ЕдиницаИзмерения.Представление КАК ЕдиницаИзмерения,
| ТчТовары.Цена КАК Цена,
| ТчТовары.Количество КАК Количество,
| ВЫБОР
| КОГДА ТчТовары.Цена * ТчТовары.Количество = 0
| ТОГДА 0
| ИНАЧЕ (1 - ТчТовары.Сумма / (ТчТовары.Цена * ТчТовары.Количество)) * 100
| КОНЕЦ КАК ПроцентСкидкиНаценки,
| ТчТовары.СтавкаНДС,
| ТчТовары.СуммаНДС
|ИЗ
| Документ.ЧекККМ.Товары КАК ТчТовары
|ГДЕ
| ТчТовары.Ссылка = &Ссылка");
Запрос.УстановитьПараметр("Ссылка", Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Ответ = "Пустой чек не может быть пробит на фискальном регистраторе!";
Отказ = Истина;
Результат = Ложь;
Если РежимРМК Тогда
ТекстОшибки = "Пустой чек!" + Символы.ПС +
"Пустой чек не может быть распечатан на фискальном регистраторе!" + Символы.ПС +
"Это не критичная ошибка, т.к. проведенный пустой чек не влияет на данные информационной базы.";
ВывестиИнформациюОбОшибке(ТекстОшибки);
КонецЕсли;
Возврат Результат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
ТаблицаТоваров = Новый ТаблицаЗначений;
ТаблицаТоваров.Колонки.Добавить("Наименование");
ТаблицаТоваров.Колонки.Добавить("НомерСекции");
ТаблицаТоваров.Колонки.Добавить("Цена");
ТаблицаТоваров.Колонки.Добавить("Количество");
ТаблицаТоваров.Колонки.Добавить("Скидка");
ТаблицаТоваров.Колонки.Добавить("СтавкаНДС");
ПечататьНДСВКассовыхЧекахИзДокументовЧекККМ = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ПечататьНДСВКассовыхЧекахИзДокументовЧекККМ");
Пока Выборка.Следующий() Цикл
Товар = ТаблицаТоваров.Добавить();
Товар.Наименование = СокрЛП(Выборка.Номенклатура)
+ "(" + СокрЛП(Выборка.ЕдиницаИзмерения)
+ ?(ПустаяСтрока(Выборка.ХарактеристикаНоменклатуры), "", ", " + СокрЛП(Выборка.ХарактеристикаНоменклатуры)) + ")";
Товар.НомерСекции = 1;
Товар.Цена = Выборка.Цена;
Товар.Количество = Выборка.Количество;
Товар.Скидка = Выборка.ПроцентСкидкиНаценки;
Товар.СтавкаНДС = ?(ПечататьНДСВКассовыхЧекахИзДокументовЧекККМ, Ценообразование.ПолучитьСтавкуНДС(Выборка.СтавкаНДС), 0);
КонецЦикла;
ОшибкаТО = ПечатьЧекаККМ(ФР, НомерЧекаККМ, НомерСменыККМ,
ТаблицаТоваров, ПолучитьСуммуНаличнойОплаты(),
ПолучитьСуммуБезналичнойОплаты() + ПолучитьСуммуОплатыПодарочнымиСертификатами(),
ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат);
КонецЕсли;
Если НЕ ЗначениеЗаполнено(ОшибкаТО) Тогда
СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Пробитый;
Попытка
Записать(РежимЗаписиДокумента.Запись);
Исключение
Ответ = "Не удалось записать документ с установленными параметрами пробитого чека.";
Отказ = Истина;
Результат = Ложь;
Если РежимРМК Тогда
ТекстОшибки = "Ошибка записи чека!" + Символы.ПС +
"Не удалось установить признак пробития чека!" + Символы.ПС +
"Это не критичная ошибка, т.к. при закрытии смены чек в любом случае попадет в отчет о продажах.";
ВывестиИнформациюОбОшибке(ТекстОшибки);
КонецЕсли;
КонецПопытки;
Иначе
Ответ = ПолучитьСерверТО().ПолучитьТекстОшибкиФРТО(ОшибкаТО);
Отказ = Истина;
Результат = Ложь;
Если РежимРМК Тогда
ТекстОшибки = "Ошибка фискального регистратора!" + Символы.ПС +
Ответ + Символы.ПС + "!" +
"Необходимо проверить настройки подключения фискального регистратора.";
ВывестиИнформациюОбОшибке(ТекстОшибки);
КонецЕсли;
КонецЕсли;
Если ПараметрыСеанса.НаличиеОбменаДаннымиПоКассе И Не ПараметрыСеанса.ЭтоГлавныйУзелОбменаПоКассе Тогда
//определим настройку для выполнения
СтруктураНастроекОбмена = ПроцедурыОбменаДаннымиПоКассе.ПолучитьСтруктуруНастроекОбменаВУзлеКассы();
Если Не ЗначениеЗаполнено(СтруктураНастроекОбмена.НастройкаОбменаДанными) Тогда
Сообщить("Не смог определить настройку обмена данными для узла кассы!
|Необходимо в форме узла обмена выбрать соответствующую настройку обмена!", СтатусСообщения.ОченьВажное);
Иначе
ПроцедурыОбменаДанными.ВыполнитьОбменДаннымиПоПроизвольнойНастройке(СтруктураНастроекОбмена.НастройкаОбменаДанными, Ложь, глЗначениеПеременной("глОбработкаАвтоОбменДанными"));
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции // ПровестиИРаспечататьЧек()
// Функция осуществляет операцию оплаты картой, используя подключенную эквайринговую систему.
//
// Параметры:
// СуммаОплаты - сумма оплаты
//
Функция ОплатитьКартой(СуммаОплаты) Экспорт
Перем ЭС;
Перем ФР;
РезультатФункции = Истина;
Если РаботаСТорговымОборудованием.ПолучитьПроверитьПараметрыДляОплатыКартой(ЭС, ФР) Тогда
КодRRN = Неопределено;
Если ВидОперации = Перечисления.ВидыОперацийЧекККМ.Продажа Тогда
Результат = ПолучитьСерверТО().ОплатитьПлатежнойКартой(ЭС, СуммаОплаты, КодRRN, ФР);
Иначе
Результат = ПолучитьСерверТО().ОтменитьПлатежПоПлатежнойКарте(ЭС, СуммаОплаты, КодRRN, ФР);
КонецЕсли;
Если ЗначениеЗаполнено(Результат) Тогда
Ошибка = ПолучитьСерверТО().ПолучитьТекстОшибкиТО(Результат);
Предупреждение(Ошибка);
РезультатФункции = Ложь;
КонецЕсли;
КонецЕсли;
Возврат РезультатФункции;
КонецФункции // ОплатитьКартой()
// Выводит в окне информацию об ошибке
//
Процедура ВывестиИнформациюОбОшибке(ТекстОшибки) Экспорт
ФормаИнформацииОбОшибке = ПолучитьФорму("ФормаИнформацииОбОшибке");
ФормаИнформацииОбОшибке.ТекстОшибки = ТекстОшибки;
ФормаИнформацииОбОшибке.ОткрытьМодально();
КонецПроцедуры
// Вывести подготовленные сообщения
//
// Параметры
// ТаблицаСообщений - Подготовленная таблица сообщений
//
Процедура ВывестиСообщенияКассиру(ТаблицаСообщений) Экспорт
Если НЕ ЗначениеЗаполнено(ТаблицаСообщений) Тогда
Возврат;
ИначеЕсли ТаблицаСообщений.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Для каждого СтрокаТаблицыСообщений Из ТаблицаСообщений Цикл
ВывестиИнформациюОбОшибке(СтрокаТаблицыСообщений.ТекстСообщения);
КонецЦикла;
КонецПроцедуры // ВывестиСообщенияКассиру()
// Определяет скидки после закрытия чека.
//
// Параметры:
// Нет
//
Процедура ОпределитьСообщенияКассируПослеОформленияЧека() Экспорт
Если ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
Возврат;
КонецЕсли;
мСуммаДокументаБезСкидок = Ценообразование.ПолучитьСуммуДокументаБезСкидки(Товары);
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("СуммаДокумента" , мСуммаДокументаБезСкидок);
СтруктураПараметров.Вставить("Получатель" , ВладелецДисконтнойКарты);
СтруктураПараметров.Вставить("Карта" , ДисконтнаяКарта);
СтруктураПараметров.Вставить("ВидыОплат" , МассивОплатДляСкидок());
СтруктураПараметров.Вставить("УчитыватьНДС" , Истина);
СтруктураПараметров.Вставить("СуммаВключаетНДС" , Истина);
СтруктураПараметров.Вставить("НомерЧека" , НомерЧекаККМ);
СтруктураПараметров.Вставить("Купоны" , Купоны.ВыгрузитьКолонку("СкидкаНаценка"));
СтруктураПараметров.Вставить("МоментПроверкиСообщений", Перечисления.ТочкиВыдачиСообщенияКассиру.ПослеОформленияЧека);
СтруктураПараметров.Вставить("ТолькоСообщения" , Истина);
ТаблицаСообщений = Новый ТаблицаЗначений;
УправлениеМаркетинговымиАкциями.РассчитатьСообщенияПриПродаже(ЭтотОбъект, Товары, Скидки, Подарки, СтруктураПараметров, ТаблицаСообщений);
ВывестиСообщенияКассиру(ТаблицаСообщений);
КонецПроцедуры // ОпределитьСообщенияКассируПослеОформленияЧека()
#КонецЕсли
// Возвращает доступные варианты печати документа.
//
// Вовращаемое значение:
// Структура, каждая строка которой соответствует одному из вариантов печати.
//
Функция ПолучитьСтруктуруПечатныхФорм() Экспорт
СтруктураМакетов = Новый Структура("Чек", "Товарный чек");
Если КассаККМ.Организация.РозничнаяТорговляОблагаетсяЕНВД
И КассаККМ.ФормироватьНефискальныеЧеки Тогда
СтруктураМакетов.Вставить( "ТоварныйЧекДляПД", "Товарный чек для принтера документов");
КонецЕсли;
СтруктураМакетов.Вставить( "КМ3", "Пакет документов на возврат");
Возврат СтруктураМакетов;
КонецФункции // ПолучитьСтруктуруПечатныхФорм()
// Функция считает сумму, оплаченную наличными.
//
// Возвращаемое значение:
// Число - сумма, оплаченная наличными.
//
Функция ПолучитьСуммуНаличнойОплаты() Экспорт
СуммаНаличнойОплаты = 0;
Для Каждого ТекОплата Из Оплата Цикл
Если ЗначениеЗаполнено(ТекОплата.ВидОплаты) И ТекОплата.ВидОплаты.ТипОплаты = Перечисления.ТипыОплатЧекаККМ.Наличные Тогда
СуммаНаличнойОплаты = СуммаНаличнойОплаты + ТекОплата.Сумма;
КонецЕсли;
КонецЦикла;
Возврат СуммаНаличнойОплаты;
КонецФункции // ПолучитьСуммуНаличнойОплаты()
// Функция считает сумму, оплаченную безналичными.
//
// Возвращаемое значение:
// Число - сумма, оплаченная безналично.
//
Функция ПолучитьСуммуБезналичнойОплаты() Экспорт
СуммаБезналичнойОплаты = 0;
Для Каждого ТекОплата Из Оплата Цикл
Если ЗначениеЗаполнено(ТекОплата.ВидОплаты) И ТекОплата.ВидОплаты.ТипОплаты <> Перечисления.ТипыОплатЧекаККМ.Наличные
И НЕ ТекОплата.ВидОплаты = Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом Тогда
СуммаБезналичнойОплаты = СуммаБезналичнойОплаты + ТекОплата.Сумма;
КонецЕсли;
КонецЦикла;
Возврат СуммаБезналичнойОплаты;
КонецФункции // ПолучитьСуммуБезналичнойОплаты()
// Функция считает сумму, оплаченную подарочными сертификатами.
//
// Возвращаемое значение:
// Число - сумма, оплаченная подарочными сертификатами.
//
Функция ПолучитьСуммуОплатыПодарочнымиСертификатами() Экспорт
СуммаОплаты = 0;
Для Каждого ТекОплата Из Оплата Цикл
Если ТекОплата.ВидОплаты = Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом Тогда
СуммаОплаты = СуммаОплаты + ТекОплата.Сумма;
КонецЕсли;
КонецЦикла;
Возврат СуммаОплаты;
КонецФункции // ПолучитьСуммуБезналичнойОплаты()
// Функция считает сумму, оплаченную безналичными по платежным картам.
//
// Возвращаемое значение:
// Число - сумма, оплаченная наличными.
//
Функция ПолучитьСуммуОплатыПлатежнымиКартами() Экспорт
СуммаОплаты = 0;
Для Каждого ТекОплата Из Оплата Цикл
Если ЗначениеЗаполнено(ТекОплата.ВидОплаты) И ТекОплата.ВидОплаты.ТипОплаты = Перечисления.ТипыОплатЧекаККМ.ПлатежнаяКарта Тогда
СуммаОплаты = СуммаОплаты + ТекОплата.Сумма;
КонецЕсли;
КонецЦикла;
Возврат СуммаОплаты;
КонецФункции // ПолучитьСуммуОплатыПлатежнымиКартами()
// Функция считает сумму, оплаченную безналичными по банковскому кредиту.
//
// Возвращаемое значение:
// Число - сумма, оплаченная наличными.
//
Функция ПолучитьСуммуОплатыБанковскимКредитом() Экспорт
СуммаОплаты = 0;
Для Каждого ТекОплата Из Оплата Цикл
Если ЗначениеЗаполнено(ТекОплата.ВидОплаты) И ТекОплата.ВидОплаты.ТипОплаты = Перечисления.ТипыОплатЧекаККМ.БанковскийКредит Тогда
СуммаОплаты = СуммаОплаты + ТекОплата.Сумма;
КонецЕсли;
КонецЦикла;
Возврат СуммаОплаты;
КонецФункции // ПолучитьСуммуОплатыПлатежнымиКартами()
// удаляет скидки лишние при возврате
//
// Параметры:
// Нет
//
Процедура УдалитьНенужныеСкидкиПриВозврате() Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Товары.КлючСтроки
|ПОМЕСТИТЬ ДокТовары
|ИЗ
| &Товары КАК Товары
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Скидки.КлючСтроки,
| Скидки.НомерСтроки
|ПОМЕСТИТЬ ДокСкидки
|ИЗ
| &Скидки КАК Скидки
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ДокСкидки.КлючСтроки,
| ДокСкидки.НомерСтроки
|ИЗ
| ДокСкидки КАК ДокСкидки
| ЛЕВОЕ СОЕДИНЕНИЕ ДокТовары КАК ДокТовары
| ПО ДокСкидки.КлючСтроки = ДокТовары.КлючСтроки
|ГДЕ
| ДокТовары.КлючСтроки ЕСТЬ NULL ";
Запрос.УстановитьПараметр("Товары", Товары);
Запрос.УстановитьПараметр("Скидки", Скидки);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
МассивУдаляемыхСтрок = Новый Массив;
Пока Выборка.Следующий() Цикл
СтрокаПодарки = Скидки[Выборка.НомерСтроки - 1];
МассивУдаляемыхСтрок.Добавить(СтрокаПодарки);
КонецЦикла;
Для каждого СтрокаПодарки Из МассивУдаляемыхСтрок Цикл
Скидки.Удалить(СтрокаПодарки);
КонецЦикла;
КонецПроцедуры // УдалитьНенужныеСкидкиПриВозврате()
// Пересчитывает скидки в документе возврата при изменении количества
//
// Параметры
// СтрокаТабличнойЧасти - строка табличной части товары в которой изменено количество
//
Процедура ПересчитатьСкидкиВозврата(СтрокаТабличнойЧасти) Экспорт
КлючСтроки = СтрокаТабличнойЧасти.КлючСтроки;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ЧекККМТовары.Количество * ВЫБОР
| КОГДА ЧекККМТовары.Коэффициент = 0
| ТОГДА 1
| ИНАЧЕ ЧекККМТовары.Коэффициент
| КОНЕЦ / &КоличествоВЗапрос КАК КоэффициентПересчета
|ИЗ
| Документ.ЧекККМ.Товары КАК ЧекККМТовары
|ГДЕ
| ЧекККМТовары.КлючСтроки = &КлючСтроки
| И ЧекККМТовары.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("КлючСтроки", КлючСтроки);
Запрос.УстановитьПараметр("Ссылка", ЧекККМПродажа);
КоличествоВЗапрос = ?(СтрокаТабличнойЧасти.Коэффициент = 0 ,1, СтрокаТабличнойЧасти.Коэффициент)*?(СтрокаТабличнойЧасти.Количество = 0, 1, СтрокаТабличнойЧасти.Количество);
Запрос.УстановитьПараметр("КоличествоВЗапрос", КоличествоВЗапрос);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
КоэффициентПересчета = Выборка.КоэффициентПересчета;
Если НЕ КоэффициентПересчета = 0 Тогда
СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("КлючСтроки", КлючСтроки);
СтрокиЧекККМПродажи = ЧекККМПродажа.Скидки.НайтиСтроки(СтруктураПоиска);
Для каждого СтрокаЧекККМПродажи Из СтрокиЧекККМПродажи Цикл
СтруктураПоиска.Вставить("СкидкаНаценка", СтрокаЧекККМПродажи.СкидкаНаценка);
СтрокиСкидки = Скидки.НайтиСтроки(СтруктураПоиска);
Для каждого СтрокаСкидки Из СтрокиСкидки Цикл
СтрокаСкидки.Сумма = СтрокаЧекККМПродажи.Сумма / КоэффициентПересчета;
КонецЦикла;
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ПересчитатьСкидкиВозврата()
// Получает сумму номиналов подарочных сертификатов
//
//
// Возвращаемое значение:
// Число
//
Функция ПолучитьСуммуНоминаловПодарочныхСертификатов() Экспорт
СуммаПогашения = 0;
Если ПогашениеПодарочныхСертификатов.Количество() >0 Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ВЫРАЗИТЬ(ПогашениеПодарочныхСертификатов.ПодарочныйСертификат КАК Справочник.Номенклатура) КАК Номенклатура
|ПОМЕСТИТЬ ТабПогашения
|ИЗ
| &ПогашениеПодарочныхСертификатов КАК ПогашениеПодарочныхСертификатов
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СУММА(ТабПогашения.Номенклатура.Номинал) КАК СуммаПогашения
|ИЗ
| ТабПогашения КАК ТабПогашения";
Запрос.УстановитьПараметр("ПогашениеПодарочныхСертификатов", ПогашениеПодарочныхСертификатов.Выгрузить());
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.СуммаПогашения;
Иначе
Возврат 0;
КонецЕсли;
Иначе
Возврат 0;
КонецЕсли;
КонецФункции // ПолучитьСуммуНоминаловПодарочныхСертификатов()
// Получить сумму погашения подарочными сертификатами
//
// Параметры
//
// Возвращаемое значение:
// Число
//
Функция ПолучитьСуммуПогашенияПодарочнымиСертификатами() Экспорт
Возврат МИН(ПолучитьСуммуНоминаловПодарочныхСертификатов(), Товары.Итог("Сумма"));
КонецФункции // ПолучитьСуммуПогашенияПодарочнымиСертификатами()
// Добавляет или корректирует оплату подарочным сертификатом при необходимости
//
// Параметры
// Нет
//
Процедура ДобавитьОплатуПодарочнымСертификатом() Экспорт
СуммаПогашения = ПолучитьСуммуПогашенияПодарочнымиСертификатами();
СтрокаОплаты = Оплата.Найти(Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом);
Если СуммаПогашения > 0 Тогда
Если СтрокаОплаты = Неопределено Тогда
СтрокаОплаты = Оплата.Добавить();
СтрокаОплаты.ВидОплаты = Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом;
КонецЕсли;
СтрокаОплаты.Сумма = СуммаПогашения;
ИначеЕсли Не СтрокаОплаты = Неопределено И (Товары.Итог("Сумма") > 0) Тогда
Оплата.Удалить(СтрокаОплаты);
ПогашениеПодарочныхСертификатов.Очистить();
КонецЕсли;
КонецПроцедуры // ДобавитьОплатуПодарочнымСертификатом()
// Возвращает массив оплат без купонов и скидок
//
// Возвращаемое значение:
// Массив
//
Функция МассивОплатДляСкидок() Экспорт
МассивОплат = Новый Массив;
МассивОплат = Оплата.ВыгрузитьКолонку("ВидОплаты");
Если МассивОплат.Количество()=0 Тогда
МассивОплат.Добавить(Справочники.ВидыОплатЧекаККМ.Наличные);
КонецЕсли;
Возврат МассивОплат;
КонецФункции // МассивОплатДляСкидок()
// Округляет сумму чека по правилам установленным в магазине
//
// Параметры
// Нет
//
Процедура ОкруглитьСуммуЧека() Экспорт
ПорядокОкругленияСуммыЧекаВПользуПокупателя = КассаККМ.Магазин.ПорядокОкругленияСуммыЧекаВПользуПокупателя;
Если Не ЗначениеЗаполнено(ПорядокОкругленияСуммыЧекаВПользуПокупателя) ИЛИ ПорядокОкругленияСуммыЧекаВПользуПокупателя = Перечисления.ПорядкиОкругления.Окр0_01 ИЛИ Товары.Количество()= 0 Тогда
Возврат;
КонецЕсли;
ЗначениеОкругления = Число(Строка(ПорядокОкругленияСуммыЧекаВПользуПокупателя));
Если ЗначениеЗаполнено(ЗначениеОкругления) Тогда
СуммаБезОкругления = Товары.Итог("Сумма");
ОкругленнаяСумма = Цел(СуммаБезОкругления / ЗначениеОкругления) * ЗначениеОкругления;
Округление = СуммаБезОкругления - ОкругленнаяСумма;
Если Округление > 0 Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Товары.НомерСтроки,
| ВЫРАЗИТЬ(Товары.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
| Товары.Сумма КАК Сумма
|ПОМЕСТИТЬ ТаблицаВЗапросе
|ИЗ
| &Товары КАК Товары
|
|ИНДЕКСИРОВАТЬ ПО
| Сумма
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТаблицаВЗапросе.НомерСтроки,
| ТаблицаВЗапросе.Номенклатура,
| ТаблицаВЗапросе.Сумма КАК Сумма
|ИЗ
| ТаблицаВЗапросе КАК ТаблицаВЗапросе
|ГДЕ
| НЕ ТаблицаВЗапросе.Номенклатура.ПодарочныйСертификат
|
|УПОРЯДОЧИТЬ ПО
| Сумма УБЫВ";
Запрос.УстановитьПараметр("Товары", Товары);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
СтрокаМаксимальнойСуммы = Товары[Выборка.НомерСтроки - 1]
Иначе
Возврат;
КонецЕсли;
Если ЗначениеОкругления >= СтрокаМаксимальнойСуммы.Сумма Тогда
Возврат;
КонецЕсли;
СтрокаМаксимальнойСуммы.Сумма = СтрокаМаксимальнойСуммы.Сумма - Округление;
СтрокаМаксимальнойСуммы.СуммаНДС = Ценообразование.РассчитатьСуммуНДС(СтрокаМаксимальнойСуммы.Сумма,
Истина,
Истина,
Ценообразование.ПолучитьСтавкуНДС(СтрокаМаксимальнойСуммы.СтавкаНДС));
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ОкруглитьСуммуЧека()
// <Описание функции>
//
// Параметры:
// СтрокаТабличнойЧасти - ссылка на строку табличной части
//
// Возвращаемое значение:
// Число - цена возврата
//
Функция НайтиЦенуВозврата(СтрокаТабличнойЧасти) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА ВложенныйЗапрос.Количество = 0
| ИЛИ &Коэффициент = 0
| ТОГДА 0
| ИНАЧЕ ВложенныйЗапрос.Сумма / ВложенныйЗапрос.Количество / &Коэффициент
| КОНЕЦ КАК Цена
|ИЗ
| (ВЫБРАТЬ
| СУММА(ЧекККМТовары.Сумма) КАК Сумма,
| СУММА(ВЫБОР
| КОГДА ЕСТЬNULL(ЧекККМТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1) = 0
| ТОГДА 0
| ИНАЧЕ ЧекККМТовары.Количество * ВЫБОР
| КОГДА ЧекККМТовары.Коэффициент = 0
| ТОГДА 1
| ИНАЧЕ ЧекККМТовары.Коэффициент
| КОНЕЦ / ЕСТЬNULL(ЧекККМТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)
| КОНЕЦ) КАК Количество
| ИЗ
| Документ.ЧекККМ.Товары КАК ЧекККМТовары
| ГДЕ
| ЧекККМТовары.Ссылка = &Ссылка
| И ЧекККМТовары.ХарактеристикаНоменклатуры = &ХарактеристикаНоменклатуры
| И ЧекККМТовары.Номенклатура = &Номенклатура
| И ЧекККМТовары.ПроцентСкидкиНаценки = &ПроцентСкидкиНаценки) КАК ВложенныйЗапрос";
Запрос.УстановитьПараметр("Ссылка" , ЧекККМПродажа);
КоэффициентВЗапрос = ?(СтрокаТабличнойЧасти.Коэффициент = 0, 1, СтрокаТабличнойЧасти.Коэффициент);
Запрос.УстановитьПараметр("Коэффициент" , КоэффициентВЗапрос);
Запрос.УстановитьПараметр("Номенклатура" , СтрокаТабличнойЧасти.Номенклатура);
Запрос.УстановитьПараметр("ХарактеристикаНоменклатуры", СтрокаТабличнойЧасти.ХарактеристикаНоменклатуры);
Запрос.УстановитьПараметр("ПроцентСкидкиНаценки" , СтрокаТабличнойЧасти.ПроцентСкидкиНаценки);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Цена;
Иначе
Возврат 0;
КонецЕсли;
КонецФункции // НайтиЦенуВозврата()
/////////////////////////////////////////////////////////////////////////////////
// ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ ОБЕСПЕЧЕНИЯ ПРОВЕДЕНИЯ ДОКУМЕНТА
// Проверяет правильность заполнения шапки документа.
//
// Параметры:
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа.
// Отказ - флаг отказа в проведении.
// Заголовок - заголовок сообщения об ошибках.
//
Процедура ПроверитьЗаполнениеШапки(СтруктураШапкиДокумента, Отказ, Заголовок)
// Укажем, что надо проверить.
СтруктураОбязательныхПолей = Новый Структура("КассаККМ" + ?(ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат, ", ЧекККМПродажа, ХозяйственнаяОперация", ""));
// Теперь вызовем общую процедуру проверки.
ТестированиеОбъектов.ПроверитьЗаполнениеШапкиДокумента(ЭтотОбъект, СтруктураОбязательныхПолей, Отказ, Заголовок);
Если СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Аннулированный Тогда
СтрокаСообщения = "Нельзя проводить аннулированный чек";
ОбщегоНазначения.ОшибкаПриПроведении(СтрокаСообщения, Отказ, Заголовок);
КонецЕсли;
КонецПроцедуры // ПроверитьЗаполнениеШапки()
// Проверяет правильность заполнения строк табличной части "Товары".
//
// Параметры:
// ТаблицаПоТоварам - таблица значений, содержащая данные для проведения и проверки ТЧ Товары.
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа.
// Отказ - флаг отказа в проведении.
// Заголовок - заголовок сообщения об ошибках.
//
Процедура ПроверитьЗаполнениеТабличнойЧастиТовары(ТаблицаПоТоварам, СтруктураШапкиДокумента, Отказ, Заголовок, Результат)
ИмяТабличнойЧасти = "Товары";
// Укажем, что надо проверить:
СтруктураОбязательныхПолей = Новый Структура("Номенклатура, ХарактеристикаНоменклатуры, Количество, Склад");
// Теперь позовем общую процедуру проверки.
ОбработкаТабличныхЧастей.ПроверитьЗаполнениеТабличнойЧасти(ЭтотОбъект, "Товары", СтруктураОбязательныхПолей, Отказ, Заголовок);
Если Не ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
// Корректирует состав "нулевых" полей
УправлениеЗапасами.ПроверитьЗаполнениеТабличнойЧастиПоТипамСкладов(ЭтотОбъект, "Товары", Отказ, Заголовок, Результат);
Если НЕ СтруктураОбязательныхПолей.Свойство("Цена") Тогда
УправлениеЗапасами.ПроверитьЦеныСертификатов(ЭтотОбъект, "Товары", Отказ, Заголовок);
КонецЕсли;
Иначе
// Здесь подарочных сертификатов быть не должно.
УправлениеЗапасами.ПроверитьЧтоНетПодарочныхСертификатов(ЭтотОбъект, "Товары", ТаблицаПоТоварам, Отказ, Заголовок);
КонецЕсли;
// Проверим заполнение полей "Единица измерения" и "Коэффициент" для позиций номенклатуры, не являющихся услугами
ОбработкаТабличныхЧастей.ПроверитьЗаполнениеПолейЕдиницаИзмеренияИКоэффициентДляТабличнойЧасти(ЭтотОбъект, "Товары", Отказ, Заголовок);
КонецПроцедуры // ПроверитьЗаполнениеТабличнойЧастиТовары()
// Проверяет правильность заполнения строк табличной части "СоставНабора".
//
// Параметры:
// ТаблицаПоКомплектам - таблица значений, содержащая данные для проведения и проверки ТЧ СоставНабора,
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа,
// Отказ - флаг отказа в проведении,
// Заголовок - строка, заголовок сообщения об ошибке проведения.
//
Процедура ПроверитьЗаполнениеТабличнойЧастиСоставНабора(ТаблицаПоКомплектам, СтруктураШапкиДокумента, Отказ, Заголовок, Результат)
// Проверить заполнение ТЧ "Состав набора".
СтруктураОбязательныхПолей = Новый Структура("Номенклатура, ХарактеристикаНоменклатуры, Количество, Склад, Цена");
// Теперь позовем общую процедуру проверки.
ОбработкаТабличныхЧастей.ПроверитьЗаполнениеТабличнойЧасти(ЭтотОбъект, "СоставНабора", СтруктураОбязательныхПолей, Отказ, Заголовок);
Если Не ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
// Корректирует состав "нулевых" полей
УправлениеЗапасами.ПроверитьЗаполнениеТабличнойЧастиПоТипамСкладов(ЭтотОбъект, "СоставНабора", Отказ, Заголовок, Результат);
КонецЕсли;
// Здесь услуг быть не должно.
УправлениеЗапасами.ПроверитьЧтоНетУслуг(ЭтотОбъект, "СоставНабора", ТаблицаПоКомплектам, Отказ, Заголовок);
// Здесь комплектов быть не должно.
УправлениеЗапасами.ПроверитьЧтоНетКомплектов(ЭтотОбъект, "СоставНабора", ТаблицаПоКомплектам, Отказ, Заголовок);
// Здесь подарочных сертификатов быть не должно.
УправлениеЗапасами.ПроверитьЧтоНетПодарочныхСертификатов(ЭтотОбъект, "СоставНабора", ТаблицаПоКомплектам, Отказ, Заголовок);
КонецПроцедуры // ПроверитьЗаполнениеТабличнойЧастиТовары()
// Получает развернутые строки расхождения по товарам при возврате
//
Функция ПолучитьСтрокиРасхожденияПоТоварамСЧекомПродажи(ТаблицаПоТоварам, ДанныеДокумента, РазрезАналитики = "Склад") Экспорт
СтрокиРасхождения = Новый ТаблицаЗначений;
Если ДанныеДокумента.ВидОперации <> Перечисления.ВидыОперацийЧекККМ.Возврат
ИЛИ ДанныеДокумента.ЧекККМПродажа.Пустая() Тогда
Возврат СтрокиРасхождения;
КонецЕсли;
ДокументОснование = ДанныеДокумента.ЧекККМПродажа;
Запрос = Новый Запрос;
ТаблицаПоТоварамЗапрос = ТаблицаПоТоварам.Скопировать();
ТаблицаПоТоварамЗапрос.Свернуть("Номенклатура, ХарактеристикаНоменклатуры, "+РазрезАналитики, "Количество");
Запрос.УстановитьПараметр("ТаблицаПоТоварам", ТаблицаПоТоварамЗапрос);
Запрос.Текст = "
|ВЫБРАТЬ
| ТаблицаПоТоварам.Номенклатура,
| ТаблицаПоТоварам.ХарактеристикаНоменклатуры,
| ТаблицаПоТоварам.Склад,
| ТаблицаПоТоварам.Количество КАК Количество
| ПОМЕСТИТЬ ЧекККМВозврат
|ИЗ
| &ТаблицаПоТоварам КАК ТаблицаПоТоварам;
|
|////////////////////////////////////////////////
|ВЫБРАТЬ
| ЕСТЬNULL(ЧекККМПродажа.Номенклатура, ЧекККМВозврат.Номенклатура) КАК Номенклатура,
| ЕСТЬNULL(ЧекККМПродажа.ХарактеристикаНоменклатуры, ЧекККМВозврат.ХарактеристикаНоменклатуры) КАК ХарактеристикаНоменклатуры,
| ЕСТЬNULL(ЧекККМПродажа.Номенклатура.ЕдиницаХраненияОстатков, ЧекККМВозврат.Номенклатура.ЕдиницаХраненияОстатков) КАК ЕдиницаХраненияОстатков,
| ЕСТЬNULL(ЧекККМПродажа.Склад, ЧекККМВозврат.Склад) КАК Склад,
| ЕСТЬNULL(ЧекККМВозврат.Количество, 0) КАК КолвоВозврат,
| ЕСТЬNULL(ЧекККМПродажа.Количество, 0) КАК КолвоПродаж,
| ВЫБОР
| КОГДА ЕСТЬNULL(ЧекККМВозврат.Количество, 0) - ЕСТЬNULL(ЧекККМПродажа.Количество, 0) <= 0
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК Отличаются
|ИЗ
|
| (ВЫБРАТЬ
| ЕСТЬNULL(ЧекККМТовары.ХарактеристикаНоменклатуры, ВозвращенныеТовары.ХарактеристикаНоменклатуры) КАК ХарактеристикаНоменклатуры,
| ЕСТЬNULL(ЧекККМТовары.Номенклатура, ВозвращенныеТовары.Номенклатура) КАК Номенклатура,
| ЕСТЬNULL(ЧекККМТовары.Склад, ВозвращенныеТовары.Склад) КАК Склад,
| СУММА(ВЫРАЗИТЬ(ЕСТЬNULL(ЧекККМТовары.Количество, 0) - ЕСТЬNULL(ВозвращенныеТовары.Количество, 0) КАК ЧИСЛО(15, 3))) КАК Количество
| ИЗ
| (ВЫБРАТЬ
| ЧекККМТовары.Номенклатура КАК Номенклатура,
| ЧекККМТовары.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ЧекККМТовары.Склад КАК Склад,
| ЧекККМТовары.Коэффициент КАК Коэффициент,
| СУММА(ЕСТЬNULL(ЧекККМТовары.Количество, 0) * ВЫБОР
| КОГДА ЕСТЬNULL(ЧекККМТовары.Коэффициент, 1) = 0
| ТОГДА 1
| ИНАЧЕ ЕСТЬNULL(ЧекККМТовары.Коэффициент, 1)
| КОНЕЦ / ЕСТЬNULL(ЧекККМТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)) КАК Количество
| ИЗ
| Документ.ЧекККМ.Товары КАК ЧекККМТовары
| ГДЕ
| ЧекККМТовары.Ссылка = &ДокументОснование
| СГРУППИРОВАТЬ ПО
| ЧекККМТовары.Номенклатура,
| ЧекККМТовары.ХарактеристикаНоменклатуры,
| ЧекККМТовары.Склад,
| ЧекККМТовары.Коэффициент) КАК ЧекККМТовары
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ЧекККМТовары.Номенклатура КАК Номенклатура,
| ЧекККМТовары.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ЧекККМТовары.Склад КАК Склад,
| СУММА(ЧекККМТовары.Количество * ВЫБОР
| КОГДА ЧекККМТовары.Коэффициент = 0
| ТОГДА 1
| ИНАЧЕ ЧекККМТовары.Коэффициент
| КОНЕЦ / ЕСТЬNULL(ЧекККМТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)) КАК Количество
| ИЗ
| Документ.ЧекККМ.Товары КАК ЧекККМТовары
| ГДЕ
| ЧекККМТовары.Ссылка В
| (ВЫБРАТЬ
| Документ.ЧекККМ.Ссылка
| ИЗ
| Документ.ЧекККМ
| ГДЕ
| Документ.ЧекККМ.ЧекККМПродажа = &ДокументОснование
| И (НЕ Документ.ЧекККМ.Ссылка = &ТекущийДокумент)
| И Документ.ЧекККМ.Проведен = ИСТИНА)
| СГРУППИРОВАТЬ ПО
| ЧекККМТовары.Номенклатура,
| ЧекККМТовары.ХарактеристикаНоменклатуры,
| ЧекККМТовары.Склад) КАК ВозвращенныеТовары
| ПО ЧекККМТовары.ХарактеристикаНоменклатуры = ВозвращенныеТовары.ХарактеристикаНоменклатуры
| И ЧекККМТовары.Склад = ВозвращенныеТовары.Склад
| И ЧекККМТовары.Номенклатура = ВозвращенныеТовары.Номенклатура
| СГРУППИРОВАТЬ ПО
| ЕСТЬNULL(ЧекККМТовары.ХарактеристикаНоменклатуры, ВозвращенныеТовары.ХарактеристикаНоменклатуры),
| ЕСТЬNULL(ЧекККМТовары.Номенклатура, ВозвращенныеТовары.Номенклатура),
| ЕСТЬNULL(ЧекККМТовары.Склад, ВозвращенныеТовары.Склад)) КАК ЧекККМПродажа
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ЧекККМВозврат.Номенклатура КАК Номенклатура,
| ЧекККМВозврат.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ЧекККМВозврат.Склад КАК Склад,
| СУММА(ВЫРАЗИТЬ(ЧекККМВозврат.Количество КАК ЧИСЛО(15, 3))) КАК Количество
| ИЗ
| ЧекККМВозврат КАК ЧекККМВозврат
|
| СГРУППИРОВАТЬ ПО
| ЧекККМВозврат.Номенклатура,
| ЧекККМВозврат.ХарактеристикаНоменклатуры,
| ЧекККМВозврат.Склад) КАК ЧекККМВозврат
| ПО ЧекККМПродажа.Номенклатура = ЧекККМВозврат.Номенклатура
| И ЧекККМПродажа.ХарактеристикаНоменклатуры = ЧекККМВозврат.ХарактеристикаНоменклатуры
| И ЧекККМПродажа.Склад = ЧекККМВозврат.Склад";
Запрос.УстановитьПараметр("ДокументОснование", ДокументОснование);
Запрос.УстановитьПараметр("ТекущийДокумент", Ссылка);
Запрос.Текст = СтрЗаменить(Запрос.Текст, "Склад", РазрезАналитики);
Результат = Запрос.Выполнить().Выгрузить();
СтрокиРасхождения = Результат.НайтиСтроки(Новый Структура("Отличаются", Истина));
Возврат СтрокиРасхождения;
КонецФункции
// Получает развернутые строки расхождения по оплате при возврате
//
Функция ПолучитьСтрокиРасхожденияПоОплатеСЧекомПродажи(ДанныеДокумента) Экспорт
СтрокиРасхождения = Новый ТаблицаЗначений;
Если ДанныеДокумента.ВидОперации <> Перечисления.ВидыОперацийЧекККМ.Возврат
ИЛИ ДанныеДокумента.ЧекККМПродажа.Пустая() Тогда
Возврат СтрокиРасхождения;
КонецЕсли;
ДокументОснование = ДанныеДокумента.ЧекККМПродажа;
ТаблицаОплат = Оплата.Выгрузить();
КолвоЭлементов = ТаблицаОплат.Количество();
Для ОбратныйИндекс = 1 По КолвоЭлементов Цикл
СтрокаТаблицыЗначений = ТаблицаОплат[КолвоЭлементов - ОбратныйИндекс];
Если Не ЗначениеЗаполнено(СтрокаТаблицыЗначений.ВидОплаты)
ИЛИ СтрокаТаблицыЗначений.ВидОплаты.ТипОплаты = Перечисления.ТипыОплатЧекаККМ.Наличные
ИЛИ СтрокаТаблицыЗначений.ВидОплаты = Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом Тогда
ТаблицаОплат.Удалить(СтрокаТаблицыЗначений);
КонецЕсли;
КонецЦикла;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст =
"ВЫБРАТЬ
| ТаблицаПоОплате.ВидОплаты,
| ТаблицаПоОплате.Сумма
| ПОМЕСТИТЬ ЧекККМВозврат
|ИЗ
| &ТаблицаПоОплате КАК ТаблицаПоОплате";
Запрос.УстановитьПараметр("ТаблицаПоОплате", ТаблицаОплат);
Запрос.Выполнить();
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(ЧекККМПродажа.ВидОплаты, ЧекККМВозврат.ВидОплаты) КАК ВидОплаты,
| ЕСТЬNULL(ЧекККМВозврат.Сумма, 0) КАК СуммаВозврат,
| ЕСТЬNULL(ЧекККМПродажа.Сумма, 0) КАК СуммаПродаж,
| ВЫБОР
| КОГДА ЕСТЬNULL(ЧекККМВозврат.Сумма, 0) - ЕСТЬNULL(ЧекККМПродажа.Сумма, 0) = 0
| ТОГДА ЛОЖЬ
| ИНАЧЕ ИСТИНА
| КОНЕЦ КАК Отличаются
|ИЗ
| (ВЫБРАТЬ
| ЧекККМОплата.ВидОплаты КАК ВидОплаты,
| СУММА(ЧекККМОплата.Сумма) КАК Сумма
| ИЗ
| Документ.ЧекККМ.Оплата КАК ЧекККМОплата
| ГДЕ
| ЧекККМОплата.Ссылка = &ДокументОснование
| И ЧекККМОплата.ВидОплаты.ТипОплаты <> ЗНАЧЕНИЕ(Перечисление.ТипыОплатЧекаККМ.Наличные)
| И (НЕ ЧекККМОплата.ВидОплаты = ЗНАЧЕНИЕ(Справочник.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом))
|
| СГРУППИРОВАТЬ ПО
| ЧекККМОплата.ВидОплаты) КАК ЧекККМПродажа
| ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
| ЧекККМВозврат.ВидОплаты КАК ВидОплаты,
| СУММА(ЧекККМВозврат.Сумма) КАК Сумма
| ИЗ
| ЧекККМВозврат КАК ЧекККМВозврат
|
| СГРУППИРОВАТЬ ПО
| ЧекККМВозврат.ВидОплаты) КАК ЧекККМВозврат
| ПО ЧекККМПродажа.ВидОплаты = ЧекККМВозврат.ВидОплаты";
Запрос.УстановитьПараметр("ДокументОснование", ДокументОснование);
Результат = Запрос.Выполнить().Выгрузить();
СтрокиРасхождения = Результат.НайтиСтроки(Новый Структура("Отличаются", Истина));
Возврат СтрокиРасхождения;
КонецФункции
// Проверяет правильность заполнения строк табличной части "Оплата".
//
// Параметры:
// ТаблицаПоОплате - таблица значений, содержащая данные для проведения и проверки ТЧ Оплата.
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа.
// Отказ - флаг отказа в проведении.
// Заголовок - заголовок сообщения об ошибках.
//
Процедура ПроверитьЗаполнениеТабличнойЧастиОплата(ТаблицаПоОплате, СтруктураШапкиДокумента, Отказ, Заголовок)
СуммаВсего = Товары.Итог("Сумма");
ОплаченоНал = ПолучитьСуммуНаличнойОплаты();
ОплаченоБезнал = ПолучитьСуммуБезналичнойОплаты();
ОплаченоВсего = Оплата.Итог("Сумма");
Если ОплаченоВсего < СуммаВсего Тогда
ОбщегоНазначения.СообщитьОбОшибке("Сумма всех типов оплат меньше суммы документа!", Отказ, Заголовок);
КонецЕсли;
Если ОплаченоБезнал > СуммаВсего Тогда
ОбщегоНазначения.СообщитьОбОшибке("Сумма безналичной оплаты не может быть больше суммы документа!", Отказ, Заголовок);
КонецЕсли;
Если ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
Если Не Оплата.Найти(Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом, "ВидОплаты") = Неопределено Тогда
ОбщегоНазначения.СообщитьОбОшибке("Чек возврата не оплачивается подарочным сертификатом", Отказ, Заголовок);
КонецЕсли;
КонецЕсли;
// Укажем, что надо проверить.
СтруктураОбязательныхПолей = Новый Структура("ВидОплаты, Сумма");
Если Не Отказ Тогда
ОбработкаТабличныхЧастей.ПроверитьЗаполнениеТабличнойЧасти(ЭтотОбъект, "Оплата", СтруктураОбязательныхПолей, Отказ, Заголовок);
КонецЕсли;
КонецПроцедуры // ПроверитьЗаполнениеТабличнойЧастиОплата()
// Процедура проверяет возможность возврата товаров
//
Процедура ПроверитьВозможностьПроведенияЧекаВозврата(ТаблицаПоТоварам, ТаблицаПоОплате, СтруктураШапкиДокумента, Отказ, Результат);
//Проверка на возможность возврата товаров по остаткам.
СтрокиРасхождения = ПолучитьСтрокиРасхожденияПоТоварамСЧекомПродажи(ТаблицаПоТоварам, СтруктураШапкиДокумента);
Для Каждого СтрокаРасхождения Из СтрокиРасхождения Цикл
Результат = Результат
+ Строка(СтрокаРасхождения.Номенклатура) + УниверсальныеМеханизмы.ПредставлениеХарактеристик(СтрокаРасхождения)
+ " попытка вернуть на склад """ + Строка(СтрокаРасхождения.Склад)+ """: "
+ Строка(СтрокаРасхождения.КолвоВозврат) + " "
+ Строка(СтрокаРасхождения.ЕдиницаХраненияОстатков)
+ ", продано по чеку: " + Строка(СтрокаРасхождения.КолвоПродаж) + " "
+ Строка(СтрокаРасхождения.ЕдиницаХраненияОстатков)
+ Символы.ПС;
Отказ = Истина;
КонецЦикла;
//Проверка на возможность возврата товаров по продавцам.
РезультатПродавцы = "";
СтрокиРасхожденияПродавцы = ПолучитьСтрокиРасхожденияПоТоварамСЧекомПродажи(ТаблицаПоТоварам, СтруктураШапкиДокумента, "Продавец");
Для Каждого СтрокаРасхожденияПродавцы Из СтрокиРасхожденияПродавцы Цикл
РезультатПродавцы = РезультатПродавцы
+ Строка(СтрокаРасхожденияПродавцы.Номенклатура) + УниверсальныеМеханизмы.ПредставлениеХарактеристик(СтрокаРасхожденияПродавцы)
+ " попытка оформить возврат на продавца """ + Строка(СтрокаРасхожденияПродавцы.Продавец) + """: "
+ Строка(СтрокаРасхожденияПродавцы.КолвоВозврат) + " "
+ Строка(СтрокаРасхожденияПродавцы.ЕдиницаХраненияОстатков)
+ ", было продано продавцом: " + Строка(СтрокаРасхожденияПродавцы.КолвоПродаж) + " "
+ Строка(СтрокаРасхожденияПродавцы.ЕдиницаХраненияОстатков)
+ Символы.ПС;
Отказ = Истина;
КонецЦикла;
//Проверка на возможность возврата товаров по оплате.
СтрокиРасхожденияОплата = ПолучитьСтрокиРасхожденияПоОплатеСЧекомПродажи(СтруктураШапкиДокумента);
РезультатОплата = "";
Для Каждого СтрокаРасхожденияОплата Из СтрокиРасхожденияОплата Цикл
РезультатОплата = РезультатОплата
+ Строка(СтрокаРасхожденияОплата.ВидОплаты)
+ " попытка вернуть: " + ОбщегоНазначения.ФорматСумм(СтрокаРасхожденияОплата.СуммаВозврат,,"0")
+ ", оплачено по чеку: " + ОбщегоНазначения.ФорматСумм(СтрокаРасхожденияОплата.СуммаПродаж,,"0") + Символы.ПС;
Отказ = Истина;
КонецЦикла;
Результат = Результат + РезультатПродавцы + РезультатОплата;
КонецПроцедуры
// По результату запроса по шапке документа формируем движения по регистрам.
//
// Параметры:
// РежимПроведения - режим проведения документа (оперативный или неоперативный),
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа,
// ТаблицаПоТоварам - таблица значений, содержащая данные для проведения и проверки ТЧ Товары
// ТаблицаСерийныхНомеров - таблица значений для проведения сертификатов
// ТаблицаПодарочныхСертификатовПогашения - таблица значений для проведения погашения
// Отказ - флаг отказа в проведении,
// Заголовок - строка, заголовок сообщения об ошибке проведения.
//
Процедура ДвиженияПоРегистрам(РежимПроведения, СтруктураШапкиДокумента, ТаблицаПоТоварам, ТаблицаПоКомплектам, ТаблицаПоТоварамБезУслугБезКомплектов,
ТаблицаПоОплате, ТаблицаПодарки, ТаблицаСерийныхНомеров, ТаблицаПодарочныхСертификатовПогашения, Отказ, Заголовок);
Если Отказ тогда
Возврат;
КонецЕсли;
Если СтруктураШапкиДокумента.ВидОперации <> Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
Если Не ПроцедурыОбменаДаннымиПоКассе.ЭтоУзелКассы() Тогда
// ТОВАРЫ НА СКЛАДАХ
НаборДвижений = Движения.ТоварыНаСкладах;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоТоварамБезУслугБезКомплектов, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьРасход();
// ТОВАРЫ НА СКЛАДАХ для комплектующих
НаборДвижений = Движения.ТоварыНаСкладах;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоКомплектам, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьРасход();
// ПРОДАЖИ
НаборДвижений = Движения.Продажи;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.Выгрузить();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоТоварам, ТаблицаДвижений);
ТаблицаДвижений.ЗаполнитьЗначения(Ссылка,"ДокументПродажи");
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьДвижения();
//ПОДАРКИ
НаборДвижений = Движения.ТоварыНаСкладах;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПодарки, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьРасход();
КонецЕсли;
Если ЗначениеЗаполнено(СтруктураШапкиДокумента.СуммаНаличными) Тогда
//По "Денежные Средства"
НаборДвиженийОстатки = Движения.ДенежныеСредства;
ТаблицаДвиженийОстатки = НаборДвиженийОстатки.Выгрузить();
СтрокаДвиженийОстатки = ТаблицаДвиженийОстатки.Добавить();
СтрокаДвиженийОстатки.Касса = СтруктураШапкиДокумента.КассаККМ;
СтрокаДвиженийОстатки.Сумма = СтруктураШапкиДокумента.СуммаНаличными;
НаборДвиженийОстатки.мПериод = Дата;
НаборДвиженийОстатки.мТаблицаДвижений = ТаблицаДвиженийОстатки;
Движения.ДенежныеСредства.ВыполнитьПриход();
КонецЕсли;
//По Дисконтным картам
Если Не СтруктураШапкиДокумента.ДисконтнаяКарта.Пустая() Тогда
НаборДвижений = Движения.ПродажиПоДисконтнымКартам;
ТаблицаДвижений = НаборДвижений.Выгрузить();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоТоварам, ТаблицаДвижений);
ТаблицаДвижений.ЗаполнитьЗначения(СтруктураШапкиДокумента.ДисконтнаяКарта , "ДисконтнаяКарта");
ТаблицаДвижений.ЗаполнитьЗначения(СтруктураШапкиДокумента.ВладелецДисконтнойКарты, "ВладелецДисконтнойКарты");
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьДвижения();
КонецЕсли;
//По платежным картам
Если Не ТаблицаПоОплате.Количество() = 0 Тогда
НаборДвижений = Движения.ПродажиПоПлатежнымКартам;
ТаблицаДвижений = НаборДвижений.Выгрузить();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоОплате, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьДвижения();
КонецЕсли;
Если НЕ ТаблицаСерийныхНомеров.Количество() = 0 ИЛИ НЕ ТаблицаПодарочныхСертификатовПогашения.Количество() = 0 Тогда
//Сертификаты
НаборДвижений = Движения.ДвиженияСерийныхНомеров;
ТаблицаДвижений = НаборДвижений.Выгрузить();
ТаблицаСерийныхНомеров.Колонки.Склад.Имя = "Отправитель";
// Заполним таблицу движений.
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаСерийныхНомеров, ТаблицаДвижений);
ТаблицаДвижений.ЗаполнитьЗначения(Справочники.ХозяйственныеОперации.РеализацияТоваров, "ХозяйственнаяОперация");
ТаблицаПодарочныхСертификатовПогашения.Колонки.ПодарочныйСертификат.Имя = "Номенклатура";
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПодарочныхСертификатовПогашения, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
Если Не Отказ Тогда
Движения.ДвиженияСерийныхНомеров.ВыполнитьДвижения();
КонецЕсли;
КонецЕсли;
Иначе
Если Не ПроцедурыОбменаДаннымиПоКассе.ЭтоУзелКассы() Тогда
// ТОВАРЫ НА СКЛАДАХ
НаборДвижений = Движения.ТоварыНаСкладах;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоТоварамБезУслугБезКомплектов, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьПриход();
// ТОВАРЫ НА СКЛАДАХ для комплектующих
НаборДвижений = Движения.ТоварыНаСкладах;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоКомплектам, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьПриход();
// ПРОДАЖИ
НаборДвижений = Движения.Продажи;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.Выгрузить();
ТаблицаПотоварам.Колонки.Удалить("Стоимость");
ТаблицаПотоварам.Колонки.Удалить("СтоимостьБезСкидок");
ТаблицаПотоварам.Колонки.Удалить("Количество");
ТаблицаПотоварам.Колонки.Удалить("НДС");
ТаблицаПоТоварам.Колонки.Удалить("Сумма");
ТаблицаПоТоварам.Колонки.СтоимостьМинус.Имя = "Стоимость";
ТаблицаПоТоварам.Колонки.СтоимостьБезСкидокМинус.Имя = "СтоимостьБезСкидок";
ТаблицаПоТоварам.Колонки.КоличествоМинус.Имя = "Количество";
ТаблицаПоТоварам.Колонки.НДСМинус.Имя = "НДС";
ТаблицаПоТоварам.Колонки.СуммаМинус.Имя = "Сумма";
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоТоварам, ТаблицаДвижений);
ТаблицаДвижений.ЗаполнитьЗначения(Ссылка,"ДокументПродажи");
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьДвижения();
//ПОДАРКИ
НаборДвижений = Движения.ТоварыНаСкладах;
// Получим таблицу значений, совпадающую со структурой набора записей регистра.
ТаблицаДвижений = НаборДвижений.ВыгрузитьКолонки();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПодарки, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьПриход();
Иначе
ТаблицаПотоварам.Колонки.Удалить("Стоимость");
ТаблицаПотоварам.Колонки.Удалить("СтоимостьБезСкидок");
ТаблицаПотоварам.Колонки.Удалить("Количество");
ТаблицаПотоварам.Колонки.Удалить("НДС");
ТаблицаПоТоварам.Колонки.Удалить("Сумма");
ТаблицаПоТоварам.Колонки.СтоимостьМинус.Имя = "Стоимость";
ТаблицаПоТоварам.Колонки.СтоимостьБезСкидокМинус.Имя = "СтоимостьБезСкидок";
ТаблицаПоТоварам.Колонки.КоличествоМинус.Имя = "Количество";
ТаблицаПоТоварам.Колонки.НДСМинус.Имя = "НДС";
ТаблицаПоТоварам.Колонки.СуммаМинус.Имя = "Сумма";
КонецЕсли;
Если ЗначениеЗаполнено(СтруктураШапкиДокумента.СуммаНаличными) Тогда
//По "Денежные Средства"
НаборДвиженийОстатки = Движения.ДенежныеСредства;
ТаблицаДвиженийОстатки = НаборДвиженийОстатки.Выгрузить();
СтрокаДвиженийОстатки = ТаблицаДвиженийОстатки.Добавить();
СтрокаДвиженийОстатки.Касса = СтруктураШапкиДокумента.КассаККМ;
СтрокаДвиженийОстатки.Сумма = СтруктураШапкиДокумента.СуммаНаличными;
НаборДвиженийОстатки.мПериод = Дата;
НаборДвиженийОстатки.мТаблицаДвижений = ТаблицаДвиженийОстатки;
Движения.ДенежныеСредства.ВыполнитьРасход();
КонецЕсли;
//По Дисконтным картам
Если Не СтруктураШапкиДокумента.ДисконтнаяКарта.Пустая() Тогда
НаборДвижений = Движения.ПродажиПоДисконтнымКартам;
ТаблицаДвижений = НаборДвижений.Выгрузить();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоТоварам, ТаблицаДвижений);
ТаблицаДвижений.ЗаполнитьЗначения(СтруктураШапкиДокумента.ДисконтнаяКарта , "ДисконтнаяКарта");
ТаблицаДвижений.ЗаполнитьЗначения(СтруктураШапкиДокумента.ВладелецДисконтнойКарты, "ВладелецДисконтнойКарты");
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьДвижения();
КонецЕсли;
//По платежным картам
Если Не ТаблицаПоОплате.Количество() = 0 Тогда
НаборДвижений = Движения.ПродажиПоПлатежнымКартам;
ТаблицаДвижений = НаборДвижений.Выгрузить();
ТаблицаПоОплате.Колонки.Удалить("Сумма");
ТаблицаПоОплате.Колонки.СуммаМинус.Имя = "Сумма";
ТаблицаПоОплате.Колонки.Удалить("СуммаТорговойУступки");
Если СтруктураШапкиДокумента.ДоговорЭквайринга.ЭквайрерВозвращаетКомиссиюПриВозврате Тогда
ТаблицаПоОплате.Колонки.СуммаТорговойУступкиМинус.Имя = "СуммаТорговойУступки";
КонецЕсли;
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоОплате, ТаблицаДвижений);
НаборДвижений.мПериод = Дата;
НаборДвижений.мТаблицаДвижений = ТаблицаДвижений;
НаборДвижений.ВыполнитьДвижения();
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ДвиженияПоРегистрам()
// Проверяет доступный остаток товаров по складу
//
Процедура ПроверитьОстаткиТоваров(Дата, РежимПроведения, ТаблицаПоТоварамБезУслугБезКомплектов, ТаблицаПоКомплектам, Отказ, Заголовок, Результат) Экспорт
Если (РежимРМК И Не КонтролироватьОстаткиТоваровПриЗакрытииЧека)
ИЛИ ПроцедурыОбменаДаннымиПоКассе.ЭтоУзелКассы() Тогда
Возврат;
КонецЕсли;
ТаблицаОбщаяДляПроверкиОстатков = ТаблицаПоТоварамБезУслугБезКомплектов.Скопировать();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПоКомплектам, ТаблицаОбщаяДляПроверкиОстатков);
УправлениеЗапасами.ПроверитьОстаткиПоСкладам(Дата, РежимПроведения, ТаблицаОбщаяДляПроверкиОстатков, Отказ, Заголовок, Результат);
УправлениеЗапасами.ПроверитьОстаткиСерийныхНомеров(ЭтотОбъект, ТаблицаПоТоварамБезУслугБезКомплектов, "СерийныеНомера", РежимПроведения, Отказ, Заголовок, Результат, ,Дата);
КонецПроцедуры
// Процедура добавляет необходимые поля в таблицу по товарам.
//
Процедура ПодготовитьТаблицуТоваров(ТаблицаТоваров, СтруктураШапкиДокумента)
ТаблицаТоваров.Колонки.Добавить("Стоимость" , ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,2));
ТаблицаТоваров.Колонки.Добавить("СтоимостьБезСкидок", ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,2));
ТаблицаТоваров.Колонки.Добавить("СтоимостьМинус" , ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,2));
ТаблицаТоваров.Колонки.Добавить("СтоимостьБезСкидокМинус", ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,2));
ТаблицаТоваров.Колонки.Добавить("СуммаМинус", ОбщегоНазначения.ПолучитьОписаниеТиповЧисла(15,2));
Для Каждого СтрокаТаблицы Из ТаблицаТоваров Цикл
СтрокаТаблицы.Стоимость = СтрокаТаблицы.Сумма;
СтрокаТаблицы.СтоимостьБезСкидок = СтрокаТаблицы.Цена * СтрокаТаблицы.КоличествоТЧ;
СтрокаТаблицы.СтоимостьМинус = - СтрокаТаблицы.Стоимость;
СтрокаТаблицы.СтоимостьБезСкидокМинус = - СтрокаТаблицы.СтоимостьБезСкидок;
СтрокаТаблицы.СуммаМинус = - СтрокаТаблицы.Сумма;
КонецЦикла;
КонецПроцедуры
// Проверяет правильность заполнения строк табличной части "Подарки".
//
// Параметры:
// ТаблицаПодарки - таблица значений, содержащая данные для проведения и проверки ТЧ Подарки.
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа.
// Отказ - флаг отказа в проведении.
// Заголовок - заголовок сообщения об ошибках.
//
Процедура ПроверитьЗаполнениеТабличнойЧастиПодарки(ТаблицаПодарки, СтруктураШапкиДокумента, Отказ, Заголовок)
ИмяТабличнойЧасти = "Подарки";
// Укажем, что надо проверить:
СтруктураОбязательныхПолей = Новый Структура("Номенклатура, ХарактеристикаНоменклатуры, Количество, Склад");
// Теперь позовем общую процедуру проверки.
ОбработкаТабличныхЧастей.ПроверитьЗаполнениеТабличнойЧасти(ЭтотОбъект, "Подарки", СтруктураОбязательныхПолей, Отказ, Заголовок);
//Подарочных сертификатов здесь быть не должно
УправлениеЗапасами.ПроверитьЧтоНетПодарочныхСертификатов(ЭтотОбъект, "Подарки", , Отказ, Заголовок);
КонецПроцедуры // ПроверитьЗаполнениеТабличнойЧастиТовары()
// Подготавливает таблицу погашения
//
// Параметры
// Нет
//
// Возвращаемое значение:
// <Тип.Вид> - <описание возвращаемого значения>
//
Функция ПодготовитьТаблицуПогашения() Экспорт
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ТаблицаПогашения.НомерСтроки,
| ТаблицаПогашения.ПодарочныйСертификат,
| ТаблицаПогашения.СерийныйНомер
|ПОМЕСТИТЬ ТаблицаВЗапросе
|ИЗ
| &ТаблицаПогашения КАК ТаблицаПогашения
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТаблицаВЗапросе.НомерСтроки,
| ТаблицаВЗапросе.ПодарочныйСертификат.ПодарочныйСертификат КАК НоменклатураПодарочныйСертификат,
| ТаблицаВЗапросе.ПодарочныйСертификат.ВестиСерийныеНомера КАК НоменклатураВестиСерийныеНомера,
| ТаблицаВЗапросе.ПодарочныйСертификат,
| ТаблицаВЗапросе.СерийныйНомер,
| ЗНАЧЕНИЕ(Справочник.ХозяйственныеОперации.ПогашениеПодарочныхСертификатов) КАК ХозяйственнаяОперация,
| 1 КАК Количество,
| &Склад КАК Получатель
|ИЗ
| ТаблицаВЗапросе КАК ТаблицаВЗапросе";
Запрос.УстановитьПараметр("ТаблицаПогашения", ПогашениеПодарочныхСертификатов.Выгрузить());
Запрос.УстановитьПараметр("Склад", Магазин.ОсновнойСклад);
Результат = Запрос.Выполнить();
ТаблицаЗапроса = Результат.Выгрузить();
Возврат ТаблицаЗапроса;
КонецФункции // ПодготовитьТаблицуПогашения()
// Проверяет правильность заполнения строк табличной части "ПогашениеПодарочныхСертификатов".
//
// Параметры:
// ТаблицаПогашения - таблица значений, содержащая данные для проведения и проверки ТЧ ПогашениеПодарочныхСертификатов,
// СтруктураШапкиДокумента - выборка из результата запроса по шапке документа,
// Отказ - флаг отказа в проведении,
// Заголовок - строка, заголовок сообщения об ошибке проведения.
//
Процедура ПроверитьЗаполнениеТабличнойЧастиПогашения(ТаблицаПогашения, СтруктураШапкиДокумента, Отказ, Заголовок) Экспорт
// Проверить заполнение ТЧ "Состав набора".
СтруктураОбязательныхПолей = Новый Структура("ПодарочныйСертификат");
ОбработкаТабличныхЧастей.ПроверитьЗаполнениеТабличнойЧасти(ЭтотОбъект, "ПогашениеПодарочныхСертификатов", СтруктураОбязательныхПолей, Отказ, Заголовок);
Если Не Отказ Тогда
СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("НоменклатураВестиСерийныеНомера", Истина);
СтруктураПоиска.Вставить("СерийныйНомер", Справочники.СерийныеНомера.ПустаяСсылка());
МассивСтрок = ТаблицаПогашения.НайтиСтроки(СтруктураПоиска);
Для каждого СтрокаТаблицыПогашения Из МассивСтрок Цикл
СтрокаНачалаСообщенияОбОшибке = "В строке номер """+ СокрЛП(СтрокаТаблицыПогашения.НомерСтроки) +
""" табличной части ""Погашение подарочных сертификатов"": ";
СтрокаСообщения = " не заполнен серийный номер сертификата";
ОбщегоНазначения.СообщитьОбОшибке(СтрокаНачалаСообщенияОбОшибке + СтрокаСообщения, Отказ, Заголовок);
КонецЦикла;
Если Не Отказ Тогда
СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("НоменклатураПодарочныйСертификат", Ложь);
МассивСтрок = ТаблицаПогашения.НайтиСтроки(СтруктураПоиска);
Для каждого СтрокаТаблицыПогашения Из МассивСтрок Цикл
СтрокаНачалаСообщенияОбОшибке = "В строке номер """+ СокрЛП(СтрокаТаблицыПогашения.НомерСтроки) +
""" табличной части ""Погашение подарочных сертификатов"": ";
СтрокаСообщения = " выбранная номенклатура не является подарочным сертификатом ";
ОбщегоНазначения.СообщитьОбОшибке(СтрокаНачалаСообщенияОбОшибке + СтрокаСообщения, Отказ, Заголовок);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецПроцедуры // ПроверитьЗаполнениеТабличнойЧастиПогашения()
////////////////////////////////////////////////////////////////////////////////
// ОБРАБОТЧИКИ СОБЫТИЙ
// Процедура - обработчик события "ПередЗаписью".
//
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
мЗакрытиеСмены = (Не ЗначениеЗаполнено(Ссылка.ОтчетОРозничныхПродажах)
И ЗначениеЗаполнено(ОтчетОРозничныхПродажах));
Если ОбменДанными.Загрузка
ИЛИ РольДоступна("ПолныеПрава") Тогда
Возврат;
КонецЕсли;
Если Не РежимРМК
И Ссылка.СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Отложенный Тогда
СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.ПустаяСсылка();
КонецЕсли;
Если (Ссылка.СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Пробитый
И Не мЗакрытиеСмены)
ИЛИ Ссылка.СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Архивный
ИЛИ Ссылка.СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Аннулированный Тогда
ОбщегоНазначения.СообщитьОбОшибке("Чек ККМ имеет статус """ + СтатусЧекаККМ +""". Операции над этим документом запрещены!", Отказ, СокрЛП(ЭтотОбъект));
КонецЕсли;
КонецПроцедуры
// Процедура - обработчик события "ОбработкаЗаполнения".
//
Процедура ОбработкаЗаполнения(Основание)
Если ТипЗнч(Основание) = Тип("ДокументСсылка.ЧекККМ") Тогда
ОбработкаТабличныхЧастей.ЗаполнитьТабЧастьНаОсновании(ЭтотОбъект, Основание);
ЗаполнитьЗначенияСвойств(ЭтотОбъект, Основание, "ВладелецДисконтнойКарты, ДисконтнаяКарта, КассаККМ, СуммаДокумента, Магазин, ДоговорЭквайринга, Продавец");
ЧекККМПродажа = Основание;
ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат;
ДисконтнаяКарта = Основание.ДисконтнаяКарта;
ВладелецДисконтнойКарты = Основание.ВладелецДисконтнойКарты;
СерийныеНомера.Очистить();
ПогашениеПодарочныхСертификатов.Очистить();
УправлениеЗапасами.УдалитьПодарочныеСертификаты(Товары);
КолвоЭлементовКоллекции = Оплата.Количество();
Для ОбратныйИндекс = 1 По КолвоЭлементовКоллекции Цикл
ЭлементКоллекции = Оплата[КолвоЭлементовКоллекции - ОбратныйИндекс];
Если ЭлементКоллекции.ВидОплаты = Справочники.ВидыОплатЧекаККМ.ОплатаПодарочнымСертификатом Тогда
Оплата.Удалить(ЭлементКоллекции);
КонецЕсли;
КонецЦикла;
ИначеЕсли ТипЗнч(Основание) = Тип("ДокументСсылка.ОприходованиеТоваров") Тогда
ОбработкаТабличныхЧастей.ЗаполнитьТабЧастьНаОсновании(ЭтотОбъект, Основание);
Для Каждого ТекСтрокаТовары Из Товары Цикл
ТекСтрокаТовары.Склад = Основание.Склад;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
// Процедура - обработчик события "ОбработкаПроведения".
//
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Если мЗакрытиеСмены Тогда
Возврат;
КонецЕсли;
Результат = "";
СтруктураШапкиДокумента = УправлениеЗапасами.СформироватьСтруктуруШапкиДокумента(ЭтотОбъект);
// Заголовок для сообщений об ошибках проведения.
Заголовок = ОбщегоНазначения.ПредставлениеДокументаПриПроведении(СтруктураШапкиДокумента);
СуммаНаличными = Макс(0, СуммаДокумента - ПолучитьСуммуБезналичнойОплаты() - ПолучитьСуммуОплатыПодарочнымиСертификатами());
СтруктураШапкиДокумента.Вставить("СуммаНаличными", СуммаНаличными);
ПроверитьЗаполнениеШапки(СтруктураШапкиДокумента, Отказ, Заголовок);
//Формирует структуру для подстановки в цикл формирования запроса
СтруктураПолей = УправлениеЗапасами.СформироватьСтруктуруПолейТабличнойЧасти(ЭтотОбъект, "Товары");
СтруктураПолей.Количество =
"Количество *
| ВЫБОР
| КОГДА ЕдиницаИзмерения = ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)
| ТОГДА 1
| ИНАЧЕ
| Коэффициент /ЕСТЬNULL(Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)
| КОНЕЦ
|";
СтруктураПолей.Вставить("НДС", "СуммаНДС");
СтруктураПолей.Вставить("Магазин", "Склад.Магазин");
СтруктураПолей.Вставить("ТипСклада", "Склад.ТипСклада");
СтруктураПолей.Вставить("Организация", "Склад.Организация");
СтруктураПолей.Вставить("КоличествоТЧ", "Количество");
//для возврата
СтруктураПолей.Вставить("Услуга" , "Номенклатура.Услуга");
СтруктураПолей.Вставить("НДСМинус", "СуммаНДС * -1");
СтруктураПолей.Вставить("Комплект", "Номенклатура.Комплект");
СтруктураПолей.Вставить("КоличествоМинус", "Количество * -1 *
| ВЫБОР
| КОГДА ЕдиницаИзмерения = ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)
| ТОГДА 1
| ИНАЧЕ
| Коэффициент /ЕСТЬNULL(Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)
| КОНЕЦ
|");
СтруктураСложныхПолей = Новый Структура;
Если ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
СтруктураПолей.Вставить("ХозяйственнаяОперация", "Ссылка.ХозяйственнаяОперация");
Иначе
СтруктураСложныхПолей.Вставить("ХозяйственнаяОперация", "ЗНАЧЕНИЕ(Справочник.ХозяйственныеОперации.РеализацияТоваров)");
КонецЕсли;
//Формирует список дополнительных условий запроса
СписокУсловийЗапроса = Новый СписокЗначений;
СписокУсловийЗапроса.Добавить(Перечисления.ТипыСкладов.СкладЦентральногоОфиса, "Склад.ТипСклада", Ложь);
РезультатЗапросаПоТоварам = УправлениеЗапасами.СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "Товары", СтруктураПолей, СтруктураСложныхПолей, СписокУсловийЗапроса);
ТаблицаПоТоварам = РезультатЗапросаПоТоварам.Выгрузить();
ПодготовитьТаблицуТоваров(ТаблицаПоТоварам, СтруктураШапкиДокумента);
//получим таблицу комплектующих
ТаблицаПоКомплектам = УправлениеЗапасами.СформироватьТаблицуКомплектующих(ТаблицаПоТоварам, ЭтотОбъект, СтруктураШапкиДокумента);
ТаблицаПоТоварамБезУслугБезКомплектов = УправлениеЗапасами.УдалитьУслугиКомплектыИзТаблицыТоваров(ТаблицаПоТоварам);
ПроверитьЗаполнениеТабличнойЧастиТовары(ТаблицаПоТоварам, СтруктураШапкиДокумента, Отказ, Заголовок, Результат);
ПроверитьЗаполнениеТабличнойЧастиСоставНабора(ТаблицаПоКомплектам, СтруктураШапкиДокумента, Отказ, Заголовок, Результат);
//Оплата
СтруктураПолейОплата = Новый Структура;
СтруктураПолейОплата.Вставить("СуммаМинус", "Сумма * -1");
СтруктураПолейОплата.Вставить("СуммаТорговойУступкиМинус", "СуммаТорговойУступки * -1");
СтруктураПолейОплата.Вставить("ДоговорЭквайринга", "Ссылка.ДоговорЭквайринга");
СтруктураПолейОплата.Вставить("Магазин", "Ссылка.Магазин");
РезультатЗапросаПоОплате = Эквайринг.СформироватьЗапросПоОплате(ЭтотОбъект, "Оплата", СтруктураПолейОплата);
ТаблицаПоОплате = РезультатЗапросаПоОплате.Выгрузить();
ПроверитьЗаполнениеТабличнойЧастиОплата(ТаблицаПоОплате, СтруктураШапкиДокумента, Отказ, Заголовок);
// Подарки
СтруктураПолейПодарки = УправлениеЗапасами.СформироватьСтруктуруПолейТабличнойЧасти(ЭтотОбъект, "Подарки");
СтруктураПолейПодарки.Вставить("Магазин" ,"Ссылка.КассаККМ.Магазин");
СтруктураПолейПодарки.Вставить("ЕдиницаИзмерения","Номенклатура.ЕдиницаХраненияОстатков");
СтруктураПолейПодарки.Количество =
"Количество *
| ВЫБОР
| КОГДА ЕдиницаИзмерения = ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)
| ТОГДА 1
| ИНАЧЕ
| Коэффициент /ЕСТЬNULL(Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)
| КОНЕЦ
|";
СтруктураПолейПодарки.Вставить("КоличествоМинус","Количество * -1 *
| ВЫБОР
| КОГДА ЕдиницаИзмерения = ЗНАЧЕНИЕ(Справочник.ЕдиницыИзмерения.ПустаяСсылка)
| ТОГДА 1
| ИНАЧЕ
| Коэффициент /ЕСТЬNULL(Номенклатура.ЕдиницаХраненияОстатков.Коэффициент, 1)
| КОНЕЦ
|");
СписокУсловийПодарки = Новый СписокЗначений;
СписокУсловийПодарки.Добавить(Перечисления.ТипыСкладов.СкладЦентральногоОфиса, "Склад.ТипСклада", Ложь);
СтруктураСложныхПолей = Новый Структура;
СтруктураСложныхПолей.Вставить("ХозяйственнаяОперация", "ЗНАЧЕНИЕ(Справочник.ХозяйственныеОперации.СкидкиПодарки)");
РезультатЗапросаПодарки = УправлениеЗапасами.СформироватьЗапросПоТабличнойЧасти(ЭтотОбъект, "Подарки", СтруктураПолейПодарки,СтруктураСложныхПолей, СписокУсловийПодарки);
ТаблицаПодарки = РезультатЗапросаПодарки.Выгрузить();
ПроверитьЗаполнениеТабличнойЧастиПодарки(ТаблицаПодарки, СтруктураШапкиДокумента, Отказ, Заголовок);
УправлениеЗапасами.ПроверитьЗаполнениеТабличнойЧастиСерийныеНомера(ЭтотОбъект, "Товары", "СерийныеНомера", Отказ, Заголовок);
//Погашение сертификатами
ТаблицаПогашения = ПодготовитьТаблицуПогашения();
ПроверитьЗаполнениеТабличнойЧастиПогашения(ТаблицаПогашения, СтруктураШапкиДокумента, Отказ, Заголовок);
Если СтруктураШапкиДокумента.ВидОперации = Перечисления.ВидыОперацийЧекККМ.Продажа Тогда
ТаблицаПоТоварамБезУслугБезКомплектовПодарки = ТаблицаПоТоварамБезУслугБезКомплектов.Скопировать();
ОбщегоНазначения.ЗагрузитьВТаблицуЗначений(ТаблицаПодарки, ТаблицаПоТоварамБезУслугБезКомплектовПодарки);
ПроверитьОстаткиТоваров(СтруктураШапкиДокумента.Дата, РежимПроведения, ТаблицаПоТоварамБезУслугБезКомплектовПодарки, ТаблицаПоКомплектам, Отказ, Заголовок, Результат);
УправлениеЗапасами.ПроверитьДвиженияСерийныхНомеров(ЭтотОбъект, "Товары", "СерийныеНомера", РежимПроведения, Отказ, Заголовок);
УправлениеЗапасами.ПроверитьДвиженияСерийныхНомеровДляПогашения(ЭтотОбъект, РежимПроведения, Отказ, Заголовок);
Иначе
Если РежимПроведения = РежимПроведенияДокумента.Оперативный Тогда
ПроверитьВозможностьПроведенияЧекаВозврата(ТаблицаПоТоварам, ТаблицаПоОплате, СтруктураШапкиДокумента, Отказ, Результат);
КонецЕсли;
КонецЕсли;
Если Отказ Тогда
ОбщегоНазначения.СообщитьОбОшибке(Результат,,Заголовок);
Иначе
Если НЕ (КассаККМ.ТипКассы = Перечисления.ТипыКасс.КассаЦентральногоОфиса
ИЛИ СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.Архивный) Тогда
ТаблицаСерийныхНомеров = УправлениеЗапасами.СформироватьТаблицуСерийныхНомеров(ЭтотОбъект, "Товары", "СерийныеНомера", Истина);
ТаблицаПогашения.Свернуть("ПодарочныйСертификат, СерийныйНомер, Получатель, ХозяйственнаяОперация", "Количество");
ДвиженияПоРегистрам(РежимПроведения, СтруктураШапкиДокумента, ТаблицаПоТоварам, ТаблицаПоКомплектам, ТаблицаПоТоварамБезУслугБезКомплектов,
ТаблицаПоОплате, ТаблицаПодарки, ТаблицаСерийныхНомеров, ТаблицаПогашения, Отказ, Заголовок);
КонецЕсли;
КонецЕсли;
//m000 Найдем документ движения и проведем его
Если НЕ Отказ И ВидОперации = Перечисления.ВидыОперацийЧекККМ.Возврат Тогда
АСсылкаНаДвижение = Неопределено;
ЗаписатьДанныеПоДокументуВозврат(Товары, ЭтотОбъект.ЧекККМПродажа, АСсылкаНаДвижение);
ДокументСкидки = m000Сервер.НайтиДокументДвижения( ЭтотОбъект.Ссылка );
Если ДокументСкидки <> Неопределено Тогда
Если НЕ ДокументСкидки.Проведен Тогда
ДокументСкидки.ПолучитьОбъект().Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если НЕ Отказ И ВидОперации = Перечисления.ВидыОперацийЧекККМ.Продажа Тогда
ДокументСкидки = m000Сервер.НайтиДокументДвижения( ЭтотОбъект.Ссылка );
Если ДокументСкидки <> Неопределено Тогда
Если НЕ ДокументСкидки.Проведен Тогда
ДокументСкидки.ПолучитьОбъект().Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;
КонецЕсли;
КонецЕсли;
//m000/
КонецПроцедуры
// Процедура - обработчик события "ПриКопировании".
//
Процедура ПриКопировании(ОбъектКопирования)
СтатусЧекаККМ = Перечисления.СтатусыЧековККМ.ПустаяСсылка();
ОтчетОРозничныхПродажах = Документы.ОтчетОРозничныхПродажах.ПустаяСсылка();
НомерСменыККМ = 0;
НомерЧекаККМ = 0;
Скидки.Очистить();
Подарки.Очистить();
ДисконтнаяКарта = Справочники.ИнформационныеКарты.ПустаяСсылка();
ВладелецДисконтнойКарты =Неопределено;
КонецПроцедуры
Процедура ОбработкаУдаленияПроведения(Отказ)
//m000 Найдем документ движения и проведем его
Если НЕ Отказ Тогда
ДокументСкидки = m000Сервер.НайтиДокументДвижения( ЭтотОбъект.Ссылка );
Если ДокументСкидки <> Неопределено Тогда
ДокументСкидки.ПолучитьОбъект().Записать(РежимЗаписиДокумента.Проведение);
КонецЕсли;
КонецЕсли;
//m000/
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// ОПЕРАТОРЫ ОСНОВНОЙ ПРОГРАММЫ
РежимРМК = Ложь;
КонтролироватьОстаткиТоваровПриЗакрытииЧека = Ложь;