2
votes

REFORMULATED QUESTION (Apr 24):

I am using the CRM Developer Toolkit for VS2012 to create a CRM2011 plugin. The plugin is registered for the CREATE message of the "Invoice Product" entity. Pipeline-Stage is post-operational, execution is synchronous. I register for a post image that contains baseamount.

The toolkit creates an execute function that looks like this:

protected void ExecutePostInvoiceProductCreate(LocalPluginContext localContext)
{
    if (localContext == null)
    {
        throw new ArgumentNullException("localContext");
    }

    IPluginExecutionContext context = localContext.PluginExecutionContext;

    Entity postImageEntity = (context.PostEntityImages != null && context.PostEntityImages.Contains(this.postImageAlias)) ? context.PostEntityImages[this.postImageAlias] : null;
}

Since we are in post operational stage, the value of baseamount in postImageEntity should already be calculated from the user input, right? However, the value of baseamountin the postImageEntity is zero. The same holds true for the value of baseamount in the target entity that I get using the following code:

Entity targetEntity = (context.InputParameters != null && context.InputParameters.Contains("Target")) ? (Entity)context.InputParameters["Target"] : null;

Using a retrieve request like the one below, I am getting the correct value of baseamount:

Entity newlyCreated = service.Retrieve("invoicedetail", targetEntity.Id, new ColumnSet(true));
decimal baseAmount = newlyCreated.GetAttributeValue<Money>("baseamount").Value;

The issue does not appear in post operational stage of an update event.

I'd be glad to hear your ideas/explanations/suggestions on why this is the case...

(Further information: Remote debugging, no isolation mode, plugin stored in database)

Original Question:

I am working on a plugin for CRM 2011 that is supposed to calculate the amount of tax to be paid when an invoice detail is created. To this end I am trying to get the baseamount of the newly created invoicedetail entity from the post entity image in post operational stage. As far as I understood it, the post entity image is a snapshot of the entity in the database after the new invoice detail has been created. Thus it should contain all properties of the newly created invoice detail.

I am getting a "postentityimages" property of the IPluginExecutionContext that contains an entity with the alias I registered ("postImage"). This "postImage" entity contains a key for "baseamount" but its value is 0. Can anybody help me understand why this is the case and what I can do about it?

(I also noticed that the postImage does not contain all but only a subset of the entities I registered for.)

Here is what the code looks like:

  protected void ExecutePostInvoiceProductCreate(LocalPluginContext localContext)
  {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }

        // Get PluginExecutionContext to obtain PostEntityImages
        IPluginExecutionContext context = localContext.PluginExecutionContext;

        // This works: I get a postImage that is not null.
        Entity postImage = (context.PostEntityImages != null && context.PostEntityImages.Contains(this.postImageAlias)) ? context.PostEntityImages[this.postImageAlias] : null;

        // Here is the problem: There is a "baseamount" key in the postImage 
        // but its value is zero!
        decimal baseAmount = ((Money)postImage["baseamount"]).Value;

  }

ADDITION: Pre and post images for post operational update contain non-zero values for baseamount.

3
Are you debugging locally to figure out the value?Daryl
No, I am debugging remotely using the "Attach to process..." from the Debug menu. By the way, I am getting the correct value of "quantity" in the debugger but "baseamount" is zero.Olli
Either the value is getting set to 0 by some other plugin, or not getting set to something else. Since you're debugging it, do a simple retrieveEntity request to get the newly created record, and check for it's baseamount just to see if the PostImage is some how wrong, or something else is changing the value to 0 when the plugin runs.Daryl
I retrieved the newly created record in the following way: Entity newlyCreated = service.Retrieve("invoicedetail", targetEntity.Id, new ColumnSet(true)); In newlyCreated the value of baseamount is correct. Thus there is something wrong with the PostImage, I guess.Olli
Is the value correct on the Target?Daryl

3 Answers

1
votes

Three things of note, one hopefully will resolve your issue, the other two are a best practice.

  1. The post images attributes will only be populated with the values that you've specified to be populated with when you register it, so check that you've specified that the baseamount should be included in your post image. (you could also have a security issue if the user doesn't have rights to that field, but since it's 0 and not null, I would assume that this isn't the issue)
  2. Use GetAttributeValue, rather than just accessing the index off of the entity. If the string key isn't in the entity Attribute collection, you'll throw an error:

    decimal baseAmount = e.GetAttributeValue("baseamount").Value;

  3. Since this is running on the create of an invoice detail, the target should contain all of the data populated during the create, which would eliminate the need for the post-image.
0
votes

You can create a simple plugin by using following code.. reference here

public void Execute(IServiceProvider serviceProvider)
    {
        // Obtain the execution context from the service provider.
        ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

        // Obtain the execution context from the service provider.
        IPluginExecutionContext context = (IPluginExecutionContext)
            serviceProvider.GetService(typeof(IPluginExecutionContext));

        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

        // The InputParameters collection contains all the data passed in the message request.
        if (context.InputParameters.Contains("Target") &&
            context.InputParameters["Target"] is Entity)
        {
            Entity entity = (Entity)context.InputParameters["Target"];

            // Verify that the target entity represents an account.
            // If not, this plug-in was not registered correctly.
            if (entity.LogicalName != "account")
                return;

            try
            {

                     //Access / get data of entity
                     string country = entity.Attributes.ContainsKey("address1_county") ? entity.Attributes["address1_county"].ToString() : "";
                     //Update existing values in entity (Account)
                     entity.Attributes["name"] = "My Name"

            }

            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException(ex.Message + ", Stack trace : " +  ex.StackTrace);
            }

        }
    }
0
votes

Just to close this issue: In the end, I re-installed the CRM instance on the server and the problem was gone.