Thursday 5 February 2015

MSCRM 2013 Workhours (Creation of Schedule from 9 - 5 from Plugin) and (Updation of time for one day based on Date selection)

Hi Folks ,
 
After long break I am writing this blog which may help in some of your customer requirement.
MSCRM has strong feature in UR3 called Scheduling holidays and Scheduling workhours for users and Facilities.
In my Scenario , I am using Facility/Equipment entity to store my resource attendance. My functionality flow is:
Step 1: User creates a record in Custom entity which is called "Resource" a plugin will create a record in "Facilities" which by default will have calendar created for whole day(OOB)
Step2: My next step in Plugin will update the calendar created by MSCRM form full day schedule to schedule of(9AM - 6PM).
Step3: Resource will update in his "resource" record stating for one day he has worked only for 4 hours. My Plugin would again update Time for that specific date.
 
This blog will help you to achieve below 2 functionalities:
  • Creation of Workhour calendar.
  • Updating  Workhour calendar.
First of all to understand how Workhours for User and Facilities/Equipment works .Please follow below link:


http://www.microsoft.com/en-us/dynamics/crm-customer-center/set-work-hours-of-a-resource.aspx


http://crmbook.powerobjects.com/basics/service-scheduling/work-hours/




And Thanks for Nishanth Ranas blog which helped me to achieve my Functionalities:


http://nishantrana.me/2013/04/16/sample-code-to-update-users-calendar-programmatically-work-hours-in-crm-2011/


Holiday Schedule will be available only in UR3. Please find below link to know what it is and how it works:
http://inogic.com/blog/2014/07/calendars-holiday-and-customer-service-scheduling-in-microsoft-dynamics-crm-2013-sp1/




Please find code below to create WorkHour calendar for Specific Hours for Specific Date Range:


