views:

793

answers:

4

I need to write a plugin for Dynamics CRM 4.0 that executes when a closed opportunity is reopened in order to change the salesstagecode. My questions are:

  • When I register a new step to the plugin, what attribute(s) should I filter on?
  • What property on the entity should I check the value of? and
  • What should I look for the value of this entity to be so I can determine if the plugin execution should continue?

I've typically written asynchronous workflows and my experience writing plugins is still developing, so I'd appreciate any help and clarification that can be offered.

Please see below the plugin skeleton I've written

    public void Execute(IPluginExecutionContext context)
    {
        if (context.InputParameters.Properties.Contains("Target") && context.InputParameters.Properties["Target"] is DynamicEntity)
        {
            ICrmService service = context.CreateCrmService(false);

            DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties["Target"];

            if (entity.Name == EntityName.opportunity.ToString())
            {
                if (entity.Properties.Contains(/*What Property Should I Check Here?*/))
                {
                    //And what value should I be looking for in that property?

                }
            }
        }
    }
+1  A: 

You're going to want to set up the entity on the SetStateDynamic message. This doesn't provide a target, so instead you'll need to pull the EntityMoniker and manually retrieve the entity like this:

            // If this is a setstate call, we need to manually pull the entity
            if (context.InputParameters.Properties.Contains("EntityMoniker") &&
                    context.InputParameters.Properties["EntityMoniker"] is Moniker)
            {
                Moniker entity = (Moniker)context.InputParameters.Properties["EntityMoniker"];

                // get the entity
                TargetRetrieveDynamic targetRet = new TargetRetrieveDynamic();
                targetRet.EntityId = entity.Id;
                targetRet.EntityName = context.PrimaryEntityName;

                RetrieveRequest retrieveReq = new RetrieveRequest();
                retrieveReq.ColumnSet = new ColumnSet();
                retrieveReq.ColumnSet.AddColumns(new string[]{"opportunityid", "statecode", "statuscode"});
                retrieveReq.Target = targetRet;
                retrieveReq.ReturnDynamicEntities = true;

                RetrieveResponse retrieveRes = this.Service.Execute(retrieveReq) as RetrieveResponse;

                // Set the new entity and the status
                int status = (int)context.InputParameters["Status"];
                dynEntity = (DynamicEntity)retrieveRes.BusinessEntity;                                        
                dynEntity.Properties["statuscode"] = new Status(status);                      
            }
Focus
+4  A: 

I think you'll actually want to register a plugin for the post stage on the SetStateDynamicEntity message. You won't want any filtering attributes for this message.

Your code would look something like this:

public void Execute(IPluginExecutionContext context)
{
    string state = (string)context.InputParameters["State"];
    if (state == "Open")
    {
        Moniker entityMoniker = (Moniker)context.InputParameters["EntityMoniker"];
        DynamicEntity opp = new DynamicEntity("opportunity");
        opp["opportunityid"] = new Key(entityMoniker.Id);
        opp["salesstagecode"] = new Picklist(/*your value*/);
        context.CreateCrmService(true).Update(opp);
    }
}
Corey O'Brien
Microsoft recommend double-registering anything against both the SetState and SetStateDynamicEntity messages, as you can't always be sure which one will get fired.
Antony Gibbs
A: 

Here is what I ultimately arrived at. I will mark this as the correct answer but will give you both (Focus and Corey) an upvote when I'm able to upvote again because I incorporated suggestions from both of you to arrive at this solution.

    public void Execute(IPluginExecutionContext context)
    {
        if (context.InputParameters.Properties.Contains("Target") &&
            context.InputParameters.Properties["Target"] is DynamicEntity)
        {
            DynamicEntity opp = (DynamicEntity)context.InputParameters["Target"];
            Picklist StageCodePicklist = new Picklist(); (Picklist);opp.Properties["salesstagecode"];
            StageCodePicklist.name = "Advocating - Advanced (90%)";
            StageCodePicklist.Value = 200004;
            opp.Properties["salesstagecode"] = StageCodePicklist;
        }
    }
splatto
A: 

I'm newbie to CRM. Where must i put this code?

ghazalin