Skip to content

Instantly share code, notes, and snippets.

@EscApp2
Last active April 18, 2022 12:36
Show Gist options
  • Save EscApp2/cdea9cb3bb06a179dd15afc0c1d5afa2 to your computer and use it in GitHub Desktop.
Save EscApp2/cdea9cb3bb06a179dd15afc0c1d5afa2 to your computer and use it in GitHub Desktop.
basket_price_change OnGetOptimalPrice GetOptimalPrice Get Optimal Price
<?
CModule::IncludeModule('catalog');
CModule::IncludeModule('sale');
use Bitrix\Main\Localization\Loc,
Bitrix\Main,
Bitrix\Currency,
Bitrix\Catalog,
Bitrix\Sale;
class CCatalogProductCustom extends CCatalogProduct{
public static function GetOptimalPriceCustom(
$intProductID, $quantity = 1, $arUserGroups = array(),
$renewal = "N", $priceList = array(), $siteID = false,
$arDiscountCoupons = false)
{
global $APPLICATION;
$intProductID = (int)$intProductID;
if ($intProductID <= 0)
{
$APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_PRODUCT_ID_ABSENT"), "NO_PRODUCT_ID");
return false;
}
$quantity = (float)$quantity;
if ($quantity <= 0)
{
$APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_QUANTITY_ABSENT"), "NO_QUANTITY");
return false;
}
if (!is_array($arUserGroups) && (int)$arUserGroups.'|' == (string)$arUserGroups.'|')
$arUserGroups = array((int)$arUserGroups);
if (!is_array($arUserGroups))
$arUserGroups = array();
if (!in_array(2, $arUserGroups))
$arUserGroups[] = 2;
Main\Type\Collection::normalizeArrayValuesByInt($arUserGroups);
$renewal = ($renewal == 'Y' ? 'Y' : 'N');
if ($siteID === false)
$siteID = SITE_ID;
$resultCurrency = Catalog\Product\Price\Calculation::getCurrency();
if (empty($resultCurrency))
{
$APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_NO_RESULT_CURRENCY"));
return false;
}
$intIBlockID = (int)CIBlockElement::GetIBlockByID($intProductID);
if ($intIBlockID <= 0)
{
$APPLICATION->ThrowException(
Loc::getMessage(
'BT_MOD_CATALOG_PROD_ERR_ELEMENT_ID_NOT_FOUND',
array('#ID#' => $intProductID)
),
'NO_ELEMENT'
);
return false;
}
if (!isset($priceList) || !is_array($priceList))
$priceList = array();
if (empty($priceList))
{
$priceTypeList = self::getAllowedPriceTypesCustom($arUserGroups);
if (empty($priceTypeList))
return false;
$iterator = Catalog\PriceTable::getList(array(
'select' => array('ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY'),
'filter' => array(
'=PRODUCT_ID' => $intProductID,
'@CATALOG_GROUP_ID' => $priceTypeList,
array(
'LOGIC' => 'OR',
'<=QUANTITY_FROM' => $quantity,
'=QUANTITY_FROM' => null
),
array(
'LOGIC' => 'OR',
'>=QUANTITY_TO' => $quantity,
'=QUANTITY_TO' => null
)
),
'order' => array('CATALOG_GROUP_ID' => 'ASC')
));
while ($row = $iterator->fetch())
{
$row['ELEMENT_IBLOCK_ID'] = $intIBlockID;
$priceList[] = $row;
}
unset($row, $iterator);
unset($priceTypeList);
}
else
{
foreach (array_keys($priceList) as $priceIndex)
$priceList[$priceIndex]['ELEMENT_IBLOCK_ID'] = $intIBlockID;
unset($priceIndex);
}
if (empty($priceList))
return false;
$vat = CCatalogProduct::GetVATDataByID($intProductID);
if (!empty($vat))
{
$vat['RATE'] = (float)$vat['RATE'] * 0.01;
}
else
{
$vat = array('RATE' => 0.0, 'VAT_INCLUDED' => 'N');
}
unset($iterator);
$isNeedDiscounts = Catalog\Product\Price\Calculation::isAllowedUseDiscounts();
$resultWithVat = Catalog\Product\Price\Calculation::isIncludingVat();
if ($isNeedDiscounts)
{
if ($arDiscountCoupons === false)
$arDiscountCoupons = CCatalogDiscountCoupon::GetCoupons();
}
// $boolDiscountVat = ('N' != COption::GetOptionString('catalog', 'discount_vat', 'Y'));
$boolDiscountVat = true;
$minimalPrice = array();
if (self::$saleIncluded === null)
self::initSaleSettingsCustom();
$isNeedleToMinimizeCatalogGroup = self::isNeedleToMinimizeCatalogGroupCustom($priceList);
foreach ($priceList as $priceData)
{
$priceData['VAT_RATE'] = $vat['RATE'];
$priceData['VAT_INCLUDED'] = $vat['VAT_INCLUDED'];
$currentPrice = (float)$priceData['PRICE'];
if ($boolDiscountVat)
{
if ($priceData['VAT_INCLUDED'] == 'N')
$currentPrice *= (1 + $priceData['VAT_RATE']);
}
else
{
if ($priceData['VAT_INCLUDED'] == 'Y')
$currentPrice /= (1 + $priceData['VAT_RATE']);
}
if ($priceData['CURRENCY'] != $resultCurrency)
$currentPrice = CCurrencyRates::ConvertCurrency($currentPrice, $priceData['CURRENCY'], $resultCurrency);
$currentPrice = Catalog\Product\Price\Calculation::roundPrecision($currentPrice);
$result = array(
'BASE_PRICE' => $currentPrice,
'COMPARE_PRICE' => $currentPrice,
'PRICE' => $currentPrice,
'CURRENCY' => $resultCurrency,
'DISCOUNT_LIST' => array(),
'RAW_PRICE' => $priceData
);
if ($isNeedDiscounts)
{
$arDiscounts = CCatalogDiscount::GetDiscount(
$intProductID,
$intIBlockID,
array($priceData['CATALOG_GROUP_ID']),
$arUserGroups,
$renewal,
$siteID,
$arDiscountCoupons
);
$discountResult = CCatalogDiscount::applyDiscountList($currentPrice, $resultCurrency, $arDiscounts);
unset($arDiscounts);
if ($discountResult === false)
return false;
$result['PRICE'] = $discountResult['PRICE'];
$result['COMPARE_PRICE'] = $discountResult['PRICE'];
$result['DISCOUNT_LIST'] = $discountResult['DISCOUNT_LIST'];
unset($discountResult);
}
elseif($isNeedleToMinimizeCatalogGroup)
{
$calculateData = $priceData;
$calculateData['PRICE'] = $currentPrice;
$calculateData['CURRENCY'] = $resultCurrency;
$possibleSalePrice = self::getPossibleSalePriceCustom(
$intProductID,
$calculateData,
$quantity,
$siteID,
$arUserGroups,
$arDiscountCoupons
);
unset($calculateData);
if ($possibleSalePrice === null)
return false;
$result['COMPARE_PRICE'] = $possibleSalePrice;
unset($possibleSalePrice);
}
if ($boolDiscountVat)
{
if (!$resultWithVat)
{
$result['PRICE'] /= (1 + $priceData['VAT_RATE']);
$result['COMPARE_PRICE'] /= (1 + $priceData['VAT_RATE']);
$result['BASE_PRICE'] /= (1 + $priceData['VAT_RATE']);
}
}
else
{
if ($resultWithVat)
{
$result['PRICE'] *= (1 + $priceData['VAT_RATE']);
$result['COMPARE_PRICE'] *= (1 + $priceData['VAT_RATE']);
$result['BASE_PRICE'] *= (1 + $priceData['VAT_RATE']);
}
}
$result['UNROUND_PRICE'] = $result['PRICE'];
$result['UNROUND_BASE_PRICE'] = $result['BASE_PRICE'];
if (Catalog\Product\Price\Calculation::isComponentResultMode())
{
$result['BASE_PRICE'] = Catalog\Product\Price::roundPrice(
$priceData['CATALOG_GROUP_ID'],
$result['BASE_PRICE'],
$resultCurrency
);
$result['PRICE'] = Catalog\Product\Price::roundPrice(
$priceData['CATALOG_GROUP_ID'],
$result['PRICE'],
$resultCurrency
);
if (
empty($result['DISCOUNT_LIST'])
|| Catalog\Product\Price\Calculation::compare($result['BASE_PRICE'], $result['PRICE'], '<=')
)
{
$result['BASE_PRICE'] = $result['PRICE'];
}
$result['COMPARE_PRICE'] = $result['PRICE'];
}
if (empty($minimalPrice) || $minimalPrice['COMPARE_PRICE'] > $result['COMPARE_PRICE'])
{
$minimalPrice = $result;
}
unset($currentPrice, $result);
}
unset($priceData);
unset($vat);
$discountValue = ($minimalPrice['BASE_PRICE'] - $minimalPrice['PRICE']);
$arResult = array(
'PRICE' => $minimalPrice['RAW_PRICE'],
'RESULT_PRICE' => array(
'PRICE_TYPE_ID' => $minimalPrice['RAW_PRICE']['CATALOG_GROUP_ID'],
'BASE_PRICE' => $minimalPrice['BASE_PRICE'],
'DISCOUNT_PRICE' => $minimalPrice['PRICE'],
'CURRENCY' => $resultCurrency,
'DISCOUNT' => $discountValue,
'PERCENT' => (
$minimalPrice['BASE_PRICE'] > 0 && $discountValue > 0
? round((100*$discountValue)/$minimalPrice['BASE_PRICE'], 0)
: 0
),
'VAT_RATE' => $minimalPrice['RAW_PRICE']['VAT_RATE'],
'VAT_INCLUDED' => ($resultWithVat ? 'Y' : 'N'),
'UNROUND_BASE_PRICE' => $minimalPrice['UNROUND_BASE_PRICE'],
'UNROUND_DISCOUNT_PRICE' => $minimalPrice['UNROUND_PRICE']
),
'DISCOUNT_PRICE' => $minimalPrice['PRICE'],
'DISCOUNT' => array(),
'DISCOUNT_LIST' => array(),
'PRODUCT_ID' => $intProductID
);
if (!empty($minimalPrice['DISCOUNT_LIST']))
{
reset($minimalPrice['DISCOUNT_LIST']);
$arResult['DISCOUNT'] = current($minimalPrice['DISCOUNT_LIST']);
$arResult['DISCOUNT_LIST'] = $minimalPrice['DISCOUNT_LIST'];
}
unset($minimalPrice);
return $arResult;
}
public static function getAllowedPriceTypesCustom(array $userGroups){
static $priceTypeCache = array();
Main\Type\Collection::normalizeArrayValuesByInt($userGroups, true);
if (empty($userGroups))
return array();
$cacheKey = 'U'.implode('_', $userGroups);
if (!isset($priceTypeCache[$cacheKey]))
{
$priceTypeCache[$cacheKey] = array();
$priceIterator = Catalog\GroupAccessTable::getList(array(
'select' => array('CATALOG_GROUP_ID'),
'filter' => array('@GROUP_ID' => $userGroups, '=ACCESS' => Catalog\GroupAccessTable::ACCESS_BUY),
'order' => array('CATALOG_GROUP_ID' => 'ASC')
));
while ($priceType = $priceIterator->fetch())
{
$priceTypeId = (int)$priceType['CATALOG_GROUP_ID'];
$priceTypeCache[$cacheKey][$priceTypeId] = $priceTypeId;
unset($priceTypeId);
}
unset($priceType, $priceIterator);
}
return $priceTypeCache[$cacheKey];
}
public static $existPriceTypeDiscountsCustom = false;
public static function initSaleSettingsCustom()
{
if (self::$saleIncluded === null)
self::$saleIncluded = Main\Loader::includeModule('sale');
if (self::$saleIncluded)
{
self::$useSaleDiscount = (string)Main\Config\Option::get('sale', 'use_sale_discount_only') == 'Y';
if (self::$useSaleDiscount)
{
//TODO: replace runtime to reference after sale 17.5.2 will be stable
$row = Sale\Internals\DiscountEntitiesTable::getList(array(
'select' => array('ID'),
'filter' => array(
'=MODULE_ID' => 'catalog',
'=ENTITY' => 'PRICE',
'=FIELD_ENTITY' => 'CATALOG_GROUP_ID',
'=FIELD_TABLE' => 'CATALOG_GROUP_ID',
'=ACTIVE_DISCOUNT.ACTIVE' => 'Y'
),
'runtime' => array(
new Main\Entity\ReferenceField(
'ACTIVE_DISCOUNT',
'Bitrix\Sale\Internals\Discount',
array('=this.DISCOUNT_ID' => 'ref.ID'),
array('join_type' => 'LEFT')
)
),
'limit' => 1,
))->fetch();
self::$existPriceTypeDiscountsCustom = !empty($row);
unset($row);
}
}
}
public static function isNeedleToMinimizeCatalogGroupCustom(array $priceList)
{
if (self::$saleIncluded === null)
self::initSaleSettingsCustom();
if (
!self::$saleIncluded ||
!self::$useSaleDiscount ||
count($priceList) < 2
)
return false;
return self::$existPriceTypeDiscountsCustom;
}
public static function getPossibleSalePriceCustom($intProductID, array $priceData, $quantity, $siteID, array $userGroups, $coupons)
{
$possibleSalePrice = null;
if (empty($priceData))
return $possibleSalePrice;
$isCompatibilityUsed = Sale\Compatible\DiscountCompatibility::isUsed();
Sale\Compatible\DiscountCompatibility::stopUsageCompatible();
$freezeCoupons = (empty($coupons) && is_array($coupons));
if ($freezeCoupons)
Sale\DiscountCouponsManager::freezeCouponStorage();
/** @var \Bitrix\Sale\Basket $basket */
static $basket = null,
/** @var \Bitrix\Sale\BasketItem $basketItem */
$basketItem = null;
if ($basket !== null)
{
if ($basket->getSiteId() != $siteID)
{
$basket = null;
$basketItem = null;
}
}
if ($basket === null)
{
$basket = Sale\Basket::create($siteID);
$basketItem = $basket->createItem('catalog', $intProductID);
}
$fields = array(
'PRODUCT_ID' => $intProductID,
'QUANTITY' => $quantity,
'LID' => $siteID,
'PRODUCT_PRICE_ID' => $priceData['ID'],
'PRICE' => $priceData['PRICE'],
'BASE_PRICE' => $priceData['PRICE'],
'DISCOUNT_PRICE' => 0,
'CURRENCY' => $priceData['CURRENCY'],
'CAN_BUY' => 'Y',
'DELAY' => 'N',
'PRICE_TYPE_ID' => (int)$priceData['CATALOG_GROUP_ID']
);
/** @noinspection PhpInternalEntityUsedInspection */
$basketItem->setFieldsNoDemand($fields);
$discount = Sale\Discount::buildFromBasket($basket, new Sale\Discount\Context\UserGroup($userGroups));
$discount->setExecuteModuleFilter(array('all', 'catalog'));
$discount->calculate();
$calcResults = $discount->getApplyResult(true);
if ($calcResults && !empty($calcResults['PRICES']['BASKET']))
{
$possibleSalePrice = reset($calcResults['PRICES']['BASKET']);
$possibleSalePrice = $possibleSalePrice['PRICE'];
}
if ($freezeCoupons)
Sale\DiscountCouponsManager::unFreezeCouponStorage();
$discount->setExecuteModuleFilter(array('all', 'sale', 'catalog'));
if ($isCompatibilityUsed === true)
{
Sale\Compatible\DiscountCompatibility::revertUsageCompatible();
}
return $possibleSalePrice;
}
}
$eventManager = Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler('catalog', 'OnGetOptimalPrice', function(
$intProductID,
$quantity = 1,
$arUserGroups = [],
$renewal = "N",
$arPrices = [],
$siteID = false,
$arDiscountCoupons = false){
//inside CCatalogProduct::GetOptimalPrice()
$ActionPrice = 4;
$prices = \CCatalogProduct::GetByIDEx($intProductID);
//$db_props = CIBlockElement::GetProperty(38, $intProductID, array("sort" => "asc"), Array("CODE"=>"AKTSIYA"));
//if($ar_props = $db_props->Fetch()){
// $ar_props['VALUE_XML_ID']; // false;
//}
$price = $prices['PRICES'][$ActionPrice]['PRICE'];
if(isset($prices['PRICES'][$ActionPrice]) && empty($price)){
if (!is_array($arUserGroups))
$arUserGroups = array();
if (!in_array(2, $arUserGroups))
$arUserGroups[] = 2;
$priceTypeList = CCatalogProductCustom::getAllowedPriceTypesCustom($arUserGroups);
$iterator = Catalog\PriceTable::getList(array(
'select' => array('ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY'),
'filter' => array(
'=PRODUCT_ID' => $intProductID,
'@CATALOG_GROUP_ID' => $priceTypeList,
array(
'LOGIC' => 'OR',
'<=QUANTITY_FROM' => $quantity,
'=QUANTITY_FROM' => null
),
array(
'LOGIC' => 'OR',
'>=QUANTITY_TO' => $quantity,
'=QUANTITY_TO' => null
)
),
'order' => array('CATALOG_GROUP_ID' => 'ASC')
));
while ($row = $iterator->fetch())
{
$priceList[$row['CATALOG_GROUP_ID']] = $row;
}
unset($priceList[$ActionPrice]);
$priceList = array_values($priceList);
return CCatalogProductCustom::GetOptimalPriceCustom($intProductID, $quantity, $arUserGroups, $renewal, $priceList, $siteID, $arDiscountCoupons);
}
return true;
});
<?
CModule::IncludeModule('catalog');
CModule::IncludeModule('sale');
use Bitrix\Main\Localization\Loc,
Bitrix\Main,
Bitrix\Currency,
Bitrix\Catalog,
Bitrix\Sale;
//2021
class CCatalogProductCustom extends CCatalogProduct{
public static function GetOptimalPriceCustom(
$intProductID, $quantity = 1, $arUserGroups = array(),
$renewal = "N", $priceList = array(), $siteID = false,
$arDiscountCoupons = false)
{
global $APPLICATION;
$intProductID = (int)$intProductID;
if ($intProductID <= 0)
{
$APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_PRODUCT_ID_ABSENT"), "NO_PRODUCT_ID");
return false;
}
$quantity = (float)$quantity;
if ($quantity <= 0)
{
$APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_QUANTITY_ABSENT"), "NO_QUANTITY");
return false;
}
if (!is_array($arUserGroups) && (int)$arUserGroups.'|' == (string)$arUserGroups.'|')
$arUserGroups = array((int)$arUserGroups);
if (!is_array($arUserGroups))
$arUserGroups = array();
if (!in_array(2, $arUserGroups))
$arUserGroups[] = 2;
Main\Type\Collection::normalizeArrayValuesByInt($arUserGroups);
$renewal = ($renewal == 'Y' ? 'Y' : 'N');
if ($siteID === false)
$siteID = SITE_ID;
$resultCurrency = Catalog\Product\Price\Calculation::getCurrency();
if (empty($resultCurrency))
{
$APPLICATION->ThrowException(Loc::getMessage("BT_MOD_CATALOG_PROD_ERR_NO_RESULT_CURRENCY"));
return false;
}
$intIBlockID = (int)CIBlockElement::GetIBlockByID($intProductID);
if ($intIBlockID <= 0)
{
$APPLICATION->ThrowException(
Loc::getMessage(
'BT_MOD_CATALOG_PROD_ERR_ELEMENT_ID_NOT_FOUND',
array('#ID#' => $intProductID)
),
'NO_ELEMENT'
);
return false;
}
if (!isset($priceList) || !is_array($priceList))
$priceList = array();
if (empty($priceList))
{
$priceTypeList = self::getAllowedPriceTypesCustom($arUserGroups);
if (empty($priceTypeList))
return false;
$iterator = Catalog\PriceTable::getList(array(
'select' => array('ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY', 'PRICE_SCALE'),
'filter' => array(
'=PRODUCT_ID' => $intProductID,
'@CATALOG_GROUP_ID' => $priceTypeList,
array(
'LOGIC' => 'OR',
'<=QUANTITY_FROM' => $quantity,
'=QUANTITY_FROM' => null
),
array(
'LOGIC' => 'OR',
'>=QUANTITY_TO' => $quantity,
'=QUANTITY_TO' => null
)
),
'order' => array('CATALOG_GROUP_ID' => 'ASC')
));
while ($row = $iterator->fetch())
{
$row['ELEMENT_IBLOCK_ID'] = $intIBlockID;
$priceList[] = $row;
}
unset($row, $iterator);
unset($priceTypeList);
}
else
{
foreach (array_keys($priceList) as $priceIndex)
$priceList[$priceIndex]['ELEMENT_IBLOCK_ID'] = $intIBlockID;
unset($priceIndex);
}
if (empty($priceList))
return false;
$vat = CCatalogProduct::GetVATDataByID($intProductID);
if (!empty($vat))
{
$vat['RATE'] = (float)$vat['RATE'] * 0.01;
}
else
{
$vat = array('RATE' => 0.0, 'VAT_INCLUDED' => 'N');
}
unset($iterator);
$isNeedDiscounts = Catalog\Product\Price\Calculation::isAllowedUseDiscounts();
$resultWithVat = Catalog\Product\Price\Calculation::isIncludingVat();
if ($isNeedDiscounts)
{
if ($arDiscountCoupons === false)
$arDiscountCoupons = CCatalogDiscountCoupon::GetCoupons();
}
// $boolDiscountVat = ('N' != COption::GetOptionString('catalog', 'discount_vat', 'Y'));
$boolDiscountVat = true;
$minimalPrice = array();
if (self::$saleIncluded === null)
self::initSaleSettingsCustom();
$isNeedleToMinimizeCatalogGroup = self::isNeedleToMinimizeCatalogGroupCustom($priceList);
foreach ($priceList as $priceData)
{
$priceData['VAT_RATE'] = $vat['RATE'];
$priceData['VAT_INCLUDED'] = $vat['VAT_INCLUDED'];
$currentPrice = (float)$priceData['PRICE'];
if ($boolDiscountVat)
{
if ($priceData['VAT_INCLUDED'] == 'N')
$currentPrice *= (1 + $priceData['VAT_RATE']);
}
else
{
if ($priceData['VAT_INCLUDED'] == 'Y')
$currentPrice /= (1 + $priceData['VAT_RATE']);
}
if ($priceData['CURRENCY'] != $resultCurrency)
$currentPrice = CCurrencyRates::ConvertCurrency($currentPrice, $priceData['CURRENCY'], $resultCurrency);
$currentPrice = Catalog\Product\Price\Calculation::roundPrecision($currentPrice);
$result = array(
'BASE_PRICE' => $currentPrice,
'COMPARE_PRICE' => $currentPrice,
'PRICE' => $currentPrice,
'CURRENCY' => $resultCurrency,
'DISCOUNT_LIST' => array(),
'RAW_PRICE' => $priceData
);
if ($isNeedDiscounts)
{
$arDiscounts = CCatalogDiscount::GetDiscount(
$intProductID,
$intIBlockID,
array($priceData['CATALOG_GROUP_ID']),
$arUserGroups,
$renewal,
$siteID,
$arDiscountCoupons
);
$discountResult = CCatalogDiscount::applyDiscountList($currentPrice, $resultCurrency, $arDiscounts);
unset($arDiscounts);
if ($discountResult === false)
return false;
$result['PRICE'] = $discountResult['PRICE'];
$result['COMPARE_PRICE'] = $discountResult['PRICE'];
$result['DISCOUNT_LIST'] = $discountResult['DISCOUNT_LIST'];
unset($discountResult);
}
elseif($isNeedleToMinimizeCatalogGroup)
{
$calculateData = $priceData;
$calculateData['PRICE'] = $currentPrice;
$calculateData['CURRENCY'] = $resultCurrency;
$possibleSalePrice = self::getPossibleSalePriceCustom(
$intProductID,
$calculateData,
$quantity,
$siteID,
$arUserGroups,
$arDiscountCoupons
);
unset($calculateData);
if ($possibleSalePrice === null)
return false;
$result['COMPARE_PRICE'] = $possibleSalePrice;
unset($possibleSalePrice);
}
if ($boolDiscountVat)
{
if (!$resultWithVat)
{
$result['PRICE'] /= (1 + $priceData['VAT_RATE']);
$result['COMPARE_PRICE'] /= (1 + $priceData['VAT_RATE']);
$result['BASE_PRICE'] /= (1 + $priceData['VAT_RATE']);
}
}
else
{
if ($resultWithVat)
{
$result['PRICE'] *= (1 + $priceData['VAT_RATE']);
$result['COMPARE_PRICE'] *= (1 + $priceData['VAT_RATE']);
$result['BASE_PRICE'] *= (1 + $priceData['VAT_RATE']);
}
}
$result['UNROUND_PRICE'] = $result['PRICE'];
$result['UNROUND_BASE_PRICE'] = $result['BASE_PRICE'];
if (Catalog\Product\Price\Calculation::isComponentResultMode())
{
$result['BASE_PRICE'] = Catalog\Product\Price::roundPrice(
$priceData['CATALOG_GROUP_ID'],
$result['BASE_PRICE'],
$resultCurrency
);
$result['PRICE'] = Catalog\Product\Price::roundPrice(
$priceData['CATALOG_GROUP_ID'],
$result['PRICE'],
$resultCurrency
);
if (
empty($result['DISCOUNT_LIST'])
|| Catalog\Product\Price\Calculation::compare($result['BASE_PRICE'], $result['PRICE'], '<=')
)
{
$result['BASE_PRICE'] = $result['PRICE'];
}
$result['COMPARE_PRICE'] = $result['PRICE'];
}
if (empty($minimalPrice) || $minimalPrice['COMPARE_PRICE'] > $result['COMPARE_PRICE'])
{
$minimalPrice = $result;
}
elseif (
$minimalPrice['COMPARE_PRICE'] == $result['COMPARE_PRICE']
&& $minimalPrice['RAW_PRICE']['PRICE_SCALE'] > $result['RAW_PRICE']['PRICE_SCALE']
)
{
$minimalPrice = $result;
}
unset($currentPrice, $result);
}
unset($priceData);
unset($vat);
$discountValue = ($minimalPrice['BASE_PRICE'] - $minimalPrice['PRICE']);
unset($minimalPrice['RAW_PRICE']['PRICE_SCALE']);
$arResult = array(
'PRICE' => $minimalPrice['RAW_PRICE'],
'RESULT_PRICE' => array(
'ID' => $minimalPrice['RAW_PRICE']['ID'],
'PRICE_TYPE_ID' => $minimalPrice['RAW_PRICE']['CATALOG_GROUP_ID'],
'BASE_PRICE' => $minimalPrice['BASE_PRICE'],
'DISCOUNT_PRICE' => $minimalPrice['PRICE'],
'CURRENCY' => $resultCurrency,
'DISCOUNT' => $discountValue,
'PERCENT' => (
$minimalPrice['BASE_PRICE'] > 0 && $discountValue > 0
? round((100*$discountValue)/$minimalPrice['BASE_PRICE'], 0)
: 0
),
'VAT_RATE' => $minimalPrice['RAW_PRICE']['VAT_RATE'],
'VAT_INCLUDED' => ($resultWithVat ? 'Y' : 'N'),
'UNROUND_BASE_PRICE' => $minimalPrice['UNROUND_BASE_PRICE'],
'UNROUND_DISCOUNT_PRICE' => $minimalPrice['UNROUND_PRICE']
),
'DISCOUNT_PRICE' => $minimalPrice['PRICE'],
'DISCOUNT' => array(),
'DISCOUNT_LIST' => array(),
'PRODUCT_ID' => $intProductID
);
if (!empty($minimalPrice['DISCOUNT_LIST']))
{
reset($minimalPrice['DISCOUNT_LIST']);
$arResult['DISCOUNT'] = current($minimalPrice['DISCOUNT_LIST']);
$arResult['DISCOUNT_LIST'] = $minimalPrice['DISCOUNT_LIST'];
}
unset($minimalPrice);
return $arResult;
}
public static function getAllowedPriceTypesCustom(array $userGroups){
static $priceTypeCache = array();
Main\Type\Collection::normalizeArrayValuesByInt($userGroups, true);
if (empty($userGroups))
return array();
$cacheKey = 'U'.implode('_', $userGroups);
if (!isset($priceTypeCache[$cacheKey]))
{
$priceTypeCache[$cacheKey] = array();
$priceIterator = Catalog\GroupAccessTable::getList(array(
'select' => array('CATALOG_GROUP_ID'),
'filter' => array('@GROUP_ID' => $userGroups, '=ACCESS' => Catalog\GroupAccessTable::ACCESS_BUY),
'order' => array('CATALOG_GROUP_ID' => 'ASC')
));
while ($priceType = $priceIterator->fetch())
{
$priceTypeId = (int)$priceType['CATALOG_GROUP_ID'];
$priceTypeCache[$cacheKey][$priceTypeId] = $priceTypeId;
unset($priceTypeId);
}
unset($priceType, $priceIterator);
}
return $priceTypeCache[$cacheKey];
}
public static $existPriceTypeDiscountsCustom = false;
public static function initSaleSettingsCustom()
{
if (self::$saleIncluded === null)
self::$saleIncluded = Main\Loader::includeModule('sale');
if (self::$saleIncluded)
{
self::$useSaleDiscount = (string)Main\Config\Option::get('sale', 'use_sale_discount_only') == 'Y';
if (self::$useSaleDiscount)
{
//TODO: replace runtime to reference after sale 17.5.2 will be stable
$row = Sale\Internals\DiscountEntitiesTable::getList(array(
'select' => array('ID'),
'filter' => array(
'=MODULE_ID' => 'catalog',
'=ENTITY' => 'PRICE',
'=FIELD_ENTITY' => 'CATALOG_GROUP_ID',
'=FIELD_TABLE' => 'CATALOG_GROUP_ID',
'=ACTIVE_DISCOUNT.ACTIVE' => 'Y'
),
'runtime' => array(
new Main\Entity\ReferenceField(
'ACTIVE_DISCOUNT',
'Bitrix\Sale\Internals\Discount',
array('=this.DISCOUNT_ID' => 'ref.ID'),
array('join_type' => 'LEFT')
)
),
'limit' => 1,
))->fetch();
self::$existPriceTypeDiscountsCustom = !empty($row);
unset($row);
}
}
}
public static function isNeedleToMinimizeCatalogGroupCustom(array $priceList)
{
if (self::$saleIncluded === null)
self::initSaleSettingsCustom();
if (
!self::$saleIncluded ||
!self::$useSaleDiscount ||
count($priceList) < 2
)
return false;
return self::$existPriceTypeDiscountsCustom;
}
public static function getPossibleSalePriceCustom($intProductID, array $priceData, $quantity, $siteID, array $userGroups, $coupons)
{
$possibleSalePrice = null;
$registry = Sale\Registry::getInstance(Sale\Registry::REGISTRY_TYPE_ORDER);
if (empty($priceData))
return $possibleSalePrice;
$isCompatibilityUsed = Sale\Compatible\DiscountCompatibility::isUsed();
Sale\Compatible\DiscountCompatibility::stopUsageCompatible();
$freezeCoupons = (empty($coupons) && is_array($coupons));
if ($freezeCoupons)
Sale\DiscountCouponsManager::freezeCouponStorage();
/** @var \Bitrix\Sale\Basket $basket */
static $basket = null,
/** @var \Bitrix\Sale\BasketItem $basketItem */
$basketItem = null;
if ($basket !== null)
{
if ($basket->getSiteId() != $siteID)
{
$basket = null;
$basketItem = null;
}
}
if ($basket === null)
{
/** @var Sale\Basket $basketClassName */
$basketClassName = $registry->getBasketClassName();
$basket = $basketClassName::create($siteID);
$basketItem = $basket->createItem('catalog', $intProductID);
}
$fields = array(
'PRODUCT_ID' => $intProductID,
'QUANTITY' => $quantity,
'LID' => $siteID,
'PRODUCT_PRICE_ID' => $priceData['ID'],
'PRICE' => $priceData['PRICE'],
'BASE_PRICE' => $priceData['PRICE'],
'DISCOUNT_PRICE' => 0,
'CURRENCY' => $priceData['CURRENCY'],
'CAN_BUY' => 'Y',
'DELAY' => 'N',
'PRICE_TYPE_ID' => (int)$priceData['CATALOG_GROUP_ID']
);
/** @noinspection PhpInternalEntityUsedInspection */
$basketItem->setFieldsNoDemand($fields);
$discount = Sale\Discount::buildFromBasket($basket, new Sale\Discount\Context\UserGroup($userGroups));
$discount->setExecuteModuleFilter(array('all', 'catalog'));
$discount->calculate();
$calcResults = $discount->getApplyResult(true);
if ($calcResults && !empty($calcResults['PRICES']['BASKET']))
{
$possibleSalePrice = reset($calcResults['PRICES']['BASKET']);
$possibleSalePrice = $possibleSalePrice['PRICE'];
}
if ($freezeCoupons)
Sale\DiscountCouponsManager::unFreezeCouponStorage();
$discount->setExecuteModuleFilter(array('all', 'sale', 'catalog'));
if ($isCompatibilityUsed === true)
{
Sale\Compatible\DiscountCompatibility::revertUsageCompatible();
}
return $possibleSalePrice;
}
}
$eventManager = Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandler('catalog', 'OnGetOptimalPrice', function(
$intProductID,
$quantity = 1,
$arUserGroups = [],
$renewal = "N",
$arPrices = [],
$siteID = false,
$arDiscountCoupons = false){
/*
global $APPLICATION;
$dir = $APPLICATION->GetCurDir();
if(strpos($dir, '/bitrix/admin/') !== false){
return true;
}
if(strpos($dir, '/bitrix/gadgets/') !== false){
return true;
}
if(strpos($dir, '/upload/') !== false){
return true;
}
if(defined('ADMIN_SECTION')){
return true;
}
*/
global $USER;
if(!$USER->IsAdmin()){
return true;
}
//pre1('OnGetOptimalPrice');
if(!$siteID){
if(!defined('ADMIN_SECTION')){
$siteID = SITE_ID;
}
}
$arAllowPrices = array();
if('s2' == $siteID){
$arAllowPrices = array(10,11);
}elseif('s3' == $siteID){
$arAllowPrices = array(9);
}
//pre1($arAllowPrices);
//pre1($arUserGroups);
if (!is_array($arUserGroups))
$arUserGroups = array();
if (!in_array(2, $arUserGroups))
$arUserGroups[] = 2;
$priceTypeList = CCatalogProductCustom::getAllowedPriceTypesCustom($arUserGroups);
$iterator = Catalog\PriceTable::getList(array(
'select' => array('ID', 'CATALOG_GROUP_ID', 'PRICE', 'CURRENCY'),
'filter' => array(
'=PRODUCT_ID' => $intProductID,
'@CATALOG_GROUP_ID' => $priceTypeList,
array(
'LOGIC' => 'OR',
'<=QUANTITY_FROM' => $quantity,
'=QUANTITY_FROM' => null
),
array(
'LOGIC' => 'OR',
'>=QUANTITY_TO' => $quantity,
'=QUANTITY_TO' => null
)
),
'order' => array('CATALOG_GROUP_ID' => 'ASC')
));
while ($row = $iterator->fetch())
{
$priceList[$row['CATALOG_GROUP_ID']] = $row;
}
//pre1($priceList);
//pre1($arAllowPrices); a
if(count($arAllowPrices)>0){
foreach($priceList as $row){
if(!in_array($row['CATALOG_GROUP_ID'],$arAllowPrices)){
unset($priceList[$row['CATALOG_GROUP_ID']]);
}
}
}
$priceList = array_values($priceList);
//pre1($priceList);
return CCatalogProductCustom::GetOptimalPriceCustom($intProductID, $quantity, $arUserGroups, $renewal, $priceList, $siteID, $arDiscountCoupons);
// if return true product added to basket
//if return false product NOT added to basket
return true;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment