# Parts and Part Revisioning

### Parts:

Part objects in ION represent abstractions that carry information about a particular part, while the physical parts themselves are [part inventory objects](/api/examples/part-inventory-and-kitting.md#inventory). The part objects dictate the MBOM, revision, supplier part number, tracking type and other additional attributes about a part.

Below is a list of part attributes and their description. For a more complete list of part fields use the [graphiql](https://app.firstresonance.io/graphiql) editor to view the part object.

| Part Object    | Description                                                                                          |
| -------------- | ---------------------------------------------------------------------------------------------------- |
| id             | Unique identifier of Part object                                                                     |
| partNumber     | parts must have a unique partNumber and revision                                                     |
| revision       | Revision for part, defaults to A                                                                     |
| trackingType   | If set enforces all inventory for part to match tracking type. Can be either "serial" or "lot"       |
| quantity       | The summed quantity of all inventory for a part                                                      |
| partsInventory | List of [inventory](/api/examples/part-inventory-and-kitting.md#inventory) objects related to a part |
| runs           | List of [runs](/features/runs.md#what-is-a-run) related to part                                      |
| mbom           | List of [MBOM item](/api/examples/mboms.md#mbom-items) which describe the BOM of a part              |

### Query Parts

The queries below specify how to list parts by a filter or get a specific part.

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

```graphql
query GetParts($filters: PartsInputFilters) {
    parts(filters: $filters) {
        edges {
            node {
                id partNumber description thumbnail { s3Key s3Bucket url }
                fileAttachments { url } quantity
            }
        }
    }
}
```

{% endtab %}

{% tab title="Filter Inputs" %}

```javascript
{
    "filters": {
        "partNumber": {
            "eq": "ion-12"
        }
    }
}
```

{% endtab %}

{% tab title="Get" %}

```
query GetPart{
    part(id: 1) {
        id partNumber description quantity
    }
}
```

{% endtab %}
{% endtabs %}

### Create Part

Creates a part object with a particular part number. Part number and revision must be unique, if no revision is supplied in the create mutation then the part defaults to revision A. Once created the revision of a part cannot be updated, instead the [createPartRevision](/api/examples/parts-and-part-revisioning.md#create-part-revision) mutation must be used to iterate a part's revision. Returns the new part.

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

```graphql
mutation CreatePart($input: CreatePartInput!) {
    createPart(input: $input) {
        part {
            id revision partNumber description
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "partNumber": "ion-12",
        "description": "Part for API docs.",
        "revision": "C"
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to create part object*

{% hint style="info" %}
If the part you are creating contains custom attributes we highly recommend that the attributes are declared when the part is created even if the attribute contains no value.
{% endhint %}

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

```graphql
mutation CreatePart($input: CreatePartInput!) {
    createPart(input: $input) {
        part {
            id revision partNumber description attributes
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "partNumber": "ion-12",
        "description": "Part for API docs.",
        "revision": "C",
        "attributes": [
            {
                "key": "Attribute 1"
            },
            {
                "key": "Attribute 2",
                "value": "Value for attribute 2"
            }
        ]
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to create part object with attributes*

### Update Part

Updates a part object. Tracking type can only be updated to either "serial" or "lot" if all existing inventory objects related to this part conform to the new tracking type. Returns the updated part object.

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

```graphql
mutation UpdatePart($input: UpdatePartInput!) {
    updatePart(input: $input) {
        part { id partNumber description revision }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "id": 1,
        "etag": "etag1",
        "partNumber": "ion-13",
        "description": "Updated part for API docs."
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to update part object*

### Create Part Revision

Creates a new revision for a particular part. A revision can be generated from any part, there are no restrictions requiring the revision to be generated from the current latest revision. For example if our part "ion-13" has existing revisions A and B, then a third revision C can be generated from either existing revision A or B. All information in the new revision is copied over from the old revision unless explicitly overriden in the mutation input. The new revision will be the next valid alphabetic character from the part's latest revision. If the part's latest revision is C, then the new revision will be D. If the part's latest revision is Z, then the new revision will be AA. Returns the newly created part object with the updated revision.

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

```graphql
mutation CreatePartRevision($input: CreatePartRevisionInput!) {
    createPartRevision(input: $input) {
        part {
            id partNumber revision
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "input": {
        "id": 1,
        "etag": "etag1",
        "description": "New revision for part in API docs."
    }
}
```

{% endtab %}
{% endtabs %}

> *Mutation to create a part revision*

### Delete Part

Delete a part object. This will delete not only the part object itself but also cascade and delete the MBOM and MBOM substitutes associated with this part. A part which has existing inventory or was used within a run cannot be deleted. Returns the ID of the deleted part.

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

```graphql
mutation DeletePart($id: ID!, $etag: String!) {
    deletePart(id: $id, etag: $etag) {
        id
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

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

{% endtab %}
{% endtabs %}

> *Mutation to delete part object*

> *Query to retrieve parts*

### Custom Part Revision Scheme

ION allows users to define custom schemes for part revisioning. These schemes are defined within an organization's settings, the mutation below demonstrates how to create a new scheme. First a user needs the ID and etag of the organization before its settings can be updated. Following that there are four additional variables which define a part revision scheme.

* **name** (string): The name of the new revision scheme
* **default** (boolean): If true all newly created parts will inherit this revision scheme
* **allowOverflow** (boolean): Defines whether an error should be raised when the max iteration of a revision scheme is reached, or if it should overflow to the next available value.
* **format** (array\[string]): The format is an array of strings which defines how the values of a revision scheme should appear. The string values in the array can be either `NUMERIC`, `ALPHABETICAL`, or single character length constants. The format below would define part revisions like `00-1` or `95-7`.

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

```graphql
mutation CreateOrganizationPartRevisionScheme(
        $input: CreatePartRevisionSchemeSettingInput!) {
    createOrganizationPartRevisionScheme(input: $input) {
        organization {
            id settings {
                parts {
                    revisionSchemes {
                        default name allowOverflow format } } }
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "id": 1,
    "name": "new scheme",
    "default": true,
    "format": ["NUMERIC", "NUMERIC", "-", "NUMERIC"],
    "etag": "etag1",
    "allowOverflow": true
}
```

{% endtab %}
{% endtabs %}

### Update Part Revision Scheme

Once a part revision scheme exists in an organization's settings it can subsequently be updated. Currently the only allowable updates to a part revision scheme are the fields allowOverflow and default.

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

```graphql
mutation UpdateOrganizationPartRevisionScheme(
        $input: UpdatePartRevisionSchemeSettingInput!) {
    updateOrganizationPartRevisionScheme(input: $input) {
        organization {
            id settings {
                parts {
                    revisionSchemes {
                        default name allowOverflow format } } }
        }
    }
}
```

{% endtab %}

{% tab title="Inputs" %}

```javascript
{
    "id": 1,
    "name": "new scheme",
    "default": false,
    "etag": "etag1",
    "allow_overflow": false
}
```

{% endtab %}
{% endtabs %}

### Converting the Revision Scheme of an Existing Part

There are two strategies for changing the revision scheme of an existing part. Both involve setting the `revisionScheme` for a part in either the `updatePart` or `createPartRevision` mutations above. The `revisionScheme` should be set to the name of one of the schemes in the organization's settings.

* Setting the `revisionScheme` in the `updatePart` mutation casts the part's revision. For example if a part currently has revision `D` and we update that part to use the revisionScheme "new scheme" which we created above then the revision will be set to `00-4`
* Setting the `revisionScheme` in the `createPartRevision` mutation resets the parts revision, starting it over from the initial revision of the new scheme. If a part has revision `D` and we update the part's `revisionScheme` in the `createPartRevision` mutation it will be set to `00-1`.


---

# 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/parts-and-part-revisioning.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.
