Вы пошли в правильное направление - реализация ограничения.
Вот код. Написал но не проверял. По идее должен работать. Переделал по быстрому по образцу с другого ограничения.
Подключение обработчика события:
$bxEventManager = \Bitrix\Main\EventManager::getInstance();
$bxEventManager->addEventHandler(
'sale',
'onSalePaySystemRestrictionsClassNamesBuildList',
array(
\Gricuk\Sale\Payment\Restrictions\ByMeasure::class,
"onSalePaySystemRestrictionsClassNamesBuildList"
)
);
Класс с ограничением:
<?php
namespace Gricuk\Sale\Payment\Restrictions;
use Bitrix\Catalog\MeasureTable;
use Bitrix\Sale\Internals\Entity;
use Bitrix\Sale\Payment;
/** Ограничение по единицам измерения
* Class ByMeasure
* @package Gricuk\Sale\Payment\Restrictions
*/
class ByMeasure extends \Bitrix\Sale\Services\Base\Restriction
{
public static function onSalePaySystemRestrictionsClassNamesBuildList()
{
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
array(
self::class => '/local/php_interface/lib/Gricuk/Sale/Payment/Restrictions/ByMeasure.php',
)
);
}
public static function getClassTitle()
{
return 'По единицам измерения товаров в корзине';
}
public static function getClassDescription()
{
return 'Оплата будет НЕ доступна для указанных единиц измерения';
}
/** Выполняет проверку на наличие в массиве $measures единиц измерения, указанных в настройках ограничения
* @param $userId
* @param array $restrictionParams
* @param int $serviceId
* @return bool - true нет ограничения, единиц измерения из настроек нет у товаров в корзине.
* false - ограничение сработало, в корзине есть товары с указанными единицами измерения
*/
public static function check($measures, array $restrictionParams, $serviceId = 0)
{
if (empty($restrictionParams["MEASURES"]) || empty($measures)) {
return true;
}
if (count(array_intersect($measures, $restrictionParams["MEASURES"])) > 0) {
return false;
} else {
return true;
}
}
/**Преобразует $entity в то что будет передано в первый параметр метода self::check
* @param Entity $paysystem
* @return mixed|string|null
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\NotImplementedException
*/
protected static function extractParams(Entity $entity)
{
$measures = [];
if ($entity instanceof Payment) {
$order = $entity->getOrder();
if (!$order) {
return $measures;
}
$products = [];
/** @var \Bitrix\Sale\BasketItem $basketItem */
foreach ($order->getBasket() as $basketItem) {
$products[] = $basketItem->getProductId();
}
if (!empty($products)) {
$measures = array_column(\Bitrix\Catalog\ProductTable::getList([
"select" => ["MEASURE"],
"filter" => [
"ID" => $products
]
])->fetchAll(), "MEASURE");
}
}
return array_unique($measures);
}
/** Возвращает массив параметров, описывающий ограничение
* @param int $entityId
* @return array
*/
public static function getParamsStructure($entityId = 0)
{
$result = array(
"MEASURES" => array(
"TYPE" => "ENUM",
'MULTIPLE' => 'Y',
"LABEL" => "Единицы измерения",
"OPTIONS" => self::getMeasures()
)
);
return $result;
}
/**Возвращает массив единиц измерения
* @return array|mixed
* @throws \Bitrix\Main\ArgumentException
* @throws \Bitrix\Main\ObjectPropertyException
* @throws \Bitrix\Main\SystemException
*/
public static function getMeasures()
{
static $result = null;
if ($result !== null)
return $result;
$result = [];
$dbResultList = MeasureTable::getList(array(
'select' => array("ID", "MEASURE_TITLE"),
'order' => array("ID" => "ASC")
));
while ($measure = $dbResultList->fetch()) {
$result[$measure["ID"]] = $measure["MEASURE_TITLE"];
}
return $result;
}
}