Inventory Control

Current Status: Available in Customers Sandbox Environments

Inventory Control via ION Actions

ION Actions provides improved capabilities to systematically manage and control inventory creation and updates. This can be leveraged in use cases where you may want to be more granular than ION's out of the box inventory control permissions. Below is an overview to guide your integration of this functionality into your organizations ION Actions code:

Understanding Inventory Terms

  • Inventory in Code: In ION Actions, Inventory is represented as partInventory. The individual component, which may have multiple inventory entries, is simply referred to as part.

Creating Inventory Actions

  • When creating new inventory entries, utilize the rule target partInventory with the event CREATE.

  • Incorporate the howCreated attribute in your partInventory context. This attribute indicates the method of inventory creation, allowing you to implement precise access controls based on the source of the creation event.

    • Example creation methods indicated by howCreated:

      • manual: Manually created inventory entries.

      • run_made: Inventory created as a result of production runs.

      • po_line_made: Inventory generated from purchase order lines.

    • Additional scenarios include inventory creation resulting from splits, such as partially assigning lots to an issue or partially kitting inventory to a kit.

Below are all the possible values these columns can contain:

    # backfilled for inventory prior to this creation
    UNKNOWN
    # creating (no splitting)
    MANUAL # eg create inventory row from inventory table page
    RUN_MADE #eg create inventory via a make run
    PO_LINE_MADE #eg create inventory by creating a PO line
    # manual/direct splits
    DIRECT_SPLIT #eg splitting inventory via the invenotry table
    # installing splits
    PARTIAL_INSTALL
    PARTIAL_UNINSTALL
    # kitting splits
    PARTIAL_KIT
    PARTIAL_UNKIT
    # scrapping splits
    PARTIAL_SCRAP
    PARTIAL_UNSCRAP
    # receiving splits
    PARTIAL_RECEIVE # no partial unreceive
    # assigning issues split
    PARTIAL_ASSIGN_TO_ISSUE # no partial unassign

Tracking Inventory Splits

  • The howLastSplit attribute, available in the partInventory context, provides insight into how a given inventory item was last divided or modified.

Context Example

Below is a practical example demonstrating how to set up context on partInventory for leveraging these new attributes effectively in ION Actions:

{\n  partInventory(id: $id) {\n    howCreated\n    howLastSplit\n    id\n    part {\n      partType\n    }\n  }\n}

Example Use Cases

What follows are a few example createRule mutations you can deploy in sandbox to help you get started using the data available in the partInventory context:

  • Control who can create inventory via run creation:

mutation {
  createRule(input: {
    title: "No Permissions to Create Inventory via Creating a Run",
    target: PARTINVENTORY,
    ruleType: VALIDATION,
    eventType: CREATE,
    enabled: true,
    context: "{\n  partInventory(id: $id) {\n    howCreated\n    id\n    part {\n      partType\n    }\n  }\n}",
    code: "RUN_ALLOWED_ROLES = {'planner','rando'}   # ← add or remove roles here\n\npart_inv = context.get('partInventory') or {}\nuser_roles = set(context.get('currentUser', {}).get('roles', []))\nif part_inv.get('howCreated') == 'RUN_MADE':\n    if RUN_ALLOWED_ROLES.isdisjoint(user_roles):\n      raise ValidationError()",
    errorState: BLOCK
  }) {
    rule {
      id
    }
  }
}
  • Control who can create inventory via the inventory table:

mutation {
  createRule(input: {
    title: "No Permissions to Create Inventory via Inventory Table",
    target: PARTINVENTORY,
    ruleType: VALIDATION,
    eventType: CREATE,
    enabled: true,
    context: "{\n  partInventory(id: $id) {\n    howCreated\n    id\n    part {\n      partType\n    }\n  }\n}",
    code: "MANUAL_ALLOWED_ROLES = {'planner','rando'}   # ← add or remove roles here\n\npart_inv = context.get('partInventory') or {}\nuser_roles = set(context.get('currentUser', {}).get('roles', []))\nif part_inv.get('howCreated') == 'MANUAL':\n  if MANUAL_ALLOWED_ROLES.isdisjoint(user_roles):\n    raise ValidationError()",
    errorState: BLOCK
  }) {
    rule {
      id
    }
  }
}
  • Variation on the above code: Control who can create inventory but allow 'TOOL' inventory type creation:

mutation {
  createRule(input: {
    title: "No Permissions to Create Non-Tool Inventory via Inventory Table",
    target: PARTINVENTORY,
    ruleType: VALIDATION,
    eventType: CREATE,
    enabled: true,
    context: "{\n  partInventory(id: $id) {\n    howCreated\n    id\n    part {\n      partType\n    }\n  }\n}",
    code: "MANUAL_ALLOWED_ROLES = {'planner','rando'}   # ← add or remove roles here\n\npart_inv = context.get('partInventory') or {}\nuser_roles = set(context.get('currentUser', {}).get('roles', []))\nif part_inv.get('howCreated') == 'MANUAL':\n  if part_inv.get('part').get('partType') != 'TOOL':\n    if MANUAL_ALLOWED_ROLES.isdisjoint(user_roles):\n      raise ValidationError()",
    errorState: BLOCK
  }) {
    rule {
      id
    }
  }
}
  • Control who can split inventory on the inventory table:

mutation {
  createRule(input: {
    title: "No Permissions to Split Inventory via Inventory Table",
    target: PARTINVENTORY,
    ruleType: VALIDATION,
    eventType: CREATE,
    enabled: true,
    context: "{\n  partInventory(id: $id) {\n    howCreated\n    id\n    part {\n      partType\n    }\n  }\n}",
    code: "MANUAL_SPLIT_ALLOWED_ROLES = {'planner','rando'}   # ← add or remove roles here\n\npart_inv = context.get('partInventory') or {}\nuser_roles = set(context.get('currentUser', {}).get('roles', []))\nif part_inv.get('howCreated') == 'DIRECT_SPLIT':\n  if MANUAL_SPLIT_ALLOWED_ROLES.isdisjoint(user_roles):\n    raise ValidationError()",
    errorState: BLOCK
  }) {
    rule {
      id
    }
  }
}

Any of the above ION Actions can be quickly adjusted by modifying the value specified for howCreated in your python logic. For example, you could replace 'MANUAL' with 'RUN_MADE' or 'PARTIAL_KIT' to change the targeted creation event.

Last updated

Was this helpful?