web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Plugin is unable to update quotedetails before quote win throwing error "Cannot Update a Read-Only Entity".

(0) ShareShare
ReportReport
Posted on by 81

I have registered a plugin on "win" message on "quote" entity. This plugin creates projects corresponding to the quotedetails entity and attach those projects into project lookup of the qutoedetails entity. This plugin fires on below-mentioned steps:Screenshot-_2800_47_2900_.png

And the code I am using is:

using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;

public class MyPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{

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


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


if (context.InputParameters.Contains("QuoteClose") && context.InputParameters["QuoteClose"] is Entity)
{
Entity entity = (Entity)context.InputParameters["QuoteClose"];

if (entity.LogicalName != "quoteclose")
return;

// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

try
{


int noofquotedetails = 0;
Guid quoteid = ((EntityReference)entity["quoteid"]).Id;

string quotedetail = @"<fetch mapping='logical' version='1.0' distinct='false' output-format='xml-platform'>
<entity name='quotedetail'>
<attribute name='productid' />
<attribute name='productdescription' />
<attribute name='priceperunit' />
<attribute name='quantity' />
<attribute name='extendedamount' />
<attribute name='quotedetailid' />
<attribute name='quoteid' />
<attribute name='msdyn_project' />
<order descending='false' attribute='productid' />
<filter type='and'>
<condition attribute='quoteid' operator='eq' value='" + Convert.ToString(quoteid) + @"'/>
</filter>
</entity>
</fetch>";
EntityCollection allquotelines = service.RetrieveMultiple(new FetchExpression(quotedetail));
noofquotedetails = allquotelines.Entities.Count;

for (int i=0;i<noofquotedetails;i++)
{
Entity Quoteline = new Entity("quotedetail");
Quoteline = allquotelines.Entities[i];

string projectlinename = allquotelines.Entities[i].Attributes["productdescription"].ToString();

Entity Project = new Entity("msdyn_project");

Project["msdyn_subject"] = projectlinename;

Guid projectid = service.Create(Project);

//Quoteline.Attributes.Add("msdyn_project", Project.ToEntityReference());

Quoteline.Attributes["msdyn_project"] = new EntityReference("msdyn_project", projectid);
//throw new Exception(projectid.ToString()+" , "+ allquotelines.Entities[i].Attributes["quotedetailid"].ToString() );

//Quoteline.Attributes["msdyn_project"] = FromParty.ToEntityReference();
//service.Update(Project);
tracingService.Trace("before service update");
service.Update(Quoteline);
tracingService.Trace("update service update");

}
}

catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException(ex.Message);
//throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex);
}

catch (Exception ex)
{
tracingService.Trace("MyPlugin: {0}", ex.ToString());
throw;
}
}
}
}

But I am getting an error while updating quote to "close as won".

The error is:

Screenshot-_2800_48_2900_.png

I don't know why on preoperation the quotedetails entity is getting read-only.

*This post is locked for comments

