Skip to content

Commit

Permalink
Merge pull request #3 from YokySantiago/master
Browse files Browse the repository at this point in the history
INT-483: Add missing endpoints to n8n-onfleet node
  • Loading branch information
jamesliupenn authored Jan 19, 2022
2 parents 34f3b33 + 49a8e03 commit 2fb2be6
Show file tree
Hide file tree
Showing 14 changed files with 498 additions and 141 deletions.
63 changes: 61 additions & 2 deletions packages/nodes-base/nodes/Onfleet/Onfleet.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import {
OnfleetTask,
OnfleetTaskComplete,
OnfleetTaskUpdate,
OnfleetTeamAutoDispatch,
OnfleetTeams,
OnfleetWebhook,
OnfleetWorker,
OnfleetWorkerEstimates,
OnfleetWorkerFilter,
OnfleetWorkerSchedule
} from './interfaces';
Expand Down Expand Up @@ -106,7 +108,7 @@ export class Onfleet implements INodeType {
},
],
default: 'tasks',
description: 'The resource to perform operations on.',
description: 'The resource to perform operations on',
},
// Operations
...adminOperations,
Expand Down Expand Up @@ -525,7 +527,7 @@ export class Onfleet implements INodeType {
* @param operation Current team opration
* @returns {OnfleetTeams} Team information
*/
static getTeamFields(this: IExecuteFunctions, item: number, operation: string): OnfleetTeams | null {
static getTeamFields(this: IExecuteFunctions, item: number, operation: string): OnfleetTeams | OnfleetWorkerEstimates | OnfleetTeamAutoDispatch | null {
if (operation === 'create') {
/* -------------------------------------------------------------------------- */
/* Get fields to create a team */
Expand Down Expand Up @@ -555,6 +557,47 @@ export class Onfleet implements INodeType {
}
Object.assign(teamData, additionalFields);
return teamData;
} else if (operation === 'getTimeEstimates') {
/* -------------------------------------------------------------------------- */
/* Get driver time estimates for tasks that haven't been created yet */
/* -------------------------------------------------------------------------- */
const dropoff = this.getNodeParameter('dropoff', item) as boolean;
const pickup = this.getNodeParameter('pickup', item) as boolean;
if (!dropoff && !pickup) throw new Error('At least 1 of dropoffLocation or pickupLocation must be selected');
const longitudeField = `${dropoff ? 'dropoff' : 'pickup'}Longitude`;
const latitudeField = `${dropoff ? 'dropoff' : 'pickup'}Latitude`;
const longitude = this.getNodeParameter(longitudeField, item) as string;
const latitude = this.getNodeParameter(latitudeField, item) as string;

const workerTimeEstimates = {} as OnfleetWorkerEstimates;
if (pickup) {
workerTimeEstimates.pickupLocation = `${longitude},${latitude}`;
workerTimeEstimates.pickupTime = (new Date(this.getNodeParameter('pickupTime', item) as Date)).getTime() / 1000;
}
if(dropoff) {
workerTimeEstimates.dropoffLocation = `${longitude},${latitude}`;
}

const additionalFields = this.getNodeParameter('additionalFields', item) as IDataObject;
Object.assign(workerTimeEstimates, additionalFields);
return workerTimeEstimates;
} else if (operation === 'autoDispatch') {
/* -------------------------------------------------------------------------- */
/* Dynamically dispatching tasks on the fly */
/* -------------------------------------------------------------------------- */
const teamAutoDispatch = {} as OnfleetTeamAutoDispatch;
const {
taskTimeWindow, scheduleTimeWindow, ...additionalFields
} = this.getNodeParameter('additionalFields', item) as IDataObject;
if (taskTimeWindow) {
teamAutoDispatch.taskTimeWindow= JSON.parse((taskTimeWindow as string));
}
if (scheduleTimeWindow) {
teamAutoDispatch.scheduleTimeWindow= JSON.parse((scheduleTimeWindow as string));
}

Object.assign(teamAutoDispatch, additionalFields);
return teamAutoDispatch;
}
return null;
}
Expand Down Expand Up @@ -1176,6 +1219,22 @@ export class Onfleet implements INodeType {
const id = this.getNodeParameter('id', index) as string;
const path = `${resource}/${id}`;
responseData.push(await onfleetApiRequest.call(this, 'DELETE', encodedApiKey, path));
} else if (operation === 'getTimeEstimates') {
/* -------------------------------------------------------------------------- */
/* Get driver time estimates for tasks that haven't been created yet */
/* -------------------------------------------------------------------------- */
const id = this.getNodeParameter('id', index) as string;
const workerTimeEstimates = Onfleet.getTeamFields.call(this, index, operation) as OnfleetWorkerSchedule;
const path = `${resource}/${id}/estimate`;
responseData.push(await onfleetApiRequest.call(this, 'GET', encodedApiKey, path, {}, workerTimeEstimates));
} else if (operation === 'autoDispatch') {
/* -------------------------------------------------------------------------- */
/* Dynamically dispatching tasks on the fly */
/* -------------------------------------------------------------------------- */
const id = this.getNodeParameter('id', index) as string;
const teamAutoDispatch = Onfleet.getTeamFields.call(this, index, operation) as OnfleetWorkerSchedule;
const path = `${resource}/${id}/dispatch`;
responseData.push(await onfleetApiRequest.call(this, 'POST', encodedApiKey, path, teamAutoDispatch));
}
} catch (error) {
if (this.continueOnFail()) {
Expand Down
4 changes: 2 additions & 2 deletions packages/nodes-base/nodes/Onfleet/OnfleetTrigger.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class OnfleetTrigger implements INodeType {
group: [ 'trigger' ],
version: 1,
subtitle: '={{$parameter["events"]}}',
description: 'Starts the workflow when Onfleet events occur.',
description: 'Starts the workflow when Onfleet events occur',
defaults: {
name: 'Onfleet Trigger',
color: '#AA81F3',
Expand Down Expand Up @@ -142,7 +142,7 @@ export class OnfleetTrigger implements INodeType {
.then(responseData => {
if (responseData.id === undefined) {
// Required data is missing so was not successful
throw new NodeApiError(this.getNode(), responseData, { message: 'Onfleet webhook creation response did not contain the expected data.' });
throw new NodeApiError(this.getNode(), responseData, { message: 'Onfleet webhook creation response did not contain the expected data' });
}

webhookData[event] = responseData.id as string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ export const adminOperations = [
{
name: 'Create',
value: 'create',
description: 'Create a new Onfleet admin.',
description: 'Create a new Onfleet admin',
},
{
name: 'Remove',
value: 'delete',
description: 'Remove an Onfleet admin.',
description: 'Remove an Onfleet admin',
},
{
name: 'List',
value: 'getAll',
description: 'List all Onfleet admins.',
description: 'List all Onfleet admins',
},
{
name: 'Update',
value: 'update',
description: 'Update an Onfleet admin.',
description: 'Update an Onfleet admin',
},
],
default: 'getAll',
Expand All @@ -43,31 +43,31 @@ const adminNameField = {
name: 'name',
type: 'string',
default: '',
description: 'The administrator\'s name.',
description: 'The administrator\'s name',
} as INodeProperties;

const adminEmailField = {
displayName: 'Email',
name: 'email',
type: 'string',
default: '',
description: 'The administrator\'s email address.',
description: 'The administrator\'s email address',
} as INodeProperties;

const adminPhoneField = {
displayName: 'Phone',
name: 'phone',
type: 'string',
default: '',
description: 'The administrator\'s phone number.',
description: 'The administrator\'s phone number',
} as INodeProperties;

const adminReadOnlyField = {
displayName: 'Read only',
name: 'isReadOnly',
type: 'boolean',
default: false,
description: 'Whether this administrator can perform write operations.',
description: 'Whether this administrator can perform write operations',
} as INodeProperties;

export const adminFields = [
Expand All @@ -88,7 +88,7 @@ export const adminFields = [
},
default: '',
required: true,
description: 'The ID of the admin object for lookup.',
description: 'The ID of the admin object for lookup',
},
{
displayOptions: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ export const containerOperations = [
{
name: 'Insert tasks (or append)',
value: 'add',
description: 'Insert tasks at index (or append).',
description: 'Insert tasks at index (or append)',
},
{
name: 'Update tasks',
value: 'update',
description: 'Fully replace a container\'s tasks.',
description: 'Fully replace a container\'s tasks',
},
{
name: 'Get container',
value: 'get',
description: 'Get container information.',
description: 'Get container information',
},
],
default: 'get',
Expand All @@ -52,15 +52,15 @@ const containerTypeField = {
},
],
default: '',
description: 'Container type.',
description: 'Container type',
} as INodeProperties;

const containerIdField = {
displayName: 'ID',
name: 'containerId',
type: 'string',
default: '',
description: 'The object ID according to the container chosen.',
description: 'The object ID according to the container chosen',
} as INodeProperties;

const insertTypeField = {
Expand All @@ -82,31 +82,31 @@ const insertTypeField = {
},
],
default: '',
description: 'The index given indicates the position where the tasks are going to be inserted.',
description: 'The index given indicates the position where the tasks are going to be inserted',
} as INodeProperties;

const indexField = {
displayName: 'Index',
name: 'index',
type: 'number',
default: '',
description: 'The index given indicates the position where the tasks are going to be inserted.',
description: 'The index given indicates the position where the tasks are going to be inserted',
} as INodeProperties;

const tasksField = {
displayName: 'Tasks (JSON)',
name: 'tasks',
type: 'json',
default: '[]',
description: 'Array witht the task\'s ID that are going to be used in JSON format.',
description: 'Array witht the task\'s ID that are going to be used in JSON format',
} as INodeProperties;

const considerDependenciesField = {
displayName: 'Consider dependencies',
name: 'considerDependencies',
type: 'boolean',
default: false,
description: 'Whether to include the target task\'s dependency family (parent and child tasks) in the resulting assignment operation.',
description: 'Whether to include the target task\'s dependency family (parent and child tasks) in the resulting assignment operation',
} as INodeProperties;

export const containerFields = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ export const destinationOperations = [
{
name: 'Create',
value: 'create',
description: 'Create a new destination.',
description: 'Create a new destination',
},
{
name: 'Get',
value: 'get',
description: 'Get a specific destination.',
description: 'Get a specific destination',
},

],
Expand All @@ -33,47 +33,47 @@ const unparsedField = {
displayName: 'Unparsed adress',
name: 'unparsed',
type: 'boolean',
description: 'Whether the address is specified in a single.',
description: 'Whether the address is specified in a single',
default: false,
} as INodeProperties;

const unparsedAddressField = {
displayName: 'Destination address',
name: 'address',
type: 'string',
description: 'The destination\'s street address details.',
description: 'The destination\'s street address details',
default: null,
} as INodeProperties;

const unparsedAddressNumberField = {
displayName: 'Number',
name: 'addressNumber',
type: 'string',
description: 'The number component of this address, it may also contain letters.',
description: 'The number component of this address, it may also contain letters',
default: '',
} as INodeProperties;

const unparsedAddressStreetField = {
displayName: 'Street',
name: 'addressStreet',
type: 'string',
description: 'The name of the street.',
description: 'The name of the street',
default: '',
} as INodeProperties;

const unparsedAddressCityField = {
displayName: 'City',
name: 'addressCity',
type: 'string',
description: 'The name of the municipality.',
description: 'The name of the municipality',
default: '',
} as INodeProperties;

const unparsedAddressCountryField = {
displayName: 'Country',
name: 'addressCountry',
type: 'string',
description: 'The name of the country.',
description: 'The name of the country',
default: '',
} as INodeProperties;

Expand All @@ -82,31 +82,31 @@ const addressNameField = {
name: 'addressName',
type: 'string',
default: '',
description: 'A name associated with this address.',
description: 'A name associated with this address',
} as INodeProperties;

const addressApartmentField = {
displayName: 'Apartment',
name: 'addressApartment',
type: 'string',
default: '',
description: 'The suite or apartment number, or any additional relevant information.',
description: 'The suite or apartment number, or any additional relevant information',
} as INodeProperties;

const addressNoteField = {
displayName: 'Address notes',
name: 'addressNotes',
type: 'string',
default: '',
description: 'Notes about the destination.',
description: 'Notes about the destination',
} as INodeProperties;

const addressPostalCodeField = {
displayName: 'Postal code',
name: 'addressPostalCode',
type: 'string',
default: '',
description: 'The postal or zip code.',
description: 'The postal or zip code',
} as INodeProperties;

export const destinationFields = [
Expand All @@ -124,7 +124,7 @@ export const destinationFields = [
},
default: '',
required: true,
description: 'The ID of the destination object for lookup.',
description: 'The ID of the destination object for lookup',
},
{
...unparsedField,
Expand Down
Loading

0 comments on commit 2fb2be6

Please sign in to comment.