Редактирование календарей рабочего времени с помощью API-интерфейсов

Организациям часто требуется программно создавать, редактировать или удалять рабочие часы в календарях своих ресурсов. Календари показывают рабочее время, нерабочее время и перерывы, которые определяют доступность ресурса при планировании работы. Эти ресурсы должны быть запланированы в определенных часовых поясах, могут соблюдать или не соблюдать время, когда бизнес закрыт, и могут иметь переменную емкость. Для получения информации об определении рабочего времени в приложении Field Service перейдите по ссылке Добавление рабочих часов к ресурсу, доступному для резервирования.

Помимо использования приложения Field Service, вы можете использовать следующие API-интерфейсы для изменения правил календаря для выбранных типов записей:

  • API-интерфейс сохранения календаря (msdyn_SaveCalendar) создает или обновляет записи календаря для выбранной сущности на основе входных данных, переданных в качестве запроса.
  • API-интерфейс удаления календаря (msdyn_DeleteCalendar) удаляет все правила внутреннего календаря из календаря для выбранной сущности на основе входных данных, переданных в качестве запроса.
  • API сохранения/удаления календаря версии 2 (msdyn_SaveCalendar/msdyn_DeleteCalendar, флаг передачи UseV2) позволяет одновременно повторять несколько рабочих часов, изменяя логику перекрывающихся правил. Для получения дополнительной информации см. раздел Что произойдет, если есть перекрывающиеся правила?.

Эта статья содержит подробную информацию о вводных (запрос) и выходных (ответ) данных каждого API-интерфейса, а также об их использовании, с примерами.

Предварительные условия

  • Версия платформы 9.2.21055 или выше с Universal Resource Scheduling версии 3.12.45.7.
  • Использование одного из следующих типов записей:
    • Резервируемые ресурс (bookableresource)
    • Требование ресурса (msdyn_resourcerequirement)
    • Шаблон рабочего времени (msdyn_workhourtemplate)
    • Проект (msdyn_project)

Типы событий календаря

Когда вы создаете календарь, вы определяете, сколько раз тип рабочего времени произойдет — один раз, весь день, каждую неделю или каждый день, или вы можете создать настраиваемое повторение. Для получения дополнительной информации об этих календарных событиях перейдите к примерам далее в этой статье.

Вхождение

Когда тип рабочего времени встречается только один раз в календаре сущности, он называется вхождение.

Например, рассмотрим ресурс, работающий с 5:00 до 10:00 26 мая 2021 года. Эти API-интерфейсы поддерживают только этот тип событий, которые начинаются и заканчиваются в один и тот же день. В качестве другого примера рассмотрим ресурс, работающий с 20:00 26 мая 2021 года до 10:00 27 мая 2021 года. Вы не можете создать это вхождение, используя только один вызов API msdyn_SaveCalendar; вместо этого вам нужно сделать два вызова.

Вхождение на весь день

Когда тип рабочего времени соответствует одному или нескольким полным дням, начиная с полуночи (00:00) даты начала, это вхождение на целый день. Максимальная продолжительность вхождения на целый день — пять лет.

Например, ресурс работает круглосуточно с 26 мая 2021 года до конца дня 30 мая 2021 года. Это круглосуточное вхождение, которое длится пять дней.

Повторение еженедельно

Когда тип рабочего времени наступает в одно и то же время в выбранные дни каждой недели, это называется еженедельным повторением.

Например, ресурс работает с 5:00 до 10:00 каждый понедельник, вторник и среду.

Повторение ежедневно

Когда тип рабочего времени наступает в одно и то же время каждый день, это называется ежедневным повторением.

Например, ресурс работает с 5:00 до 10:00 каждый день недели.

Настраиваемое повторение

Когда тип рабочего времени наступает в определенное время в определенные дни недели, но время различается в разные дни, вы можете создать настраиваемое повторение.

Например, ресурс работает с 5:00 до 10:00 каждый понедельник и с 12:00 до 15:00 каждую среду.

Типы рабочих часов

Эти API-интерфейсы поддерживают операции создания, обновления и удаления для следующих типов рабочего времени:

Рабочие часы

Рабочее время — это время, в течение которого сущность доступна для выполнения работы.

Используя эти API-интерфейсы, вы можете делать следующее:

  • Создание, редактирование или удаление вхождения рабочего времени.
  • Создание, редактирование или удаление ежедневного повторения рабочего времени.
  • Создание, редактирование или удаление еженедельного повторения рабочего времени.
  • Создание, редактирование или удаление настраиваемого повторения рабочего времени.
  • Создание, редактирование или удаление круглосуточного рабочего времени.
  • Создание или редактирование емкости в рабочее время.
  • Изменение единичного вхождения рабочего времени в повторении.
  • Редактирование Это и последующие вхождения в повторении.
  • Изменение вхождения рабочего времени в повторение.
  • Изменение часового пояса для правила календаря.

Используя этот API-интерфейс, вы не можете делать следующее:

  • Удаление единичного вхождения рабочего времени из повторения.
  • Создание вхождения, которое длится 24 часа, но не начинается и не заканчивается в полночь (00:00).
  • Создание, редактирование или удаление круглосуточного повторения.

Нерабочие часы

Это периоды, когда сущность недоступна для работы по неуказанной причине.

Используя эти API-интерфейсы, вы можете делать следующее:

  • Создание или редактирование нерабочего времени на весь день.
  • Создание или редактирование вхождения нерабочего времени.
  • Изменение часового пояса для правила календаря.

Используя эти API-интерфейсы, вы не можете делать следующее:

  • Создание или редактирование повторения нерабочего времени.

Прервать

Это периоды рабочего дня, когда сущность делает перерыв и не может работать. Перерывы не могут существовать без рабочего времени; они должны происходить между двумя периодами рабочего времени в день. Перерывы не могут перекрываться с рабочим временем.

