Dispatch Data Mappings
A dispatch rule can optionally define how data is prefilled into the dispatched form’s fields. By default, the following data will be prefilled.
Below is a list of ServiceTrade API field names, and their corresponding ServiceForms field names:
ServiceTrade API field name |
ServiceForms field name |
GET /api/job/:jobId |
|
job.id |
servicetrade_job_id |
job.number |
servicetrade_job_number |
job.description |
servicetrade_job_description |
job.location.name |
servicetrade_location_name |
job.location.address.street |
servicetrade_location_street |
job.location.address.city |
servicetrade_location_city |
job.location.address.state |
servicetrade_location_state |
job.location.address.postalCode |
servicetrade_location_postal_code |
job.customer.name |
servicetrade_customer_name |
job.customer.address.street |
servicetrade_customer_street |
job.customer.address.city |
servicetrade_customer_city |
job.customer.address.state |
servicetrade_customer_state |
job.customer.address.postalCode |
servicetrade_customer_postal_code |
job.location.primaryContact.name |
servicetrade_contact_name |
job.location.primaryContact.phone |
servicetrade_contact_phone |
job.location.primaryContact.mobile |
servicetrade_contact_mobile |
job.location.primaryContact.alternatePhone |
servicetrade_contact_alt_phone |
GET /api/appointment/:appointmentId |
|
appointment.windowStart |
servicetrade_appointment_start |
appointment.windowEnd |
servicetrade_appointment_end |
GET /api/servicerequest?status=open,in_progress&appointmentId=:appointmentId |
|
servicerequest[].id |
servicetrade_services[].service_request_id |
servicerequest[].description |
servicetrade_services[].description |
servicerequest[].serviceLine.name |
servicetrade_services[].service_line |
servicerequest[].asset.name |
servicetrade_services[].asset_name |
servicerequest[].asset.id |
servicetrade_services[].asset_id |
servicerequest[].deficiency.id |
servicetrade_services[].deficiency_id |
servicerequest[].windowStart |
servicetrade_services[].start |
servicerequest[].windowEnd |
servicetrade_services[].end |
servicerequest[].serviceRecurrence.frequency |
servicetrade_services[].frequency |
servicerequest[].serviceRecurrence.interval |
servicetrade_services[].interval |
servicerequest[].deficiency.id |
servicetrade_services[].deficiency_id |
servicerequest[].deficiency.description |
servicetrade_services[].deficiency_description |
servicerequest[].status |
servicetrade_services[].status |
GET /api/jobItem?jobId=:jobId |
|
jobItem[].id |
servicetrade_job_items[].id |
jobItem[].quantity |
servicetrade_job_items[].quantity |
jobItem[].name |
servicetrade_job_items[].name |
jobItem[].libItem.code |
servicetrade_job_items[].code |
jobItem[].cost |
servicetrade_job_items[].cost |
jobItem[].serviceRequest.id |
servicetrade_job_items[].service_id |
jobItem[].serviceRequest.description |
servicetrade_job_items[].service_description |
GET /api/asset?appointmentId=:appointmentIdto get only this appointment’s assets GET /api/asset?locationId=:locationIdto get ALL assets at this location |
|
asset[].id |
servicetrade_assets[].asset_id |
asset[].name |
servicetrade_assets[].name |
asset[].serviceLine.name |
servicetrade_assets[].service_line |
asset[].properties.* Properties vary by asset definition |
servicetrade_assets[].properties_* Properties vary by asset definition Example: properties_barcode |
GET /api/deficiency?locationId=:locationId&status=new,verified |
|
deficiency[].id |
servicetrade_deficiencies[].deficiency_id |
deficiency[].asset.id |
servicetrade_deficiencies[].asset_id |
deficiency[].severity |
servicetrade_deficiencies[].severity |
deficiency[].status |
servicetrade_deficiencies[].status |
deficiency[].description |
servicetrade_deficiencies[].description |
deficiency[].resolution |
servicetrade_deficiencies[].resolution |
deficiency[].serviceLine.name |
servicetrade_deficiencies[].service_line |
deficiency[].job.id |
servicetrade_deficiencies[].job_id |
deficiency[].reportedOn |
servicetrade_deficiencies[].reported_date |
GET /api/user/:userId userId is the ID of the clocked-in technician who receives the dispatch |
|
user.id |
servicetrade_technician_id |
user.name |
servicetrade_technician_name |
user.phone |
servicetrade_technician_phone |
user.email |
servicetrade_technician_email |
user.details |
servicetrade_technician_details |
GET /api/brand/:brandId brandId is the ID of the brand associated with the job’s office |
|
brand.displayName (or job vendor name if not set) |
servicetrade_brand_display_name |
brand.webSite |
servicetrade_brand_website |
brand.details |
servicetrade_brand_details |
Destination Rule Methods
These methods can be called inside a destination rule to create/update data inside ServiceTrade.
createDeficiencies(deficienciesArray)
Creates a set of deficiencies from a given array. Each array member should have the following properties:
- assetId (int) - ID of asset to which deficiency should be added *Required
- jobId (int) - ID of job on which deficiency is being reported *Required
- severity (enum, one of: ‘inoperable’, ‘deficient’, ‘suggested’) *Required
- description (string) *Required
- status (enum, one of: ‘new’, ‘verified’, ‘fixed’) *Required
- reportSource (enum, one of: ‘manual’, ‘mobile’) *Required
- images (array)
For each deficiency, this method will construct and execute an API call like:
let deficiencyPayload = {
assetId: assetId,
severity: severity,
description: description,
status: status,
reportSource: reportSource,
jobId: jobId,
Images: [] // TODO
};
servicetrade.post('/deficiency', deficiencyPayload);
createAssets(assetsArray)
Creates a set of assets from a given array. Each array member should have the following properties:
- locationId (int) - ID of location to which asset should be added *Required
- type (enum, one of the types listed in GET /api/assetDefinition) *Required
- parentId (int) - ID of the asset which is the parent of the asset being added (optional; if not supplied, the top-level building asset will be used as the parent)
- properties (object -- contents vary by asset definition) *Required
For each asset, this method will construct an API call like:
let assetPayload = {
locationId: locationId,
type: type,
parentId: parentId,
properties: properties
};
servicetrade.post('/asset’, assetPayload);
updateAssets(assetsArray)
Updates a set of assets from a given array. Each array member should have the following properties:
- assetId (int) - ID of the asset to be updated *Required
- properties (object -- contents vary by asset definition)
- status (enum, one of: ‘active’, ‘inactive’)
For each asset, this method will construct an API call like:
let assetPayload = {
status: status,
properties: properties
};
servicetrade.put('/asset/’ + assetId, assetPayload);
createJobItems(jobItemsArray)
Creates a set of job items from a given array. Each array member should have the following properties:
- jobId (int) - ID of the job to which the job item should be added *Required
- libItemId (int) - ID of lib item to use when creating the job item. *Required, unless ‘name’ and ‘serviceLineId’ are provided
- name (string) [REQUIRED, unless ‘libItemId’ is provided]
- serviceLineId (int) - ID of service line to use when creating the job item. *Required, unless ‘libItemId’ is provided AND referenced lib item has a service line assignment.
- quantity (float) *Required
- serviceRequestId (int) - ID of the service request to which the job item should be associated
- source (object - see job item API documentation for details)
For each job item, this method will construct an API call like:
let jobItemPayload = {
jobId: jobId,
libItemId: libItemId,
name: name,
serviceLineId: serviceLineId,
serviceRequestId: serviceRequestId,
quantity: quantity,
source: source,
usedOn: Moment().format(‘X’) // Always today
};
servicetrade.post('/jobitem’, jobItemPayload);
createJobAttachments(attachmentsArray)
Creates a set of job attachments from the given array. Each array member should have the following properties:
- jobId (int) - ID of the job to which the attachment should be added *Required
- attachmentUrl - the URL of the attachment *Required
Returns an array of attachment objects. Example:
/* creates a job attachment if the ‘Interesting Job Image’ question is answered */
let jobAttachmentsToCreate = [];
if (SF.answers.Interesting_Job_Image && SF.answers.Interesting_Job_Image.value) {
jobAttachmentsToCreate.push({
attachmentUrl: SF.answers.Interesting_Job_Image.value,
jobId: SF.job.id
});
}
await SF.createJobAttachments(jobAttachmentsToCreate);
createAssetAttachments(attachmentsArray)
Creates a set of asset attachments from the given array. Each array member should have the following properties:
- assetId (int) - ID of the asset to which the attachment should be added *Required
- attachmentUrl - the URL of the attachment *Required
Returns an array of attachment objects. Example:
/* creates attachments on all assets that have the ‘Interesting Image’ question answered */
let assets = SF.answers.servicetrade_assets ? SF.answers.servicetrade_assets.values : [];
let assetAttachmentsToCreate = [];
for (let a of assets) {
const assetId = d.asset_id ? d.asset_id.value : null;
if (assetId && a.Interesting_Image && a.Interesting_Image.value) {
assetAttachmentsToCreate.push({
attachmentUrl: a.Interesting_Image.value,
assetId: assetId
});
}
}
await SF.createAssetAttachments(assetAttachmentsToCreate);
Example Destination Rule:
The content shown below will be entered by a user into the ‘code goes here’ box in https://app.moqups.com/BlmK9KQVCB/view/page/aeb147601
/* creates deficiencies for each asset that has a Visual or Functional test failure */
let assets = SF.answers.servicetrade_assets ? SF.answers.servicetrade_assets.values : [];
for (asset of assets) {
const assetId = asset.asset_id ? asset.asset_id.value : null;
if (!assetId) {
const assetPayload = {
locationId: SF.job.location.id,
type: 'hvac_unit',
properties: {
barcode: asset.properties_barcode ? asset.properties_barcode.value : null,
area_serviced: asset.properties_area_serviced ? asset.properties_area_serviced.value : null
}
};
const newAsset = await SF.createAssets([assetPayload]);
asset.asset_id = {value: newAsset[0].id};
}
}
const deficientAssets = assets.filter(v => {
return (v.Visual && v.Visual.value == 'Fail') || (v.Functional && v.Functional.value == 'Fail');
});
let deficienciesToCreate = [];
for (let d of deficientAssets) {
let description, deficiency, severity;
const assetId = d.asset_id ? d.asset_id.value : null;
const failFunctional = d.Functional && d.Functional.value == 'Fail';
const failVisual = d.Visual && d.Visual.value == 'Fail';
if (failVisual && !failFunctional) {
description = 'Visual test failure';
severity = 'deficient';
} else if (!failVisual && failFunctional) {
description = 'Functional test failure';
severity = 'inoperable';
} else {
description = 'Visual and functional test failure';
severity = 'inoperable';
}
let deficiencyPayload = {
assetId: assetId,
severity: severity,
description: description,
status: 'verified',
reportSource: 'mobile',
jobId: SF.job.id,
attachments: []
};
if (d.Visual_Failure_Image && d.Visual_Failure_Image.value) {
deficiencyPayload.attachments.push(d.Visual_Failure_Image.value);
}
if (d.Functional_Failure_Image && d.Functional_Failure_Image.value) {
deficiencyPayload.attachments.push(d.Functional_Failure_Image.value);
}
deficienciesToCreate.push(deficiencyPayload);
}
await SF.createDeficiencies(deficienciesToCreate);
Example of Device Magic Submission
// 20200124170428
// https://raw.githubusercontent.com/servicetrade/devicemagic/master/devicemagic-integration/devicemagic-submission-example.txt?token=AHOMPFIM3CX3EZ4TBVWIMA26GSSGU
{
"metadata": {
"device_id": "iPhone_B47461D1-D4D6-46BF-BBC0-70DBE8E0CC01",
"user_id": null,
"username": "Randolph Childress",
"submitted_at": "2019-11-27 10:09:02 -05:00",
"received_at": "2019-11-27 15:09:03 +00:00",
"submission_id": "42466896",
"device_submission_identifier": "F9875453-6E13-4710-8A4C-3F97C9B06F78",
"submission_counter": "1",
"form_name": "Inspection Job #17245299 - JHACO Supervisory Device",
"form_namespace": "http://www.devicemagic.com/xforms/903925e0-651f-0137-a3e7-0ab2d1506b92?a39a2330-f355-0137-0429-06b163b15006",
"form_version": "1.01"
},
"answers": {
"servicetrade_job_number": {
"value": "17245299"
},
"servicetrade_location_name": {
"value": "Jay Hospital"
},
"servicetrade_job_id": {
"value": "9801431"
},
"servicetrade_asset_list": {
"values": [
{
"servicetrade_asset_id": {
"value": "12560972"
},
"Zone_or_Address": {
"value": "A1"
},
"ID_____Area___Location": {
"value": "Front Door"
},
"Device_Type": {
"value": "Water Flow"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 1
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560981"
},
"Zone_or_Address": {
"value": "A1"
},
"ID_____Area___Location": {
"value": "Rear Entrance"
},
"Device_Type": {
"value": "Control Valve Supervisory Tamper Switch"
},
"Visual": {
"value": "Fail"
},
"Visual_Failure_Image": {
"value": "https://s3.amazonaws.com/hack-st-devicemagic-dev/servicetrade_asset_list%5B2%5D.Visual_Failure_Image.c97a45f0-f355-0137-6e84-028f45e3c9fe.JPEG"
},
"Functional": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 1
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 1
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560976"
},
"Zone_or_Address": {
"value": "A3"
},
"ID_____Area___Location": {
"value": "Office 123"
},
"Device_Type": {
"value": "Control Valve Supervisory Tamper Switch"
},
"Visual": {
"value": "Pass"
},
"Functional": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 1
},
"Control_Valve_Pass": {
"value": 1
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560982"
},
"Zone_or_Address": {
"value": "A4"
},
"ID_____Area___Location": {
"value": "Side Entrance"
},
"Device_Type": {
"value": "Control Valve Supervisory Tamper Switch"
},
"Visual": {
"value": "Pass"
},
"Functional": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 1
},
"Control_Valve_Pass": {
"value": 1
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560979"
},
"Zone_or_Address": {
"value": "B1"
},
"ID_____Area___Location": {
"value": "Office 555"
},
"Device_Type": {
"value": "Low/High Supervisory Pressure Switch"
},
"Visual": {
"value": "Pass"
},
"Functional": {
"value": "Fail"
},
"Functional_Failure_Image": {
"value": "https://s3.amazonaws.com/hack-st-devicemagic-dev/servicetrade_asset_list%5B5%5D.Functional_Failure_Image.c99df2f0-f355-0137-6e84-028f45e3c9fe.JPEG"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 1
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 1
}
},
{
"servicetrade_asset_id": {
"value": "12560973"
},
"Zone_or_Address": {
"value": "B14"
},
"ID_____Area___Location": {
"value": "Side Entrance"
},
"Device_Type": {
"value": "Water Flow"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 1
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560975"
},
"Zone_or_Address": {
"value": "B2"
},
"ID_____Area___Location": {
"value": "Back Door"
},
"Device_Type": {
"value": "Control Valve Supervisory Tamper Switch"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 1
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560980"
},
"Zone_or_Address": {
"value": "B8"
},
"ID_____Area___Location": {
"value": "Loading Dock"
},
"Device_Type": {
"value": "Low/High Supervisory Pressure Switch"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 1
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560977"
},
"Zone_or_Address": {
"value": "C14"
},
"ID_____Area___Location": {
"value": "Office 456"
},
"Device_Type": {
"value": "Water Flow"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 1
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560984"
},
"Zone_or_Address": {
"value": "C2"
},
"ID_____Area___Location": {
"value": "Office 234"
},
"Device_Type": {
"value": "Low/High Supervisory Pressure Switch"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 1
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560974"
},
"Zone_or_Address": {
"value": "C4"
},
"ID_____Area___Location": {
"value": "Back Door"
},
"Device_Type": {
"value": "Control Valve Supervisory Tamper Switch"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 1
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560978"
},
"Zone_or_Address": {
"value": "D6"
},
"ID_____Area___Location": {
"value": "Office 432"
},
"Device_Type": {
"value": "Water Flow"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 1
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 0
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
},
{
"servicetrade_asset_id": {
"value": "12560983"
},
"Zone_or_Address": {
"value": "D7"
},
"ID_____Area___Location": {
"value": "Office 995"
},
"Device_Type": {
"value": "Low/High Supervisory Pressure Switch"
},
"Visual": {
"value": "Pass"
},
"Is_Water_Flow": {
"value": 0
},
"Water_Flow_Pass": {
"value": 0
},
"Water_Flow_Fail": {
"value": 0
},
"Is_Control_Valve": {
"value": 0
},
"Control_Valve_Pass": {
"value": 0
},
"Control_Valve_Fail": {
"value": 0
},
"Is_Low_High": {
"value": 1
},
"Low_High_Pass": {
"value": 0
},
"Low_High_Fail": {
"value": 0
}
}
]
},
"Water_Flow_Device_Total": {
"value": 4
},
"Water_Flow_Device___Tested": {
"value": 0
},
"Water_Flow_Device___Passed": {
"value": 0
},
"Water_Flow_Device___Failed": {
"value": 0
},
"Control_Valve_Device_Total": {
"value": 5
},
"Control_Valve_Device___Tested": {
"value": 3
},
"Control_Valve_Device___Passed": {
"value": 2
},
"Control_Valve_Device___Failed": {
"value": 1
},
"Low_High_Device_Total": {
"value": 4
},
"Low_High_Device___Tested": {
"value": 1
},
"Low_High_Device___Passed": {
"value": 0
},
"Low_High_Device___Failed": {
"value": 1
}
}
}