T
T
tgarl2020-02-13 17:27:11
PHP
tgarl, 2020-02-13 17:27:11

How to recalculate an order taking into account all discounts using the OnSaleOrderSaved event?

There is a checkout still on the old API. In Bitrix there is such a functional as additional services.
I need to make a choice of additional services in the design.

I added checkboxes. Based on these checkboxes, the order property is filled. Next, I use the OnSaleOrderSaved event where I check the property is full and, if not empty, put down the shipping cost. But the trouble is that shipping discounts are not taken into account. If you click to recalculate the order, then everything will fall into place as it should, but this is not an option, since customers pay for the order immediately, and managers are not aware that the order is not correctly calculated.
Here is my resulting code at the moment and I can’t figure out how to get around this situation.

spoiler

//событие OnSaleOrderSaved
public static function OnSaleOrderSavedEnded(Event $event)
    {
        $order = $event->getParameter('ENTITY');
        $isNew = $event->getParameter("IS_NEW");
        if ($isNew) {
         $orderProperties = $order->getPropertyCollection();
         $propertyValue = $orderProperties->getItemByOrderPropertyId(61)->getValue();
         if(intval($propertyValue)>0){
            $shipmentCollection = $order->getShipmentCollection();
            foreach ($shipmentCollection as $shipment)
            {
               if ($shipment->isSystem()) continue;
               $shipment->setExtraServices([$propertyValue=>'Y']);

               $resCalc = \Bitrix\Sale\Delivery\Services\Manager::calculateDeliveryPrice($shipment,$shipment->getField("DELIVERY_ID"));
               if($resCalc->isSuccess()){
                  $arShipments1 = $resCalc->getExtraServicesPrice();
                  $service = \Bitrix\Sale\Delivery\Services\Manager::getById($shipment->getField("DELIVERY_ID"));
                  $deliveryData = [
                     'DELIVERY_ID' => $service['ID'],
                     'DELIVERY_NAME' => $service['NAME'],
                     'ALLOW_DELIVERY' => 'N',
                     'PRICE_DELIVERY' => $arShipments1,
                     'BASE_PRICE_DELIVERY' => $arShipments1,
                     'CUSTOM_PRICE_DELIVERY' => 'N',
                     'CURRENCY' => $order->getCurrency(),
                  ];
                  $shipment->setFields($deliveryData);
               }                                
            }
            $now_order_id=$order->getId();
            $order->save();

            $order_resave = \Bitrix\Sale\Order::load($now_order_id);
            $discount = $order_resave->getDiscount();
            \Bitrix\Sale\DiscountCouponsManager::clearApply(true);
            \Bitrix\Sale\DiscountCouponsManager::useSavedCouponsForApply(true);
            $discount->setOrderRefresh(true);
            $discount->setApplyResult(array());

            if (!($basket = $order_resave->getBasket())) {
               throw new \Bitrix\Main\ObjectNotFoundException('Entity "Basket" not found');
            }

            $basket->refreshData(array('PRICE', 'COUPONS'));
            $discount->calculate();

            $order_resave->setField("PRICE", $order_resave->getPrice());
            $order_resave->save();
         }
      }
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Aisamiery, 2020-02-16
@Aisamiery

Firstly, you are not using the correct event, you should not use the save itself in the order save events, this usually leads to sad consequences. It is better to hang on events before saving, if you need to change the order exactly and so that it remains changed.
Secondly, it is not entirely clear what you are doing here, since you reset all discounts on the order, and then try to recalculate them

T
tgarl, 2020-02-19
@tgarl

I was wrong to refuse before. Need all the same at the event before saving. But the trouble remains that there is no recalculation of the final price, taking into account shipping discounts. Logically, the recalculation should be done by itself, but this does not happen. Order at your price, delivery at your own.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question