Используя эти API-интерфейсы, вы можете делать следующее:

  • Создание или редактирование перерывов во время рабочего времени.

Используя эти API-интерфейсы, вы не можете делать следующее:

  • Удаление только перерывов из вхождения или повторения рабочего времени.

Выходные

Это периоды, когда сущность недоступна для работы по причине отпуска. Причину выходных можно указать.

Используя эти API-интерфейсы, вы можете делать следующее:

  • Создание или редактирование выходных с меткой.
  • Изменение часового пояса для правила календаря.

Используя эти API-интерфейсы, вы не можете делать следующее:

  • Создание или редактирование повторения времени выходных.

Нерабочий день

Вы можете создавать сущности нерабочих дней бизнеса, которые определяют время, когда компания не работает. С помощью API-интерфейса msdyn_SaveCalendar вы можете настроить каждую сущность для соблюдения или игнорирования нерабочего времени компании с помощью необязательного ключа ObserveClosure. Когда они настроены на соблюдение этих нерабочих периодов, сущности недоступны для работы.

API-интерфейс сохранения календаря

Входные данные

Запрос содержит только один атрибут — CalendarEventInfo, который имеет тип Строка. Он содержит несколько других атрибутов, встроенных в эту строку.

Заметка

В следующей таблице Тип представляет формат, который ожидается, чтобы был успешный запрос. Однако весь запрос анализируется как одна строка.

CalendarEventInfo

имени Тип Обязательное поле Описание
EntityLogicalName String Да Этот ключ описывает сущность, из которой вызывается API. Календарь этой сущности должен быть создан или отредактирован.
CalendarId GUID Да Этот ключ содержит идентификатор календаря, относящийся к описанной выше сущности. Когда создается какая-либо из этих сущностей, автоматически создается календарная запись. Эти API-интерфейсы редактируют эту календарную запись, добавляя правила или редактируя существующие правила.
RulesAndRecurrences RulesAndRecurrences Да Этот ключ представляет собой массив, и каждый элемент содержит несколько атрибутов, перечисленных в таблице в следующем разделе. Размер массива должен быть не меньше единицы.
IsVaried Логическое значение No Этот ключ должен быть установлен на true для пользовательских сценариев повторения.
IsEdit Логическое значение No Этот ключ должен быть установлен на true для редактирования существующих правил.
TimeZoneCode Integer No Этот ключ принимает целочисленное значение, соответствующее часовому поясу для правил календаря. Для сопоставления см. раздел Коды часовых поясов далее в этой статье. Значение по умолчанию — часовой пояс пользователя.
InnerCalendarDescription String No Этот ключ нужен только в том случае, если правило календаря предназначено для выходного дня. В нем должна быть указана причина выходного.
ObserveClosure Логическое значение No Этот ключ специфичен для повторений. Если он установлен на true, сущность соблюдает нерабочее время компании.
RecurrenceEndDate Дата/время No Этот ключ специфичен для повторений. Он содержит дату окончания повторения. Если метка времени — 08:00:00 или раньше, дата окончания повторения будет за день до указанной даты. Если метка времени — 08:00:01 или позже, дата учитывается как есть. Значение по умолчанию для вхождений — null. Значение по умолчанию для повторений: 30 декабря 9999 г., 23:59:59 часов, время в формате UTC.
RecurrenceSplit Логическое значение No Этот ключ специфичен для повторений. Он установлен на true для редактирования "Это и следующие вхождения" повторения.
ResourceId GUID No Этот ключ содержит SystemUserId или же ResourceId и должен передаваться только в том случае, если сущность, связанная с этим вызовом, является резервируемым ресурсом типа SystemUser. Это необходимо для проверки прав OwnCalendar на вкладке Управление службой.
UseV2 Флаг No Передача этого флага включает версию календаря рабочего времени V2 с улучшенной логикой перекрывающихся правил, допускающей многократное повторение. Для получения дополнительной информации см. раздел Что произойдет, если есть перекрывающиеся правила?.

RulesAndRecurrences

Полное имя Type Обязательно Описание:
Правила Правила Да Этот ключ представляет собой массив, и каждый элемент содержит несколько атрибутов, перечисленных в таблице в следующем разделе. Размер массива должен быть не меньше единицы.
RecurrencePattern String No Этот ключ специфичен для повторений. В настоящее время мы поддерживаем только этот шаблон: FREQ=WEEKLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA. BYDAY можно изменить, чтобы включить меньшее количество дней; тем не менее, FREQ и INTERVAL не могут быть изменены.
InnerCalendarId GUID No Этот ключ специфичен для редактирования. Если правило редактируется, InnerCalendarId необходимо передать здесь. Если InnerCalendarId не передается, API создает новое правило, даже если ключ IsEdit установлен в значение true.
Действие Integer No Этот ключ специфичен для настраиваемых повторений. Если настраиваемое повторение создается или редактируется, необходимо ввести одно из следующих чисел:
  • (1) Добавление дня к повторению
  • (2) Удаление дня из повторения
  • (3) Редактирование только начальной или конечной даты или времени или редактирование емкости
  • (4) Редактирование чего-либо, кроме ключей, упомянутых в (3)

Правила

