Если вы пишете модуль под Битрикс, у вас может возникнуть необходимость получить финальную цену товара с учетом валюты, скидок, прав пользователя и того, что товар может быть как обычным, так и содержать торговые предложения. Вот вам код функции, которая это делает:
<?php
use COption;
use CCurrency;
use CCatalogProduct;
use CFile;
use CModule;
use CCatalogDiscount;
use CCatalogSKU;
use CPrice;
use CCurrencyLang;
use CCurrencyRates;
use CIBlockElement;
use CIBlockPriceTools;
\CModule::IncludeModule('iblock');
\CModule::IncludeModule('catalog');
\CModule::IncludeModule('sale');
/**
* Calculate final price of product
* @param integer $item_id Item ID
* @param string $sale_currency Currency code
* @return float
*/
function getFinalPriceInCurrency($item_id, $sale_currency = 'RUB') {
global $USER;
$currency_code = 'RUB';
// Do item have offers?
if(CCatalogSku::IsExistOffers($item_id)) {
// Пытаемся найти цену среди торговых предложений
$res = CIBlockElement::GetByID($item_id);
if($ar_res = $res->GetNext()) {
if(isset($ar_res['IBLOCK_ID']) && $ar_res['IBLOCK_ID']) {
// Find all offers
$offers = CIBlockPriceTools::GetOffersArray(array(
'IBLOCK_ID' => $ar_res['IBLOCK_ID'],
'HIDE_NOT_AVAILABLE' => 'Y',
'CHECK_PERMISSIONS' => 'Y'
), array($item_id), null, null, null, null, null, null, array('CURRENCY_ID' => $sale_currency), $USER->getId(), null);
foreach($offers as $offer) {
$price = CCatalogProduct::GetOptimalPrice($offer['ID'], 1, $USER->GetUserGroupArray(), 'N');
if(isset($price['PRICE'])) {
$final_price = $price['PRICE']['PRICE'];
$currency_code = $price['PRICE']['CURRENCY'];
// Find discounts and calculate price with discounts
$arDiscounts = CCatalogDiscount::GetDiscountByProduct($item_id, $USER->GetUserGroupArray(), "N");
if(is_array($arDiscounts) && sizeof($arDiscounts) > 0) {
$final_price = CCatalogProduct::CountPriceWithDiscount($final_price, $currency_code, $arDiscounts);
}
// Stop cycle, use found value
break;
}
}
}
}
} else {
// Simple product, not trade offers
$price = CCatalogProduct::GetOptimalPrice($item_id, 1, $USER->GetUserGroupArray(), 'N');
// Got price?
if(!$price || !isset($price['PRICE'])) {
return false;
}
// Change currency code if found
if(isset($price['CURRENCY'])) {
$currency_code = $price['CURRENCY'];
}
if(isset($price['PRICE']['CURRENCY'])) {
$currency_code = $price['PRICE']['CURRENCY'];
}
// Get final price
$final_price = $price['PRICE']['PRICE'];
// Find discounts and calculate price with discounts
$arDiscounts = CCatalogDiscount::GetDiscountByProduct($item_id, $USER->GetUserGroupArray(), "N", 2);
if(is_array($arDiscounts) && sizeof($arDiscounts) > 0) {
$final_price = CCatalogProduct::CountPriceWithDiscount($final_price, $currency_code, $arDiscounts);
}
}
// Convert to sale currency if needed
if($currency_code != $sale_currency) {
$final_price = CCurrencyRates::ConvertCurrency($final_price, $currency_code, $sale_currency);
$currency_code = $sale_currency;
}
return $final_price;
}