locked
Plugin Email : Unwanted Multiple Emails Issue RRS feed

  • Question

  • Hello,

    I created a plugin that will send an email to customers. I registered the step Update, Asynchronously and Post. The plugin is supposed to just email the customer once, but it emails it multiple times. Sometimes it emails the customer 20x. I'm not sure what is going on and why it emails multiple times. How do I stop this from happening? Any suggestions.

    Here is the code for my plugin:

    namespace SendEmailFromProdSheet
    {
        public class SendEmail:IPlugin
        {
            private String pointOfContact;
            private String contactEmail;
            private String clientContact1;
            private String clientContact2;
            private String clientContact3;
            private String clientContact4;
            private DateTime approvalDeadline;
            private String emailSent;
            private Guid ownerId;
            private String ownerName;
            private Guid origSalesOrderId;
            private String origSalesOrderPO;
            private String origSalesOrderName;
            private Entity ClientCont1;
            private Guid clientCont1Id;
            private Entity ClientCont2;
            private Guid clientCont2Id;
            private Entity ClientCont3;
            private Guid clientCont3Id;
            private Entity ClientCont4;
            private Guid clientCont4Id;        
            private String stageAction;
            private String nimlokOnline;
            
            public void Execute(IServiceProvider serviceProvider)
            {
                Entity targetEntityImage = null;
    
                var pluginExecutionContext = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
    
                if (pluginExecutionContext.PrimaryEntityName != "orbus_graphicsproductionsheet" && pluginExecutionContext.MessageName != "Update")
                {
                    throw new Exception("This plugin should be fire on Production Sheet Only!");
                }
    
                if (pluginExecutionContext.InputParameters.Contains("Target") && pluginExecutionContext.InputParameters["Target"] is Entity)
                {
                    targetEntityImage = (Entity)pluginExecutionContext.InputParameters["Target"];
                }
                else
                {
                    throw new Exception("No Target Entity Image found.");
                }
    
                try
                {
                    var factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    var service = factory.CreateOrganizationService(pluginExecutionContext.UserId);                                              
    
                    //Get Production Sheet's information including Owner and Prod sheet Id
                    Guid prodsheetId = targetEntityImage.Id;
                    Entity prodsheet = service.Retrieve("orbus_graphicsproductionsheet", prodsheetId, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
    
                    //Get Owner of Prod Sheet
                    if (prodsheet.Contains("ownerid") && prodsheet.Attributes["ownerid"] != null)
                    {
                        ownerId = ((EntityReference)prodsheet.Attributes["ownerid"]).Id;
                        Entity owner = service.Retrieve("systemuser", ownerId, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
                        ownerName = (String)owner.Attributes["fullname"];
                    }
                    else
                    {
                        ownerName = "Arvin B";
                    }
    
    
                    //Get PO of Prod Sheet (edited cause Maris prodsheet is failing)
                    if (prodsheet.Contains("orbus_originalsalesorderid") && prodsheet.Attributes["orbus_originalsalesorderid"] != null)
                    {
                        origSalesOrderId = ((EntityReference)prodsheet.Attributes["orbus_originalsalesorderid"]).Id;
                        Entity origSalesOrder = service.Retrieve("salesorder", origSalesOrderId, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
                        origSalesOrderName = (String)origSalesOrder.Attributes["name"];
                        if (origSalesOrder.Contains("new_customerpo") && (String)origSalesOrder.Attributes["new_customerpo"] != "")
                        {
                            origSalesOrderPO = (String)origSalesOrder.Attributes["new_customerpo"];
                        }
                        else
                        {
                            origSalesOrderPO = "";
                        }
                    }
    
                    //Get Point of Contact of Prod Sheet -- sometimes this is null which is the reason for this if statement      
                    if (prodsheet.Contains("orbus_clientpocid") && prodsheet.Attributes["orbus_clientpocid"] != null)
                    {
                        Guid pocId = ((EntityReference)prodsheet.Attributes["orbus_clientpocid"]).Id;
                        Entity poc = service.Retrieve("contact", pocId, new Microsoft.Xrm.Sdk.Query.ColumnSet(true));
                        pointOfContact = (String)poc.Attributes["fullname"];
                    }
                    else
                    {
                        pointOfContact = "";
                    }
    
                    //Get eProof Contact Email -- sometimes this is is null which is the reason for this if statement
                    if (prodsheet.Contains("ehtc_endusercontact") && (String)prodsheet.Attributes["ehtc_endusercontact"] != "")
                    {
                        contactEmail = (String)prodsheet.Attributes["ehtc_endusercontact"];
    
                    }
                    else
                    {
                        //ask Jenny where to send it null - this is required!!
                        contactEmail = "test@email.com";
                    }
    
                    //Get Contact #1 Email -- sometimes this could be null
                    if (prodsheet.Contains("ehtc_endusercontact4") && (String)prodsheet.Attributes["ehtc_endusercontact4"] != "")
                    {
                        clientContact1 = (String)prodsheet.Attributes["ehtc_endusercontact4"];
                    }
                    else
                    { 
                        clientContact1 = "test@email.com";
                    }               
    
                    //Get Contact #2 Email -- sometimes this could be null
                    if (prodsheet.Contains("ehtc_endusercontact5") && (String)prodsheet.Attributes["ehtc_endusercontact5"] != "")
                    {
                        clientContact2 = (String)prodsheet.Attributes["ehtc_endusercontact5"];
                    }
                    else
                    {
                        clientContact2 = "test@email.com";
                    }
    
                    //Get Contact #3 Email - sometimes this could be null
                    if (prodsheet.Contains("ehtc_enduserpocemail") && (String)prodsheet.Attributes["ehtc_enduserpocemail"] != "")
                    {
                        clientContact3 = (String)prodsheet.Attributes["ehtc_enduserpocemail"];
                    }
                    else
                    {
                        clientContact3 = "test@email.com";
                    }
    
                    //Get Contact #4 Email - sometimes this could be null
                    if (prodsheet.Contains("ehtc_enduserpocemail2") && (String)prodsheet.Attributes["ehtc_enduserpocemail2"] != "")
                    {
                        clientContact4 = (String)prodsheet.Attributes["ehtc_enduserpocemail2"];
                    }
                    else
                    {
                        clientContact4 = "test@email.com";
                    }
                 
     
                    //Get Approval Deadline Date -- if date is not null
                    if (prodsheet.Contains("ehtc_approvaldeadline") && prodsheet.Attributes["ehtc_approvaldeadline"] != null)
                    {
                        approvalDeadline = (DateTime)prodsheet.Attributes["ehtc_approvaldeadline"];
                    }
                    else
                    {
                        approvalDeadline = DateTime.Today.AddDays(2);
                    }
    
                    //Get Email Sent Value -- if email sent is not null
                    if (prodsheet.Contains("orbus_emailsent") && (String)prodsheet.Attributes["orbus_emailsent"] != "")
                    {
                        emailSent = (String)prodsheet.Attributes["orbus_emailsent"];
                    }
                    else
                    {
                        emailSent = "";
                    }
    
                    //Get Stage Action
                    if (prodsheet.Contains("orbus_stageactiontext") && (String)prodsheet.Attributes["orbus_stageactiontext"] != "")
                    {
                        stageAction = (String)prodsheet.Attributes["orbus_stageactiontext"];
                    }
                    else
                    {
                        stageAction = "Not Correct";
                    }
                    
                    //Check if Production Sheet is a Nimlok Online order
                    String orbusName = (String)prodsheet.Attributes["orbus_name"];
                    if (orbusName.Contains("Nimlok Online"))
                    {
                        nimlokOnline = "Yes";
                    }
                    else
                    {
                        nimlokOnline = "No";
                    }
    
                    //String salesOrder = orbusName.Substring(orbusName.Length - 7, 7);                
    
                    //Date Filters
                    DateTime today = DateTime.Today;
                    DateTime tomorrow = DateTime.Today.AddDays(1);
                    String approvalDate = DateTime.Now.ToShortDateString();
    
                    //Time Filters -- must be between 11 AM and 11:30 AM
                    DateTime systemTime = DateTime.Now;
                    DateTime startTime = DateTime.Today.AddHours(11.00);
                    DateTime endTime = DateTime.Today.AddHours(11.50);
    
                    //Email Structure
                    String subject = "Approval Reminder: PO " + origSalesOrderPO + " / " + origSalesOrderName + "";
                    String desc = "Good Morning, " + pointOfContact + "<br><br> To ensure on-time delivery of your graphics, we have sent this automated email to remind you that PO " + origSalesOrderPO + " / " + origSalesOrderName + " has a scheduled date of approval today, " + approvalDate + " by NOON CST. <br><br>";
                    String desc2 = "If approval is given any later than noon or if new art is sent the same day approval is needed, your ship date may be pushed back or a late approval fee may be incurred. <br><br>";
                    String desc3 = "This automated reminder is being sent as part of our commitment to customer service in an effort to help you meet your scheduled approval date. <br><br> Thank you for your business and cooperation! <br><br>" + ownerName + "";
    
                    if (approvalDeadline >= today && approvalDeadline < tomorrow)
                    {
                        if (stageAction == "E-proofs Sent Out - Waiting for Approval" || stageAction == "Hard Copy Proofs Sent Out - Waiting for Approval")
                        {
                            if (systemTime >= startTime && systemTime <= endTime)
                            {
                                if (emailSent != "Yes")
                                {
                                    if (nimlokOnline == "No")
                                    {
                                        if (ownerName == "Elisa R" || ownerName == "Arvin B")
                                        {
    
                                        //Create a temp contact to send an email to (To: field)
                                        Entity Contact = new Entity("contact");
                                        Contact.Attributes.Add("firstname", "Email");
                                        Contact.Attributes.Add("lastname", "Contact1");
                                        Contact.Attributes.Add("emailaddress1", contactEmail);
                                        Guid contactId = service.Create(Contact);
    
                                        //Create a temp client contact 1 to send an email to (CC: field) 
                                        ClientCont1 = new Entity("contact");
                                        ClientCont1.Attributes.Add("firstname", "Client");
                                        ClientCont1.Attributes.Add("lastname", "Contact1");
                                        ClientCont1.Attributes.Add("emailaddress1", clientContact1);
                                        clientCont1Id = service.Create(ClientCont1);
    
                                        //Create a temp client contact 2 to send an email to (CC: field) 
                                        ClientCont2 = new Entity("contact");
                                        ClientCont2.Attributes.Add("firstname", "Client");
                                        ClientCont2.Attributes.Add("lastname", "Contact2");
                                        ClientCont2.Attributes.Add("emailaddress1", clientContact2);
                                        clientCont2Id = service.Create(ClientCont2);
    
                                        //Create a temp client contact 3 to send an email to (CC: field) 
                                        ClientCont3 = new Entity("contact");
                                        ClientCont3.Attributes.Add("firstname", "Client");
                                        ClientCont3.Attributes.Add("lastname", "Contact3");
                                        ClientCont3.Attributes.Add("emailaddress1", clientContact3);
                                        clientCont3Id = service.Create(ClientCont3);
    
                                        //Create a temp client contact 4 to send an email to (CC: field) 
                                        ClientCont4 = new Entity("contact");
                                        ClientCont4.Attributes.Add("firstname", "Client");
                                        ClientCont4.Attributes.Add("lastname", "Contact4");
                                        ClientCont4.Attributes.Add("emailaddress1", clientContact4);
                                        clientCont4Id = service.Create(ClientCont4);
    
                                        //Build From: Email
                                        Entity fromParty = new Entity("activityparty");
                                        fromParty["partyid"] = new EntityReference("systemuser", ownerId);
    
                                        //Build To: Email
                                        Entity toParty = new Entity("activityparty");
                                        toParty["partyid"] = new EntityReference("contact", contactId);
    
                                        //Build CC: Email
                                        Entity ccParty = new Entity("activityparty");
                                        ccParty["partyid"] = new EntityReference("contact", clientCont1Id);
    
                                        Entity ccParty2 = new Entity("activityparty");
                                        ccParty2["partyid"] = new EntityReference("contact", clientCont2Id);
    
                                        Entity ccParty3 = new Entity("activityparty");
                                        ccParty3["partyid"] = new EntityReference("contact", clientCont3Id);
    
                                        Entity ccParty4 = new Entity("activityparty");
                                        ccParty4["partyid"] = new EntityReference("contact", clientCont4Id);
    
                                        //Error is here
                                        //Build Email: Email
                                        Entity Email = new Entity("email");
                                        Email.Attributes["from"] = new Entity[] { fromParty };
                                        Email.Attributes["to"] = new Entity[] { toParty };
                                        Email.Attributes["bcc"] = new Entity[] { ccParty, ccParty2, ccParty3, ccParty4, fromParty };
                                        Email.Attributes["subject"] = subject;
                                        Email.Attributes["description"] = desc + desc2 + desc3;
                                        Email.Attributes["ownerid"] = new EntityReference("systemuser", ownerId);
                                        Email.Attributes["regardingobjectid"] = new EntityReference("orbus_graphicsproductionsheet", prodsheetId);
                                        Guid EmailId = service.Create(Email);
    
                                        SendEmailRequest req = new SendEmailRequest();
                                        req.EmailId = EmailId;
                                        req.IssueSend = true;
                                        req.TrackingToken = "";
    
                                        SendEmailResponse res = (SendEmailResponse)service.Execute(req);
    
    
                                        //Update Sent Email field to 'Yes'
                                        prodsheet["orbus_emailsent"] = "Yes";
                                        service.Update(prodsheet);
    
                                        //Delete the temp contact that was created
                                        service.Delete(Contact.LogicalName, contactId);
                                        service.Delete(ClientCont1.LogicalName, clientCont1Id);
                                        service.Delete(ClientCont2.LogicalName, clientCont2Id);
                                        service.Delete(ClientCont3.LogicalName, clientCont3Id);
                                        service.Delete(ClientCont4.LogicalName, clientCont4Id);
    
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                                
                catch (Exception ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred in the Send Email from Prod Sheet plugin.", ex);
                }
            }
           
        }
    }



    • Edited by OrbusMan Thursday, November 7, 2013 3:54 PM
    Wednesday, November 6, 2013 5:08 PM

Answers

  • Thank you for the reply. However, I decided to re-create the plugin by re-registering it and recreating the step (update) to Asynch using a user with an Admin rights and an Email. I'm not sure if that made the issue worked, but I didn't get any duplicates again after re-running the update. I will do one more test tomorrow and if that succeed, I will mark this the answer.

    Arvin

    • Marked as answer by OrbusMan Thursday, November 14, 2013 10:45 PM
    Monday, November 11, 2013 9:58 PM

All replies

  • if (pluginExecutionContext .Depth > 1)
                    {
                        return;
                    }

    Try writing above code after getting plugin context and before sending an email. Context depth is used for infinite loop prevention.

    Friday, November 8, 2013 8:13 PM
  • Thank you for the reply. However, I decided to re-create the plugin by re-registering it and recreating the step (update) to Asynch using a user with an Admin rights and an Email. I'm not sure if that made the issue worked, but I didn't get any duplicates again after re-running the update. I will do one more test tomorrow and if that succeed, I will mark this the answer.

    Arvin

    • Marked as answer by OrbusMan Thursday, November 14, 2013 10:45 PM
    Monday, November 11, 2013 9:58 PM