Handling a trip

This tutorial is intended for developers who are involved in the development of (Planning-)software that is responsible for responding to trips by creating and executing trips that are a result of the trip. Creating a trip is described in tutorial Creating a trip

In the previous tutorial, we saw how easy it is to create a new trip. In this tutorial we discuss how the trip should be handled. Only Transporters are allowed to accept or reject a trip. Accepting or rejecting can be done by calling the Actions Trip.Accept and Trip.Reject respectively. There is no body to create or a need for content-type. Just execute a POST request to a specific URI and that’s it.

When a trip is accepted, its StatusName changes from "New" to "Planned"

When a trip is rejected, its StatusName changes from "New" to "Declined". This is a final state, nothing can be done anymore to the trip.

Let's move on and POST the following function to accept the trip

/Trips(3220)/Accept

The server responds with a result 200 (OK) and includes in the body the updated trip. The trip is in the form of an object of type TripSummary. Summary-types contain the fields of the related entity plus several extra fields of related child entities, so you don't need to perform extra requests.

{
  "odata.metadata" : "https://www.cabmanonline.nl/CCPService/DataServiceCCP.svc/$metadata#TripsSummary/@Element",
  "TripId" : 438778,
  "PlannedPickupTime" : "2014-12-04T10:59:50.387",
  "PlannedDropoffTime" : "2014-12-04T10:59:50.387",
  "StartingTime" : null,
  "Description" : "",
  "PlannedDistance" : 0.0,
  "TravelerCount" : 1,
  "WheelchairCount" : 0,
  "AttendantCount" : 0,
  "StatusName" : "Planned",
  "DayCode" : "E0001",
  "LicensePlate" : null,
  "PickUpLocationDescr" : null,
  "DropOffLocationDescr" : null,
  "Remark" : null,
  "Reference" : null,
  "FlightNumber" : null,
  "FlightDateTime": null,
  "FlightOrigin": null,
  "PaymentTypeName" : null,
  "VehicleKindName" : "Taxi",
  "CostCenterDescription" : null,
  "DatacommunicationTripId" : null,
  "VehicleNr" : null,
  "VehicleUnitName" : null,
  "AmountCash" : null,
  "AmountBill" : null,
  "LastUpdated" : "2014-12-04T10:03:38.323",
  "TransporterName" : "Taxi TEST",
  "AssignedTransporterName" : null,
  "DriverName" : "-",
  "ShiftId" : null,
  "VehicleId" : null,
  "DriverId" : null,
  "ContractorId" : null,
  "TripId" : 3220,
  "TransporterId" : 1,
  "AssignedTransporterId" : null,
  "PickUpLocationId" : null,
  "DropOffLocationId" : null,
  "VehicleTypeId" : null,
  "Deleted" : false,
  "FirstAddress" : {
    "Street" : "Wilhelminapark",
    "Number" : 36,
    "Addition" : null,
    "PostalCode" : null,
    "State" : null,
    "Town" : "TILBURG",
    "CountryId" : null,
    "Coordinates" : {
      "Latitude" : 51.565360000000005,
      "Longitude" : 5.0777600000000005,
      "FormatName" : "GeoDecimal"
    }
  },
  "LastAddress" : {
    "Street" : null,
    "Number" : null,
    "Addition" : null,
    "PostalCode" : null,
    "State" : null,
    "Town" : null,
    "CountryId" : null,
    "Coordinates" : {
      "Latitude" : null,
      "Longitude" : null,
      "FormatName" : null
    }
  }
}

What happens next?

  • The Trip can be handled by the planning team, that can specify a Driver and a Vehicle for the Trip.
  • Once editing to the Trip is complete, it can be sent to the dataterminal to be executed.
  • The vehicle starts to move to the pickup location of the Trip. It's StateName should change to "InTransit".
  • When the vehicle arrives at the pickup location and travelers are picked up, and the Trip has been started on the dataterminal, it's StateName should change from "Planned" to "Active" (traveler picked up) or to "NoShow" (traveler not present at the pickup location).
  • When the traveler(s) is/are transported to their destination the Trip can be closed, by changing it's StatusName to "Done".

All this information about Trips can be used to provide feedback to the trip software. Especially the "InTransit" can be useful, as an indication to the waiting traveler that the vehicle is on its way

Canceling or modifying a trip

It can happen that a trip has to be cancelled or details have to be changed on the trip, after the trip has been created. The following rules apply:

  • As long as the StatusName of the trip is "New", the trip can be updated of cancelled without further consequences.
    The software that is used to let the user Accept or Reject the trip should always present a refreshed trip, so the possible changes are reflected as well.
  • Trips that have the StatusName "Declined" cannot be updated nor cancelled.
  • Trips that have the StatusName "Planned" can only be updated or cancelled when there are no conflicting TripRules, which is explained in detail below.
  • It is not allowed to modify the StatusName-field of the Trip. The StatusName changes automatically as a result of the Actions that will be executed.

Trip rules

Trips that are already accepted (StatusName = "Planned") can only be cancelled or updated if none of the possible TripRules are violated. There are separate rules for cancelling or updating. You can edit and create TripRules using Cabman Online or using the OData-interface of CCP. A POST to create a typical TripRule could look like this:

POST /CCPService/DataServiceCCP.svc/TripRules HTTP/1.1
Authorization: Basic dGVzdEB0ZXN0LmNvbTp0ZXN0MTIz
Accept: application/json
Content-Type: application/json
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
CabmanCloudPlatformVersion: 40.0
MaxCabmanCloudPlatformVersion: 40.0
{
  "TripRuleTypeName": "Cancel",
  "TripRuleConstraintName": "TimeBeforePlannedTime",
  "DayOfWeekName": null,
  "Time": "36000000000",
}

TripRuleTypeName could either be "Cancel" or "Update".

TripRuleConstraintName could be one of the following values:

  • "FixedTime": Cancelling or updating is only allowed before a the given time of day
  • "TimeBeforePlannedTime": Cancelling or updating is only allowed before the given time before the planned start of the Trip

DayOfWeekName could either be null (rule applies to all days in the week) or one of the following values: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" or "Saturday". This gives you the opportunity to specify different rules for each day of the week.

Time is expressed in ticks (one tick = 100ns). The value 36000000000 x 100ns = 3600000000μs = 3600000ms = 3600s = 1 hour.

When an accepted Trip is cancelled (and no TripRules are being violated), its StatusName changes to "Cancelled", and it's related Trip(s) are cancelled, by setting their StatusName to "Canceled" (note: one "l" here!). When trips are synchronized (Trips where CCP is responsible for datacommunication to Cabman Terminals), they are withdrawn from the terminal.

When an accepted Trip is updated (and no TripRules are being violated), its StatusName changes to "New", and it's related Trips(s) are cancelled as well. This is because the Transporter, that has to perform the Trip, should validate and accept (or reject) the Trip again.

Synchronization

The Transporter that handles the Trip should be informed about new trips or changes in existing trips. The best way to achieve this, is using synchronisation, described in the guide Synchronisation. By periodically checking/syncing the entitysets Movements, Trips, Trips, Travelers, etc. the software keeps up-to-date about new, changed or deleted entities.

Using email notification

Using Cabman Online the Transporter can perform a number of Email Settings, which also has the option to receive email on new or changed trips. These setting can also be performed by the OData interface, using the generic Settings and SettingValues entitysets.

To get an overview of all possible settings you could perform the following GET request:

GET /CCPService/DataServiceCCP.svc/Settings HTTP/1.1
Authorization: Basic dGVzdEB0ZXN0LmNvbTp0ZXN0MTIz
Accept: application/json
Content-Type: application/json
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
CabmanCloudPlatformVersion: 40.0
MaxCabmanCloudPlatformVersion: 40.0
The response should look like:
{
  "odata.metadata": "http://localhost/CCPService/DataServiceCCP.svc/$metadata#Settings",
  "value": [
    ::
    {
      "SettingId": 7,
      "Name": "DefaultLanguage",
      "SettingTypeName": "String",
      "DefaultValue": "nl",
      "EntitySetId": 1,
      "Deleted": false,
      "LastUpdated": "2015-09-10T11:32:23.813"
    },
    ::
    {
      "SettingId": 11,
      "Name": "NotifyNewOrChangedTrip",
      "SettingTypeName": "String",
      "DefaultValue": "-",
      "EntitySetId": 32,
      "Deleted": false,
      "LastUpdated": "2015-09-10T11:32:23.813"
    },
    ::
  ]
}

We are particulary interested in SettingId 7, DefaultLanguage and SettingId 11, NotifyNewOrChangedTrip at which we are going to create a SettingValue.

First we need to check if there is already an existing setting value:

GET /SettingValues?$filter=SettingId eq 11&$select=SettingValueId HTTP/1.1
Authorization: Basic dGVzdEB0ZXN0LmNvbTp0ZXN0MTIz
Accept: application/json
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
CabmanCloudPlatformVersion: 40.0
MaxCabmanCloudPlatformVersion: 40.0

Result when the setting could be found:

{
  "odata.metadata": "http://localhost/CCPService/DataServiceCCP.svc/$metadata#SettingValues&$select=SettingValueId",
  "value": [
    {
      "SettingValueId": 34
    }
  ]
}

When no SettingValue could be found, the "value"-array will be empty. Now you can use a MERGE (to modify the existing SettingValue) or a POST (to create a new SettingValue). In the next example we are modifying the existing SettingValue (having SettingValueId = 34, obtained from the previous request), by sending a MERGE-request:

MERGE /CCPService/DataServiceCCP.svc/SettingValues(34) HTTP/1.1
Authorization: Basic dGVzdEB0ZXN0LmNvbTp0ZXN0MTIz
Content-Type: application/json
DataServiceVersion: 3.0
MaxDataServiceVersion: 3.0
CabmanCloudPlatformVersion: 40.0
MaxCabmanCloudPlatformVersion: 40.0

having the following body:

{
  "Value": "user@euphoria-it.nl"
}

Using the same kind of requests we can also set SettingId 7 DefaultLanguage, to specify in which language we want to receive the emails (currently: "ne", "en" or "de").

Now when a new trip is created or when an existing trip has been updated, the user will receive an email containing details about the created/updated trip.