Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Dynamics 365 general forum

Dynamics 365 CRM Online - Plugin Only Performs Update Every Other Time it is Triggered

(0) ShareShare
ReportReport
Posted on by Microsoft Employee

Yesterday, I realized the error in my ways of not using a PreImage to get the values that were not being included in the updated attributes collection - SCORE! Now, the plugin works, but it only works every other time I trigger the plugin.

So, it seems the plugin is actually firing (I can see the plugin profile in Settings > plugin profiles), but is not performing the update that I need, until I trigger the plugin a second time. This seems to happen on all 3 attributes that I am listening for, and each of the attributes will need to be updated twice (as in, if I update Attribute 1, plugin doesn't update my value, if I then update attribute 2, plugin still doesn't update my value, until I re-update Attribute 1 or Attribute 2 again). As I profile/debug my code and step through it, I can see that the if statements are being hit, and the line of code that updates the entity field is also being executed - but for whatever reason, it does not set the value (CLIENT_nteexceeded = true or false) until I trigger it for the second time. It would make a lot more sense if it just didn't update the entity record value at all, and I was missing some type of an 'update' message (I have played with service.Entity.Update() but it does not seem to apply to this plugin)

I am still relatively new to CRMDEV, so please excuse the silly question. This just seems like a really silly issue to me, and it's gotta be something small that I'm missing. Any thoughts as to why this is forcing me to trigger the code twice to get the update executed?

Here is the config of the plugin step. The three filter attributes are those referenced in the code. Again, plugin works fine, just doesn't update the record every time. 

PluginReg.PNG