имени Тип Обязательное поле Описание
Время начала Дата/время Да Этот ключ содержит запись даты и времени в формате ISO. Например: \"2021-05-15T12:00:00.000Z\". Временная часть определяет время начала рабочего времени в указанном ранее часовом поясе. Часть даты определяет дату начала рабочего времени. Здесь 15 мая 2021 года — это дата вхождения или начальная дата повторения. Если бы шаблон был BYDAY=TU,WE, но дата была бы 15 мая (суббота), API автоматически создаст или изменит правила для всех вторников и сред после 15 мая. Это тот случай, когда в правиле не обязательно должна быть дата, соответствующая дню.
EndTime Дата/время Да Он содержит запись даты и времени в формате ISO. Например: \"2021-05-15T12:00:00.000Z\". Временная часть определяет время окончания рабочего времени в указанном ранее часовом поясе. Часть даты должна содержат ту же дату, что и часть даты StartTime. Единственные исключения:
  • Если это вхождение на весь день. В этом случае часть даты должна отражать дату окончания вхождения на весь день.
  • Вхождение заканчивается в конце дня, то есть в 00:00 следующего дня. В этом случае дата должна быть \"2021-05-16T00:00:00.000Z\". Чтобы указать дату окончания повторения, измените атрибут RecurrenceEndDate.
WorkHourType Integer Да Этот ключ содержит номер, соответствующий одному из следующих вариантов:
  • (0) Работает
  • (1) Перерыв
  • (2) Не работает
  • (3) Выходные
Трудозатраты Целое No Этот ключ определяет емкость сущности. Он должен быть задан целым числом. Значение по умолчанию равно 1.

Выходные данные

Этот POST API-интерфейс создает или изменяет записи правил календаря для выбранной сущности. Он также дает следующий результат.

имени Тип Описание
InnerCalendarIds String Массив идентификаторов GUID InnerCalendarIds, которые являются результатом операции POST.

API-интерфейс удаления календаря

Входные данные

имени Тип Обязательное поле Описание
EntityLogicalName String Да Это поле описывает сущность, календарные правила которой должны быть удалены.
InnerCalendarId GUID Да Это поле описывает идентификатор InnerCalendarId, который нужно удалить. Если есть несколько InnerCalendarIds, связанных с одним правилом, здесь достаточно одного любого из этих идентификаторов. Подробнее о внутренних и внешних календарях: Сущности календаря
CalendarId GUID Да Это поле описывает CalendarId сущности.
IsVaried Логическое значение No Это поле относится к повторениям и имеет значение yes, если пользовательское правило повторения удаляется.
UseV2 Флаг No Передача этого флага включает версию календаря рабочего времени V2 с улучшенной логикой перекрывающихся правил, допускающей многократное повторение. Для получения дополнительной информации см. раздел Что произойдет, если есть перекрывающиеся правила?.

Выходные данные

Этот POST API-интерфейс удаляет записи правил календаря для выбранной сущности. Кроме того, он также дает следующий результат.

имени Тип Описание
InnerCalendarIds String Массив идентификаторов GUID InnerCalendarIds, которые являются результатом операции POST.

API-интерфейс загрузки календаря

Входные данные

Имя: msdyn_LoadCalendars
Тип: Действие
Описание: Возвращает календари для заданного LoadCalendarsInput.

Имя: msdyn_LoadCalendars.LoadCalendarsInput
Тип: Параметр
Описание: Строка в следующем формате JSON:

{
   StartDate: string,
   EndDate: string,
   CalendarIds: string[]
}

Имя: msdyn_LoadCalendarsResponse
Тип: ComplexType
Описание: Содержит ответ из действия msdyn_loadCalendars.

Имя: msdyn_LoadCalendarsResponse.CalendarEvents
Тип: Свойство
Описание: Строка в следующем формате JSON:

{
"calendarId": CalendarEventSlot[]
}

Где CalendarId — это правильный идентификатор Guid, представляющий Guid календаря, а CalendarEventSlot — это объект следующего формата:

{
  CalendarId: string,
  InnerCalendarId: string,
  Start: string,
  End: string,
  Effort: double
}

Как вызывать это API-интерфейсы

Эти API-интерфейсы можно вызывать с помощью браузера.

  1. Откройте браузер и организацию, в которой вам нужно внести эти изменения в календарь.
  2. Откройте инструменты разработчика (выберите Ctrl+Shift+I в Microsoft Edge, выберите F12 в Google Chrome).
  3. В консоли введите следующую функцию после замены [org-name] на сведения об организации (например, http://your_org.crm.dynamics.com):
       function CalendarAction(action, data) {
           let req = new XMLHttpRequest();
           req.open("POST", "**[org-name]**/api/data/v9.0/" + action, true);
           req.setRequestHeader("OData-MaxVersion", "4.0");
           req.setRequestHeader("OData-Version", "4.0");
           req.setRequestHeader("Accept", "application/json");
           req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
           req.setRequestHeader("Prefer", 'odata.include-annotations="*"');
           req.onreadystatechange = function () {
               if (this.readyState === 4) {
                   req.onreadystatechange = null;
                   if(this.status == 200) {
                       console.log(JSON.parse(this.response));
                   } else {
                       console.error(JSON.parse(this.response));
                   }
               }
           };
           req.send(JSON.stringify(data));
       }
  1. После того как эта функция определена, вы можете вызывать ее для создания, редактирования или удаления календарей с помощью этих API-интерфейсов. Введите следующий вызов, чтобы сохранить календарь:
       CalendarAction("msdyn_SaveCalendar",{
           "CalendarEventInfo":"{
               \"CalendarId\":\"df0857c4-50f5-4576-8e89-f236670ad2d5\",
               \"EntityLogicalName\":\"bookableresource\",
               \"TimeZoneCode\":92,\"StartDate\":\"2021-04-25T00:00:00.000Z\",
               \"IsVaried\":false,
               \"RulesAndRecurrences\":[{
                   \"Rules\":[{
                       \"StartTime\":\"2021-04-25T08:00:00.000Z\",
                       \"EndTime\":\"2021-04-25T17:00:00.000Z\",
                       \"Duration\":540,
                       \"Effort\":1
                   }]
               }]
           }"
       })

