Adding Code to Listen for Entity Events in Creatio

An integral part in building business logic in Creatio is being able to respond to entity events, such as when a record is added, modified, deleted, etc. Creatio does provide many ways to handle these events. You can add signal starts in processes or handle these events in entity subprocesses. This article will cover another option, which is to add a C# class in a source code schema to handle these events as well. These types of classes to handle entity events are referred to as the “entity event layer” (this capability was added in 7.12.4).

One thing to note here, the order that the entity events are typically triggered are as follows:

  1. First, entity subprocesses are executed (the subprocess in an entity object where you can add script tasks tied to entity event messages)
  2. Then, the entity event layer classes are executed (the method described in this article)
  3. Lastly, the entity signal starts in processes (the signals for record added, modified, deleted to start a process. These are after events)

Of course, it also depends on whether you’re handling a before or an after event. Let’s take a look at how how to create an entity event layer class.

Let’s say you want to handle the event before an Activity is saved to the database. You can create a source code schema and add a class that inherits from BaseEntityEventListener and add the EntityEventListener attribute to it indicating the SchemaName for the entity you want to handle events for. The name of the class and the name of the namespace doesn’t matter, you can name those whatever you’d like. You’ll need to add using directives for Terrasoft.Core.Entities and Terrasoft.Core.Entities.Events namespaces.

using Terrasoft.Core.Entities;
using Terrasoft.Core.Entities.Events;

namespace FX.EntityEventListeners
    [EntityEventListener(SchemaName = "Activity")]
    public class ActivityEntityEventListener : BaseEntityEventListener
        public override void OnInserting(object sender, EntityBeforeEventArgs e)
            base.OnInserting(sender, e);
            var activity = (Entity)sender;
            var userConnection = activity.UserConnection;

In the code above, we’ve created a class that will receive entity events for the Activity entity. We’re overriding the OnInserting event (which is before the activity is inserted). We then call the base OnInserting event (this is important, don’t forget this). In the event we can get the entity object being inserted as the sender. This entity gives us access to the UserConnection, if needed. We can then do whatever is needed in this event such as set additional fields, etc, and these will get saved with the record – we don’t need to call save here to save the activity since this is before the record is saved.

If you want to create a class that handles events for all entities, not just a specific one, such as Activity, you can add a class like the following:

[EntityEventListener(IsGlobal = true)]
public class GlobalEntityEventListener : BaseEntityEventListener
    public override void OnSaved(object sender, EntityAfterEventArgs e)
        base.OnSaved(sender, e);
        var entity = (Entity)sender;
        var userConnection = entity.UserConnection;

The class above will handle the after saved event (inserted or updated) for all entities, not just a specific one. Additionally, you can also create a class that handles the event of several entities by adding multiple EntityEventListener attributes, such as the following that will handle events for both Opportunities and Leads:

[EntityEventListener(SchemaName = "Opportunity")]
[EntityEventListener(SchemaName = "Lead")]
public class SalesEntityEventListener : BaseEntityEventListener

The events methods you can override here are the following:

  • OnInserting – Before a record is added
  • OnInserted – After a record is added
  • OnUpdating – Before a record is updated
  • OnUpdated – After a record is updated
  • OnSaving – Before a record is saved, for both inserting and updating events
  • OnSaved – After a record is saved, for both inserting and updating events
  • OnDeleting – Before a record is deleted
  • OnDeleted – After a record is deleted

One thing that is important to note here, if you’re handling a Before event, you will receive an EntityBeforeEventArgs argument. If you’re handling an after event, you’ll receive an EntityAfterEventArgs argument. These both provide different values depending on the context of the event happening before or after.

EntityBeforeEventArgs provides:

  • KeyValue – the Id value of the record
  • IsCanceled – set to true to cancel, meaning stop the insert, update, or delete from happening
  • AdditionalCondition – allows you to provide additional filter conditions

EntityAfterEventArgs provides:

  • ModifiedColumnValues – a collection of the columns modified on the entity
  • PrimaryColumnValue – the Id value of the record

Using the ModifiedColumnValues in the EntityAfterEventArgs you can conditionally have your event logic only fire if certain columns were changed in the event. Additionally, the entity has a built-in function named GetChangedColumnValues to get any changed columns which you can also use for this purpose. For example, only handle the event if the StartDate or the DueDate has been changed in an Activity, you’d do something like the following:

// if the change isn't StartDate or DueDate then exit out
var cols = new List<string>{ "StartDate", "DueDate" };
if (!activity.GetChangedColumnValues().Any(x => cols.Contains(x.Name))) return;


// if the change isn't StartDate or DueDate then exit out
var cols = new List<string>{ "StartDate", "DueDate" };

var hasColumn = false;
foreach (var col in activity.GetChangedColumnValues())
    if (cols.Contains(col.Name)) hasColumn = true;

if (!hasColumn) return;

You can use this approach for either before or after events.

Want content like this delivered to your inbox? Sign up for our newsletter!

Ryan Farley

Ryan Farley is the Director of Development for Customer FX and creator of He's been blogging regularly about SalesLogix, now Infor CRM, since 2001 and believes in sharing with the community. His new passion for CRM is Creatio, formerly bpm'online. He loves C#, Javascript, web development, open source, and Linux. He also loves his hobby as an amateur filmmaker.

Submit a Comment

Your email address will not be published. Required fields are marked *