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 cam achieve this requirement writing plugin on the update of the parent entity where we can check statecode value wheather 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 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

Leave a Reply

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