|
<?php |
|
$eventManager = \Bitrix\Main\EventManager::getInstance(); |
|
$eventManager->addEventHandler("catalog", "OnGetOptimalPrice", ["amountForPrice", "onGetPriceEvent"]); |
|
|
|
global $basketPrice; |
|
$basketPrice = []; |
|
class amountForPrice |
|
{ |
|
/** |
|
* [BASE ID: 7] при сумме заказа до 15 000 рублей |
|
*/ |
|
// Проставляем ID типов цен |
|
const BASE_GROUP = 7; |
|
const GROUP_15 = 5; |
|
const GROUP_20 = 2; |
|
const GROUP_40 = 6; |
|
const GROUP_80 = 3; |
|
const GROUP_110 = 4; |
|
|
|
public function onGetPriceEvent($productID, $quantity = 1, $arUserGroups = [], $renewal = "N", $arPrices = array(), $siteID = false, $arDiscountCoupons = false) |
|
{ |
|
// Через global, чтоб не вызывалось по несколько раз |
|
// OnGetOptimalPrice вызывается для каждого товара |
|
global $basketPrice; |
|
if (empty($basketPrice)) { |
|
$basketPrice = self::getBasketUser(); |
|
} |
|
|
|
// Получаем доступные цены для товара |
|
$resOptPrices = \Bitrix\Catalog\PriceTable::getList([ |
|
'filter' => ['=PRODUCT_ID' => $productID], |
|
'select' => ['CATALOG_GROUP_ID', 'PRICE', 'CURRENCY', 'QUANTITY_TO', 'QUANTITY_FROM'], |
|
]); |
|
|
|
while($optPrice = $resOptPrices->fetch()){ |
|
// Если вкл. расширенные цены |
|
if(!empty($optPrice['QUANTITY_FROM']) && $optPrice['QUANTITY_FROM'] > $quantity){ |
|
continue; |
|
} |
|
if(!empty($optPrice['QUANTITY_TO']) && $optPrice['QUANTITY_TO'] < $quantity){ |
|
continue; |
|
} |
|
$arOptPrices[$optPrice['CATALOG_GROUP_ID']] = $optPrice; |
|
} |
|
|
|
if(empty($arOptPrices)){ |
|
return false; |
|
} |
|
|
|
$arPrice = self::getPrice($basketPrice, $arOptPrices); |
|
$result = [ |
|
'PRICE' => [ |
|
"ID" => $productID, |
|
'CATALOG_GROUP_ID' => $arPrice['group'], |
|
'PRICE' => $arPrice['price'], |
|
'CURRENCY' => $arPrice['currency'], |
|
'ELEMENT_IBLOCK_ID' => $productID, |
|
'VAT_INCLUDED' => "Y", |
|
], |
|
'DISCOUNT' => ['VALUE' => $discount, 'CURRENCY' => $arPrice['currency']], |
|
]; |
|
|
|
return $result; |
|
} |
|
|
|
/** |
|
* Функция смотрит цену корзины и выбирает подходящую цену |
|
* Функции цен уже сам перебразывают цену в зависимости от доступности |
|
*/ |
|
public function getPrice($sum = [], $arPrices = []) |
|
{ |
|
if ($sum[self::GROUP_110] >= 110000) { |
|
$result = self::price110($arPrices); |
|
}elseif ($sum[self::GROUP_80] >= 80000) { |
|
$result = self::price80($arPrices); |
|
} elseif ($sum[self::GROUP_40] >= 40000) { |
|
$result = self::price40($arPrices); |
|
} elseif ($sum[self::GROUP_20] >= 20000) { |
|
$result = self::price20($arPrices); |
|
} elseif ($sum[self::GROUP_15] >= 15000) { |
|
$result = self::price15($arPrices); |
|
} else { |
|
$result = self::priceBase($arPrices); |
|
} |
|
return $result; |
|
} |
|
|
|
public function price110(array $arPrices) |
|
{ |
|
if (empty($arPrices[self::GROUP_110])) { |
|
$result = self::price40($arPrices); |
|
} else { |
|
$result = [ |
|
'group' => self::GROUP_110, |
|
'price' => $arPrices[self::GROUP_110]['PRICE'], |
|
'currency' => $arPrices[self::GROUP_110]['CURRENCY'] |
|
]; |
|
} |
|
return $result; |
|
} |
|
|
|
public function price80(array $arPrices) |
|
{ |
|
if (empty($arPrices[self::GROUP_80])) { |
|
$result = self::price40($arPrices); |
|
} else { |
|
$result = [ |
|
'group' => self::GROUP_80, |
|
'price' => $arPrices[self::GROUP_80]['PRICE'], |
|
'currency' => $arPrices[self::GROUP_80]['CURRENCY'] |
|
]; |
|
} |
|
return $result; |
|
} |
|
public function price40(array $arPrices) |
|
{ |
|
if (empty($arPrices[self::GROUP_40])) { |
|
$result = self::price20($arPrices); |
|
} else { |
|
$result = [ |
|
'group' => self::GROUP_40, |
|
'price' => $arPrices[self::GROUP_40]['PRICE'], |
|
'currency' => $arPrices[self::GROUP_40]['CURRENCY'] |
|
]; |
|
} |
|
return $result; |
|
} |
|
public function price20(array $arPrices) |
|
{ |
|
if (empty($arPrices[self::GROUP_20])) { |
|
$result = self::price15($arPrices); |
|
} else { |
|
$result = [ |
|
'group' => self::GROUP_20, |
|
'price' => $arPrices[self::GROUP_20]['PRICE'], |
|
'currency' => $arPrices[self::GROUP_20]['CURRENCY'] |
|
]; |
|
} |
|
return $result; |
|
} |
|
public function price15(array $arPrices) |
|
{ |
|
if (empty($arPrices[self::GROUP_15])) { |
|
$result = self::priceBase($arPrices); |
|
} else { |
|
$result = [ |
|
'group' => self::GROUP_15, |
|
'price' => $arPrices[self::GROUP_15]['PRICE'], |
|
'currency' => $arPrices[self::GROUP_15]['CURRENCY'] |
|
]; |
|
} |
|
return $result; |
|
} |
|
|
|
public function priceBase(array $arPrices) |
|
{ |
|
$result = [ |
|
'group' => 1, |
|
'price' => $arPrices[self::BASE_GROUP]['PRICE'], |
|
'currency' => $arPrices[self::BASE_GROUP]['CURRENCY'] |
|
]; |
|
return $result; |
|
} |
|
|
|
/** |
|
* Получение суммы корзины текущего пользователя |
|
* Получаем суммы всех типов цен |
|
*/ |
|
public function getBasketUser() |
|
{ |
|
$resultPrice = []; |
|
$resultPrice[self::BASE_GROUP] = 0; |
|
$resultPrice[self::GROUP_15] = 0; |
|
$resultPrice[self::GROUP_20] = 0; |
|
$resultPrice[self::GROUP_40] = 0; |
|
$resultPrice[self::GROUP_80] = 0; |
|
$resultPrice[self::GROUP_110] = 0; |
|
|
|
$obBasket = \Bitrix\Sale\Basket::getList([ |
|
'filter' => [ |
|
'FUSER_ID' => \Bitrix\Sale\Fuser::getId(), |
|
'LID' => 's1', |
|
'ORDER_ID' => NULL // Т.к корзина связана с заказами, то нам нужна корзина у которой нет заказа |
|
], |
|
'select' => ['QUANTITY', 'PRODUCT_ID', 'CAN_BUY', 'DELAY'] |
|
]); |
|
while($arItem = $obBasket->Fetch()){ |
|
// Нам нужны только доступные товары остальные не считаем |
|
if ($arItem['DELAY'] == 'N' && $arItem['CAN_BUY'] == 'Y') { |
|
$resPrices = \Bitrix\Catalog\PriceTable::getList([ |
|
'filter' => ['=PRODUCT_ID' => $arItem['PRODUCT_ID']], |
|
'select' => ['CATALOG_GROUP_ID', 'PRICE'], |
|
]); |
|
while ($price = $resPrices->fetch()) { |
|
$arItem['PRICES'][$price['CATALOG_GROUP_ID']] = $price['PRICE']; |
|
} |
|
// Если вдруг нет у товара цены, то берем следующую т.к нам нужна именно сумма |
|
$resultPrice[self::GROUP_110] += (($arItem['PRICES'][self::GROUP_110] ?? $arItem['PRICES'][self::GROUP_80] ?? $arItem['PRICES'][self::GROUP_40] ?? $arItem['PRICES'][self::GROUP_20] ?? $arItem['PRICES'][self::GROUP_15] ?? $arItem['PRICES'][self::BASE_GROUP]) * $arItem['QUANTITY']); |
|
$resultPrice[self::GROUP_80] += (($arItem['PRICES'][self::GROUP_80] ?? $arItem['PRICES'][self::GROUP_40] ?? $arItem['PRICES'][self::GROUP_20] ?? $arItem['PRICES'][self::GROUP_15] ?? $arItem['PRICES'][self::BASE_GROUP]) * $arItem['QUANTITY']); |
|
$resultPrice[self::GROUP_40] += (($arItem['PRICES'][self::GROUP_40] ?? $arItem['PRICES'][self::GROUP_20] ?? $arItem['PRICES'][self::GROUP_15] ?? $arItem['PRICES'][self::BASE_GROUP]) * $arItem['QUANTITY']); |
|
$resultPrice[self::GROUP_20] += (($arItem['PRICES'][self::GROUP_20] ?? $arItem['PRICES'][self::GROUP_15] ?? $arItem['PRICES'][self::BASE_GROUP]) * $arItem['QUANTITY']); |
|
$resultPrice[self::GROUP_15] += (($arItem['PRICES'][self::GROUP_15] ?? $arItem['PRICES'][self::BASE_GROUP]) * $arItem['QUANTITY']); |
|
$resultPrice[self::BASE_GROUP] += ($arItem['PRICES'][self::BASE_GROUP] * $arItem['QUANTITY']); |
|
} |
|
} |
|
return $resultPrice; |
|
} |
|
|
|
/** |
|
* Получение цен и текущей цены |
|
*/ |
|
public function getListPrices() |
|
{ |
|
$oPrices = self::getBasketUser(); |
|
|
|
foreach($oPrices as $key => $price){ |
|
$arPrice[$key]['price'] = $price; |
|
$arPrice[$key]['~price'] = html_entity_decode(\CCurrencyLang::CurrencyFormat($price, \Bitrix\Currency\CurrencyManager::getBaseCurrency())); |
|
$arPrice[$key]['group'] = $key; |
|
$arPrice[$key]['active'] = false; |
|
} |
|
|
|
// Ищем актуальную цену |
|
if ($arPrice[self::GROUP_110]['price'] >= 110000) { |
|
$arPrice[self::GROUP_110]['active'] = true; |
|
}elseif ($arPrice[self::GROUP_80]['price'] >= 80000) { |
|
$arPrice[self::GROUP_80]['active'] = true; |
|
}elseif ($arPrice[self::GROUP_40]['price'] >= 40000) { |
|
$arPrice[self::GROUP_40]['active'] = true; |
|
}elseif ($arPrice[self::GROUP_20]['price'] >= 20000) { |
|
$arPrice[self::GROUP_20]['active'] = true; |
|
}elseif ($arPrice[self::GROUP_15]['price'] >= 15000) { |
|
$arPrice[self::GROUP_15]['active'] = true; |
|
}else{ |
|
$arPrice[self::BASE_GROUP]['active'] = true; |
|
} |
|
|
|
// Узнаем название группы |
|
$rsGroup = \Bitrix\Catalog\GroupTable::getList(['select' => ['ID', 'NAME', 'XML_ID', 'SORT']]); |
|
while($arGroup = $rsGroup->fetch()){ |
|
$id = $arGroup['ID']; |
|
if(isset($arPrice[$id])){ |
|
$arPrice[$id]['name'] = $arGroup['NAME']; |
|
$arPrice[$id]['XML_ID'] = $arGroup['XML_ID']; |
|
$arPrice[$id]['SORT'] = $arGroup['SORT']; |
|
} |
|
} |
|
// Сортируем |
|
usort($arPrice, function($a, $b){ |
|
if ($a['SORT'] == $b['SORT']) { |
|
return 0; |
|
} |
|
return ($a['SORT'] < $b['SORT']) ? -1 : 1; |
|
}); |
|
|
|
return $arPrice; |
|
|
|
} |
|
|
|
} |