Configuring Real-Time Sync for Actual Time Fields in Jobs
The Job object is configured with Actual Start Time and Actual End Time fields in Service Board. However, the corresponding fields are not configured for the Work Order object in Salesforce. If you have a business need to track scheduled versus actual times, you can add existing fields or custom fields to the Salesforce Work Order object to configure initial and real-time sync. In Salesforce, you can configure the Actual Start Time and Actual End Time fields for the Work Order, Event, or ServiceMax Event objects.
To configure real-time sync for Actual Time fields in Jobs:
1. In Max Designer, on the Developer Tools () launchpad menu, click Transform Templates, and then in the list view, click WorkOrder to Job Create Template.
2. On the record page, on the Overview tab, in the Custom Field Mappings field, add the following code, and then in the top left corner, click Save and Close ().
"dev_actual_start": "isoDateFormat(fields.SVMXC__Actual_Onsite_Response__c)",
"dev_actual_end": "isoDateFormat(fields.SVMXC__Completed_Date_Time__c)"
3. In the Transform Templates list view, click WorkOrder to Job Update Template, and then in the Custom Field Mappings field, add the same code shown in the previous step and save and close the record.
4. To sync Actual Start Time and Actual End Time fields between Jobs and Appointments, follow the steps in Creating an Event Handler to configure an Event Handler record with the following values.
Field
Value
Name
Actual Times Event Handler
Trigger
Before
Link Relation Operations list on Originators tab
Create Appointment
Update Job
Sample Source Code
package com.servicemax.dc.custom

import com.servicemax.core.MaxObject
import com.servicemax.core.annotations.Application
import com.servicemax.core.event_handler.TemplateOperationEventHandler
import com.servicemax.core.Database

@Application(application='svmx_dispatch_console')
public class ActualTimesEventHandler extends TemplateOperationEventHandler {
private static final String OBJECT_APPOINTMENT_ID = 'svmx_appointment'

@Override
public Object realExecute(Map<String, Object> parameters) {
MaxObject record = affectedMaxObject
def objectId = record.getDefinition().getFullIdentifier()
def isAppointment = objectId == OBJECT_APPOINTMENT_ID
if (isAppointment) {
this.handleAppointmentUpdate(record)
} else {
this.handleJobUpdate(record)
}
}

private void handleAppointmentUpdate(MaxObject record) {
def job = Database.querySingleResult('select * from svmx_job where io_uuid = :jobId', [jobId: record._svmx_related_to])
if (job) {
record.svmx_actual_start_time = job.dev_actual_start
record.svmx_actual_end_time = job.dev_actual_end
record.update()
}
}

private void handleJobUpdate(MaxObject record) {
def isActualStartChanged = record.isFieldChanged('dev_actual_start')
def isActualEndChanged = record.isFieldChanged('dev_actual_end')
if (isActualStartChanged || isActualEndChanged) {
def appts = Database.query('select * from svmx_appointment where svmx_related_to = :relatedTo', [relatedTo: record.io_uuid])
if (appts.size()) {
appts*.svmx_actual_start_time = record.getFieldValue('dev_actual_start')
appts*.svmx_actual_end_time = record.getFieldValue('dev_actual_end')
}
Database.update(appts)
}
}
}
For more information:
Was this helpful?