Professional Services Automation Apex API Developer Reference

pse.AddFromProjectTemplateService

global with sharing class AddFromProjectTemplateService

A service used to clone related records between projects. Core fields of copied objects are also copied.

This class contains deprecated items.

Enums

SchedulingStrategy

Value Description
CALCULATE_END_DATE_IGNORE_AVAILABILITY calculates end date ignoring availability.
ADJUST_DAILY_HOURS adjusts per day hours based on start date, end date, and total hours.
ZERO_HOUR_SCHEDULING creates schedule with zero hours for each day.
RETAIN_PREFERRED_SCHEDULE create a schedule by retaining previous schedule hours per day.
NONE should not create any schedule.

Methods

addFromTemplates

global static List<pse.AddFromProjectTemplateService.AddFromProjectResponse> addFromTemplates(List<pse.AddFromProjectTemplateService.AddFromProjectRequest> requests)

This method clones related records between projects or to an opportunity using the details specified. Multiple requests are executed asynchronously and sequentially, in the given order.

Input Parameters

Name Type Description
requests List<pse.AddFromProjectTemplateService.AddFromProjectRequest> The list of requests in AddFromProjectRequest.

Return Value

This service returns values in the AddFromProjectResponses list in response to the requests in the input list.

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.

Id template1 = 'a2V0R000001km2BUAQ';
Id template2 = 'a2V0R000001khHXUAY';
Id destination = 'a2V0R000001km2LUAQ';

pse.AddFromProjectTemplateService.ProjectTaskRequest request1 = 
    new pse.AddFromProjectTemplateService.ProjectTaskRequest(template1, destination);
pse.AddFromProjectTemplateService.MilestoneRequest request2 = 
    new pse.AddFromProjectTemplateService.MilestoneRequest(template2, destination);

List<pse.AddFromProjectTemplateService.AddFromProjectRequest> requests = 
    new List<pse.AddFromProjectTemplateService.AddFromProjectRequest>{ request1, request2 };

// Enqueue the Add From Template requests
List<pse.AddFromProjectTemplateService.AddFromProjectResponse> responses = 
    pse.AddFromProjectTemplateService.addFromTemplates(requests);

// Loop through each response to see whether the request succeeded or failed
for (pse.AddFromProjectTemplateService.AddFromProjectResponse response : responses) {
    if (response.isSuccess()) {
        System.debug('Successfully queued this request: ' + response.Request);
    } else {
        System.debug('This request failed: ' + response.Request);
        System.debug('Reasons: ' + response.Errors);
    }
}

Deprecated

The following items are deprecated and not supported for use. We recommend that you stop using these items to avoid exceptions.

Methods

addTasksFromTemplates

Deprecated: Use addFromTemplates(List requests) instead.

global static List<pse.AddFromProjectTemplateService.AddFromProjectResponse> addTasksFromTemplates(List<pse.AddFromProjectTemplateService.ProjectTaskRequest> requests)

This method clones project tasks between projects using the details specified. Multiple requests are executed asynchronously and sequentially, in the given order.

Input Parameters

Name Type Description
requests List<pse.AddFromProjectTemplateService.ProjectTaskRequest> The list of ProjectTaskRequest.

Return Value

This service returns AddFromProjectResponses in a list that parallels the input list.

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.

Id template1 = 'a2V2F000000xpS3UAI';
Id template2 = 'a2V2F000000xpS4UAI';
Id destination = 'a2V2F000000xpSGUAY';
Date startDate = Date.Today();

pse.AddFromProjectTemplateService.ProjectTaskRequest request1 = 
    new pse.AddFromProjectTemplateService.ProjectTaskRequest(template1, destination);
pse.AddFromProjectTemplateService.ProjectTaskRequest request2 = 
    new pse.AddFromProjectTemplateService.ProjectTaskRequest(template2, destination);

request1.StartDate = startDate;
request2.StartDate = startDate;

List<pse.AddFromProjectTemplateService.ProjectTaskRequest> requests = 
    new List<pse.AddFromProjectTemplateService.ProjectTaskRequest>{ request1, request2 };

// Enqueue the Add Tasks From Template requests
List<pse.AddFromProjectTemplateService.AddFromProjectResponse> responses = 
    pse.AddFromProjectTemplateService.addTasksFromTemplates(requests);

