back to top

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;

Or

// 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.

Contact Customer FX for your CRM project
We let our expertise speak for itself - let us know how our all-star team can help on your CRM project
About the Author
Ryan Farley
Ryan Farleyhttps://customerfx.com/article/author/ryanfarley/
Ryan Farley is the Director of Development for Customer FX and creator of slxdeveloper.com. 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.

3 COMMENTS

  1. Do you have any recommended ways of efficiently checking which columns have been modified in an OnSaving event? OnSaved has the e.ModifiedColumnValues property, but no such property exists on the EntityBeforeEventArgs unfortunately.

    I can see that there’s a method entity.GetColumnOldValue(“UsrColumnName”), but looking at the source code for this I believe it will load the data from the database if it isn’t already cached, so it’s hard to tell if this is efficient in the general case, and if you wanted to check for any changes across all column values you’d have to run this over every column on the entity.

    I can also see that there’s a method entity.GetChangedColumnValues() but again I’m not quite sure if it re-queries the database – this wouldn’t necessarily be a dealbreaker, but it would be good to know if this performance overhead exists when deciding whether to use it or not. Do you have any knowledge about this?

    • Hi Harvey,
      Other than the GetChangedColumnValues/GetTypedOldColumnValue/GetColumnOldValue, I am not aware of any way to get the old values (or changed columns) in the BEFORE events. However, I do use those often in before events. If they do query the database or not, I’ve not looked. It would seem strange and unnecessary, but I suppose I could see that being the case.
      Ryan

    • Thanks Ryan, I may have a look at some point and let you know what I find. My hesitance mainly comes from it not being as readily available as in the EntityAfterEventArgs, plus the decompiled OOTB code for Entity is fairly generic to handle all cases of working with an Entity, not just when its already in an OnSaving event and will therefore need the old data anyway to check for changing values. Not sure why that info isn’t included in the EntityBeforeEventArgs, would be nice if the pattern was the same.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

AI Readiness Checklist for CRM Teams: Is Your CRM System Ready for AI?

Before using AI in Creatio, make sure your CRM data, users, processes, and automation foundation are ready. Use this practical AI readiness checklist for CRM teams.

Build Your Creatio AI Skills with the 2026 AI Summer Program

Join Creatio’s free 2026 AI Summer Program to learn how to identify, build, deploy, and manage AI agents.

Creatio 10x Is Coming: Join the Webinar to Explore the Future of AI-Native CRM

Learn what's new in Creatio 10x and how AI-native CRM, agentic AI, and no-code automation are shaping the future of customer relationship management. Join the upcoming webinar and discover what's next.

Creatio Unlimited Pricing Explained: AI Packages, Costs, Pros & Cons

Learn what Creatio’s new Unlimited pricing model includes, what it doesn’t include, how AI Action packages work, and the pros and cons for businesses evaluating Creatio.

Using the AI Prompt to Create Dynamic Folders in Creatio

Using Creatio's AI prompt to create the filter for a dynamic folder works best if you specifically ask for that, and if you are as clear and direct as possible about the filtering, conditions.

Related Articles

AI Readiness Checklist for CRM Teams: Is Your CRM System Ready for AI?

Before using AI in Creatio, make sure your CRM data, users, processes, and automation foundation are ready. Use this practical AI readiness checklist for CRM teams.

Build Your Creatio AI Skills with the 2026 AI Summer Program

Join Creatio’s free 2026 AI Summer Program to learn how to identify, build, deploy, and manage AI agents.

Creatio 10x Is Coming: Join the Webinar to Explore the Future of AI-Native CRM

Learn what's new in Creatio 10x and how AI-native CRM, agentic AI, and no-code automation are shaping the future of customer relationship management. Join the upcoming webinar and discover what's next.

Creatio Unlimited Pricing Explained: AI Packages, Costs, Pros & Cons

Learn what Creatio’s new Unlimited pricing model includes, what it doesn’t include, how AI Action packages work, and the pros and cons for businesses evaluating Creatio.

Related Videos