9AM - 6PM

                    //Create workHour calendar for attendance




                    // Get the calendar id of the facilities
                    Entity facilityEntity = service.Retrieve("equipment", attendance, new ColumnSet(new String[] { "calendarid" }));


                    // Retrieve the calendar of the Facilities
                    Entity facilityCalendarEntity = service.Retrieve("calendar", ((Microsoft.Xrm.Sdk.EntityReference)(facilityEntity.Attributes["calendarid"])).Id, new ColumnSet(true));

                    // Retrieve the calendar rules defined in the calendar
                    EntityCollection calendarRules = (EntityCollection)facilityCalendarEntity.Attributes["calendarrules"];

                    // Create a new inner calendar
                    Entity newInnerCalendar = new Entity("calendar");
                    newInnerCalendar.Attributes["businessunitid"] = new EntityReference("businessunit", ((Microsoft.Xrm.Sdk.EntityReference)(facilityCalendarEntity["businessunitid"])).Id);
                    Guid innerCalendarId = service.Create(newInnerCalendar);

                   
                    // Create a new calendar rule and assign the inner calendar id to it
                    Entity calendarRule = new Entity("calendarrule");
                    calendarRule.Attributes["duration"] = 1440;
                    calendarRule.Attributes["extentcode"] = 1;
                    calendarRule.Attributes["pattern"] = "FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR";
                    calendarRule.Attributes["rank"] = 0;
                    calendarRule.Attributes["timezonecode"] = 190;
                    calendarRule.Attributes["innercalendarid"] = new EntityReference("calendar", innerCalendarId);
                    calendarRule.Attributes["starttime"] = new DateTime(2015, 2, 3,9, 0, 0, DateTimeKind.Utc);
                   // calendarRule.Attributes["endtime"] = new DateTime(9999, 12, 30, 23, 59, 59, DateTimeKind.Utc);
                    calendarRules.Entities.Add(calendarRule);

                    // assign all the calendar rule back to the user calendar
                    facilityCalendarEntity.Attributes["calendarrules"] = calendarRules;
                    // update the user calendar entity that has the new rule
                    service.Update(facilityCalendarEntity);

                    Entity calendarRule1 = new Entity("calendarrule");
                    // duration of 5 hours
                    calendarRule1.Attributes["issimple"] = true;
                   // calendarRule1.Attributes["isselected"] = false;
                    calendarRule1.Attributes["duration"] = 540;
                    calendarRule1.Attributes["offset"] = 0;
                   // calendarRule1.Attributes["isselected"] = true;
                    calendarRule1.Attributes["rank"] = 0;
                    calendarRule1.Attributes["subcode"] = 1;
                    calendarRule1.Attributes["timecode"] = 0;
                    calendarRule1.Attributes["timezonecode"] = 190;
                    calendarRule1.Attributes["calendarid"] = new EntityReference("calendar", innerCalendarId);

                    EntityCollection innerCalendarRules = new EntityCollection();
                    innerCalendarRules.EntityName = "calendarrule";
                    innerCalendarRules.Entities.Add(calendarRule1);

                    newInnerCalendar.Attributes["calendarrules"] = innerCalendarRules;
                    newInnerCalendar.Attributes["calendarid"] = innerCalendarId;
                    service.Update(newInnerCalendar);

                    //Create second inner calendar
                    Entity newInnerCalendar1 = new Entity("calendar");
                    newInnerCalendar1.Attributes["businessunitid"] = new EntityReference("businessunit", ((Microsoft.Xrm.Sdk.EntityReference)(facilityCalendarEntity["businessunitid"])).Id);
                    Guid innerCalendarId1 = service.Create(newInnerCalendar1);

                    // Create a 2nd calendar rule and assign the inner calendar id to it
                    Entity calendarRuleWeekend = new Entity("calendarrule");
                    calendarRuleWeekend.Attributes["duration"] = 525600;
                    calendarRuleWeekend.Attributes["extentcode"] = 1;
                    calendarRuleWeekend.Attributes["pattern"] = "FREQ=YEARLY;INTERVAL=1";
                    calendarRuleWeekend.Attributes["rank"] = 0;
                    calendarRuleWeekend.Attributes["timezonecode"] = 190;
                    calendarRuleWeekend.Attributes["innercalendarid"] = new EntityReference("calendar", innerCalendarId1);
                    calendarRuleWeekend.Attributes["starttime"] = new DateTime(2015, 2, 3, 9, 0, 0, DateTimeKind.Utc);
                   // calendarRuleWeekend.Attributes["endtime"] = new DateTime(9999, 12, 30, 23, 59, 59, DateTimeKind.Utc);
                    calendarRules.Entities.Add(calendarRuleWeekend);
                    // assign all the calendar rule back to the user calendar
                    facilityCalendarEntity.Attributes["calendarrules"] = calendarRules;
                    // update the user calendar entity that has the new rule
                    service.Update(facilityCalendarEntity);
                   

                    Entity calendarRule2 = new Entity("calendarrule");
                    calendarRule2.Attributes["issimple"] = true;
                    calendarRule2.Attributes["duration"] = 0;
                    calendarRule2.Attributes["offset"] = 0;
                    calendarRule2.Attributes["rank"] = 1;
                    calendarRule2.Attributes["subcode"] = 0;
                    calendarRule2.Attributes["timecode"] = 0;
                    calendarRule2.Attributes["timezonecode"] = 190;
                    calendarRule2.Attributes["calendarid"] = new EntityReference("calendar", innerCalendarId1);

                    EntityCollection innerCalendarRules1 = new EntityCollection();
                    innerCalendarRules1.EntityName = "calendarrule";
                    innerCalendarRules1.Entities.Add(calendarRule2);

                    newInnerCalendar1.Attributes["calendarrules"] = innerCalendarRules1;
                    newInnerCalendar1.Attributes["calendarid"] = innerCalendarId1;
                    service.Update(newInnerCalendar1);





In Above Code I have created 2 Inner Calendar, one to add standard schedule and one to state leav on Saturday and Sunday.




