PHP
#bitrix#catalog#price#php#cPrice#discount

Получить цены товара и выбрать актуальную

Получение всех цен товара через CPrice::GetList с фильтрацией по типу цены и выбором актуальной цены с учётом скидок.

Как использовать

  1. Скопируйте нужный фрагмент кода.
  2. Вставьте в свой проект и при необходимости измените под задачу.
  3. Проверьте зависимости и окружение (версии, переменные).

Получение цен товара из каталога с выбором актуальной цены. Используйте в компонентах каталога, корзины, детальных страницах для отображения правильной цены с учётом типов цен и скидок.

use Bitrix\Main\Loader;

/**
 * Получить все цены товара
 * @param int $productId ID товара
 * @param int $priceTypeId ID типа цены (опционально)
 * @return array Массив цен
 */
function getProductPrices($productId, $priceTypeId = null) {
    if (!Loader::includeModule('catalog')) {
        return [];
    }
    
    $filter = ['PRODUCT_ID' => $productId];
    if ($priceTypeId) {
        $filter['CATALOG_GROUP_ID'] = $priceTypeId;
    }
    
    $res = CPrice::GetList(
        ['CATALOG_GROUP_ID' => 'ASC'],
        $filter
    );
    
    $prices = [];
    while ($price = $res->Fetch()) {
        $prices[] = [
            'ID' => $price['ID'],
            'PRICE' => $price['PRICE'],
            'CURRENCY' => $price['CURRENCY'],
            'PRICE_TYPE_ID' => $price['CATALOG_GROUP_ID'],
            'QUANTITY_FROM' => $price['QUANTITY_FROM'],
            'QUANTITY_TO' => $price['QUANTITY_TO']
        ];
    }
    
    return $prices;
}

/**
 * Получить актуальную цену товара с учётом скидок
 * @param int $productId ID товара
 * @param int $quantity Количество для расчёта (по умолчанию 1)
 * @param int $userId ID пользователя (для персональных скидок)
 * @return array|false ['PRICE' => float, 'CURRENCY' => string, 'DISCOUNT_PRICE' => float] или false
 */
function getActualProductPrice($productId, $quantity = 1, $userId = 0) {
    if (!Loader::includeModule('catalog') || !Loader::includeModule('sale')) {
        return false;
    }
    
    // Получаем базовую цену
    $prices = getProductPrices($productId);
    if (empty($prices)) {
        return false;
    }
    
    // Берём первую цену (обычно базовая)
    $basePrice = $prices[0];
    
    // Используем CCatalogProduct для получения цены с учётом скидок
    $arPrice = CCatalogProduct::GetOptimalPrice(
        $productId,
        $quantity,
        $userId ?: $GLOBALS['USER']->GetID(),
        'N'
    );
    
    if ($arPrice && isset($arPrice['PRICE']['PRICE'])) {
        return [
            'PRICE' => (float)$arPrice['PRICE']['PRICE'],
            'CURRENCY' => $arPrice['PRICE']['CURRENCY'],
            'DISCOUNT_PRICE' => isset($arPrice['DISCOUNT']['PRICE']) ? (float)$arPrice['DISCOUNT']['PRICE'] : null,
            'DISCOUNT_PERCENT' => isset($arPrice['DISCOUNT']['PERCENT']) ? (float)$arPrice['DISCOUNT']['PERCENT'] : null,
            'BASE_PRICE' => (float)$basePrice['PRICE']
        ];
    }
    
    return [
        'PRICE' => (float)$basePrice['PRICE'],
        'CURRENCY' => $basePrice['CURRENCY'],
        'DISCOUNT_PRICE' => null,
        'BASE_PRICE' => (float)$basePrice['PRICE']
    ];
}

Usage:

// Получить все цены товара
$prices = getProductPrices(12345);
foreach ($prices as $price) {
    echo $price['PRICE'] . ' ' . $price['CURRENCY'];
}

// Получить актуальную цену с учётом скидок
$actualPrice = getActualProductPrice(12345, 1, $USER->GetID());
if ($actualPrice) {
    if ($actualPrice['DISCOUNT_PRICE']) {
        echo 'Старая цена: ' . $actualPrice['BASE_PRICE'];
        echo 'Цена со скидкой: ' . $actualPrice['PRICE'];
    } else {
        echo 'Цена: ' . $actualPrice['PRICE'];
    }
}

Notes:

⚠️ CCatalogProduct::GetOptimalPrice() учитывает скидки, персональные цены, количество. Для работы скидок должен быть подключен модуль sale. Если пользователь не авторизован, передавайте 0 в $userId. Метод возвращает цену с учётом всех применённых скидок.