Code Below (with references to Client's name removed)

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
using System.ServiceModel;
using System.Data.SqlClient;
using System.Threading.Tasks;

namespace CLIENTNTE
{
    public class NTEExceedance : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);
            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            Money subtotal = null;
            Money nte = null;
            Decimal nte_percent = 0;
            Decimal subtotalDecimal = 0;
            Decimal nteDecimal = 0;
            Decimal amountDiffDecimal = 0;
            Decimal percentDifference = 0;
            try
            {

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    Entity entity = (Entity)context.InputParameters["Target"];
                    if (entity.LogicalName == "msdyn_workorder")
                    {
                        //code fires onChange of NTE Amount (same logic will apply to NTE % and Est Subtotal Amount)
                        if (entity.Attributes.Contains("CLIENT_nteamount") == true)
                        {
                            //String NewValue = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()));
                            // String NewSubTotal = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["msdyn_estimatesubtotalamount"].ToString());
                            //String NewNTE = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["CLIENT_nteamount"].ToString());
                            //String Newpercent = FieldValue(service, new Guid(entity["msdyn_workorderid"].ToString()), entity["CLIENT_ntepercent"].ToString());
                            if (context.PreEntityImages.Contains("WONTEPreImage") && context.PreEntityImages["WONTEPreImage"] is Entity)
                            {
                                Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
                                // get topic field value before database update perform
                                //pretopic = (String)preMessageImage.Attributes["subject"];
                                subtotal = (Money)preMessageImage.Attributes["msdyn_estimatesubtotalamount"];
                                nte = (Money)preMessageImage.Attributes["CLIENT_nteamount"];
                                nte_percent = (Decimal)preMessageImage.Attributes["CLIENT_ntepercent"];
                            }
                            //old way of trying to get values NON IMAGE
                            //subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"];
                            //nte = (Money)entity.Attributes["CLIENT_nteamount"];
                            //nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"];

                            subtotalDecimal = subtotal.Value;
                            nteDecimal = nte.Value;
                            amountDiffDecimal = (subtotalDecimal - nteDecimal);
                            percentDifference = ((amountDiffDecimal / nteDecimal) * 100);
                            if (percentDifference > nte_percent)
                            {
                                //know this snippet works
                                entity["CLIENT_nteexceeded"] = true;
                            }
                            if (percentDifference <= nte_percent)
                            {
                                //know this snippet works
                                entity["CLIENT_nteexceeded"] = false;
                            }
                        }
                        if (entity.Attributes.Contains("CLIENT_ntepercent") == true)
                        {
                            if (context.PreEntityImages.Contains("WONTEPreImage") && context.PreEntityImages["WONTEPreImage"] is Entity)
                            {
                                Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
                                // get topic field value before database update perform
                                //pretopic = (String)preMessageImage.Attributes["subject"];
                                subtotal = (Money)preMessageImage.Attributes["msdyn_estimatesubtotalamount"];
                                nte = (Money)preMessageImage.Attributes["CLIENT_nteamount"];
                                nte_percent = (Decimal)preMessageImage.Attributes["CLIENT_ntepercent"];
                            }

                            //old way of trying to get values NON IMAGE
                            //subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"];
                            //nte = (Money)entity.Attributes["CLIENT_nteamount"];
                            //nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"];
                            subtotalDecimal = subtotal.Value;
                            nteDecimal = nte.Value;
                            amountDiffDecimal = (subtotalDecimal - nteDecimal);
                            percentDifference = ((amountDiffDecimal / nteDecimal) * 100);

                            if (percentDifference > nte_percent)
                            {
                                //know this snippet works
                                entity["CLIENT_nteexceeded"] = true;
                            }
                            if (percentDifference <= nte_percent)
                            {
                                //know this snippet works
                                entity["CLIENT_nteexceeded"] = false;
                            }
                        }
                        if (entity.Attributes.Contains("msdyn_estimatesubtotalamount") == true)
                        { 
                            if (context.PreEntityImages.Contains("WONTEPreImage") && context.PreEntityImages["WONTEPreImage"] is Entity)
                            {
                                Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"];
                                subtotal = (Money)preMessageImage.Attributes["msdyn_estimatesubtotalamount"];
                                nte = (Money)preMessageImage.Attributes["CLIENT_nteamount"];
                                nte_percent = (Decimal)preMessageImage.Attributes["CLIENT_ntepercent"];
                            }

                            //old way of trying to get values NON IMAGE
                            //subtotal = (Money)entity.Attributes["msdyn_estimatesubtotalamount"];
                            //nte = (Money)entity.Attributes["CLIENT_nteamount"];
                            //nte_percent = (Decimal)entity.Attributes["CLIENT_ntepercent"];

                            subtotalDecimal = subtotal.Value;
                            nteDecimal = nte.Value;
                            amountDiffDecimal = (subtotalDecimal - nteDecimal);
                            percentDifference = ((amountDiffDecimal / nteDecimal) * 100);

                            if (percentDifference > nte_percent)
                            {
                                //know this snippet works
                                entity["CLIENT_nteexceeded"] = true;
                            }
                            if (percentDifference <= nte_percent)
                            {
                                //know this snippet works
                                entity["CLIENT_nteexceeded"] = false;
                            }

                        }

                    }
                }

            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                tracingService.Trace("CLIENTPlugin - Update NTEExceededNonCalc: {0}", e.ToString());
                throw e;
            }
        }
    }

}


  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Dynamics 365 CRM Online - Plugin Only Performs Update Every Other Time it is Triggered

    Ben,

    Thank you so much.  Your answer definitely gave me both things I needed - working code, and a lesson as to why it works.

    I wasn't thinking about the preImage being 'old data' for the fields I wasn't updating, but of course, that makes perfect sense.

    Also, I pulled your logic into my code to clean it up very much.  Now instead of all of those nested Ifs, I have much cleaner, much more concise code.  This code now fires every time, and updates my attributes every time.

    You are a life saver! Thank you so much.  

  • Verified answer
    Ben Thompson Profile Picture
    Ben Thompson 6,350 on at
    RE: Dynamics 365 CRM Online - Plugin Only Performs Update Every Other Time it is Triggered

    The pre-image entity contains the original value before the change, so the calculation in your current code isn't using the newly updated value(s) it using the previous (historic) values.

    What you need to be doing (for all 3 values is something like)

    Entity entity = (Entity)context.InputParameters["Target"];
    // note change in logic I prefer to exit things asap if you don't need to continue
    // it also removes a tab or 2 making things easier to follow if (entity.LogicalName != "msdyn_workorder") { return; } Decimal nteDecimal = 0; Entity preMessageImage = (Entity)context.PreEntityImages["WONTEPreImage"]; if (entity.Attributes.Contains("CLIENT_nteamount") == true // note you don't need the == true bit) { nteDecimal=entity.GetAttributeValue<Money>("CLIENT_nteamount").Value; } else { nteDecimal=preMessageImage.GetAttributeValue<Money>("CLIENT_nteamount").Value; } // repeat the above for subtotal and percentage amountDiffDecimal = (subtotalDecimal - nteDecimal); percentDifference = ((amountDiffDecimal / nteDecimal) * 100); if (percentDifference > nte_percent) { entity["CLIENT_nteexceeded"] = true; } else { entity["CLIENT_nteexceeded"] = false; }

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

November Spotlight Star - Khushbu Rajvi

Congratulations to a top community star!

Forum Structure Changes Coming on 11/8!

In our never-ending quest to help the Dynamics 365 Community members get answers faster …

Dynamics 365 Community Platform update – Oct 28

Welcome to the next edition of the Community Platform Update. This is a status …

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,492 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,305 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans