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: