1С-Битрикс. Скидка на первый заказ по купону
В прошлой заметке я рассказал как применять только большую скидку из всех. А в этой расскажу, как дать скидку по купону на первый заказ больше определенной суммы заказа.
Как и в прошлый раз на помощь приходят два события: OnGetDiscount и OnGetDiscountResult модуля «Торговый каталог».
// {{{ Применении скидки по купону, только если заказ больше определённой суммы \Bitrix\Main\EventManager::getInstance()->addEventHandler("catalog", "OnGetDiscount", array("WeProductDiscountHandler", "OnGetDiscount") ); \Bitrix\Main\EventManager::getInstance()->addEventHandler("catalog", "OnGetDiscountResult", array("WeProductDiscountHandler", "OnGetDiscountResult") ); class WeProductDiscountHandler{ const COUPON_CODE = 'CP-0ZMA0-QDIMFQI'; const TOTAL_SUMM_ORDER = 3000; protected static $basketItems = null; protected static $productPrice = null; protected static $totalCountOrders = null; /** * Вызывается в методе CCatalogDiscount::GetDiscount перед получением всех скидок * @return bool true */ public function OnGetDiscount($intProductID, $intIBlockID, $arCatalogGroups, $arUserGroups, $strRenewal, $siteID, $arDiscountCoupons, $boolSKU, $boolGetIDS){ // получение цены товара $curProductPrice = CPrice::GetBasePrice($intProductID, false, false, false); if($curProductPrice != false){ self::$productPrice = $curProductPrice; } return true; } /** * Возвращает товары в корзине пользователя * @return (array) */ public static function getBasketItems(){ if(self::$basketItems === null){ \Bitrix\Main\Loader::includeModule('sale'); $arItems = array(); $resBasket = CSaleBasket::GetList( array(), array( "FUSER_ID" => CSaleBasket::GetBasketUserID(), "LID" => SITE_ID, "ORDER_ID" => "NULL" ) ); while($arItem = $resBasket->Fetch()){ $arItems[] = $arItem; } self::$basketItems = $arItems; } return self::$basketItems; } /** * Возвращает общую сумму товаров в корзине * @return (int) */ public static function getTotalSumBasketItems(){ $basketItems = self::getBasketItems(); $totalSum = 0; foreach($basketItems as $item){ $totalSum += ($item['PRICE'] + $item['DISCOUNT_PRICE']) * $item['QUANTITY']; } return $totalSum; } /** * Возвращает количество оформленных заказов текущего пользователя * @return (int) */ public static function getCountOrdersByUser(){ global $USER; if(self::$totalCountOrders === null){ self::$totalCountOrders = 0; if ($USER->IsAuthorized()){ \Bitrix\Main\Loader::includeModule('sale'); $dbSales = CSaleOrder::GetList( array(), array( "USER_ID" => $USER->GetID() ), array( "COUNT" => "ID" ) ); while ($arSales = $dbSales->Fetch()){ if(isset($arSales['ID'])){ self::$totalCountOrders = intval($arSales['ID']); } } } } return self::$totalCountOrders; } /** * Вызывается в методе CCatalogDiscount::GetDiscount после получения * и обработки всех скидок для товара * @return array() возвращаем только нужную нам скидку */ public function OnGetDiscountResult(&$arResult){ if(self::$productPrice === null) return; $boolHasCoupon = false; $discounts = array(); foreach($arResult as $key_discount => &$discount){ if(isset($discount['COUPON_ACTIVE'], $discount['COUPON']) && $discount['COUPON_ACTIVE'] == 'Y' && $discount['COUPON'] === self::COUPON_CODE){ $boolHasCoupon = true; if(self::getTotalSumBasketItems() >= self::TOTAL_SUMM_ORDER){ $discount['VALUE'] = $discount['VALUE'] * self::$productPrice['PRICE'] / self::getTotalSumBasketItems(); $discounts[] = $discount; } break; } } if($boolHasCoupon){ if(self::getCountOrdersByUser() == 0){ $arResult = $discounts; }else{ $arResult = array(); } } } } // }}}
Код купона, по которому давать скидку, и сумма заказа, после которой скидка будет применена, устанавливаются в константах в классе.
Хочу заметить, что данный способ отменяет все скидки на товары, если такие были. Если нужно оставить эту возможность, то обработчик надо будет поправить под эти нужды.
4 комментария
А что нужно сделать чтобы ваш модуль заработал?
Mar, этот код нужно поместить в файл /bitrix/php_interface/init.php
Добрый день, данный код не работает, можете актуализировать? 2023 год на дворе )
Danil, у заметки скоро юбилей, угу.
Предлагаю вам в честь этого замечательного события обновить код из этой заметки, протестировать его и прислать нам обновлённую версию на электронную почту (или куда вам удобнее).
А мы вам, от лица всей команды olegpro.ru, скажем спасибо.