This document assumes familiarity with the following:

- \[Create shipment tasks\]\[1\]
- The introduction to \[Scheduled tasks\]\[3\], which covers the relationship between tasks, stops, and vehicles in detail.

As stated in \[Scheduled tasks\]\[3\] in the
**Fleet Engine Essentials**, you create tasks and associate them with a vehicle
stop as a way to model the real-world association between the task and the
location where the vehicle is expected to stop so that the driver can complete
the task.

From there, you manage the progress of tasks throughout their lifecycle by
sending updates to Fleet Engine so that it can best perform routing and status
updates along the task journey. One key way you do this is to update
the vehicle stop when the vehicle approaches, arrives at, and leaves the stop.
This enables reporting and analysis about the task progress for both
Fleet operators and end users. These status updates are as follows:

- **En route** : The `STATE` enum for `VehicleStop` uses `ENROUTE` to indicate that the stop is next up on the list for the vehicle itinerary. From the perspective of the task, it means any task associated with the stop is next on the list to be completed.
- **Arrived** : The `STATE` enum for `VehicleStop` uses `ARRIVED` to indicate that the vehicle has arrived at the stop. From the perspective of the task, it means that any task associated with the stop being actively worked on.
- **Completed**: You mark a stop complete by removing it from the list of stops for the vehicle. When you do this, Fleet Engine automatically marks all associated tasks as CLOSED. For more details about closing tasks, see \[Finalize tasks\]\[4\].

This document describes how update stop status using server-side approaches. You
can also do this from your driver app if you provide the driver the ability to
manage tasks using a trusted device. Use only one method so that you avoid race
conditions and maintain a single source of truth.

## Vehicle is enroute to stop

Your system should notify Fleet Engine when the vehicle begins navigation to the
next stop. This improves ETA and route calculations.

### Required fields for stop updates

Fleet Engine ignores all other fields in the entity for the notification.

<br />

| Field | Value |
|---|---|
| `remainingVehicleJourneySegments` | List of remaining vehicle stops with their states marked as State.NEW. |

<br />

### Enroute to stop example

The following examples show how to notify Fleet Engine that a vehicle is
enroute to its next stop, using either the \[Java gRPC library\]\[5\] or an HTTP
REST call to `UpdateDeliveryVehicle`.All other stops are marked as new.

### gRPC

```java
 static final String PROJECT_ID = "my-delivery-co-gcp-project";
 static final String VEHICLE_ID = "vehicle-8241890";

 DeliveryServiceBlockingStub deliveryService =
   DeliveryServiceGrpc.newBlockingStub(channel);

 // Vehicle settings
 DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
     // Next stop marked as ENROUTE
     .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 1st stop
        .setStop(VehicleStop.newBuilder()
            .setPlannedLocation(LocationInfo.newBuilder()
                .setPoint(LatLng.newBuilder()
                    .setLatitude(37.7749)
                    .setLongitude(122.4194)))
            .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
            .setState(VehicleStop.State.ENROUTE)))
     // All other stops marked as NEW
     .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
        .setStop(VehicleStop.newBuilder()
            .setPlannedLocation(LocationInfo.newBuilder()
                .setPoint(LatLng.newBuilder()
                    .setLatitude(37.3382)
                    .setLongitude(121.8863)))
            .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
            .setState(VehicleStop.State.NEW)))
     .build();

 // DeliveryVehicle request
 UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
   UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
       .setName(vehicleName)
       .setDeliveryVehicle(deliveryVehicle)
       .setUpdateMask(FieldMask.newBuilder().addPaths("remaining_vehicle_journey_segments"))
       .build();

 try {
   DeliveryVehicle updatedDeliveryVehicle =
       deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
 } catch (StatusRuntimeException e) {
   Status s = e.getStatus();
   switch (s.getCode()) {
      case NOT_FOUND:
        break;
      case PERMISSION_DENIED:
        break;
   }
   return;
 }
```

### REST

```console
PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`
```

- *\<id\>* is a unique identifier for the task.
- The request header must contain a field *Authorization* with the value *Bearer \<token\>* , where *\<token\>* is issued by your server according to the guidelines described in \[Service account roles\]\[6\] and \[JSON Web tokens\]\[6\].
- The request body must contain a `DeliveryVehicle` entity:

Example `curl` command:

> [!NOTE]
> **Note:** This command overwrites any `remainingVehicleJourneySegments` already set on the delivery vehicle.

```console
 # Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
 # environment
 curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
   -H "Content-type: application/json" \
   -H "Authorization: Bearer ${JWT}" \
   --data-binary @- << EOM
 {
   "remainingVehicleJourneySegments": [
     {
       "stop": {
         "state": "ENROUTE",
         "plannedLocation": {
           "point": {
             "latitude": 37.7749,
             "longitude": -122.084061
           }
         },
         "tasks": [
           {
             "taskId": "${TASK1_ID}"
           }
         ]
       }
     },
     {
       "stop": {
         "state": "NEW",
         "plannedLocation": {
           "point": {
             "latitude": 37.3382,
             "longitude": 121.8863
           }
         },
         "tasks": [
           {
             "taskId": "${TASK2_ID}"
           }
         ]
       }
     }
   ]
 }
 EOM
