Skip to main content

Notifications

Announcements

No record found.

Service | Customer Service, Contact Center, Fie...
Unanswered

Find non working hours from calendar

Posted on by 205

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

}

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Find non working hours from calendar

    Hi Suresh_Satti,

    Unfortunately, there is no OOB way to do this. You could post an idea at here(experience.dynamics.com/.../) to progress this feature.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Tips for Writing Effective Suggested Answers

Best practices for providing successful forum answers ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,280 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,235 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans