CRM 2011Plugin - unable to modify a field that already has existing data

Unanswered CRM 2011Plugin - unable to modify a field that already has existing data

  • Tuesday, March 05, 2013 1:11 AM
     
      Has Code

    We are using CRM 2011 Online. I have a plugin that is attempting to update the account name from the company name in the regarding lead. It executes without an error but the account name doesn't get updated if there is data in already in the account name.  The plugin is registered "Post Operation" and has a post image that includes just the account name field. I have tried using the post image and the account to do the update. With the post image I get the same message, and with the account it's saved but the name doesn't change. One question I have is, if there is no data in the account name field, is the field part of the attribute list of the post image? Here is the code...

                            Entity lead = service.Retrieve("lead",
                                ((EntityReference)account["originatingleadid"]).Id, new ColumnSet(true));
    
                            if (lead.Attributes.Contains("companyname"))
                            {
    
                                companyName = lead.Attributes["companyname"].ToString();
    
                                if (context.PostEntityImages.Contains("AccountPostImage") &&
                                    context.PostEntityImages["AccountPostImage"] is Entity)
                                {
                                    accountPostImage = (Entity)context.PostEntityImages["AccountPostImage"];
                           
                                    if (accountPostImage.Contains("name"))
                                    {
                                        var accountUpdate = new Entity
                                        {
                                            Id = account.Id,
                                            LogicalName = "account",
                                        };
    
                                        accountUpdate.Attributes.Add("name", companyName);
                                        service.Update(accountUpdate);
                                    }
                                    else
                                    {
                                        account.Attributes.Add("name", companyName);
                                        service.Update(account);
                                    }
                                }
                            }
                        }

    I get a message that says "Unsaved Changes". If you click on save, the account name is not updated.

    Thank you for the help!!


    • Edited by GaryMk Tuesday, March 05, 2013 7:59 PM
    • Edited by GaryMk Tuesday, March 05, 2013 8:01 PM
    • Edited by GaryMk Tuesday, March 05, 2013 8:02 PM
    •  

