PSA Apex API Developer Reference

pse.PSATimecardService

global with sharing class PSATimecardService

A service that provides functionality relating to Timecards.

Methods

submit

global static pse.PSATimecardService.SubmitResponse submit(pse.PSATimecardService.SubmitRequest request)

This method is the preferred way to submit timecards for approval. This method only sets the Status field, typically customizations will be in place to set the Submitted field and actually enter the record into a Salesforce Approval Process. After performing some validations it updates the Status field to Submitted. (This value is customizable through custom setting Timecard Entry UI Global - Timecard submit button action.) The validations performed are:

  • The timecard has not yet been submitted.
  • You are not attempting to submit a timecard with zero hours logged if this is forbidden by settings. (For more information, see Timecard Entry UI Global - Submit timecard with zero hours.)
  • The timecard currently has a status that allows it to be edited. (For more detail, see Global Timecard Entry UI - Timecard Edit Status Values.)
  • The linked project is active.
  • The timecard is not invoiced or billed.
  • The user has permission to edit this timecard.
If some records fail validation, other records will still be submitted.

Input Parameters

Name Type Description
request pse.PSATimecardService.SubmitRequest Request indicating Timecards to be submitted

Return Value

A response object containing a success flag and potential validation messages.

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.

//I have a timecard header that I want to submit. The id is 'a431D00000000snQaH'

//Create the request
pse.PSATimecardService.SubmitRequest request = new pse.PSATimecardService.SubmitRequest();
request.TimecardIds = new Set<Id>{'a431D00000000snQaH'};

//Call the service to submit
pse.PSATimecardService.SubmitResponse response = pse.PSATimecardService.submit(request);

//Check the results
Map<Id, List<String>> failureReasons = new Map<Id, List<String>>();
for (pse.PSATimecardService.SubmitResult result : response.Results) {
    if (result.Successful) {
        //Great, no action required. But you could report the success if necessary.
    } else {
        //We need to inform the user why their timecard could not be submitted.
        //Depending on the use-case we could show messages on the UI, or email or do anything.
        failureReasons.put(result.TimecardId, result.Errors);
    }
}
if (!failureReasons.isEmpty()) {
    informUser(failureReasons);   
}

save

global static pse.PSATimecardService.SaveResponse save(pse.PSATimecardService.SaveRequest request)

This method saves the information in the request by creating or updating Timecard_Header__c records and Timecard__c records. It can also create and update records in Task_Time__c when time is being logged on tasks. If some Timecards fail validation or fail with DML errors the other changes will still be saved. The response object provides details about which records failed and why, as well as the Id of newly created Timecards.</p>
It is possible to change the project a timecard is linked to with this method, which is generally not possible with native edits. Changing the project is audited on the record.
It performs the following validations:

  • The timecard is linked to an active project.
  • If the timecard is linked to an assignment, then the assignment is not closed for time entry.
  • If the timecard is linked to an assignment, and required by settings, the period of the timecard overlaps the linked assignment. (For more information, see Timecard Entry UI Global - Assignments load date restriction.)
  • If the timecard is not linked to an assignment, then the linked project is not closed for time entry.
  • If the timecard is not linked to an assignment, and required by settings, the period of the timecard overlaps the linked project. (For more information, see Timecard Entry UI Global - Projects load date restriction.)
  • If the timecard is linked to an assignment, its Status is in the list indicated in Timecard Entry UI Global - Assignments load status values.
  • Billable timecards are not logged on non-billable assignments.
  • If the timecard is billable and not linked to an assignment, ensure the project is billable.
  • The timecard is not for zero hours if this is forbidden by the config Timecard Entry UI Global - Save timecard with zero hours.
  • No days have negative hours recorded if this is forbidden by the config Timecard Entry UI Global - Allow timecard with negative hours.
  • That daily notes are provided, if the project or assignment indicates this is required. For more information, see Daily Timecard Notes Required fields on Project and Assignment.

These extra validations are performed only when updating timecard records:
  • The timecard is not already billed or invoiced.
  • The timecard status is one that allows the timecard to be edited. (For more information, see Timecard Entry UI Global - Timecard edit status values).

