Skip to content

Instantly share code, notes, and snippets.

@dmitryburov
Last active March 17, 2023 13:17
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save dmitryburov/878edc4aec1477d54f92913cd5e25cbf to your computer and use it in GitHub Desktop.
Save dmitryburov/878edc4aec1477d54f92913cd5e25cbf to your computer and use it in GitHub Desktop.
Данная кастомизация позволяет использовать свои ограничения в службах доставки или платежных системах. Результат для ПС - http://prntscr.com/mo1y77 и результат для СД - http://prntscr.com/mo1zu1
<?php
namespace Burov\Handlers;
/**
* Class Restrictions
* @package Burov\Handlers
* @link https://gist.github.com/burovofficial/878edc4aec1477d54f92913cd5e25cbf
*
* В данном примере используюется кастомизация и добавление своих ограничений (рестрикций)
* для служб доставок и платежных систем
*
* Добавление события для служб (в init.php, например)
* \Bitrix\Main\EventManager::getInstance()->addEventHandler('sale', 'onSalePaySystemRestrictionsClassNamesBuildList', array('\\Burov\\Handlers\\Restrictions', 'onCheckRulePayment');
* \Bitrix\Main\EventManager::getInstance()->addEventHandler('sale', 'onSaleDeliveryRestrictionsClassNamesBuildList', array('\\Burov\\Handlers\\Restrictions', 'onCheckRuleDelivery');
*
* И регистрируем наш класс
* \Bitrix\Main\Loader::registerAutoLoadClasses(null, array('\\Burov\\Handlers\\Restrictions' => '/bitrix/php_interface/classes/restrictions.php'));
*/
class Restrictions
{
/**
* Ограничения для платежных систем
* @return \Bitrix\Main\EventResult
*/
function onCheckRulePayment()
{
$filePayments = '/bitrix/php_interface/classes/restrictions/payments.php';
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
array(
'\checkPayBrand' => $filePayments, // по бренду
'\checkPayDiscount' => $filePayments, // по скидкам
)
);
}
/**
* Ограничения для доставок
* @return \Bitrix\Main\EventResult
*/
function onCheckRuleDelivery()
{
$fileDelivery = '/bitrix/php_interface/classes/restrictions/delivery.php';
return new \Bitrix\Main\EventResult(
\Bitrix\Main\EventResult::SUCCESS,
array(
'\checkDeliveryUserGroup' => $fileDelivery, // по группе пользователя
'\checkDeliveryStore' => $fileDelivery, // по наличию на складе
'\checkDeliveryBrand' => $fileDelivery, // по бренду
)
);
}
}
<?php
use Bitrix\Sale\Delivery\Restrictions;
use Bitrix\Sale\Internals\Entity;
\Bitrix\Main\Loader::includeModule('highloadblock');
/**
* Class checkDeliveryUserGroup
* Проверка на наличие группы пользователя
*/
class checkDeliveryUserGroup extends Restrictions\Base
{
public static $easeSort = 200;
public static function getClassTitle()
{
return 'по группе пользователя';
}
public static function getClassDescription()
{
return 'Правило позволяет отображать доставку только пользователям, принадлежащим к указанным группам.';
}
/**
* Проверяем
* @param $userGroups
* @param array $restrictionParams
* @param int $deliveryId
* @return bool
*/
public static function check($userGroups, array $restrictionParams, $deliveryId = 0)
{
if(is_array($restrictionParams) && is_array($userGroups))
{
foreach ($restrictionParams['GROUPS'] as $group)
{
if(in_array($group, $userGroups)) return true;
}
}
return false;
}
/**
* Вернем в параметры проверки текущие группы пользователя
* @param \Bitrix\Sale\Shipment $shipment
* @return array|mixed
*/
protected static function extractParams(Bitrix\Sale\Shipment $shipment)
{
$USER = new \CUser();
return $USER->GetUserGroupArray();
}
/**
* Получим перчень всех групп сайта
* @param int $entityId
* @return array
* @throws \Bitrix\Main\ArgumentException
*/
public static function getParamsStructure($entityId = 0)
{
$resGroups = \Bitrix\Main\GroupTable::getList([]);
$arGroups = array();
if (!empty($resGroups))
while($group = $resGroups->fetch())
$arGroups[$group['ID']] = $group['NAME'];
return array(
"GROUPS" => array(
"TYPE" => "ENUM",
'MULTIPLE' => 'Y',
"OPTIONS" => $arGroups,
"LABEL" => 'Группы пользователя',
)
);
}
}
/**
* Class checkDeliveryStore
* Проверка на наличие остатов на складе
*/
class checkDeliveryStore extends Restrictions\Base
{
public static $easeSort = 100;
public static function getClassTitle()
{
return 'по наличию на складе';
}
public static function getClassDescription()
{
return 'Будет произведена проверка оформляемой корзины на наличие товаров на выбранном складе.';
}
/**
* Проверяем
* @param $shipmentData
* @param array $restrictionParams
* @param int $deliveryId
* @return bool
*/
public static function check($shipmentData, array $restrictionParams, $deliveryId = 0)
{
$allowShow = true;
$accessStores = array();
if(!empty($shipmentData) && is_array($shipmentData)
&& !empty($restrictionParams) && is_array($restrictionParams))
{
// склады
foreach ($restrictionParams['STORES'] as $store)
{
$isAllinStock = true;
//товары
foreach ($shipmentData as $arProduct)
{
// если недостаточно товара на складе
if($arProduct['AMOUNTS'][$store] < $arProduct['QUANTITY'])
$isAllinStock = false;
}
if($isAllinStock) $accessStores[$store] = true;
else $accessStores[$store] = false;
}
// не подходит по условиям
if(!in_array(true, $accessStores)) $allowShow = false;
}
return $allowShow;
}
/**
* Получим из отгрузки и корзины данные для проверки
* @param \Bitrix\Sale\Shipment $shipment
* @return array|mixed
* @throws \Bitrix\Main\ArgumentException
*/
protected static function extractParams(Bitrix\Sale\Shipment $shipment)
{
$basketItems = array();
foreach ($shipment->getShipmentItemCollection() as $shipmentItem)
{
$productId = $shipmentItem->getProductId();
$arAmounts = array();
$resAmounts = \Bitrix\Catalog\StoreProductTable::getList([
'select' => ['AMOUNT', 'STORE_ID'],
'filter' => ['=PRODUCT_ID' => $productId]
]);
while($datAmount = $resAmounts->fetch())
$arAmounts[$datAmount['STORE_ID']] = $datAmount['AMOUNT'];
$basketItems[] = [
'ID' => $productId,
'QUANTITY' => $shipmentItem->getQuantity(),
'AMOUNTS' => $arAmounts
];
}
return $basketItems;
}
/**
* Сформируем перечень складов
* @param int $deliveryId
* @return array
*/
public static function getParamsStructure($deliveryId = 0)
{
return array(
"STORES" => array(
"TYPE" => "ENUM",
'MULTIPLE' => 'Y',
"OPTIONS" => self::getStoreList(),
"LABEL" => 'Наличие на складах',
)
);
}
/**
* Получение складов
* @return array
* @throws \Bitrix\Main\ArgumentException
*/
protected static function getStoreList()
{
$arStores = [];
$resStores = \Bitrix\Catalog\StoreTable::getList([]);
if (!empty($resStores))
while($store = $resStores->fetch())
$arStores[$store['ID']] = $store['TITLE'];
return $arStores;
}
}
/**
* Class checkDeliveryBrand
* Проверка на присутствие бренда в корзине
*/
class checkDeliveryBrand extends Restrictions\Base
{
public static $easeSort = 100;
public static function getClassTitle()
{
return 'по бренду';
}
public static function getClassDescription()
{
return 'доставка не будет исключаться, если присутствует разерешенный бренд';
}
/**
* Получим информацию по брендам из корзины
* @param \Bitrix\Sale\Shipment $shipment
* @return array|bool|mixed
*/
protected static function extractParams(Bitrix\Sale\Shipment $shipment)
{
if (!$shipment->getShipmentItemCollection())
return false;
$basketItems = array();
foreach ($shipment->getShipmentItemCollection() as $shipmentItem)
{
$productId = $shipmentItem->getProductId();
$arProduct = \Bitrix\Iblock\ElementTable::getById($productId)->fetch();
$arProperty = CIBlockElement::GetByID($productId)->GetNextElement()->GetProperties();
$basketItems[$productId] = $arProduct;
$basketItems[$productId]['PROPERTY'] = $arProperty;
}
return $basketItems;
}
/**
* Получаем перечень брендов
* @param int $deliveryId
* @return array
* @throws \Bitrix\Main\LoaderException
* @throws \Bitrix\Main\SystemException
*/
public static function getParamsStructure($deliveryId = 0)
{
// получаем список брендов
\Bitrix\Main\Loader::includeModule('highloadblock');
$arBrandsList = \Bitrix\Highloadblock\HighloadBlockTable::getById(ID_BRAND_HL)->fetch();
$arListBrand = array();
if (!empty($arBrandsList))
{
$hlentity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity($arBrandsList);
$hlDataClass = $arBrandsList['NAME'].'Table';
$res = $hlDataClass::getList(array('select' => array("*")));
while($row = $res->fetch())
{
$arListBrand[$row['ID']] = $row['UF_NAME'];
}
}
return array(
"BRAND_LIST" => array(
"TYPE" => "ENUM",
'MULTIPLE' => 'Y',
"OPTIONS" => $arListBrand,
"LABEL" => 'Разрешенные бренды',
)
);
}
/**
* Проверяем
* @param $arBasket
* @param array $restrictionParams
* @param int $deliveryId
* @return bool
* @throws \Bitrix\Main\LoaderException
* @throws \Bitrix\Main\SystemException
*/
public static function check($arBasket, array $restrictionParams, $deliveryId = 0)
{
// получаем список брендов
\Bitrix\Main\Loader::includeModule('highloadblock');
$arBrandsList = \Bitrix\Highloadblock\HighloadBlockTable::getById(ID_BRAND_HL)->fetch();
$arListBrand = array();
if (!empty($arBrandsList))
{
$hlentity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity($arBrandsList);
$hlDataClass = $arBrandsList['NAME'].'Table';
foreach ($arBasket as $basketItem)
{
$res = $hlDataClass::getList(array(
'select' => array("*"),
'filter' => array('=UF_XML_ID' => $basketItem['PROPERTY']['BRAND']['VALUE'])
))->fetch();
if($res['ID'])
{
if(in_array($res['ID'], $restrictionParams['BRAND_LIST'], true))
return true;
}
}
}
return false;
}
}
<?php
use Bitrix\Sale\Services\Base;
use Bitrix\Sale\Internals\CollectableEntity;
use Bitrix\Sale\Internals\Entity;
use Bitrix\Sale\Order;
\Bitrix\Main\Loader::includeModule('highloadblock');
/**
* Class checkPayBrand
* Класс для проверки на присутствии бренда (свойство справочник) в одном из товаров в корзине
*/
class checkPayBrand extends Base\Restriction
{
public static function getClassTitle()
{
return 'по бренду';
}
public static function getClassDescription()
{
return 'платежная система не будет выводится для выбранных брендов';
}
/**
* Проведем проверку
* @param $arBasket
* @param array $restrictionParams
* @param int $serviceId
* @return bool
* @throws \Bitrix\Main\SystemException
*/
public static function check($arBasket, array $restrictionParams, $serviceId = 0)
{
// получаем список брендов
$arBrandsList = \Bitrix\Highloadblock\HighloadBlockTable::getById(ID_BRAND_HL)->fetch();
$arListBrand = array();
if (!empty($arBrandsList))
{
$hlentity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity($arBrandsList);
$hlDataClass = $arBrandsList['NAME'].'Table';
foreach ($arBasket as $basketItem)
{
$res = $hlDataClass::getList(array(
'select' => array("*"),
'filter' => array('=UF_XML_ID' => $basketItem['PROPERTY']['BRAND']['VALUE'])
))->fetch();
if($res['ID'])
{
if(in_array($res['ID'], $restrictionParams['BRAND_LIST'], true))
return false;
}
}
}
return true;
}
/**
* Вернем корзину для проверки
* @param Entity $entity
* @return array|bool|mixed
* @throws \Bitrix\Main\LoaderException
*/
protected static function extractParams(Entity $entity)
{
if ($entity instanceof CollectableEntity) {
$collection = $entity->getCollection();
$order = $collection->getOrder();
} elseif ($entity instanceof Order) {
$order = $entity;
}
if (!$order->getBasket())
return false;
$basket = $order->getBasket();
$basketCollection = $basket->getBasketItems();
$returnBasket = array();
if (count($basketCollection) > 0) {
\Bitrix\Main\Loader::includeModule('highloadblock');
foreach ($basketCollection as $basketItem) {
$arProduct = \Bitrix\Iblock\ElementTable::getById($basketItem->getField('PRODUCT_ID'))->fetch();
$arProperty = CIBlockElement::GetByID($basketItem->getField('PRODUCT_ID'))->GetNextElement()->GetProperties();
$returnBasket[$basketItem->getField('PRODUCT_ID')] = $arProduct;
$returnBasket[$basketItem->getField('PRODUCT_ID')]['PROPERTY'] = $arProperty;
}
}
return $returnBasket;
}
/**
* Получим из highloadblock перечень брендов
* @param int $entityId
* @return array
* @throws \Bitrix\Main\LoaderException
* @throws \Bitrix\Main\SystemException
*/
public static function getParamsStructure($entityId = 0)
{
$arListBrand = array();
$arBrandsList = \Bitrix\Highloadblock\HighloadBlockTable::getById(ID_BRAND_HL)->fetch();
// получаем список брендов
if (!empty($arBrandsList))
{
$hlentity = \Bitrix\Highloadblock\HighloadBlockTable::compileEntity($arBrandsList);
$hlDataClass = $arBrandsList['NAME'].'Table';
$res = $hlDataClass::getList(array('select' => array("*")));
while($row = $res->fetch())
$arListBrand[$row['ID']] = $row['UF_NAME'];
}
// возвращаем список (ID => NAME)
return array(
"BRAND_LIST" => array(
"TYPE" => "ENUM",
'MULTIPLE' => 'Y',
"OPTIONS" => $arListBrand,
"LABEL" => 'Запрещенные бренды',
)
);
}
}
/**
* Class checkPayDiscount
* Класс для проверки на присутвии примененных скидок в заказе
*/
class checkPayDiscount extends Base\Restriction
{
public static function getClassTitle()
{
return 'по примененным скидкам';
}
public static function getClassDescription()
{
return 'если в заказе применена одна из скидок - оплата не выводится';
}
/**
* Произведем проверку
* @param $discountData
* @param array $restrictionParams
* @param int $serviceId
* @return bool
*/
public static function check($discountData, array $restrictionParams, $serviceId = 0)
{
// примененные скидки в корзине и заказе
$applyDiscountList = array_merge($discountData['APPLY_BLOCKS'][0]['BASKET'], $discountData['APPLY_BLOCKS'][0]['ORDER']);
// соберем инфо по этим скидкам
$arApplyDiscountList = [];
foreach ($applyDiscountList as $discountItem)
$arApplyDiscountList[] = $discountData['DISCOUNT_LIST'][$discountItem['DISCOUNT_ID']];
// проверим наше правило
if(is_array($arApplyDiscountList))
{
foreach ($arApplyDiscountList as $arDiscount)
if(in_array($arDiscount['REAL_DISCOUNT_ID'], $restrictionParams['DISCOUNT_LIST'])
&& $arDiscount['APPLY'] == 'Y')
return false;
}
return true;
}
/**
* Получим применненные скидки по текущему заказу
* @param Entity $entity
* @return array|bool|mixed
*/
protected static function extractParams(Entity $entity)
{
if ($entity instanceof CollectableEntity) {
$collection = $entity->getCollection();
$order = $collection->getOrder();
} elseif ($entity instanceof Order) {
$order = $entity;
}
else return false;
return $order->getDiscount()->getApplyResult();
}
/**
* Получаем перечень всех скидок в магазине
* @param int $entityId
* @return array
* @throws \Bitrix\Main\ArgumentException
*/
public static function getParamsStructure($entityId = 0)
{
$arList = [];
$resDiscount = Bitrix\Sale\Internals\DiscountTable::getList(['select' => ['ID', 'NAME', 'ACTIVE']]);
while ($arDiscount = $resDiscount->fetch())
$arList[$arDiscount['ID']] = $arDiscount["NAME"].' ['.$arDiscount["ID"].' / '.$arDiscount["ACTIVE"].']';
return array(
"DISCOUNT_LIST" => array(
"TYPE" => "ENUM",
'MULTIPLE' => 'Y',
"OPTIONS" => $arList,
"LABEL" => 'Запрет по скидкам',
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment