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

Создаем файл /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',
]
);
} Далее в ограничениях платежной системы (Магазин -> Настройки -> Платежные системы) появится наше добавленное ограничение и его можно будет применить.
