Студия Михаила Кечинова

ruen
Навигация
Главная Хозяйке на заметку: как получить финальную цену на товар в Битриксе

Хозяйке на заметку: как получить финальную цену на товар в Битриксе

Если вы пишете модуль под Битрикс, у вас может возникнуть необходимость получить финальную цену товара с учетом валюты, скидок, прав пользователя и того, что товар может быть как обычным, так и содержать торговые предложения. Вот вам код функции, которая это делает:


<?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;

}