В 1С-Битрикс для получения и вывода минимальной цены товара с учётом скидки и без скидки есть несколько способов. Ниже описаны основные подходы.
1. Через типовые компоненты каталога
Стандартные компоненты bitrix:catalog, bitrix:catalog.section, bitrix:catalog.element уже рассчитывают цены со скидками. В результатах работы компонента в $arResult для каждого товара формируется массив PRICES и MIN_PRICE.
Ключевые поля в $arResult['ITEM']['MIN_PRICE'] (или $arResult['MIN_PRICE']):
VALUE— цена без скидки (базовая цена);DISCOUNT_VALUE— цена со скидкой (итоговая);PRINT_VALUE— цена без скидки, отформатированная с символом валюты;PRINT_DISCOUNT_VALUE— цена со скидкой, отформатированная с символом валюты;DISCOUNT_DIFF— абсолютная разница (скидка в валюте);DISCOUNT_DIFF_PERCENT— скидка в процентах;CURRENCY— валюта цены;PRINT_DISCOUNT_DIFF— форматированная разница.
Пример вывода в шаблоне компонента:
<?php
// $arItem - текущий товар из цикла
if (!empty($arItem['MIN_PRICE'])): ?>
<?php if ($arItem['MIN_PRICE']['DISCOUNT_DIFF'] > 0): ?>
<p>
<span style="text-decoration: line-through; color: #999;">
<?= $arItem['MIN_PRICE']['PRINT_VALUE'] ?>
</span>
<br>
<span style="color: red; font-size: 1.2em;">
<?= $arItem['MIN_PRICE']['PRINT_DISCOUNT_VALUE'] ?>
</span>
<br>
<em>Экономия: <?= $arItem['MIN_PRICE']['PRINT_DISCOUNT_DIFF'] ?>
(<?= $arItem['MIN_PRICE']['DISCOUNT_DIFF_PERCENT'] ?>%)</em>
</p>
<?php else: ?>
<p>Цена: <?= $arItem['MIN_PRICE']['PRINT_VALUE'] ?></p>
<?php endif; ?>
<?php endif; ?>
2. Программно — через CIBlockPriceTools::GetItemPrices()
Метод CIBlockPriceTools::GetItemPrices() (модуль iblock, файл /bitrix/modules/iblock/classes/general/comp_pricetools.php, строка 272) возвращает массив всех цен для одного товара с уже рассчитанными скидками.
Пример получения минимальной цены для товара:
<?php
\Bitrix\Main\Loader::includeModule('iblock');
\Bitrix\Main\Loader::includeModule('catalog');
$IBLOCK_ID = 2; // ID инфоблока каталога
$ELEMENT_ID = 123; // ID товара
// 1. Получаем список типов цен, разрешённых для показа
$arPriceCode = ['BASE']; // коды типов цен
$arCatalogPrices = CIBlockPriceTools::GetCatalogPrices($IBLOCK_ID, $arPriceCode);
// 2. Получаем элемент со всеми ценовыми полями
$arSelect = ['ID', 'IBLOCK_ID', 'NAME'];
foreach ($arCatalogPrices as $price) {
$arSelect[] = $price['SELECT'];
foreach ($price['SELECT_EXTENDED'] as $field) {
$arSelect[] = $field;
}
}
$arSelect[] = 'CATALOG_GROUP_ID';
$arSelect[] = 'CATALOG_VAT';
$arSelect[] = 'CATALOG_VAT_INCLUDED';
$rsElement = CIBlockElement::GetList(
[],
['IBLOCK_ID' => $IBLOCK_ID, 'ID' => $ELEMENT_ID],
false,
false,
$arSelect
);
if ($arElement = $rsElement->GetNext()) {
// 3. Получаем цены со скидками
$arPrices = CIBlockPriceTools::GetItemPrices(
$IBLOCK_ID,
$arCatalogPrices,
$arElement,
true, // bVATInclude
['CURRENCY_ID' => 'RUB'] // конвертировать в валюту
);
// 4. Находим минимальную цену
$minPrice = CIBlockPriceTools::getMinPriceFromList($arPrices);
if ($minPrice): ?>
<p>
<b>Цена без скидки:</b> <?= $minPrice['PRINT_VALUE'] ?><br>
<b>Цена со скидкой:</b> <?= $minPrice['PRINT_DISCOUNT_VALUE'] ?><br>
<?php if ($minPrice['DISCOUNT_DIFF'] > 0): ?>
<b>Скидка:</b> <?= $minPrice['PRINT_DISCOUNT_DIFF'] ?>
(<?= $minPrice['DISCOUNT_DIFF_PERCENT'] ?>%)
<?php endif; ?>
</p>
<?php endif;
}
?>
3. Для товаров с торговыми предложениями (SKU/офферы)
Если товар имеет торговые предложения, минимальная цена определяется по всем офферам. Используйте CIBlockPriceTools::GetOffersArray() и getMinPriceFromOffers():
<?php
\Bitrix\Main\Loader::includeModule('iblock');
\Bitrix\Main\Loader::includeModule('catalog');
$IBLOCK_ID = 2;
$ELEMENT_ID = 123;
$arPriceCode = ['BASE'];
// 1. Получаем разрешённые типы цен
$arCatalogPrices = CIBlockPriceTools::GetCatalogPrices($IBLOCK_ID, $arPriceCode);
$arPricesAllowed = CIBlockPriceTools::GetAllowCatalogPrices($arCatalogPrices);
// 2. Получаем массив офферов с ценами
$arOffers = CIBlockPriceTools::GetOffersArray(
[
'IBLOCK_ID' => $IBLOCK_ID,
'HIDE_NOT_AVAILABLE' => 'N',
],
[$ELEMENT_ID],
['SORT' => 'ASC'],
['ID', 'NAME'],
[], // свойства для выборки
0, // лимит (0 - без лимита)
$arCatalogPrices,
true, // bVATInclude
['CURRENCY_ID' => 'RUB']
);
// 3. Находим минимальную цену среди офферов
$minPriceFromOffers = CIBlockPriceTools::getMinPriceFromOffers(
$arOffers,
'RUB',
true
);
if ($minPriceFromOffers): ?>
<p>
<b>Минимальная цена без скидки:</b>
<?= $minPriceFromOffers['PRINT_VALUE'] ?><br>
<b>Минимальная цена со скидкой:</b>
<?= $minPriceFromOffers['PRINT_DISCOUNT_VALUE'] ?><br>
<?php if ($minPriceFromOffers['DISCOUNT_DIFF'] > 0): ?>
<b>Скидка:</b>
<?= $minPriceFromOffers['PRINT_DISCOUNT_DIFF'] ?>
(<?= $minPriceFromOffers['DISCOUNT_DIFF_PERCENT'] ?>%)
<?php endif; ?>
</p>
<?php endif; ?>
4. Напрямую через ORM Bitrix\Catalog\PriceTable
Для низкоуровневой работы с ценами используйте ORM-таблицу Bitrix\Catalog\PriceTable (модуль catalog):
<?php
use Bitrix\Catalog\PriceTable;
use Bitrix\Catalog\GroupTable;
\Bitrix\Main\Loader::includeModule('catalog');
$ELEMENT_ID = 123;
// Получаем все цены товара по всем типам цен
$prices = PriceTable::getList([
'select' => ['*', 'CATALOG_GROUP_NAME' => 'GROUP.NAME'],
'filter' => ['=PRODUCT_ID' => $ELEMENT_ID],
'order' => ['CATALOG_GROUP_ID' => 'ASC']
])->fetchAll();
// Для расчёта скидок используйте CCatalogDiscount::GetDiscount
// и CCatalogProduct::CountPriceWithDiscount
?>
Ключевые классы и методы
CIBlockPriceTools::GetCatalogPrices()— модуль iblock, класс/bitrix/modules/iblock/classes/general/comp_pricetools.php(строка 21). Возвращает массив типов цен с правами доступа.CIBlockPriceTools::GetItemPrices()— тот же файл (строка 272). Рассчитывает все цены для товара с применением скидок и НДС.CIBlockPriceTools::getMinPriceFromList()— тот же файл (строка 2670). Находит цену с флагомMIN_PRICE = 'Y'в массиве цен.CIBlockPriceTools::getMinPriceFromOffers()— тот же файл (строка 2322). Находит минимальную цену среди массива торговых предложений.CIBlockPriceTools::GetOffersArray()— тот же файл (строка 1346). Получает массив офферов с ценами.Bitrix\Catalog\PriceTable— ORM-сущность для таблицы цен b_catalog_price.
Ключевые поля результата работы GetItemPrices():
VALUE/PRINT_VALUE— цена без скидки;DISCOUNT_VALUE/PRINT_DISCOUNT_VALUE— цена со скидкой;DISCOUNT_DIFF/PRINT_DISCOUNT_DIFF— разница (скидка);DISCOUNT_DIFF_PERCENT— скидка в процентах;MIN_PRICE— флаг'Y'у минимальной цены среди всех типов цен;CURRENCY— валюта.