Введите следующий вызов, чтобы удалить календарь:

       CalendarAction("msdyn_DeleteCalendar", {
           "CalendarEventInfo":"{
               \"CalendarId\":\"8390358c-77d0-430f-b176-f27adadac8eb\",
               \"EntityLogicalName\":\"bookableresource\",
               \"InnerCalendarId\":\"cf508c2c-5c55-485c-be1e-d2ebcb385441\"
           }"
       })
       

В следующем разделе приведены примеры того, как совершать различные вызовы в зависимости от ваших потребностей. Замените action вызова функции на шаге 3 на msdyn_SaveCalendar или msdyn_DeleteCalendar и замените data на соответствующее значение CalendarEventInfo.

Также см. следующий снимок экрана с вызовом Power Automate к msdyn_SaveCalendar действию: Вызов действия msdyn_SaveCalendar в Power Automate.

Примеры сценариев использования API

Давайте рассмотрим некоторые сценарии, для которых вы можете использовать эти API-интерфейсы.

Боб и Тим — водители грузовиков для службы доставки Contoso Enterprises в Белвью, штат Вашингтон. Их диспетчер, Дебби, отвечает за изменения в их календарях рабочего времени. Дебби вносит эти изменения, используя API-интерфейсы msdyn_SaveCalendar и msdyn_DeleteCalendar.

Создание вхождения рабочего времени.

Боб запланирован ездить, чтобы доставить посылки с 9:00 до 17:00 15 мая 2021 года. Дебби использует API msdyn_SaveCalendar.

Запрос

{
 "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-15T09:00:00.000Z\",\"EndTime\":\"2021-05-15T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}]}]}"
}

Response

{
  "InnerCalendarIds": "[\"f76cc333-cbbe-eb11-a81d-000d3a6e4359\"]"
}

Изменение вхождения рабочего времени.

Затем расписание Боба изменяется и работа начнется в 10:00 15 мая 2021 года. Дебби использует API msdyn_SaveCalendar.

Запрос

{
 "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"IsEdit\":\"true\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-15T10:00:00.000Z\",\"EndTime\":\"2021-05-15T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}], \"InnerCalendarId\":\"f76cc333-cbbe-eb11-a81d-000d3a6e4359\"}]}"
}

Response

{
  "InnerCalendarIds": "[\"f76cc333-cbbe-eb11-a81d-000d3a6e4359\"]"
}

Удаление вхождения рабочего времени.

Наступает чрезвычайная ситуация в семье, и Бобу нужно отменить весь свой рабочий день. Дебби использует API msdyn_DeleteCalendar.

Запросить

{
 "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"InnerCalendarId\":\"f76cc333-cbbe-eb11-a81d-000d3a6e4359\"}"
}

Отклик

{
  "InnerCalendarIds": "[\"f76cc333-cbbe-eb11-a81d-000d3a6e4359\"]"
}

Создание ежедневного повторения рабочего времени

Боб решает работать на Contoso всю неделю с 8:00 до 17:00 начиная с 20 мая 2021 г. и прекратить работу там 15 июля 2021 г.

Запросить

{
 "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RecurrenceEndDate\":\"2021-07-15T00:00:00.000Z\",\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-20T08:00:00.000Z\",\"EndTime\":\"2021-05-20T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA\"}]}"
}

Отклик

{
  "InnerCalendarIds": "[\"20f6cfa7-cfbe-eb11-a81d-000d3a6e4359\"]"
}

Редактирование ежедневного повторения рабочего времени с увеличенной емкостью

Боб решает прекратить работать всю неделю с 15 июня 2021 года, чтобы сделать перерыв. А до тех пор Боб будет продолжать работать по ранее согласованному графику на всю неделю. Дебби вносит эти изменения, используя API-интерфейс msdyn_SaveCalendar.

Запрос

{
 "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RecurrenceEndDate\":\"2021-06-15T00:00:00.000Z\",\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-20T08:00:00.000Z\",\"EndTime\":\"2021-05-20T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"InnerCalendarId\":\"20f6cfa7-cfbe-eb11-a81d-000d3a6e4359\",\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA\"}]}"
}

Response

{
  "InnerCalendarIds": "[\"867a2461-cdbe-eb11-a81d-000d3a6e4359\"]"
}

Создание еженедельного повторения рабочего времени

С 16 июня 2021 года Боб будет работать с 8:00 до 17:00 по средам и пятницам и будет делать перерыв на обед с 12:00 до 12:30. Дебби использует API msdyn_SaveCalendar но ошибается и планирует перерыв с 12:00 до 13:00.

Запросить

{
  "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-06-16T08:00:00.000Z\",\"EndTime\":\"2021-06-16T12:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}, {\"StartTime\":\"2021-06-16T12:00:00.000Z\",\"EndTime\":\"2021-06-16T13:00:00.000Z\",\"Effort\":null,\"WorkHourType\":1}, {\"StartTime\":\"2021-06-16T13:00:00.000Z\",\"EndTime\":\"2021-06-16T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=WE,TH,FR\"}]}"
}

Отклик

{
  "InnerCalendarIds": "[\"1f894441-d0be-eb11-a81d-000d3a6e4359\"]"
}

Изменение перерыва в еженедельном повторении рабочего времени

Затем Дебби исправляет ошибку и устанавливает перерыв с 12:00 до 12:30 с помощью API msdyn_SaveCalendar.

Запрос

{
  "CalendarEventInfo": "{\"CalendarId\":\"d33263c7-c16b-4e3e-a56a-20f7a66cafc1\",\"EntityLogicalName\":\"bookableresource\",\"IsEdit\":\"true\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-06-15T08:00:00.000Z\",\"EndTime\":\"2021-06-15T12:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}, {\"StartTime\":\"2021-06-15T12:00:00.000Z\",\"EndTime\":\"2021-06-15T12:30:00.000Z\",\"Effort\":null,\"WorkHourType\":1}, {\"StartTime\":\"2021-06-15T12:30:00.000Z\",\"EndTime\":\"2021-06-15T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"InnerCalendarId\":\"1f894441-d0be-eb11-a81d-000d3a6e4359\",\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=WE,TH,FR\"}]}"
}