```

> [!WARNING]
> **Experimental:** As an experimental feature, the `LocationInfo` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#locationinfo) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt)) field now supports using `place` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt#FIELDS.place)), either alongside or instead of `LatLng`.

[placeidtrips1](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#locationinfo): /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#locationinfo
[placeidtrips2](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt): /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html
[placeidtrips3](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place): /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place
[placeidtrips4](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt#FIELDS.place): /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html#FIELDS.place

## Vehicle arrives at stop

Fleet Engine must be notified when a vehicle arrives at a stop.

### Required fields for stop updates

Fleet Engine ignores all other fields in the entity for the notification.

<br />

| Field | Value |
|---|---|
| `remainingVehicleJourneySegments` | List of remaining vehicle stops with their states marked as State.NEW. |

<br />

### Arrives at stop example

The following examples show how to notify Fleet Engine that a vehicle arrived
at the stop, using either the \[Java gRPC library\]\[5\] or an HTTP REST call to
`UpdateDeliveryVehicle`. All other stops are marked as new.

### gRPC

```java
  static final String PROJECT_ID = "my-delivery-co-gcp-project";
  static final String VEHICLE_ID = "vehicle-8241890";

  DeliveryServiceBlockingStub deliveryService =
    DeliveryServiceGrpc.newBlockingStub(channel);

  // Vehicle settings
  String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
  DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
      // Marking the arrival at stop.
      .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()
         .setStop(VehicleStop.newBuilder()
             .setPlannedLocation(LocationInfo.newBuilder()
                 .setPoint(LatLng.newBuilder()
                     .setLatitude(37.7749)
                     .setLongitude(122.4194)))
             .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
             .setState(VehicleStop.State.ARRIVED)))
      // All other remaining stops marked as NEW.
      .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // 2nd stop
         .setStop(VehicleStop.newBuilder()
             .setPlannedLocation(LocationInfo.newBuilder()
                 .setPoint(LatLng.newBuilder()
                     .setLatitude(37.3382)
                     .setLongitude(121.8863)))
             .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
             .setState(VehicleStop.State.NEW))) // Remaining stops must be NEW.
      .build();

  // DeliveryVehicle request
  UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
    UpdateDeliveryVehicleRequest.newBuilder()  // No need for the header
        .setName(vehicleName)
        .setDeliveryVehicle(deliveryVehicle)
        .setUpdateMask(FieldMask.newBuilder()
            .addPaths("remaining_vehicle_journey_segments"))
        .build();

  try {
    DeliveryVehicle updatedDeliveryVehicle =
        deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
  } catch (StatusRuntimeException e) {
    Status s = e.getStatus();
    switch (s.getCode()) {
       case NOT_FOUND:
         break;
       case PERMISSION_DENIED:
         break;
    }
    return;
  }
```

### REST

```console
`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remainingVehicleJourneySegments`
```

- *\<id\>* is a unique identifier for the task.
- The request header must contain a field *Authorization* with the value *Bearer \<token\>* , where *\<token\>* is issued by your server according to the guidelines described in \[Service account roles\]\[6\] and \[JSON Web tokens\]\[6\].
- The request body must contain a `DeliveryVehicle` entity:

Example `curl` command:

> [!NOTE]
> **Note:** This command overwrites any `remainingVehicleJourneySegments` already set on the delivery vehicle.

```console
  # Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
  # environment
  curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
    -H "Content-type: application/json" \
    -H "Authorization: Bearer ${JWT}" \
    --data-binary @- << EOM
  {
    "remainingVehicleJourneySegments": [
      {
        "stop": {
          "state": "ARRIVED",
          "plannedLocation": {
            "point": {
              "latitude": 37.7749,
              "longitude": -122.084061
            }
          },
          "tasks": [
            {
              "taskId": "${TASK1_ID}"
            }
          ]
        }
      },
      {
        "stop": {
          "state": "NEW",
          "plannedLocation": {
            "point": {
              "latitude": 37.3382,
              "longitude": 121.8863
            }
          },
          "tasks": [
            {
              "taskId": "${TASK2_ID}"
            }
          ]
        }
      }
    ]
  }
  EOM
