locked
CRM 2011 - Plugin for Opportunity Close RRS feed

  • Question

  • Hi All,

    I need your help on below mentioned scenario for Plugin development. We are on CRM 2011 on-premise UR 18.

    Scenario: When end user close the opportunity as 'Lost', dialog box comes up asking for the close date, competitor,description and couple of other fields. Our requirement is that end user need to put reason for the 'Lost' opportunity into the "Description" field. If they don't put anything into that field than throw error to user informing that description is required.

    so I have written below very basic plugin:

        public class OpportunityLost : IPlugin
         {
             public void Execute(IServiceProvider ServiceProvider)
            {
                 IPluginExecutionContext context = (IPluginExecutionContext)ServiceProvider.GetService(typeof(IPluginExecutionContext));
                 IOrganizationService service = GetserviceClass.GetCRMService(ServiceProvider);
                 string description = "";
            
                 if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                 {
                     Entity OppClose = (Entity)context.InputParameters["Target"];
                                   
                     if (OppClose.LogicalName.ToLower() != "opportunityclose")
                     {
                         return;
                     }
                      try
                     {
                             description = OppClose.GetAttributeValue<string>("description");
                             if (description == null || description == string.Empty)
                             {
                                 throw new InvalidPluginExecutionException("Please enter reson for lost opportunity in description field");
                             }
                         
                     }
                     catch (FaultException<OrganizationServiceFault> ex)
                     {
    
                        throw new InvalidPluginExecutionException("An error occurred in the Lost Opportunity plug-in", ex);
                     }
    
                }
             }
         }


    Plug in is registered with below settings.

    Message : Create

    Entity : opportuityclose

    Secondary Entity : none

    Event Pipeline : Pre-Operation

    Execution Mode : Synchronous

    This plugin is firing fine but it fires on both "Lost" and "Won" opportunity scenario. We want this plugin to fire only when

    opportunity is Lost.

    Please note that Win and Lost messages won't work here as I won't be able to get 'description' field of the "Opportunityclose" dialog box. Context and entity images are not giving me anything useful (Correct me if I am wrong here ).

    Is there anyone out there who has faced the similar situation who can help me to overcome this issue.

    Thanks for reading.

    Regards,

    H.desai




    • Edited by H.Desai Tuesday, March 17, 2015 10:21 PM
    Tuesday, March 17, 2015 10:18 PM

Answers

  • Hi Desai,

    The above code should be registered in “LOSE” message of Opportunity entity not for OpportunityClose Entity. This Plugin worked in my organization.

    In Lose message we can only get two inputparameters are,

    1.       OpportunityClose ( (Entity)context.InputParameters["OpportunityClose"];)
    2.       Status (OptionSetValue)context.InputParameters["Status"];  

    Directly we can’t get the OPPORTUNITY  entity from LOSE message INPUTPARAMETER.

    I’m just retrieving Status value from INPUTPARAMETER and i'm not using it.

    Debug your plugin to find the problem. step by step debug plugin link

    Post your entire plugin code and registration steps here.


    • Edited by Gugan A Thursday, March 19, 2015 6:11 AM
    • Marked as answer by H.Desai Thursday, March 19, 2015 8:26 PM
    Thursday, March 19, 2015 6:09 AM

