Answer the question
In order to leave comments, you need to log in
How to update order properties and change payer type in Bitrix?
Orders from Bitrix are uploaded to the accounting program, and then, after processing, they arrive back in the form of an unloading XML file.
Sometimes the counterparty changes in the accounting program: it is necessary that in the order of Bitrix it also changes in accordance with the data from XML.
The XML parser has already been written. And the function is successfully hung up on the "OnSaleOrderBeforeSaved" event. The only thing that does not work is to save the new data to the order, deleting the old ones.
Example: the counterparty was:
[1] Ваше ФИО: Дмитрий
[21] Получатель: Дмитрий Иванов
[20] Паспортные данные: 0000 123456
[2] E-Mail: [email protected]
[3] Телефон: +7 (000) 111-22-33
[4] Индекс: 190000
[7] Адрес доставки: Санкт-Петербург, Невский пр.
[8] Название компании: ООО "ОРГАНИЗАЦИЯ"
[10] ИНН: 7800000000
[11] КПП: 780000000
[25] ОГРН: 10000000000
[9] Юридический адрес: 190000 ГОРОД САНКТ-ПЕТЕРБУРГ, НЕВСКИЙ ПРОСПЕКТ, ДОМ 1
[24] Физический адрес: 190000 ГОРОД САНКТ-ПЕТЕРБУРГ, НЕВСКИЙ ПРОСПЕКТ, ДОМ 1
[26] Расчётный счёт: 40000000000000001
[29] Наименование банка: Филиал ПАО Банка «БАНК» г. Санкт-Петербург
[28] Корреспондентский счёт: 30000000000009
[27] БИК: 000000011
[12] Контактное лицо: Иван Петров
[13] E-Mail: [email protected]
[14] Телефон: +7 (999) 999-99-99
[44] Получатель: Семен
[16] Индекс: 190000
[19] Адрес доставки: г Санкт-Петербург, Московское шоссе, д.1
$propertyCollection = $OrderBX->getPropertyCollection();
foreach ($propertyCollection as $Prop)
{
echo '['.$Prop->getPropertyId().'] '.$Prop->getName().': '.$Prop->getValue().'<br>';
}
// 1. Формирование нового профиля
$arProfileFields = array(
"NAME" => $NAME,
"USER_ID" => $UID,
"PERSON_TYPE_ID" => $PID
);
$PROPS = array ( ... );
$PROFILE_ID = CSaleOrderUserProps::Add($arProfileFields);
foreach ($PROPS as $prop)
{
CSaleOrderUserPropsValue::Add($prop);
}
$newUserIDBX = $PROFILE_ID;
// 2. Удалим все свойства заказа
$orderProperties = $OrderBX->getPropertyCollection();
foreach ($orderProperties as $orderProperty) {
$Del = $orderProperty->getPropertyId();
$orderProperty->delete($Del);
}
$orderProperties->save();
// 3. Установим новый тип плательщика
$OrderBX->setPersonTypeId(intval($PID));
// 4. Получим свойства профиля $newUserIDBX и назначим соответствующие им ORDER_PROPS
$profileProperties = Sale\OrderUserProperties::getProfileValues(intval($newUserIDBX));
$propertyCollection = $OrderBX->getPropertyCollection();
foreach ($profileProperties as $propId => $propVal) {
$orderPropValue = $propertyCollection->getItemByOrderPropertyId($propId);
$orderPropValue->setValue($propVal);
}
// Сохраним
$propertyCollection->save();
[Error]
Call to a member function setValue() on null (0)
/home/bitrix/www/bitrix/php_interface/init.php:1020
Answer the question
In order to leave comments, you need to log in
Try this
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler('sale', 'OnSaleOrderBeforeSaved', 'orderModify');
function orderModify(Bitrix\Main\Event $event)
{
global $USER;
/** @var \Bitrix\Sale\Order $order */
$order = $event->getParameter('ENTITY');
$personTypeId = 3;
$profileId = CSaleOrderUserProps::DoSaveUserProfile($USER->GetID(), null, 'Профиль ' . random_int(0, 500), $personTypeId,
// код свойства и его значение
[
20 => random_int(100, 900),
21 => random_int(500, 599)
], $errors);
// Получаем текущую коллекцию свойств заказа и удаляем все свойства
/** @var \Bitrix\Sale\PropertyValueCollection $orderProperties */
$orderProperties = $order->getPropertyCollection();
/** @var \Bitrix\Sale\PropertyValue $orderProperty */
foreach ($orderProperties as $orderProperty) {
$orderProperty->delete();
}
// Меняем тип плательщика
$order->setPersonTypeId($personTypeId);
// Далее взято из \Bitrix\Sale\PropertyValueCollection::load()
// Т.к. на объекте заказа уже была получена коллекция, то при вызове $order->getPropertyCollection(),
// коллекция не будет заполнена свойствами под новый тип плательщика.
// Поэтому нужно добавлять свойства вручную
// Получаем список свойств нового плательщика
$props = \Bitrix\Sale\PropertyValue::loadForOrder($order);
// Добавляем свойства к коллекции
/** @var \Bitrix\Sale\PropertyValue $prop */
foreach ($props as $prop) {
$prop->setCollection($orderProperties);
$orderProperties->addItem($prop);
// В своём коде напямую этого сделать не можем, т.к. метод и свойство имеют приватный доступ
// Но можно сделать обходным путём
// $orderProperties->setAttributes($prop);
// $orderProperties->propertyGroupMap[$prop->getGroupId() > 0 && isset($groups[$personTypeId][$prop->getGroupId()]) ? $prop->getGroupId() : 0][] = $prop;
}
// Получаем значения профиля
$profileProperties = \Bitrix\Sale\OrderUserProperties::getProfileValues($profileId);
// Записываем к заказу
$orderProperties->setValuesFromPost(array('PROPERTIES' => $profileProperties), array());
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question