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).''; } }
Далее дело за малым поставить его на обновление в нужный промежуток времени.
Хостинг - FastVPS