I have the same question (0)
  • Rawish Kumar Profile Picture
    13,758 on at

    Hi Naveen, in pre-operations , you dont need to "service.update" - you just have to simply set the values for that attribute in the target entity and leave

    nishantrana.me/.../update-in-pre-update-plugin-crm

  • Naveen Goyal Profile Picture
    81 on at

    Thanks Rawish for replying, but I am not updating the "quote" entity and my plugin is running on "quote" entity for "win" message. so I have to update the quotedetails entity in order to update the changes I have made.

    I tried the solution you provided also but it is not updating quote details.

  • Rawish Kumar Profile Picture
    13,758 on at

    okay , did you check what is the status & state of quoteentitydetails during the transaction in plugin?debug

  • Michel Gueli Profile Picture
    982 on at

    If have rewritten your code to make sure I'll understand.

    using System;

    using System.ServiceModel;

    using Microsoft.Xrm.Sdk;

    using Microsoft.Xrm.Sdk.Query;

    using Microsoft.Xrm.Sdk.Messages;

    using System.Collections.Generic;

    using System.Linq;

    namespace MGTest.Plugins

    {

    public class QuoteWin : IPlugin

    {

    public void Execute(IServiceProvider serviceProvider)

    {

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

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

    tracingService.Trace("Tracing: EXECUTE");

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

    {

    var entity = (Entity)context.InputParameters["QuoteClose"];

    if (entity.LogicalName != "quoteclose")

    return;

    //throw new InvalidPluginExecutionException("Check");

    // Obtain the organization service reference which you will need for

    // web service calls.

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

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

    try

    {

    var quoteid = ((EntityReference)entity["quoteid"]).Id;

    var quoteDetails = RetrieveQuoteDetails(service, quoteid);

    if (quoteDetails != null)

    {

    foreach (var qd in quoteDetails)

    {

    var project = new Entity("msdyn_project");

    if (qd.Contains("productdescription"))

    {

    project.Attributes.Add("msdyn_subject", qd.GetAttributeValue<string>("productdescription"));

    }

    Guid projectId = service.Create(project);

    UpdateQuoteDetail(service, qd.Id, projectId);

    }

    }

    }

    catch (FaultException<OrganizationServiceFault> ex)

    {

    throw new InvalidPluginExecutionException(ex.Message);

    //throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex);

    }

    catch (Exception ex)

    {

    tracingService.Trace("MyPlugin: {0}", ex.ToString());

    throw;

    }

    }

    }

    private List<Entity> RetrieveQuoteDetails(IOrganizationService service, Guid quoteId)

    {

    var query = new QueryExpression("quotedetail");

    query.ColumnSet.AddColumn("productdescription");

    query.Criteria.AddCondition("quoteid", ConditionOperator.Equal, quoteId);

    var result = service.RetrieveMultiple(query);

    if (result != null && result.Entities != null && result.Entities.Any())

    {

    return result.Entities.ToList();

    }

    return null;

    }

    private void UpdateQuoteDetail(IOrganizationService service, Guid quoteDetailId, Guid projectId)

    {

    var quoteDetail = new Entity("quotedetail", quoteDetailId);

    quoteDetail.Attributes.Add("msdyn_project",new EntityReference("msdyn_project", projectId));

    service.Update(quoteDetail);

    }

    }

    }

    But I cannot trigger the win event on Quote. If I press Create order on quote It should be executing my plugin.

  • Naveen Goyal Profile Picture
    81 on at

    but there is no message in plugin registration tool for "create" on "order". So how I can execute that and also after winning the quote, "quotedetails" entity changes to read only so there is no way it can be updated on the creation of order which is next step to winning of quote.

  • Verified answer
    Naveen Goyal Profile Picture
    81 on at

    Finally I got the answer for this:

    Register this plugin on PreOperation stage (stage 20) of custom action "msdyn_CloseQuoteAsWon" for the Quote entity.

    At that stage quote is going to remain editable so the quote lines can be updated.

    Registering the plugin that updates QuoteLine on PreOperate stage of Quote Win message is incorrect (by design).

    Quote can be Won only if the quote is in Active state, however in this state quote can't be edited, there are validations in Sales solution that prevent an update of the quote and lines.

    'The Close As Won' button in the Project Service quote form calls custom action "msdyn_CloseQuoteAsWon" instead of "Win" message.

    The custom action does the following:

       Sets state of Quote to Active (if the quote is not in the Active state)

       Calls quote "Win"

       Create Sales Order for the Quote

    That is why it looks like you can edit and then close quote as won in one click (since the action activates the quote for you).

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
SA-08121319-0 Profile Picture

SA-08121319-0 4

#1
Calum MacFarlane Profile Picture

Calum MacFarlane 4

#3
Alex Fun Wei Jie Profile Picture

Alex Fun Wei Jie 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans