Выявление неактивных контрагентов

Руководителям отделов продаж часто бывает необходимо выявить неактивных долгое время контрагентов. Рассмотрим случай, когда необходимо создать следующее правило: активностью по контрагенту считать изменение полей в карточке контрагента: Описание, Телефон, E-mail. А также активностью считается добавление комментария, сделки, звонка, письма, встречи.

Предлагается 2 шага для решения этой задачи.

  1. Создадим перехватчики (listener) изменений контрагента и связанных объектов, перечисленных выше. Будем использовать для этого специально созданное поле Дата и время последней активности (LastDateTime).
  2. Создадим фильтр для отображения неактивных контрагентов.

Перехватчики срабатывают при действиях с базой данных. Нас будет интересовать изменение значений в списках (Телефонов, E-mail, Комментариев) и сущностях (Контрагент, Сделка). Результат перехвата – обновлённое поле LastDateTime и текущей датой и временем.

Создадим объект Перехватчики и на закладке Сценарии добавим следующие пространства имен и код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using EleWise.ELMA.Common.Models;
using EleWise.ELMA.ComponentModel;
using EleWise.ELMA.ConfigurationModel;
using EleWise.ELMA.CRM.Models;
using EleWise.ELMA.Documents.Models;
using EleWise.ELMA.Logging;
using EleWise.ELMA.Model.Common;
using EleWise.ELMA.Model.Entities;
using EleWise.ELMA.Model.Managers;
using EleWise.ELMA.Model.Types.Settings;
using EleWise.ELMA.Runtime.Managers;
using EleWise.ELMA.Runtime.NH.Listeners;
using NHibernate.Event;

Текст сценария:

namespace EleWise.ELMA.ConfigurationModel.Scripts
{
  
  /// <summary>
  /// Модуль сценариев объекта "Перехватчики"
  /// </summary>
  public class PerehvatchikiScripts : EleWise.ELMA.Model.Scripts.Entities.EntityScriptModule<IPerehvatchiki>
  {
    
    [Component] 
     public class ReSaveContractor : EntityEventsListener 
     {  
       // Переопределённый метод для перехвата изменений в телефонах и email контрагентов
       public override void OnPreUpdateCollection(PreCollectionUpdateEvent @event)
       {
         var collection = @event.Collection;
         var collectionEntry = @event.Session.PersistenceContext.GetCollectionEntry(@event.Collection);
         var collectionEntries = collection.Entries(collectionEntry.LoadedPersister);
         
         foreach (var entry in collectionEntries) 
         {
   // Обработка списка измененных комментариев
           if (entry is IComment)
           {
             
             Filter filter = new Filter();  
             filter.Query = string.Format("Comments in (Id = {0})",(entry as IComment).Id); // Запрос фильтра для поиска контрагента, по которому сделан комментарий
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null); // Поиск по фильтру
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               break;
             }
         
           }
   // Обработка списка измененных Телефонов
           if (entry is IPhone)
           {
             
             Filter filter = new Filter();
             filter.Query = string.Format("Phone in (Id = {0})",(entry as IPhone).Id); // Запрос фильтра для поиска контрагента, по которому сделан звонок
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null); // Поиск по фильтру
             {
               saveLastDateTime(listKA.First().Id);
               break;
             }
         
           }
   // Обработка списка измененных Email
           if (entry is IEmail)
           {
             Logger.Log.Error("--->"+(entry as IEmail).GetType().ToString());
             Filter filter = new Filter();
             filter.Query = string.Format("Email in (Id = {0})",(entry as IEmail).Id); // Запрос фильтра для поиска контрагента, по которому создано email взаимоотношение

             var listKA = EntityManager<IContractor>.Instance.Find(filter, null); // Поиск по фильтру
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               break;
             }
         
           }           
         
         }
         
       }
       
       // событие изменение объекта/документа
       public override bool OnPreUpdate(PreUpdateEvent @event) 
       {  
          
         

         if(@event.Entity is IContractor)  //  интерфейс объекта типа Контрагент
         {
    var Kontragent  = (IContractor)@event.Entity;  // приведение к типу                     
           saveLastDateTime(Kontragent.Id);
          } 
  if(@event.Entity is ISale)  //  интерфейс объекта типа Сделка
         {
           var SaleNew = (ISale)@event.Entity;
           if (SaleNew.Contractor != null ) // 
           {
             saveLastDateTime(SaleNew.Contractor.Id);
           }
         }
         if (@event.Entity is IRelationshipCall)
           {
             Logger.Log.Error("--->"+(@event.Entity as IRelationshipCall).GetType().ToString());
             Filter filter = new Filter();
             filter.Query = string.Format("Relationships in (Id = {0})",(@event.Entity as IRelationshipCall).Id);
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null);
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               
             }
         
           }    
           if (@event.Entity is IRelationshipMail)
           {
             Logger.Log.Error("--->"+(@event.Entity as IRelationshipMail).GetType().ToString());
             Filter filter = new Filter();
             filter.Query = string.Format("Relationships in (Id = {0})",(@event.Entity as IRelationshipMail).Id);
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null);
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               
             }
         
           }
           if (@event.Entity is IRelationshipMeeting)
           {
             Logger.Log.Error("--->"+(@event.Entity as IRelationshipMeeting).GetType().ToString());
             Filter filter = new Filter();
             filter.Query = string.Format("Relationships in (Id = {0})",(@event.Entity as IRelationshipMeeting).Id);
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null);
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               
             }
         
           }    
 return false; // возврат в норме
         
       }
       // Обновление даты и времени последней активности по контрагенту
       private void saveLastDateTime(long id)
       {
           var kExt = EntityManager<IContractorConfigExt>.Instance.Load(id); // загрузить расширенную модель для контрагента
          kExt.LastActiveTime = DateTime.Now;
       }       
    }   
  }
}
  1. Опубликуем объект и перезапустим сервер. Добавим, например, комментарий по контрагенту, чтобы заполнилось поле LastDateTime.
  2. Создадим фильтр в контрагентах для поиска контрагентов, по которым не было активности за последние две недели.

Откройте расширенный поиск, выберите EQL и напишите следующий код:

(NOT LastActiveTime in RelativeDateTime(’-2н’, ’0н’)) OR (LastActiveTime is NULL)

После поиска у нас должны появится все контрагенты, за исключением тех, у кого происходило изменение полей в карточке контрагента: Описание, Телефон, E-mail. Или добавление комментария, сделки, звонка, письма, встречи.

Можно создать фильтр, чтобы отслеживать активность по контрагентам за сегодня:

LastActiveTime >= DateTime(’Today’)