If the request is logging time against tasks, a check for duplicate Task Time records is performed; each Timecard can have at most one Task Time linking it to a given Project Task. If this request would create more than that an error is added to the response.

Input Parameters

Name Type Description
request pse.PSATimecardService.SaveRequest Request containing the timecard information to be saved.

Return Value

A response object containing details about successes and failures.

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.

//Prepare the request. The data might come from a custom UI or an external integration.
pse.PSATimecardService.TimecardSaveDTO timecard1 = new pse.PSATimecardService.TimecardSaveDTO();
timecard1.ResourceId = '0031D00000ZaGwNQAV';
timecard1.AssignmentId = 'a1U1D000000obR0UAI';
timecard1.ProjectId = 'a2j1D0000008139QAA';
timecard1.StartDate = Date.newInstance(2021, 3, 21);
timecard1.EndDate = Date.newInstance(2021, 3, 27);
timecard1.MondayHours = 4;

pse.PSATimecardService.TimecardSaveDTO timecard2 = new pse.PSATimecardService.TimecardSaveDTO();
timecard2.ResourceId = '0031D00000ZaGwNQAV';
timecard2.AssignmentId = 'a1U1D000000wry8DPE';
timecard2.ProjectId = 'a2j1D0000008139QAA';
timecard2.StartDate = Date.newInstance(2021, 3, 21);
timecard2.EndDate = Date.newInstance(2021, 3, 27);
timecard2.MondayHours = 4;

pse.PSATimecardService.SaveRequest request = new pse.PSATimecardService.SaveRequest();
request.Timecards = new List<pse.PSATimecardService.TimecardSaveDTO>{timecard1, timecard2};

//Call the save
pse.PSATimecardService.SaveResponse response = pse.PSATimecardService.save(request);

//Handle the response
List<Id> newTimecardIds = new List<Id>(); //make a note of new Ids, so we can retrieve them and update them later
Boolean allSuccess = true;
for (pse.PSATimecardService.SaveResult result : response.Results) {
    if (result.Successful) {
        newTimecardIds.add(result.TimecardId);
    } else {
        allSuccess = false;
        //Timecard failed validation or had a DML error.
        //Check result.Errors, result.DailyErrors for details
    }
}

//If there were errors we should report them to the user

pse.PSATimecardService.SubmitRequest

global inherited sharing class SubmitRequest

Request object used to submit Timecards.

Properties

Name Type Description
TimecardIds Set<Id> The Ids of Timecard_Header__c records to be submitted.

pse.PSATimecardService.SubmitResponse

global inherited sharing class SubmitResponse

Response object received after calling the submit method.

Properties

Name Type Description
Results List<pse.PSATimecardService.SubmitResult> A list of results from a request to submit timecards. Each timecard in the request has its own SubmitResult.

pse.PSATimecardService.SubmitResult

global inherited sharing class SubmitResult

Contains information on the result of a request to submit a Timecard.

Properties

Name Type Description
TimecardId Id The Id of the Timecard_Header__c this result pertains to.
Successful Boolean Indicates if the request was successful. If false, check Errors to learn why the request did not succeed.
Errors List<String> A list of validation errors relating to this Timecard.

pse.PSATimecardService.SaveRequest

global inherited sharing class SaveRequest

Class contain details of timecards to be saved.

Properties

Name Type Description
Timecards List<pse.PSATimecardService.TimecardSaveDTO> A list of timecards to be saved.

Methods

SaveRequest

global SaveRequest()

pse.PSATimecardService.SaveResponse

global inherited sharing class SaveResponse

A class containing the response from calling save with a SaveRequest. Partial saves are allowed so some results may be successful, while others have failed.

Properties

Name Type Description
Results List<pse.PSATimecardService.SaveResult> A list of results, each corresponding to one Timecard. The order matches SaveRequest.Timecards.

pse.PSATimecardService.SaveResult

global inherited sharing class SaveResult

A class containing the result relating to one timecard. It holds the Id of the timecard if known, if the timecard was saved successfullly, and details of any validation or DML errors.

Properties

