1С-Битрикс. Своя логика подсчета суммы оплаченных заказов при расчете накопительной скидки
«Из коробки» в 1С-Битрикс при расчете накопительной скидки сумма оплаченных заказов юзера считается из всех заказов, сделанных им, с флагом «Оплачен». И это логично. А что если нужно выбирать заказы по своей логике, например, заказы с определенным статусом? На этот счет есть не документированное событие.
В методе \CAllCatalogDiscountSave::__SaleOrderSumm есть вызов не документированного события OnSaleOrderSumm. По умолчанию на него подписан CSaleOrder::__SaleOrderCount с сортировкой 100. Схитрим и подпишемся на это событие, с сортировкой меньше 100. Тогда наш обработчик вызовется раньше.
Код обработчика:
\Bitrix\Main\EventManager::getInstance()->addEventHandlerCompatible('catalog', 'OnSaleOrderSumm', function ($arFilter, $strCurrency = '') { global $USER; $mxResult = false; // Id статуса заказа, по которому считать заказа выполненным. $saleStatusId = 'G'; // ID пользователей, кому вообще не надо давать накопительную скидку $withoutDiscountUserIds = array(3); if (is_array($arFilter) && !empty($arFilter)) { if (isset($arFilter['PAYED'])) { unset($arFilter['PAYED']); } if (!isset($arFilter['STATUS_ID'])) { $arFilter['STATUS_ID'] = $saleStatusId; } $dblPrice = 0; $strCurrency = strval($strCurrency); $mxLastOrderDate = ''; $intMaxTimestamp = 0; $intTimeStamp = 0; $rsSaleOrders = CSaleOrder::GetList(array(), $arFilter, false, false, array('ID', 'PRICE', 'CURRENCY', 'DATE_INSERT')); while ($arSaleOrder = $rsSaleOrders->Fetch()) { $intTimeStamp = MakeTimeStamp($arSaleOrder['DATE_INSERT']); if ($intMaxTimestamp < $intTimeStamp) { $intMaxTimestamp = $intTimeStamp; $mxLastOrderDate = $arSaleOrder['DATE_INSERT']; } if (empty($strCurrency)) { $dblPrice += $arSaleOrder['PRICE']; $strCurrency = $arSaleOrder['CURRENCY']; } else { if ($strCurrency != $arSaleOrder['CURRENCY']) { $dblPrice += $arSaleOrder['PRICE']; } else { $dblPrice += $arSaleOrder['PRICE']; } } } if (in_array($arFilter['USER_ID'], $withoutDiscountUserIds)) { $dblPrice = 0; } $mxResult = array( 'PRICE' => $dblPrice, 'CURRENCY' => $strCurrency, 'LAST_ORDER_DATE' => $mxLastOrderDate, 'TIMESTAMP' => $intMaxTimestamp, ); } return $mxResult; }, false, 10);
В обработчике так же предусмотрен механизм исключения определённых пользователей и подсчета. То есть у них сумма оплаченных заказов всегда будет равна 0. Это полезно, когда заказ менеджер создаёт руками и нужно чтобы скидка не накапливалась и не применялась.
На этом всё. Читайте исходники — там много полезного.