Hello All,
I am trying to find business hours from the calendar and while i was exploring for options i did not find anything other than creating a custom workflow activity that queries the calendar and determining any holidays and weekends. I would like to really use a non code solution, is it possible?
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using Microsoft.Xrm.Sdk.Workflow; using System; using System.Activities; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WorkHours { public class CalculateBusinessHours : CodeActivity { [RequiredArgument] [Input("Start Date")] public InArgument StartDate { get; set; } [RequiredArgument] [Input("End Date")] public InArgument EndDate { get; set; } [RequiredArgument] [Input("Exclude Weekend?")] public InArgument ExcludeWeekend { get; set; } [RequiredArgument] [Input("Exclude Busines Closure")] public InArgument ExcludeBusinessClosure { get; set; } [Output("Minutes")] public OutArgument Minutes { get; set; } [Output("Hours")] public OutArgument Hours { get; set; } protected override void Execute(CodeActivityContext excontext) { IWorkflowContext context = excontext.GetExtension(); IOrganizationServiceFactory factory = excontext.GetExtension(); IOrganizationService service = factory.CreateOrganizationService(context.UserId); List Closures = new List(); Util helper = new Util(); if (ExcludeBusinessClosure.Get(excontext)) { Closures = helper.GetClosureConfig(service); } #region CalculateMinutes int TotalMinutes = CalculateMinutes(StartDate.Get(excontext), EndDate.Get(excontext), Closures, ExcludeWeekend.Get(excontext), 8, 30, 17, 0, service); decimal TotalHours = CalculateHours(TotalMinutes); Minutes.Set(excontext, TotalMinutes); Hours.Set(excontext, TotalHours); #endregion } private int CalculateMinutes(DateTime StartDate, DateTime EndDate, List ListClosure, bool ExcludeWeekend, int StartHours, int StartMinutes, int EndHours, int EndMinutes, IOrganizationService service) { #region Office Start/End Time TimeSpan OfficeStart = new TimeSpan(StartHours, StartMinutes, 0); TimeSpan OfficeEnd = new TimeSpan(EndHours, EndMinutes, 0); #endregion #region CalculateMinutes Util helper = new Util(); //Converting Local time from UTC DateTime EDate = TimeConversionUtility.GetLocalTime(EndDate, service); DateTime SDate = TimeConversionUtility.GetLocalTime(StartDate, service); StartDate = SDate.AddSeconds(SDate.Second * -1); EndDate = EDate.AddSeconds(EDate.Second * -1); int TotalMinutes = 0; while (StartDate < EndDate) { bool IsDayAddRequired = true; #region Logic for calculating Minutes if (!helper.IsBusinessClosure(StartDate, ListClosure)) { if (ExcludeWeekend) { if (helper.IsInDaysConfigured(StartDate)) { if (StartDate.TimeOfDay >= OfficeStart && StartDate.TimeOfDay <= OfficeEnd) { if (StartDate.Date == EndDate.Date) { if (EndDate.TimeOfDay > OfficeEnd) EndDate = EndDate.Date.AddHours(EndHours).AddMinutes(EndMinutes); TimeSpan span = EndDate.Subtract(StartDate); TotalMinutes = (int)span.TotalMinutes; //IsDayAddRequired = true; //Logic for subtracting Lunch break if (EndDate.TimeOfDay >= new TimeSpan(12, 30, 0) && StartDate.TimeOfDay <= new TimeSpan(12, 0, 0)) { //Subtract Lunch TotalMinutes = TotalMinutes - 30; } else if (EndDate.TimeOfDay >= new TimeSpan(12, 0, 0) && EndDate.TimeOfDay <= new TimeSpan(12,30,0)) { TotalMinutes = TotalMinutes - EndDate.Minute; } } else { TimeSpan span = StartDate.Date.AddHours(EndHours).AddMinutes(EndMinutes).Subtract(StartDate); TotalMinutes = (int)span.TotalMinutes; //Subtract Lunch break TotalMinutes = TotalMinutes - 30; //IsDayAddRequired = true; } } else if (StartDate.TimeOfDay < OfficeStart) { StartDate = StartDate.Date.AddHours(StartHours).AddMinutes(StartMinutes); IsDayAddRequired = false; } } } else { if (StartDate.TimeOfDay >= OfficeStart && StartDate.TimeOfDay <= OfficeEnd) { if (StartDate.Date == EndDate.Date) { TimeSpan span = EndDate.Subtract(StartDate); TotalMinutes = (int)span.TotalMinutes; //IsDayAddRequired = true; } else { TimeSpan span = StartDate.Date.AddHours(EndHours).AddMinutes(EndMinutes).Subtract(StartDate); TotalMinutes = (int)span.TotalMinutes; //IsDayAddRequired = true; } } else if (StartDate.TimeOfDay < OfficeStart) { StartDate = StartDate.Date.AddHours(StartHours).AddMinutes(StartMinutes); IsDayAddRequired = false; } } } #endregion if (IsDayAddRequired) StartDate = StartDate.AddDays(1).Date.AddHours(StartHours).AddMinutes(StartMinutes); } return TotalMinutes; #endregion } private decimal CalculateHours(int TotalMinutes) { return (TotalMinutes / 60M); } } class Util { public bool IsInDaysConfigured(DateTime Dt) { bool IsValidForTheDay = false; switch (Dt.DayOfWeek) { case DayOfWeek.Sunday: IsValidForTheDay = false; break; case DayOfWeek.Monday: IsValidForTheDay = true; break; case DayOfWeek.Tuesday: IsValidForTheDay = true; break; case DayOfWeek.Wednesday: IsValidForTheDay = true; break; case DayOfWeek.Thursday: IsValidForTheDay = true; break; case DayOfWeek.Friday: IsValidForTheDay = true; break; case DayOfWeek.Saturday: IsValidForTheDay = false; break; } return IsValidForTheDay; } public bool IsBusinessClosure(DateTime Dt, List BusinessClosure) { bool IsBusinessClosure = false; foreach (ClosureConfig rule in BusinessClosure) { if (Dt >= rule.Start && Dt <= rule.End) { IsBusinessClosure = true; } } return IsBusinessClosure; } public List GetClosureConfig(IOrganizationService service) { List list = new List(); QueryByAttribute query = new QueryByAttribute(); query.EntityName = "calendar"; query.Attributes.Add("name"); query.Values.Add("Business Closure Calendar"); query.ColumnSet = new ColumnSet(true); EntityCollection collection = service.RetrieveMultiple(query); EntityCollection CalenderRules = collection.Entities[0].Attributes["calendarrules"] as EntityCollection; foreach (Entity Calender in CalenderRules.Entities) { if (Calender.Attributes.Contains("effectiveintervalend") && Calender.Attributes.Contains("effectiveintervalstart")) { DateTime StartDate = (DateTime)Calender.Attributes["effectiveintervalstart"]; DateTime EndDate = (DateTime)Calender.Attributes["effectiveintervalend"]; list.Add(new ClosureConfig() { Start = StartDate, End = EndDate }); } } return list; } } class ClosureConfig { public DateTime Start { get; set; } public DateTime End { get; set; } } }