Skip to main content

Notifications

Community site session details

Community site session details

Session Id :
Customer experience | Sales, Customer Insights,...
Answered

Retrieve and update Product Line Item on a Quote

(1) ShareShare
ReportReport
Posted on by 15

I am trying to create a plugin that would allow me to update some custom field on product line item on a quote.

I have the below code which does not allow me to retrieve the list of the products included on the quote. I always get a -1 return. Please help as I am new to this.

public class ProductTemplateAssignment : IPlugin
    {

        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
            (ITracingService)serviceProvider.GetService(typeof(ITracingService));

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


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

                if (entity.LogicalName != "quote")
                    return;
                IOrganizationServiceFactory serviceFactory =
                    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                try
                {
                    var quoteID = entity.Id.ToString();
                    tracingService.Trace("QuoteID: {0}", quoteID);
                    ExecuteAddTemplateToQuoteItem(service, new Guid(quoteID));
                }

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


            }
        }

        public EntityCollection RetrieveQuoteItem(IOrganizationService service, Guid quoteid)
        {

            var query = new QueryExpression
            {
                EntityName = "quotedetail",
                ColumnSet = new ColumnSet("quoteid", "productid"),
                Criteria = new FilterExpression
                {
                    FilterOperator = LogicalOperator.And,
                    Conditions =
                {
                    new ConditionExpression
                    {
                        AttributeName = "quoteid",
                        Operator = ConditionOperator.Equal,
                        Values = { quoteid }
                    }
                }
                }
            };
            var results = service.RetrieveMultiple(query);
            return results;
        }

        public void ExecuteAddTemplateToQuoteItem(IOrganizationService service, Guid quoteid)
        {
            EntityCollection quoteItem = RetrieveQuoteItem(service, quoteid);
            //Add Template
        }

    }

