И вот перешла торговля на новый интерфейс (не Такси, а просто на управляемые формы). Многие торговые организации хотят работать не с фискальными регистратором, а с обычным POS-принтером или принтером чеков (в простонародье - кухонником). Но не все так гладко, как раньше. Простым добавлением внешней обработки уже не решить вопрос. Надо дорабатывать. За основу был взят типовой драйвер "1С: Драйвер фискального регистратора (эмулятор)"
Как многие знают, принтер чеков отображается в системе, как обычный принтер и не требует никаких специальных команд. В типовой конфигурации эмулятор сформированные строки чека просто выводит на экран. Нам необходимо всю эту информацию вставить в макет и уже его печатать на принтер. За основу были взяты обработки для предыдущих версий торговли на обычных формах.
Для воплощения задуманного Нам необходимо:
Доработать:
- - ОбщийМодуль.ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор
- - ОбщаяФорма.ФормаНастройки1СФискальныйРегистраторЭмулятор
- - Документ.ЧекККМ
- - Документ.ЧекККМВозврат
Создать:
- - ОбщийМодуль.ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер
- - Обработка.ФискальныйРегистраторКассираПринтер
Начну с новых объектов. Обработка нам нужна как хранение макета чека. В будущем я еще планирую в нее добавить печать копии чека на этот же принтер чеков(для ФР такое категорически противопоказанно, а нам-то ничего не мешает нарушить это правило ). Я думаю, что с этим пунктом проблем не будет. Вот перечень реализуемых параметров:
- - Организация
- - Номер чека в текущей смене
- - Номер смены или дата чека
- - Наименование + Характеристика
- - Количество
- - Цена
- - Скидка/Наценка
- - Сумма
- - Итого
- - Оплачено
- - Сдача
- - В завистимости от типа чека - разные шапки и конец
Сам макет (корявенький и плывет, но для наглядности сойдет; лучше скачать макет из архива):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Пробел |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Шапка |
*Организация* |
*Чек* |
*Смена* |
Наименование |
Кол-во |
Цена |
Скидка |
Сумма |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ШапкаНаВозврат |
*Организация* |
Чек на возврат |
*Чек* |
*Смена* |
Наименование |
Кол-во |
Цена |
Скидка |
Сумма |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Товары |
*Наименование* |
*Количество* |
*Цена* |
*Скидка* |
*Сумма* |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Итого |
Итого: |
*Сумма* |
Оплачено: |
*ОплаченоСумма* |
Сдача: |
*СдачаСумма* |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
КонецЧека |
Спасибо за покупку! |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
КонецЧекаНаВозврат |
Ждем Вас снова! |
Не забываем выставить права для кассира на работу с этим объектом
Далее - Общий модуль. ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор - клиентский модуль. В Нашем случе - необходимо выполнять ряд процедур и функций, которые не доступны НаКлиенте. По-этому создаем новый общий модуль ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер, ставим ему параметры как на рисунке ниже
Обратите внимание на пункт "Вызов сервера". Теперь можно отправить на сервер выполнение процедур и функций, не доступных на клиенте. На самом деле там будут только заполняться макет и получать некоторую информацию для чека. Вот текст модуля:
ОбщийМодуль.ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер
// Процедура добавляет значения переменнх в параметры подключения для работы стандартного модуля
// ТабДок;
Процедура ПолучитьОбщиеПараметры(ПараметрыПодключения) Экспорт
ТабДок = Новый ТабличныйДокумент;
ПараметрыПодключения.Вставить("ТабДок", ТабДок);
Конецпроцедуры // ПолучитьОбщиеПараметры()
// Процедура очищает табличный документ
Процедура ОчиститьТабДок(ТабДок) Экспорт
ТабДок.Очистить();
Конецпроцедуры // ОчиститьТабДок()
// Процедура возвращает номер чека и номер смены для подстановки (вместо чтения данных из фискального
// регистратора просто ориентируется на последний чек в смене)
Процедура ПолучитьРеквизитыПоследнегоЧека(НомерЧека, НомерСмены, КассаККМ, КассоваяСмена) Экспорт
НомерСмены = КассоваяСмена.Номер;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1
ЧекиККМ.НомерЧекаККМ КАК НомерЧекаККМ,
ЧекиККМ.КассаККМ,
ЧекиККМ.КассоваяСмена
ИЗ
ЖурналДокументов.ЧекиККМ КАК ЧекиККМ
ГДЕ
ЧекиККМ.КассаККМ = &КассаККМ
И ЧекиККМ.КассоваяСмена = &КассоваяСмена
УПОРЯДОЧИТЬ ПО
НомерЧекаККМ УБЫВ";
Запрос.УстановитьПараметр("КассаККМ", КассаККМ);
Запрос.УстановитьПараметр("КассоваяСмена", КассоваяСмена);
Результат = Запрос.Выполнить().Выгрузить();
Если Результат.Количество()>0 Тогда
НомерЧека = Результат[0].НомерЧекаККМ + 1;
Иначе
НомерЧека = 1;
КонецЕсли;
КонецПроцедуры
//Получает область из макета, заполняет его и стыкует с существующим табличным документом
Процедура ЗаполнитьИВывестиОбластьТабДок (ТабДок, ИмяОбласти, Значения) Экспорт
Макет = Обработки.ФискальныйРегистраторКассираПринтер.ПолучитьМакет("ДляWinПринтера");
Область = Макет.ПолучитьОбласть(ИмяОбласти);
Область.Параметры.Заполнить(Значения);
ТабДок.Вывести(Область);
КонецПроцедуры
Ну, а теперь - самое интересное. Что же Нам необходимо доработать? Начнем с настроек фискального регистратора. По сути, необходимо добавить на форму "ФормаНастройки1СФискальныйРегистраторЭмулятор" еще два реквизита и, затем, сохранять эти значения (чтоб они затем передавались в "ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор"):
- - ПринтерДляПечати (тип:строка)
- - ВыборПринтера (тип:булево)
Примечание: Далее я буду писать только функции/процедуры с добавленным/измененным кодом.
Измененный или добавленный код находится в блоке. Типовой код, который не нужен, но и не мешает, оставил.
Но Вы можете почистить от него модули.
В модуле формы добавляем строки:
- - В процедуре "ПриСозданииНаСервере"
ОбщаяФорма.
ФормаНастройки1СФискальныйРегистраторЭмулятор
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Параметры.Свойство("Идентификатор", Идентификатор);
Заголовок = НСтр("ru='ФР'") + " """ + Строка(Идентификатор) + """";
времНомерСекции = Неопределено;
времКодСимволаЧастичногоОтреза = Неопределено;
времМодель = Неопределено;
// (н) Кирилл
// ПечатьЧеков
времВыборПринтера = Ложь;
времПринтерДляПечати = "";
// (к) Кирилл
Параметры.Свойство("НомерСекции" , времНомерСекции);
Параметры.Свойство("КодСимволаЧастичногоОтреза", времКодСимволаЧастичногоОтреза);
Параметры.Свойство("Модель" , времМодель);
// (н) Кирилл
// ПечатьЧеков
Параметры.Свойство("ВыборПринтера" , времВыборПринтера);
Параметры.Свойство("ПринтерДляПечати" , времПринтерДляПечати);
// (к) Кирилл
НомерСекции = ?(времНомерСекции = Неопределено, 0, времНомерСекции);
КодСимволаЧастичногоОтреза = ?(времКодСимволаЧастичногоОтреза = Неопределено, 22, времКодСимволаЧастичногоОтреза);
Модель = ?(времМодель = Неопределено, Элементы.Модель.СписокВыбора[0], времМодель);
// (н) Кирилл
// ПечатьЧеков
ВыборПринтера = времВыборПринтера;
ПринтерДляПечати = времПринтерДляПечати;
// (к) Кирилл
КонецПроцедуры
- - В процедуре "ЗаписатьИЗакрытьВыполнить"
ОбщаяФорма.
ФормаНастройки1СФискальныйРегистраторЭмулятор
&НаКлиенте
Процедура ЗаписатьИЗакрытьВыполнить()
Параметры.ПараметрыНастройки.Добавить(НомерСекции, "НомерСекции");
Параметры.ПараметрыНастройки.Добавить(КодСимволаЧастичногоОтреза, "КодСимволаЧастичногоОтреза");
Параметры.ПараметрыНастройки.Добавить(Модель , "Модель");
// (н) Кирилл
// ПечатьЧеков
Параметры.ПараметрыНастройки.Добавить(ВыборПринтера , "ВыборПринтера");
Параметры.ПараметрыНастройки.Добавить(ПринтерДляПечати , "ПринтерДляПечати");
// (к) Кирилл
Закрыть(КодВозвратаДиалога.ОК);
КонецПроцедуры
Переходим к чекам. Необходимость доработки сводится к тому, что в случае с работой в режиме ФР, фискальный регистратор берет данные организации, номера чека, номера смены из своей памяти. В нашем случае - эту информацию необходимо черпать из БД. Следующая необходимость связана с тем, что в типовой на чек выводится только наименование номенклатуры. В моем случае была необходимость выводить характеристику. Для документа "ЧекККМ" редактируем модуль формы "ФормаДокументаМастер", а в документе "ЧекККМВозврат" - "ФормаДокумента". Изменения в обоих документах чека идентичны. По-этому привожу код только одного из них.
В функции "ПробитьЧекВыполнить"
Документ.ЧекККМ.
ФормаДокументаМастер / Документ.ЧекККМВозврат.ФормаДокумента
&НаКлиенте
Функция ПробитьЧекВыполнить()
ЧекПробит = Ложь;
ОписаниеОшибки = "";
Если Объект.НомерЧекаККМ <> 0 Тогда
ТекстСообщения = НСтр("ru = 'Чек уже пробит на фискальном регистраторе!'");
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
Возврат Ложь;
КонецЕсли;
Если МенеджерОборудованияКлиент.ОбновитьРабочееМестоКлиента() Тогда // Проверка на определенность рабочего места ВО
ПараметрыКассыККМ = ЗначениеНастроекПовтИсп.ПолучитьПараметрыКассыККМ(Объект.КассаККМ);
ИдентификаторУстройстваФР = ПараметрыКассыККМ.ИдентификаторУстройства;
ИспользоватьБезПодключенияОборудования = ПараметрыКассыККМ.ИспользоватьБезПодключенияОборудования;
Если ЗначениеЗаполнено(ИдентификаторУстройстваФР) ИЛИ ИспользоватьБезПодключенияОборудования Тогда
// Подключаем ФР
Результат = МенеджерОборудованияКлиент.ПодключитьОборудованиеПоИдентификатору(
УникальныйИдентификатор,
ИдентификаторУстройстваФР,
ОписаниеОшибки
);
Если Результат Или ИспользоватьБезПодключенияОборудования Тогда
Если Не ИспользоватьБезПодключенияОборудования Тогда
// Готовим данные
ВходныеПараметры = Новый Массив;
ВыходныеПараметры = Неопределено;
НомерСекции = 1;
// Подготовка таблицы товаров
ТаблицаТоваров = Новый Массив();
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
СтавкаНДС = ЦенообразованиеКлиентСервер.ПолучитьСтавкуНДСЧислом(СтрокаТЧ.СтавкаНДС);
Если Объект.ЦенаВключаетНДС Тогда
Сумма = СтрокаТЧ.Сумма;
Иначе
Сумма = СтрокаТЧ.Сумма + СтрокаТЧ.СуммаНДС;
КонецЕсли;
СуммаСкидки = СтрокаТЧ.СуммаАвтоматическойСкидки + СтрокаТЧ.СуммаРучнойСкидки;
ПроцентСкидки = СтрокаТЧ.ПроцентАвтоматическойСкидки + СтрокаТЧ.ПроцентРучнойСкидки;
СтрокаТаблицыТоваров = Новый СписокЗначений();
// (н) Кирилл
// Печать чеков
//СтрокаТаблицыТоваров.Добавить(Строка(СтрокаТЧ.Номенклатура));
Если СтрокаТЧ.Характеристика.Пустая() Тогда
СтрокаТаблицыТоваров.Добавить(Строка(СтрокаТЧ.Номенклатура));
Иначе
СтрокаТаблицыТоваров.Добавить(Строка(СтрокаТЧ.Номенклатура)+" ("+Строка(СтрокаТЧ.Характеристика)+")");
КонецЕсли;
// 1 - Наименование
// (к) Кирилл
СтрокаТаблицыТоваров.Добавить(""); // 2 - Штрихкод
СтрокаТаблицыТоваров.Добавить(""); // 3 - Артикул
СтрокаТаблицыТоваров.Добавить(НомерСекции); // 4 - Номер отдела
СтрокаТаблицыТоваров.Добавить(СтрокаТЧ.Цена); // 5 - Цена за позицию без скидки
СтрокаТаблицыТоваров.Добавить(СтрокаТЧ.КоличествоУпаковок); // 6 - Количество
СтрокаТаблицыТоваров.Добавить(""); // 7 - Наименование скидки/наценки
СтрокаТаблицыТоваров.Добавить(СуммаСкидки); // 8 - Сумма скидки/наценки
СтрокаТаблицыТоваров.Добавить(ПроцентСкидки); // 9 - Процент скидки/наценки
СтрокаТаблицыТоваров.Добавить(Сумма); // 10 - Сумма позиции со скидкой
СтрокаТаблицыТоваров.Добавить(0); // 11 - Номер налога (1)
СтрокаТаблицыТоваров.Добавить(СтрокаТЧ.СуммаНДС); // 12 - Сумма налога (1)
СтрокаТаблицыТоваров.Добавить(СтавкаНДС * 100); // 13 - Процент налога (1)
СтрокаТаблицыТоваров.Добавить(0); // 14 - Номер налога (2)
СтрокаТаблицыТоваров.Добавить(0); // 15 - Сумма налога (2)
СтрокаТаблицыТоваров.Добавить(0); // 16 - Процент налога (2)
СтрокаТаблицыТоваров.Добавить(""); // 17 - Наименование секции форматирования товарной строки
ТаблицаТоваров.Добавить(СтрокаТаблицыТоваров);
КонецЦикла;
// Подготовка таблицы оплат
ТаблицаОплат = Новый Массив();
// Наличные
СтрокаОплаты = Новый СписокЗначений();
СтрокаОплаты.Добавить(0);
СтрокаОплаты.Добавить(Объект.ПолученоНаличными);
СтрокаОплаты.Добавить("Наличная оплата");
СтрокаОплаты.Добавить("");
ТаблицаОплат.Добавить(СтрокаОплаты);
// Безналичные
СтрокаОплаты = Новый СписокЗначений();
СтрокаОплаты.Добавить(1);
СтрокаОплаты.Добавить(Объект.ОплатаПлатежнымиКартами.Итог("Сумма"));
СтрокаОплаты.Добавить("Безналичная оплата");
СтрокаОплаты.Добавить("");
ТаблицаОплат.Добавить(СтрокаОплаты);
// Подготовка таблицы общих параметров
ОбщиеПараметры = Новый Массив();
ОбщиеПараметры.Добавить(0); // 1 - Тип чека
ОбщиеПараметры.Добавить(Истина); // 2 - Признак фискального чека
ОбщиеПараметры.Добавить(Неопределено); // 3 - Печать на подкладном документе
ОбщиеПараметры.Добавить(СуммаДокумента); // 4 - Сумма по чеку без скидок/наценок
ОбщиеПараметры.Добавить(СуммаДокумента); // 5 - Сумма по чеку с учетом всех скидок/наценок
ОбщиеПараметры.Добавить(""); // 6 - Номер дисконтной карты
ОбщиеПараметры.Добавить(""); // 7 - Текст шапки
ОбщиеПараметры.Добавить(""); // 8 - Текст подвала
ОбщиеПараметры.Добавить(0); // 9 - Номер смены (для копии чека)
ОбщиеПараметры.Добавить(0); // 10 - Номер чека (для копии чека)
ОбщиеПараметры.Добавить(0); // 11 - Номер документа (для копии чека)
ОбщиеПараметры.Добавить(0); // 12 - Дата документа (для копии чека)
ОбщиеПараметры.Добавить(""); // 13 - Имя кассира (для копии чека)
ОбщиеПараметры.Добавить(""); // 14 - Пароль кассира
ОбщиеПараметры.Добавить(0); // 15 - Номер шаблона
ОбщиеПараметры.Добавить(""); // 16 - Наименование секции форматирования шапки
ОбщиеПараметры.Добавить(""); // 17 - Наименование секции форматирования подвала
// (н) Кирилл
// Печать чеков
ОбщиеПараметры.Добавить(Объект.КассаККМ); // 18 - КассаККМ (для определения последнего номера если эмулятор)
ОбщиеПараметры.Добавить(Объект.КассоваяСмена); // 19 - Кассовая смена (для определения последнего номера если эмулятор)
ОбщиеПараметры.Добавить(Объект.Организация); // 20 - Организация (если эмулятор)
// (к) Кирилл
ВходныеПараметры.Добавить(ТаблицаТоваров);
ВходныеПараметры.Добавить(ТаблицаОплат);
ВходныеПараметры.Добавить(ОбщиеПараметры);
// Печатаем чек.
Результат = МенеджерОборудованияКлиент.ВыполнитьКоманду(
ИдентификаторУстройстваФР,
"PrintReceipt",
ВходныеПараметры,
ВыходныеПараметры
);
КонецЕсли;
Если Результат ИЛИ ИспользоватьБезПодключенияОборудования Тогда
// Установить полученное значение номера чека реквизиту документа.
Если Не ИспользоватьБезПодключенияОборудования Тогда
Объект.НомерЧекаККМ = ВыходныеПараметры[1];
КонецЕсли;
Объект.Статус = ПредопределенноеЗначение("Перечисление.СтатусыЧековККМ.Пробит");
Объект.Дата = ТекущаяДата();
Если Не ЗначениеЗаполнено(Объект.НомерЧекаККМ) Тогда
Объект.НомерЧекаККМ = 1;
КонецЕсли;
Модифицированность = Истина;
РезультатПроведения = Записать(Новый Структура("РежимЗаписи, РежимПроведения", РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный));
Если РезультатПроведения = Истина Тогда
ЧекПробит = Истина;
КонецЕсли;
ПересчитатьДокументНаКлиенте();
ПодключитьОбработчикОжидания("УстановитьТекущийЭлементНаКнопкуЗакрыть", 0.1, Истина);
Иначе
ТекстСообщения = НСтр("ru = 'При печати чека произошла ошибка.
Чек не напечатан на фискальном регистраторе.
Дополнительное описание:
%ДополнительноеОписание%'");
ТекстСообщения = СтрЗаменить(ТекстСообщения,
"%ДополнительноеОписание%",
ВыходныеПараметры[1]);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецЕсли;
// Отключаем ФР
МенеджерОборудованияКлиент.ОтключитьОборудованиеПоИдентификатору(УникальныйИдентификатор, ИдентификаторУстройстваФР);
Иначе
ТекстСообщения = НСтр("ru = 'При подключении устройства произошла ошибка.
Чек не напечатан на фискальном регистраторе.
Дополнительное описание:
%ДополнительноеОписание%'");
ТекстСообщения = СтрЗаменить(ТекстСообщения, "%ДополнительноеОписание%", ОписаниеОшибки);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецЕсли;
Иначе
ТекстСообщения = НСтр("ru = 'Не выбран фискальный регистратор.'");
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецЕсли;
Иначе
ТекстСообщения = НСтр("ru = 'Предварительно необходимо выбрать рабочее место внешнего оборудования текущего сеанса.'");
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
КонецЕсли;
Возврат ЧекПробит;
КонецФункции
Подготовку сделали. Осталось изменить основной модуль " ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор".
- Функция "ПодключитьУстройство". Вот здесь добавляем Наши новые параметры настройки принтера (имя и признак печати)
ОбщийМодуль.
ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор
Функция ПодключитьУстройство(ОбъектДрайвера, Параметры, ПараметрыПодключения, ВыходныеПараметры) Экспорт
Результат = Истина;
ПараметрыПодключения.Вставить("СерийныйНомерККМ", "0");
ПараметрыПодключения.Вставить("ИДУстройства", "");
ПараметрыПодключения.Вставить("ФРПодключен", Ложь);
ПараметрыПодключения.Вставить("СтрокаЛога", "");
// (н) Кирилл
// Печать чеков
// Добавим дополнительные параметры
ПараметрыПодключения.Вставить("ВыборПринтера", Ложь);
ПараметрыПодключения.Вставить("ИмяПринтера", "");
//Вставляем табличный документ
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ПолучитьОбщиеПараметры(ПараметрыПодключения);
// (к) Кирилл
//Обязательные выходные
ВыходныеПараметры = Новый Массив();
// Проверка настроенных параметров
КодСимволаЧастичногоОтреза = Неопределено;
НомерСекции = Неопределено;
Модель = Неопределено;
НаправлениеПечати = Неопределено;
// (н) Кирилл
// Печать чеков
ИмяПринтера = Неопределено;
ВыборПринтера = Неопределено;
// (к) Кирилл
Параметры.Свойство("КодСимволаЧастичногоОтреза", КодСимволаЧастичногоОтреза);
Параметры.Свойство("НомерСекции" , НомерСекции);
Параметры.Свойство("Модель" , Модель);
Параметры.Свойство("НаправлениеПечати" , НаправлениеПечати);
// (н) Кирилл
// Печать чеков
Параметры.Свойство("ПринтерДляПечати" , ИмяПринтера);
Параметры.Свойство("ВыборПринтера" , ВыборПринтера);
// (к) Кирилл
// (н) Кирилл
// Печать чеков
ПараметрыПодключения.Вставить("ВыборПринтера", ВыборПринтера);
ПараметрыПодключения.Вставить("ИмяПринтера", ИмяПринтера);
// (к) Кирилл
Если КодСимволаЧастичногоОтреза = Неопределено
Или НомерСекции = Неопределено
Или Модель = Неопределено Тогда
Результат = Ложь;
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить(НСтр("ru='Не настроены параметры устройства.
Для корректной работы устройства необходимо задать параметры его работы.
Сделать это можно при помощи формы ""Настройка параметров"" модели
подключаемого оборудования в форме ""Подключение и настройка оборудования"".'"));
КонецЕсли;
// Конец: Проверка настроенных параметров
Если Результат Тогда
Если ПараметрыПодключения.ФРПодключен Тогда
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить(НСтр("ru='Фискальный регистратор уже подключен'"));
Результат = Ложь;
Иначе
ПараметрыПодключения.ФРПодключен = Истина;
ВыходныеПараметры.Добавить(""); // Источник событий
ВыходныеПараметры.Добавить(Неопределено); // Список событий
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
- Функция "ПечатьЧека". Здесь вставляем в параметры подключения значения кассы ККМ, кассовой смены и организации. Так же отключим вывод на экран сформированного чека.
ОбщийМодуль.
ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор
- Функция "ОткрытьЧек".
ОбщийМодуль.
ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор
Функция ОткрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ЧекВозврата, ФискальныйЧек, ВыходныеПараметры) Экспорт
Результат = Истина;
СтрокаЛога = "";
мНомерСмены = 1;
мНомерЧека = 1;
// (н) Кирилл
// Печать чеков
// Заполняем правильные значения номера чека и номера смены. По-умолчанию они должны браться из ФР
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ПолучитьРеквизитыПоследнегоЧека(мНомерЧека, мНомерСмены, ПараметрыПодключения.КассаККМ, ПараметрыПодключения.КассоваяСмена);
// (к) Кирилл
СтрокаЛога = СтрокаЛога + "===== " + ?(ЧекВозврата, НСтр("ru='Открытие чека возврата'"), НСтр("ru='Открытие чека продажи'")) + " =====" + Символы.ПС;
СтрокаЛога = СтрокаЛога + "=====" + ?(ФискальныйЧек, "== " + НСтр("ru='Фискальный режим'"), " " + НСтр("ru='Нефискальный режим'")) + "=====" + Символы.ПС;
СтрокаЛога = СтрокаЛога + НСтр("ru='№ чека'") + ": " + Формат(мНомерЧека, "ЧЦ=4; ЧН=0; ЧВН=")
+ " "
+ НСтр("ru='№ смены'") + ": " + Формат(мНомерСмены, "ЧЦ=4; ЧН=0; ЧВН=") + Символы.ПС;
// (н) Кирилл
// Печать чеков
// Чтобы время на чеке и время документа совпадали
ТекДата = ТекущаяДата();
Значения = Новый Структура;
Значения.Вставить("Организация", ПараметрыПодключения.Организация); // По-умолчанию организация берется из ФР. Нам пришлось этот параметр передавать вместе с "КассойККМ"
Значения.Вставить("Чек", "№ чека: " + Формат(мНомерЧека, "ЧЦ=4; ЧВН="));
//Область.Параметры.Смена = "№ смены: " + Формат(мНомерСмены, "ЧЦ=4; ЧВН="); // Заполним номер смены
Значения.Вставить("Смена", ТекДата); // Вместо номера смены можно указать дату чека
ПараметрыПодключения.Вставить("ЧекВозврата", ЧекВозврата); // Этот параметр будет необходим при закрытии чека
Если ПараметрыПодключения.ЧекВозврата Тогда
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, "ШапкаНаВозврат", Значения);
Иначе
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, "Шапка", Значения);
КонецЕсли;
// (к) Кирилл
НомерСмены = мНомерСмены;
НомерЧека = мНомерЧека;
// Заполнение выходных параметров
ВыходныеПараметры.Добавить(НомерСмены);
ВыходныеПараметры.Добавить(НомерЧека);
ВыходныеПараметры.Добавить(0);
// (н) Кирилл
// Печать чеков
// Чтобы время на чеке и время документа совпадали
//ВыходныеПараметры.Добавить(ТекущаяДата());
ВыходныеПараметры.Добавить(ТекДата);
// (к) Кирилл
ПараметрыПодключения.Вставить("ФискальныйЧек", ФискальныйЧек);
ПараметрыПодключения.Вставить("ЧекОткрыт" , Истина);
ПараметрыПодключения.Вставить("ИтогЧека" , 0);
ПараметрыПодключения.СтрокаЛога = ПараметрыПодключения.СтрокаЛога + СтрокаЛога;
Возврат Результат;
КонецФункции
- Функция "НапечататьФискальнуюСтроку". Печатаем только фискальные строки. Функцию "НапечататьНефискальнуюСтроку" не трогаем.
ОбщийМодуль.
ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор
Функция НапечататьФискальнуюСтроку(ОбъектДрайвера, Параметры, ПараметрыПодключения,
Наименование, Количество, Цена, ПроцентСкидки, Сумма,
НомерСекции, СтавкаНДС, ВыходныеПараметры) Экспорт
Результат = Истина;
СтрокаЛога = "";
Если Не ПараметрыПодключения.ЧекОткрыт Тогда
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить(НСтр("ru='Чек не был открыт'"));
Результат = Ложь;
Иначе
// Печать строки чека
СтрокаЛога = ".............................." + Символы.ПС;
СтрокаЛога = СтрокаЛога + Наименование + Символы.ПС;
СтрокаЛога = СтрокаЛога + Строка(Количество) + " * " + Строка(Цена) + " = " + Формат(Количество*Цена, "ЧЦ=15; ЧДЦ=2; ЧН=0; ЧГ=0") + Символы.ПС;
// (н) Кирилл
// ПечатьЧеков
// Заносим необходимые значения в структуру
Значения = Новый Структура;
Значения.Вставить("Наименование", Наименование);
Значения.Вставить("Количество", Строка(Количество));
Значения.Вставить("Цена", Формат(Цена, "ЧДЦ=2; ЧН=0,00"));
Значения.Вставить("Сумма", Формат(Количество*Цена, "ЧДЦ=2; ЧН=0,00"));
// (к) Кирилл
СкидкаНаценка = Сумма - Цена*Количество;
Если СкидкаНаценка < 0 Тогда
СтрокаЛога = СтрокаЛога + НСтр("ru='Скидка'") + ": " + Формат(-СкидкаНаценка, "ЧЦ=15; ЧДЦ=2; ЧН=0; ЧГ=0")
+ " (" + ПроцентСкидки + "%)" + Символы.ПС;
// (н) Кирилл
// ПечатьЧеков
Значения.Вставить("Скидка", Формат(-СкидкаНаценка, "ЧЦ=15; ЧДЦ=2; ЧН=0; ЧГ=0")); //Устанвливает скидку в виде суммы
//Значения.Вставить("Скидка", ПроцентСкидки + "%"); //Устанвливает скидку в виде %%
// (к) Кирилл
Иначе
СтрокаЛога = СтрокаЛога + НСтр("ru='Наценка'") + ": " + Формат(СкидкаНаценка, "ЧЦ=15; ЧДЦ=2; ЧН=0; ЧГ=0")
+ " (" + ПроцентСкидки + "%)" + Символы.ПС;
// (н) Кирилл
// ПечатьЧеков
// Т.к. мы не можем в макете указывать скидка это или наценка для каждой строки, то делаем это через "-"
Значения.Вставить("Скидка", Формат(-СкидкаНаценка, "ЧЦ=15; ЧДЦ=2; ЧН=0; ЧГ=0")); //Устанвливает наценку в виде суммы
//Значения.Вставить("Скидка", -ПроцентСкидки + "%"); //Устанвливает наценку в виде %%
// (к) Кирилл
КонецЕсли;
СтрокаЛога = СтрокаЛога + НСтр("ru='Отдел'") + ": №" + НомерСекции + Символы.ПС;
Если СтавкаНДС > 0 Тогда
СтрокаЛога = СтрокаЛога + НСтр("ru='НДС'") + ": " + СтавкаНДС + "%" + Символы.ПС;
// (н) Кирилл
// ПечатьЧеков
// Не выводим НДС в этом решении. В случе добавления параметра в макет - просто раскомментировать строку
// Значения.Вставить("НДС", СтавкаНДС + "%");
// (к) Кирилл
КонецЕсли;
// (н) Кирилл
// ПечатьЧеков
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, "Товары", Значения);
// (к) Кирилл
СтрокаЛога = СтрокаЛога + ".............................." + Символы.ПС;
ПараметрыПодключения.ИтогЧека = ПараметрыПодключения.ИтогЧека + Сумма;
КонецЕсли;
ПараметрыПодключения.СтрокаЛога = ПараметрыПодключения.СтрокаЛога + СтрокаЛога;
Возврат Результат;
КонецФункции
- Функция "ЗакрытьЧек".
ОбщийМодуль.
ПодключаемоеОборудование1СФискальныйРегистраторЭмулятор
Функция ЗакрытьЧек(ОбъектДрайвера, Параметры, ПараметрыПодключения, ТаблицаОплат, ВыходныеПараметры) Экспорт
Результат = Истина;
СтрокаЛога = "";
СуммаНаличнойОплаты = 0;
СуммаБезналичнойОплаты1 = 0;
СуммаБезналичнойОплаты2 = 0;
Для ИндексОплаты = 0 По ТаблицаОплат.Количество() - 1 Цикл
Если ТаблицаОплат[ИндексОплаты][0].Значение = 0 Тогда
СуммаНаличнойОплаты = СуммаНаличнойОплаты + ТаблицаОплат[ИндексОплаты][1].Значение;
ИначеЕсли ТаблицаОплат[ИндексОплаты][0].Значение = 1 Тогда
СуммаБезналичнойОплаты1 = СуммаБезналичнойОплаты1 + ТаблицаОплат[ИндексОплаты][1].Значение;
Иначе
СуммаБезналичнойОплаты2 = СуммаБезналичнойОплаты2 + ТаблицаОплат[ИндексОплаты][1].Значение;
КонецЕсли;
КонецЦикла;
Если Не ПараметрыПодключения.ЧекОткрыт Тогда
ВыходныеПараметры.Очистить();
ВыходныеПараметры.Добавить(999);
ВыходныеПараметры.Добавить(НСтр("ru='Чек не был открыт'"));
Результат = Ложь;
Иначе
Если ПараметрыПодключения.ФискальныйЧек Тогда
СтрокаЛога = СтрокаЛога + НСтр("ru='ИТОГО'") + ": " + Формат(ПараметрыПодключения.ИтогЧека, "ЧЦ=15; ЧДЦ=2; ЧН=0; ЧГ=0") + Символы.ПС;
СтрокаЛога = СтрокаЛога + НСтр("ru='Оплачено наличными'") + ": " + СуммаНаличнойОплаты + Символы.ПС;
СтрокаЛога = СтрокаЛога + НСтр("ru='Оплачено безналичными 1'") + ": " + СуммаБезналичнойОплаты1 + Символы.ПС;
СтрокаЛога = СтрокаЛога + НСтр("ru='Оплачено безналичными 2'") + ": " + СуммаБезналичнойОплаты2 + Символы.ПС;
СтрокаЛога = СтрокаЛога + НСтр("ru='Сдача'") + ": "
+ Строка(СуммаНаличнойОплаты
+ СуммаБезналичнойОплаты1
+ СуммаБезналичнойОплаты2
- ПараметрыПодключения.ИтогЧека) + Символы.ПС;
КонецЕсли;
СтрокаЛога = СтрокаЛога + "===== "
+ ?(ПараметрыПодключения.ФискальныйЧек,
НСтр("ru='Закрытие фискального чека'"),
НСтр("ru='Закрытие нефискального чека'"))
+ " =====" + Символы.ПС;
// (н) Кирилл
// ПечатьЧеков
Значения = Новый Структура;
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, "Пробел", Значения);
Значения = Новый Структура;
Значения.Вставить("Сумма", Окр(ПараметрыПодключения.ИтогЧека, 2, РежимОкругления.Окр15как20));
Значения.Вставить("ОплаченоСумма", Формат(СуммаНаличнойОплаты+СуммаБезналичнойОплаты1 + СуммаБезналичнойОплаты2, "ЧДЦ=2; ЧН=0,00"));
Значения.Вставить("СдачаСумма", Формат(СуммаНаличнойОплаты + СуммаБезналичнойОплаты1 + СуммаБезналичнойОплаты2 - ПараметрыПодключения.ИтогЧека, "ЧДЦ=2; ЧН=0,00"));
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, "ИТОГО", Значения);
Значения = Новый Структура;
Если ПараметрыПодключения.ЧекВозврата Тогда
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, "КонецЧекаНаВозврат", Значения);
Иначе
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ЗаполнитьИВывестиОбластьТабДок(ПараметрыПодключения.ТабДок, " КонецЧека", Значения);
КонецЕсли;
ПараметрыПодключения.ЧекОткрыт = Ложь;
Если ПараметрыПодключения.ИмяПринтера<>"" Тогда
ПараметрыПодключения.ТабДок.ИмяПринтера=ПараметрыПодключения.ИмяПринтера;
КонецЕсли;
// Явно убераем поля и устанавливаем автомасштаб по ширине
ПараметрыПодключения.ТабДок.ПолеСверху=0;
ПараметрыПодключения.ТабДок.ПолеСнизу=0;
ПараметрыПодключения.ТабДок.ПолеСлева=0;
ПараметрыПодключения.ТабДок.ПолеСправа=0;
ПараметрыПодключения.ТабДок.АвтоМасштаб=Истина;
// Вместо выбора принтера - выдаем на экран чек. Вместо связки Если КонецЕсли можно использовать строку ниже.
// ПараметрыПодключения.ТабДок.Напечатать(Не ПараметрыПодключения.ВыборПринтера);
Если ПараметрыПодключения.ВыборПринтера Тогда
ПараметрыПодключения.ТабДок.Показать();
Иначе
ПараметрыПодключения.ТабДок.Напечатать();
КонецЕсли;
ПодключаемоеОборудование1СФискальныйРегистраторЭмуляторСервер.ОчиститьТабДок(ПараметрыПодключения.ТабДок);
// (к) Кирилл
КонецЕсли;
ПараметрыПодключения.СтрокаЛога = ПараметрыПодключения.СтрокаЛога + СтрокаЛога;
Возврат Результат;
КонецФункции
Вот и все! Теперь добвляем оборудование "Фискальный регистратор" и в поле "Обработчик драйвера" выбираем "1С: Фискальный регистратор (эмулятор)". А после настраиваем (указываем имя принтера для печати или ставим галочку "Выбор принтера".
P.S.: Данный прием не актуален для Розницы 2.0. Там данное решение доступно "из коробки". Как - смотрим комментарии.
UPD 1: Если используется терминал, то печатную форму ровно как и функцию закрытия чека желательно доработать для того чтобы на печать выводить оплаты наличными и картой
UPD 2: Выявилась проблема при печати текстовых блоков. Например, когда происходит попытка распечатать слип-чек, то вылетает ошибка отсутствия в передаваемых параметрах кассы ККМ. Фиксится не сложно, но в моем случае такой необходимости нет.
UPD 3: Данный прием теряет свою актуальность для новых версий конфигурации.