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