Finding inactive contractors

Sales managers often need to find contractors that have been inactive for a while. Assume you need to create the following rule: changing contractor fields (description, phone, email) must be considered activity with the contractor. Adding a comment, deal, call, mail or meeting is also considered activity.

This task includes two steps.

  1. Create listeners of changes in the contractor and linked objects, listed above. For this, use a special field - Date and time of last activity (LastDateTime).
  2. Create a filter for displaying inactive contractors.

Listeners are triggered when actions with the database are performed. We are interested in changes in lists (phones, email, comments) and objects (contractor, deal). The result of listening is a declared field LastDateTime with the current date and time.

Create the Listeners object, open its Scripts tab, add a script with the following namespaces:

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;

And code:

namespace EleWise.ELMA.ConfigurationModel.Scripts
{
   
  /// <summary>
  /// Script module of the Listeners object
  /// </summary>
  public class PerehvatchikiScripts : EleWise.ELMA.Model.Scripts.Entities.EntityScriptModule<IPerehvatchiki>
  {
     
    [Component]
     public class ReSaveContractor : EntityEventsListener
     { 
       // Redefined method for listening to changes in contractors' phones and emails
       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)
         {
   // Process the list of changed comments
           if (entry is IComment)
           {
              
             Filter filter = new Filter(); 
             filter.Query = string.Format("Comments in (Id = {0})",(entry as IComment).Id); // Request a filter for searching a contractor, to which a comment was added
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null); // Search according to the filter
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               break;
             }
          
           }
   // Process the list of changed Phone numbers
           if (entry is IPhone)
           {
              
             Filter filter = new Filter();
             filter.Query = string.Format("Phone in (Id = {0})",(entry as IPhone).Id); // Request a filter for searching a contractor, to which a call was made
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null); // Search according to the filter
             {
               saveLastDateTime(listKA.First().Id);
               break;
             }
          
           }
   // Process the list of changed Emails
           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); // Request a filter for searching a contractor, for which an email was created
 
             var listKA = EntityManager<IContractor>.Instance.Find(filter, null); // Search according to the filter
             if (listKA.Count > 0)
             {
               saveLastDateTime(listKA.First().Id);
               break;
             }
          
           }          
          
         }
          
       }
        
       // Change object/document event
       public override bool OnPreUpdate(PreUpdateEvent @event)
       { 
           
          
 
         if(@event.Entity is IContractor)  //  Interface of the Contractor type object
         {
    var Contractor  = (IContractor)@event.Entity;  // Cast to the type
           saveLastDateTime(Contractor.Id);
          }
  if(@event.Entity is ISale)  //  Interface of the Deal type object
         {
           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; // return to normal
          
       }
       // Update the date and time of the last activity with the contractor
       private void saveLastDateTime(long id)
       {
           var kExt = EntityManager<IContractorConfigExt>.Instance.Load(id); // Load the extended model for the contractor
          kExt.LastActiveTime = DateTime.Now;
       }      
    }  
  }
}
 

1. Publish the object and restart the server. Add a comment to the contractor, so that the LastDateTime got filled in.

2. Create a filter for searching contractors without activities for the last two weeks.

Open advanced search, select EQL and add the following query:

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

The search should find all the contractors that have been unchanged for two weeks.

You can create a filter to track activity with contractors for the current day:

LastActiveTime >= DateTime(’Today’)