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)

Add quote products via a plugin

(0) ShareShare
ReportReport
Posted on by

Hi all.

I was playing around trying to add products to a quote with a workflow. I have basically copied a workflow i use in the pricelists and tried to modify it to work. Not quite sure what i'm missing so any help would be great. My current code is below. I get the sense i'm not correctly calling the quotedetail right to add the products. I idea is that in the quote entity i will have option boxes yes/no to add various groups of product to the quotes to speed up the creation.

public class Quoteproducts : CodeActivity
{

protected override void Execute(CodeActivityContext executionContext)
{


//Create the tracing service
ITracingService tracingService = executionContext.GetExtension<ITracingService>();

//Create the context
IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

// Create a column set to define which attributes should be retrieved.
ColumnSet attributes = new ColumnSet(true);

Entity currentPriceLevelEntity = new Entity("quote");
currentPriceLevelEntity = service.Retrieve("quote", CurrentQuote.Get<EntityReference>(executionContext).Id, attributes);

// Create New Price List
Entity newPriceLevel = new Entity("quote");
//newPriceLevel.Id = Guid.Parse(quotedetailId.Get<string>(executionContext));
// newPriceLevel["name"] = NewPriceListName.Get<string>(executionContext);
// newPriceLevel["sb_fpaid"] = Contractor.Get<string>(executionContext);
// newPriceLevel["sb_manholerun"] = manholerun.Get<int>(executionContext);
// newPriceLevel["transactioncurrencyid"] = currentPriceLevelEntity["transactioncurrencyid"];
service.Update(newPriceLevel);

newPriceLevel["MH900"] = MH900.Get<string>(executionContext);

// Get current product price level
QueryExpression productPriceLevelExpression = new QueryExpression("quotedetail");

FilterExpression productPriceLevelFilterExpression = new FilterExpression();
productPriceLevelFilterExpression.Conditions.Add(new ConditionExpression("quoteid", ConditionOperator.Equal, currentPriceLevelEntity["quoteid"]));

productPriceLevelExpression.ColumnSet = new ColumnSet(true);
productPriceLevelExpression.Criteria = productPriceLevelFilterExpression;

EntityCollection productPriceLevelList = service.RetrieveMultiple(productPriceLevelExpression);

// Create new product price level records
for (int index = 0; productPriceLevelList.Entities != null && index < productPriceLevelList.Entities.Count; index++)
{
Entity newProductPriceLevelEntity = new Entity("quotedetail");
// newProductPriceLevelEntity["pricelevelid"] = new EntityReference("pricelevel", newPriceLevel.Id);
// newProductPriceLevelEntity["productid"] = productPriceLevelList.Entities[index]["productid"];
newProductPriceLevelEntity["productnumber"] = "F0900 TAG VMHS F";
Guid guid = new Guid();
newProductPriceLevelEntity.Id = guid;

service.Create(newProductPriceLevelEntity);


}

}

private void mbox()
{
throw new NotImplementedException();
}

//Define the properties

[RequiredArgument]
[Input("Current Quote")]
//[ReferenceTarget("quote")]
public InArgument<string> CurrentQuote { get; set; }


[Input("MH900 : MH900")]
public InArgument<string> MH900 { get; set; }

Regards

Dan

*This post is locked for comments

I have the same question (0)
  • Suggested answer
    ashlega Profile Picture
    34,477 on at

    Hi Dan,

     not sure what's happening there, but I see a couple of things:

    - These two lines are in reverse order:

    service.Update(newPriceLevel);

    newPriceLevel["MH900"] = MH900.Get<string>(executionContext);

    Although, I'm not sure what MH900 stands for - I don't think there is such attribute name

    - In the for loop, you have to link your new quote detail to the quote. For example:

    newProductPriceLevelEntity["quoteid"] = currentPriceLevelEntity.Id;

    BTW, most of the times you don't need to create GUID-s yourself - CRM will do it for you, so you might simply remove these two lines inside the for loop:

    Guid guid = new Guid();

    newProductPriceLevelEntity.Id = guid;

    Also, you might want to rename some of the variables there to make those names consistent with what the code is, actually, doing.. just so it would be easier to read.

  • Rajat Awasthi Profile Picture
    675 on at

    Hi Dandare ,

    QuoteLine Items will be added to Quote Product Subgrid.

  • Community Member Profile Picture
    on at

    Hi Thank you for response. The MH900 is a field in the quote that will either have a yes or no in it. That i will do a if = yes then add certain products.

    The error i'm currently getting is .Quoteproducts: System.NullReferenceException: Object reference not set to an instance of an object.</Message>.

