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