// Loop through each response to see whether the request succeeded or failed
for (pse.AddFromProjectTemplateService.AddFromProjectResponse response : responses) {
    if (response.isSuccess()) {
        System.debug('Successfully queued this request: ' + response.Request);
    } else {
        System.debug('This request failed: ' + response.Request);
        System.debug('Reasons: ' + response.Errors);
    }
}

pse.AddFromProjectTemplateService.AddFromProjectRequest

global abstract inherited sharing class AddFromProjectRequest

The request structure for the AddFromProjectTemplateService.

Properties

Name Type Description
DestinationProjectId Id The project ID that related records are copied to.
Mappers List<pse.SObjectCloneMapper> The SObjectCloneMapper list defining which fields are copied for which SObjects when adding related records from a template. This is in addition to the default objects and fields as well as the fields contained in the field sets. Mappers can be used to select specific related records to copy. See SObjectCloneMapper.
StartDate Date The date after which to insert the related objects.
If the Work_Calendar__c field on the Project_Task__c sObject has been included in either Project Task field set or passed as a Mapper on this request, project tasks are adjusted into working time after the offset is applied. This determines the working days according to the Work_Calendar__c on each Project Task.
strategiesMapper Map<Id, pse.AddFromProjectTemplateService.SchedulingStrategy> It's a map of resource request id with scheduling strategy. Schedule will be created for the cloned resource request of passed resource request id as per the provided strategy.
TemplateProjectId Id The template project ID that related records are copied from.
ActionTitle String ActionTitle Name of the action to be performed like 'Assignment', 'Milestone', 'Related'

pse.AddFromProjectTemplateService.ProjectTaskRequest

global with sharing class ProjectTaskRequest extends AddFromProjectRequest

The request structure for adding tasks from template only. To be used with addFromTemplates.
Tasks are scheduled so that the earliest task will start on StartDate. If EndDate is set, tasks are scheduled so that the latest ending task will end on EndDate. Tasks are appended to the bottom of the hierarchy of the destination project. The WBS of the copied tasks is cleared, it can be regenerated by opening the project in Gantt.
Fields are copied from a project task field set that is referenced in the following custom settings:
• Template Proj Task Fieldset
• Template Proj Alt Copy Task Fieldset

This class extends pse.AddFromProjectTemplateService.AddFromProjectRequest

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.

global with sharing class ActionProjectTasksAddFromTemplates {
    //Prevents unwanted instantiation
    private ActionProjectTasksAddFromTemplates() {
    }

    @InvocableMethod(
        label='Add Project Tasks from Template'
        description='Add project tasks from the given template ID.'
        category='Templating'
    )
    global static void run(List<AtftRequest> builderRequests) {
        List<AddFromProjectTemplateService.ProjectTaskRequest> apiRequests = new List<AddFromProjectTemplateService.ProjectTaskRequest>();

        // Create the Add Tasks from Template requests
        for (AtftRequest req : builderRequests) {
            apiRequests.add(makeRequest(req));
        }

        // Enqueue the Add Tasks from Template requests
        AddFromProjectTemplateService.addFromTemplates(apiRequests);
    }

    private static AddFromProjectTemplateService.ProjectTaskRequest makeRequest(
        AtftRequest builderRequest
    ) {
        // Create the request
        AddFromProjectTemplateService.ProjectTaskRequest request = new AddFromProjectTemplateService.ProjectTaskRequest(
            builderRequest.TemplateId,
            builderRequest.TargetId
        );

        // Set the start/end date you want to offset task dates by
        if (builderRequest.ScheduleByEndDate) {
            request.EndDate = builderRequest.ScheduleDate;
        } else {
            request.StartDate = builderRequest.ScheduleDate;
        }

        // Copy associated project task assignments
        request.CopyProjectTaskAssignments = builderRequest.CopyProjectTaskAssignments;

        // Create a mapper so associated milestones are linked
        if (builderRequest.MilestoneId != null) {
            SObjectCloneMapper.Field milestoneField = new SObjectCloneMapper.Field(
                Project_Task__c.Milestone__c
            );
            milestoneField.DefaultValue = builderRequest.MilestoneId;

            SObjectCloneMapper mapper = new SObjectCloneMapper(
                Project_Task__c.SObjectType,
                new Set<SObjectCloneMapper.Field>{ milestoneField }
            );
            request.Mappers = new List<SObjectCloneMapper>{ mapper };
        }

        return request;
    }

    global with sharing class AtftRequest {
        @InvocableVariable(
            required=true
            label='Template ID'
            description='The ID of the template project you want to add tasks from.'
        )
        global ID TemplateId;

        @InvocableVariable(
            required=true
            label='Target ID'
            description='The ID of the project you want to add tasks to.'
        )
        global ID TargetId;

        @InvocableVariable(
            label='Milestone ID'
            description='The ID of the milestone to map tasks to.'
        )
        global ID MilestoneId;

        @InvocableVariable(
            label='Offset Schedule Date'
            description='The date to offset task dates from, either forward or backward, depending on the value in the schedule by end date.'
        )
        global Date ScheduleDate;

        @InvocableVariable(
            label='Schedule by End Date'
            description='Set to true to offset backward based on the schedule date.'
        )
        global Boolean ScheduleByEndDate = false;

        @InvocableVariable(
            label='Copy Project Task Assignments'
            description='Set to false if you do not want to copy any associated project task assignments.'
        )
        global Boolean CopyProjectTaskAssignments = true;

        global AtftRequest() {
        }
    }
}