Отклик

{
  "InnerCalendarIds": "[\"1f894441-d0be-eb11-a81d-000d3a6e4359\"]"
}

Создание настраиваемого повторения рабочего времени

Тим работает в Contoso по понедельникам с 8:00 до 17:00 и по средам с 11:00 до 15:00. Тим начал работать в Contoso 16 мая 2021 г. Дебби использует API msdyn_SaveCalendar для создания рабочего времени Тима.

Запрос

{
"CalendarEventInfo": "{\"CalendarId\":\"a68245c9-ba2e-4496-9c18-3bee75fda396\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"IsVaried\":true,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-16T08:00:00.000Z\",\"EndTime\":\"2021-05-16T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"Action\":1,\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO\"},{\"Rules\":[{\"StartTime\":\"2021-05-16T11:00:00.000Z\",\"EndTime\":\"2021-05-16T15:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"Action\":1,\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=WE\"}]}"
}

Response

{
  "InnerCalendarIds": "[\"9fb8c199-d1be-eb11-a81d-000d3a6e4359\", \"a2b8c199-d1be-eb11-a81d-000d3a6e4359\"]"
}

Изменение настраиваемого повторения рабочего времени

Затем график Тима меняется: теперь он работает по средам с 17:00 до 20:00 и в четверг с 10:00 до 12:00. Понедельник исключается из расписания Тима. Дебби использует API msdyn_SaveCalendar для этого.

Запросить

{
"CalendarEventInfo": "{\"CalendarId\":\"a68245c9-ba2e-4496-9c18-3bee75fda396\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"IsVaried\":true,\"IsEdit\":true,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-16T08:00:00.000Z\",\"EndTime\":\"2021-05-16T17:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"Action\":2,\"InnerCalendarId\":\"9fb8c199-d1be-eb11-a81d-000d3a6e4359\",\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=MO\"},{\"Rules\":[{\"StartTime\":\"2021-05-16T17:00:00.000Z\",\"EndTime\":\"2021-05-16T20:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"Action\":3,\"InnerCalendarId\":\"a2b8c199-d1be-eb11-a81d-000d3a6e4359\",\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=WE\"}, {\"Rules\":[{\"StartTime\":\"2021-05-16T10:00:00.000Z\",\"EndTime\":\"2021-05-16T12:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}],\"Action\":1,\"InnerCalendarId\":null,\"RecurrencePattern\":\"FREQ=WEEKLY;INTERVAL=1;BYDAY=TH\"}]}"
}

Отклик

{
  "InnerCalendarIds": "[\"a2b8c199-d1be-eb11-a81d-000d3a6e4359\", \"942bda0f-d3be-eb11-a81d-000d3a6e4359\"]"
}

Изменение вхождения рабочего времени в повторении

26 мая 2021 года Тим сможет работать только с 13:00 до 19:00. Здесь Дебби использует API msdyn_SaveCalendar.

Запросить

{
 "CalendarEventInfo": "{\"CalendarId\":\"a68245c9-ba2e-4496-9c18-3bee75fda396\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-26T13:00:00.000Z\",\"EndTime\":\"2021-05-26T19:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}], \"InnerCalendarId\":\"a2b8c199-d1be-eb11-a81d-000d3a6e4359\"}]}"
}

Отклик

{
  "InnerCalendarIds": "[\"a2b8c199-d1be-eb11-a81d-000d3a6e4359\"]"
}

Удаление настраиваемого повторения рабочего времени

Тим решил покинуть компанию и должен удалить все свое расписание. Здесь Дебби использует API msdyn_DeleteCalendar.

Запросить

{
 "CalendarEventInfo": "{\"CalendarId\":\"a68245c9-ba2e-4496-9c18-3bee75fda396\",\"EntityLogicalName\":\"bookableresource\",\"InnerCalendarId\":\"34d2210c-9fb6-eb11-a820-000d3afb1dba\",\"IsVaried\":true}"
}

Отклик

{
  "InnerCalendarIds": "[\"a2b8c199-d1be-eb11-a81d-000d3a6e4359\", \"942bda0f-d3be-eb11-a81d-000d3a6e4359\"]"
}

Создание выходных

Тим возьмет три дня выходных для семейного отдыха, начиная с 9 июня 2021 года.

Запрос

{
 "CalendarEventInfo": "{\"CalendarId\":\"a68245c9-ba2e-4496-9c18-3bee75fda396\",\"InnerCalendarDescription\":\"Family Vacation\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-06-15T00:00:00.000Z\",\"EndTime\":\"2021-06-17T00:00:00.000Z\",\"Effort\":1,\"WorkHourType\":3}]}]}"
}

Response

{
  "InnerCalendarIds": "[\"266c434e-d5be-eb11-a81d-000d3a6e4359\"]"
}

Создание рабочего времени на весь день

С 20 мая 2021 года у Тима 72-часовая смена. Дебби использует API msdyn_SaveCalendar для создания рабочего времени Тима.

Запросить

{
 "CalendarEventInfo": "{\"CalendarId\":\"a68245c9-ba2e-4496-9c18-3bee75fda396\",\"EntityLogicalName\":\"bookableresource\",\"TimeZoneCode\":5,\"RulesAndRecurrences\":[{\"Rules\":[{\"StartTime\":\"2021-05-20T00:00:00.000Z\",\"EndTime\":\"2021-05-22T00:00:00.000Z\",\"Effort\":1,\"WorkHourType\":0}]}]}"
}

Отклик

{
  "InnerCalendarIds": "[\"6e160a8e-d5be-eb11-a81d-000d3a6e4359\"]"
}

Вопросы и ответы по

Я получаю сообщение об ошибке: «Время начала не может быть больше или равно времени окончания».

