bitrix Вывод доставки в зависимости от маржи в корзине (ограничения способов доставки)

В битрикс приходит информация о закупочной цене и РРЦ.

Задача выводить определенный тип доставки в зависимости от маржи всей корзины, если маржа больше 3000р. — то бесплатная доставка по городу.

Изначально при экспорте товаров, сформировал свойство усл. «маржа», записываю в него маржу товара. Создаю новую доставку в «службах доставок».

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

Мы можем дополнить стандартный набор ограничений своими собственными. Для этого используется событие onSaleDeliveryRestrictionsClassNamesBuildListю

Для этого, вешаем обработчик и создаем свой класс

$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler(
    'sale',
    'onSaleDeliveryRestrictionsClassNamesBuildList',
    'myDeliveryRestrictions'
);

function myDeliveryRestrictions()
{
    return new \Bitrix\Main\EventResult(
        \Bitrix\Main\EventResult::SUCCESS,
        array(
            '\MyDeliveryRestriction' => '/путь_до_вашего_класса/class/restriction.php',
        )
    );
}

ОГРАНИЧЕНИЯ В СЛУЖБАХ ДОСТАВКИ БИТРИКС D7

Минимальный класс ограничения службы доставки

class MyRestriction extends Bitrix\Sale\Delivery\Restrictions\Base
{
    public static function getClassTitle()
    {
        return 'Моё собственное ограничение';
    }

    public static function getClassDescription()
    {
        return 'Моё собственное ограничение для службы доставки';
    }

    protected static function extractParams(Bitrix\Sale\Shipment $shipment)
    {
        return null;
    }

    public static function getParamsStructure($deliveryId = 0)
    {
        return array();
    }

    public static function check($shipmentParams, array $restrictionParams, $deliveryId = 0)
    {
        return true;
    }
}

getClassTitle() — Наименование ограничения

getClassDescription() — описание ограничения

extractParams() —  принимает объект отгрузки Bitrix\Sale\Shipment и должен подготовить необходимые данные для проверки ограничения и вернуть их. Далее эти данные передаются в метод check.

Пример расчета маржи из свойств товаров в корзине extractParams()

protected static function extractParams(\Bitrix\Sale\Internals\Entity $shipment)
    {
        $mxResult = false;
        // Получаем товары в корзине:

        $i = 0;
        foreach ($shipment->getShipmentItemCollection() as $shipmentItem) {
            /** @var \Bitrix\Sale\BasketItem $basketItem - запись в корзине */
            $basketItem = $shipmentItem->getBasketItem();
            $productId = $basketItem->getProductId(); // Получим id товара

            $basketCountItem = $shipmentItem->getQuantity(); // Получим конкретного товара в корз

            // Если товар ТП - получим данные элемента ИБ по ID ТП, в противном случае - по текущему ID
            $tpInfo = CCatalogSku::GetProductInfo(
                $productId
            );
            if (is_array($tpInfo)) {
                $mxResult[$i] = $tpInfo;
            } else {
                $mxResult[$i] = \CIBlockElement::GetByID($productId)->Fetch();
            }
            // добавляем количество товара в корзине, в маcсив передающейся в check
            if (!empty($basketCountItem)) {
                $mxResult[$i]["basket_count"] = $basketCountItem;
            }

            $i++;
        }

        return $mxResult;
    }

Пример от mrcappuccino.ru extractParams()

protected static function extractParams(Bitrix\Sale\Shipment $shipment)
{
    $someShipmentParams = array();

    // Получаем товары в корзине:
    foreach ($shipment->getShipmentItemCollection() as $shipmentItem) {
        /** @var \Bitrix\Sale\BasketItem $basketItem - запись в корзине*/
        $basketItem = $shipmentItem->getBasketItem();
        // ...
    }

    // Получаем информацию о заказе:
    /** @var \Bitrix\Sale\ShipmentCollection $collection - коллекция всех отгрузок в заказе */
    $collection = $shipment->getCollection();
    /** @var \Bitrix\Sale\Order $order - объект заказа*/
    $order = $collection->getOrder();

    // Получаем выбранные оплаты:
    /** @var \Bitrix\Sale\Payment $payment - объект оплаты */
    foreach($order->getPaymentCollection() as $payment) {
        /** @var int $paySystemId - ID способа оплаты*/
        $paySystemId = $payment->getPaymentSystemId();
        // ...
        $someShipmentParams["paySystem"] = $paySystemId;
    }
    //...

    return $someShipmentParams;
}

