UPD: Говорят, что в последних версиях перенесли функционал на новые классы, где нет нижеописанных событий.
Для определения уровня накопительной скидки в Битрикс используется сумма оплаченных пользователем заказов. В некоторых случаях нужно установить начальное значение суммы заказов или использовать собственную логику начисления суммы. За расчёт суммы заказов отвечает метод CCatalogDiscountSave::__SaleOrderSumm. В нём вызываются два события: OnSaleOrderSumm во время расчёта и OnSaleOrderSummResult после.
Для того, чтобы задать пользователю начальное значение суммы, например, после переноса пользователей с другого сайта/платформы, нужно создать для пользователей пользовательское поле с кодом UF_ORDERS_SUMM и заполнить нужными значениями сумм. Далее нужно в init.php добавить обработчик события OnSaleOrderSummResult, которое вызывается после подсчёта суммы заказов покупателя:
/**
* Для последних версий:
*/
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible('catalog', 'OnSaleOrderSummResult', 'addInitialValueToOrderSumm');
/**
* Для старых версий нужно использовать:
* AddEventHandler('catalog', 'OnSaleOrderSummResult', 'addInitialValueToOrderSumm');
*/
function addInitialValueToOrderSumm(&$arOrderSumm)
{
global $USER, $USER_FIELD_MANAGER;
if (!$USER->isAuthorized())
return true;
$userFields = $USER_FIELD_MANAGER->GetUserFields(
'USER',
$USER->GetID()
);
$initialValue = intval($userFields['UF_ORDERS_SUMM']['VALUE']);
if ($initialValue > 0) {
$arOrderSumm['SUMM'] += $initialValue;
$arOrderSumm['RANGE_SUMM'] += $initialValue;
}
}
Если не прибавлять значение к сумме, а присвоить значение, можно переопределить сумму. Это не совсем оптимально с точки зрения производительности. Поэтому для того, чтобы отменить стандартный расчёт и самому посчитать сумму заказа для накопительной скидки нужно добавить обработчик события OnSaleOrderSumm:
/**
* Для последних версий:
*/
$eventManager = \Bitrix\Main\EventManager::getInstance();
$eventManager->addEventHandlerCompatible('catalog', 'OnSaleOrderSumm', 'calculateOrderSumm', false, 99);
/**
* Для старых версий нужно использовать:
* AddEventHandler('catalog', 'OnSaleOrderSumm', 'calculateOrderSumm', 99);
*/
function calculateOrderSumm($arOrderFilter)
{
// ...
return array(
'PRICE' => $price,
'CURRENCY' => $currency,
'LAST_ORDER_DATE' => $date,
'TIMESTAMP' => $timestamp,
);
}
При добавлении обработчика указана сортировка 99, т.к. так можно отменить выполнение стандартного поведения - вызова метода CSaleOrder::__SaleOrderCount, в коде которого можно посмотреть как рассчитывается сумма по умолчанию и поменять на нужный алгоритм.