Убедитесь, что временные интервалы различных правил календаря не перекрываются. Проверьте даты, чтобы убедиться, что StartTime не позже, чем EndTime. Также убедитесь, что время соответствует 24-часовому формату.

Можно ли использовать API-интерфейсы для обновления сущности «Шаблоны рабочих часов»?

Да, вы можете использовать этот API для создания и обновления шаблонов рабочих часов в дополнение к рабочим часам ресурсов.

Я получаю сообщение об ошибке: «Произошла ошибка десериализации объекта типа Microsoft.Dynamics.UCICalendar.Plugins.SaveCalendarContract+CalendarEventInfo. Источник входных данных неправильно отформатирован.
or
Ожидается состояние "Element".. Обнаружен 'Text' с именем '', namespace ''."

Убедитесь, что строка проанализирована правильно. Могут отсутствовать скобки, запятые или точки с запятой.

Я получаю сообщение об ошибке "Недопустимый шаблон повторения. Обратитесь к документации для поддерживаемых шаблонов."

В настоящее время мы поддерживаем только этот шаблон: FREQ=DAILY;INTERVAL=1;BYDAY=SU,MO,TU,WE,TH,FR,SA. BYDAY можно изменить, чтобы включить меньшее количество дней; тем не менее, FREQ и INTERVAL не могут быть изменены. Убедитесь, что в шаблоне нет пробелов.

Как мы получаем информацию о CalendarId и InnerCalendarId ресурса?

CalendarId можно получить из атрибутов ресурса. Сделайте следующий вызов, чтобы получить эту информацию: [org-url]/api/data/v9.1/bookableresources([bookableresourceGUID]).

Примером предыдущего вызова может быть [org-url]/api/data/v9.1/bookableresources(7bb0224b-6712-ec11-94f9-000d3a6d888e).

InnerCalendarId можно получить из атрибутов календаря. Сделайте следующий вызов, чтобы получить эту информацию: [org-url]/api/data/v9.1/calendars([calendar-id-from-above-call])?$expand=calendar_calendar_rules.

Пример предыдущего вызова: [org-url]/api/data/v9.1/calendars(02481736-1b6a-4d49-9ebd-a5bd041c1c99)?$expand=calendar_calendar_rules.

Что произойдет, если есть перекрывающиеся правила?

Есть пара разных рангов, к которым относятся правила:

  • Ранг 1 — ежедневное вхождение (работает/не работает) и наступление выходных.
  • Ранг 0 — еженедельная повторяемость (рабочий/нерабочий).

Перекрывающиеся правила V2

  • Правила ранга 1 имеют более высокий приоритет, чем правила ранга 0. Если есть два правила (по одному каждого ранга) в один и тот же день, ежедневное событие или возникновение нерабочего времени имеет приоритет над еженедельным повторением.
  • При наличии нескольких правил ранга 0 в одном и том же диапазоне дат:
    • Если времена не пересекаются, они оба останутся в календаре.
    • Если времена пересекаются, то для календаря ресурса учитывается последнее созданное/измененное правило. Все другие пересекающиеся правила в диапазоне дат удаляются. Если некоторые правила ранга 0 имеют пересечения в некоторые даты, но не в другие, правило объединяется, чтобы сохранить непересекающиеся части, а пересекающиеся части удаляются.

Примеры поведения календаря V2:

Пример 1. Повторяющиеся рабочие часы: перекрывающиеся даты без перекрывающихся дней/времени

В течение заданного периода времени техник работает в утренние, дневные или ночные смены в разные дни.

  1. Создайте первое повторяющееся правило календаря для заданного диапазона дат. Например: Повтор пн, вт; 1.1-4.1; 8:00–17:00 по восточному времени.

  2. Создайте второе повторяющееся правило календаря для пересекающегося диапазона дат, убедившись, что рабочие часы не пересекаются с предыдущими днями или временем. Например: Повтор ср, чт; 1.1-4.1; 8:00–17:00 по восточному времени или Повтор пн, вт; 1.1-4.1; 17:00–20:00 по восточному времени.

Результат: оба правила календаря остаются и сосуществуют рядом друг с другом.

Пример 2. Повторяющиеся рабочие часы: несколько перекрывающихся дат, все дни перекрываются, а второе правило начинается/заканчивается до или после первого правила

Техник получает новый график работы, который заменяет его старый график на несколько недель. По контракту они всегда работают в одни и те же дни каждую неделю.

  1. Создайте первое повторяющееся правило календаря для заданного диапазона дат. Например: Повтор пн, вт; 2.1-4.1; 8:00–17:00 по восточному времени.

  2. Создайте второе повторяющееся правило календаря для перекрывающегося диапазона дат, где все дни имеют перекрывающиеся рабочие часы. Выберите даты начала/окончания для этого нового правила, которые раньше или позже даты начала/окончания первого правила. Например: Повтор пн, вт; 3.1-5.1; 13:00–20:00 по восточному времени.

Результат: первое правило усекается, чтобы соответствовать дате начала/окончания второго правила. Например: Повтор пн, вт; 2.1-2.28; 8:00–17:00 по восточному времени И Повтор пн, вт; 3.1-5.1; 13:00–20:00 по восточному времени.

Пример 3. Повторяющиеся рабочие часы: все перекрывающиеся даты с некоторыми перекрывающимися днями/временем

Техник работает по контракту на фиксированный 2-месячный период. Они согласились взять дополнительную работу на несколько дней. Они хотят перенести рабочие часы вторника на более раннее/позднее время.

  1. Создайте некоторые повторяющиеся правила календаря для заданного диапазона дат. Например: Повтор пн, вт; 2.1-4.1; 8:00–12:00 по восточному времени И Повтор вт, ср; 2.1-4.1; 13:00–17:00 по восточному времени.

  2. Создайте новое повторяющееся правило календаря для того же диапазона дат. Выберите дни/время, которые частично перекрываются с исходными правилами. Например: Повторить вт, чт; 2.1-4.1; 10:00–14:00 по восточному времени.