Please find Code below to Update time for Resource for specified Date:


                    //Retrieve workHours from resource
                    Entity resourceschedule = service.Retrieve("contact", resource.Id, new ColumnSet(true));
                    switch ((datetoUpdate.AddDays(1)).ToString("dddd"))
                    {
                        case "Sunday":
                            duration = (int) resourceschedule.Attributes["usmc_sunday"];
                            break;
                        case "Saturday":
                            duration = (int) resourceschedule.Attributes["usmc_saturday"];
                            break;
                        case "Monday":
                            duration = (int)resourceschedule.Attributes["usmc_monday"];
                            break;
                        case "Tuesday":
                            duration = (int)resourceschedule.Attributes["usmc_tuesday"];
                            break;
                        case "Wednesday":
                            duration = (int)resourceschedule.Attributes["usmc_wednesday"];
                            break;
                        case "Thursday":
                            duration = (int)resourceschedule.Attributes["usmc_thursday"];
                            break;
                        case "Friday":
                            duration = (int)resourceschedule.Attributes["usmc_friday"];
                            break;
                    }

                    TimeSpan time1 = new TimeSpan(0,9,0,0);
                    datetoUpdate = datetoUpdate.AddDays(1).Date.Add(time1);
                    //Retrieve Facilities for Specific Leav Record
                    QueryExpression Qe = new QueryExpression();
                    Qe.EntityName = "equipment";
                    Qe.ColumnSet = new ColumnSet(true);
                    ConditionExpression ce = new ConditionExpression();
                    ce.AttributeName = "usmc_resource";
                    ce.Operator = ConditionOperator.Equal;
                    ce.Values.Add(resource.Id);
                    Qe.Criteria.AddCondition(ce);
                    EntityCollection facility = service.RetrieveMultiple(Qe);
                    foreach (Entity FC in facility.Entities)
                    {
                        faciltyID = FC.Id;
                    }
                   
                    //Update Time for Specific Faciltiy/Attendance for selected date
                    // Get the calendar id of the facilities
                    Entity FaciltiyEntity = service.Retrieve("equipment", faciltyID, new ColumnSet(new String[] { "calendarid" }));


                    // Retrieve the calendar of the Facilities
                    Entity FaciltiyCalendarEntity= service.Retrieve("calendar", ((Microsoft.Xrm.Sdk.EntityReference)(FaciltiyEntity.Attributes["calendarid"])).Id, new ColumnSet(true));



                    // Retrieve the calendar rules defined in the calendar
                    EntityCollection calendarRules = (EntityCollection)userCalendarEntity.Attributes["calendarrules"];

                    //Create a new inner calendar
                    Entity newInnerCalendar = new Entity("calendar");
                    newInnerCalendar.Attributes["businessunitid"] = new EntityReference("businessunit", ((Microsoft.Xrm.Sdk.EntityReference)(userCalendarEntity["businessunitid"])).Id);
                    Guid innerCalendarId = service.Create(newInnerCalendar);

                     //Create a new calendar rule and assign the inner calendar id to it
                     Entity calendarRule = new Entity("calendarrule");
                     calendarRule.Attributes["duration"] = 1440;
                     calendarRule.Attributes["extentcode"] = 1;
                     calendarRule.Attributes["pattern"] = "FREQ=DAILY;COUNT=1";
                     calendarRule.Attributes["rank"] = 0;
                     calendarRule.Attributes["timezonecode"] = 190;
                     calendarRule.Attributes["innercalendarid"] = new EntityReference("calendar", innerCalendarId);
                     calendarRule.Attributes["starttime"] = datetoUpdate;
                     calendarRules.Entities.Add(calendarRule);

                     // assign all the calendar rule back to the Faacility calendar
                     userCalendarEntity.Attributes["calendarrules"] = calendarRules;
                     // update the Facility calendar entity that has the new rule
                     service.Update(userCalendarEntity);

                     Entity calendarRule1 = new Entity("calendarrule");
                     calendarRule1.Attributes["duration"] = duration*60;
                     calendarRule1.Attributes["effort"] = 0.0;
                    calendarRule1.Attributes["extentcode"] = 1;
                    calendarRule1.Attributes["issimple"] = true;
                     calendarRule1.Attributes["offset"] = 0;
                     calendarRule1.Attributes["rank"] = 0;
                     calendarRule1.Attributes["subcode"] = 1;
                     calendarRule1.Attributes["timecode"] = 0;
                     calendarRule1.Attributes["timezonecode"] = 190;
                     calendarRule1.Attributes["calendarid"] = new EntityReference("calendar", innerCalendarId);

                    EntityCollection innerCalendarRules = new EntityCollection();
                    innerCalendarRules.EntityName = "calendarrule";
                    innerCalendarRules.Entities.Add(calendarRule1);

                    newInnerCalendar.Attributes["calendarrules"] = innerCalendarRules;
                    newInnerCalendar.Attributes["calendarid"] = innerCalendarId;
                    service.Update(newInnerCalendar);







Hope it help you to achieve ur requirments.


Thank you












No comments:

Post a Comment