Как получить цену товара со скидками, 1С-Битрикс

Как получить цену товара со скидками, 1С-Битрикс

Как получить цену товара со скидками, 1С-Битрикс

Казалось бы, в чем может быть загвоздка при получении цены товара, обработанного всеми скидками и накопительными программами? Как оказалось - в отсутствии встроенного функционала.

Перепробовав массу вариантов из апи хелпа битрикса я так и не нашел тех средств, с помощью которых смог бы легко решить свою проблему.

Но чудесным образом, среди тонны неподходящих статей и топиков на форумах, после безуспешного обращения на форуме сообщества, я все-таки обнаружул в одном дальнем уголке всемирной паутины решение моей задачи.

Привожу полностью код этого решения:

<?
/***Как посчитать стоимость товара или предложения со всеми скидками***/
function getFinalPriceInCurrency($item_id, $sale_currency = 'RUB') {
CModule::IncludeModule("iblock"); 
CModule::IncludeModule("catalog");
CModule::IncludeModule("sale");   
    global $USER;

    $currency_code = 'RUB';

    // Проверяем, имеет ли товар торговые предложения?
    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']) {

                // Ищем все тогровые предложения
                $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'];

                        // Ищем скидки и высчитываем стоимость с учетом найденных
                        $arDiscounts = CCatalogDiscount::GetDiscountByProduct($item_id, $USER->GetUserGroupArray(), "N");
                        if(is_array($arDiscounts) && sizeof($arDiscounts) > 0) {
                            $final_price = CCatalogProduct::CountPriceWithDiscount($final_price, $currency_code, $arDiscounts);
                        }

                        // Конец цикла, используем найденные значения
                        break;
                    }

                }
            }
        }

    } else {

        // Простой товар, без торговых предложений (для количества равному 1)
        $price = CCatalogProduct::GetOptimalPrice($item_id, 1, $USER->GetUserGroupArray(), 'N');

        // Получили цену?
        if(!$price || !isset($price['PRICE'])) {
            return false;
        }

        // Меняем код валюты, если нашли
        if(isset($price['CURRENCY'])) {
            $currency_code = $price['CURRENCY'];
        }
        if(isset($price['PRICE']['CURRENCY'])) {
            $currency_code = $price['PRICE']['CURRENCY'];
        }

        // Получаем итоговую цену
        $final_price = $price['PRICE']['PRICE'];

        // Ищем скидки и пересчитываем цену товара с их учетом
        $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);
        }

    }

    // Если необходимо, конвертируем в нужную валюту
    if($currency_code != $sale_currency) {
        $final_price = CCurrencyRates::ConvertCurrency($final_price, $currency_code, $sale_currency);
    }

    return $final_price;

}
?>

Вкраце: функция принимает в качестве параметра ID товара и код валюты магазина(по-умолчанию 'RUB'). После чего проверяет, есть ли у него торговое предложение. Если оно есть, то идет пересчет его цены. Если же его нет, то идет пересчет самого товара.

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

<?
/***Как посчитать стоимость товара или предложения со всеми скидками***/
function getFinalPriceInCurrency($item_id, $sale_currency = 'RUB') {
CModule::IncludeModule("iblock"); 
CModule::IncludeModule("catalog");
CModule::IncludeModule("sale");   
    global $USER;

    $currency_code = 'RUB';

    // Простой товар, без торговых предложений (для количества равному 1)
    $price = CCatalogProduct::GetOptimalPrice($item_id, 1, $USER->GetUserGroupArray(), 'N');

    // Получили цену?
    if(!$price || !isset($price['PRICE'])) {
        return false;
    }

    // Меняем код валюты, если нашли
    if(isset($price['CURRENCY'])) {
        $currency_code = $price['CURRENCY'];
    }
    if(isset($price['PRICE']['CURRENCY'])) {
        $currency_code = $price['PRICE']['CURRENCY'];
    }

    // Получаем итоговую цену
    $final_price = $price['PRICE']['PRICE'];

    // Ищем скидки и пересчитываем цену товара с их учетом
    $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);
    }


    // Если необходимо, конвертируем в нужную валюту
    if($currency_code != $sale_currency) {
        $final_price = CCurrencyRates::ConvertCurrency($final_price, $currency_code, $sale_currency);
    }

    return $final_price;

}
?>

И снова упорство побеждает неполноту документации! =)


  • Здравствуйте! Если у вас нет торговых предложений у товаров, то это несложно. Достаточно добавить условие для конкретного раздела (если это комплексный компонент каталога) и фильтр для компонента: if($APPLICATION->GetCurDir() == "/catalog/vse-po-99"){ $GLOBALS["arrMyFilter"] = array("> array("99.00","99.99")); }else{ $GLOBALS["arrMyFilter"] = $arParams["FILTER_NAME"]; } Это условие вам нужно указать в файле section.php (перед подключением компонента, в папке комплексного компонента bitrix:catalog) - вот сюда http://joxi.ru/5mdGJ9tv89eLr1 Если у вас не комплексный компонент, а простой компонент bitrix:catalog.section, который лежит на статической странице, то просто перед ним укажите фильтр: $GLOBALS["arrMyFilter"] = array("> array("99.00","99.99")); и подставьте название фильтра - arrMyFilter - в поле "FILTER_NAME" компонента. Если же у вас товары с торговыми предложениями, то там все сложнее. Если вкратце, то вам нужно будет создать дополнительное свойство у элементов - "Минимальная цена" с типом "Число", и в него записывать значение минимальной цены вашего товара. И потом уже по этому свойству выводить товары на странице. Точно также, фильтром: $GLOBALS["arrMyFilter"] = array("> array("99.00","99.99")); P.S. символы "><" перед свойством означают, что числа должны находиться в диапазоне между двумя значениями. В вашем случае это 99.00 и 99.99
  • Спасибо большое! Очень помогло, всё работает.
  • Не за что! ;)