13.03.2022
В обычной ситуации Битрикс сам прекрасно справляется с обновлением цен в корзине при изменении их в Торговом каталоге.
Но бывают случаи, как у моего клиента, когда например закостылен метод GetOptimalPrice с установкой CUSTOM_PRICE предыдущими разработчиками, тогда все начинает работать не так как ожидается по умолчанию, а обновление цен просят сделать срочно.
Поэтому иногда проще написать небольшой скрипт и поставить его на агент/крон чтобы он обновлял цены в корзине в заданный промежуток времени.
Пример кода для обновления:
CModule::IncludeModule("sale");
// перебираем все текущие позиции корзины, которые не привязаны к заказу
$dbBasketItems = CSaleBasket::GetList(
array(),
array(
"LID" => SITE_ID,
"ORDER_ID" => "NULL"
),
false,
false,
array("ID", "CALLBACK_FUNC", "MODULE", "PRODUCT_ID", "QUANTITY", "DELAY", "CAN_BUY", "PRICE", "BASE_PRICE", "DISCOUNT_PRICE")
);
while ($arItems = $dbBasketItems->Fetch())
{
// Получим актуальные цены
$arPrice = \CCatalogProduct::getOptimalPrice(
$arItems["PRODUCT_ID"],
$arItems["QUANTITY"],
[2], // если есть необходимость, тут получаем и указываем группы пользователей, для меня это было не принципиально
"N",
array(),
SITE_ID
);
// проставим для сравнения и обновления
$arFields = [
"PRICE" => $arPrice["RESULT_PRICE"]["DISCOUNT_PRICE"],
"BASE_PRICE" => $arPrice["RESULT_PRICE"]["BASE_PRICE"],
"DISCOUNT_PRICE" => $arPrice["RESULT_PRICE"]["DISCOUNT"],
];
// сравним
if(
$arItems["BASE_PRICE"] != $arFields["BASE_PRICE"] ||
$arItems["PRICE"] != $arFields["PRICE"] ||
$arItems["DISCOUNT_PRICE"] != $arFields["DISCOUNT_PRICE"]
) {
// если надо обновим
\CSaleBasket::Update($arItems["ID"], $arFields);
//echo ''.print_r($arFields,true).'
';
}
}
Далее дело за малым поставить его на обновление в нужный промежуток времени.