getParamsStructure должен возвращать массив параметров ограничения. Если ограничения не требует настройки, то возвращается пустой массив.

Пример с маржой в корзине getParamsStructure()

 public static function getParamsStructure($deliveryId = 0)
    {
        return array(
            "PARAM_VALUE" => array(
                'TYPE' => 'STRING',
                'LABEL' => 'Минимальная сумма маржи',
            ),
            "PARAM_ACTION" => array(
                "TYPE" => "ENUM",
                'MULTIPLE' => 'N',
                "OPTIONS" => array(
                    'Y' => 'Отображать доставку',
                    'N' => 'Скрывать доставку',
                ),
                "LABEL" => 'Действие',
            ),
        );
    }

Пример от mrcappuccino.ru getParamsStructure()

public static function getParamsStructure($deliveryId = 0)
{
    return array(
        "MY_PARAM_CHECKBOX" => array(
            'TYPE' => 'Y/N',
            'VALUE' => 'Y',
            'LABEL' => 'Галочка',
        ),
        "MY_PARAM_ENUM" => array(
            "TYPE" => "ENUM",
            'MULTIPLE' => 'Y',
            "OPTIONS" => array(1 => "Первый вариант", 2 => "Второй вариант"),
            "LABEL" => 'Список',
        ),
        "MY_PARAM_NUMBER" => array(
            'TYPE' => 'NUMBER',
            'DEFAULT' => "0",
            'MIN' => 0,
            'LABEL' => 'Число',
        ),
    );
}

Метод check выполняет основную работу и должен возвращать true, если данная служба доставки доступна при данных параметрах. Первый аргумент — $shipmentParams — параметры отгрузки, те самые, которые вернул метод extractParams. Второй аргумент — $restrictionParams — параметры ограничения. Третий аргумент — $deliveryId — ID службы доставки. Например, extractParams вернул массив с ИД платежной системы, а в MY_PARAM_NUMBER пользователь ограничивает доставку необходимым ИД:

Пример от mrcappuccino.ru check()

public static function check($shipmentParams, $restrictionParams, $deliveryId = 0)
{
    if (intval($deliveryId) <= 0) {
        return true;
    }

    return $restrictionParams["MY_PARAM_NUMBER"] == $shipmentParams["paySystem"];
}

Пример из задачи по марже check()

В «PROPERTY_MARGIN_PRICE» содержится маржа товара

public static function check($arData, array $restrictionParams, $deliveryId = 0)
    {
        /* для корректной работы, нам нужно инвертировать значение стартового параметра $restrictionParams['PARAM_ACTION']
            Если он выставлен в настроках на Y - то выставить N и наоборот*/
        $visibleDelivery = (($restrictionParams['PARAM_ACTION'] == 'Y') ? 'N' : 'Y');

        $cartMargin = 0;

        foreach ($arData as $data) {

            $arPriceBase = \CIBlockElement::GetProperty(
                $data['IBLOCK_ID'],
                $data['ID'],
                array('sort' => 'asc'),
                array('CODE' => "PROPERTY_MARGIN_PRICE"))->Fetch();

            if (!empty($arPriceBase)){
                if (!empty($data["basket_count"])){
                    $sumMarginElement = (int)$arPriceBase["VALUE"] * (int)$data["basket_count"];
                    $cartMargin += $sumMarginElement;
                } else {
                    $cartMargin += (int)$arPriceBase["VALUE"];
                }
            }

            if($cartMargin > $restrictionParams['PARAM_VALUE']){
                break;
            }
        }

        if($cartMargin > $restrictionParams['PARAM_VALUE']){
            return true;
        } else {
            return false;
        }

    }

Источник
Оцените статью
Разработчик на bitrix и wordpress