Please note that I have attached this plugin to Update Message on the Quote Entity with PostOperation Execution.

  • ajyendra Profile Picture
    1,738 on at
    RE: Retrieve and update Product Line Item on a Quote

    Glad to help Cheers buddy!

  • Suggested answer
    hkccrm Profile Picture
    15 on at
    RE: Retrieve and update Product Line Item on a Quote

    Hi Ajyendra,

    Thanks a bunch for your help I'm finally able to work it out now with your awesome help!

    public class ProductTemplateAssignment : IPlugin
        {
    
            public void Execute(IServiceProvider serviceProvider)
            {
                ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));
    
                IPluginExecutionContext context = (IPluginExecutionContext)
                    serviceProvider.GetService(typeof(IPluginExecutionContext));
    
    
                tracingService.Trace("Run: {0}");
                // The InputParameters collection contains all the data passed in the message request.
                if (context.InputParameters.Contains("Target") &&
                    context.InputParameters["Target"] is Entity)
                {
                    Entity entity = (Entity)context.InputParameters["Target"];
    
                    if (entity.LogicalName != "quote")
                        return;
                    IOrganizationServiceFactory serviceFactory =
                        (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                    try
                    {
                        var quoteID = (entity.Id).ToString();
                        tracingService.Trace("QuoteID: {0}", quoteID);
                        ExecuteAddTemplateToQuoteItem(service, tracingService, new Guid(quoteID));
                    }
    
                    catch (Exception ex)
                    {
                        tracingService.Trace("ProductTemplateAsg: {0}", ex.ToString());
                        throw;
                    }
    
    
                }
            }
    
            public EntityCollection RetrieveQuoteItem(IOrganizationService service, Guid quoteid)
            {
                var query = new QueryExpression
                {
                    EntityName = "quotedetail",
                    ColumnSet = new ColumnSet("quotedetailid", "quoteid", "productid", "new_quotetext"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                    {
                        new ConditionExpression
                        {
                            AttributeName = "quoteid",
                            Operator = ConditionOperator.Equal,
                            Values = { quoteid }
                        }
                    }
                    }
                };
                EntityCollection results = service.RetrieveMultiple(query);
                return results;
            }
    
            public Entity RetrieveQuoteTemplate(IOrganizationService service, Guid prodID)
            {
    
                var query = new QueryExpression
                {
                    EntityName = "product",
                    ColumnSet = new ColumnSet("productid","new_producttemplate"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                    {
                        new ConditionExpression
                        {
                            AttributeName = "productid",
    
                            Operator = ConditionOperator.Equal,
                            Values = { prodID }
                        }
                    }
                    }
                };
    
    
                Entity results = service.RetrieveMultiple(query).Entities.FirstOrDefault();
                return results;
            }
    
            public void ExecuteAddTemplateToQuoteItem(IOrganizationService service, ITracingService ts, Guid quoteid)
            {
    
    
                
                EntityCollection quoteItem = RetrieveQuoteItem(service, quoteid);
                if (quoteItem != null)
                {
                    if (quoteItem.Entities.Count > 0)
                    {
                        foreach (var qi in quoteItem.Entities)
                        {
                            if (qi.Contains("productid") && qi["productid"] != null)
                            {
                                if (!(qi.Contains("new_quotetext") && qi["new_quotetext"] != null))
                                {
                                    EntityReference ProductId = (EntityReference)qi["productid"];
                                    Guid prodid = ProductId.Id;
    
    
                                    Entity qiTemplate = RetrieveQuoteTemplate(service, prodid);
                                    var template = qiTemplate.Attributes["new_producttemplate"].ToString();
    
                                    var qiUpdateTemplate = new Entity("quotedetail");
                                    qiUpdateTemplate.Id = qi.Id;
                                    qiUpdateTemplate.Attributes["new_quotetext"] = template;
                                    try
                                    {
                                        service.Update(qiUpdateTemplate);
                                    }
                                    catch (Exception ex)
                                    {
                                        throw new InvalidPluginExecutionException("Unable to update quote template "   ex.ToString());
                                    }
                                }
                            }
                        }
                        return;
                    }
                }
                return;
            }
    
        }

  • Suggested answer
    ajyendra Profile Picture
    1,738 on at
    RE: Retrieve and update Product Line Item on a Quote

    Also change this line var quoteID = entity.Id.ToString(); to

    var quoteID = (entity.Id).toString();

  • Verified answer
    ajyendra Profile Picture
    1,738 on at
    RE: Retrieve and update Product Line Item on a Quote

    I think it is just because you are not checking the productid is null or not

    for that Use this Code

    if(qi.Contains("productid") && qi["productid"] != null){

    EntityReference ProductId = (EntityReference) qi["productid"];
                        Guid id = ProductId.Id;


               Entity qiTemplate = RetrieveQuoteTemplate(service, id);
                ts.Trace(qiTemplate.Attributes["new_producttemplate"].ToString());

    }

  • hkccrm Profile Picture
    15 on at
    RE: Retrieve and update Product Line Item on a Quote

    I finally made it to work with the code below

    public class ProductTemplateAssignment : IPlugin
        {
    
            public void Execute(IServiceProvider serviceProvider)
            {
                ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));
    
                IPluginExecutionContext context = (IPluginExecutionContext)
                    serviceProvider.GetService(typeof(IPluginExecutionContext));
    
    
                tracingService.Trace("Run: {0}");
                // The InputParameters collection contains all the data passed in the message request.
                if (context.InputParameters.Contains("Target") &&
                    context.InputParameters["Target"] is Entity)
                {
                    Entity entity = (Entity)context.InputParameters["Target"];
    
                    if (entity.LogicalName != "quote")
                        return;
                    IOrganizationServiceFactory serviceFactory =
                        (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                    try
                    {
                        var quoteID = entity.Id.ToString();
                        tracingService.Trace("QuoteID: {0}", quoteID);
                        ExecuteAddTemplateToQuoteItem(service, tracingService, new Guid(quoteID));
                    }
    
                    catch (Exception ex)
                    {
                        tracingService.Trace("ProductTemplateAsg: {0}", ex.ToString());
                        throw;
                    }
    
    
                }
            }
    
            public EntityCollection RetrieveQuoteItem(IOrganizationService service, Guid quoteid)
            {
                var query = new QueryExpression
                {
                    EntityName = "quotedetail",
                    ColumnSet = new ColumnSet("quoteid", "productid"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                    {
                        new ConditionExpression
                        {
                            AttributeName = "quoteid",
                            Operator = ConditionOperator.Equal,
                            Values = { quoteid }
                        }
                    }
                    }
                };
                EntityCollection results = service.RetrieveMultiple(query);
                return results;
            }
    
            public Entity RetrieveQuoteTemplate(IOrganizationService service, Guid prodID)
            {
                var query = new QueryExpression
                {
                    EntityName = "product",
                    ColumnSet = new ColumnSet("new_producttemplate"),
                    Criteria = new FilterExpression
                    {
                        Conditions =
                    {
                        new ConditionExpression
                        {
                            AttributeName = "productid",
    
                            Operator = ConditionOperator.Equal,
                            Values = { prodID }
                        }
                    }
                    }
                };
    
    
                Entity results = service.RetrieveMultiple(query).Entities.FirstOrDefault();
                return results;
            }
    
            public void ExecuteAddTemplateToQuoteItem(IOrganizationService service, ITracingService ts, Guid quoteid)
            {
    
    
                
                EntityCollection quoteItem = RetrieveQuoteItem(service, quoteid);
                if (quoteItem != null)
                {
                    if (quoteItem.Entities.Count > 0) {
                        foreach (var qi in quoteItem.Entities)
                        {
                            Entity qiTemplate = RetrieveQuoteTemplate(service, new Guid(qi.Attributes["productid"].ToString()));
                            ts.Trace(qiTemplate.Attributes["new_producttemplate"].ToString());
                        }
    
                    }
                    else
                    {
                        throw new InvalidPluginExecutionException("no content");
    
                    }
                }
                else
                {
                    throw new InvalidPluginExecutionException("No Content");
                }
                }
    
        }

    But I'm getting an error "Guid should contain 32 digits with 4 dashes". I can confirm that the quote has products on it.

    I'm supposed to assign / update a value on a custom field on the Product Line Item's product record.

    Please be patient with me on this one as I'm relatively new to this. Thank you again.

  • Suggested answer
    ajyendra Profile Picture
    1,738 on at
    RE: Retrieve and update Product Line Item on a Quote

    Hi,

    I know its a silly to change but try if it is related to coding syntax

    public EntityCollection RetrieveQuoteItem(IOrganizationService service, Guid quoteid)

    {

       QueryExpression query = new QueryExpression("quotedetail");

       query.ColumnSet = new ColumnSet("quoteid", "productid","quotedetailid");

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

       EntityCollection results = service.RetrieveMultiple(query);

       return results;

    }

    OR

    public EntityCollection RetrieveQuoteItem(IOrganizationService service, Guid quoteid)

    {

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

    <entity name='quotedetail'>

    <attribute name='productid'/>

    <attribute name='quotedetailid'/>

    <attribute name='quoteid'/>

    <order descending='false' attribute='productid'/>

    <filter type='and'>

    <condition attribute='quoteid' value='{0}'   operator='eq'/>

    </filter>

    </entity>

    </fetch>";

    string formatXml = string.Format(fetchXml, userid.ToString());

                   // Executing fetchxml using  RetrieveMultiple method

                   EntityCollection results = service.RetrieveMultiple(new FetchExpression(formatXml));

    return results;

    }

    if it doesn't work might have some other issue and also please check first on advanced find that particular quote have product or not?

  • hkccrm Profile Picture
    15 on at
    RE: Retrieve and update Product Line Item on a Quote

    Thank you but I'm still getting a -1 return.

  • ajyendra Profile Picture
    1,738 on at
    RE: Retrieve and update Product Line Item on a Quote

    Hi,

    Please Change this piece of code and try

    Remove this line

    FilterOperator = LogicalOperator.And,

    and ALSo Replace this line 

    var results = service.RetrieveMultiple(query);

    with 

    EntityCollection results = service.RetrieveMultiple(query);

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

🌸 Community Spring Festival 2025 Challenge Winners! 🌸

Congratulations to all our community participants!

Adis Hodzic – Community Spotlight

We are honored to recognize Adis Hodzic as our May 2025 Community…

Kudos to the April Top 10 Community Stars!

Thanks for all your good work in the Community!

Leaderboard > Customer experience | Sales, Customer Insights, CRM

#1
Daivat Vartak (v-9davar) Profile Picture

Daivat Vartak (v-9d... 225 Super User 2025 Season 1

#2
Muhammad Shahzad Shafique Profile Picture

Muhammad Shahzad Sh... 106 Most Valuable Professional

#3
Eugen Podkorytov Profile Picture

Eugen Podkorytov 87

Overall leaderboard

Product updates

Dynamics 365 release plans