В типовой конфигурации «1С:Розница 2.2» пользователи часто сталкиваются с ситуацией, когда при создании документа ЧекККМ на основании ЗаказПокупателя реквизит Касса ККМ остается незаполненным. Это замедляет работу кассира, так как требует ручного выбора кассы из справочника. Разберем подробно, почему так происходит и как с помощью механизма расширений автоматизировать этот процесс, сохранив конфигурацию на поддержке.
Проанализируем логику работы типового решения. В 1С:Розница выбор кассы ККМ тесно завязан на понятие Рабочее место (справочник РабочиеМеста). Каждое рабочее место привязывается к конкретному идентификатору компьютера (ID клиента). Когда кассир открывает стандартную форму РМК (Рабочее место кассира), система автоматически определяет подключенное оборудование и соответствующую ему кассу.
Однако при выполнении операции «Создать на основании» из документа ЗаказПокупателя, система обращается к модулю объекта ЧекККМ, где стандартные алгоритмы заполнения могут не учитывать текущее рабочее место пользователя или настройки торговой точки, указанной в заказе. В результате реквизит КассаККМ остается пустым.
Выясним причину, где именно происходит первичная инициализация данных документа. Основным обработчиком для создания «на основании» является процедура ОбработкаЗаполнения, расположенная в модуле объекта документа. Чтобы не вносить изменения в типовой код, мы создадим расширение.
Рассмотрим пошагово реализацию программного кода в расширении:
ЧекККМ.ЧекККМ создадим процедуру-перехватчик для метода ОбработкаЗаполнения с аннотацией &После.Проанализируем пример кода, который позволит нам подставить кассу:
&После("ОбработкаЗаполнения")
Процедура Расш1_ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
// Проверяем, что заполнение происходит именно на основании Заказа покупателя
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
// Если касса еще не заполнена стандартными средствами
Если НЕ ЗначениеЗаполнено(ЭтотОбъект.КассаККМ) Тогда
// Получаем рабочее место текущего сеанса
ТекущееРабочееМесто = ПараметрыСеанса.РабочееМестоКлиента;
// Используем типовой программный интерфейс Розницы для поиска кассы
// Важно использовать встроенные функции общего модуля МенеджерОборудованияРТ
КассаПоУмолчанию = МенеджерОборудованияРТ.ПолучитьКассуККМПоРабочемуМесту(ТекущееРабочееМесто);
Если ЗначениеЗаполнено(КассаПоУмолчанию) Тогда
ЭтотОбъект.КассаККМ = КассаПоУмолчанию;
Иначе
// Если по рабочему месту не нашли, можно попробовать найти любую кассу магазина из заказа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| КассыККМ.Ссылка КАК Ссылка
|ИЗ
| Справочник.КассыККМ КАК КассыККМ
|ГДЕ
| КассыККМ.Владелец = &Магазин
| И НЕ КассыККМ.ПометкаУдаления";
Запрос.УстановитьПараметр("Магазин", ДанныеЗаполнения.Магазин);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
ЭтотОбъект.КассаККМ = Выборка.Ссылка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Иногда заполнения в модуле объекта бывает недостаточно, так как при открытии формы документа ЧекККМ могут срабатывать дополнительные проверки в процедуре ПриСозданииНаСервере, которые очищают реквизит, если, например, касса не соответствует текущему складу или организации, выбранной в форме.
Разберем, как подстраховаться на уровне формы документа. Для этого добавим форму документа ФормаДокумента (или ФормаЧека) в расширение и используем следующий код:
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Выполняем код только для новых, еще не записанных документов
Если Объект.Ссылка.Пустая() Тогда
// Проверяем, заполнена ли касса
Если НЕ ЗначениеЗаполнено(Объект.КассаККМ) Тогда
// Пытаемся определить кассу по рабочему месту
РМ = ПараметрыСеанса.РабочееМестоКлиента;
КассаККМ = МенеджерОборудованияРТ.ПолучитьКассуККМПоРабочемуМесту(РМ);
Если ЗначениеЗаполнено(КассаККМ) Тогда
Объект.КассаККМ = КассаККМ;
// Важно вызвать стандартные оповещения об изменении кассы,
// если в форме есть зависимые реквизиты
// Например, пересчет налогов или доступность кнопок фискализации
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
При реализации данного механизма необходимо учитывать права доступа. Если у кассира ограничены права (используется RLS), программный поиск кассы может вернуть пустое значение, так как кассир «не видит» справочник вне своего магазина. В таких случаях в модуле расширения рекомендуется выполнять запрос к базе данных в Привилегированном режиме.
Для этого можно вынести логику поиска кассы в отдельную функцию модуля расширения с установленным признаком «Привилегированный» или использовать конструкцию УстановитьПривилегированныйРежим(Истина) внутри кода расширения, если права позволяют.
Прежде чем приступать к написанию кода, убедитесь, что выполнены базовые настройки конфигурации, которые могут влиять на поведение системы:
ЗаказПокупателя корректно указан Магазин, так как касса является подчиненным справочником по отношению к магазину или организации.Использование связки метода МенеджерОборудованияРТ.ПолучитьКассуККМПоРабочемуМесту и расширения модуля объекта является наиболее корректным и архитектурно правильным решением для 1С:Розница 2.2, так как оно опирается на стандартные механизмы работы с торговым оборудованием.