Properties

Name Type Description
CopyMilestones Boolean Copies milestones that are associated with project tasks, which are not copied by default.
Fields are copied from a Milestone field set that is referenced in the following custom settings:
• Template Proj MS Fieldset
• Template Proj Alt Copy MS Fieldset
CopyProjectTaskAssignments Boolean Copy project task assignments (PTAs), they are not copied by default.
Fields are copied from a project task assignment field set that is referenced in the following custom settings:
• Template Proj Copy PTA Fieldset
EndDate Date The last date that the copied related objects should end on. If this field is set, StartDate must be null.
If the Work_Calendar__c field on the Project_Task__c sObject has been included in either of the Project Task field sets or passed as a Mapper on this request, project tasks are adjusted into working time after the offset is applied. This determines the working days according to the Work_Calendar__c on each project task.

Methods

ProjectTaskRequest

global ProjectTaskRequest(Id templateProjectId, Id destinationProjectId)

A default constructor with minimum required properties.

Input Parameters

Name Type Description
templateProjectId Id The project template ID.
destinationProjectId Id The destination project ID.

pse.AddFromProjectTemplateService.MilestoneRequest

global with sharing class MilestoneRequest extends AddFromProjectRequest

The request structure for adding milestones from template only. To be used with addMilestonesFromTemplates.
Fields are copied from a Milestone field set that is referenced in the following custom settings:
• Template Proj MS Fieldset
• Template Proj Columns MS Fieldset
• Template Proj Alt Copy MS Fieldset

This class extends pse.AddFromProjectTemplateService.AddFromProjectRequest

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.

