[ELMA3] Выявление неактивных контрагентов
Руководителям отделов продаж часто бывает необходимо выявить неактивных долгое время контрагентов. Рассмотрим случай, когда необходимо создать следующее правило: активностью по контрагенту считать изменение полей в карточке контрагента: Описание, Телефон, E-mail. А также активностью считается добавление комментария, сделки, звонка, письма, встречи.
Предлагается 2 шага для решения этой задачи:
- Создадим перехватчики (listener) изменений контрагента и связанных объектов, перечисленных выше. Будем использовать для этого специально созданное поле Дата и время последней активности (LastDateTime).
- Создадим фильтр для отображения неактивных контрагентов.
Перехватчики срабатывают при действиях с базой данных. Нас будет интересовать изменение значений в списках (Телефонов, E-mail, Комментариев) и сущностях (Контрагент, Сделка). Результат перехвата – обновлённое поле LastDateTime и текущей датой и временем.
Пример сценария с использованием PublicAPI
Для корректной работы сценария необходимо подключить следующие пространства имен:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EleWise.ELMA.API;
using EleWise.ELMA.Common.Models;
using EleWise.ELMA.ComponentModel;
using EleWise.ELMA.CRM.Models;
using EleWise.ELMA.Logging;
using EleWise.ELMA.Runtime.NH.Listeners;
using EleWise.ELMA.Runtime.Settings;
using NHibernate.Event;
Текст сценария:
[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)
{
var listKA = PublicAPI.CRM.Contractor.Find(string.Format("Comments in (Id = {0})", (entry as IComment).Id));// Поиск по фильтру контрагента, по которому сделан комментарий
if (listKA.Count > 0)
{
saveLastDateTime(listKA.First().Id);
break;
}
}
// Обработка списка измененных Телефонов
if (entry is IPhone)
{
var listKA = PublicAPI.CRM.Contractor.Find(string.Format("Phone in (Id = {0})", (entry as IPhone).Id));// Поиск по фильтру контрагента, по которому сделан звонок
{
saveLastDateTime(listKA.First().Id);
break;
}
}
// Обработка списка измененных Email
if (entry is IEmail)
{
Logger.Log.Error("--->" + (entry as IEmail).GetType().ToString());
var listKA = PublicAPI.CRM.Contractor.Find(string.Format("Email in (Id = {0})", (entry as IEmail).Id));// Поиск по фильтру контрагента, по которому создано email взаимоотношение
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());
var listKA = PublicAPI.CRM.Contractor.Find(string.Format("Relationships in (Id = {0})", (@event.Entity as IRelationshipCall).Id));
if (listKA.Count > 0)
{
saveLastDateTime(listKA.First().Id);
}
}
if (@event.Entity is IRelationshipMail)
{
Logger.Log.Error("--->" + (@event.Entity as IRelationshipMail).GetType().ToString());
var listKA = PublicAPI.CRM.Contractor.Find(string.Format("Relationships in (Id = {0})", (@event.Entity as IRelationshipMail).Id));
if (listKA.Count > 0)
{
saveLastDateTime(listKA.First().Id);
}
}
if (@event.Entity is IRelationshipMeeting)
{
Logger.Log.Error("--->" + (@event.Entity as IRelationshipMeeting).GetType().ToString());
var listKA = PublicAPI.CRM.Contractor.Find(string.Format("Relationships in (Id = {0})", (@event.Entity as IRelationshipMeeting).Id));
if (listKA.Count > 0)
{
saveLastDateTime(listKA.First().Id);
}
}
return false; // возврат в норме
}
// Обновление даты и времени последней активности по контрагенту
private void saveLastDateTime(long id)
{
var kExt = PublicAPI.CRM.Contact.Load(id) as IContractorConfigExt;
kExt.LastDateTime = DateTime.Now;
}
}
Пример сценария без использования PublicAPI
Создадим объект Перехватчики и на вкладке Сценарии добавим следующие пространства имен:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using EleWise.ELMA.Common.Models; using EleWise.ELMA.ComponentModel; using EleWise.ELMA.CRM.Models; using EleWise.ELMA.Logging; using EleWise.ELMA.Model.Common; using EleWise.ELMA.Model.Managers; using EleWise.ELMA.Runtime.NH.Listeners;
using EleWise.ELMA.Runtime.Setting; 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.LastDateTime = DateTime.Now; } } } }
- Опубликуем объект и перезапустим сервер. Добавим, например, комментарий по контрагенту, чтобы заполнилось поле LastDateTime.
- Создадим фильтр в контрагентах для поиска контрагентов, по которым не было активности за последние две недели.
Откройте расширенный поиск, выберите EQL и напишите следующий код:
(NOT LastActiveTime in RelativeDateTime(’-2н’, ’0н’)) OR (LastActiveTime is NULL)
После поиска у нас должны появится все контрагенты, за исключением тех, у кого происходило изменение полей в карточке контрагента: Описание, Телефон, E-mail. Или добавление комментария, сделки, звонка, письма, встречи.
Можно создать фильтр, чтобы отслеживать активность по контрагентам за сегодня:
LastActiveTime >= DateTime(’Today’)