Всем привет! На дополнительном сайте использует покупное решение, поэтому переписывать компоненты/внедрять свой класс корзины, свои провайдеры - вроде не вариант. И править сильно шаблоны товаров, которых хватает, тоже не хочется. А задача вроде не сложная - у товара есть <розничная цена> и есть <старая цена> (доступная для просмотра, но не покупки), и нужно указывать их разницу через механизм вывода скидок.
Для этого написал обработчик OnGetOptimalPriceResult, который проверяет наличие у товара <старой цены>, и, если она есть, то рассчитывает соответствующим образом значения ['RESULT_PRICE']['BASE_PRICE'] (а также ['RESULT_PRICE']['DISCOUNT'] и ['RESULT_PRICE']['PERCENT'] - используется для отображения в шаблонах купленного решения). Ну и ['DISCOUNT'] и ['DISCOUNT_LIST'] в возвращаемый массив добавляю для красоты (в плане вывода почти ни на что не влияет).
Все бы хорошо, но при добавлении в корзину/создании заказа в корзину (в таблицу b_sale_basket) попадает <старая цена> то есть ['RESULT_PRICE']['BASE_PRICE'], а не ['RESULT_PRICE']['DISCOUNT_PRICE'], как, казалось бы должно быть.
Видимо при добавлении товара цена пересчитывается из базовой, а так как скидка заданная мной в ['DISCOUNT_LIST'] не описана в базе, после перерасчета остается только одна <старая цена>.
Для решения проблемы пока не придумал ничего лучше тупой проверки запроса на наличие действия с корзиной, для отключения расчета скидки при добавлении/изменении. Можно придумать что-то посложнее, какие-то глобальные флаги для остановки расчета скидки (мне же нужен только вывод в каталоге) по событиям типа OnSaleBasketItemSaved или OnSaleBasketBeforeSaved. Но это все как-то не православно. Как правильно сделать, кто-то может подсказать?
Для этого написал обработчик OnGetOptimalPriceResult, который проверяет наличие у товара <старой цены>, и, если она есть, то рассчитывает соответствующим образом значения ['RESULT_PRICE']['BASE_PRICE'] (а также ['RESULT_PRICE']['DISCOUNT'] и ['RESULT_PRICE']['PERCENT'] - используется для отображения в шаблонах купленного решения). Ну и ['DISCOUNT'] и ['DISCOUNT_LIST'] в возвращаемый массив добавляю для красоты (в плане вывода почти ни на что не влияет).
Код |
---|
function getOptimalPriceResultHandler(&$arFields) { // Если у товара не задано других скидок, то вычисляем по старой цене if($arFields['PRODUCT_ID'] && empty($arFields['DISCOUNT'])) { $dbOldPrice = CPrice::GetList( array(), array( "PRODUCT_ID" => $arFields['PRODUCT_ID'], "CATALOG_GROUP_ID" => OLD_PRICE_CATALOG_GROUP_ID, "CAN_ACCESS" => "Y" ) ); $arResultPrice = &$arFields['RESULT_PRICE']; // Если старая цена установлена для товара, то вычисляем скидку if(($arOldPrice = $dbOldPrice->Fetch()) && $arResultPrice['CURRENCY'] == $arOldPrice['CURRENCY'] && $arOldPrice['PRICE'] > $arFields['DISCOUNT_PRICE']) { $arResultPrice['UNROUND_BASE_PRICE'] = $arResultPrice['BASE_PRICE'] = $arOldPrice["PRICE"]; $arResultPrice['DISCOUNT'] = $discountValue = $arOldPrice["PRICE"] - $arFields['DISCOUNT_PRICE']; $arResultPrice['PERCENT'] = $discountPercent = round((100*$discountValue) / $arOldPrice["PRICE"], 0); $arFields['DISCOUNT'] = array( "ID" => 0, "SORT" => 0, "ACTIVE" => 'Y', "RENEWAL" => 'N', "VALUE_TYPE" => 'F', "SITE_ID" => SITE_ID, "VALUE" => $discountValue, "CURRENCY" => $arResultPrice['CURRENCY'], "NAME" => $arOldPrice['CATALOG_GROUP_NAME'], ); $arFields['DISCOUNT_LIST'] = array($arFields['DISCOUNT']); } } } |
Все бы хорошо, но при добавлении в корзину/создании заказа в корзину (в таблицу b_sale_basket) попадает <старая цена> то есть ['RESULT_PRICE']['BASE_PRICE'], а не ['RESULT_PRICE']['DISCOUNT_PRICE'], как, казалось бы должно быть.
Видимо при добавлении товара цена пересчитывается из базовой, а так как скидка заданная мной в ['DISCOUNT_LIST'] не описана в базе, после перерасчета остается только одна <старая цена>.
Для решения проблемы пока не придумал ничего лучше тупой проверки запроса на наличие действия с корзиной, для отключения расчета скидки при добавлении/изменении. Можно придумать что-то посложнее, какие-то глобальные флаги для остановки расчета скидки (мне же нужен только вывод в каталоге) по событиям типа OnSaleBasketItemSaved или OnSaleBasketBeforeSaved. Но это все как-то не православно. Как правильно сделать, кто-то может подсказать?