Create a N: N relationship between opportunity and contact and Quote and contact, use contact sub grid in opportunity and Quote. On create of Quote bring all associated contact for the opportunity and associate them to quote as well. If removed one contact from opportunity then it needs to remove from quote sub gird as well. By using Plugins

 

Breakdown structure:

Entities:

·         Opportunity

·         Contact

·         Quote

       Fields:

§  Opportunity:

o   Contact (Sub grid)

§  Quote:

o   Contact (Sub grid)

Triggering Point:

·         On Create of record in quote entity.

·         Associate

·         Disassociate

 

Step 1: Whenever you are creating a record in quote entity then whatever the contacts are associated with opportunity those contacts are need to be associate with quote.

Task 1:

Retrieve the quote entity from context by using Target key.

Read the opportunity lookup from quote entity

Task 2:

Retrieve the all contacts from related opportunity by using fetch xml.

Task 3:

By using foreach add the contacts to opportunity related quote.

Create the instance for associate request.

Declare the related entities and mention the quote, contact relationship.

Task 4:

Execute associate request by using service.Execute(request).

Step 2: if you are adding the contact in opportunity entity then need to be add same contacts in related opportunity quotes.

Here Related Entities and Relationship came from context keys.

Task 1:

Read the relationship, Opportunity and related entities.

Task 2:

Retrieve the opportunity entity by using service.retrieve.

Retrieve the related entities (Contacts list) from context.

Task 3:

Retrieve the all quotes from related opportunity by using fetch xml.

Task 4:

Create the associate and disassociate request.

 

Creating N: N relationship between opportunity and contact:



        


 Adding contact sub grid into Opportunity:

 


Creating N: N relationship between Quote and contact:


       

Adding contact sub grid into Quote:



On create of Quote bring all associated contact for the opportunity and associate them to quote as well:

Fetch xml:




Plugin Code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Microsoft.Xrm.Sdk;

using Microsoft.Xrm.Sdk.Messages;

using Microsoft.Xrm.Sdk.Query;

 

namespace Plugins_2

{

    public class Task1 : IPlugin

    {

        public void Execute(IServiceProvider serviceProvider)

        {

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)

            {

                try

                {

                    Entity quote = (Entity)context.InputParameters["Target"];

                    EntityReference opportunity = quote.GetAttributeValue<EntityReference>("opportunityid");

 

                    string fetch = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>" +

"<entity name='contact'>" +

"<attribute name='fullname'/>" +

"<attribute name='telephone1'/>" +

"<attribute name='contactid'/>" +

"<order attribute='fullname' descending='false'/>" +

"<link-entity name='new_opportunity_contact' from='contactid' to='contactid' visible='false' intersect='true'>" +

"<link-entity name='opportunity' from='opportunityid' to='opportunityid' alias='ac'>" +

"<filter type='and'>" +

"<condition attribute='opportunityid' operator='eq' uitype='opportunity' value='" + opportunity.Id + "'/>" +

"</filter>" +

"</link-entity>" +

"</link-entity>" +

"</entity>" +

"</fetch>";

                    EntityCollection contactlist = service.RetrieveMultiple(new FetchExpression(fetch));

                    EntityReferenceCollection quote_contact = new EntityReferenceCollection();

 

                    foreach (var relatedRecord in contactlist.Entities)

                    {

                        quote_contact.Add(new EntityReference(relatedRecord.LogicalName, relatedRecord.Id));

                    }      

                    AssociateRequest request = new AssociateRequest()

                    {

                        RelatedEntities = quote_contact,

                        Relationship = new Relationship("new_quote_contact"),

                        Target = new EntityReference(quote.LogicalName, quote.Id)

                    };

                    service.Execute(request);

                }              

                catch (Exception EX)

                {

                    throw new InvalidPluginExecutionException(EX.Message);

                }

            }

        }

    }

}


 



 

Step2: If you are adding the contact in opportunity entity then need to be add same contacts in related opportunity quotes.

Fetch xml:



Plugin code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Microsoft.Xrm.Sdk;

using Microsoft.Xrm.Sdk.Query;

using Microsoft.Xrm.Sdk.Messages;

namespace Plugins_2

{

    public class Taks1_oppo : IPlugin

    {    

        public void Execute(IServiceProvider serviceProvider)

        {

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

             IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

 

            try

            {

                string relationshipName = string.Empty;

 

                if (context.InputParameters.Contains("Relationship"))

                {

                    relationshipName = ((Relationship)context.InputParameters["Relationship"]).SchemaName;

                }

 

                if (relationshipName != "new_opportunity_contact")

                {

                    return;

                }

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is EntityReference)

                {

                    EntityReference oppo = (EntityReference)context.InputParameters["Target"];

                    Entity opportunity = service.Retrieve(oppo.LogicalName, oppo.Id, new ColumnSet(true));

 

                    // Related entities

                    EntityReferenceCollection ContactsList = (EntityReferenceCollection)context.InputParameters["RelatedEntities"];

       string fetch = "<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +

    "<entity name='quote'>" +

    "<attribute name='name'/>" +

    "<attribute name='customerid'/>" +

    "<attribute name='statecode'/>" +

    "<attribute name='totalamount'/>" +

    "<attribute name='quoteid'/>" +

    "<attribute name='createdon'/>" +

    "<order attribute='name' descending='false'/>" +

    "<link-entity name='opportunity' from='opportunityid' to='opportunityid' link-type='inner' alias='ab'>" +

    "<filter type='and'>" +

    "<condition attribute='opportunityid' operator='eq' uitype='opportunity' value='" + opportunity.Id + "'/>" +

    "</filter>" +

    "</link-entity>" +

    "</entity>" +

    "</fetch>";

                    EntityCollection quotelist = service.RetrieveMultiple(new FetchExpression(fetch));

                    if (context.MessageName.ToLower() == "associate")

                    {

                        foreach (var quote in quotelist.Entities)

                        {

                            AssociateRequest request = new AssociateRequest()

                            {

                                RelatedEntities = ContactsList,

 

                                Relationship = new Relationship("new_quote_contact"),

                                Target = new EntityReference(quote.LogicalName, quote.Id)

                            };

                            service.Execute(request);

                        }

                    }

                   else if (context.MessageName.ToLower() == "disassociate")

                    {

                        foreach (var quote in quotelist.Entities)

                        {

                            DisassociateRequest request = new DisassociateRequest()

                            {

                                RelatedEntities = ContactsList,

                                Relationship = new Relationship("new_quote_contact"),

                                Target = new EntityReference(quote.LogicalName, quote.Id)

                            };

                            service.Execute(request);

                        }

                    }

                }

            }

            catch (Exception ex)

            {

                throw new InvalidPluginExecutionException(ex.Message);

            }

            }

        }

    }


 

 



 


Output:

Whenever you are adding the contacts into opportunity entity then same contacts are added to opportunity related quote


 








Whenever you are removing the contacts from opportunity entity then same contacts are removed from opportunity related quote



Comments

Popular posts from this blog

SSRS User Story-7: Create a SSRS report group by Case, retrieve all work orders and make work orders as sub group, retrieve all bookable resource bookings based on work order. If booking is completed then show the row color as green.

SSRS User Story-6: Prepare a SSRS report on the birthday, In First part, group by with date of birth. In second report, prepare the wishes card with individual students.

SSRS User Story 2: Generate a report on individual student, if I click on the payment details report in student record. It need to show all the transactions done in current year along with sum. (it should show for each student separately)