Сценарии для изменения календарей
Получение календарей
Базовым классом календаря с рабочим расписанием является справочник Календарь объекта (ResourceCalendar). В нем хранится расписание для глобального производственного календаря, который всегда присутствует в системе с Id = 1. Также в данном справочнике хранятся расписания общих календарей системы, которые можно получить, например, по наименованию. Ниже приведены примеры кода для получения календарей разными способами.
Пример без использования Public API
Пространство имен:
using EleWise.ELMA.Projects.Models.Resources; //здесь класс ResourceCalendar
using EleWise.ELMA.Model.Managers; //здесь класс EntityManager
using EleWise.ELMA.Model.Services; //здесь класс InterfaceActivator
Текст сценария
var scheduleGlobal = EntityManager<ResourceCalendar>.Instance.Load(1L); //Получение глобального производственного календаря
var manager = EntityManager<ResourceCalendar, long>.Instance;
var filter = InterfaceActivator.Create<ResourceCalendarFilter>();
filter.SearchString = "809";
var scheduleShared1 = EntityManager<ResourceCalendar, long>.Instance.Find(filter, new FetchOptions(0,1)).FirstOrDefault();//Получение общего календаря с наванием "809" через фильтр объекта по строке поиска
var scheduleShared2 = EntityManager<ResourceCalendar, long>.Instance.Find("Name like '809'").FirstOrDefault();//Получение общего календаря с названием "809" через EQL-запрос
Пример с использованием Public API
Пространство имен:
using EleWise.ELMA.API;
Текст сценария:
var scheduleGlobal = PublicAPI.Projects.Objects.Resources.ResourceCalendar.Load(1L);
var filter = PublicAPI.Projects.Objects.Resources.ResourceCalendar.Filter().SearchString("809").Filter;
var scheduleShared1 = EntityManager<ResourceCalendar, long>.Instance.Find(filter, new FetchOptions(0,1)).FirstOrDefault();//Получение общего календаря с наванием "809" через фильтр объекта по строке поиска
var scheduleShared2 = PublicAPI.Projects.Objects.Resources.ResourceCalendar.Find("Name like '809'").FirstOrDefault();//Получение общего календаря с названием "809" через EQL-запрос
После получения календаря можно проводить настройку интервалов рабочего времени, отмечать рабочие и выходные дни. Основными настраиваемыми параметрами календаря являются:
- BaseIntervals – задает базовые интервалы рабочего времени. Один интервал, если обеденный перерыв не определен, и два, если указан обед. Данный параметр влияет только на вновь создаваемые в календаре рабочие дни и исключительные рабочие дни. По умолчанию их расписание будет взято из базовых интервалов. Изменение базовых интервалов не изменяет уже существующее расписание;
- WorkIntervals – задает интервалы рабочего времени в каждый день рабочей недели, а также определяет исключительные рабочие дни (например, рабочие предпраздничные субботы);
- HolidayIntervals – определяет праздничные дни, которые выпадают на рабочие дни календаря.
Изменения в расписании глобального производственного календаря
Рассмотрим некоторые примеры по изменению расписания в глобальном производственном календаре.
Пример 1
Изменение на предприятии интервалов рабочего времени на 8:30 – 17:30 с обедом в 12:30 – 13:30.
//Задаем базовое временя работы до обеда (дата в данном случае совершенно не важна и может быть любой, важно только время)
scheduleGlobal.BaseIntervals.ElementAt(0).Start = new DateTime(2000, 1, 1, 8, 30, 0);
scheduleGlobal.BaseIntervals.ElementAt(0).Finish = new DateTime(2000, 1, 1, 12, 30, 0);
//Задаем базовое временя работы после обеда. При этом проверяем, что в календаре прописан обед и сущесвует второй интервал рабочего времени
if (scheduleGlobal.BaseIntervals.Count > 1)
{
scheduleGlobal.BaseIntervals.ElementAt(1).Start = new DateTime(2000, 1, 1, 13, 30, 0);
scheduleGlobal.BaseIntervals.ElementAt(1).Finish = new DateTime(2000, 1, 1, 17, 30, 0);
}
//Если второй интервал не прописан, то создаем его
else
{
//Или с помощью менеджера или с помощью PublicAPI
var newInterval = EntityManager<EleWise.ELMA.Calendar.Models.BaseTimeInterval>.Instance.Create();
//var newInterval = PublicAPI.Portal.Objects.Calendar.BaseTimeInterval.Create();
newInterval.Calendar = scheduleGlobal;
newInterval.Start = new DateTime(2000, 1, 1, 13, 30, 0);
newInterval.Finish = new DateTime(2000, 1, 1, 17, 30, 0);
newInterval.Save();
}
//Теперь переопределяем интервалы рабочего времени, попробуем, например, сдвинуть рабочую неделю на 1 день вперед (вт-сб)
//Удаляем записи о работе в понедельник и воскресенье
var removeInterval = scheduleGlobal.WorkIntervals.Where(c => c.DayOfWeek == 1 || c.DayOfWeek == 7).FirstOrDefault();
while (removeInterval != null)
{
scheduleGlobal.WorkIntervals.Remove(removeInterval);
removeInterval.Delete();
removeInterval = scheduleGlobal.WorkIntervals.Where(c => c.DayOfWeek == 1 || c.DayOfWeek == 7).FirstOrDefault();
}
//Правим или добавляем записи о работе со вторника по субботу
for (int day = 2; day <= 6; day++)
{
var workIntervals = scheduleGlobal.WorkIntervals.Where(c => c.DayOfWeek == day);
var interval1 = workIntervals.ElementAtOrDefault(0);
if (interval1 == null)
{
//Создаем интервал с помощью менеджера или же PublicAPI
interval1 = EntityManager<WorkTimeInterval>.Instance.Create();
//interval1 = PublicAPI.Projects.Objects.Resources.WorkTimeInterval.Create();
}
interval1.Calendar = scheduleGlobal;
interval1.DayOfWeek = day;
interval1.Start = new DateTime(2000, 1, 1, 8, 30, 0);
interval1.Finish = new DateTime(2000, 1, 1, 12, 30, 0);
interval1.Save();
var interval2 = workIntervals.ElementAtOrDefault(1);
if (interval2 == null)
{
//Создаем интервал с помощью менеджера или же PublicAPI
interval2 = EntityManager<WorkTimeInterval>.Instance.Create();
//interval2 = PublicAPI.Projects.Objects.Resources.WorkTimeInterval.Create();
}
interval2.Calendar = scheduleGlobal;
interval2.DayOfWeek = day;
interval2.Start = new DateTime(2000, 1, 1, 13, 30, 0);
interval2.Finish = new DateTime(2000, 1, 1, 17, 30, 0);
interval2.Save();
}
scheduleGlobal.Save();
Пример 2
Пусть у нас существует какой-то процесс/интеграция, через которые мы хотим задавать праздничные дни и рабочие дни-исключения. Опишем соответствующие функции:
//Функция добавления праздничного дня
public virtual bool AddHoliday(DateTime newHoliday)
{
//Отсекаем время на случай, если оно есть
DateTime newHolidayDate = newHoliday.Date;
var scheduleGlobal = EntityManager<ResourceCalendar>.Instance.Load(1L);
//var scheduleGlobal = PublicAPI.Projects.Objects.Resources.ResourceCalendar.Load(1L);
//Если указанный праздничный день уже есть в календаре, то ничего не делаем
if (scheduleGlobal.HolidayIntervals.Where(c => c.DateStart == newHolidayDate).Any())
return false;
var newCalendarHoliday = EntityManager<HolidayInterval>.Instance.Create();
//var newCalendarHoliday = PublicAPI.Projects.Objects.Resources.HolidayInterval.Create();
newCalendarHoliday.Calendar = scheduleGlobal;
newCalendarHoliday.DateStart = newHolidayDate;
newCalendarHoliday.DateFinish = newHolidayDate;
newCalendarHoliday.Save();
return true;
}
//Функция добавления исключительного рабочего дня
public virtual bool AddExceptionWorkDay(DateTime newExceptionWorkDay)
{
//Отсекаем время на случай, если оно есть
DateTime newExceptionWorkDayDate = newExceptionWorkDay.Date;
var scheduleGlobal = EntityManager<ResourceCalendar>.Instance.Load(1L);
//var scheduleGlobal = PublicAPI.Projects.Objects.Resources.ResourceCalendar.Load(1L);
//Если указанный исключительный день уже есть в календаре, то ничего не делаем
if (scheduleGlobal.WorkIntervals.Where(c => c.DateExceptionStart == newExceptionWorkDayDate).Any())
return false;
//Создаем рабочий интервал исключительного дня на каждый базовый интервал
foreach (var baseInterval in scheduleGlobal.BaseIntervals)
{
var newCalendarException = EntityManager<WorkTimeInterval>.Instance.Create();
//var newCalendarException = PublicAPI.Projects.Objects.Resources.WorkTimeInterval.Create();
newCalendarException.Calendar = scheduleGlobal;
newCalendarException.DateExceptionStart = newExceptionWorkDayDate;
newCalendarException.DateExceptionFinish = newExceptionWorkDayDate;
newCalendarException.Start = baseInterval.Start;
newCalendarException.Finish = baseInterval.Finish;
newCalendarException.Save();
}
return true;
}
Рассмотрим, как можно использовать эти функции для нашего примера компании, в которой рабочая неделя идет со вторника по субботу. Зададим праздничными днями 23 февраля, 8 и 9 марта. А за 9 марта установим рабочий день 11 марта:
AddHoliday(new DateTime(2019, 2, 23));
AddHoliday(new DateTime(2019, 3, 8));
AddHoliday(new DateTime(2019, 3, 9));
AddExceptionWorkDay(new DateTime(2019, 3, 11));
Вычисления с учетом рабочего календаря
Для проверки, является ли какой-либо день рабочим в производственном календаре, а также для вычислений с учетом производственного календаря предусмотрен сервис IProductionCalendarService.
Пример без использования Public API
Пространства имен:
using EleWise.ELMA.Services;
using EleWise.ELMA.Scheduling;
Текст сценария:
var productionCalendar = Locator.GetServiceNotNull<IProductionCalendarService>();
if (productionCalendar.IsWorkDay(context.StartDate.Value))
{
Console.WriteLine(context.Data + " - работаем");
}
else
{
Console.WriteLine(context.Data + " - отдыхаем");
}
Пример с использованием Public API
Пространство имен:
using EleWise.ELMA.API;
Текст сценария:
if (PublicAPI.Services.ProductionCalendar.IsWorkDay(context.StartDate.Value))
{
Console.WriteLine(context.Data + " - работаем");
}
else
{
Console.WriteLine(context.Data + " - отдыхаем");
}
Более подробно с функциями для вычислений с учетом производственного календаря можно ознакомится в статье https://www.elma-bpm.ru/KB/article-5494.html.