Name Type Description
TimecardId Id The Id of the timecard. It will be populated in all situations except when saving a new timecard has failed.
Successful Boolean Indicates if the timecard was successfullly saved.
TaskSaveResults List<pse.PSATimecardService.TaskSaveResult> If the timecard had time logged against project tasks, this list contains details of related errors that may have occurred.
Errors List<String> A list of validation or DML errors that affected the save and which are not related to a specific Project Task or a problem with a specific day of the week.
DailyErrors Map<pse.CalendarUtil.DayOfWeek, List<String>> Contains any validation errors relating to days on the Timecard.

pse.PSATimecardService.TaskSaveResult

global inherited sharing class TaskSaveResult

Identifier which matches the value set on the TimecardSaveDTO that led to this SaveResult. Useful for matching up SaveResults with TimecardSaveDTO, particularly for phantom records that do not have an ID yet.

Properties

Name Type Description
TaskTimeId Id
Errors List<String>

pse.PSATimecardService.TimecardSaveDTO

global inherited sharing class TimecardSaveDTO

Contains details of one Timecard to be saved.

Properties

Name Type Description
TimecardId Id The Id of the Timecard_Header__c to be updated or null to create a new record.
ResourceId Id The Id of the Contact record this Timecard is for.
AssignmentId Id The Id of the Assignment__c record.
ProjectId Id The Id of the Project__c record.
StartDate Date The start date of the Timecard. Note each Timecard must cover exactly one week.
EndDate Date The end date of the Timecard. Note each Timecard must cover exactly one week.
TimecardNotes String Notes to be recorded in the Timecard_Notes__c field.
AuditNotes String Audit Notes to be recorded in the Audit_Notes__c field.
MondayHours Decimal Hours logged on Monday
MondayNotes String Notes for Monday
TuesdayHours Decimal Hours logged on Tuesday
TuesdayNotes String Notes for Tuesday
WednesdayHours Decimal Hours logged on Wednesday
WednesdayNotes String Notes for Wednesday
ThursdayHours Decimal Hours logged on Thursday
ThursdayNotes String Notes for Thursday
FridayHours Decimal Hours logged on Friday
FridayNotes String Notes for Friday
SaturdayHours Decimal Hours logged on Saturday
SaturdayNotes String Notes for Saturday
SundayHours Decimal Hours logged on Sunday
SundayNotes String Notes for Sunday
Tasks List<pse.PSATimecardService.TaskTimeSaveDto> Details of logging time against a Project Task. Each TaskTimeSaveDto corresponds to one Task_Time__c record.
CustomFields Map<String, Object> Any data to save in custom fields can be provided here. The keys are the API names of the field including the namespace.

Methods

TimecardSaveDTO

global TimecardSaveDTO()

pse.PSATimecardService.TaskTimeSaveDto

global inherited sharing class TaskTimeSaveDto

A class containing information for logging time on a task.

Properties

Name Type Description
TasktimeId Id The Id of the Task_Time__c record if we are updating a record. Or null to request that a new Task_Time__c record is created.
ProjectTaskId Id The Id of the Project__Task__c to log time on.
MondayHours Double Hours logged on Monday
TuesdayHours Double Hours logged on Tuesday
WednesdayHours Double Hours logged on Wednesday
ThursdayHours Double Hours logged on Thursday
FridayHours Double Hours logged on Friday
SaturdayHours Double Hours logged on Saturday
SundayHours Double Hours logged on Sunday
ProjectTaskCustomFields Map<String, Object> Use this map to update fields on the Project Task when logging time. It is possible to reference the same ProjectTask more than once in the same save request. (Specifically, if the TaskTimes are on different Timecards.) When that happens the first instance of ProjectTaskCustomFields for the ProjectTask is used. All subsequent CustomField updates to that Project Task in the request are ignored.
TaskTimeCustomFields Map<String, Object> Use this map to write other fields on the Task_Time__c record.

Methods

TaskTimeSaveDto

global TaskTimeSaveDto()

© Copyright 2009–2022 FinancialForce.com, inc. All rights reserved. Various trademarks held by their respective owners.