Professional Services Automation Apex API Developer Reference

pse.ScheduleService

global with sharing class ScheduleService

A service that provides functionality relating to schedules. To understand schedules, call this service rather than query Schedule and ScheduleException separately and interpret the results. To make simple updates to existing schedules associated with assignments or resource requests, call this service rather than use DML on Schedule and ScheduleException separately.

Methods

getScheduledHoursForDates

global static Map<Id, pse.ScheduleService.HoursDetail> getScheduledHoursForDates(Set<Id> scheduleIds, Date startDate, Date endDate)

This method does all the logic of looking at the specified schedules and their schedule exceptions and working out how many hours the resources are scheduled to work on specific dates.

Input Parameters

Name Type Description
scheduleIds Set<Id> The schedules to be queried.
startDate Date The start of the period you are requesting data for.
endDate Date The end of the period you are requesting data for.

Return Value

A map keyed on Schedule Id. The values detail the scheduled hours after schedule exceptions have been considered.

Sample Code

//Note: This sample code is for demonstration purposes only. It is not intended for
//use in a production environment, is not guaranteed against defects or errors, and
//is in no way optimized or streamlined.

//Use the service to find scheduled hours in October for a specific schedule.
Set<Id> scheduleIds = new Set<Id>{'a3W55000000pO2WEAU'};
Map<Id, pse.ScheduleService.HoursDetail> scheduleMap = pse.ScheduleService.getScheduledHoursForDates(
    scheduleIds,
    Date.newInstance(2020, 10, 1),
    Date.newInstance(2020, 10, 31)
);

pse.ScheduleService.HoursDetail firstSchedule = scheduleMap.get('a3W55000000pO2WEAU');
String messageTemplate = 'Schedule runs from {0} to {1}\n';
String message = String.format(
    messageTemplate,
    new List<String>{
        firstSchedule.scheduleStart.format(),
        firstSchedule.scheduleEnd.format()
    }
);

for (Integer day = 1; day<=31; day++) {
    Date queryDate = Date.newInstance(2020, 10, day);

    //Map does not contain keys for dates outside the scheduled period
    if (firstSchedule.dateToHours.containsKey(queryDate)) {
        Decimal hoursScheduled = firstSchedule.dateToHours.get(queryDate);
        message += queryDate + ' -> ' + hoursScheduled + '\n';
    }
}
System.debug(message);

updateSchedules

global static List<pse.ScheduleService.UpdateScheduleResponse> updateSchedules(List<pse.ScheduleService.UpdateScheduleRequest> requests)

Amends the specified schedules and their schedule exceptions to change specific dates to the hours indicated in the request. If you want to make extensive changes to the schedule, such as changing the pattern for the whole scheduled period or altering the end date, we recommend that you use the pse.SchedulingStrategyService API. The return value contains one response for each request and indicates if the request was valid. For example, a request is invalid if you attempt to change a date outside the range of the schedule. Any DML errors are thrown as exceptions.

Sample Code

//Note: This sample code is for demonstration purposes only. It is not intended for
//use in a production environment, is not guaranteed against defects or errors, and
//is in no way optimized or streamlined.

//The Project Manager of Universal Internet has decided to put everybody's hours to zero on his birthday.
//Now they have no reason to miss his party.
Date specialDay = Date.newInstance(2020, 9,19);
List<pse__Assignment__c> asmts = [
    SELECT Id, pse__Schedule__c
    FROM pse__Assignment__c
    WHERE pse__Project__r.Name = 'Universal Internet'
];

List<pse.ScheduleService.UpdateScheduleRequest> requests = new List<pse.ScheduleService.UpdateScheduleRequest>();
for (Assignment__c asmt : asmts) {
    pse.ScheduleService.UpdateScheduleRequest request = new pse.ScheduleService.UpdateScheduleRequest();
    request.ScheduleId = asmt.pse__Schedule__c;
    request.Hours = new Map<Date, Decimal>();
    request.Hours.put(specialDay, 0);
    requests.add(request);
}

List<ScheduleService.UpdateScheduleResponse> responses = pse.ScheduleService.updateSchedules(
    requests
);
for (ScheduleService.UpdateScheduleResponse response : responses) {
    if (response.Success) {
        //We could tell the person the good news
    } else {
        //His birthday is probably outside their schedule, we never checked.
        //But let's have a look at the messages anyway.
        System.debug(LoggingLevel.ERROR, response.Errors);
    }
}