global with sharing class ActionMilestonesAddFromTemplates {
    //Prevents unwanted instantiation
    private ActionMilestonesAddFromTemplates() {
    }

    @InvocableMethod(
        label='Add Milestones from Template'
        description='Add milestones from the given template ID.'
        category='Templating'
    )
    global static void run(List<AmftRequest> builderRequests) {
        List<AddFromProjectTemplateService.MilestoneRequest> apiRequests = new List<AddFromProjectTemplateService.MilestoneRequest>();

        Set<Id> templateIds = new Set<Id>();
        for (AmftRequest request : builderRequests) {
            templateIds.add(request.TemplateId);
        }

        List<Milestone__c> milestones = MilestoneSelector.newInstance()
            .selectByProject(
                templateIds,
                new Set<String>{
                    'Id',
                    'Name',
                    'Project__c',
                    'Milestone_Amount__c',
                    'Planned_Hours__c',
                    'Default_Bill_Rate__c'
                }
            );

        // Create the Add Milestones from Template requests
        for (AmftRequest req : builderRequests) {
            apiRequests.add(makeRequest(req, milestones));
        }

        // Enqueue the Add Milestones from Template requests
        AddFromProjectTemplateService.addFromTemplates(apiRequests);
    }

    private static AddFromProjectTemplateService.MilestoneRequest makeRequest(
        AmftRequest builderRequest,
        List<Milestone__c> milestones
    ) {
        // Create the request
        AddFromProjectTemplateService.MilestoneRequest request = new AddFromProjectTemplateService.MilestoneRequest(
            builderRequest.TemplateId,
            builderRequest.TargetId
        );

        Map<Id, Milestone__c> templateMilestones = new Map<Id, Milestone__c>();
        for (Milestone__c milestone : milestones) {
            if (milestone.Project__c == builderRequest.TemplateId) {
                templateMilestones.put(milestone.Id, milestone);
            }
        }

        List<SObjectCloneMapper> mapperList = new List<SObjectCloneMapper>();

        // For each milestone, override the values from the request
        for (Id milestoneId : templateMilestones.keySet()) {
            SObjectCloneMapper mapper = new SObjectCloneMapper(
                Milestone__c.SObjectType,
                new Set<SObjectCloneMapper.Field>()
            );

            Milestone__c overrideMilestone = buildOverrideMilestone(
                builderRequest,
                templateMilestones.get(milestoneId)
            );

            mapper.SObjectRecordsToOverride = new Map<Id, SObject>{
                milestoneId => overrideMilestone
            };

            mapperList.add(mapper);
        }
        request.Mappers = mapperList;

        // Set the start date you want to offset milestone dates by
        request.StartDate = builderRequest.StartDate;

        // Set whether associated milestone risks should be copied as well
        request.CopyRisks = builderRequest.CopyRisks;

        return request;
    }

    private static Milestone__c buildOverrideMilestone(
        AmftRequest builderRequest,
        Milestone__c templateMilestone
    ) {
        Milestone__c overrideMilestone = new Milestone__c();

        if (builderRequest.StartDateOverride != null) {
            overrideMilestone.Start_Date__c = builderRequest.StartDateOverride;
        }

        if (builderRequest.TargetDateOverride != null) {
            overrideMilestone.Target_Date__c = builderRequest.TargetDateOverride;
        }

        if (builderRequest.MilestoneAmountOverride != null) {
            overrideMilestone.Milestone_Amount__c = builderRequest.MilestoneAmountOverride;
        }

        if (builderRequest.ApproverOverride != null) {
            overrideMilestone.Approver__c = builderRequest.ApproverOverride;
        }

        if (
            builderRequest.MilestoneAmountOverride == null &&
            templateMilestone.Milestone_Amount__c != null
        ) {
            overrideMilestone.Milestone_Amount__c =
                builderRequest.MilestoneAmountMultiplier * templateMilestone.Milestone_Amount__c;
        }

        if (templateMilestone.Planned_Hours__c != null) {
            overrideMilestone.Planned_Hours__c =
                builderRequest.PlannedHoursMultiplier * templateMilestone.Planned_Hours__c;
        }

        if (templateMilestone.Default_Bill_Rate__c != null) {
            overrideMilestone.Default_Bill_Rate__c =
                builderRequest.DefaultBillRateMultiplier * templateMilestone.Default_Bill_Rate__c;
        }

        return overrideMilestone;
    }

    global with sharing class AmftRequest {
        @InvocableVariable(
            required=true
            label='Template ID'
            description='The ID of the template project you want to add milestones from.'
        )
        global ID TemplateId;

        @InvocableVariable(
            required=true
            label='Target ID'
            description='The ID of the project you want to add milestones to.'
        )
        global ID TargetId;

        @InvocableVariable(
            label='Offset Start Date'
            description='The start date you want to offset milestone dates from.'
        )
        global Date StartDate;

        @InvocableVariable(
            label='Start Date Override'
            description='The start date to override on milestones.'
        )
        global Date StartDateOverride;

        @InvocableVariable(
            label='Target Date Override'
            description='The target date to override on milestones.'
        )
        global Date TargetDateOverride;

        @InvocableVariable(
            label='Milestone Amount Override'
            description='The milestone amount to override on milestones.'
        )
        global Double MilestoneAmountOverride;

        @InvocableVariable(
            label='Milestone Amount Multiplier'
            description='Apply a multiplier to the milestone amount on each milestone (ignored if a milestone amount override is also supplied).'
        )
        global Double MilestoneAmountMultiplier = 1;

        @InvocableVariable(
            label='Planned Hours Multiplier'
            description='Apply a multiplier to the planned hours on each milestone.'
        )
        global Double PlannedHoursMultiplier = 1;

        @InvocableVariable(
            label='Default Bill Rate Multiplier'
            description='Apply a multiplier to the default bill rate on each milestone.'
        )
        global Double DefaultBillRateMultiplier = 1;

        @InvocableVariable(
            label='Approver Override'
            description='The approver to override on milestones.'
        )
        global Id ApproverOverride;

        @InvocableVariable(
            label='Copy Risks'
            description='Set to false if you do not want to copy any associated risks.'
        )
        global Boolean CopyRisks = true;

        global AmftRequest() {
        }
    }
}

