/**
* @module mHelpDesk/craeteCreateMovementRequest
*/
const axios = require('axios')
const { getPromiseOfAccessToken } = require('./authentication')
const config = require('../config')
/**
* Create a movement request handler function. This is used to generate the
* handlers for pickup and delivery requests, because they are so similar.
* @param {string} typeId - The string of the job typeId to give mHelpDesk.
* @return {Function} A function to handle movement requests of the given type.
*/
exports.createCreateMovementRequestFunction = (
typeId, customFieldXMLNames, attachEquipment
) => async xmlObject => {
const accessToken = await getPromiseOfAccessToken()
// TODO: Remove this line once we can use service locations.
// eslint-disable-next-line no-unused-vars
const [serviceLocationData, equipmentData] = await Promise.all([
makeAPIRequest(
'get',
`/customers/${config.api.fieldValues.customerId}/servicelocations`,
accessToken
),
attachEquipment
? makeAPIRequest('get', '/equipment', accessToken) : Promise.resolve()
])
// TODO: Find the ids of the service location for this job.
// At the moment we cannot get service location custom fields, and so
// cannot find which ones are to be associated with the job, this will
// have to be done manually. This will need to change later.
const serviceLocation = { id: config.api.fieldValues.customerId }
let equipment
if (attachEquipment) {
const matchingEquipment = equipmentData.results
.map(equipment => ({
id: equipment.equipmentId,
clientReferenceNumber: equipment.customFields.filter(
({ customFieldId }) => customFieldId ===
config.api.jobCustomFieldMappings.ClientReferenceNumber
)[0].value
}))
.filter(
({ clientReferenceNumber }) =>
clientReferenceNumber === ('' + xmlObject.ClientReferenceNumber)
)
if (matchingEquipment.length !== 1) {
throw new Error(
`Found ${matchingEquipment.length} matching equipment, expected 1`
)
}
equipment = matchingEquipment[0]
}
const priority = {
'Standard': '1',
'Normal': '1',
'High': '2',
'Urgent': '3',
'Critical': '4'
}[xmlObject['Priority']]
if (!priority) {
throw new Error(`Invalid priority: ${xmlObject['Priority']}`)
}
// Find and build the custom field values.
const valueTranslators = {
'Hinging': x => x[0].toUpperCase(),
'IsLiftingRequired': x => x.toLowerCase() === 'true' ? 'True' : 'False',
'IsLightBoxRequired': x => x.toLowerCase() === 'true' ? 'y' : 'n',
'IsLockRequired': x => x.toLowerCase() === 'true' ? 'y' : 'n'
}
const customFields = customFieldXMLNames
.map(customField => {
const translator = valueTranslators[customField] || (value => value)
return {
customFieldId: config.api.jobCustomFieldMappings[customField],
fieldValue: translator(xmlObject[customField][0])
}
})
if (attachEquipment) {
customFields.push({
customFieldId: config.api.nonXMLCustomFieldIds.CRN_Equipment_Number,
fieldValue: equipment.clientReferenceNumber
})
}
const job = {
'customerId': config.api.fieldValues.customerId,
'serviceLocationId': serviceLocation.id,
'subject': 'Awaiting Job Name',
'statusId': 1,
priority,
'summary': '',
typeId,
'customFields': customFields,
'equipment': attachEquipment ? [equipment.id] : []
}
// Create the job on mHelpDesk.
const jobCreationResponseData = await makeAPIRequest(
'post', '/tickets', accessToken, job
)
// Get the ticket name, update it on mHelpDesk, and return it.
job.subject = `PA-${jobCreationResponseData.ticketNumber}M`
await makeAPIRequest(
'put', `/tickets/${jobCreationResponseData.ticketId}`, accessToken, job
)
return jobCreationResponseData.ticketNumber
}
/**
* Make a request of the given form, using the given access token, to the
* mHelpDesk API. It throws a custom error message if the request fails,
* returns any data yeilded by the response.
* @param {string} method - The http method to use.
* @param {string} url - The sub URL of the API to use.
* @param {string} accessToken - The acces token to authenticate with.
* @param {string} data - Any data to include.
* @returns {object} The data of the response.
*/
const makeAPIRequest = (method, url, accessToken, data) => {
const axiosConfig = {
method,
baseURL: config.api.url + `/portal/${config.api.portalId}`,
url,
headers: { 'Authorization': 'bearer ' + accessToken }
}
if (data) axiosConfig.data = data
return axios(axiosConfig)
.then(response => response.data)
.catch(error => {
error.message = 'mHelpDesk API usage failed. Status ' +
`${error.response.status} ${error.response.statusText}`
throw error
})
}