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
Post a Comment