Возникла задача организации интернет-магазина с множеством торговых предложений (деление по цвету изделия, типам и пр.). За основу выбрали шаблон компонента Каталог по умолчанию. Инфолоки настроили, товары с торговыми предложениям создали - компонент работает. Но тут возникло требование - реализовать зависимость цены на товарную позицию от количества добавленного товара в корзину (расширенный режим управления ценами) и оказалось, что шаблон компонента данный фукнционал ещё не поддерживает.
Для начала в файле result_modifier организуем получение "ценовой матрицы" для товарной позиции. За работу с простым типом товаров и товаров с торговыми предложениями отвечают два простых условия:
if ($arResult['CATALOG'] && isset($arResult['OFFERS']) && !empty($arResult['OFFERS'])) {
...
foreach ($arResult['OFFERS'] as &$arOffer) {
...
$arResultPrices = CIBlockPriceTools::GetCatalogPrices($arParams['IBLOCK_ID'], $arParams['PRICE_CODE']);
foreach ($arResultPrices as $value) {
// if (!$value['CAN_VIEW'] && !$value['CAN_BUY'])
// continue;
$arPriceTypeID[] = $value['ID'];
}
if (isset($value))
unset($value);
$arOffer['PRICE_MATRIX'] = CatalogGetPriceTableEx($arOffer['ID'], 0, $arPriceTypeID, 'Y');
if (is_array($arOffer['PRICE_MATRIX'])) {
$boolSKUDisplayProps = true;
if (isset($arOffer['PRICE_MATRIX']['COLS']) && is_array($arOffer['PRICE_MATRIX']['COLS'])) {
foreach ($arOffer['PRICE_MATRIX']['COLS'] as $keyColumn => $arColumn)
$arOffer['PRICE_MATRIX']['COLS'][$keyColumn]['NAME_LANG'] = htmlspecialcharsbx($arColumn['NAME_LANG']);
}
}
}
...
}
|
if ($arResult['CATALOG_TYPE'] == CCatalogProduct::TYPE_PRODUCT || $arResult['CATALOG_TYPE'] == CCatalogProduct::TYPE_SET) {
...
$arResultPrices = CIBlockPriceTools::GetCatalogPrices($arParams['IBLOCK_ID'], $arParams['PRICE_CODE']);
foreach ($arResultPrices as &$value) {
// if (!$value['CAN_VIEW'] && !$value['CAN_BUY'])
// continue;
$arPriceTypeID[] = $value['ID'];
}
if (isset($value))
unset($value);
$arResult['PRICE_MATRIX'] = CatalogGetPriceTableEx($arResult['ID'], 0, $arPriceTypeID, 'Y');
if (isset($arResult['PRICE_MATRIX']['COLS']) && is_array($arResult['PRICE_MATRIX']['COLS'])) {
foreach ($arResult['PRICE_MATRIX']['COLS'] as $keyColumn => $arColumn)
$arResult['PRICE_MATRIX']['COLS'][$keyColumn]['NAME_LANG'] = htmlspecialcharsbx($arColumn['NAME_LANG']);
}
...
}
|
Далее в шаблоне для простого типа товаров просто выводим таблицу в отдельном блоке:
$strMatrix = '';
if (!isset($arResult['OFFERS']) || empty($arResult['OFFERS'])) {
...
if (is_array($arResult['PRICE_MATRIX'])) {
$strMatrix .= '<dd class="clear">';
$strMatrix .= '<table cellpadding="0" cellspacing="0" class="price-matrix">';
$strMatrix .= '<thead>';
$strMatrix .= '<tr>';
if (count($arResult['PRICE_MATRIX']['ROWS']) >= 1 && ($arResult['PRICE_MATRIX']['ROWS'][0]['QUANTITY_FROM'] > 0 || $arResult['PRICE_MATRIX']['ROWS'][0]['QUANTITY_TO'] > 0)) {
$strMatrix .= '<td>' . GetMessage('CATALOG_QUANTITY') . '</td>';
}
foreach ($arResult['PRICE_MATRIX']['COLS'] as $typeID => $arType) {
$strMatrix .= '<td>' . $arType['NAME_LANG'] . '</td>';
}
$strMatrix .= '</tr>';
$strMatrix .= '</thead>';
foreach ($arResult['PRICE_MATRIX']['ROWS'] as $ind => $arQuantity) {
$strMatrix .= '<tr>';
if ((count($arResult['PRICE_MATRIX']['ROWS']) > 1) || (count($arResult['PRICE_MATRIX']['ROWS']) == 1 && ($arResult['PRICE_MATRIX']['ROWS'][0]['QUANTITY_FROM'] > 0 || $arResult['PRICE_MATRIX']['ROWS'][0]['QUANTITY_TO'] > 0))) {
$strMatrix .= '<td nowrap>';
if (IntVal($arQuantity['QUANTITY_FROM']) > 0 && IntVal($arQuantity['QUANTITY_TO']) > 0)
$strMatrix .= str_replace('#FROM#', $arQuantity['QUANTITY_FROM'], str_replace('#TO#', $arQuantity['QUANTITY_TO'], GetMessage('CATALOG_QUANTITY_FROM_TO')));
elseif (IntVal($arQuantity['QUANTITY_FROM']) > 0)
$strMatrix .= str_replace('#FROM#', $arQuantity['QUANTITY_FROM'], GetMessage('CATALOG_QUANTITY_FROM'));
elseif(IntVal($arQuantity['QUANTITY_TO']) > 0)
$strMatrix .= str_replace('#TO#', $arQuantity['QUANTITY_TO'], GetMessage('CATALOG_QUANTITY_TO'));
$strMatrix .= '</td>';
}
foreach ($arResult['PRICE_MATRIX']['COLS'] as $typeID => $arType) {
$strMatrix .= '<td style="text-align: center;">';
if ($arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['DISCOUNT_PRICE'] < $arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['PRICE'])
$strMatrix .= '<s>' . FormatCurrency($arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['PRICE'], $arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['CURRENCY']) . '</s> <span class="catalog-price">' . FormatCurrency($arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['DISCOUNT_PRICE'], $arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['CURRENCY']) . '</span>';
else
$strMatrix .= '<span class="catalog-price">' . FormatCurrency($arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['PRICE'], $arResult['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['CURRENCY']) . '</span>';
$strMatrix .= '</td>';
}
$strMatrix .= '</tr>';
}
$strMatrix .= '</table>';
$strMatrix .= '</dd>';
}
if (strlen($strMatrix) > 0) {
?>
<div class="item_info_section">
<dl id="<?=$arItemIDs['DISPLAY_MATRIX_DIV'] ?>"><?=$strMatrix?></dl>
</div>
<?php
}
}
|
Для товаров с торговыми предложениями вывод интервалов цен несколько сложнее, т. к. у разных торговых предложений цены могут различаться. Вывод таблицы строится аналогично выводу свойств торговых предложений. Сначала выводится пустой блок с заданным идентификатором для доступа посредством JS. Затем формируется вывод таблицы для каждого торгового предложения в виде строки и добавляется в массив параметров для вызова JS.
...
if (isset($arResult['OFFERS']) && !empty($arResult['OFFERS']) && !empty($arResult['OFFERS_PROP'])) {
?>
<div class="item_info_section">
<dl id="<?=$arItemIDs['DISPLAY_MATRIX_DIV'] ?>" style="display: none;"></dl>
</div>
<?php
}
...
if (isset($arResult['OFFERS']) && !empty($arResult['OFFERS'])) {
foreach ($arResult['JS_OFFERS'] as $iKey => &$arOneJS) {
if (isset($arResult['OFFERS'][$iKey]['PRICE_MATRIX']) && is_array($arResult['OFFERS'][$iKey]['PRICE_MATRIX'])) {
...
$strMatrix = '';
$strMatrix .= '<dd class="clear">';
$strMatrix .= '<table cellpadding="0" cellspacing="0" class="price-matrix">';
$strMatrix .= '<thead>';
$strMatrix .= '<tr>';
if (count($arOffer['PRICE_MATRIX']['ROWS']) >= 1
&& ($arOffer['PRICE_MATRIX']['ROWS'][0]['QUANTITY_FROM'] > 0
|| $arOffer['PRICE_MATRIX']['ROWS'][0]['QUANTITY_TO'] > 0)
) {
$strMatrix .= '<td>' . GetMessage('CATALOG_QUANTITY') . '</td>';
}
foreach($arOffer['PRICE_MATRIX']['COLS'] as $typeID => $arType) {
$strMatrix .= '<td>' . $arType['NAME_LANG'] . '</td>';
}
$strMatrix .= '</tr>';
$strMatrix .= '</thead>';
$strMatrix .= '<tbody>';
foreach ($arOffer['PRICE_MATRIX']['ROWS'] as $ind => $arQuantity) {
$strMatrix .= '<tr>';
if ((count($arOffer['PRICE_MATRIX']['ROWS']) > 1)
|| (count($arOffer['PRICE_MATRIX']['ROWS']) == 1 && ($arOffer['PRICE_MATRIX']['ROWS'][0]['QUANTITY_FROM'] > 0
|| $arOffer['PRICE_MATRIX']['ROWS'][0]['QUANTITY_TO'] > 0))
) {
$strMatrix .= '<td nowrap>';
if (IntVal($arQuantity['QUANTITY_FROM']) > 0 && IntVal($arQuantity['QUANTITY_TO']) > 0)
$strMatrix .= str_replace('#FROM#', $arQuantity['QUANTITY_FROM'], str_replace('#TO#', $arQuantity['QUANTITY_TO'], GetMessage('CATALOG_QUANTITY_FROM_TO')));
elseif (IntVal($arQuantity['QUANTITY_FROM']) > 0)
$strMatrix .= str_replace('#FROM#', $arQuantity['QUANTITY_FROM'], GetMessage('CATALOG_QUANTITY_FROM'));
elseif (IntVal($arQuantity['QUANTITY_TO']) > 0)
$strMatrix .= str_replace('#TO#', $arQuantity['QUANTITY_TO'], GetMessage('CATALOG_QUANTITY_TO'));
$strMatrix .= '</td>';
}
foreach($arOffer['PRICE_MATRIX']['COLS'] as $typeID => $arType) {
$strMatrix .= '<td style="text-align: center;">';
if ($arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['DISCOUNT_PRICE'] < $arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['PRICE'])
$strMatrix .= '<s>'.FormatCurrency($arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['PRICE'], $arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['CURRENCY']).'</s> <span class="catalog-price">'.FormatCurrency($arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['DISCOUNT_PRICE'], $arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['CURRENCY']).'</span>';
else
$strMatrix .= '<span class="catalog-price">'.FormatCurrency($arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['PRICE'], $arOffer['PRICE_MATRIX']['MATRIX'][$typeID][$ind]['CURRENCY']).'</span>';
$strMatrix .= '</td>';
}
$strMatrix .= '</tr>';
}
$strMatrix .= '</tbody>';
$strMatrix .= '</table>';
$strMatrix .= '</dd>';
...
}
}
...
$arOneJS['DISPLAY_MATRIX'] = $strMatrix;
...
if (isset($arResult['OFFERS'][$iKey]['PRICE_MATRIX']) && is_array($arResult['OFFERS'][$iKey]['PRICE_MATRIX'])) {
$arOneJS['PRICE_MATRIX'] = $arResult['OFFERS'][$iKey]['PRICE_MATRIX'];
}
}
...
|
Далее в файле script.js остаётся выбрать значение цены для указанного количества и подставить это значение в момент обновления цены на странице шаблона компонента. За выбор значения цены отвечает отдельный метод, который с помощью простых итераций формирует объект calcPrice. Обновление цены выполняется в методах QuantityUp, QuantityDown и QuantityChange.
...
calcPrice = {
DISCOUNT_VALUE: this.currentBasisPrice.DISCOUNT_VALUE * this.obQuantity.value,
VALUE: this.currentBasisPrice.VALUE * this.obQuantity.value,
DISCOUNT_DIFF: this.currentBasisPrice.DISCOUNT_DIFF * this.obQuantity.value,
DISCOUNT_DIFF_PERCENT: this.currentBasisPrice.DISCOUNT_DIFF_PERCENT,
CURRENCY: this.currentBasisPrice.CURRENCY
};
...
|
При обновлении цены также необходимо учитывать тип продукта.
switch (this.productType) {
case 1://product
case 2://set
...
break;
case 3://sku
...
break;
}
|
1С-Битрикс: Управление сайтом 15.0.6.
Главный модуль: 15.0.6.
Торговый каталог: 15.0.3.