consolidateExceptionsOnSchedules

global static List<pse.ScheduleService.ConsolidateScheduleExceptionsResponse> consolidateExceptionsOnSchedules(Set<Id> scheduleIds)

This method looks at the specified schedules and schedule exceptions and then combines the exceptions which have identical hour patterns over consecutive weeks. The scheduled hours on each date will not change, but the number of schedule exception records used may be reduced.

Input Parameters

Name Type Description
scheduleIds Set<Id> The Ids of schedules, for which the exceptions will be consolidated.

Return Value

A list of responses has one response for each schedule which indicates if the request is valid. For example, a request is invalid if you attempt to correct a schedule having zero or one exception.

Sample Code

//Note: This sample code is for demonstration purposes only. It is not intended for
//use in a production environment, is not guaranteed against defects or errors, and
//is in no way optimized or streamlined.

//The schedule of an assignment 'FF-Implementation-Resource-1' has too many schedule exceptions with same hourly pattern over several weeks.
//We want to correct the schedule by combining the schedule exceptions to reduce the count.
List<pse__Assignment__c> asmts = [
    SELECT Id, pse__Schedule__c
    FROM pse__Assignment__c
    WHERE Name = 'FF-Implementation-Resource-1'
];

Set<Id> scheduleIds = new Set<Id>();
for (Assignment__c asmt : asmts) {
    scheduleIds.add(asmt.pse__Schedule__c);
}

List<ScheduleService.ConsolidateScheduleExceptionsResponse> responses = pse.ScheduleService.consolidateExceptionsOnSchedules(
    scheduleIds
);
for (ScheduleService.ConsolidateScheduleExceptionsResponse response : responses) {
    if (response.Success) {
        //The exceptions have been updated as required. No further action is required.'
    } else {
        //There might be some validation failure occured on this schedule.
        //Let's have a look at the messages anyway.
        System.debug(LoggingLevel.ERROR, response.Errors);
    }
}

saveScheduleData

global static List<pse.ScheduleSaveDTO.SaveResult> saveScheduleData(List<ScheduleSaveDto> data, Boolean allOrNone)

This method saves the provided schedule data. It combines different types of DML operations on pse__Schedule__c and pse__Schedule_Exception__c for ease of use. It also prevents issues that could arise from a sequence of saves causing the data to be temporarily invalid before reaching a valid state.
Order of operations:

  1. The provided schedules are upserted.
  2. Schedule Exception deletes are performed.
  3. Schedule Exception updates are performed.
  4. Schedule Exception inserts are performed.

This method requires the following security permissions
  • Create and update object level permission on schedule.
  • Create and update object level permission on schedule exception.
  • Delete object level permission on schedule exception when the request contains schedule exceptions to delete.
  • Edit FLS permissions on any custom fields that you provide.

The data is saved synchronously, however side effects that can happen asynchronously (depending on settings) include:
  • The Schedule Days and Scheduled Hours fields are computed.
  • Utilization Engine records are computed for affected resources.

If the allOrNone flag is false, any schedules that fail validation and their schedule exceptions will not be saved. This flag applies to all DML statements used to save schedules and exceptions. If some schedule exceptions fail to save due to errors, others might still succeed even on the same schedule. If a schedule fails to save, no attempt will be made to save its exceptions. You can inspect the SaveResult object to identify DML errors. If the allOrNone flag is set to true, any errors will result in an exception being thrown.

Input Parameters

Name Type Description
data List<ScheduleSaveDto> Should contain the schedule and schedule exception data to be saved.
allOrNone Boolean Set to false to allow some schedules to be saved while others fail.

Return Value

An array of results that matches the input data.

Sample Code

//Note: This sample code is for demonstration purposes only. It is not intended for
//use in a production environment, is not guaranteed against defects or errors, and
//is in no way optimized or streamlined.

//This code will move a schedule and all its exceptions.
Integer offset = 300; // Move everything this many days

//Find a schedule to move
List<Id> schedulesToMove = new List<Id>{
    'a21DR000001mmidYAA'
};

