Deactivate Child Records Using Plug-in

Requirement

Deactivate child records using 1:N association using plugin.

Details

Sometimes we want to deactivate/activate records based on the Parent record deactivation/activation. We can achieve this requirement by writing plugin on the update of the parent entity where we can check statecode value whether it’s 0 or 1 (Most of the activities have two states 0- Active, 1- Inactive) but we can similarly check for the other statecode as well.

IOrganizationService service = null;
 
public void Execute(IServiceProvider serviceProvider)
{

    ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    service = serviceFactory.CreateOrganizationService(context.UserId);

    Entity primaryEntity = null;

    if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
    {
        try
        {
            primaryEntity = (Entity)context.InputParameters["Target"];

            //check if record is deactivated
            if (primaryEntity.Contains("statecode") &&
              primaryEntity.GetAttributeValue<OptionSetValue>("statecode").Value == 1)
            {
                //for disable send operation as 0
                EnableDisableOneToManyRelatedEntities("childentitylogicalname", "parententitylookupfieldlogicalname", primaryEntity.Id,0);
            }
            //check if record is activated
            else if (primaryEntity.Contains("statecode") &&
               primaryEntity.GetAttributeValue<OptionSetValue>("statecode").Value == 0)
            {
                //for disable send operation as 1
                EnableDisableOneToManyRelatedEntities("childentitylogicalname", "parententitylookupfieldlogicalname", primaryEntity.Id,1);
            }
        }
        catch (Exception ex)
        {
            tracingService.Trace("Error occured while deactivating "+primaryEntity.LogicalName +" child records Detials" + ex.Message);
        }
    }
}

In the above code we are retrieving primary entity from the context and checking statecode value. Based on the satecode value we are calling another method to perform activation and deactivation like below.

private void EnableDisableOneToManyRelatedEntities(string entityname, string parententityfieldname, Guid parentfieldvalue,int operation)
{
    EntityCollection results = null;
    QueryExpression query = new QueryExpression()
    {
        EntityName = entityname,
        Criteria =
                    {
             FilterOperator = LogicalOperator.And,
                        Filters =
                        {
                            new FilterExpression
                            {
                                FilterOperator = LogicalOperator.And,
                                Conditions =
                                {
                                  new ConditionExpression(parententityfieldname,ConditionOperator.Equal,parentfieldvalue),
                                  new ConditionExpression("statecode",ConditionOperator.Equal,operation)
                                },
                            }

                        }
                    }
    };
    results = service.RetrieveMultiple(query);

    #region Disable records
    if (operation == 0)
    {
        //deactivate records
        foreach (Entity relatedentity in results.Entities)
        {
            Entity deactivateRecord = new Entity(entityname);
            deactivateRecord.Id = relatedentity.Id;
            deactivateRecord["statecode"] = new OptionSetValue(1);
            deactivateRecord["statuscode"] = new OptionSetValue(2);

            service.Update(deactivateRecord);

        }
    }
    #endregion
    #region Enable records
    else if (operation==1)
    {
        //activate them
        foreach (Entity relatedentity in results.Entities)
        {
            Entity activateRecord = new Entity(entityname);
            activateRecord.Id = relatedentity.Id;
            activateRecord["statecode"] = new OptionSetValue(0);
            activateRecord["statuscode"] = new OptionSetValue(1);

            service.Update(activateRecord);

        }
    }
    #endregion
}

In the above method based on the operation we are retrieving data from the child entity so for example if parent record is deactivated, we are fetching child entity records which are in activate state and associated with the parent entity and once we have them we are deactivating these records. We can register this plugin on the update of the parent entity and select statecode under the Filtering Attribute so that this plugin will only fire when status is changed.

Summary

This is how we can write plugin code Dynamics 365 CE to deactivate/activate child records when parent record is deactivated/activated.

Hope it will help someone !!

Keep learning and Keep Sharing !!

5 Quick Steps to debug your CRM Online Plugin


Similar Articles
HIMBAP
We are expert in Microsoft Power Platform.