@borisevstratov

Каким образом в Битриксе назначать стоимость доставок при синхронизации?

Столкнулся со следующей проблемой: при синхронизации сайт на Битрикс получает JSON-файл с заказом клиента. Требуется обновить данные в существующем заказе.
При обновлении заказа (привожу фрагмент кода с использованием Bitrix D7): если отгрузка содержит платную доставку, то её сумма "приплюсовывалась" к сумме доставке, изначально указанной в заказе.
Например, изначально пользователь оформил заказ с платной доставкой в 500₽, позже — после обработки заказа учётной программой — была создана реализация товаров с услугой "Доставка" стоимостью в те же 500₽, итак, в результате импорта заказа на сайт "Стоимость доставки" стала равна 1000₽. То есть, как будто, доставка, что была в отгрузке "приплюсовалась" к уже имеющейся в заказе, хотя и в файле импорта стоимость доставки для заказа равно 500₽, как и для отгрузки.
<?
$importJson = file_get_contents('php://input');
$orderBx = Sale\Order::loadByAccountNumber($importJson['Info']['Id']);

// ...

// создаём отгрузки
$shipmentCollection = $orderBx->getShipmentCollection();

// отгрузок может быть несколько
foreach (importJson['Shipments'] as $importOrderShipment)
{
    $shipment = $shipmentCollection->createItem();
    $shipment->setAccountNumber($orderBx->getId());
    $shipmentItemCollection = $shipment->getShipmentItemCollection();
    
    foreach ($importOrderShipment['Items'] as $item)
    {
        // добавляем элементы корзины из файла импорта
    }
    
    $shipment->setStoreId($importOrderShipment['StoreId']); // id склада
    $service = \Bitrix\Sale\Delivery\Services\Manager::getById($importOrderShipment['DeliveryId']);	// id способа доставки

    $shipment->setFields([
        'STATUS_ID' => 'DF',
        'DEDUCTED' => 'Y',
        'COMPANY_ID' => 1,
        'DATE_DEDUCTED' => \Bitrix\Main\Type\DateTime::createFromTimestamp($importOrderShipment['Date']),
        'DELIVERY_ID' => $service['ID'],
        'DELIVERY_NAME' => $service['NAME'],
        'DELIVERY_DOC_NUM' => $importOrderShipment['Document'],
        'DELIVERY_DOC_DATE' => \Bitrix\Main\Type\DateTime::createFromTimestamp($importOrderShipment['Date']),
        'COMMENTS' => $importOrderShipment['Comments'],
        'CURRENCY' => $orderBx->getCurrency(),
        'PRICE_DELIVERY' => $importOrderShipment['DeliveryPrice'], // в данном случае только одна отгрузка с $importOrderShipment['DeliveryPrice'] = 500;
        'BASE_PRICE_DELIVERY' => $importOrderShipment['DeliveryPrice'],
        'UPDATED_1C' => 'Y'
    ]);
    
    $shipment->allowDelivery();
}

// Установим значение "стоимость доставки" из файла импорта
// $importJson['DeliveryPrice'] = 500;
$orderBx->setFieldNoDemand('PRICE_DELIVERY', $importJson['DeliveryPrice']);

$orderBx->save();
?>
  • Вопрос задан
  • 3344 просмотра
Решения вопроса 1
gromdron
@gromdron
Работаю с Bitrix24
Давайте разберем чуть подробнее ваш фрагмент кода и представим гипотетическую ситуацию: у вас на сайте создана 1 отгрузка, а после обмена из вашей системы прилетает 2 новые отгрузки, вместо 1 существовавшей.

Начнем с того что в:
// создаём отгрузки
$shipmentCollection = $orderBx->getShipmentCollection();


Вы получаете коллекцию отгрузок. Коллекция отгрузок представляет из себя набор, состоящий из системной отгрузки + созданных системой или пользователем.
При обработке существующего заказа с одной отгрузкой вам вернется коллекция (объект) с содержимым в 2 отгрузки: системная + ваша.

Далее, вы производите итерацию по пришедшим отгрузкам
foreach (importJson['Shipments'] as $importOrderShipment)

Т.е. получается вам пришло 2 отгрузки и соответственно вы 2 раза зайдете в ваш цикл.

Фрагмент:
$shipment = $shipmentCollection->createItem();
Создаст еще одну отгрузку. Иными словами после выполнения фрагмента в коллекции отгрузок у вас будет уже 4 отгрузки: системная, исходная (которая была на сайте), а так же две новых отгрузки, которые вы создали при итерировании по импортируемым отгрузкам.

В данном случае у вас есть несколько вариантов развития событий:
1) Вы можете очищать коллекцию отгрузок и создавать новые. Событий на изменение заказа у вас будет большое количество, но тем не менее это даст вам больше прозрачности в вашем процессе (не говоря уже о простоте реализации).

2) Добавить маркер и по нему обновлять существующие отгрузки - менять стоимость тип и т.п.
Это будет сложнее, но при этом чище с точки зрения событий в системе.

P.S. И насколько я помню, цена доставки PRICE_DELIVERY из order это вроде как сумма PRICE_DELIVERY (?CUSTOM_PRICE_DELIVERY) из всех не системных отгрузок, так что задавать его бесполезно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@Evanescing
Изменение стоимости доставки заказа с созданными отгрузками:
$shipmentCollection = $orderBx->getShipmentCollection();
$shipment = $shipmentCollection->createItem();

или
$shipmentCollection = $orderBx->getShipmentCollection();
$shipment = $shipmentCollection->createItem(
	Delivery\Services\Manager::getObjectById($deliveryID) // ID службы доставки
);

Установка стоимости доставки
$price = 123;
$shipment->setBasePriceDelivery($price);
Ответ написан
Комментировать
AlexeyGfi
@AlexeyGfi
YouTube >>> Битриксоид из Колхоза
Вы создаете отгрузки без проверки на существование. Это не стыкуется с «обновить данные в существующем заказе». К тому же в заказе всегда присутствует сисемная отгрузка, даже если отгрузка одна, в коллекции их фктически две.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы