1С-Битрикс — не меняется скидка у пользователя при переходе в новую группу

Не так давно я писал про то как отменить скидку пользователя в корзине , на сей раз мне нужно было изменить скидку.

Кейс

Пользователь покупает на сайте премиальный статус, «прем» дает право на скидку скажем в 20%. Если пользователь оплачивает прем наличкой — ничего не происходит до тех пор пока мы не получим деньги и руками не поменяем статус (группу) у пользователя.
Если прем был оплачен карточкой и транзакция успешно прошла, то нужно автоматически добавить пользователя в группу премиальных юзеров.
В магазине для группы премов создана скидка в 20%.

Все вроде бы хорошо?

При помощи событий системы мы перехватываем изменение статуса оплаты заказа, смотрим тип оплаты и товар. Если товар — прем, тип оплаты — карточка, а статус оплаты — «оплачено», то с радостью добавляем пользователя в новую группу.
В админке все гуд, видно что пользователь в нужной группе, а к группе привязана скидка.

Но не тут то было!

Вопреки нашим ожиданиям у пользователя не появилась скидка! И не появится до тех пор пока он не зайдет с другого устройства или еще как-то не убьет свою сессию. Сессия, это то что мне пришло в голову, также можно было грешить на кеш, мол он не сбрасывается.
Для того чтобы прояснить ситуацию я открыл исходный код и начал следить за расчетом скидок для пользователей.

За скидки отвечает метод CCatalogDiscount::GetDiscount.
Я сделал трассировку данной функции дабы отследить ее вызовы и входные параметры.
В полученном массиве было явно видно что в функцию приходит массив групп пользователя и он не содержит прем группы, но в тоже время ее видно в админке!
Оказалось что при расчете скидок группы пользователя получаются методом CUser::GetUserGroup, который получает данные о группах пользователя из его сессии! Т.е. ему плевать что там у нас в БД, он берет данные из сессии и отдает в метод расчета скидок. Таким образом скидка не рассчитывается потому что не знает что пользователь уже находится в прем группе.

Такие вот пироги.

Конечно это легко лечится, достаточно при обновлении групп пользователя залезть и в его сессию, но чтобы понять откуда растут ноги пришлось переворошить тучу кода.

Оставить комментарий