При классическом использовании функционала работы с купонами в Битриксе, размер скидки и обновление цен в корзине происходит в момент сохранения заказа. До этого момента объект Basket содержит «исходную» цену товара, а DiscountCouponsManager знает о примененных купонах.
Разбираемся, как показывать цену товаров в корзине до момента оформления заказа с учетом примененных скидок.
Алгоритм прост и состоит из нескольких шагов:
- создаем виртуальный клон корзины без сохранения в базу данных
- применяем скидки к корзине
- вычисляем реальную стоимость товаров
Реализуется это так:
$registry = Bitrix\Sale\Registry::getInstance(Bitrix\Sale\Registry::REGISTRY_TYPE_ORDER);
$basketClass = $registry->getBasketClassName();
/** Получаем текущую корзину пользователя */
$basket = $basketClass::loadItemsForFUser(
Bitrix\Sale\Fuser::getId(),
Bitrix\Main\Context::getCurrent()->getSite()
);
/** @var Sale\Basket $basketClone */
$basketClone = $basket->createClone();
$orderableBasket = $basketClone->getOrderableItems();
unset($basketClone);
$coupons = DiscountCouponsManager::get(false, [], false, true);
if (!empty($coupons) && !$orderableBasket->isEmpty()) {
/** Магия расчета цен */
$discounts = Sale\Discount::buildFromBasket(
$orderableBasket,
new Sale\Discount\Context\Fuser(Fuser::getId())
);
$discountResult = $discounts->calculate();
if ($discountResult->isSuccess()) {
/** Получение массива цен и обновление свойств виртуальной корзины */
$showPrices = $discounts->getShowPrices();
if (!empty($showPrices['BASKET'])) {
foreach ($showPrices['BASKET'] as $basketCode => $data) {
$basketItem = $orderableBasket->getItemByBasketCode($basketCode);
if ($basketItem instanceof Sale\BasketItemBase) {
$basketItem->setFieldNoDemand('BASE_PRICE', $data['SHOW_BASE_PRICE']);
$basketItem->setFieldNoDemand('PRICE', $data['SHOW_PRICE']);
}
}
unset($basketItem, $basketCode);
}
unset($showPrices);
}
unset($discountResult);
}
/** Формирование ответа для фронта или другие действия */
Мы используем виртуальную корзину, поэтому можно наполнять ее произвольными товарами и вычислять, сколько будет стоить та или иная позиция с учетом введенной пользователем скидки.
Больше статей и материалов по web-разработке в tg-канале - подписывайтесь!
Подписаться в telegram