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