locked
Dynamics 365 Plug-in to create opportunity product RRS feed

  • Question

  • I have a plug-in that is registered on the post create event of an opportunity.  I want to create an opportunity product line using the value that is in a lookup to product on the opportunity form. My debugger is not working (I keep getting the following error when downloading the profile in the plug-in registration tool:

    Unhandled Exception: System.ArgumentException: Unable to parse the OrganizationServiceFault.
    Parameter name: serializedReport
       at PluginProfiler.Library.ProfilerUtility.ExtractReport(String serializedReport)
       at PluginProfiler.Library.ProfilerUtility.DeserializeProfilerReport(String assemblyFilePath, String logFilePath, Boolean isCrmDataStream)
       at PluginProfiler.Library.ProfilerExecutionUtility.RetrieveReport(String logFilePath, Boolean isCrmDataStream)
       at Microsoft.Crm.Tools.PluginRegistration.CommonControls.Helper.ParseReportOrShowError(Window window, FileBrowserView profilePathControl, Boolean requireReportParse, ProfilerPluginReport& report)
    Inner Exception: System.InvalidOperationException: Message does not contain a serialized value.
       at PluginProfiler.Library.ProfilerUtility.ExtractReportFromFault(OrganizationServiceFault fault)
       at PluginProfiler.Library.ProfilerUtility.ExtractReport(String serializedReport)

    Anyway, this is making my issue difficult to debug. When I call service.RetrieveMultiple, it works fine. When I copy in code from the MS examples, and create a task activity, that also works - so service.Create works. However, when I try to create an opportunity product, it does not work. Here is my code:

    using Microsoft.Xrm.Sdk;
    using Microsoft.Xrm.Sdk.Client;
    using Microsoft.Xrm.Sdk.Query;
    using MyCo.CRM.Proxy;
    using MyCo.CRM.MyCoSdk;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.ServiceModel;
    using System.ServiceModel.Description;
    
    using Microsoft.Crm.Sdk.Messages;
    using Microsoft.Xrm.Sdk.Discovery;
    
    
    namespace MyCo.CRM.Plugins
    {
        public class OpportunityCreate_CreatePrimaryOppProdLine : PluginBase, IPlugin
        {
           
            public void Execute(IServiceProvider serviceProvider)
            {
                #region
                // Get product data from Opp 
                // Create opportunity product line using that product
                // Mark it as the primary product 
                // Register on post create            
                try
                {
                    StackTrace st = new StackTrace(new StackFrame(true));
    
                    Guid id = new Guid("9d37a1fe-xxxx-xxxx-xxx-00155d016f85");
                    CRMSdkHelper helper = new CRMSdkHelper(serviceProvider, id);
                   
                    #region
                    // Obtain the execution context from the service provider.
                    IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                    // Obtain the organization service reference.
                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(id);
                    
                    if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                    {
                        // Obtain the target entity from the input parameters.
                        Entity entity = (Entity)context.InputParameters["Target"];
    
                        // Verify that the target entity represents an opportunity.                   
                        if (entity.LogicalName != "opportunity")
                            return;
    
                        #region Get entity data
                        try
                        {
                            EntityReference myProduct = new EntityReference("product");
                            myProduct = (EntityReference)(entity.Contains("str_product") ? entity["str_product"] : ((entityIn.Contains("str_product") ? entityIn["str_product"] : null)));
    
                            if (myProduct != null)
                            {
                                // Get any existing primary opp product records
                                QueryExpression getExistingPrimaryOppProdLine = new QueryExpression();
    
                                getExistingPrimaryOppProdLine.EntityName = "opportunityproduct";
                                ConditionExpression condition1 = new ConditionExpression("str_primaryopportunityproduct", ConditionOperator.Equal, "true");
                                ConditionExpression condition2 = new ConditionExpression("productid", ConditionOperator.Equal, myProduct.Id);
                                getExistingPrimaryOppProdLine.Criteria.AddCondition(condition1);
                                getExistingPrimaryOppProdLine.Criteria.AddCondition(condition2);
                                EntityCollection existingPrimaryOppProd = service.RetrieveMultiple(getExistingPrimaryOppProdLine);
                                if (existingPrimaryOppProd.Entities.Count < 1)
                                {
                                    Guid unitId = new Guid("8b6424d8-xxxx-xxxx-xxxx-6a5ca0b75519");
                                    // Create an opportunity product 
                                    OpportunityProduct newOpportunityProduct1 = new OpportunityProduct
                                    {
                                        OpportunityId = new EntityReference(Opportunity.EntityLogicalName, entity.Id),
                                        ProductId = new EntityReference(Product.EntityLogicalName, myProduct.Id),
                                        UoMId = new EntityReference(UoM.EntityLogicalName, unitId),
                                        Quantity = 3,
                                        Tax = new Money(4.80m)
                                    };
                                    Guid _opportunityProduct1Id = new Guid();
                                    _opportunityProduct1Id = service.Create(newOpportunityProduct1);
                                    
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            tracingService.Trace(ex.Message);
                        }
                        #endregion
    
                    }
                }
                catch (Exception ex)
                {
                    tracingService.Trace("Could not create Opportunity Product line, detail:" + ex.Message);
                }
                #endregion
            }
    
           
        }
    }
    

    And here is the error I get:

    Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Unexpected exception from plug-in (Execute): MyCo.CRM.Plugins.OpportunityCreate_CreatePrimaryOppProdLine: System.NullReferenceException: Object reference not set to an instance of an object.Detail: 
    <OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
      <ActivityId>566c07d9-1041-4766-b340-2316573a2cc5</ActivityId>
      <ErrorCode>-2147220956</ErrorCode>
      <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
      <Message>Unexpected exception from plug-in (Execute): MyCo.CRM.Plugins.OpportunityCreate_CreatePrimaryOppProdLine: System.NullReferenceException: Object reference not set to an instance of an object.</Message>
      <Timestamp>2017-07-14T16:42:36.0654064Z</Timestamp>
      <ExceptionSource i:nil="true" />
      <InnerFault i:nil="true" />
      <OriginalException i:nil="true" />
      <TraceText>
    
    [MyCo.CRM.Plugins: MyCo.CRM.Plugins.OpportunityCreate_CreatePrimaryOppProdLine]
    [3461229c-7c68-e711-80c1-00155d016f85: MyCo.CRM.Plugins.OpportunityCreate_CreatePrimaryOppProdLine: Create of opportunity]
    
    
    </TraceText>
    </OrganizationServiceFault>
    

    If I comment out the create, there is no error. So I think there is something wrong with the opportunity product object I am creating. I have used some hard coded values in there to check a few values. entity.Id and myProduct.Id have guid values.

    Thanks.

    Friday, July 14, 2017 4:45 PM

All replies

  • Hello,

    What's the meaning of following 2 lines:

    Guid id = new Guid("9d37a1fe-xxxx-xxxx-xxx-00155d016f85");
    IOrganizationService service = serviceFactory.CreateOrganizationService(id);


    Try following instead and it should work:

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

    or

    IOrganizationService service = serviceFactory.CreateOrganizationService(null);



    Dynamics CRM/Business Solutions MVP
    Read My blog

    Friday, July 14, 2017 5:28 PM
    Moderator
  • Not that this will solve your problem, but I would suggest letting CRM set the GUID itself - i.e. remove this line:

    Guid _opportunityProduct1Id = new Guid();

    Friday, July 14, 2017 7:33 PM
  • I was trying to make sure that there was actually a value for the user id. As I was getting the 'object reference not set to an instance of an object'' error, I was trying to pin point what item was causing that error. I'll try your suggestion, thanks
    • Edited by MOTO1978 Saturday, July 15, 2017 9:29 AM
    Saturday, July 15, 2017 9:28 AM
  • Thanks for the suggestions. I tried them both, but I am still getting the 'Object reference not set to an instance of an object' error when I uncomment the service.Create(newOpportunityProduct1)

    When I uncomment the create call above, the opportunity gets created fine (this plugin is called on the creation of an opportunity), and I can write out other log messages. By doing this, I have been able to check the values in all the lds used to create the opportunity product object before actually calling the service.create to create the record in CRM. They are all valid values. So I don't know which field/what object/line of code is causing the error.

    As my debugger is not working (I've already tried to fix that, to no avail), does anyone have any other ideas? Or can anyone see any issues with my code?

    Thanks.

    Friday, July 21, 2017 2:43 PM
  • What is happening with the debugger?

    In a situation like this I would consider starting with a console app where I have full control of the debugging. You might want to start with creating a hard-coded Opportunity Product in the console app. You might also want to check if there are any other required fields on the Opp Product.

    Friday, July 21, 2017 4:28 PM