Результат: новое правило перезаписывает старое там, где есть перекрытия, а остальные оставляет без изменений. Например: Повтор пн; 2.1-4.1; 8:00–12:00 по восточному времени И Повтор ср; 2.1-4.1; 13:00–17:00 по восточному времени И Повтор вт, чт; 2.1-4.1; 10:00–14:00 по восточному времени.

Пример 4. Повторяющиеся рабочие часы: даты нового правила содержатся в старом правиле, некоторые дни/время перекрываются

Мастер работает с 8:00 до 17:00, пн-пт каждую неделю. Всего в течение двух недель они будут заниматься специальным экстренным проектом каждый понедельник-среду с другим рабочим временем с 6:00 до 18:00.

  1. Создайте первое повторяющееся правило календаря для заданного диапазона дат. Например: Повтор Пн, Вт, Ср, Чт, Пт; 1.1-Без даты окончания; 8:00–17:00 по восточному времени.

  2. Создайте второе повторяющееся правило календаря, содержащееся в указанном выше диапазоне дат, выберите рабочие часы, которые перекрываются в некоторые дни. Например: Повтор пн, вт, ср; 5.1-5.14; 6:00–18:00 по восточному времени.

Результат: к концу этого упражнения в календаре должно быть четыре повторяющихся правила:

  • обрежьте первое правило до даты начала второго правила
  • второе правило календаря
  • создайте новое правило, аналогичное первому правилу, но с датами второго правила для непересекающихся дней
  • обрежьте первое правило до начала с конечной даты второго правила, без даты окончания

Например: Повтор Пн, Вт, Ср, Чт, Пт; 1.1–4.30; 08:00-17:00 по восточному времени И Повтор Пн, Вт, Ср; 5.1-5.14; 06:00-18:00 по восточному времени И Повтор Чт, Птi, 5.1-5.14; 08:00-17:00 по восточному времени И Повтор Пн, Вт, Ср, Чт, Пт; 5.15–без конечной даты; 08:00-17:00 по восточному времени

Пример 5. Неповторяющиеся рабочие часы (событие, правило ранга 1)

У технического специалиста есть несколько дней на слаживание рабочей группы, которые имеют приоритет над всеми другими экземплярами рабочего времени для этого дня.

  1. Создайте повторяющееся правило календаря для заданного диапазона дат. Например: Повтор Пн, Вт, Ср, Чт, Пт; 1.1-Без даты окончания; 8:00–17:00 по восточному времени.

  2. Создайте неповторяющееся правило календаря, содержащееся в указанном выше диапазоне дат. Выберите рабочие часы, которые перекрываются в некоторые дни. Например: Без повтора; 6.21; 7:00–13:00 по восточному времени.

Результат: к концу этого упражнения в календаре должно быть 1 неповторяющееся правило (экземпляр). Неповторяющееся правило переопределяет перекрывающееся повторяющееся событие для всего дня. Например: Повтор пн, вт, ср, чт, пт; 1.1-Без даты окончания кроме 6.21; без поврота; 6.21; 07:00–13:00 по восточному времени.

Перекрывающиеся правила V1

  • Правила ранга 1 имеют более высокий приоритет, чем правила ранга 0. Таким образом, если было два правила (по одному каждого ранга) в один и тот же день, ежедневное событие или возникновение нерабочего времени имеет приоритет над еженедельным повторением.
  • Если есть два правила одного ранга, то для календаря ресурса будет учитываться последнее созданное/измененное правило.
  • Имейте в виду, что события, происходящие в течение всего дня, имеют ранг 1, поэтому вы можете подумать об изменении его на еженедельное повторение, чтобы иметь возможность добавлять рабочие часы в случае возникновения и обеспечивать их соблюдение.
  • Когда существует рабочее время и создается вхождение нерабочего времени, перекрывающее его, правила разделяются таким образом, чтобы обеспечить соблюдение нерабочего времени, и любое оставшееся время в качестве рабочих часов останется без изменений. Например, если 21 сентября установлены рабочие часы с 8:00 до 17:00, и 21 сентября с 15:00 до 19:00 добавлен перерыв, это будет считаться рабочим временем с 08:00 до 15:00 и выходной с 15:00 до 19:00. Однако, если правила были созданы в противоположном порядке (сначала создается нерабочее время, а затем создаются рабочие часы), независимо от временных интервалов, повторно выбирается только рабочее время. Нерабочее время будет перезаписано.

Коды часовых поясов

