Skip to content

Instantly share code, notes, and snippets.

@Isa3v Isa3v/README.md
Last active Jan 9, 2020

Embed
What would you like to do?
Тип цен в зависимости от суммы корзины (Bitrix)

Тип цен в зависимости от суммы корзины (Bitrix)

В init.php PHP 7.0+ Bitrix (Бизнес) 16+

Задача

Изменение типов цен в зависимости от суммы коризны.

  • При сумме заказа до 15 000 рублей по розничной стоимости - тип цены розница
  • При сумме заказа от 15.000 руб по розничной стоимости - тип цены мелкий опт
  • При сумме заказа от 50.000 руб по мелкий опт стоимости - тип цены средний опт
  • При сумме заказа от 100.000 руб по средний опт стоимости - тип цены крупный опт

Если у одного из товаров отсутвует одна из цен то берется предыдущая для суммирования
Например если у товара "Гвоздь" есть все типы цен, а у товара "Молоток" есть только розница, то будет считать: Крупный опт = Гвоздь (крупный опт) * кол-во + Молоток (розница) * кол-во

Вдохновлен старой статьей 2013 год

<?php
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler("catalog", "OnGetOptimalPrice", ["amountForPrice", "onGetPriceEvent"]);
global $basketPrice;
$basketPrice = [];
class amountForPrice
{
/**
* [BASE ID: 1] при сумме заказа до 15 000 рублей
* [SALE_SMAL ID: 2] Мелкий опт от 15.000 руб.
* [SALE_MIDDLE ID: 4] Средний опт от 50.000 руб.
* [SALE_LARGE ID: 5] Крупный опт от 100.000 руб.
*/
// Проставляем ID типов цен
protected static $baseGroup = 1;
protected static $smallGroup = 2;
protected static $middleGroup = 4;
protected static $largeGroup = 5;
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'],
]);
while($optPrice = $resOptPrices->fetch()){
$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::$middleGroup] >= 100000) {
$result = self::priceLarge($arPrices);
} elseif ($sum[self::$smallGroup] >= 50000) {
$result = self::priceMiddle($arPrices);
} elseif ($sum[self::$baseGroup] >= 15000) {
$result = self::priceSmall($arPrices);
} else {
$result = self::priceBase($arPrices);
}
return $result;
}
public function priceLarge(array $arPrices)
{
if (empty($arPrices[self::$largeGroup])) {
$result = self::priceMiddle($arPrices);
} else {
$result = [
'group' => self::$largeGroup,
'price' => $arPrices[self::$largeGroup]['PRICE'],
'currency' => $arPrices[self::$largeGroup]['CURRENCY']
];
}
return $result;
}
public function priceMiddle(array $arPrices)
{
if (empty($arPrices[self::$middleGroup])) {
$result = self::priceSmall($arPrices);
} else {
$result = [
'group' => self::$middleGroup,
'price' => $arPrices[self::$middleGroup]['PRICE'],
'currency' => $arPrices[self::$middleGroup]['CURRENCY']
];
}
return $result;
}
public function priceSmall(array $arPrices)
{
if (empty($arPrices[self::$smallGroup])) {
$result = self::priceBase($arPrices);
} else {
$result = [
'group' => self::$smallGroup,
'price' => $arPrices[self::$smallGroup]['PRICE'],
'currency' => $arPrices[self::$smallGroup]['CURRENCY']
];
}
return $result;
}
public function priceBase(array $arPrices)
{
$result = [
'group' => 1,
'price' => $arPrices[self::$baseGroup]['PRICE'],
'currency' => $arPrices[self::$baseGroup]['CURRENCY']
];
return $result;
}
/**
* Получение суммы корзины текущего пользователя
* Получаем суммы всех типов цен
*/
public function getBasketUser()
{
$resultPrice = [];
$resultPrice[self::$baseGroup] = 0;
$resultPrice[self::$smallGroup] = 0;
$resultPrice[self::$middleGroup] = 0;
//$resultPrice[self::$largeGroup] = 0; // large мы не считаем т.к он уже не учавствует в выборке
$obBasket = \Bitrix\Sale\Basket::getList([
'filter' => [
'FUSER_ID' => \Bitrix\Sale\Fuser::getId(),
'LID' => SITE_ID,
'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::$middleGroup] += (($arItem['PRICES'][self::$middleGroup] ?? $arItem['PRICES'][self::$smallGroup] ?? $arItem['PRICES'][self::$baseGroup]) * $arItem['QUANTITY']);
$resultPrice[self::$smallGroup] += (($arItem['PRICES'][self::$smallGroup] ?? $arItem['PRICES'][self::$baseGroup]) * $arItem['QUANTITY']);
$resultPrice[self::$baseGroup] += ($arItem['PRICES'][self::$baseGroup] * $arItem['QUANTITY']);
}
}
return $resultPrice;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.