Properties

Name Type Description
CopyRisks Boolean Copies risks, which are are not copied by default.
Fields are copied from a Risk field set that is referenced in the following custom settings:
• Template Proj Risk Fieldset
• Template Proj Alt Copy Risk Fieldset

Methods

MilestoneRequest

global MilestoneRequest(Id templateProjectId, Id destinationProjectId)

A default constructor with minimum required properties.

Input Parameters

Name Type Description
templateProjectId Id The project template ID.
destinationProjectId Id The destination project ID.

pse.AddFromProjectTemplateService.AssignmentRequest

global with sharing class AssignmentRequest extends AddFromProjectRequest

The request structure for adding assignment from template only. To be used with addAssignmentsFromTemplates.
Fields are copied from a Assignment field set that is referenced in the following custom settings:
• Template_Proj_Columns_Assign_Fieldset
• Template_Proj_Assignment_Fieldset
• Template_Proj_Alt_Copy_Assign_Fieldset

This class extends pse.AddFromProjectTemplateService.AddFromProjectRequest

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.

global with sharing class ActionAssignmentsAddFromTemplates {
    //Prevents unwanted instantiation by customers
    private ActionAssignmentsAddFromTemplates() {
    }

    @InvocableMethod(
        label='Add Assignments from Template'
        description='Add assignments from the given template ID.'
        category='Templating'
    )
    global static void run(List<AddAssignmentFromTemplateRequest> builderRequests) {
        List<AddFromProjectTemplateService.AssignmentRequest> apiRequests = new List<AddFromProjectTemplateService.AssignmentRequest>();

        Set<Id> templateIds = new Set<Id>();
        for (AddAssignmentFromTemplateRequest request : builderRequests) {
            templateIds.add(request.TemplateId);
        }

        List<Assignment__c> assignmentsRecord = AssignmentSelector.newInstance()
            .selectByProjectIdWithSetOfFields(
                templateIds,
                new Set<String>{ 'Planned_Bill_Rate__c' }
            );

        // Create the Add Assignments from Template requests
        for (AddAssignmentFromTemplateRequest req : builderRequests) {
            apiRequests.add(makeRequest(req, assignmentsRecord));
        }

        // Enqueue the Add Assignments from Template requests
        AddFromProjectTemplateService.addFromTemplates(apiRequests);
    }

    private static AddFromProjectTemplateService.AssignmentRequest makeRequest(
        AddAssignmentFromTemplateRequest builderRequest,
        List<Assignment__c> assignments
    ) {
        // Create the request
        AddFromProjectTemplateService.AssignmentRequest request = new AddFromProjectTemplateService.AssignmentRequest(
            builderRequest.TemplateId,
            builderRequest.TargetId
        );

        Map<Id, Assignment__c> templateAssignments = new Map<Id, Assignment__c>();
        for (Assignment__c assignment : assignments) {
            if (assignment.Project__c == builderRequest.TemplateId) {
                templateAssignments.put(assignment.Id, assignment);
            }
        }

        List<SObjectCloneMapper> mapperList = new List<SObjectCloneMapper>();

        // For each assignment, override the values from the request
        for (Id assignmentId : templateAssignments.keySet()) {
            SObjectCloneMapper mapper = new SObjectCloneMapper(
                Assignment__c.SObjectType,
                new Set<SObjectCloneMapper.Field>()
            );

            Assignment__c overrideAssignment = buildOverrideAssignment(
                builderRequest,
                templateAssignments.get(assignmentId)
            );

            mapper.SObjectRecordsToOverride = new Map<Id, SObject>{
                assignmentId => overrideAssignment
            };

            mapperList.add(mapper);
        }
        request.Mappers = mapperList;

        // Set the start date you want to offset assignment dates by
        request.StartDate = builderRequest.StartDate;

        return request;
    }

    private static Assignment__c buildOverrideAssignment(
        AddAssignmentFromTemplateRequest builderRequest,
        Assignment__c templateAssignment
    ) {
        Assignment__c overrideAssignment = new Assignment__c();

        if (
            builderRequest.PlannedBillRateMultiplier != null &&
            templateAssignment.Planned_Bill_Rate__c != null
        ) {
            overrideAssignment.Planned_Bill_Rate__c =
                builderRequest.PlannedBillRateMultiplier * templateAssignment.Planned_Bill_Rate__c;
        }

        if (builderRequest.BillRateMultiplier != null && templateAssignment.Bill_Rate__c != null) {
            overrideAssignment.Bill_Rate__c =
                builderRequest.BillRateMultiplier * templateAssignment.Bill_Rate__c;
        }

        if (builderRequest.MilestoneOverride != null) {
            overrideAssignment.Milestone__c = builderRequest.MilestoneOverride;
        }

        return overrideAssignment;
    }

    global with sharing class AddAssignmentFromTemplateRequest {
        @InvocableVariable(
            required=true
            label='Template ID'
            description='The ID of the template project you want to add assignments from.'
        )
        global Id TemplateId;

        @InvocableVariable(
            required=true
            label='Target ID'
            description='The ID of the project you want to add assignments to.'
        )
        global Id TargetId;

        @InvocableVariable(
            label='Offset Start Date'
            description='The start date you want to offset assignments dates from.'
        )
        global Date StartDate;

        @InvocableVariable(
            label='Planned Bill Rate Multiplier'
            description='Applies a multiplier to the planned bill rate on each assignment.'
        )
        global Double PlannedBillRateMultiplier = 1;

        @InvocableVariable(
            label='Bill Rate Multiplier'
            description='Applies a multiplier to the bill rate on each assignment.'
        )
        global Double BillRateMultiplier = 1;

        @InvocableVariable(
            label='Milestone Override'
            description='The milestone to override on assignments.'
        )
        global Id MilestoneOverride;

        global AddAssignmentFromTemplateRequest() {
        }
    }
}

