Bhoopathi

"Be Somebody Nobody Thought You could Be"

Thursday, August 4

Handle birthdays in Microsoft CRM 2011/2013

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Linq;
using Microsoft.Xrm.Sdk.Query;

namespace Crm.Birthday.Remainder
{
    public class Contact_BirthDay : IPlugin
    {
        public enum RecurrenceRulePatternEndType
        {
            NoEndDate = 1,
            Occurrences = 2,
            PatternEndDate = 3
        };

        public enum RecurrencePatternTypes
        {
            Daily = 0,
            Weekly = 1,
            Monthly = 2,
            Yearly = 3
        };

        public enum DayOfWeek
        {
            Sunday = 0x01,
            Monday = 0x02,
            Tuesday = 0x04,
            Wednesday = 0x08,
            Thursday = 0x10,
            Friday = 0x20,
            Saturday = 0x40
        };
        private string birthday_remainder = "card_birthdayremainder";

        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);

            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {
                Entity entity = (Entity)context.InputParameters["Target"];
                if (entity.LogicalName == "contact" && entity.Attributes.Contains("birthdate"))
                {
                    //  if the entity is created => create the recurring appointment and update your lookupfield with the created master
                    if (context.MessageName == "Create")
                    {
                        Entity newRecurringAppointment = this.createRecurringAppointment(entity, context.UserId);
                        Guid recurringappointmentmasterID = service.Create(newRecurringAppointment);
                        Entity cUpdate = new Entity("card_contactdetails");
                        cUpdate.Id = entity.Id;
                        cUpdate.Attributes.Add(birthday_remainder, new EntityReference("card_locations", recurringappointmentmasterID));
                        service.Update(cUpdate);
                    }
                    // If the entity is updated get the "old" contact
                    if (context.MessageName == "Update")
                    {
                        if (entity.LogicalName == "card_contactdetails" && entity.Attributes.Contains("card_dateofbirthdate"))
                        {
                            Entity oldContact = service.Retrieve("card_contactdetails", entity.Id, new ColumnSet(new string[] { "card_firstname", "ownerid", birthday_remainder }));
                            // if a birthday is set to null it means the birthday filed was deleted.
                            //In this case we delete the recurring appointment
                            if (entity.Attributes["card_dateofbirthdate"] != null)
                            {
                                // we need the contacts fullname for the subject. so if we do not update the field we get it from the "old" contact
                                if (!entity.Attributes.Contains("card_firstname"))
                                    entity.Attributes.Add("card_firstname", oldContact["card_firstname"]);

                                Guid? OwnerID = null;
                                if (entity.Attributes.Contains("ownerid"))
                                {
                                    OwnerID = ((EntityReference)entity["ownerid"]).Id;
                                }
                                else
                                {
                                    OwnerID = ((EntityReference)oldContact["ownerid"]).Id;
                                }

                                // Create a new recurringappointment
                                Entity newRecurringAppointment = this.createRecurringAppointment(entity, OwnerID);

                                // If there is a existing recurringappointment pointing to birthday update this entity, else create a new one
                                if (oldContact.Attributes.Contains(birthday_remainder))
                                {
                                    newRecurringAppointment.Id = ((EntityReference)oldContact[birthday_remainder]).Id;
                                    service.Update(newRecurringAppointment);
                                    entity[birthday_remainder] = new EntityReference("recurringappointmentmaster", newRecurringAppointment.Id);
                                }
                                else
                                {
                                    Guid recurringappointmentmasterID = service.Create(newRecurringAppointment);
                                    entity.Attributes.Add(birthday_remainder, new EntityReference("card_locations", recurringappointmentmasterID));
                                }

                            }
                            else
                            {
                                if (oldContact.Attributes.Contains(birthday_remainder))
                                {
                                    service.Delete("card_locations", ((EntityReference)oldContact[birthday_remainder]).Id);
                                    entity[birthday_remainder] = null;
                                }
                            }
                        }
                    }
                }
            }
        }
        // Creates an recurring appointment
        public Entity createRecurringAppointment(Entity entity, Guid? OwnerID)
        {
            // if the contact has an owner use his id to create a required attendee
            Guid? ownerid = null;
            if (entity.Attributes.Contains("ownerid"))
            {
                ownerid = ((EntityReference)entity["ownerid"]).Id;
            }
            else
            {
                if (OwnerID != null)
                {
                    ownerid = OwnerID.Value; ;
                }
            }

            // Create a recurring appointment
            Entity newRecurringAppointment = new Entity("card_contactdetails");
            DateTime birthday = (DateTime)entity["card_dateofbirthdate"];
            // its a allday event
            newRecurringAppointment.Attributes.Add("isalldayevent", true);
            if (entity.Attributes.Contains("fullname"))
            {
                newRecurringAppointment.Attributes.Add("subject", "Geburtstag von " + entity["fullname"].ToString());
            }
            // set the reagrding filed to the contact
            newRecurringAppointment.Attributes.Add("regardingobjectid", new EntityReference(entity.LogicalName, entity.Id));
            // Birthday is recurring once a year
            newRecurringAppointment.Attributes.Add("recurrencepatterntype", new OptionSetValue((int)RecurrencePatternTypes.Yearly));
            // start the pattern today
            newRecurringAppointment.Attributes.Add("patternstartdate", DateTime.Today);
            // Dont stop the recurring appointment at a certain date
            newRecurringAppointment.Attributes.Add("patternendtype", new OptionSetValue((int)RecurrenceRulePatternEndType.NoEndDate));
            // every year => interval = 1
            newRecurringAppointment.Attributes.Add("interval", 1);
            // Set the day (zero-based!)
            newRecurringAppointment.Attributes.Add("dayofmonth", birthday.Day + 1);
            // set the month
            newRecurringAppointment.Attributes.Add("monthofyear", new OptionSetValue(birthday.Month));
            // pretty useless because its a all day event, but if this is not set, the start and end-date were set incorrectly
            newRecurringAppointment.Attributes.Add("starttime", DateTime.Now);
            newRecurringAppointment.Attributes.Add("endtime", DateTime.Now.AddHours(1));

            // set the required attendee
            if (ownerid != null)
            {
                Entity activityparty = new Entity("activityparty");
                activityparty.Attributes.Add("partyid", new EntityReference("systemuser", ownerid.Value));
                newRecurringAppointment.Attributes.Add("requiredattendees", new Entity[] { activityparty });
            }
            return newRecurringAppointment;
        }
   }
}