locked
Opportunity Item OnCreate error when trying to add a Bundle RRS feed

  • Question

  • I have plugins registered on the OnCreate event of Opportunities (OpportunityItemOnCreate.OnCreate: Create of opportunityproduct)

    When adding single products to the Opportunity all works fine.  However, when adding a bundle, the following error occurs: 
    <Message>CREATE ERROR:  If a bundle is selected as an existing product, you can't change it to another value.</Message>

    See my Plugin code below

    namespace OpportunityItemOnCreate
    {
        public class OnCreate : IPlugin
        {
            public void Execute(IServiceProvider serviceProvider)
            {
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
    
                 ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
                 tracer.Trace("Start IPlugin.execute");
                 if (context.Depth > 1) return;
                Entity OpportunityProduct = null;
    
    
                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    OpportunityProduct = (Entity)context.InputParameters["Target"];
                    
                    if (OpportunityProduct.LogicalName != "opportunityproduct")
                    {
                        return;
                    }
                }
                else
                {
                    return;
                }
    
                try
                {
    
                    if (OpportunityProduct.Contains("isproductoverridden"))
                    {
                        if ((Boolean)OpportunityProduct.Attributes["isproductoverridden"] == false)
                        {
                            IOrganizationService _orgService = factory.CreateOrganizationService(context.UserId);
    
                            /*
                             ********Add description to opportunity item***************
                             */
                            Decimal TotalPercentage = 0; /*Calculate the total Percentage for the product.  This needs to be pulled through to the order.*/
    
    
                            var ProductEntityReferenceValue = OpportunityProduct.GetAttributeValue<EntityReference>("productid");
                            ColumnSet attributes = new ColumnSet(new string[] { "name", "description", "prknc_autodeskdesignandcreationsuite", "productid", "price", "prknc_applybackendprofit", "prknc_profitmarginpercentage" });
    
                            Entity Product = _orgService.Retrieve("product", ProductEntityReferenceValue.Id, attributes);
    
    
                            string ProductDesc = Product.GetAttributeValue<string>("description");
                            var SuiteEntityReferenceValue = Product.GetAttributeValue<EntityReference>("prknc_autodeskdesignandcreationsuite");
    
                            string DescriptionItems = "";
                            if (SuiteEntityReferenceValue != null)
                            {
                                /*Retreive related suite items*/
                           //     prknc_sequencenumber
                                OrderExpression oe = new OrderExpression();
                                QueryExpression opportunityProductsQuery = new QueryExpression
                                {
                                    EntityName = "prknc_suiteitem",
                                    ColumnSet = new ColumnSet("prknc_suiteid", "prknc_name"),
                                    Criteria = new FilterExpression
                                    {
                                        Conditions = 
                                        {
                                            new ConditionExpression 
                                            {
                                                AttributeName = "prknc_suiteid",
                                                Operator = ConditionOperator.Equal,
                                                Values = { SuiteEntityReferenceValue.Id.ToString() }
                                            }
                                        }
                                    },
                                    Orders = { new OrderExpression
                                                {
                                                    AttributeName = "prknc_sequencenumber",
                                                    OrderType = OrderType.Descending
                                                }
                                    }
                                };
                                
                                
                             
    
    
                                DataCollection<Entity> suiteItems = _orgService.RetrieveMultiple(opportunityProductsQuery).Entities;
    
                                DescriptionItems += System.Environment.NewLine;
                                foreach (Entity Item in suiteItems)
                                {
                                    DescriptionItems += System.Environment.NewLine + Item["prknc_name"].ToString();
                                }
                            }
    
    
                         /*
                         *The Back End percentage to calculate the back end profit amount  
                         */
    
                            /******************************UPDATE PROFIT VARIABLES FROM XML FILE*************************/
                            XmlDocument VariableXMLdoc = new XmlDocument();/*XML document storing variables*/
                            VariableXMLdoc.Load(@"C:\Prokon\Plugins\variables.xml");
                            XmlNode varProfitPerc = VariableXMLdoc.SelectSingleNode("/Variables/variable[@name='BackEndProfitPercentage']");
                            int BackEndProfitPercentage = Convert.ToInt32(varProfitPerc.InnerText);
                            /********************************************************************************************/
    
                            /*Get OpportunityProduct basic values*/
    
                            //Attributes must exist
    
                            Money mPricePerUnit = null;
                            if (OpportunityProduct.Contains("priceperunit"))
                                mPricePerUnit = (Money)OpportunityProduct.Attributes["priceperunit"];
                            else
                            {
                                 /*Get the opportuniy*/
                                var OpportunityEntityReferenceValue = OpportunityProduct.GetAttributeValue<EntityReference>("opportunityid");
                                ColumnSet p_attributes = new ColumnSet(new string[] { "pricelevelid"});
                                Entity Opportunity = _orgService.Retrieve("opportunity", OpportunityEntityReferenceValue.Id, p_attributes);
    
                                /*Get the pricelist for the opportunity*/
                                var PriceListEntityReferenceValue = Opportunity.GetAttributeValue<EntityReference>("pricelevelid");
                                ColumnSet pl_attributes = new ColumnSet(new string[] { "pricelevelid","prknc_discountpricelist" });
                                Entity Pricelist = _orgService.Retrieve("pricelevel", PriceListEntityReferenceValue.Id, pl_attributes);
    
                                /*Get the Pricelist Product*/
                                 QueryExpression C_PricelistProductsQuery = new QueryExpression
                                    {
                                        EntityName = "productpricelevel",
                                        ColumnSet = new ColumnSet("pricelevelid", "productid", "amount"),
    
                                        Criteria = new FilterExpression
                                        {
                                            Conditions = 
                                                {
                                                     new ConditionExpression 
                                                    {
                                                        AttributeName = "pricelevelid",
                                                        Operator = ConditionOperator.Equal,
                                                        Values = {PriceListEntityReferenceValue.Id.ToString() }
                                                    },
                                                    new ConditionExpression 
                                                    {
                                                        AttributeName = "productid",
                                                        Operator = ConditionOperator.Equal,
                                                        Values = { ProductEntityReferenceValue.Id.ToString() }
                                                    }
    
                                                }
                                        }
                                    };
                                 DataCollection<Entity> c_pricelistproduct = _orgService.RetrieveMultiple(C_PricelistProductsQuery).Entities;
                                 mPricePerUnit = (Money)c_pricelistproduct[0]["amount"];
    
    
                            }
    
                            Decimal dPricePerUnit = mPricePerUnit.Value;
    
                            Decimal quantity = 1;
                            if (OpportunityProduct.Contains("quantity"))
                                 quantity = (Decimal)OpportunityProduct.Attributes["quantity"];
                            
                            Decimal baseAmount = dPricePerUnit * quantity;
    
    
                            /* 
                            * Update backend profit
                            */
                            Decimal dBackEndAmount = 0;
    
                            /*Get the product*/
                            var ProductReferenceValue = OpportunityProduct.GetAttributeValue<EntityReference>("productid");
                            Product = _orgService.Retrieve("product", ProductReferenceValue.Id, attributes);
    
                            /*Verify if Back End should be applied to the product*/
                            bool ApplyBackEnd = false; //Initialise
                            if (Product.Attributes.Contains("prknc_applybackendprofit")) //If the attribute have values assigned
                                ApplyBackEnd = (Boolean)Product.Attributes["prknc_applybackendprofit"]; //Get the value
    
                            if (ApplyBackEnd == true)
                            {
                                dBackEndAmount = dPricePerUnit * quantity * BackEndProfitPercentage / 100;
                                TotalPercentage += BackEndProfitPercentage;
                            }
                            OpportunityProduct["prknc_backendamount"] = new Money(dBackEndAmount);
    
    
                            /*
                             * Update frontend profit by margin
                             */
                            Decimal FrontEndPercentage = 0; //Initialise
    
                            if (Product.Attributes.Contains("prknc_profitmarginpercentage")) //If the attribute have values assigned         
                                FrontEndPercentage = (Decimal)Product.Attributes["prknc_profitmarginpercentage"]; //Get the value
    
                            OpportunityProduct["prknc_productprofitmargin"] = FrontEndPercentage;
                            Decimal subFrontEndAmount = baseAmount * FrontEndPercentage / 100;
                            OpportunityProduct["prknc_subfrontendprofit"] = new Money(subFrontEndAmount);
    
                            TotalPercentage += FrontEndPercentage;
                            /*
                             * Update New Customer Profit (NCP)
                             */
                            Decimal NCP_Profit = 0; //Initialise
                            OpportunityProduct["prknc_ncpprofit"] = new Money(NCP_Profit);
                            /*
                             * Calculate the total front end profit
                             */
                            Decimal totalFrontEnd = subFrontEndAmount + NCP_Profit;
                            OpportunityProduct["prknc_totalfrontendprofit"] = new Money(totalFrontEnd);
                            /*
                             * Add all the profit and update the total profit
                             */
                            Decimal TotalProductProfit = dBackEndAmount + totalFrontEnd;
                            OpportunityProduct["prknc_profit"] = new Money(TotalProductProfit);
                            /*
                             * Update the total percentage
                             */
                            OpportunityProduct["prknc_totalprofitpercentage"] = TotalPercentage;
                           
                            OpportunityProduct["prknc_lineitemdescription"] = ProductDesc + DescriptionItems;  
     
                            _orgService.Update(OpportunityProduct);
    
                        }
    
                    }
                    else
                    {
                        IOrganizationService _orgService = factory.CreateOrganizationService(context.UserId);
                        OpportunityProduct["prknc_lineitemdescription"] = OpportunityProduct["productdescription"];
                        _orgService.Update(OpportunityProduct);
                    }
                }
                catch (FaultException<OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("CREATE ERROR:  " + ex.Message);
                }
            }
        }
    }



    Christo Vermeulen

    Monday, July 13, 2015 9:04 AM