Methods

AssignmentRequest

global AssignmentRequest(Id templateProjectId, Id destinationProjectId)

A default constructor with minimum required properties.

Input Parameters

Name Type Description
templateProjectId Id The project template ID.
destinationProjectId Id The destination project ID.

pse.AddFromProjectTemplateService.ResourceRequestToProjectRequest

global with sharing class ResourceRequestToProjectRequest extends AddFromProjectRequest

The request structure for adding resource requests to a project. To be used with addFromTemplates.
Fields are copied from a Resource Request field set that is referenced in the following custom settings:
• Template Proj RR Fieldset
• Template Proj Columns RR Fieldset
• Template Proj Alt Copy RR Fieldset

This class extends pse.AddFromProjectTemplateService.AddFromProjectRequest

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.

global with sharing class ActionResourceRequestsAddFromTemplates {
    //Prevents unwanted instantiation
    private ActionResourceRequestsAddFromTemplates() {
    }

    @InvocableMethod(
        label='Add Resource Requests from Template'
        description='Add resource requests from the given template ID to an opportunity or project.'
        category='Templating'
    )
    global static void run(List<ArrftRequest> builderRequests) {
        List<AddFromProjectTemplateService.AddFromProjectRequest> apiRequests = new List<AddFromProjectTemplateService.AddFromProjectRequest>();

        Set<Id> templateIds = new Set<Id>();
        for (ArrftRequest request : builderRequests) {
            templateIds.add(request.TemplateId);
        }

        List<Resource_Request__c> resourceRequests = ResourceRequestSelector.newInstance()
            .selectByProjectId(
                templateIds,
                new Set<String>{ 'Id', 'Project__c', 'SOW_Hours__c', 'Requested_Bill_Rate__c' }
            );

        // Create the Add Resource Requests from Template requests
        for (ArrftRequest req : builderRequests) {
            apiRequests.add(makeRequest(req, resourceRequests));
        }

        // Enqueue the Add Resource Requests from Template requests
        AddFromProjectTemplateService.addFromTemplates(apiRequests);
    }

    private static AddFromProjectTemplateService.AddFromProjectRequest makeRequest(
        ArrftRequest builderRequest,
        List<Resource_Request__c> resourceRequests
    ) {
        AddFromProjectTemplateService.AddFromProjectRequest request;

        Map<Id, Resource_Request__c> templateRRs = new Map<Id, Resource_Request__c>();
        for (Resource_Request__c resourceRequest : resourceRequests) {
            if (resourceRequest.Project__c == builderRequest.TemplateId) {
                templateRRs.put(resourceRequest.Id, resourceRequest);
            }
        }

        // For each resource request, override the the values from the request
        List<SObjectCloneMapper> mapperList = new List<SObjectCloneMapper>();
        for (Id resourceRequestId : templateRRs.keySet()) {
            SObjectCloneMapper mapper = new SObjectCloneMapper(
                Resource_Request__c.SObjectType,
                new Set<SObjectCloneMapper.Field>()
            );

            Resource_Request__c overrideResourceRequest = buildOverrideResourceRequest(
                builderRequest,
                templateRRs.get(resourceRequestId)
            );

            mapper.SObjectRecordsToOverride = new Map<Id, SObject>{
                resourceRequestId => overrideResourceRequest
            };

            mapperList.add(mapper);
        }

        if (builderRequest.TargetId.getSObjectType() == Proj__c.SobjectType) {
            // Create the request
            AddFromProjectTemplateService.ResourceRequestToProjectRequest projRequest = new AddFromProjectTemplateService.ResourceRequestToProjectRequest(
                builderRequest.TemplateId,
                builderRequest.TargetId
            );

            // Set whether associated resource skill requests should be copied as well
            projRequest.CopyResourceSkillRequests = builderRequest.CopyResourceSkillRequests;

            request = projRequest;
        } else if (builderRequest.TargetId.getSObjectType() == Opportunity.SobjectType) {
            // Create the request
            AddFromProjectTemplateService.ResourceRequestToOpportunityRequest oppRequest = new AddFromProjectTemplateService.ResourceRequestToOpportunityRequest(
                builderRequest.TemplateId,
                builderRequest.TargetId
            );

            // Set whether associated resource skill requests should be copied as well
            oppRequest.CopyResourceSkillRequests = builderRequest.CopyResourceSkillRequests;

            request = oppRequest;
        }

        request.Mappers = mapperList;

        // Set the start date you want to offset resource request dates by
        request.StartDate = builderRequest.StartDate;

        return request;
    }

    private static Resource_Request__c buildOverrideResourceRequest(
        ArrftRequest builderRequest,
        Resource_Request__c templateResourceRequest
    ) {
        Resource_Request__c overrideResourceRequest = new Resource_Request__c();

        if (builderRequest.StartDateOverride != null) {
            overrideResourceRequest.Start_Date__c = builderRequest.StartDateOverride;
        }

        if (builderRequest.EndDateOverride != null) {
            overrideResourceRequest.End_Date__c = builderRequest.EndDateOverride;
        }

        if (builderRequest.MilestoneId != null) {
            overrideResourceRequest.Milestone__c = builderRequest.MilestoneId;
        }

        if (templateResourceRequest.SOW_Hours__c != null) {
            overrideResourceRequest.SOW_Hours__c =
                builderRequest.HoursMultiplier * templateResourceRequest.SOW_Hours__c;
        }

        if (templateResourceRequest.Requested_Bill_Rate__c != null) {
            overrideResourceRequest.Requested_Bill_Rate__c =
                builderRequest.RequestedBillRateMultiplier *
                templateResourceRequest.Requested_Bill_Rate__c;
        }

        return overrideResourceRequest;
    }

    global with sharing class ArrftRequest {
        @InvocableVariable(
            required=true
            label='Template ID'
            description='The ID of the template project you want to add resource requests from.'
        )
        global ID TemplateId;

        @InvocableVariable(
            required=true
            label='Target ID'
            description='The ID of the project or opportunity you want to add resource requests to.'
        )
        global ID TargetId;

        @InvocableVariable(
            label='Offset Start Date'
            description='The start date you want to offset resource request dates from.'
        )
        global Date StartDate;

        @InvocableVariable(
            label='Start Date Override'
            description='The start date to override on resource requests.'
        )
        global Date StartDateOverride;

        @InvocableVariable(
            label='End Date Override'
            description='The end date to override on resource requests.'
        )
        global Date EndDateOverride;

        @InvocableVariable(
            label='Hours Multiplier'
            description='Apply a multiplier to the planned hours on each resource request.'
        )
        global Double HoursMultiplier = 1;

        @InvocableVariable(
            label='Requested Bill Rate Multiplier'
            description='Apply a multiplier to the requested bill rate on each resource request.'
        )
        global Double RequestedBillRateMultiplier = 1;

        @InvocableVariable(
            label='Milestone ID'
            description='The ID of the milestone you want to map resource requests to.'
        )
        global ID MilestoneId;

        @InvocableVariable(
            label='Copy Resource Skill Requests'
            description='Set to false if you do not want to copy any associated resource skill requests.'
        )
        global Boolean CopyResourceSkillRequests = true;

        global ArrftRequest() {
        }
    }
}

