This document assumes you understand how to create and use tasks. It provides
specific examples for how to finalize shipment tasks as follows:

- **Close a task** : Closing a shipment task changes its state to `CLOSED` and
  indicates that that task is no longer active.

- **Set the task outcome** : Once a task is closed, you then finalize it by
  setting its outcome to either `SUCCEEDED` or `FAILED`. This is an important
  part of finalizing a task in order to show the delivery outcome in journey
  sharing and to ensure correct billing for the Fleet Engine service.

## Close a task

You can close a task in the following ways:

- **Update the stop status for the vehicle** . You remove the stop from the vehicle, which in turn closes all tasks associated with the stop. See [Update stop status for details](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/update-stops.md.txt).
- **Remove the task from the list of vehicle stops** . This involves updating the list of tasks for the stop, but with the closed task no longer part of the list. See Update task order in [Update tasks](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/update-tasks.md.txt).
- **Set the task state to `CLOSED`**. This can only be done on tasks not assigned to vehicles. This section shows this approach.

Once you close a task, you may not reopen it.
> > **Closing of a task does not indicate its success or failure** . It indicates
> > that the task is no longer considered in progress. In order to indicate the
> > actual outcome of a task and to have that displayed for Fleet Tracking and
> > journey sharing purposes, you must indicate the actual outcome of a task. See
> > [Set the task outcome](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/finalize-tasks.md.txt#set-task-outcome) below.

### Task fields for closing tasks

This section documents the required fields to set when closing a
task. Fleet engine ignores all other fields in the entity for the update.

<br />

| Required field | Value |
|---|---|
| `state` | `State.CLOSED` |

<br />

### Close a task directly

The following examples show how to set an unassigned task to a closed state,
either in gRPC or using an HTTP REST request call to `UpdateTask`

### gRPC

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

 DeliveryServiceBlockingStub deliveryService =
   DeliveryServiceGrpc.newBlockingStub(channel);

 // Task settings
 String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
 Task task = Task.newBuilder()
   .setName(taskName)
   .setState(Task.State.CLOSED) // You can only directly CLOSE a
   .build();                    // task that is NOT assigned to a vehicle.

 // Task request
 UpdateTaskRequest updateTaskRequest =
   UpdateTaskRequest.newBuilder()  // No need for the header
       .setTask(task)
       .setUpdateMask(FieldMask.newBuilder().addPaths("state"))
       .build();

 try {
   Task updatedTask = deliveryService.updateTask(updateTaskRequest);
 } catch (StatusRuntimeException e) {
   Status s = e.getStatus();
   switch (s.getCode()) {
      case NOT_FOUND:
        break;
      case PERMISSION_DENIED:
        break;
   }
   return;
 }
```

### REST

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=state`

- *\<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](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts.md.txt) and [JSON Web tokens](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt.md.txt).
- You must include a `Task` entity in the request body

Example `curl` command:

```bash
 # Set JWT, PROJECT_ID, and TASK_ID in the local environment
 curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=state,taskOutcome,taskOutcomeTime" \
   -H "Content-type: application/json" \
   -H "Authorization: Bearer ${JWT}" \
   --data-binary @- << EOM
 {
   "state": "CLOSED",
   "taskOutcome": "SUCCEEDED",
   "taskOutcomeTime": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
 }
 EOM
```

## Set the task outcome

To indicate the actual outcome of a task, you set the outcome for closed tasks
to either `SUCCEEDED` or `FAILED`. A task must be closed before you set its
outcome. Fleet Engine only charges for delivery tasks with a state of
`SUCCEEDED`.

### Task outcome details

Tasks also provide additional details about the task outcome. You can set these
directly and Fleet Engine respects your settings:

- **Task outcome location**: Fleet Engine automatically fills in the task outcome location with the last known vehicle location. You can provide this instead if you prefer.
- **Task outcome time**: Fleet Engine does not fill this field in, but is available for you to set.

You can use any of the following approaches to setting `task_outcome_location`
and `task_outcome_time`:

- **Update them in the same request** that sets the task outcome.
- **Update them later**, after you have set task outcome.
- **Modify them again** after they have been set.

Fleet Engine prevents the following updates related to task outcomes:

- **You can't modify a task outcome once it is set** to either `SUCCEEDED` or `FAILED`.
- **You can't set a task outcome location or outcome time** for tasks without a set outcome.

### Task fields for setting outcome

This section documents the required and optional fields to set when setting a
task outcome. Fleet Engine ignores other fields in the entity for the update.

<br />

| Required field | Value |
|---|---|
| `taskOutcome` | `Outcome.SUCCEEDED` or `Outcome.FAILED` |

<br />

<br />

| Optional field | Value |
|---|---|
| `taskOutcomeLocation` | The location where the task was completed. If not set, Fleet Engine defaults this to the last vehicle location. |
| `taskOutcomeTime` | The timestamp when the task was completed. |

<br />

### Task outcome examples

The following example shows how to use the [Java gRPC library](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/client-libraries-tasks.md.txt) and an HTTP
REST call to `UpdateTask` to set a task outcome to `SUCCEEDED` and set the
location where the task was completed.

### gRPC

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

 DeliveryServiceBlockingStub deliveryService =
   DeliveryServiceGrpc.newBlockingStub(channel);

 // Task settings
 String taskName = "providers/" + PROJECT_ID + "/tasks/" + TASK_ID;
 Task task = Task.newBuilder()
   .setName(taskName)
   .setTaskOutcome(TaskOutcome.SUCCEEDED)
   .setTaskOutcomeTime(now())
   .setTaskOutcomeLocation(               // Grand Indonesia East Mall
     LocationInfo.newBuilder().setPoint(
       LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
   .build();

 // Task request
 UpdateTaskRequest updateTaskRequest =
   UpdateTaskRequest.newBuilder()  // No need for the header
       .setTask(task)
       .setUpdateMask(FieldMask.newBuilder().addPaths("task_outcome", "task_outcome_time", "task_outcome_location"))
       .build();

 try {
   Task updatedTask = deliveryService.updateTask(updateTaskRequest);
 } catch (StatusRuntimeException e) {
   Status s = e.getStatus();
   switch (s.getCode()) {
      case NOT_FOUND:
        break;
      case PERMISSION_DENIED:
        break;
   }
   return;
 }
```

### REST

`PATCH https://fleetengine.googleapis.com/v1/providers/<project_id>/tasks/<id>?updateMask=taskOutcome,taskOutcomeTime,taskOutcomeLocation`

- *\<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](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts.md.txt) and [JSON Web tokens](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt.md.txt).
- The request body must contain a `Task` entity.

```bash
 # Set JWT, PROJECT_ID, and TASK_ID in the local environment
 curl -X PATCH "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks/${TASK_ID}?updateMask=taskOutcome,taskOutcomeTime,taskOutcomeLocation" \
   -H "Content-type: application/json" \
   -H "Authorization: Bearer ${JWT}" \
   --data-binary @- << EOM
 {
   "taskOutcome": "SUCCEEDED",
   "taskOutcomeTime": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
   "taskOutcomeLocation": {
     "point": {
       "latitude": -6.195139,
       "longitude": 106.820826
     }
   }
 }
 EOM
```

## What's next

- [Find tasks](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/find-tasks.md.txt)