List<pse__Schedule__c> schedules = [
    SELECT
        Id,
        pse__Start_Date__c,
        pse__End_Date__c,
        pse__Monday_Hours__c,
        pse__Tuesday_Hours__c,
        pse__Wednesday_Hours__c,
        pse__Thursday_Hours__c,
        pse__Friday_Hours__c,
        pse__Saturday_Hours__c,
        pse__Sunday_Hours__c,
        (
            SELECT Id, pse__Date__c, pse__End_Date__c, pse__Exception_Hours__c
            FROM pse__Schedule_Exceptions__r
        )
    FROM pse__Schedule__c
    WHERE Id IN :schedulesToMove
];
List<pse.ScheduleSaveDTO> data = new List<pse.ScheduleSaveDTO>();

for (pse__Schedule__c s : schedules) {
    pse.ScheduleSaveDTO schedDto = new pse.ScheduleSaveDTO();
    schedDto.ScheduleId = s.Id;
    schedDto.StartDate = s.Start_Date__c.addDays(offset);
    schedDto.EndDate = s.End_Date__c.addDays(offset);
    //You have to populate these even though they aren't changing as the fields are required for the update.
    schedDto.MondayHours = s.Monday_Hours__c;
    schedDto.TuesdayHours = s.Tuesday_Hours__c;
    schedDto.WednesdayHours = s.Wednesday_Hours__c;
    schedDto.ThursdayHours = s.Thursday_Hours__c;
    schedDto.FridayHours = s.Friday_Hours__c;
    schedDto.SaturdayHours = s.Saturday_Hours__c;
    schedDto.SundayHours = s.Sunday_Hours__c;
    data.add(schedDto);

    schedDto.ExceptionsToUpdate = new List<pse.ScheduleSaveDTO.ScheduleExceptionDTO>();
    for (pse__Schedule_Exception__c se : s.Schedule_Exceptions__r) {
        pse.ScheduleSaveDTO.ScheduleExceptionDTO expDto = new pse.ScheduleSaveDTO.ScheduleExceptionDTO();
        expDto.ScheduleExceptionId = se.Id;
        expDto.StartDate = se.Date__c.addDays(offset);
        expDto.EndDate = se.End_Date__c.addDays(offset);
        expDto.ExceptionHours = se.Exception_Hours__c;
        schedDto.ExceptionsToUpdate.add(expDto);
    }
}

List<pse.ScheduleSaveDTO.SaveResult> results = pse.ScheduleService.saveScheduleData(data, true);

for (pse.ScheduleSaveDTO.SaveResult result : results) {
    Assert.isTrue(result.Success);
}

pse.ScheduleService.HoursDetail

global inherited sharing class HoursDetail

Properties

Name Type Description
dateToHours Map<Date, Decimal> Indicates how many hours are scheduled for each date in the range. The dates included in the map are the intersection of the scheduled period and the dates passed in the call to getScheduledHoursForDates.
scheduleStart Date The start date of the schedule.
scheduleEnd Date The end date of the schedule.

pse.ScheduleService.UpdateScheduleRequest

global inherited sharing class UpdateScheduleRequest

Use instances of this object with updateSchedules to edit schedules.

Properties

Name Type Description
ScheduleId Id The Id of the schedule to be amended.
Hours Map<Date, Decimal> The keys are the dates to be amended, and the values are the new scheduled hours for each date. Only scheduled hours for dates included in this map are amended, scheduled hours for other dates are unchanged.

pse.ScheduleService.UpdateScheduleResponse

global inherited sharing class UpdateScheduleResponse

Response object returned from updateSchedules. Use the ScheduleId to match it to a request.

Properties

Name Type Description
ScheduleId Id The Id of the updated schedule.
Success Boolean False if the request was invalid. True otherwise. Invalid requests will not be processed.
Errors List<String> Any validation errors with the request will be stored here.

pse.ScheduleService.ConsolidateScheduleExceptionsResponse

global inherited sharing class ConsolidateScheduleExceptionsResponse

Response object returned from consolidateExceptionsOnSchedules. Use the ScheduleId to match it to a request.

Properties

Name Type Description
ScheduleId Id The ID of the updated schedule.
Success Boolean Returns true if the request is valid else returns false. Invalid requests are not processed and DML errors are thrown as exceptions.
Errors List<String> Any validation errors with the request are stored here.
© Copyright 2009–2024 Certinia Inc. All rights reserved. Various trademarks held by their respective owners.