Добавление пользовательского ограничения на оплату в 1С-Битрикс


Описанным ниже способом можно добавить пользовательское ограничение на оплату, в данном случае добавляется ограничение на выбор способа оплаты, если в заказе есть товары “под заказ” (нулевое доступное количество в параметрах товара (торговый каталог)).

Доступное количество
Доступное количество

Создаем файл /local/Lib/Restrictions/OnOrderProductsInBasket.php 

<?php 

  

namespace Lib\Restrictions; 

  

use Bitrix\Sale\Internals\Entity; 

use Bitrix\Sale\Order; 

use Bitrix\Sale\Payment; 

use Bitrix\Sale\PaymentCollection; 

use Bitrix\Sale\Services\Base; 

  

/** 

* Ограничение платёжных систем, при наличию в корзине товаров «под заказ» 

*/ 

class OnOrderProductsInBasket extends Base\Restriction { 

  

    /** 

     * Метод проверки основного условия 

     * @param $courierUnavailable 

     * @param array $restrictionParams 

     * @param $deliveryId 

     * @return void 

     */ 

    public static function check($checkOnOrderItems, array $restrictionParams, $serviceId = 0) 

    { 

        if(empty($restrictionParams)){ 

            return true; 

        } 

  

        if($restrictionParams['ONORDERPRODUCTS_UNAVAILABLE'] == 'Y' && $checkOnOrderItems == true){ 

            $result = false; 

        } 

  

        if($restrictionParams['ONORDERPRODUCTS_UNAVAILABLE'] == 'Y' && $checkOnOrderItems == false){ 

            $result = true; 

        } 

  

        if($restrictionParams['ONORDERPRODUCTS_UNAVAILABLE'] == 'N' && $checkOnOrderItems == true){ 

            $result = false; 

        } 

  

        return $result; 

    } 

  

    /** 

     * Название ограничения 

     * @return mixed 

     */ 

    public static function getClassTitle() 

    { 

        return 'По наличию товаров "не в наличии" в корзине'; 

    } 

  

    /** 

     * Описание ограничения 

     * @return mixed 

     */ 

    public static function getClassDescription() 

    { 

        return 'Ограничение по наличию товаров "не в наличии" в корзине.'; 

    } 

  

    protected static function extractParams(Entity $entity) 

    { 

        if ($entity instanceof Payment) { 

            /** @var PaymentCollection $collection */ 

            $collection = $entity->getCollection(); 

            /** @var Order $order */ 

            $order = $collection->getOrder(); 

            /** И вот тут проверяем, есть ли в заказе заказная позиция */ 

            $basket = $order->getBasket(); 

            if($basket){ 

                return self::checkOnOrderItems($basket); 

            } 

  

        } else { 

            return -1; 

        } 

  

        return 0; 

    } 

  

    /** 

     * Параметры для создания формы ограничения в админке (типа, дефолтных значений и т.д.) 

     * @param $entityId 

     * @return array[] 

     */ 

    public static function getParamsStructure($entityId = 0) 

    { 

        return [ 

            "ONORDERPRODUCTS_UNAVAILABLE" => [ 

                "TYPE" => "Y/N", 

                "DEFAULT" => "Y", 

                'MIN' => 0, 

                "LABEL" => 'Доступно только для заказов, в которых нет товаров, которых нет в наличии' 

            ], 

        ]; 

    } 

  

    /** 

     * Проверяем, есть ли в заказе товары не в наличии 

     * @param \Sale\Basket $basket 

     * @return void 

     */ 

    public static function checkOnOrderItems($basket) 

    { 

        $isOnOrderItems = false; 

        //Получим массив ID товаров с меткой "Под заказ" 

        $arOnOrderProductsId = self::getOnOrderedProductsId(); 

        //Получим товары корзины пользователя 

        $products = $basket->getBasketItems(); 

        //И проверим, есть ли в корзине товары из списка "Под заказ" 

        foreach ($products as $itemIndex => $product) { 

            $offerId = $product->getProductId(); 

            if(in_array($offerId, $arOnOrderProductsId)){ 

                //Если такие товары найдены, меняем флаг наличия товаров под заказ на true 

                $isOnOrderItems = true; 

            } 

        } 

  

        return $isOnOrderItems; 

    } 

  

    /** 

     * Получить список товаров с меткой "Под заказ" 

     * @return array 

     */ 

    public static function getOnOrderedProductsId() 

    { 

        $productsForOrdered = []; 

        $arSelect = ['ID']; 

        $arFilter = ['IBLOCK_ID'=>$arFields['IBLOCK_ID'], '<CATALOG_QUANTITY'=>1]; 

        $res = \CIBlockElement::GetList(['ID'=>'ASC'], $arFilter, false, false, $arSelect); 

        while($ob = $res->GetNextElement()) 

        { 

            $arFields = $ob->GetFields(); 

            $productsForOrdered[] = $arFields['ID']; 

        } 

        return $productsForOrdered; 

    } 

} 

Далее добавляем код в обработчик пользовательских событий init.php (/local/php_interface/init.php)

Bitrix\Main\Loader::registerAutoLoadClasses(null, [ 

    'Lib\Restrictions\OnOrderProductsInBasket' => Bitrix\Main\Application::getDocumentRoot() . '/local/Lib/Restrictions/OnOrderProductsInBasket.php', 

]); 

$eventManager = Bitrix\Main\EventManager::getInstance(); 

$eventManager->addEventHandler( 

    'sale', 

    'onSalePaySystemRestrictionsClassNamesBuildList', 

    'customPaySystemRestrictionAdd' 

); 

function customPaySystemRestrictionAdd(){ 

    return new Bitrix\Main\EventResult( 

        Bitrix\Main\EventResult::SUCCESS, 

        [ 

            'Lib\Restrictions\OnOrderProductsInBasket' => '/local/Lib/Restrictions/OnOrderProductsInBasket.php', 

        ] 

    ); 

} 

Далее в ограничениях платежной системы (Магазин -> Настройки -> Платежные системы) появится наше добавленное ограничение и его можно будет применить.

Ограничение платежной системы