B
B
boris tyrepharm2020-01-06 19:11:50
1C-Bitrix
boris tyrepharm, 2020-01-06 19:11:50

How to set the cost of deliveries during synchronization in Bitrix?

I ran into the following problem: when synchronizing, the site on Bitrix receives a JSON file with a customer order. You need to update data in an existing order.
When updating an order (I give a code fragment using Bitrix D7): if the shipment contains paid delivery, then its amount was "added" to the amount of delivery originally specified in the order.
For example, initially the user placed an order with a paid delivery of 500 rubles, later - after the order was processed by the accounting program - a sale of goods with the "Delivery" service was created at the cost of the same 500 rubles, so, as a result of importing the order to the site, the "Delivery cost" became is equal to 1000₽. That is, as if the delivery that was in the shipment "added" to the one already in the order, although in the import file the delivery cost for the order is 500 rubles, as well as for the shipment.

<?
$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();
?>

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Andrey Nikolaev, 2020-01-07
@borisevstratov

Let's take a closer look at your code fragment and imagine a hypothetical situation: you have 1 shipment created on your site, and after the exchange, 2 new shipments arrive from your system instead of the 1 existing one.
Let's start with what's in:

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

You get a collection of shipments. The collection of shipments is a set consisting of a system shipment + those created by the system or the user.
When processing an existing order with one shipment, you will get back a collection (object) with the contents of 2 shipments: system + yours.
Next, you iterate over incoming shipments
Those. it turns out you received 2 shipments and, accordingly, you will enter your cycle 2 times.
Fragment:
Will create another shipment. In other words, after executing the fragment in the collection of shipments, you will already have 4 shipments: system, original (which was on the site), as well as two new shipments that you created when iterating over imported shipments.
In this case, you have several options for the development of events:
1) You can clear the collection of shipments and create new ones. You will have a large number of order change events, but nevertheless this will give you more transparency in your process (not to mention ease of implementation).
2) Add a marker and update existing shipments using it - change the cost type, etc.
This will be more complex, but cleaner in terms of events in the system.
PS And as far as I remember, the delivery price PRICE_DELIVERY from order is like the sum of PRICE_DELIVERY (? CUSTOM_PRICE_DELIVERY) from all non-system shipments, so it's useless to set it.

A
Alexey Burlaka, 2020-01-06
@AlexeyGfi

You create shipments without checking for existence. This is inconsistent with " update data in an existing order ". In addition, there is always a system shipment in the order, even if there is only one shipment, there are actually two of them in the collection.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question