All replies

  • Hi Desai,

           You can use LOSE message to achieve your scenario.

           You can get the description field value in lose message

           Use below code for your scenario using LOSE message

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

                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

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

                Entity OppClose = (Entity)context.InputParameters["OpportunityClose"];

                OptionSetValue status = (OptionSetValue)context.InputParameters["Status"];

                try

                {

                    if (!OppClose.Contains("description"))

                    {

                        throw new InvalidPluginExecutionException("Please enter reson for lost opportunity in description field");

                    }

                    else if(OppClose.Contains("description"))

                    {

                        string description = OppClose.GetAttributeValue<string>("description");

                        if((description==string.Empty) || (description==null))

                        {

                            throw new InvalidPluginExecutionException("Please enter reson for lost opportunity in description field");

                        }

                    }

                       

                }

                catch(Exception ex)

                {

                    throw new InvalidPluginExecutionException(ex.Message);

                }

    Plugin Registration Steps:

    Message : Lose

    Entity : opportunity

    Secondary Entity : none

    Event Pipeline : Pre-Operation

    Execution Mode : Synchronous

    Wednesday, March 18, 2015 6:44 AM
  • You can do this with a plugin as Gugan A has proposed, but have you considered using some Javascript on the Opportunity form and running code on the 'OnSave' event?  You can test of the description field is blank, then throw a javascript alert telling them it is a required field to fill in before they save it.

    if (Xrm.Page.getAttribute('description').getValue() == null || Xrm.Page.getAttribute('description').getValue() == "") {
      alert("WARNING:\nThere is no DESCRIPTION ");
      ExecutionObj.getEventArgs().preventDefault(); // This prevents the record from being saved
    }



    • Edited by Chris_Harrington Wednesday, March 18, 2015 1:40 PM
    • Marked as answer by H.Desai Thursday, March 19, 2015 8:26 PM
    • Unmarked as answer by H.Desai Thursday, March 19, 2015 9:30 PM
    Wednesday, March 18, 2015 1:39 PM
  • Hi Gugan,

    Thanks for your reply but unfortunately, that code did not worked. (Plugin not firing at all)

    In your code, you are accessing opportunityclose entity from context but in the plugin registration you are using Opportunity entity which I think reason for not firing your code.

    I have tried changing it to opportunityclose entity but Lose message is not supported for this entity.

    Also, I can see that in your code you are getting status value but not using anywhere.

    Any suggestion ?

    @Chris: thanks for your input but I want to access description field from OpportunityClose dialog box and not from the Opportunity entity itself. Therefore you won't get correct attribute in your JavaScript.

    EDIT : I have tried to access statecode attribute but it gives me statecode of 'Opportunity Close' entity and not Opportunity entity. Description value is coming Ok as per my original post.

    Entity OppClose = (Entity)context.InputParameters["Target"];
                
     int statecode = OppClose.GetAttributeValue<OptionSetValue>("statecode").Value;
    
     if (OppClose.LogicalName.ToLower() != "opportunityclose")
                    {
                        return;
                    }
    
                    if (statecode != 2) // 2 = lost.
                    {
                        return;
                    }

    Thanks,

    H.desai



    • Edited by H.Desai Wednesday, March 18, 2015 10:22 PM
    Wednesday, March 18, 2015 8:35 PM
  • Hi Desai,

    The above code should be registered in “LOSE” message of Opportunity entity not for OpportunityClose Entity. This Plugin worked in my organization.

    In Lose message we can only get two inputparameters are,

    1.       OpportunityClose ( (Entity)context.InputParameters["OpportunityClose"];)
    2.       Status (OptionSetValue)context.InputParameters["Status"];  

    Directly we can’t get the OPPORTUNITY  entity from LOSE message INPUTPARAMETER.

    I’m just retrieving Status value from INPUTPARAMETER and i'm not using it.

    Debug your plugin to find the problem. step by step debug plugin link

    Post your entire plugin code and registration steps here.


    • Edited by Gugan A Thursday, March 19, 2015 6:11 AM
    • Marked as answer by H.Desai Thursday, March 19, 2015 8:26 PM
    Thursday, March 19, 2015 6:09 AM
  • Hi Gugan,

    Thank you very much for this explanation and your help. Your suggestion is working now. I was doing wrong by firing the plug-in for Opportunity Close entity on 'Create' message based on my understanding that I should get both Opportunity status and description from OpportunityClose activity. (which gets created once Opportunity is closed). Did not know that OpportunityClose entity can be accessed through input parameter while plugin is registered for Opportunity. ( I must have missed this value while debugging)

    Appreciate your time and follow ups.

    Regards,

    H.desai




    • Edited by H.Desai Thursday, March 19, 2015 8:40 PM
    Thursday, March 19, 2015 8:32 PM
  • Perfect Gugan! You're the man. Thumbs up!!
    Friday, July 24, 2015 10:36 AM