# Part Inventory and Kitting

## Inventory

Parts can be tracked by either serial or lot numbers. They can also be untracked with just their quantities.  Here we will introduce Part Inventory, which can be used to hold information about a part and set it up, so it can be tracked in runs and aBOM construction. The following documentation will go through how to create part inventory objects and issue those parts to part kits for allocating inventory to runs. To tie it all up we will demonstrate how to move new or unused parts into inventory.

| Part Inventory | Description                                                                                                                                                                                      |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id             | Unique identifier for a Part Inventory object                                                                                                                                                    |
| serialNumber   | Required if part is serial tracked. Must be unique per part, meaning another inventory object with the same part relation cannot have a matching serial number. Can be optionally autogerenated. |
| lotNumber      | Required if part is lot tracked. Can be optionally autogerenated.                                                                                                                                |
| location       | Location inventory object is stored                                                                                                                                                              |
| part           | [Part](/api/examples/parts-and-part-revisioning.md#parts) that this inventory object is an instance of                                                                                           |
| unitOfMeasure  | How quantity of this inventory object is measured                                                                                                                                                |
| quantity       | Amount of inventory present                                                                                                                                                                      |
| runs           | [Runs](/features/runs.md#creating-a-run) related to this inventory object                                                                                                                        |
| installed      | True if all quantity are attached to ABOM items, else False                                                                                                                                      |
| kitted         | True if all quantity are kitted to runs, else false                                                                                                                                              |

### Inventory Tracking Types:

| Tracking Type |                                                                                                                                                                                        |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| serial        | Any inventory with a serial number, has the serial tracking type. It can also have a lot tracking number in addition. Serialized inventory objects can only have a quantity of 0 or 1. |
| lot           | Any inventory object with a lot number and no serial number is a lot tracked. Lot tracked items must have a quantity greater than or equal to 0.                                       |
| untracked     | If a part inventory has neither a serial or lot number than it is an untracked item. There are no quantity restrictions on an untracked part.                                          |

### Query Part Inventories

The queries below specify how to list part inventories by a filter or get a specific inventory object.

{% tabs %}
{% tab title="List" %}

```graphql
query PartInventories($filters: PartInventoriesInputFilters) {
    partInventories(sort: $sort, filters: $filters) {
        edges{
            node {
                id cost quantity usageType
                part { partNumber }
                location { id }
            }
        }
    }
}
```

{% endtab %}

{% tab title="Filter Inputs" %}

```javascript
{
    "filters": {
        "locationId": {
            "eq": 1
        }
    }
}
```

{% endtab %}

{% tab title="Get" %}

```graphql
query PartInventory {
    partInventory(id: 1) {
        id cost quantity usageType
        part { partNumber }
        location { id }
    }
}
```

{% endtab %}
{% endtabs %}

> *Query part inventory objects*

### Create Part Inventories

Executing the below mutation with the first inputs creates a part inventory object for the serial part with part id 1. Executing the mutation again with the second input creates an inventory object for the lot tracked part with of part id 2. No quantity was specified, so the inventory object will have a quantity of 0. Serial and lot number can also be autogenerated using the last set of inputs when creating a part inventory object.

{% tabs %}
{% tab title="Create inventory" %}

```graphql
mutation CreatePartInventory($input: CreatePartInventoryInput!) {
    createPartInventory(input: $input) {
        partInventory {
            id quantity cost usageType createdById
            trackingType locationId supplierId _etag
        }
    }
}
```

{% endtab %}

{% tab title="Inputs for serial" %}

```javascript
{
    "input": {
        "serialNumber": "sn-1",
        "lotNumber": "123",  // Serialized parts can be a part of lots too
        'quantity': 1,  // Note: Serial-tracked parts cannot have quantity > 1
        'partId': 1,
        'usageType': 'purchase_to_stock',
        'supplierId': 1,
        'locationId': 5
    }
}
```

{% endtab %}

{% tab title="Inputs for lot-tracked part" %}

```javascript
{
    "input": {
        "lotNumber": "lot-12"
        'partId': 2,
        'usageType': 'purchase_to_stock',
        'supplierId': 1,
        'locationId': 5
    }
}
```

{% endtab %}

{% tab title="Autogenerate a serial or lot" %}

```javascript
{
    "input": {
        "autogenerateSerialNumber": true,
        "autogenerateLotNumber": true,
        "lotNumber": "123",  // Serialized parts can be a part of lots too
        'quantity': 1,  // Note: Serial-tracked parts cannot have quantity > 1
        'partId': 1,
        'usageType': 'purchase_to_stock',
        'supplierId': 1,
        'locationId': 5
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to create part inventory for a part item.*

### Updating inventory items

Almost all the fields associated with a inventory object can be altered except for it's relation to the part of which it is an instance. All of the validations regarding quantity and tracking type that are enforced on inventory creation are also enforced on update. Returns the newly updated part inventory object.

{% tabs %}
{% tab title="Mutation" %}

```graphql
mutation UpdatePartInventory($input: UpdatePartInventoryInput!) {
    updatePartInventory(input: $input) {
        partInventory {
            id quantity cost locationId serialNumber lotNumber
        }
    }
}
```

{% endtab %}

{% tab title="Inputs " %}

```javascript
{
    "input": {
        "id": 1,
        "etag": "etag1",
        "lotNumber": "ion-21",
        "cost": 11.21,
        "locationId": 1
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to update a part inventory.*

### Delete Part Inventories

A part inventory object can be deleted using the following mutation. Returns the ID of the deleted part inventory object.&#x20;

{% tabs %}
{% tab title="Mutation" %}

```graphql
mutation DeletePartInventory($id: ID!, $etag: String!) {
    deletePartInventory(id: $id, etag: $etag) {
        id
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "id": 1,
    "etag": "etag1"
}
```

{% endtab %}
{% endtabs %}

> *Mutation to delete part inventory.*

## Issuing parts to runs

![Overview of how parts move through ion: From inventory to kits to installations on the aBOM and back.](/files/-MAP9-yR6PvQXlWBNX5p)

### Part Kits

Part Kits allow you to allocate specific parts and quantities for a run. To create a part kit, you must already have a run. See the Runs mutations for that.

To remove the parts from inventory and attach them to the run in which they will be consumed we use a Part Kit object. Below we create that part kit and attach it to a run.

| Part Kits       | Description                                                                                                                              |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| id              | Unique identifier for a Part Kit object                                                                                                  |
| run             | [Run](/features/runs.md#creating-a-run) which inventory objects are kitted too                                                           |
| partInventories | Inventory objects with additional field `issuedQuantity` which identifies that quantity of the inventory which is allocated to thhe run. |

{% tabs %}
{% tab title="Create a kit" %}

```graphql
mutation CreatePartKit($input: CreatePartKitInput!) {
    createPartKit(input: $input) {
        partKit {
            id run { id title }
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "runId": 1
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to create a kit of parts.*

### Issuing inventory to kits

To move the parts from inventory into the part kit we will use the `issueItemToKit` mutation. Whether a part is serial-tracked, lot-tracked, or not tracked, we simply reference its `partInventoryId` and, when the item is not serial-tracked, the `quantity` we want to issue to that particular kit.

{% tabs %}
{% tab title="Issue to kit" %}

```graphql
mutation IssueItemToKit($input: InventoryToKitInput!) {
    issueItemToKit(input: $input) {
        partInventoryId {
            id serialNumber partKits { id }
            partsInventory { id quantity }
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "partInventoryId": 1,
        "etag": "etag",
        "partKitId": 1
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to issue a serialized part to a part kit.*

Issuing serials, lots, or untracked parts are very similar and, in fact, use the same mutation,`issueItemToKit`. When parts are issued to kits, the kit will show the quantity of that required part fulfilled as `issuedQuantity` . The quantity is decremented from the original inventory object.

### Moving parts back to Inventory

Once a part is built (serial-tracked), it should be moved back to inventory for use on a higher-level assembly. To do so, use the `moveItemToInventory` mutation.

{% tabs %}
{% tab title="Move to inventory" %}

```graphql
mutation MoveItemToInventory($input: InventoryToKitInput!) {
    moveItemToInventory(input: $input) {
        partInventory {
           id quantity partId serialNumber lotNumber 
           location { name } partKits { id }
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "quantity": 2,
        "partKitId": 1, 
        "etag": "etag",
        "partInventoryId": 3
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to move a part into inventory.*

Quantity is included in the case that a lot-tracked or untracked inventory item with more than quantity 1 needs to moved back to inventory, but not the full amount of originally issued inventory. Therefore, you must include the quantity that you are moving back to inventory.

### Query Part Kits

{% tabs %}
{% tab title="List" %}

```graphql
query PartKits($filters: PartKitsInputFilters) {
    partKits(sort: $sort, filters: $filters) {
        edges{
            node {
                id
                run { id }
                partInventories { id issuedQuantity }
            }
        }
    }
}
```

{% endtab %}

{% tab title="Filter Inputs" %}

```javascript
{
    "filters": {
        "runId": {
            "eq": 1
        }
    }
}
```

{% endtab %}
{% endtabs %}

> *Query part kits*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://manual.firstresonance.io/api/examples/part-inventory-and-kitting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
