Если 30 мин нет задачи по лиду или сделке, то уведомление ответственному отделу



Задача:
Отправить уведомление всем менеджерам ОП парка, если в лиде/сделке нет задачи больше 30 минут с момента снятия прошлой задачи. Если до этого задачи не было, то с момента создания лида/сделки
- По лидам это должно работать на стадиях: "Не обработан" и "В работе"
- По сделкам на стадиях от "бронь" до "предоплата" (для 4х воронок)

Парк - свойствА в лиде, сделке
В init.php
агенты
function CheckLeadsWithoutTasksAgent(){
    $h = date("H");
    if(CModule::IncludeModule('crm') && $h>9 && $h<22){  
        CheckTasksForEntity(CCrmOwnerType::Lead);
    }   
    return "CheckLeadsWithoutTasksAgent();";
}
function CheckDealsWithoutTasksAgent(){
    $h = date("H");
    if(CModule::IncludeModule('crm') && $h>9 && $h<22){  
        CheckTasksForEntity(CCrmOwnerType::Deal);
    }   
    return "CheckDealsWithoutTasksAgent();";
}
данные о парках
function GetParksInfo(){
   $cacheTime = 86400;
   $cacheId = "GetParksInfo";
   $cacheDir = "getparksinfo";
     
   $result = [];

   $cache = Bitrix\Main\Data\Cache::createInstance();
   if ($cache->initCache($cacheTime, $cacheId, $cacheDir)){
      $result = $cache->getVars();
   }
   elseif ($cache->startDataCache()){       
      $arParks = [         
         "PARK1" => [
           "DEPARTMENTS" => [1609, 1242],
           "USERS" => [],
           "PROP_DEAL" => 782,
           "PROP_LEAD" => 282
         ],
         
         "PARK2" => [
           "DEPARTMENTS" => [1611, 181],
           "USERS" => [],
           "PROP_DEAL" => 784,
           "PROP_LEAD" => 284
         ],         
         "PARK3" => [
           "DEPARTMENTS" => [1612, 183],
           "USERS" => [],
           "PROP_DEAL" => 786,
           "PROP_LEAD" => 286
         ],         
         "PARK4" => [
           "DEPARTMENTS" => [1610, 1292],
           "USERS" => [],
           "PROP_DEAL" => 788,
           "PROP_LEAD" => 288
         ],         
      ];

      $arUsersAll = [];
      $propsDealAll = [];
      $propsLeadAll = [];

      if(CModule::IncludeModule('intranet')){           
         foreach($arParks as $key => $arPark){   
              $propsDealAll[] = $arPark["PROP_DEAL"];        
              $propsLeadAll[] = $arPark["PROP_LEAD"];
              $rsUsers = CIntranetUtils::GetDepartmentEmployees($arPark["DEPARTMENTS"], true);
              while($arUser = $rsUsers->fetch()){
                  $arParks[$key]["USERS"][$arUser["ID"]] = $arUser["ID"];                                         
                  $arUsersAll[$arUser["ID"]] = $arUser["ID"];
              }
         }


         $result = [
            "PARKS" => $arParks,
            "PROPS_DEAL" => $propsDealAll,
            "PROPS_LEAD" => $propsLeadAll,
            "USERS" => $arUsersAll
         ];   
      }
      else{
         $cache->abortDataCache();
      }
      $cache->endDataCache($result);      
      
   }    
    return $result;
}
параметры по которым отбираем
function GetParamsForCheckTasks($entityType){
   $result = [];
   if($entityType == "deal"){
      $result = [
         "STAGES" => [
            "C1:NEW","C1:PREPARATION","C1:PREPAYMENT_INVOICE","C1:EXECUTING",
            "C3:NEW","C3:PREPARATION","C3:PREPAYMENT_INVOICE","C3:EXECUTING",
            "C5:NEW","C5:PREPARATION","C5:PREPAYMENT_INVOICE","C5:EXECUTING",
            "C7:NEW","C7:PREPARATION","C7:PREPAYMENT_INVOICE","C7:EXECUTING"
         ],
         "PROP_PARK" => "UF_CRM_5BCDF7FEE1029",
         //"PROP_NEED_CHECK" =>"UF_CRM_1707488381",
         "PREFIX" =>"D_" 
      ];
   }
   elseif($entityType == "lead"){
      $result = [
         "STAGES" => ["NEW","IN_PROCESS"],
         "PROP_PARK" => "UF_CRM_1540199230710",
         //"PROP_NEED_CHECK" =>"UF_CRM_1707488157",
         "PREFIX" =>"L_" 
      ];
   }
   return $result;   
}
отправляет уведомления менеджерам
function SendMessageByCrmTasks($arUsers, $entityType, $entityId){
    if(CModule::IncludeModule('im')){
        $message = '<a target="_self" href="https://bitrix.nebojump.ru/crm/';
        if($entityType == CCrmOwnerType::Lead){
            $message .= 'lead/details/'.$entityId.'/" >Лид'; 
        }
        else{ //сделка
            $message .= 'deal/details/'.$entityId.'/">Сделка';
        }
        $message .=' №'.$entityId. '</a> без задачи более 30 минут';
        
        foreach($arUsers as $userId){
            $arFields = array(
               "NOTIFY_TITLE" => "Нет задачи", //заголовок                     
               "MESSAGE" => $message,
               "MESSAGE_TYPE" => IM_MESSAGE_SYSTEM, // IM_MESSAGE_PRIVATE, IM_MESSAGE_CHAT, IM_MESSAGE_OPEN, IM_MESSAGE_SYSTEM, IM_MESSAGE_OPEN_LINE
               "TO_USER_ID" => $userId,
               "FROM_USER_ID" => 0,
               //"AUTHOR_ID" => $userIdOther, //может отличаться от FROM_USER_ID                           
               "NOTIFY_TYPE" => IM_NOTIFY_SYSTEM,  // IM_NOTIFY_CONFIRM, IM_NOTIFY_SYSTEM, IM_NOTIFY_FROM
               "NOTIFY_MODULE" => "main", // module id sender (ex: xmpp, main, etc)
               "NOTIFY_EVENT" => "manage",                           
            );      
            CIMMessenger::Add($arFields);   
        }
    } 
}
Функция, которая собирает такие лиды и сделки
function CheckTasksForEntity($entityType){
   CModule::IncludeModule('crm');   
   CModule::IncludeModule('tasks');   
   $arParksInfo = GetParksInfo();
   $deadlineDate = date("d.m.Y H:i:s",time()-30*60);

   //соответствие парков и департаментов
   if($entityType == CCrmOwnerType::Lead){
      $arParams = GetParamsForCheckTasks("lead");
      $arFilter = array(         
         "UF_CRM_1543416257" => "696", //входящий поток    
         "STATUS_ID" => $arParams["STAGES"],
         "ASSIGNED_BY_ID"=> $arParksInfo["USERS"],
         $arParams["PROP_PARK"] =>   $arParksInfo["PROPS_LEAD"],   
         "<DATE_CREATE" => $deadlineDate,
         "CHECK_PERMISSIONS"=>"N", //не проверять права доступа текущего пользователя         
      );            
      $arSelect = array(
        "ID",      
        $arParams["PROP_PARK"] //парк
      );            
      $res = CCrmLead::GetList(Array(), $arFilter, $arSelect);
   }   
   else{//сделка   
      
      $arParams = GetParamsForCheckTasks("deal");
      $arFilter = array(
         "STAGE_ID" => $arParams["STAGES"], 
         "ASSIGNED_BY_ID"=> $arParksInfo["USERS"],
         $arParams["PROP_PARK"] =>   $arParksInfo["PROPS_DEAL"], 
         "CHECK_PERMISSIONS"=>"N", //не проверять права доступа текущего пользователя
         "<DATE_CREATE" => $deadlineDate,  
      );            
      $arSelect = array(
        "ID",                    
        $arParams["PROP_PARK"] //парк
      );            
      $res = CCrmDeal::GetList(Array(), $arFilter, $arSelect);
   }
   $arIds = [];
   $arEntities = [];
   while($row = $res->Fetch()){      
      $arIds[] = $arParams["PREFIX"].$row["ID"];
      $arEntities[$row["ID"]] = $row;
   }

   if(!empty($arIds)){
      global $DB;
      $sIds = implode("','",$arIds);
      $strSql = "SELECT VALUE_ID,VALUE from b_utm_tasks_task where FIELD_ID=11 and VALUE in ('".$sIds."') ;";
      $resdb = $DB->Query($strSql); 
      $arTaskCrm = [];
      $arTaskIds = [];
      while ($rowdb = $resdb->Fetch()){
         $arTaskCrm[] = [
               "TASK_ID"=>$rowdb["VALUE_ID"],
               "CRM_ENTITY_ID" =>$rowdb["VALUE"]
         ];
         $arTaskIds[$rowdb["VALUE_ID"]] = $rowdb["VALUE_ID"];
      }
      $arTasks = [];
      if(!empty($arTaskIds)){
         $sTaskIds = implode(",",$arTaskIds);         
         $strSql = "SELECT ID,STATUS,CLOSED_DATE from b_tasks where ID in (".$sTaskIds.") AND (CLOSED_DATE is null OR CLOSED_DATE>'".$deadlineDate."');";         
         $resdb = $DB->Query($strSql);         
         while($arTask = $resdb->Fetch()){            
            foreach($arTaskCrm as $taskCrm){
               if($taskCrm["TASK_ID"] == $arTask["ID"]){
                  $arTasks[$taskCrm["CRM_ENTITY_ID"]][] = $arTask;  
               }

            }     
         }         
      }
      foreach ($arEntities as $entityId => $arEntity) {            
         if(empty($arTasks[$arParams["PREFIX"].$entityId]) && !empty($arEntity[$arParams["PROP_PARK"]])){                        
            //$arParksInfo = GetParksInfo();
           
            foreach($arParksInfo["PARKS"] as $arPark){                           
               if(
                  (($entityType == CCrmOwnerType::Lead)&& ($arEntity[$arParams["PROP_PARK"]]==$arPark["PROP_LEAD"])) ||
                  ($arEntity[$arParams["PROP_PARK"]]==$arPark["PROP_DEAL"])
               ){                                   

                  SendMessageByCrmTasks($arPark["USERS"], $entityType, $entityId);   
                  break;
               }               
            }            
         }              
      }
   } 
}





