Почему изменения в OnSaleComponentOrderCreated не влияют на свойства заказа

При доработке оформления заказа в 1С-Битрикс часто возникает задача автоматически заполнять свойства заказа после его создания. Для этого разработчики обычно используют событие:

AddEventHandler(
"sale",
"OnSaleComponentOrderCreated",
"OnSaleComponentOrderCreatedFunction"
);

function OnSaleComponentOrderCreatedFunction(
$order,
&$arUserResult,
$request,
&$arParams,
&$arResult
)
{
}

На первый взгляд кажется, что если массив $arUserResult передаётся по ссылке, то можно изменить свойства заказа прямо в обработчике. Но на практике это работает не совсем так.

Что смутило

В сигнатуре события часть параметров передаётся по ссылке:

&$arUserResult
&$arParams
&$arResult

Логично предположить, что можно изменить данные пользователя:

$arUserResult['ORDER_PROP'][7] = 'prop_value';

и новое значение попадёт в заказ.

Однако после выполнения обработчика никаких изменений в заказе не происходит.

Почему так происходит

Передача по ссылке означает только одно: событие позволяет изменить содержимое переменной в памяти.

Например:

$arUserResult['ORDER_PROP'][7] = 'Новое значение';

действительно изменит массив $arUserResult.

Но это не означает, что Битрикс автоматически сохранит эти данные в заказ.

Важно понимать разницу между:

  • изменением переменной;

  • изменением объекта заказа;

  • сохранением данных в базе.

Событие даёт доступ к данным компонента, но не гарантирует дальнейшее использование изменённого массива.

Как проверить, что изменения происходят

Если открыть исходный код компонента sale.order.ajax, можно увидеть, что после события содержимое массива действительно меняется.

То есть ссылка работает корректно.

Проблема заключается в другом: дальнейшая логика компонента может уже не использовать изменённые данные для сохранения заказа.

Из-за этого разработчику кажется, что изменения «не сработали».

Где нужно менять данные заказа

Во время анализа компонента было обнаружено, что массив пользовательских данных формируется внутри механизма:

synchronizeOrder()

Однако для модификации пользовательских данных существует более подходящее событие:

OnSaleComponentOrderUserResult

Именно на этом этапе изменения массива $arUserResult влияют на дальнейшую обработку заказа.

Поэтому если требуется:

  • изменить свойства заказа;

  • подставить дополнительные значения;

  • изменить данные покупателя;

  • заполнить свойства автоматически;

то лучше использовать OnSaleComponentOrderUserResult, а не OnSaleComponentOrderCreated.

Когда использовать OnSaleComponentOrderCreated

Событие удобно использовать, когда объект заказа уже сформирован:

$order

и требуется выполнить дополнительные действия:

  • записать информацию в собственные таблицы;

  • отправить данные во внешнюю систему;

  • выполнить расчёты;

  • изменить объект заказа через API модуля Sale.

Но рассчитывать на изменение массива $arUserResult на этом этапе обычно не стоит.

Вывод

Передача аргументов по ссылке в событии OnSaleComponentOrderCreated действительно позволяет изменить содержимое массивов $arUserResult, $arParams и $arResult.

Однако это не означает, что изменения автоматически попадут в заказ.

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

OnSaleComponentOrderUserResult

Перед внедрением любых доработок полезно изучить последовательность вызова событий внутри sale.order.ajax. Это позволяет выбрать правильную точку расширения и избежать ситуации, когда изменения есть в памяти, но не влияют на итоговый заказ.