inventory control examples.md

Inventory Control Examples

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

Creating Inventory Actions

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

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:

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
    }
  }
}
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
    }
  }
}
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
    }
  }
}
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.