Пересчет цены сейчас происходит в
двух трех случаях (из тех, что понятны посетителю):
- Добавление товара в корзину.
- Открытие страницы корзины (bitrix:sale.basket.basket)
- Открытие страницы заказа (bitrix:sale.order.ajax)
Если при добавлении в корзину вмешательство в расчет оптимальной цены возможно при знании только самого добавляемого товара, то при обновлении корзины это может быть недостаточно.
Примеры:
- Требуется учесть ценовое предложение (а соответственно и группу каталога), которые были выбраны той же (через событие OnGetOptimalPrice) процедурой выбора оптимальной цены еще при добавлении в корзину.
- Процедура пересчета цены позиции корзины может нуждаться в дополнительных данных, которые могут быть записаны в свойство позиции корзины (учитываем, что один и тот же товар в разных комбинациях свойств в корзине может появиться не один раз!).
В обоих случаях требуется ИД самой позиции и знание ИД товара здесь точно недостаточно, требуется контекст (конкретная позиция корзины).
Что сейчас есть- CSaleBasket::UpdateBasketPrices. Метод используется в коде компоненты для обновления цены.
- Аналогичный метод CSaleBasket::ReReadPrice делает тоже самое для одного товара, и тоже без сведений о позиции корзины (он используется пока только при добавлении в корзину, так что может и не страшно).
- Так или иначе, все сводится к вызову провайдера каталога CCatalogProductProvider::GetProductData. Этот метод провайдера в состоянии получить BASKET_ID, но его туда не передают (это недоразумение обещано исправить).
- Уже сам провайдер вызывает метод CCatalogProduct::GetOptimalPrice и здесь информация о позиции корзины теряется (и разработчик отказался это исправлять).
- Само собой обработчику события OnGetOptimalPrice не может быть передана информация о позиции корзины
- Нормально пересчитать цену товара, уже добавленному в корзину, нельзя.
Какие есть костылиНу конечно, можно что-то придумать. Решение здесь очевидно - нужно кастомизировать компоненту корзины
и заказа, чтобы гарантировать точный порядок перебора позиций. Далее глобальная переменная и знание обработчика о наличии такого контекста его исполнения.
Но зачем так делать, если можно сделать нормальный API?Идея рождена по предложению сотрудника поддержки (обращение 500340).
В моей ситуации есть два дополнительных типа цены для комплектов. Да именно для комплектов!
Вот только новую номенклатуру ради комплектов никто не хочет заводить и на сайте конструировать комплекты - тоже. И я людей понимаю. Если включать в комплекты сотовых телефонов разные варианты чехлов (их десятки и сотни, то можно сойти с ума, проще обсудить вариант комплекта с покупателем).
Как раз для этой ситуации очень пригодился обработчик события OnGetOptimalPrice. Но нормально с ним работать можно только при добавлении (в обработчике информация появляется через $_REQUEST, данные заботливо подготовлены в шаблоне страницы).
Предположим, могут помочь правила ... Смотрим правила и что видим? Я не могу там применить к товарам новый тип цен. Только скидку и наценку. А это вообще никак не подходит к задаче (не выразить цену комплекта для всех товаров даже одной группы через фиксированный процент наценки или фиксированную прибавку).
Да и само правило (если бы и было действие по смене группы каталога (типа цены)) как бы я выразил? Мне в правиле нужно сослаться, либо на тип исходной цены (что я уже сделал обработчиком), либо на наличие некоторых свойств позиции корзины. А таких условий там нет.
И это еще не все. Правила работы с корзиной нацелены на оформление заказа. А я решаю простую проблему - обновление цены товара при открытии корзины (никто на оформление заказа еще не переходит)
Идея с правилами работы с корзиной здесь не проходит совсем!