Thursday, February 28, 2013

Rollup 12 :- Pricelist Item error on Opportunity screen

In the latest roll-up 12 updates, I found an error message displaying on the opportunity screen for the missing price list. If your business not making use of the price list item an OOTB feature, one of the solution you can make use of to suppress the error message, is  by updating a price List Item using a Retrieve plugin. Keep in mind this needs to be configured as a Pre-event stage in the Plugin configuration tool. 

Code sample:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace Opportunity
{
    public class SetDefaultPriceList : IPlugin
    {
        public void Execute(IServiceProvider sp)
        {
            //--Trigger: Retrieve Message of opportunity
            //--Stage: Pre
            //--Method: Synchronous
            //--Filter Attributes: none
            //--Pre Attributes: none
            //--Post Attributes: none
            //--Description: Setting the the default PriceList value.
            //--Author: Chaitanya

            var tracer = (ITracingService)sp.GetService(typeof(ITracingService));
            var context = (IPluginExecutionContext)sp.GetService(typeof(IPluginExecutionContext));

            if (context.MessageName == "Retrieve" && context.PrimaryEntityName == "opportunity")
            {
                var factory = (IOrganizationServiceFactory)sp.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = factory.CreateOrganizationService(null);

                Guid priceListId = Guid.Empty;

                var priceListsEntity = GetDefaultPriceLevel(service);
                if(priceListsEntity.Entities.Count > 0)
                    if(priceListsEntity.Entities[0].Attributes.Count > 0)
                        if(priceListsEntity.Entities[0].Attributes.Contains("pricelevelid"))
                            priceListId = (Guid)priceListsEntity.Entities[0].Attributes["pricelevelid"];
                   if(priceListId != Guid.Empty)
                   {
                       var opportunity = new Entity(context.PrimaryEntityName) { Id = context.PrimaryEntityId };
                       opportunity.Attributes.Add("pricelevelid", new EntityReference("pricelevel",priceListId));
                       service.Update(opportunity);
                   }
            }
        }

        private static EntityCollection GetDefaultPriceLevel(IOrganizationService service)
        {
            var cols = new ColumnSet("pricelevelid", "name");
            var filter = new FilterExpression { FilterOperator = LogicalOperator.And };
            filter.AddCondition(new ConditionExpression("name", ConditionOperator.Equal, new object[] { "Default Price List" }));

            var query = new QueryExpression
            {
                ColumnSet = cols,
                Criteria = filter,
                EntityName = "pricelevel"
            };
            return service.RetrieveMultiple(query);
        }
    }
}
One more thing to keep in mind, Before running this code, you should have a "Default Price List" created with the same name. 

Hope this helps, 
Chaitanya...

3 comments:

Anonymous said...

I have noticed the same error.
Thank you for this solution

Anonymous said...

This is exactly the solution I am looking for. But I am not a programmer so I am struggling with the implementation. Can you provide more detailed guideance to get this working?

Many thanks

Chaitanya... said...

Hello,

Steps are very simple, but you should know how to create a plugin and register them using the plugin registration tool.

I will try to provide you with the steps to do this, but, I am not sure how easy it is follow if you are not a programmer. Give it a try!!!

Following are the steps:
1) Create a pricelist item with the same name "Default Price List" record in CRM

2) Create a Visual studio Class Library project

3) Add "Microsoft.Crm.Sdk.Proxy" and "Microsoft.Xrm.Sdk" dlls from your SDK bin folder in to the visual studio References folder
4) Add "System.Runtime.Serialization" dll from the .Net (tab)

NOTE: For doing 3 and 4 you should right click on the References folder of a visual studio project and select add References.

For point 3) Use browse option to locate the SDK bin DLL's

For point 4) Use .Net tab to locate the dll

5) Rightclick on the Visiual studio project and go to properties and sign the assembly

6) Add the class file calles "SetDefaultPriceList" and paste the code as in the sample above.

7) Build the project and register the plugin on a "Retrieve" message

Let me know, if you need further help on this?

Thanks,
Chaitanya...