All Replies

  • Tuesday, March 05, 2013 8:24 AM
     
     

    Hi,

    Try like this:

    if (context.PostEntityImages.Contains("Target"))
                {
                    Entity postMessageImage = (Entity)context.PostEntityImages["Target"];

                    if (postMessageImage.Attributes.Contains("originatingleadid") == true)
                    {
                        IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                        IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                        EntityReference originatingleadid = postMessageImage.GetAttributeValue<EntityReference>("originatingleadid");
                        Entity Lead = service.Retrieve(originatingleadid.LogicalName,originatingleadid.Id,new ColumnSet("companyname"));

                        postMessageImage.Attributes["name"] = postMessageImage.GetAttributeValue<string>("companyname");
                        service.Update(postMessageImage);
                    }
                }


    Naren

  • Tuesday, March 05, 2013 12:16 PM
     
     
     

    use the following code, it should work.

    Entity lead = service.Retrieve("lead",
                                ((EntityReference)account["originatingleadid"]).Id, new ColumnSet(true));

                            if (lead.Attributes.Contains("companyname"))
                            {

                                companyName = lead.Attributes["companyname"].ToString();

                                if (context.PostEntityImages !=  null && context.PostEntityImages.Contains("AccountPostImage") &&
                                    context.PostEntityImages["AccountPostImage"] is Entity)
                                {
                                    accountPostImage = (Entity)context.PostEntityImages["AccountPostImage"];
    var accountUpdate = new Entity
                                        {
                                            Id = account.Id,
                                            LogicalName = "account",
                                        };
                                    if (accountPostImage.Contains("name"))
                                    {  
                                        accountUpdate["name"] = companyName;                                    
                                    }
                                    else
                                    {
                                        accountUpdate.Attributes.Add("name", companyName);                                    
                                    }
    service.Update(accountUpdate);
                                }
                            }
                        }


    Guru Prasad

  • Tuesday, March 05, 2013 4:16 PM
     
      Has Code

    Thanks. I still receive the message "unsaved changes". It works when the account name is not filled in. Here is the current code...

                                if (context.PostEntityImages.Contains("AccountPostImage") &&
                                    context.PostEntityImages["AccountPostImage"] is Entity)
                                {
                                    accountPostImage = (Entity)context.PostEntityImages["AccountPostImage"];
    
                                    var accountUpdate = new Entity
                                    {
                                        Id = account.Id,
                                        LogicalName = "account",
                                    };
    
                                    if (accountPostImage.Contains("name"))
                                    {
                                        accountUpdate.Attributes["name"] = companyName;
                                    }
                                    else
                                    {
                                        accountUpdate.Attributes.Add("name", companyName);
                                        
                                    }
    
                                    service.Update(accountUpdate);
                                }

    • Edited by GaryMk Tuesday, March 05, 2013 4:17 PM
    •  
  • Tuesday, March 05, 2013 6:17 PM
     
     

    Hey Gary,

    This is a very strange way to accomplish your goal. I would recommend pairing with the pre-operation step. Performing additional Sdk operations such as update while in transaction can be unwise. Is there anything in your code that stops infinite loop? Your plugin fires on update, and then calls an update, which in turn triggers the plugin... etc. The fact that it's running without error may be because CRM Online is recognizing that it is in an error state due to the loop, and shutting it down, killing the transaction as a whole - which would abort your core request.

    Now, in the pre-operation, you do not need to make a new entity and call update. Simply modify or add the name field to the entity stored in your inputparameters target, and allow the CRM organizational web service to take care of the change for you.

    Perhaps I am misunderstanding the business need / process, however I would strongly encourage you not to call an update to an entity that is already being updated.

    Regards,

    Alex

  • Tuesday, March 05, 2013 7:08 PM
     
     

    Thanks Alex for the reply.

    This is only triggered on create, so the loop is not a problem. The reason for the post vs pre is that I need the originating lead and it was my understanding that the id wouldn't be there until the update took place.

    • Edited by GaryMk Tuesday, March 05, 2013 7:09 PM
    •  
  • Tuesday, March 05, 2013 7:17 PM
     
     

    Hey Gary,

    This seems like the kind of situation where you could use a no-code workflow.

    Workflow fires on create of account, and if the account has an originating lead, it updates the account name with the relevant data from the lead.

    Regards,

    Alex

  • Tuesday, March 05, 2013 7:56 PM
     
     

    Hi Alex,

    Actually that's what we have right now. The problem that we're having is that there are times that the account is being created before the lead is completed and we end up with accounts that don't have account names. It seems to be a timing thing. At this point I want this to work if for no other reason as a learning exercise.

    Thanks,

    Gary


    • Edited by GaryMk Tuesday, March 05, 2013 7:57 PM
    •  
  • Tuesday, March 05, 2013 9:31 PM
     
      Has Code

    Interesting. The following code runs without issue:

            public void Execute(IServiceProvider serviceProvider)
            {
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                Entity account = context.InputParameters["Target"] as Entity;
                Entity accountUpdate = new Entity("account")
                {
                    Id = account.Id
                };
                accountUpdate.Attributes.Add("name", "overridden");
                
                service.Update(accountUpdate);
            }

  • Wednesday, March 06, 2013 12:51 AM
     
     

    Your code will update the account name if the user doesn't enter any information into the name field. If the user enters data into the name field it doesn't get updated with the company name of the lead. I'm trying to ensure that the account name always matches the company name in the lead.

    Thanks

  • Wednesday, March 06, 2013 3:39 AM
     
     

    I am still unsure if post is the way to go.

    Reading the thread it says you would not get the Lead in originating lead unless the account is created? Is that correct and have you verified this?

    It should still be a better idea to use the Pre operation stage, use the Target and update the account name in the Target image which is finally passed to the platform to create and it would/should update the account name at all times. It is not conditional...

    If you would like to go the Post Operation route, the code provided by Alex should work.

    Are you sure there are no other plugins or workflows working alongside that is probably interfering with this one. Can you disable all plugins and only keep this one active and check.

    Sam


    Dynamics CRM MVP | Inogic | http://inogic.blogspot.com| news at inogic dot com

    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

  • Wednesday, March 06, 2013 5:39 PM
     
      Has Code

    Thanks for the reply Sam.

    I am using a trial system for my development platform. I unregistered the only other plugin and deactivated the only process. Both were tied to the lead not the account, but just to play it safe. It didn't make any difference.

    As far as Alex's code it would update the account name if the user didn't enter any data into it, otherwise it would say "Unsaved Changes" on the bottom and the header information would say "overridden" but the actual account name wouldn't change. Of course if you then manually save it it saves as the original entry.

    I went back and changed the plugin to a pre operation and I can't save the account because it doesn't exist.

                        if (account.LogicalName == "account")
                        {
                            Entity lead = service.Retrieve("lead",
                                ((EntityReference)account["originatingleadid"]).Id, new ColumnSet("companyname"));
    
                            if (lead.Attributes.Contains("companyname"))
                            {
    
                                companyName = lead.Attributes["companyname"].ToString();
    
    
                                var accountUpdate = new Entity
                                {
                                    Id = account.Id,
                                    LogicalName = "account",
                                };
    
                                accountUpdate.Attributes.Add("name", companyName);
                                service.Update(accountUpdate);
                                }
                        }
     

    I then changed it to where I'm just using the account as a pre operation and I get the same thing. If I enter data into the name field and then try to change it with the plugin, the name changes at the top of the form but the data in the actual name field doesn't. I'm very surprised how difficult this is.

                        if (account.LogicalName == "account")
                        {
                            Entity lead = service.Retrieve("lead",
                                ((EntityReference)account["originatingleadid"]).Id, new ColumnSet("companyname"));
    
                            if (lead.Attributes.Contains("companyname"))
                            {
    
                                companyName = lead.Attributes["companyname"].ToString();
    
    
                                     if (account.Contains("name"))
                                    {
                                        companyName = "overwritten";          
                                        account.Attributes["name"] = companyName;
                                    }
                                    else
                                    {
                                        account.Attributes.Add("name", companyName);
                                    }                            }
                        }
     



     
    • Edited by GaryMk Wednesday, March 06, 2013 5:55 PM
    • Edited by GaryMk Wednesday, March 06, 2013 9:46 PM
    •  
  • Wednesday, March 06, 2013 10:29 PM
     
      Has Code

    Hey Gary,

    I placed the word overridden in there simply to show that you could set the value to any string you want.

    It sounds to me like this is a display issue you're having with the process driven form.

    Specifically, the line:

    the name changes at the top of the form but the data in the actual name field doesn't.

    Suggests that this is an issue where the change is being persisted, however the form is not rendering this change in the field. If you were to save & close your form (triggering the plugin), and then reopen it, would the name be populated in the field?

    Regards,

    Alex

  • Thursday, March 07, 2013 3:31 AM
     
     

    further to alex post...can u check the schema name of the attribute placed on the form?

    perhaps the field on the form is different from the standard OOB field that we are updating?

    If the header value has changed this means the OOB name field of the account has changed. The attribute on the form is not the same as the one we updated through plugin.

    HTH

    Sam


    Dynamics CRM MVP | Inogic | http://inogic.blogspot.com| news at inogic dot com

    If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful"

  • Thursday, March 07, 2013 9:45 PM
     
     
    No, it's not populated. It saves it as the value in the name field.
  • Thursday, March 07, 2013 9:56 PM
     
     

    I thought the same thing so I checked it a couple of times. The name of the attribute is "name" and that's what's being populated on the form.

    Here are a couple of screen shots to show what I'm talking about...

    As you can see from the first image the bottom right hand corner says "unsaved changes". Where do I find the schema name?


    • Edited by GaryMk Thursday, March 07, 2013 9:58 PM
    •