Properties

Name Type Description
CopyResourceSkillRequests Boolean Copies resource skill requests, which are are not copied by default.
Fields are copied from a Resource Skill Request field set that is referenced in the Resource Skill Request Fieldset custom setting.

Methods

ResourceRequestToProjectRequest

global ResourceRequestToProjectRequest(Id templateProjectId, Id destinationProjectId)

A default constructor with minimum required properties.

Input Parameters

Name Type Description
templateProjectId Id The project template ID.
destinationProjectId Id The destination project ID.

pse.AddFromProjectTemplateService.ResourceRequestToOpportunityRequest

global with sharing class ResourceRequestToOpportunityRequest extends AddFromProjectRequest

The request structure for adding resource requests to an opportunity. To be used with addFromTemplates. Fields are copied from a Resource Request field set that is referenced in the following custom settings: • Template Proj RR Fieldset • Template Proj Columns RR Fieldset • Template Proj Alt Copy RR Fieldset

This class extends pse.AddFromProjectTemplateService.AddFromProjectRequest

Properties

Name Type Description
DestinationOpportunityId Id The opportunity ID that related records are copied to.
CopyResourceSkillRequests Boolean Copies resource skill requests, which are are not copied by default.
Fields are copied from a Resource Skill Request field set that is referenced in the Resource Skill Request Fieldset custom setting.

