У заказчика было несколько обработчиков на добавление и редактирование сделки Для оптимизации объединила в 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); } } }); |