Association and Dissociation of records using plugin in MS CRM

using System;
using System.Collections;
using System.Text;
using Microsoft.Xrm.Sdk;
using System.Web;
using System.Xml;
using System.Diagnostics;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;

namespace Termination
{
///// In Enquiry entity we are having the subgrid of CarrirerSupplierRateRequest and RateRequestAdditional
/////1. Registering the Plugin on Create and Update CarrirerSupplierRateRequest entity
/////2. CarrirerSupplierRateRequest is having the lookup are aki_enquirynumber and aki_raterequestadditionals
/////3. Enquiry and RateRequestAdditional entities are having the N:N relationship
/////4. creating and updating the CarrirerSupplierRateRequest entity with aki_raterequestadditionals lookup field we are updating the sub grid(raterequestadditionals) in Enquiry entity
    public class AssociateAndDissociateRRA : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            if (context.Depth > 1)
                return;

            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
            ITracingService trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));                   

            try
            {
                //new EntityReference();
                EntityReference RRAdd= new EntityReference();
                #region
                if (context.InputParameters["Target"] is Entity && context.InputParameters.Contains("Target"))
                {
                    Entity postImage=context.PostEntityImages.Contains("PostCSRRImage")?context.PostEntityImages["PostCSRRImage"] as Entity:null;
                    Entity preImage = context.PreEntityImages.Contains("PreCSRRImage") ? context.PreEntityImages["PreCSRRImage"] as Entity : null;
                    Entity targetEntCSRateRequest = context.MessageName.Equals("Create") ? context.InputParameters["Target"] as Entity : postImage;
                    if (targetEntCSRateRequest != null)
                    {
                        EntityReference raterequestadditional = (EntityReference)targetEntCSRateRequest.Attributes["aki_raterequestadditionals"];// Lookup field aki_raterequestadditionals
                        EntityReference enquiryNumber = (EntityReference)targetEntCSRateRequest.Attributes["aki_enquirynumber"];// Lookup field aki_enquirynumber
                        if (raterequestadditional != null && enquiryNumber != null)
                        {
                            AssociateRecordsWithPreCheck("aki_aki_enquiry_aki_raterequestadditional", "aki_aki_enquiry_aki_raterequestadditional", enquiryNumber, raterequestadditional, "aki_enquiryid", "aki_raterequestadditionalid", service);
                        }
                        if (preImage != null)
                        {
                            EntityReference preRaterequestadditional = (EntityReference)preImage.Attributes["aki_raterequestadditionals"];
                            if (preRaterequestadditional != null)
                            {
                                EntityCollection rateReqs = GetCSRRforDisassociaterecords(preRaterequestadditional, preImage.Id, service);
                               if (rateReqs.Entities.Count == 0)
                               {
                                   Relationship rel=new Relationship();
                                   rel.SchemaName="aki_aki_enquiry_aki_raterequestadditional";
                                   EntityReferenceCollection entRefColl = new EntityReferenceCollection();
                                   entRefColl.Add(preRaterequestadditional);
                                   service.Disassociate("aki_enquiry", enquiryNumber.Id, rel, entRefColl);
                               }
                            }
                        }
                    }
                }
                #endregion     
            }
            catch (Exception ex)
            {
                trace.Trace(string.Format("Event-Delegate Associate & Dissassociate Plugin error: {0}", new[] { ex.ToString() }));
            }
        }

        private EntityCollection GetCSRRforDisassociaterecords(EntityReference preRaterequestadditional, Guid guid, IOrganizationService service)
        {
            //QueryExpression queryExp = new QueryExpression("aki_carriersupplierraterequest");
            //queryExp.ColumnSet = new ColumnSet(true);
            //queryExp.Criteria.AddCondition("aki_carriersupplierraterequestid", ConditionOperator.Equal, guid);
            //queryExp.Criteria.AddCondition("aki_raterequestadditionals", ConditionOperator.NotEqual, preRaterequestadditional);
            //return service.RetrieveMultiple(queryExp);
            var fetchXml = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                           "<entity name='aki_carriersupplierraterequest'>" +
                           "<attribute name='aki_carriersupplierraterequestid' />" +
                           "<attribute name='aki_name' />" +
                           "<attribute name='createdon' />" +
                           "<order attribute='aki_name' descending='false' />" +
                           "<filter type='and'>" +
                             "<condition attribute='aki_raterequestadditionals' operator='eq' uiname='RRA1' uitype='aki_raterequestadditional' value='" + preRaterequestadditional.Id + "' />" +
                           "</filter>" +
                           "</entity>" +
                           "</fetch>";

            return service.RetrieveMultiple(new FetchExpression(fetchXml));
        }
        #region


        #region Associate Any Two Records Which Has N:N Relation
        /// <summary>
        /// Associate Entity1 and Entity2 records if no association exists between them.
        /// </summary>
        /// <param name="relationshipEntityName">Takes input as relationshipEntityName to find record exist record.</param>
        /// <param name="relationshipName">Takes input as relationshipName to associate record.</param>
        /// <param name="entityRef1">Takes input as entityRef1 to have id to filter record from relationship.</param>
        /// <param name="entityRef2">Takes input as entityRef2 to have id to filter record from relationship.</param>
        /// <param name="entityRef1_idAttribute">Takes input as entityRef2 to have id logicalname to filter record from relationship.</param>
        /// <param name="entityRef2_idAttribute">Takes input as entityRef2 to have id logicalname to filter record from relationship.</param>
        /// <param name="service">Takes input as service for retrive  collection of opportunity products record.</param>
        private void AssociateRecordsWithPreCheck(string relationshipEntityName, string relationshipName, EntityReference entityRef1, EntityReference entityRef2, string entityRef1_idAttribute, string entityRef2_idAttribute, IOrganizationService service, bool preCheckRequired = true)
        {
            EntityCollection result = null;
            //If one of the ID's,relationshipName is null,or relationshipName is empty do nothing
            if (entityRef1 == null || entityRef2 == null) return;
            if (entityRef1.Id == Guid.Empty || entityRef2.Id == Guid.Empty) return;
            if (relationshipName == null || relationshipName == "") return;

            //Create a query that will check to see if the relationship already exists between Entity1 record and Entity2 record if preCheckRequired is true
            if (preCheckRequired)
                result = GetAssociateRecords(service, relationshipEntityName, entityRef1, entityRef1_idAttribute, entityRef2, entityRef2_idAttribute);

            //Check if the relationship was not found between Entity1 record and Entity2 record
            if (!preCheckRequired || (result == null || result.Entities == null || result.Entities.Count < 1))
            {
                //The relationship was not found, so create it
                service.Associate(entityRef1.LogicalName, entityRef1.Id, new Relationship(relationshipName), new EntityReferenceCollection() { entityRef2 });
            }

        }
        #endregion

        #region Get Associate Records
        /// <summary>
        /// Function to retrieve associate enitity2 record collection form given relationship and enitity1 record info.
        /// </summary>
        /// <param name="service">IOrganizationService</param>
        /// <param name="relationshipEntityName">string</param>
        /// <param name="entityRef1">EntityReference</param>
        /// <param name="entityRef1_idAttribute">string</param>
        /// <param name="entityRef2">EntityReference</param>
        /// <param name="entityRef2_idAttribute">string</param>
        /// <param name="columnSet">ColumnSet</param>
        /// <returns>EntityCollection</returns>
        private EntityCollection GetAssociateRecords(IOrganizationService service, string relationshipEntityName, EntityReference entityRef1, string entityRef1_idAttribute, EntityReference entityRef2 = null, string entityRef2_idAttribute = null, ColumnSet columnSet = null)
        {
            //If entityRef1 ID null or empty or relationshiEntitypName is null, then retun null
            if (entityRef1 == null || relationshipEntityName == null || entityRef1.Id == Guid.Empty) return null;

            QueryExpression query = new QueryExpression(relationshipEntityName)
            {
                NoLock = true
            };
            //add filter to retrieve enitity2 records associate enitity1
            FilterExpression associateRecordsFilter = new FilterExpression(LogicalOperator.And);
            associateRecordsFilter.Conditions.Add(new ConditionExpression(entityRef1_idAttribute, ConditionOperator.Equal, entityRef1.Id.ToString()));

            //if filter to get entity with particular id for verification of association used.
            if (!string.IsNullOrEmpty(entityRef2_idAttribute) && entityRef2 != null)
                associateRecordsFilter.Conditions.Add(new ConditionExpression(entityRef2_idAttribute, ConditionOperator.Equal, entityRef2.Id.ToString()));

            //add filter to query.
            query.Criteria.Filters.Add(associateRecordsFilter);
            query.ColumnSet = columnSet == null ? new ColumnSet(false) : columnSet;

            //return association query info.
            return service.RetrieveMultiple(query);
        }
        #endregion

        #endregion
    }
}

Comments

Popular posts from this blog

Basic Plugin Code in D365 using C#

CURD (Create, Update, Retrieve and Delete) Operation in D365 using Power Shell Script

Meta Data Using WebApiRequest