Как создать новый документ через HTTP-сервис и OData в 1С: решаем ошибку "ОбработкаЗаполнения"

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Торговля и дистрибуция
← На главную

Рассмотрим достаточно распространенную задачу интеграции, когда требуется создать новый документ (например, ПриходныйОрдерНаТовары) в базе 1С из внешней системы (например, скрипта на PHP) посредством HTTP-запроса. Проанализируем типичные подводные камни, с которыми сталкиваются разработчики, выясним причину возникновения ошибок стандартного интерфейса и разберем по шагам создание собственного надежного HTTP-сервиса.

Попытка использования стандартного OData и анализ ошибки

Первая мысль при необходимости создать объект извне — воспользоваться готовым стандартным интерфейсом OData, который предоставляет платформа 1С. Однако при отправке POST-запроса на создание документа разработчики часто получают от сервера ответ с кодом 500 и следующим содержанием:


{
  "odata.error": {
    "code": "-1",
    "message": {
      "lang": "ru",
      "value": "Ошибка при выполнении обработчика - 'ОбработкаЗаполнения'"
    }
  }
}

Давайте выясним причину такого поведения. При попытке создать новый объект (документ, справочник) через OData, платформа автоматически инициализирует этот объект и вызывает событие ОбработкаЗаполнения в его модуле. Если в данном обработчике написан "тяжелый" прикладной код, который жестко завязан на пользовательский интерфейс, или ожидающий строго определенную структуру параметров (например, данные из документа-основания, которых OData не передает), происходит программный сбой.

Способ 1: Отладка и исправление прикладного кода 1С

Если мы хотим продолжить использовать именно OData, нам потребуется вмешаться в код самой конфигурации. Рассмотрим этот процесс подробнее:

  1. Откройте конфигуратор 1С и найдите нужный документ в дереве метаданных.
  2. Перейдите в Модуль объекта этого документа.
  3. Найдите процедуру ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка).
  4. Воспользуйтесь отладчиком, чтобы поймать конкретную строку, вызывающую ошибку при вызове через OData.

Чаще всего проблема кроется в отсутствии проверок на тип входящего параметра ДанныеЗаполнения. Когда запрос приходит извне, этот параметр может быть равен Неопределено. Чтобы исправить ошибку, достаточно обернуть проблемный код в условие проверки или добавить игнорирование обработки при загрузке данных:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    // Пропускаем выполнение, если идет загрузка данных извне
    Если ОбменДанными.Загрузка Тогда 
        Возврат; 
    КонецЕсли;
    
    // Остальной прикладной код...
КонецПроцедуры

Способ 2: Создание собственного HTTP-сервиса (рекомендуется)

Если исправлять чужой прикладной код нельзя (конфигурация на поддержке) или нужна более гибкая логика обработки входящих запросов от PHP, разработка собственного HTTP-сервиса станет идеальным выходом. В этом случае мы сможем принудительно отключить лишние обработчики, создавая объект в режиме загрузки.

Разберем по шагам процесс создания своего API в 1С:

  1. В конфигураторе добавьте новый HTTPСервис (назовем его, например, ApiIntegration).
  2. Создайте Шаблон URL (например, /create_order).
  3. Внутри шаблона добавьте Метод HTTP (метод POST).
  4. Назначьте методу функцию-обработчик.

Посмотрим на пример кода, который необходимо разместить в модуле HTTP-сервиса:


Функция ApiIntegrationСоздатьДокумент(Запрос)
    // 1. Создаем пустой объект документа
    НовыйДокумент = Документы.ПриходныйОрдерНаТовары.СоздатьДокумент();
    НовыйДокумент.Дата = ТекущаяДата();
    
    // Здесь можно получить тело запроса от PHP и распарсить JSON
    // СтрокаЗапроса = Запрос.ПолучитьТелоКакСтроку();
    // И заполнить реквизиты документа...
    
    // 2. Включаем Режим Загрузки!
    // Это ключевой момент: установка флага отключает запуск ОбработкиЗаполнения
    // и других прикладных проверок, которые могут вызвать ошибку.
    НовыйДокумент.ОбменДанными.Загрузка = Истина; 
    
    Попытка
        // 3. Записываем объект без проведения
        НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);
        
        // 4. Формируем успешный ответ для внешней системы
        Ответ = Новый HTTPСервисОтвет(200);
        Ответ.УстановитьТелоИзСтроки("Документ успешно создан. GUID: " + Строка(НовыйДокумент.Ссылка.УникальныйИдентификатор()));
    Исключение
        // 5. Обрабатываем возможные ошибки при записи
        Ответ = Новый HTTPСервисОтвет(500);
        Ответ.УстановитьТелоИзСтроки("Ошибка создания документа: " + ОписаниеОшибки());
    КонецПопытки;
    
    Возврат Ответ;
КонецФункции

Ключевым свойством здесь является использование ОбменДанными.Загрузка. Установив его в Истина, мы сообщаем платформе, что объект записывается программно в рамках обмена, и выполнять интерактивные или сложные проверки не требуется.

Публикация HTTP-сервиса на веб-сервере

Чтобы созданный нами сервис стал доступен извне для скриптов PHP, проанализируем финальный шаг — публикацию базы.

Для публикации необходим настроенный веб-сервер (Apache или IIS). Перейдите в конфигураторе в меню Администрирование -> Публикация на веб-сервере. В открывшемся окне обязательно перейдите на вкладку HTTP-сервисы и установите галочку напротив созданного сервиса ApiIntegration. После нажатия кнопки публикации и перезапуска веб-сервера, ваш PHP-скрипт сможет отправлять POST-запросы по адресу вашей базы, безопасно создавая новые документы в обход всех проблемных проверок.

← На главную