/// <summary> /// This method checks if validation rules have been set properly for all rules if not returns reason explaining what has not been set. /// </summary> /// <param name="holidayRule">List of rules to be validated.</param> /// <returns>Text explaining what has not been set properly for which rule. If all configuration valid returns null </returns> public string ValidateHolidayRule(HolidayRule holidayRule) { string validationMessage = null; var ruleConfigurationValid = true; HolidayRuleValidator holidayRuleValidator = new HolidayRuleValidator(); // Check if configuration valid for Always_Same_Day if (holidayRule.Always_Same_Day != null) { validationMessage = holidayRuleValidator.Validate_Rule_Always_Same_Day <Always_Same_Day>(holidayRule.Always_Same_Day); if (validationMessage != null) { ruleConfigurationValid = false; } } // Check if configuration is valid for Always_On_Same_Day_Except_Weekend if (ruleConfigurationValid && holidayRule.Always_On_Same_Day_Except_Weekend != null) { validationMessage = holidayRuleValidator.Validate_Rule_Always_Same_Day <Always_On_Same_Day_Except_Weekend>(holidayRule.Always_On_Same_Day_Except_Weekend); if (validationMessage != null) { ruleConfigurationValid = false; } } // Check if configuration is valid for Always_On_Same_Day_Except_Weekend if (ruleConfigurationValid && holidayRule.Nth_Occurance_Given_Month_Given_Week != null) { validationMessage = holidayRuleValidator.Validate_Rule_Nth_Occurance_Given_Month_Given_Week(holidayRule.Nth_Occurance_Given_Month_Given_Week); } return(validationMessage); }
/// <summary> /// This takes two dates, applies rules specified for holidays and returns business days between two dates(exclusive) /// </summary> /// <param name="firstDate"> date to start counting business day from (exclusive)</param> /// <param name="secondDate">date to stop counting business day to (exclusive) </param> /// <param name="holidayRule">list of rules specifying holidays</param> /// <returns> tuple containing no of Business days between two dates and validation message if validation failed </returns> public Tuple <int, string> BusinessDaysBetweenTwoDates(DateTime firstDate, DateTime secondDate, HolidayRule holidayRule) { List <DateTime> resultDateList = new List <DateTime>(); List <DateTime> holidayOnWeekEndList = new List <DateTime>(); List <DateTime> dateRange = new List <DateTime>(); List <DateTime> selectedDates_Week_Days = new List <DateTime>(); List <DateTime> selectedDates_WeekEnds = new List <DateTime>(); try { string validationMessage = null; var holidayRuleValidator = new HolidayRuleValidator(); if (holidayRule != null) { validationMessage = holidayRuleValidator.ValidateHolidayRule(holidayRule); // If rules configuration is valid allow to proceed further. if (validationMessage == null) { var DateHelper = new DateHelper(); dateRange = DateHelper.GetSelectedDateRange(firstDate, secondDate); selectedDates_Week_Days = DateHelper.GetWeekDays(dateRange); selectedDates_WeekEnds = DateHelper.GetWeekEnds(dateRange); // Find holidays which are always on same day and falls on week days. foreach (Always_Same_Day always_Same_Day_Rule in holidayRule.Always_Same_Day) { resultDateList.AddRange(selectedDates_Week_Days.ToList().FindAll(d => d.Day == always_Same_Day_Rule.Day && d.Month == always_Same_Day_Rule.Month && !resultDateList.Any(rs => rs == d))); } // Find holidays which are always on same day except on weekend. foreach (Always_On_Same_Day_Except_Weekend always_On_Same_Day_Except_Weekend in holidayRule.Always_On_Same_Day_Except_Weekend) { // Always on same day except on weekend, which are not on weekends resultDateList.AddRange(selectedDates_Week_Days.ToList().FindAll(d => d.Day == always_On_Same_Day_Except_Weekend.Day && d.Month == always_On_Same_Day_Except_Weekend.Month && !resultDateList.Any(rs => rs == d))); // So we are only interested in weekends which also are public holidays and are part of Always_On_Same_Day_Except_Weekend holidayOnWeekEndList = selectedDates_WeekEnds.ToList().FindAll(d => d.Day == always_On_Same_Day_Except_Weekend.Day && d.Month == always_On_Same_Day_Except_Weekend.Month); } // Find holidays which falls on Nth occurrence of given week day in given month. foreach (Nth_Occurrence_Given_Month_Given_Week objRule in holidayRule.Nth_Occurance_Given_Month_Given_Week) { // We only need to consider week day as week end has already been taken care of. resultDateList.AddRange(selectedDates_Week_Days.ToList().FindAll(d => d.Month == objRule.Month && Convert.ToInt32(d.DayOfWeek) == objRule.DayOfWeek && d.Date == DateHelper.GetDayOfMonth(d.Date , Convert.ToInt32(objRule.WeekOfMonth), Convert.ToInt32(objRule.DayOfWeek)))); } } } return(Tuple.Create(selectedDates_Week_Days.Count - (resultDateList.Count + holidayOnWeekEndList.Count), validationMessage)); } catch (Exception ex) { return(Tuple.Create(0, "A fatal error occurred while calculating business days")); } finally { resultDateList = null; holidayOnWeekEndList = null; dateRange = null; selectedDates_Week_Days = null; selectedDates_WeekEnds = null; } }