    I will have a play and make the changes you have suggested and see if it helps

    Thank you

    Dan

  • Community Member Profile Picture
    on at

    Hi

    I have made them changes but something is still missing the error i get when running is

    Business Process Error

    Unexpected exception from plug-in (Execute): StantonBonna.Quoteproducts: System.NullReferenceException: Object reference not set to an instance of an object

    The code now looks like

       public class Quoteproducts : CodeActivity

       {

           protected override void Execute(CodeActivityContext executionContext)

           {

               //Create the tracing service

               ITracingService tracingService = executionContext.GetExtension<ITracingService>();

               //Create the context

               IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();

               IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();

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

               // Create a column set to define which attributes should be retrieved.

               ColumnSet attributes = new ColumnSet(true);

               Entity CurrentQuoteEntity = new Entity("quote");

               CurrentQuoteEntity = service.Retrieve("quote", CurrentQuote.Get<EntityReference>(executionContext).Id, attributes);

               // Create New Price List

               Entity newquote = new Entity("quote");

               newquote["MH900"] = MH900.Get<string>(executionContext);

               service.Update(newquote);

               // Get current product price level

               QueryExpression QuoteproductsExpression = new QueryExpression("quotedetail");

               FilterExpression QuoteproductsFilterExpression = new FilterExpression();

               QuoteproductsFilterExpression.Conditions.Add(new ConditionExpression("quoteid", ConditionOperator.Equal, CurrentQuoteEntity["quoteid"]));

               QuoteproductsExpression.ColumnSet = new ColumnSet(true);

               QuoteproductsExpression.Criteria = QuoteproductsFilterExpression;

               EntityCollection QuoteproductsList = service.RetrieveMultiple(QuoteproductsExpression);

               // Create new product price level records

               for (int index = 0; QuoteproductsList.Entities != null && index < QuoteproductsList.Entities.Count; index++)

               {

                   Entity newQuoteproductsEntity = new Entity("quotedetail");

                   newQuoteproductsEntity["productnumber"] = "F0900 TAG VMHS F";

                                  service.Create(newQuoteproductsEntity);

               }

           }

           private void mbox()

           {

               throw new NotImplementedException();

           }

           //Define the properties

           [RequiredArgument]

           [Input("Current Quote")]

           //[ReferenceTarget("quote")]

           public InArgument<string> CurrentQuote { get; set; }

           [Input("MH900 : MH900")]

           public InArgument<string> MH900 { get; set; }

       }

    Regards

    Dan

  • ashlega Profile Picture
    34,477 on at

    Hi Dan,

     MH900 must be a custom field, then. You can't use the display name there - have to use the schema name (something like "new_mh900"). It's not failing there, though, because you have switched the linees (you run the update before you assign that field)

     As for the NullReference, it could be because there is no quoteid in the quotedetail record now (try adding it)

     Also, I just noticed you are doing this in the loop:

     newProductPriceLevelEntity["productnumber"] = "F0900 TAG VMHS F";

     But there is no productnumber field in the quotedetail entity.

  • ashlega Profile Picture
    34,477 on at

    You still did not set quoteid in the loop.

    If that does not help either, try adding "return;" somewhere in the middle of your code, then move it up or down till it stops failing.. you'll find the line that's failing - post it here so we could see. It should only take a few attempts.

  • Community Member Profile Picture
    on at

    the quoteid could i change to productname. I have changed the productnumber to productname which does exist. I think my plan with the quoteid was to create a field in the quote with the quote guid

    Regards

    Dan

  • Community Member Profile Picture
    on at

    Hi

    after doing what you recommended the return; the issue seems really early on when i'm trying to reference the quote. I narrowed it down to these lines

    Entity CurrentQuoteEntity = new Entity("quote");

              CurrentQuoteEntity = service.Retrieve("quote", CurrentQuote.Get<EntityReference>(executionContext).Id, attributes);

    I think it's something to do with the currentquoteget. i do have a field within the quote which is populated with the guid

    regards

    dan

  • ashlega Profile Picture
    34,477 on at

    Ah.. ok. You inputparameter for the CurrentQuote is of the "string" type. Should be an EntityReference. There is an example here (and you should define the reference target as well for that parameter):

    msdn.microsoft.com/.../gg327842.aspx

  • Community Member Profile Picture
    on at

    Hi Thanks for that. I have set that up as such

           [RequiredArgument]

           [Input("Current Quote")]

           [ReferenceTarget("quote")]

           public InArgument<EntityReference> CurrentQuote { get; set; }

    but when i setup the work flow it is asking me the name of a quote. I want that quote to be the current quote i am on if that makes sense

    Regards

    Dan

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