При работе конфигурации 1С:Управление торговлей (ред. 10.3) в связке с фронт-офисными программами (например, Штрих-М: Кассир) при снятии Z-отчета и загрузке данных о розничных продажах часто возникает типовая проблема. Если на складе 1С не хватает остатка по переданной номенклатуре (например, из-за весового товара, пересортицы или несвоевременного прихода), система останавливает проведение документа Отчет о розничных продажах. В результате транзакция загрузки отменяется, а кассовая смена не закрывается.
Разберем подробно причины такого поведения системы, проанализируем штатный код обработки закрытия смены и рассмотрим варианты решения этой задачи.
Проанализируем механику работы процедуры закрытия смены. Проблема возникает из-за совокупности нескольких факторов:
РежимПроведенияДокумента.Оперативный). В этом режиме механизмы регистров накопления (ТоварыНаСкладах, ТоварыВРознице, ТоварыОрганизаций) жестко контролируют остатки товаров и при отрицательном балансе генерируют ошибку.НачатьТранзакцию() ... ЗафиксироватьТранзакцию()). Если проведение документа вызывает ошибку, срабатывает отмена транзакции (ОтменитьТранзакцию()), из-за чего созданный документ Отчет о розничных продажах полностью удаляется, а данные из ККМ Offline не загружаются.Рассмотреть решение стоит с самой простой настройки, не требующей изменения конфигурации. В УТ 10.3 контроль остатков ведется в двух разрезах: по конкретному складу и по организации в целом. Чтобы разрешить проведение документов в "минус", необходимо включить оба права одновременно.
Откроем в программе меню: Сервис -> Пользователи -> Настройка дополнительных прав пользователей. Для пользователя или группы пользователей, под которыми выполняется процедура закрытия смены, установим значению Истина для двух флагов:
Важно: Если закрытие кассовой смены выполняется через торговое оборудование в режиме Offline под специальной технологической учетной записью, права должны быть настроены именно для этого пользователя 1С.
Если настройка прав не помогла или требуется гарантированно загрузить файл продаж (чтобы товаровед затем мог разобраться с минусами), необходимо модифицировать обработку закрытия смены. Разберем по шагам, как изменить код, чтобы документ Отчет о розничных продажах в любом случае записывался в базу данных, а проведение выполнялось в отдельном блоке обработки ошибок.
Посмотрим на стандартный фрагмент процедуры ОбработкаЧековOffline в обработке закрытия кассовой смены:
Процедура ОбработкаЧековOffline(ККМ)
Отчет = Неопределено;
Результат = ПолучитьСерверТО().ЗагрузитьОтчетОПродажах(ККМ, Отчет);
Если НЕ ЗначениеЗаполнено(Результат) Тогда
Если Отчет.Количество() = 0 Тогда
// Обработка пустого отчета
Иначе
ДокОтчет = СоздатьОтчетОРозничныхПродажах();
Для каждого Позиция Из Отчет Цикл
Товар = ДокОтчет.Товары.Добавить();
ЗаполнитьЗначенияСвойств(Товар, Позиция);
// ... заполнение реквизитов ...
КонецЦикла;
// Запись документа без проведения
ЗаписатьОтчетОРозничныхПродажах(ДокОтчет);
Результат = ПолучитьСерверТО().ЗавершитьЗагрузкуОтчетаОПродажах(ККМ);
ДокОтчет.ПолучитьФорму().Открыть();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратим внимание на функцию записи документа ЗаписатьОтчетОРозничныхПродажах(ДокОтчет):
Функция ЗаписатьОтчетОРозничныхПродажах(ОтчетОРозничныхПродажах)
ОтчетОРозничныхПродажах.ДополнитьДокументЗначениямиПоУмолчанию();
Попытка
ОтчетОРозничныхПродажах.Записать(РежимЗаписиДокумента.Запись);
Результат = Истина;
Исключение
ОбщегоНазначения.СообщитьОбОшибке("Не удалось записать документ """ + ОтчетОРозничныхПродажах + """."
+ Символы.ПС + Символы.ПС + ОписаниеОшибки());
Результат = Ложь;
КонецПопытки;
Возврат Результат;
КонецФункции
Для гарантированного сохранения документа при продажах KKM OnLine / ЧекККМ, проанализируем блок ОбработкаЧековККМ. Проведение документов в нем должно выполняться вынесением за пределы основной транзакции. Разберем соответствующую часть кода:
Если ОтменитьТранзакцию Тогда
ОтменитьТранзакцию();
Иначе
ЗафиксироватьТранзакцию();
// Проведение записанных документов вынесено из транзакции загрузки
Для Каждого ДокументКПроведению Из МассивДокументовКПроведению Цикл
Попытка
ДокументКПроведению.Записать(РежимЗаписиДокумента.Проведение, РежимПроведения);
Исключение
ОбщегоНазначения.СообщитьОбОшибке("Не удалось провести документ """ + ДокументКПроведению + """.");
КонецПопытки;
ДокументКПроведению.ПолучитьФорму().Открыть();
КонецЦикла;
КонецЕсли;
Благодаря такой конструкции, даже если попытка ДокументКПроведению.Записать(РежимЗаписиДокумента.Проведение) вызовет исключение из-за нехватки остатков на складе, сам документ Отчет о розничных продажах останется записанным в базе данных в непроведенном состоянии, а чеки будут обработаны без отката транзакции.
Выясним еще одну особенность платформы. В неоперативном режиме проведения (РежимПроведенияДокумента.Неоперативный) 1С не контролирует текущие остатки на складах в моментальных регистрах накопления. Проведение документа оформляется задним числом.
Если в коде обработки явно передать неоперативный режим проведения для создаваемого документа, проведение пройдет успешно независимо от наличия отрицательных остатков:
// Принудительная установка неоперативного режима проведения
РежимПроведения = РежимПроведенияДокумента.Неоперативный;
ДокументКПроведению.Записать(РежимЗаписиДокумента.Проведение, РежимПроведения);
Проводя документ Отчет о розничных продажах с недостающими остатками, мы предотвращаем сбой в работе кассиров, однако создаем временные искажения в учете:
Оприходование товаров или Пересортица товаров).Отчет о розничных продажах и выполнить обработку Перепроведение документов для восстановления последовательности партионного учета.