Quite often, several types of prices can be found at online wholesale stores - they are usually referred to as OPT1, OPT2, OPT3, etc. Depending on how much the customer has collected good in the basket and (or) other conditions, this or that type of prices works for him.
Unfortunately, not all site engines provide for the presence of several types of prices for a product at once, and even those engines in which it is possible to set more than one price for a product often do not have flexible switching mechanisms. The latter is pretty popular "1C-Bitrix". On the one hand, in this CMS already in the “boxed” version (in the “Business” edition and above) there is support for several types of prices, and on the other hand, it is completely incomprehensible how to set up dynamic switching of these prices depending on certain conditions. The staff manual for this part also keeps deathly silence. I hope that the comrades from Bitrix will correct this unfortunate misunderstanding, but I decided not to wait for this happy moment and clearly thought of a crutch solution, which I decided to share with the community.
So let's go ...
')
First of all, you should pay attention to the
OnGetOptimalPrice handler. Despite the fact that this function appeared in the kernel a long time ago, its description was added recently in the online documentation. Meanwhile, this handler is triggered when there is an automatic selection of the optimal price for a particular product and allows you to redefine the price for it. We will try to use it to recalculate all prices in the basket, depending on the total amount of the purchase.
We connect the handler in the file / php_interface/init.php (by itself, if this file does not exist, then it must be created - the bitrix will connect it automatically)
AddEventHandler("catalog", "OnGetOptimalPrice", "MyGetOptimalPrice");
The declaration of the MyGetOptimalPrice function together with the input parameters will look like this:
function MyGetOptimalPrice($productID, $quantity = 1, $arUserGroups = array(), $renewal = "N", $arPrices = array(), $siteID = false, $arDiscountCoupons = false)
As can be seen from the above code, the function does not receive at the input the total amount of the value of the goods in the basket, but only the data of a particular product. So, it is necessary to get the cart data by request to the database. Because the handler is called in a cycle depending on the number of items in the cart, it makes sense to define a global variable in which we will write the total amount of the cart content when you first call the OnGetOptimalPrice handler.
The output should be something like this:
global $ LocalPrice;
$ LocalPrice = 0;
function MyGetOptimalPrice ($ productID, $ quantity = 1, $ arUserGroups = array (), $ renewal = "N", $ arPrices = array (), $ siteID = false, $ arDiscountCoupons = false)
{
global $ LocalPrice;
if ($ LocalPrice <= 0)
{
// Display the current cart for the current user
$ dbBasketItems = CSaleBasket :: GetList (false,
array (
"FUSER_ID" => CSaleBasket :: GetBasketUserID (),
"LID" => SITE_ID,
"ORDER_ID" => "NULL"
),
false
false
array ("ID", "MODULE", "PRODUCT_ID", "CALLBACK_FUNC", "QUANTITY", "DELAY", "CAN_BUY", "PRICE")
);
while ($ arItem = $ dbBasketItems-> Fetch ())
{
if ($ arItem ['DELAY'] == 'N' && $ arItem ['CAN_BUY'] == 'Y')
{
$ LocalPrice + = $ arItem ['PRICE'] * $ arItem ['QUANTITY'];
}
}
}
// OPT 1 with order amount up to 10 000 rubles
// OPT 2 with the order amount up to 20 000 rubles
// OPT 3 with an order value of more than 20 000 rubles
// we get all types of prices possible for this product
$ arOptPrices = CCatalogProduct :: GetByIDEx ($ productID);
if ($ LocalPrice <10000) {
$ price = $ arOptPrices ['PRICES'] [1] ['PRICE'];
$ catalog_group_id = 1;
}
elseif ($ LocalPrice> = 10,000 and $ LocalPrice <20000) {
$ price = $ arOptPrices ['PRICES'] [2] ['PRICE'];
$ catalog_group_id = 2;
}
elseif ($ LocalPrice> = 20000) {
$ price = $ arOptPrices ['PRICES'] [3] ['PRICE'];
$ catalog_group_id = 3;
}
return array (
'PRICE' => array (
"Id" => $ productID,
'CATALOG_GROUP_ID' => $ catalog_group_id,
'PRICE' => $ price,
'CURRENCY' => "RUB",
'ELEMENT_IBLOCK_ID' => $ productID,
'VAT_INCLUDED' => "Y",
),
'DISCOUNT' => array (
'VALUE' => $ discount,
'CURRENCY' => "RUB",
),
);
}
If you wish, you can optimize the code by adding caching to store the sample of prices, get rid of the hard-code task of conditions and bring the conditions into the config files or into the database. In principle, the very sampling of data from the recycle bin can also be taken out of the handler function and store the amount where the thread is in a session, a cookie, or a global variable (as you like and thinks correct). Of course, for the example of training did not begin to do all this. Use on health!