| У заказчика было несколько обработчиков на добавление и редактирование сделки Для оптимизации объединила в 1. Реализация купона (купон - это свойство в сделке типа список (3 вида купона), который действует на некоторые виды товаров 20% от стоимости товара, но максимум 3000р Считает сумму среднюю по чеку на 1 гостя, считает сколько на товары типа напитки, бар. декор и тд приходится |
OnBeforeCrmDealAdd, OnBeforeCrmDealUpdate - в них товары не меняются при изменении массива $arFields["PRODUCT_ROWS"]
OnBeforeCrmDealProductRowsSave - тут тоже не модифицируется товары (есть тикет в битриксе на доработку)
OnAfterCrmDealProductRowsSave - поэтому приходится после сохранения их еще раз сохранять. можно было бы сюда всю логику положить с модификацией товара, но так как мне еще надо свойства в сделке менять, то пришлось бы 2 раза делать выборки и прочее.
function CalcMultipleForDeal(&$arFields){
//AddMessage2Log("CalcMultipleForDeal");
if(isset($arFields["PRODUCT_ROWS"])){
// global $USER;
// if($USER->GetID()==54043){
// AddMessage2Log($arFields["PRODUCT_ROWS"]);
// }
$entertSum = 0;// Развлечения 530
$menuSum = 0;// Банкет 531
$dopSum = 0;// Допы 533
$barSum = 0;// Бар 532
$sumAll = 0;
$sumAverage = 0;
$arSectionIds = [];
$arProductIds = [];
foreach($arFields["PRODUCT_ROWS"] as $arProduct){
$arProductIds[] = $arProduct["PRODUCT_ID"];
}
if(!empty($arProductIds) && CModule::IncludeModule("iblock")){
//свойство в сделке купоны: UF_CRM_1708101511: 13928 13929 13930
$bCoupon = false;
if(isset($arFields["UF_CRM_1708101511"])){
//AddMessage2Log($arFields["UF_CRM_1708101511"]);
if(in_array($arFields["UF_CRM_1708101511"],[13928, 13929, 13930])){
$bCoupon = true;
}
}
elseif(!empty($arFields["ID"]) && CModule::IncludeModule("crm")){ //если изменение сделки
//получаем значение свойства купон
$arFilter = array(
"ID"=>$arFields["ID"], //выбираем определенную сделку по ID
"CHECK_PERMISSIONS"=>"N" //не проверять права доступа текущего пользователя
);
$arSelect = array(
"ID",
"UF_CRM_1708101511", //
"UF_CRM_1530623573843",
"UF_CRM_1530623600935"
);
$res = CCrmDeal::GetList(Array(), $arFilter, $arSelect);
if($deal = $res->Fetch()){
//AddMessage2Log($deal);
if(in_array($deal["UF_CRM_1708101511"],[13928, 13929, 13930])){
$bCoupon = true;
}
}
}
if($bCoupon){
//AddMessage2Log("купон найден");
//скидка 20% от стоимости, максимум 3000р
$maxDiscount = 3000;
//свойство, из которого брать PROPERTY_626
// -Анимация 304 -Аренда 314 -Батут 298 -Декор 308 -Доп. услуги (подарок) 312 -Доп. услуги (шоу) 306 -Зал\Стол 316 -Носки 300 -Официант 328 -Пробка 326 -Тренер 302
$arTypesForCoupon = [304,314,298,308,312,306,316,300,328,326,302];
}
$arFilter = Array(
"IBLOCK_ID"=>28,
"ID" => $arProductIds
);
$arSelect = Array("ID","IBLOCK_ID","PROPERTY_4098","PROPERTY_626","IBLOCK_SECTION_ID");
$res = CIBlockElement::GetList(Array("sort"=>"asc"), $arFilter, false, Array("nPageSize"=>150,"iNumPage"=>1), $arSelect);
$arEntertIds = [];
$arMenuIds = [];
$arDopIds = [];
$arBarIds = [];
$arAverageIds = [];
$arBatutIds = [];
$arCouponItems = [];
while($arItem = $res->Fetch()){
if($bCoupon && !empty($arItem["PROPERTY_626_ENUM_ID"]) && in_array($arItem["PROPERTY_626_ENUM_ID"],$arTypesForCoupon)){
$arCouponItems[$arItem["ID"]] = $arItem["ID"]; // товары, которые попадают по купоны
}
if($arItem["PROPERTY_4098_ENUM_ID"]==530){
$arEntertIds[$arItem["ID"]] = $arItem["ID"];// Развлечения
}
elseif($arItem["PROPERTY_4098_ENUM_ID"]==531){// Банкет
$arMenuIds[$arItem["ID"]] = $arItem["ID"];
}
elseif($arItem["PROPERTY_4098_ENUM_ID"]==532){// Бар
$arBarIds[$arItem["ID"]] = $arItem["ID"];
}
elseif($arItem["PROPERTY_4098_ENUM_ID"]==533){// Допы
$arDopIds[$arItem["ID"]] = $arItem["ID"];
}
elseif($arItem["PROPERTY_4098_ENUM_ID"]==298){// Допы
$arDopIds[$arItem["ID"]] = $arItem["ID"];
}
if(in_array($arItem["PROPERTY_626_ENUM_ID"], [318,320,322])){
$arAverageIds[$arItem["ID"]] = $arItem["ID"];
}
elseif($arItem["PROPERTY_626_ENUM_ID"] == 298){//Батут
$arBatutIds[$arItem["ID"]] = $arItem["ID"];
}
$arSectionIds[$arItem["IBLOCK_SECTION_ID"]] = $arItem["IBLOCK_SECTION_ID"];
}
if($bCoupon && !empty($arCouponItems)){
//сначала проверяем сумму товаров и смотрим 20% или 3000р
$sumCoupon = 0;
$sumBatut = 0;
foreach($arFields["PRODUCT_ROWS"] as $arProduct){
if(in_array($arProduct["PRODUCT_ID"],$arCouponItems)){
$sumCoupon = $sumCoupon + $arProduct["QUANTITY"]*$arProduct["PRICE_BRUTTO"];
}
if(in_array($arProduct["PRODUCT_ID"],$arBatutIds)){
$sumBatut = $sumBatut + $arProduct["QUANTITY"]*$arProduct["PRICE_BRUTTO"];
}
}
if($sumCoupon>0){
//AddMessage2Log(["sumGoods",$sumCoupon]);
if(($sumCoupon*0.2)<$maxDiscount){ //уменьшаем на 20%
//$discount = 20;
$sumCoupon = $sumCoupon*0.2;
}
else{
$sumCoupon = 3000;
//$discount = $maxDiscount*100/$sumCoupon;
}
//AddMessage2Log(["sumCoupon",$sumCoupon]);
//AddMessage2Log(["sumBatut",$sumBatut]);
if($sumCoupon>($sumBatut-0)){
$sumCoupon = $sumBatut - 0;
}
//AddMessage2Log(["sumCoupon2",$sumCoupon]);
$discount = $sumCoupon*100/$sumBatut;
//AddMessage2Log(["discount",$discount]);
//AddMessage2Log($discount);
}
$arProducts = [];
//$arProducts2 = [];
global $newProducts;
$newProducts = [];
foreach($arFields["PRODUCT_ROWS"] as $key => $arProduct){
if(in_array($arProduct["PRODUCT_ID"],$arBatutIds)){
$arProduct["DISCOUNT_TYPE_ID"] = 1;
//$arProduct["DISCOUNT_RATE"] = $discount;
//AddMessage2Log([$arProduct["PRICE_BRUTTO"]*$discount/100,round($arProduct["PRICE_BRUTTO"]*$discount/100,1,PHP_ROUND_HALF_DOWN),round($arProduct["PRICE_BRUTTO"]*$discount/100,2,PHP_ROUND_HALF_DOWN)]);
$arProduct["DISCOUNT_SUM"] = round($arProduct["PRICE_BRUTTO"]*$discount/100);
$arProduct["PRICE"] = $arProduct["PRICE_BRUTTO"] - $arProduct["DISCOUNT_SUM"];
$arProduct["PRICE_EXCLUSIVE"] = $arProduct["PRICE"];
$arProduct["DISCOUNT_ROW"] = $arProduct["DISCOUNT_SUM"]*$arProduct["QUANTITY"];
$newProducts[$key] = [
"ID"=> $arProduct["ID"],
"PRODUCT_ID" => $arProduct["PRODUCT_ID"],
"QUANTITY" => $arProduct["QUANTITY"],
"PRICE" => $arProduct["PRICE"],
"DISCOUNT_TYPE_ID" => 1,
"DISCOUNT_SUM" => $arProduct["DISCOUNT_SUM"]
];
}
else{
$newProducts[$key] = $arProduct;
}
$arProducts[$key] = $arProduct;
}
$arFields["PRODUCT_ROWS"] = $newProducts;
//$newProducts = $arProducts2;
}
if(!empty($arAverageIds)){
foreach ($arFields["PRODUCT_ROWS"] as $arProduct) {
if(isset($arAverageIds[$arProduct["PRODUCT_ID"]])){
$sumAverage = $sumAverage + $arProduct["PRICE"]*$arProduct["QUANTITY"];
}
}
if($sumAverage){
$questCount = 1;
if((!$bCoupon ||!isset($arFields['UF_CRM_1530623573843']) || !isset($arFields['UF_CRM_1530623600935'])) && CModule::IncludeModule("crm")){ //поля с количеством гостей
$arFilter = array(
"ID"=>$arFields["ID"], //выбираем определенную сделку по ID
"CHECK_PERMISSIONS"=>"N" //не проверять права доступа текущего пользователя
);
$arSelect = array(
"ID",
"UF_CRM_1530623573843",
"UF_CRM_1530623600935"
);
$res = CCrmDeal::GetList(Array(), $arFilter, $arSelect);
if($deal = $res->Fetch()){
$questCount = $deal["UF_CRM_1530623573843"] + $deal["UF_CRM_1530623600935"];
}
}
else{
if($bCoupon){
$questCount = $deal["UF_CRM_1530623573843"] + $deal["UF_CRM_1530623600935"];
}
$questCount = $arFields["UF_CRM_1530623573843"] + $arFields["UF_CRM_1530623600935"];
}
if($questCount < 1){
$questCount = 1;
}
$sumAverage = ceil($sumAverage/$questCount);
}
}
foreach($arFields["PRODUCT_ROWS"] as $arProduct){
if(isset($arEntertIds[$arProduct["PRODUCT_ID"]])){
$entertSum = $entertSum + $arProduct["QUANTITY"]*$arProduct["PRICE"];
}
if(isset($arMenuIds[$arProduct["PRODUCT_ID"]])){
$menuSum = $menuSum + $arProduct["QUANTITY"]*$arProduct["PRICE"];
}
if(isset($arDopIdsp[$arProduct["PRODUCT_ID"]])){
$dopSum = $dopSum + $arProduct["QUANTITY"]*$arProduct["PRICE"];
}
if(isset($arBarIds[$arProduct["PRODUCT_ID"]])){
$barSum = $barSum + $arProduct["QUANTITY"]*$arProduct["PRICE"];
}
$sumAll = $sumAll + $arProduct["PRICE"]*$arProduct["QUANTITY"];
}
}
$arFields["UF_CRM_ENTERTAINMENT_AMOUNT"] = $entertSum;
$arFields["UF_CRM_SUM_BANQUET"] = $menuSum;
$arFields["UF_CRM_SUM_ADDITIONAL"] = $dopSum;
$arFields["UF_CRM_SUM_BAR"] = $barSum;
$arFields["UF_CRM_1619693698"] = implode(", ", $arSectionIds);
$arFields["UF_CRM_AVERAGE_CHECK"] = $sumAverage;
if($bCoupon){
$arFields["OPPORTUNITY"] = $sumAll;
}
//AddMessage2Log([$entertSum,$menuSum,$dopSum,$barSum,$sumAverage,$arFields["UF_CRM_1619693698"]]);
}
}
AddEventHandler('crm', 'OnBeforeCrmDealAdd', 'MyOnBeforeCrmDealAdd', 10000);
function MyOnBeforeCrmDealAdd(&$arFields){
CalcMultipleForDeal($arFields);
}
AddEventHandler('crm', 'OnBeforeCrmDealUpdate', 'MyOnBeforeCrmDealUpdate', 10000);
function MyOnBeforeCrmDealUpdate(&$arFields){
CalcMultipleForDeal($arFields); //
}
|
OnAfterCrmDealProductRowsSave
AddEventHandler('crm', 'OnAfterCrmDealProductRowsSave', 'MyOnAfterCrmDealProductRowsSave');
function MyOnAfterCrmDealProductRowsSave($id,$fields){
global $newProducts;
if(!empty($newProducts)){
CCrmProductRow::SaveRows('D', $id, $newProducts);
}
} |
с правкой ядра (эта ошибка есть у Битрикса в доработке), но все красиво отображается
OnBeforeCrmDealProductRowsSave
AddEventHandler('crm', 'OnBeforeCrmDealProductRowsSave', 'MyOnBeforeCrmDealProductRowsSave');
function MyOnBeforeCrmDealProductRowsSave($id,&$fields){
global $newProducts;
if(!empty($newProducts)){
$fields = $newProducts;
}
} |
/bitrix/modules/crm/classes/general/crm_deal.php
добавляем & перед $arRows в методе SaveProductRows

и чтобы красиво итоговые суммы были
/local/assets/entities-expansion/js/deal.js
BX.addCustomEvent( 'onAjaxSuccess' , function (params, event) {
if(event){
let url = event.url;
if(
(url.indexOf('/bitrix/components/bitrix/crm.entity.product.list/list.ajax.php') >= 0) &&
(url.indexOf('grid_action=showpage') >= 0)
){
setTimeout(function(){
if($('div[data-name=QUANTITY] input.main-grid-editor-money-price').length >0){
let id = $('div[data-name=QUANTITY] input.main-grid-editor-money-price').first().attr('id');
let qnt = $('div[data-name=QUANTITY] input.main-grid-editor-money-price').first().val();
$('div[data-name=QUANTITY] input.main-grid-editor-money-price').first().val(1);
BX.fireEvent(BX(id),'change');
$('div[data-name=QUANTITY] input.main-grid-editor-money-price').first().val(qnt);
BX.fireEvent(BX(id),'change');
}
},500);
}
}
}); |