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