Расчет рабочего времени в Dynamics CRM 2016/365
- Алексей
- Комментариев нет
В данной статье представлен класс, который позволит производить операции с рабочим временем в Microsoft Dynamics CRM. С его помощью к заданной дате можно прибавить рабочие дни, часы и минуты.
Для использования класса необходимо создать его экземпляр, в качестве параметров передаем ссылку на сервис и сущность календаря обслуживания клиентов. Далее можно будет использовать методы AddWorkDays, AddWorkHours и AddWorkMinutes в качестве параметров они принимают дату, к которой нужно применить операцию и соответственно дни, часы и минуты, которые мы хотим прибавить к этой дате.
using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System; namespace Yandex.Money.CRM.Actions.Helpers.BusinessCalendarLogic { public class BusinessCalendarLogic { private readonly Entity _calendarWorkDay; private readonly Entity _calendarHoliday; /// <summary> /// Инициализирует новый объект для работы с рабочими днями, в качестве параметром принимает сервис CRM и календарь обслуживания клиентов /// </summary> /// <param name="service">Сервис CRM</param> /// <param name="calendar">Календарь обслуживания клиентов</param> public BusinessCalendarLogic(IOrganizationService service, Entity calendar) { var holidayschedulecalendarRef = calendar.GetAttributeValue<EntityReference>("holidayschedulecalendarid"); if (holidayschedulecalendarRef != null) _calendarHoliday = service.Retrieve(holidayschedulecalendarRef.LogicalName, holidayschedulecalendarRef.Id, new ColumnSet(true)); var calendarRules = calendar.GetAttributeValue<EntityCollection>("calendarrules"); var innercalendarRef = calendarRules[0].GetAttributeValue<EntityReference>("innercalendarid"); _calendarWorkDay = service.Retrieve(innercalendarRef.LogicalName, innercalendarRef.Id, new ColumnSet(true)); } public DateTime AddWorkDays(DateTime date, int days) { while (days > 0) { if (IsBusinessTime(date)) days--; date = date.AddDays(1); } return date; } public DateTime AddWorkHours(DateTime date, int hours) { int minutes = hours * 60; return AddWorkMinutes(date, minutes); } public DateTime AddWorkMinutes(DateTime date, int minutes) { while (minutes > 0) { if (IsBusinessTime(date)) minutes--; date = date.AddMinutes(1); } return date; } public bool IsBusinessTime(DateTime dateToCheck) { return dateToCheck.IsBusinessTime(_calendarWorkDay, _calendarHoliday); } } public static class BusinessCalendarLogicExtension { public static bool IsBusinessTime(this DateTime dateToCheck, Entity calendarWorkDay, Entity calendarHoliday) { return dateToCheck.IsBusinessTimeWorkDay(calendarWorkDay) && dateToCheck.IsBusinessTimeHoliday(calendarHoliday); } public static bool IsBusinessTimeHoliday(this DateTime dateToCheck, Entity calendar) { if (calendar == null) return true; var calendarRules = calendar.GetAttributeValue<EntityCollection>("calendarrules"); foreach (var calendarRule in calendarRules.Entities) { var startTime = calendarRule.GetAttributeValue<DateTime>("starttime"); var duration = calendarRule.GetAttributeValue<int>("duration") - 1; var endTime = startTime.AddMinutes(duration); if (dateToCheck.IsBetween(startTime, endTime)) return false; } return true; } public static bool IsBusinessTimeWorkDay(this DateTime dateToCheck, Entity calendar) { var calendarRules = calendar.GetAttributeValue<EntityCollection>("calendarrules"); foreach (var calendarRule in calendarRules.Entities) { var startTime = new DateTime(dateToCheck.Year, dateToCheck.Month, dateToCheck.Day).AddMinutes(calendarRule.GetAttributeValue<int>("offset")); var duration = calendarRule.GetAttributeValue<int>("duration"); var endTime = startTime.AddMinutes(duration); if (dateToCheck.IsBetween(startTime, endTime)) return true; } return false; } private static bool IsBetween(this DateTime input, DateTime date1, DateTime date2) { return input >= date1 && input <= date2; } } }
Класс хорошо работает при следующих настройках (в календаре выходных дней хранятся все выходные дни, включая праздники и собственно обычные выходные):
Но при необходимости можно будет его модернизировать и для работы в иных ситуациях.
Комментариев нет