Dispatch Service
A Dispatch is a generic construct that represents the movement of the resources (eg. operator, vehicle) to multiple locations to perform pre-defined objectives at each location. Within a Dispatch, there are a set of tasks that the field operator needs to perform.
We can also say that the manifestation of the intent to move goods from or to a location(s) in order to perform a unit of action, i.e., a task or set of tasks is Dispatch.
The Platform Dispatch Service is to be built as a component of the OS1 Platform. The Dispatch Service provides abstract models, interfaces, and event stores for managing and monitoring the lifecycle of a Dispatch and the associated objectives and jobs.
The Dispatch Lifecycle defines a set of states through which a Dispatch proceeds as it develops.
The platform provides a default of five states for a Dispatch:
- Initiated: The Dispatch is being prepared.
- In-Progress: This signifies that the dispatch is currently being processed by the Participants.
- Closed: The custody ledger of the dispatch is reconciled and the dispatch has been completed.
Attributes of a Dispatch are divided into one of the following categories:
- Base: These are the attributes mandated by the platform for the Objective. Some of these attributes are mandatory.
- Custom: These are the attributes that the Tenant defines for the Objectives, to enhance their usability. Tenants can define custom validations, and specify whether they are indexed or non-indexed.
Attribute Name | Category | Purpose | Data Type Expected |
Tenant ID | Base | The ID of the tenant to whose realm the dispatch belongs. | String |
Dispatch ID | Base | A system-generated unique ID for the dispatch. This is maintained for every Dispatch created by the platform. | UUID |
Dispatch Reference ID (Optional) | Base | This field allows Tenants to give their Dispatch ID that may be generated by their batching & routing system, and this may be used for cross-reference and debugging. | VarChar |
Participant List (Optional) | Base | A list of Participants that execute the dispatch. This list can involve - Users, Vehicles, Devices, or any other types of Participants defined by the Tenant. The participant list can consist of either a list of ParticipantIDs or the complete details of participants mentioned in GraphQL. Example: [{ participantID: 1, participantType:"User"}, { participantID: 45, participantType: "Vehicle"}] A minimum of ONE User-type Participant is required to set the dispatch to “ASSIGNED” state, and then to “IN-PROGRESS” state. | Array of JSON |
Job List (Optional) | Base | This field contains a list of Job IDs. Required to set the Dispatch to “IN-PROGRESS” staate. | Array of JSON |
Custom Attributes 1-to-n (Indexed) | Custom | Custom attributes for a Dispatch with indexing. If required, the tenant is able to configure validations for these attributes. | Key-Value |
Custom Attributes 1-to-n (Non-Indexed) | Custom | Custom attributes for a Dispatch without indexing. If required, the Tenant is able to configure validations for these attributes. | Key-Value |
To create a Custom Dispatch Attribute, call the Post attribute for the dispatch endpoint.
Request bodies are specified in JSON format. The following examples show a request body for creating a Custom Dispatch Attribute:
Member | Description | Validation | Data type |
attributes | Dispatch/job type attributes configuration. | minItems: 1 | |
name | Name of the attribute. | minLength: 1 maxLength: 32 pattern: ^[a-zA-Z]{1,32}$ | string |
description (optional) | Description of the attribute. | minLength: 0 maxLength: 256 | string |
dataType | Data type of the attribute. | Valid values: string, number, boolean, object, array | string |
indexed | | default: false | boolean |
validation | Specifies all the validations to be performed on an attribute, when a participant of this type is created/updated. | | |
range | Field to specify the range that the attribute value must lie. In the case of the "string" datatype, the range will be the length of the string value. this validation allowed only for string and number type of attributes. | | number |
regex | Field to specify the regex pattern that the value of an attribute MUST match. This validation is allowed only for string-type of attributes. | minLength: 1 maxLength: 512 | string |
valueOneOf | Field to specify enum values for an attribute. List of valueOneOf should be homogeneous. | minItems: 1 | string |
required | Field to specify if the value for the attribute is mandatory or not. If TRUE, the value MUST be provided. | default: false | boolean |
To create a new dispatch, you need to consider the following components:
- Creating an empty dispatch
- Adding jobs to a dispatch
- Allocating resources to a dispatch
The Dispatch Service provides endpoints to create an empty dispatch. You can add jobs to the dispatch either in bulk (e.g. via the batching system) or one at a time (manually). Jobs can also be removed from an existing dispatch.
The Dispatch service also provides endpoints to allocate participants and resources to a Dispatch. All locations and workflows are provided as reference IDs in a Job.
To create a Dispatch, call the Create new dispatch endpoint.
Request bodies are specified in JSON format. The following examples show a request body for creating a Dispatch:
Member | Description | Validation | Data type |
dispatchRef | External dispatch reference. | minLength: 4 maxLength: 64 | string |
dispatchTypeId | Dispatch Type ID. | minLength: 4 maxLength: 64 | string |
The Dispatch Service fetches the corresponding workflow data and location data from respective services. The Dispatch Service further validates the workflows and whether the required input data has been provided for the execution of the workflows.
The dispatch service doesn't take care of a few things:
- It doesn't check the Dispatch execution feasibility in terms of the number of jobs added, the distance between locations, the load to be carried, Dispatch execution time, etc.
- It also doesn't check if the allocated resources exceed or fall short of the actual resource requirement.
All such limitations, if any, should be computed/determined before adding jobs to a Dispatch by applications or services that are external to Platform Dispatch Service.
After creating a Dispatch and allocating resources to it, the Dispatch is ready to publish. Publishing a Dispatch triggers pre-processing of the Dispatch which includes the following:
- Extract all of the reference IDs for locations, contacts, and workflows to actual data from the respective services.
- Merge one or more grouped objectives for a given location/time-slot/customer at the workflow level if they have the same workflow associated with them and the workflow ID designed for grouping.
The pre-processing provides an option to call an external route optimization engine.
After creation, the Dispatch is transferred to the Dispatch App installed on authenticated mobile devices of Users allocated to the Dispatch.
Dispatch execution functions through a standard SDK for mobile devices comprising the following modules:
- Dispatch Module
- Workflow Execution Module
- Status Update Module
- Incoming Notification Handler
- Location Tracking
Objective status updates flow back as objective events to the Dispatch Service through API calls made by the SDK and they are stored in the Objective Events Store.
Objective and Dispatch events are translated into Job events and stored in the Job Events Store.
Motion Tracking System (MTS) Service provides a way to capture streaming location data from GPS-enabled devices (e.g., mobile devices, vehicle GPS modules, etc.). In the case of the dispatch mobile app, the Location Tracking module of the SDK provides a configurable way to capture and stream location data from the mobile device to the MTS service, without any user intervention.
The Location Tracking module captures the following events along with location data:
- Objective status change event
- Device health data & user intervention on device settings (e.g., battery, mobile data connectivity, GPS enabled/disabled, etc).
MTS Service provides APIs and Pub-Sub mechanisms for continuous tracking of device location or geofence entry and exit events.
Objective workflows can include a physical transfer of inventory. For example, the Field Executive must pick up a shipment and then deliver it to successfully complete the workflow. Or you might also need to capture cash or some kind of document(s) as a part of the workflow.
Keeping a general ledger book-keeping of what inventory is picked or delivered at any point of an active dispatch is important. This introduces the concept of Custody.
Custody is an implicit mechanism to keep a ledger or record of what inventory (physical objects) is in the custody of an operator for a given dispatch. Dispatch always starts with zero inventory in custody and also should end with zero inventory in custody.
A Dispatch can only be closed when the general ledger tallies to zero.
Custody transfer is the mechanism to track the transfer of ownership. Custody implies knowing who has what, when, and where. It is a chronological documentation of all parties that came into contact with a shipment, and a history of all trades.
COLLECT (Execution Task) is when the inventory transfer is Receivables (In) and DROP-OFF (Execution Task) is when the inventory transfer is Payables (Out).
OS1 App developers can use GraphQL queries to retrieve lists for dispatches and jobs using a single API.