Перечисление Часовой пояс
0 (GMT-12:00) Линия перемены дат
1 (GMT+13:00) Самоа
2 (GMT-10:00) Гавайские о-ва
3 (GMT-09:00) Аляска
4 (GMT-08:00) Тихоокеанское время (США и Канада)
5 (GMT-08:00) Нижняя Калифорния
6 (GMT-11:00) Время в формате UTC-11
7 (GMT-10:00) Алеутские острова
8 (GMT-09:30) Маркизские о-ва
9 (GMT-09:00) Время в формате UTC-09
10 (GMT-07:00) Горное время (США и Канада)
11 (GMT-08:00) Время в формате UTC-08
12 (GMT-07:00) Чиуауа, Ла-Пас, Масатлан
15 (GMT-07:00) Аризона
20 (GMT-06:00) Центральное время (США и Канада)
25 (GMT-06:00) Саскачеван
29 (GMT-06:00) Гвадалахара, Мехико, Монтеррей
33 (GMT-06:00) Центральная Америка
34 (GMT-06:00) о. Пасхи
35 (GMT-05:00) Восточное время (США и Канада)
40 (GMT-05:00) Индиана (восток)
43 (GMT-05:00) Гаити
44 (GMT-05:00) Гавана
45 (GMT-05: 00) Богота, Лима, Кито, Риу-Бранку
47 (GMT-04:00) Каракас
50 (GMT-04:00) Атлантическое время (Канада)
51 (GMT-05:00) Острова Теркс и Кайкос
55 (GMT-04:00) Джорджтаун, Ла-Пас, Сан-Хуан
56 (GMT-04:00) Сантьяго
58 (GMT-04:00) Куяба
59 (GMT-04:00) Асунсьон
60 (GMT-03:30) Ньюфаундленд
65 (GMT-03:00) Бразилиа
69 (GMT-03:00) Буэнос-Айрес
70 (GMT-03:00) Кайенна, Форталеза
71 (GMT-03:00) Сальвадор
72 (GMT-03:00) Сен-Пьер и Микелон
73 (GMT-03:00) Гренландия
74 (GMT-03:00) Монтевидео
75 (GMT-02:00) Среднеатлантическое время
76 (GMT-02:00) Время в формате UTC-02
77 (GMT-03:00) Арагуаяна
80 (GMT-01:00) Азорские о-ва
83 (GMT-01:00) о. Кабо-Верде
84 (GMT+01:00) Касабланка
85 (GMT+00:00) Дублин, Эдинбург, Лиссабон, Лондон
90 (GMT+00:00) Монровия, Рейкьявик
92 (GMT) Время в формате UTC
95 (GMT+01:00) Белград, Братислава, Будапешт, Любляна, Прага
100 (GMT+01:00) Сараево, Скопье, Варшава, Загреб
105 (GMT+01:00) Брюссель, Копенгаген, Мадрид, Париж
110 (GMT+01:00) Амстердам, Берлин, Берн, Рим, Стокгольм, Вена
113 (GMT+01:00) Западная Центральная Африка
115 (GMT+02:00) Кишинев
120 (GMT+02:00) Каир
125 (GMT+02:00) Хельсинки, Киев, Рига, София, Таллинн, Вильнюс
129 (GMT+02:00) Амман
130 (GMT+02:00) Афины, Бухарест
131 (GMT+02:00) Бейрут
133 (GMT+02:00) Дамаск
134 (GMT+03:00) Стамбул
135 (GMT+02:00) Иерусалим
140 (GMT+02:00) Хараре, Претория
141 (GMT+02:00) Виндхук
142 (GMT+02:00) Сектор Газа, Хеврон
145 (GMT+03:00) Москва, Санкт-Петербург
150 (GMT+03:00) Кувейт, Эр-Рияд
151 (GMT+03:00) Минск
155 (GMT+03:00) Найроби
158 (GMT+03:00) Багдад
159 (GMT+02:00) Калининград
160 (GMT+03:30) Тегеран
165 (GMT+04:00) Абу-Даби, Маскат
169 (GMT+04:00) Баку
170 (GMT+04:00) Ереван
172 (GMT+04:00) Порт-Луи
173 (GMT+04:00) Тбилиси
174 (GMT+04:00) Ижевск, Самара
175 (GMT+04:30) Кабул
176 (GMT+04:00) Астрахань, Ульяновск
180 (GMT+05:00) Екатеринбург
184 (GMT+05:00) Исламабад, Карачи
185 (GMT+05:00) Ташкент
190 (GMT+05:30) Ченнаи, Колката, Мумбаи, Нью-Дели
193 (GMT+05:45) Катманду
195 (GMT+06:00) Астана
196 (GMT+06:00) Дакка
197 (GMT+06:00) Омск
200 (GMT+05:30) Шри Джаяварденепура
201 (GMT+07:00) Новосибирск
203 (GMT+06:30) Янгон (Рангун)
205 (GMT+07:00) Бангкок, Ханой, Джакарта
207 (GMT+07:00) Красноярск
208 (GMT+07:00) Барнаул, Горно-Алтайск
209 (GMT+07:00) Ховд
210 (GMT+08:00) Пекин, Чунцин, Гонконг, Урумчи
211 (GMT+07:00) Томск
215 (GMT+08:00) Куала-Лумпур, Сингапур
220 (GMT+08:00) Тайбэй
225 (GMT+08:00) Перт
227 (GMT+08:00) Иркутск
228 (GMT+08:00) Улан-Батор
229 (GMT+09:00) Пхеньян
230 (GMT+09:00) Сеул
231 (GMT+08:45) Юкла
235 (GMT+09:00) Осака, Саппоро, Токио
240 (GMT+09:00) Якутск
241 (GMT+09:00) Чита
245 (GMT+09:30) Дарвин
250 (GMT+09:30) Аделаида
255 (GMT+10:00) Канберра, Мельбурн, Сидней
260 (GMT+10:00) Брисбен
265 (GMT+10:00) Хобарт
270 (GMT+10:00) Владивосток
274 (GMT+10:30) Лорд-Хау
275 (GMT+10:00) Гуам, Порт-Морсби
276 (GMT+11:00) Остров Бугенвиль
277 (GMT+11:00) Остров Норфолк
278 (GMT+11:00) Сахалин
279 (GMT+11:00) Чокурдах
280 (GMT+11:00) Соломоновы о-ва, Нов. Каледония
281 (GMT+11:00) Магадан
284 (GMT+12:00) Время в формате UTC+12
285 (GMT+12:00) Фиджи
290 (GMT+12:00) Окленд, Веллингтон
295 (GMT+12:00) Анадырь, Петропавловск-Камчатский
299 (GMT+12:45) Чатем
300 (GMT+13:00) Нукуалофа
301 (GMT-05:00) Четумаль
302 (UTC+02:00) Хартум
303 (GMT-03:00) Пунта-Аренас
304 (GMT+04:00) Волгоград
305 (GMT-07:00) Юкон