# Service jobs

## Service jobs

A **service job** is the actual instance of a custom service in a facility. A [custom service](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/services/custom-services) is an entity that contains all the information about an offered service.

While a [custom service](https://docs.fulfillmenttools.com/documentation/by-pillar/store-operations/services/custom-services) serves as a blueprint, a service job is the actual instance of that service in a specific facility. Furthermore, every service job is part of a linked service job. A new linked service job is created automatically with the first service job. Subsequent service jobs can be added to this existing linked service job by providing a reference during their creation.

### Create a service job

{% hint style="warning" %}
While service jobs can be created using the API, the system can also create them automatically from an order routing decision, similar to how it creates pick jobs.
{% endhint %}

A service job can be created either as part of an order via the `Order.customServices` object or by using the following direct API call:

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/servicejobs
```

```json
{
  "customServiceRef": "sad5622-gfd1-441v-132h-23refsfsass",
  "processRef": "a28835b9-f81a-4f63-96a6-c7e612ebc2a3",
  "facilityRef": "8a5b283a-bcf9-4f63-132h-v93ca6ea011n3",
  "lineItems": [
    {
      "quantity": 15,
      "scannableCodes": [
        "0799439112766"
      ],
      "article": {
        "tenantArticleId": "100029-W",
        "title": "White Shirt",
        "imageUrl": "https://cdn11.bigcommerce.com/s-2fhihzl616/images/stencil/960w/products/6562/24857/Mens_White_Cotton_Shirt_MS236LS_4__24507.1645457383.jpg"
      }
    }
  ]
}
```

### Create a service job from an order

{% hint style="warning" %}
You can only add up to maximum 15 custom services on one level and up to 50 custom services per order.
{% endhint %}

The `customServices` object in an order is structured as follows:

```json
{
  // Order
  ...
  "customServices":[
    {
      "customServiceDefinition":{
        "customServiceRef": "CustomServiceRef_Parent"
      },
      "articleItems":[],
      "customServiceItems":[
        {
          "customServiceDefinition":{
            "customServiceRef": "CustomServiceRef_Child"
          },
          "articleItems":[
            {
              "tenantArticleRef": "Item_1",
              "quantity":1
            }
          ],
          "customServiceItems":[]
        }
      ]
    }
  ]
}
```

In this example, the child `customService` requires `Item_1`, which is also required by the parent `customServices`. After the order is processed, the system generates the corresponding service jobs.

#### Child service job (partial)

```json
{
  "id": "ServiceJob_Child",
  "requiredLineItems": [
    {
      "article": {
        "tenantArticleRef": "Item_1"
      },
      "quantity": 1
    }
  ],
  "lineItems": []
}
```

#### Parent service job (partial)

```json
{
  "id": "ServiceJob_Parent",
  "requiredLineItems": [
    {
      "article": {
        "tenantArticleRef": "Item_1"
      },
      "quantity": 1
    }
  ],
  "lineItems": []
}
```

The system transfers the required items defined in the custom service to the `requiredLineItems` field of the corresponding service job. Any items subsequently selected for the job are stored in the `lineItems` field.

### Update a service job

A service job is updated using the actions API endpoint. For details on available actions, see the [Service Job Actions API reference](https://fulfillmenttools.github.io/fulfillmenttools-api-reference-ui/#post-/api/servicejobs/-serviceJobId-/actions):

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/servicejobs/{serviceJobId}/actions
```

Example body:

```json
{
  "name": "StartServiceJob",
  "additionalInformation": [
    {
      "additionalInformationRef": "{additionalInfoRef}",
      "value": "value"
    }
  ],
  "version": 3
}
```

### Cancel a service job

If a service job in the dependency tree is canceled (for example, due to unavailable items), all subsequent dependent jobs in the sequence are also automatically canceled.

### Service data

Each service job has a `serviceData` object that contains information about the items that can be selected for it. This object contains the items for the specified service job and all connected service jobs. Through this object, a user can see which item is altered by which service job, the sequence of execution, how many items have been used, and whether the items can be returned after job completion.

```json
{
  "id": "IdServiceData",
  "serviceJobRefs": ["IdServiceJobA", "IdServiceJobB"],
  "availableLineItems": [
    {
      "id": "IdAvailableLineItem",
      "article": {
        "tenantArticleId": "TenantArticleId",
        "title": "Title"
      },
      "quantity": 4,
      "availableQuantity": 0,
      "executedServiceJobData": [
        {
          "serviceJobRef": "ABC",
          "sequence": 1,
          "appliedQuantity": 4,
          "itemsReturnable": true
        },
        {
          "serviceJobRef": "DEF",
          "sequence": 2,
          "appliedQuantity": 4,
          "itemsReturnable": false
        }
      ]
    }
  ]
}
```

Retrieve the `serviceData` object using the following `GET` request:

```http
GET https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/servicejobs/{serviceJobId}/servicedata
```

### Selecting and unselecting items

When a service job has the status `NOT_READY`, a user can select the items required for its execution. The job status changes to `OPEN` once all required items from the order are selected. It's possible to add more items, but items already used by a child job can't be removed, as they are automatically passed to the parent job. Required items are stored in the custom service in the `articleItems` field and appear in the `requiredLineItems` field after the transition from the custom service to the service job. Selected items are stored in the `lineItems` field. Items are selected or unselected using actions on the `serviceData` object with the following API calls.

#### Select items

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/servicejobs/{serviceJobId}/servicedata/actions
```

```json
{
  "name": "SELECT_ITEMS_FOR_SERVICE_JOB",
  "serviceJobVersion": 3,
  "serviceItemsToSelect": [
    {
      "serviceItemRef": "{ServiceItemRefFromServiceData}",
      "quantity": 2
    }
  ]
}
```

#### Unselect items

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/servicejobs/{serviceJobId}/servicedata/actions
```

```json
{
  "name": "UNSELECT_ITEMS_FOR_SERVICE_JOB",
  "serviceJobVersion": 3,
  "serviceItemsToUnselect": [
    {
      "serviceItemRef": "{ServiceItemRefFromServiceData}",
      "quantity": 2
    }
  ]
}
```

When selecting items, note that an item used in one branch of a parallel process cannot be used in another parallel branch. However, it can be used in subsequent parent jobs.

```
Order: Item_1, Item_2, Item_3, Item_4
          ---A---
        /        \
    ---B---    ---C---
    (Item_1)   (Item_1)  <- Not possible
```

However, it's possible to use items that have not yet been assigned in parallel branches.

```
Order: Item_1, Item_2, Item_3, Item_4

          ---A---
        /        \
    ---B---    ---C---
    (Item_1)   (Item_3)  <- Possible
```

## Linked service jobs

A linked service job defines the sequence and dependencies between different [service jobs](#service-jobs). It contains one or more service job links, each referencing a specific service job.

A linked service job creates dependencies by mapping the execution sequence. The order is determined by nesting service job links within the `nextServiceJobLinks` array. For example, if the link for service job B contains a reference to service job A in its `nextServiceJobLinks` array, service job A must be completed before service job B can begin.

The system enforces this dependency by setting the status of service job B to `NOT_READY`. The status automatically changes to `OPEN` only after all prerequisite jobs (from the `nextServiceJobLinks` array) reach a terminal status like `FINISHED`, `CANCELLED`, or `OBSOLETE`. A `service job` can't be manually transitioned from `NOT_READY` to `IN_PROGRESS`, `FINISHED` or `WAITING_FOR_INPUT`.

### Service job links

A service job link references a service job and contains an array, `nextServiceJobLinks`, that points to any subsequent job links. This nested structure within a linked service job maps the execution sequence of all related service jobs.

The system automatically creates a linked service job when the first service job in a sequence is created. It can't be created manually. However, users can add new service job links to an existing linked service job to customize the workflow.

#### Inherited line items

When service jobs are sequenced in a linked service job, line items from one job can be inherited by the next. These items appear in the `inheritedLineItems` array of the subsequent service jobs.

For example, a custom-tailored shirt that receives an embroidery and undergoes a quality check at the end. There are three `service jobs` (custom tailoring, embroidery, and quality check) and two line items (a shirt to be tailored and thread for the embroidery) that are involved in this process. The first service job (tailoring) has one line item (the shirt), the following service job (embroidery) has one line item (the thread) and one inherited line item (the shirt), and the last service job (quality check) has no new line items but has two inherited line items (the shirt and the thread).

#### Add a service job link to a linked service job

A service job link can be added either to the root level of a linked service job or inside an existing service job link.

**Add a service job link to the root level**

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/linkedservicejobs/{linkedServiceJobId}/servicejoblink
```

```json
{
  "serviceJobRef": "a28835b9-f81a-4f63-96a6-c7e612ebc2a3"
}
```

**Add a service job link below an existing service job link**

```http
POST https://{YOUR-TENANT-NAME}.api.fulfillmenttools.com/api/linkedservicejobs/{linkedServiceJobId}/servicejoblinks/{serviceJobLinkId}
```

```json
{
  "serviceJobRef": "a28835b9-f81a-4f63-96a6-c7e612ebc2a3"
}
```