Methods

ResourceRequestToOpportunityRequest

global ResourceRequestToOpportunityRequest(Id templateProjectId, Id destinationOpportunityId)

A default constructor with minimum required properties.

Input Parameters

Name Type Description
templateProjectId Id The project template ID.
destinationOpportunityId Id The destination opportunity ID.

pse.AddFromProjectTemplateService.AllRelatedRecordsRequest

global with sharing class AllRelatedRecordsRequest extends AddFromProjectRequest

The request structure for adding all related record types to a project. To be used with addFromTemplates.

This class extends pse.AddFromProjectTemplateService.AddFromProjectRequest

Methods

AllRelatedRecordsRequest

global AllRelatedRecordsRequest(Id templateProjectId, Id destinationProjectId)

A default constructor with minimum required properties.

Input Parameters

Name Type Description
templateProjectId Id The project template ID.
destinationProjectId Id The destination project ID.

pse.AddFromProjectTemplateService.AddFromProjectResponse

global inherited sharing class AddFromProjectResponse

The response structure returned for each request.

Properties

Name Type Description
Request pse.AddFromProjectTemplateService.AddFromProjectRequest The request associated with the response of AddFromProjectTemplateService.
Errors List<pse.AddFromProjectTemplateService.AddFromProjectError> Stores error messages that occur when executing methods from AddFromProjectTemplateService.
QueuedJobId Id The AddFromProjectTemplateService creates Queueables to complete the work in later transactions. This is the ID of the AsyncApexJob controlling the work. The record can be queried to monitor its status. When multiple requests are processed, only the QueuedJobId of the first response is set.

Methods

isSuccess

global Boolean isSuccess()

Indicates if the request was queued successfully.

pse.AddFromProjectTemplateService.AddFromProjectError

global with sharing class AddFromProjectError

Stores error messages that occur when executing methods from AddFromProjectTemplateService.

Properties

Name Type Description
Message String The error message.
RecordId Id The Id of the record that the error message is associated with. It is optional
© Copyright 2009–2024 Certinia Inc. All rights reserved. Various trademarks held by their respective owners.