старый вариант, долго работает
Функция, которая собирает такие лиды
function CheckTasksForEntity($entityType){

   CModule::IncludeModule('crm');   
   CModule::IncludeModule('tasks');
   
   

   //соответствие парков и департаментов
   if($entityType == CCrmOwnerType::Lead){
      $propPark = "UF_CRM_1540199230710"; 
      $prefix = "L_";
      $arParks = [
         282 => [1609, 1242],//парк 1
         284 => [1611, 181],//парк 2
         286 => [1612, 183],//парк 3
         288 => [1610, 1292],//парк 4         
      ];
      $arUsers = GetParkManagers($arParks);
      //выбираем ВСЕ лиды на 2х начальных стадиях
      $arFilter = array(
         "STATUS_ID" => ["NEW","IN_PROCESS"],
         "ASSIGNED_BY_ID"=> $arUsers["ALL"],
         "UF_CRM_1543416257" => "696", //входящий поток    
         $propPark => array_keys($arParks),
          "CHECK_PERMISSIONS"=>"N", //не проверять права доступа текущего пользователя
       );            
      $arSelect = array(
        "ID",            
        "DATE_CREATE",
        $propPark //парк
      );            
      $res = CCrmLead::GetList(Array(), $arFilter, $arSelect);
   }   
   else{//сделка   
      $propPark = "UF_CRM_5BCDF7FEE1029";
      $prefix = "D_";
      $arParks = [
         782 => [1609, 1242],//парк 1
         784 => [1611, 181],//парк 2
         786 => [1612, 183],//парк 3
         788 => [1610, 1292],//парк 4         
      ];
      $arUsers = GetParkManagers($arParks);
      $arFilter = array(
         "STAGE_ID" => [
            "C1:NEW","C1:PREPARATION","C1:PREPAYMENT_INVOICE","C1:EXECUTING",
             "C3:NEW","C3:PREPARATION","C3:PREPAYMENT_INVOICE","C3:EXECUTING",
             "C5:NEW","C5:PREPARATION","C5:PREPAYMENT_INVOICE","C5:EXECUTING",
             "C7:NEW","C7:PREPARATION","C7:PREPAYMENT_INVOICE","C7:EXECUTING"
         ],
         "ASSIGNED_BY_ID"=> $arUsers["ALL"],
         //"UF_CRM_1543416257" => "696", //входящий поток    
         $propPark => array_keys($arParks),
          "CHECK_PERMISSIONS"=>"N", //не проверять права доступа текущего пользователя
       );            
      $arSelect = array(
        "ID",            
        "DATE_CREATE",
        $propPark //парк
      );            
      $res = CCrmDeal::GetList(Array(), $arFilter, $arSelect);
   }
   
   $arIds = [];
   $arEntities = [];
   while($row = $res->Fetch()){      
      $arIds[] = $prefix.$row["ID"];
      $arEntities[$row["ID"]] = $row;
   }

   if(!empty($arIds)){
      $arFilter = array(                          
            "UF_CRM_TASK" => $arIds, 
      );
      $res = CTasks::GetList(
          Array("DEADLINE" => "ASC"), 
          $arFilter,
          array("ID","STATUS","CLOSED_DATE","STATUS_CHANGED_DATE","UF_CRM_TASK"),
          array("USER_ID"=>1)   //из-под админа получаем                 
      );
      $arTasks = [];
      while($arTask = $res->GetNext()){   
         foreach($arTask["UF_CRM_TASK"] as $entityId){
            $arTasks[$entityId][] = $arTask;   
         }
         
      }
      $t = time()-30*60; //30 мин назад
      

      foreach ($arEntities as $entityId => $arEntity) {
         $bFind = false;
         if(!empty($arTasks[$prefix.$entityId])){
            foreach($arTasks[$prefix.$entityId] as $arTask){
               if($arTask["STATUS"]==CTasks::STATE_COMPLETED){//завершена
                  if(strtotime($arTask["CLOSED_DATE"]) > $t){
                     $bFind = true;
                     break;
                  }
               }   
               elseif($arTask["STATUS"]==CTasks::STATE_SUPPOSEDLY_COMPLETED){//ждет приема
                  if(strtotime($arTask["STATUS_CHANGED_DATE"]) > $t){
                     $bFind = true;
                     break;
                  }
               }
               else{
                  $bFind = true;
                  break;
               }
            }            
         }
         elseif(strtotime($arEntity["DATE_CREATE"]) > $t){//проверяем дату создания         
            $bFind = true;            
         }   

         
            
         if(!$bFind && !empty($arUsers["BY_PARK"][$arEntity[$propPark]])){            
            SendMessageByCrmTasks($arUsers["BY_PARK"][$arEntity[$propPark]], $entityType, $entityId);
            //echo $entityId.", ";   
                    }
              
      }
   }   
}


Если блог был полезным, можете угостить меня "чашечкой кофе" :)

Сбер по номеру телефона +7 (953) 585-13-09 Вероника.
Спасибо!