```

> [!WARNING]
> **Experimental:** As an experimental feature, the `LocationInfo` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#locationinfo) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt)) field now supports using `place` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt#FIELDS.place)), either alongside or instead of `LatLng`.

## Vehicle completes a stop

Fleet Engine must be notified when a vehicle completes a stop. This causes
all tasks associated with the stop to be set to a CLOSED state.

### Required fields for stop updates

Fleet Engine ignores all other fields in the entity for the notification.

<br />

| Field | Value |
|---|---|
| `remainingVehicleJourneySegments` | List of remaining vehicle stops with their states marked as State.NEW. The first stop on the list must have its state marked as State.ENROUTE. |

<br />

### Completes a stop example

The following examples show how to notify Fleet Engine that a vehicle arrived
at the stop, using either the \[Java gRPC library\]\[5\] or an HTTP REST call to
`UpdateDeliveryVehicle`. All other stops are marked as new.

### gRPC

```java
  static final String PROJECT_ID = "my-delivery-co-gcp-project";
  static final String VEHICLE_ID = "vehicle-8241890";

  DeliveryServiceBlockingStub deliveryService =
    DeliveryServiceGrpc.newBlockingStub(channel);

  // Vehicle settings
  String vehicleName = "providers/" + PROJECT_ID + "/deliveryVehicles/" + VEHICLE_ID;
  DeliveryVehicle deliveryVehicle = DeliveryVehicle.newBuilder()
      // This stop has been completed and is commented out to indicate it
      // should be removed from the list of vehicle journey segments.
      // .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()
      //    .setStop(VehicleStop.newBuilder()
      //        .setPlannedLocation(LocationInfo.newBuilder()
      //            .setPoint(LatLng.newBuilder()
      //                .setLatitude(37.7749)
      //                .setLongitude(122.4194)))
      //        .addTasks(TaskInfo.newBuilder().setTaskId(TASK1_ID))
      //        .setState(VehicleStop.State.ARRIVED)))
      // All other remaining stops marked as NEW.
      // The next stop could be marked as ENROUTE if the vehicle has begun
      // its journey to the next stop.
      .addRemainingVehicleJourneySegments(VehicleJourneySegment.newBuilder()  // Next stop
         .setStop(VehicleStop.newBuilder()
             .setPlannedLocation(LocationInfo.newBuilder()
                 .setPoint(LatLng.newBuilder()
                     .setLatitude(37.3382)
                     .setLongitude(121.8863)))
             .addTasks(TaskInfo.newBuilder().setTaskId(TASK2_ID))
             .setState(VehicleStop.State.NEW)))
      .build();

  // DeliveryVehicle request
  UpdateDeliveryVehicleRequest updateDeliveryVehicleRequest =
    UpdateDeliveryVehicleRequest.newBuilder()  // no need for the header
        .setName(vehicleName)
        .setDeliveryVehicle(deliveryVehicle)
        .setUpdateMask(FieldMask.newBuilder()
            .addPaths("remaining_vehicle_journey_segments"))
        .build();

  try {
    DeliveryVehicle updatedDeliveryVehicle =
        deliveryService.updateDeliveryVehicle(updateDeliveryVehicleRequest);
  } catch (StatusRuntimeException e) {
    Status s = e.getStatus();
    switch (s.getCode()) {
       case NOT_FOUND:
         break;
       case PERMISSION_DENIED:
         break;
    }
    return;
  }
```

### REST

```console
PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/deliveryVehicles/<id>?updateMask=remaining_vehicle_journey_segments`
```

- *\<id\>* is a unique identifier for the task.
- The request header must contain a field *Authorization* with the value *Bearer \<token\>* , where *\<token\>* is issued by your server according to the guidelines described in \[Service account roles\]\[6\] and \[JSON Web tokens\]\[6\].
- The request body must contain a `DeliveryVehicle` entity:

Example `curl` command:

> [!NOTE]
> **Note:** This command overwrites any `remainingVehicleJourneySegments` already set on the delivery vehicle.

```console
 # Set JWT, PROJECT_ID, VEHICLE_ID, TASK1_ID, and TASK2_ID in the local
 # environment
 curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/deliveryVehicles/${VEHICLE_ID}?updateMask=remainingVehicleJourneySegments" \
   -H "Content-type: application/json" \
   -H "Authorization: Bearer ${JWT}" \
   --data-binary @- << EOM
 {
   "remainingVehicleJourneySegments": [
     {
       "stop": {
         "state": "NEW",
         "plannedLocation": {
           "point": {
             "latitude": 37.3382,
             "longitude": 121.8863
           }
         },
         "tasks": [
           {
             "taskId": "${TASK2_ID}"
           }
         ]
       }
     }
   ]
 }
 EOM
```

> [!WARNING]
> **Experimental:** As an experimental feature, the `LocationInfo` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#locationinfo) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt)) field now supports using `place` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt#FIELDS.place)), either alongside or instead of `LatLng`.

[placeidtrips1](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#locationinfo): /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#locationinfo
[placeidtrips2](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt): /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html
[placeidtrips3](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place): /maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.html#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place
[placeidtrips4](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt#FIELDS.place): /maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.html#FIELDS.place

## What's next

- \[Finalize tasks\]\[4\]

\[1\]: /maps/documentation/mobility/fleet-engine/journeys/tasks/create-shipment-tasks
\[3\]: /maps/documentation/mobility/fleet-engine/essentials/tasks-intro
\[4\]: /maps/documentation/mobility/fleet-engine/journeys/tasks/finalize-tasks
\[5\]: /maps/documentation/mobility/fleet-engine/essentials/client-libraries-tasks
\[6\]: /maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts