Auto-extract StatusCode values for docs (#12686)

* Auto-extract StatusCode values for docs

* Extract user roles from code

* Fix links

* Remove extraneous source code in docs
This commit is contained in:
Oliver
2026-08-23 18:48:05 +10:00
committed by GitHub
parent f063a6c67f
commit bc98e4bab6
20 changed files with 486 additions and 238 deletions
@@ -0,0 +1,58 @@
"""Custom management command to export all user permission roles.
This is used to generate a JSON file which contains all of the roles (rulesets)
available in InvenTree, so that they can be introspected by the InvenTree
documentation system. This allows the roles table to be documented without
having to manually duplicate the information (which otherwise silently drifts
out of sync with the source code - e.g. a newly added ruleset going undocumented).
"""
import json
from django.core.management.base import BaseCommand
from users.ruleset import RULESET_CHOICES, RuleSetEnum
from .export_report_context import parse_docstring
class Command(BaseCommand):
"""Extract user permission role information, and export to a JSON file."""
def add_arguments(self, parser):
"""Add custom arguments for this command."""
parser.add_argument(
'filename', type=str, help='Output filename for role definitions'
)
def handle(self, *args, **kwargs):
"""Export role information to a JSON file."""
roles = discover_roles()
filename = kwargs.get('filename', 'inventree_roles.json')
with open(filename, 'w', encoding='utf-8') as f:
json.dump(roles, f, indent=4)
print(f"Exported InvenTree role definitions to '{filename}'")
def discover_roles():
"""Discover all available user permission roles (rulesets).
Returns a list of roles, in the order they are declared in `RULESET_CHOICES`.
Each role's description is sourced from `RuleSetEnum`'s docstring `Attributes:`
block, rather than being manually curated here - so a role's description can
never drift out of sync with its source.
"""
attributes = parse_docstring(RuleSetEnum.__doc__ or '').get('Attributes', {})
return [
{
'name': key.name,
'key': str(key.value),
'label': str(label),
'description': attributes.get(key.name, ''),
}
for key, label in RULESET_CHOICES
]
@@ -0,0 +1,84 @@
"""Custom management command to export all status codes.
This is used to generate a JSON file which contains all of the 'StatusCode'
classes available in InvenTree, so that they can be introspected by the
InvenTree documentation system. This allows status code tables to be
documented without having to manually duplicate the information (which
otherwise silently drifts out of sync with the source code).
"""
import json
from django.core.management.base import BaseCommand
from generic.states import StatusCode
from InvenTree.helpers import inheritors
from .export_report_context import parse_docstring
class Command(BaseCommand):
"""Extract status code information, and export to a JSON file."""
def add_arguments(self, parser):
"""Add custom arguments for this command."""
parser.add_argument(
'filename', type=str, help='Output filename for status code definitions'
)
def handle(self, *args, **kwargs):
"""Export status code information to a JSON file."""
status_codes = discover_status_codes()
filename = kwargs.get('filename', 'inventree_status_codes.json')
with open(filename, 'w', encoding='utf-8') as f:
json.dump(status_codes, f, indent=4)
print(f"Exported InvenTree status code definitions to '{filename}'")
def discover_status_codes():
"""Discover all available status code classes.
Returns a dict, keyed by class name, of every concrete `StatusCode`
subclass (i.e. one which defines at least one status value - this
excludes abstract base classes such as `MachineStatus`, which is
subclassed per machine driver/plugin rather than used directly).
Each entry contains the class' module path and 'tag', plus a list of its
status values. The description of each value is sourced from the
class docstring's Google-style `Attributes:` block (see e.g.
`build.status_codes.BuildStatus`), rather than being manually curated
here - so a status code's description can never drift out of sync with
its source.
"""
data = {}
for cls in inheritors(StatusCode):
# custom=False: this is a definition of the *built-in* status codes as
# they exist in source - user/plugin-defined custom states are runtime data
values = cls.dict(custom=False)
if not values:
# Abstract base class with no concrete status values (e.g. MachineStatus)
continue
attributes = parse_docstring(cls.__doc__ or '').get('Attributes', {})
data[cls.__name__] = {
'module': cls.__module__,
'tag': cls.tag(),
'values': [
{
'name': item['name'],
'key': item['key'],
'label': str(item['label']),
'color': item['color'],
'description': attributes.get(item['name'], ''),
}
for item in values.values()
],
}
return dict(sorted(data.items()))
+14 -6
View File
@@ -6,13 +6,21 @@ from generic.states import ColorEnum, StatusCode
class BuildStatus(StatusCode):
"""Build status codes."""
"""Build status codes.
PENDING = 10, _('Pending'), ColorEnum.secondary # Build is pending / active
PRODUCTION = 20, _('Production'), ColorEnum.primary # Build is in production
ON_HOLD = 25, _('On Hold'), ColorEnum.warning # Build is on hold
CANCELLED = 30, _('Cancelled'), ColorEnum.danger # Build was cancelled
COMPLETE = 40, _('Complete'), ColorEnum.success # Build is complete
Attributes:
PENDING: Build is pending / active
PRODUCTION: Build is in production
ON_HOLD: Build is on hold
CANCELLED: Build was cancelled
COMPLETE: Build is complete
"""
PENDING = 10, _('Pending'), ColorEnum.secondary
PRODUCTION = 20, _('Production'), ColorEnum.primary
ON_HOLD = 25, _('On Hold'), ColorEnum.warning
CANCELLED = 30, _('Cancelled'), ColorEnum.danger
COMPLETE = 40, _('Complete'), ColorEnum.success
class BuildStatusGroups:
+14 -18
View File
@@ -6,22 +6,18 @@ from generic.states import ColorEnum, StatusCode
class DataImportStatusCode(StatusCode):
"""Defines a set of status codes for a DataImportSession."""
"""Defines a set of status codes for a DataImportSession.
INITIAL = (
0,
_('Initializing'),
ColorEnum.secondary,
) # Import session has been created
MAPPING = (
10,
_('Mapping Columns'),
ColorEnum.primary,
) # Import fields are being mapped
IMPORTING = 20, _('Importing Data'), ColorEnum.primary # Data is being imported
PROCESSING = (
30,
_('Processing Data'),
ColorEnum.primary,
) # Data is being processed by the user
COMPLETE = 40, _('Complete'), ColorEnum.success # Import has been completed
Attributes:
INITIAL: Import session has been created
MAPPING: Import fields are being mapped
IMPORTING: Data is being imported
PROCESSING: Data is being processed by the user
COMPLETE: Import has been completed
"""
INITIAL = 0, _('Initializing'), ColorEnum.secondary
MAPPING = 10, _('Mapping Columns'), ColorEnum.primary
IMPORTING = 20, _('Importing Data'), ColorEnum.primary
PROCESSING = 30, _('Processing Data'), ColorEnum.primary
COMPLETE = 40, _('Complete'), ColorEnum.success
+71 -46
View File
@@ -6,16 +6,25 @@ from generic.states import ColorEnum, StatusCode
class PurchaseOrderStatus(StatusCode):
"""Defines a set of status codes for a PurchaseOrder."""
"""Defines a set of status codes for a PurchaseOrder.
# Order status codes
PENDING = 10, _('Pending'), ColorEnum.secondary # Order is pending (not yet placed)
PLACED = 20, _('Placed'), ColorEnum.primary # Order has been placed with supplier
ON_HOLD = 25, _('On Hold'), ColorEnum.warning # Order is on hold
COMPLETE = 30, _('Complete'), ColorEnum.success # Order has been completed
CANCELLED = 40, _('Cancelled'), ColorEnum.danger # Order was cancelled
LOST = 50, _('Lost'), ColorEnum.warning # Order was lost
RETURNED = 60, _('Returned'), ColorEnum.warning # Order was returned
Attributes:
PENDING: Order is pending (not yet placed)
PLACED: Order has been placed with supplier
ON_HOLD: Order is on hold
COMPLETE: Order has been completed
CANCELLED: Order was cancelled
LOST: Order was lost
RETURNED: Order was returned
"""
PENDING = 10, _('Pending'), ColorEnum.secondary
PLACED = 20, _('Placed'), ColorEnum.primary
ON_HOLD = 25, _('On Hold'), ColorEnum.warning
COMPLETE = 30, _('Complete'), ColorEnum.success
CANCELLED = 40, _('Cancelled'), ColorEnum.danger
LOST = 50, _('Lost'), ColorEnum.warning
RETURNED = 60, _('Returned'), ColorEnum.warning
class PurchaseOrderStatusGroups:
@@ -39,20 +48,27 @@ class PurchaseOrderStatusGroups:
class SalesOrderStatus(StatusCode):
"""Defines a set of status codes for a SalesOrder."""
"""Defines a set of status codes for a SalesOrder.
PENDING = 10, _('Pending'), ColorEnum.secondary # Order is pending
IN_PROGRESS = (
15,
_('In Progress'),
ColorEnum.primary,
) # Order has been issued, and is in progress
SHIPPED = 20, _('Shipped'), ColorEnum.primary # Order has been shipped to customer
ON_HOLD = 25, _('On Hold'), ColorEnum.warning # Order is on hold
COMPLETE = 30, _('Complete'), ColorEnum.success # Order is complete
CANCELLED = 40, _('Cancelled'), ColorEnum.danger # Order has been cancelled
LOST = 50, _('Lost'), ColorEnum.warning # Order was lost
RETURNED = 60, _('Returned'), ColorEnum.warning # Order was returned
Attributes:
PENDING: Order is pending
IN_PROGRESS: Order has been issued, and is in progress
SHIPPED: Order has been shipped to customer
ON_HOLD: Order is on hold
COMPLETE: Order is complete
CANCELLED: Order has been cancelled
LOST: Order was lost
RETURNED: Order was returned
"""
PENDING = 10, _('Pending'), ColorEnum.secondary
IN_PROGRESS = 15, _('In Progress'), ColorEnum.primary
SHIPPED = 20, _('Shipped'), ColorEnum.primary
ON_HOLD = 25, _('On Hold'), ColorEnum.warning
COMPLETE = 30, _('Complete'), ColorEnum.success
CANCELLED = 40, _('Cancelled'), ColorEnum.danger
LOST = 50, _('Lost'), ColorEnum.warning
RETURNED = 60, _('Returned'), ColorEnum.warning
class SalesOrderStatusGroups:
@@ -71,16 +87,19 @@ class SalesOrderStatusGroups:
class ReturnOrderStatus(StatusCode):
"""Defines a set of status codes for a ReturnOrder."""
"""Defines a set of status codes for a ReturnOrder.
Attributes:
PENDING: Order is pending, waiting for receipt of items
IN_PROGRESS: Items have been received, and are being inspected
ON_HOLD: Order is on hold
COMPLETE: Order is complete
CANCELLED: Order has been cancelled
"""
# Order is pending, waiting for receipt of items
PENDING = 10, _('Pending'), ColorEnum.secondary
# Items have been received, and are being inspected
IN_PROGRESS = 20, _('In Progress'), ColorEnum.primary
ON_HOLD = 25, _('On Hold'), ColorEnum.warning
COMPLETE = 30, _('Complete'), ColorEnum.success
CANCELLED = 40, _('Cancelled'), ColorEnum.danger
@@ -98,35 +117,41 @@ class ReturnOrderStatusGroups:
class ReturnOrderLineStatus(StatusCode):
"""Defines a set of status codes for a ReturnOrderLineItem."""
"""Defines a set of status codes for a ReturnOrderLineItem.
Attributes:
PENDING: No outcome has been decided yet (default value for a new line item)
RETURN: The item is to be returned to the customer, with no further action
REPAIR: The item is to be repaired, and returned to the customer
REPLACE: The item is to be replaced with a new item
REFUND: The item cannot be repaired, and a refund is to be issued
REJECT: The return is rejected
"""
PENDING = 10, _('Pending'), ColorEnum.secondary
# Item is to be returned to customer, no other action
RETURN = 20, _('Return'), ColorEnum.success
# Item is to be repaired, and returned to customer
REPAIR = 30, _('Repair'), ColorEnum.primary
# Item is to be replaced (new item shipped)
REPLACE = 40, _('Replace'), ColorEnum.warning
# Item is to be refunded (cannot be repaired)
REFUND = 50, _('Refund'), ColorEnum.info
# Item is rejected
REJECT = 60, _('Reject'), ColorEnum.danger
class TransferOrderStatus(StatusCode):
"""Defines a set of status codes for a TransferOrder."""
"""Defines a set of status codes for a TransferOrder.
# Order status codes
PENDING = 10, _('Pending'), ColorEnum.secondary # Order is pending (not yet issued)
ISSUED = 20, _('Issued'), ColorEnum.primary # Order has been issued
ON_HOLD = 25, _('On Hold'), ColorEnum.warning # Order is on hold
COMPLETE = 30, _('Complete'), ColorEnum.success # Order has been completed
CANCELLED = 40, _('Cancelled'), ColorEnum.danger # Order was cancelled
Attributes:
PENDING: Order is pending (not yet issued)
ISSUED: Order has been issued
ON_HOLD: Order is on hold
COMPLETE: Order has been completed
CANCELLED: Order was cancelled
"""
PENDING = 10, _('Pending'), ColorEnum.secondary
ISSUED = 20, _('Issued'), ColorEnum.primary
ON_HOLD = 25, _('On Hold'), ColorEnum.warning
COMPLETE = 30, _('Complete'), ColorEnum.success
CANCELLED = 40, _('Cancelled'), ColorEnum.danger
class TransferOrderStatusGroups:
+70 -19
View File
@@ -6,24 +6,27 @@ from generic.states import ColorEnum, StatusCode
class StockStatus(StatusCode):
"""Status codes for Stock."""
"""Status codes for Stock.
OK = 10, _('OK'), ColorEnum.success # Item is OK
ATTENTION = 50, _('Attention needed'), ColorEnum.warning # Item requires attention
DAMAGED = 55, _('Damaged'), ColorEnum.warning # Item is damaged
DESTROYED = 60, _('Destroyed'), ColorEnum.danger # Item is destroyed
REJECTED = 65, _('Rejected'), ColorEnum.danger # Item is rejected
LOST = 70, _('Lost'), ColorEnum.dark # Item has been lost
QUARANTINED = (
75,
_('Quarantined'),
ColorEnum.info,
) # Item has been quarantined and is unavailable
RETURNED = (
85,
_('Returned'),
ColorEnum.warning,
) # Item has been returned from a customer
Attributes:
OK: Stock item is healthy, nothing wrong to report
ATTENTION: Stock item hasn't been checked or tested yet
DAMAGED: Stock item is not functional in its present state
DESTROYED: Stock item has been destroyed
REJECTED: Stock item did not pass the quality control standards
LOST: Stock item has been lost
QUARANTINED: Stock item has been intentionally isolated and is unavailable
RETURNED: Stock item has been returned from a customer
"""
OK = 10, _('OK'), ColorEnum.success
ATTENTION = 50, _('Attention needed'), ColorEnum.warning
DAMAGED = 55, _('Damaged'), ColorEnum.warning
DESTROYED = 60, _('Destroyed'), ColorEnum.danger
REJECTED = 65, _('Rejected'), ColorEnum.danger
LOST = 70, _('Lost'), ColorEnum.dark
QUARANTINED = 75, _('Quarantined'), ColorEnum.info
RETURNED = 85, _('Returned'), ColorEnum.warning
class StockStatusGroups:
@@ -39,7 +42,55 @@ class StockStatusGroups:
class StockHistoryCode(StatusCode):
"""Status codes for StockHistory."""
"""Status codes for StockHistory.
Attributes:
LEGACY: Legacy stock tracking entry, created before tracking entry types existed
CREATED: Stock item created
EDITED: Stock item was manually edited
ASSIGNED_SERIAL: A serial number was assigned to the stock item
STOCK_COUNT: Stock was manually counted
STOCK_ADD: Stock was manually added
STOCK_REMOVE: Stock was manually removed
STOCK_SERIALIZED: Stock items were serialized
RETURNED_TO_STOCK: Stock item was returned to stock
STOCK_MOVE: The location of the stock item was changed
STOCK_UPDATE: Stock item was updated
INSTALLED_INTO_ASSEMBLY: Stock item was installed into an assembly
REMOVED_FROM_ASSEMBLY: Stock item was removed from an assembly
INSTALLED_CHILD_ITEM: A component item was installed into this stock item
REMOVED_CHILD_ITEM: A component item was removed from this stock item
SPLIT_FROM_PARENT: Stock item was split from a parent stock item
SPLIT_CHILD_ITEM: A child stock item was split from this stock item
MERGED_STOCK_ITEMS: Multiple stock items were merged into this one
DISASSEMBLED: Stock item was disassembled into its component items
CREATED_FROM_DISASSEMBLY: Stock item was created as a result of disassembly
CONVERTED_TO_VARIANT: Stock item was converted to a variant of its part
BUILD_OUTPUT_CREATED: Stock item was created as a build order output
BUILD_OUTPUT_COMPLETED: Stock item (a build order output) was completed
BUILD_OUTPUT_REJECTED: Stock item (a build order output) was rejected
BUILD_CONSUMED: Stock item was consumed by a build order
SHIPPED_AGAINST_SALES_ORDER: Stock item was shipped against a Sales Order
RECEIVED_AGAINST_PURCHASE_ORDER: Stock item was received against a Purchase Order
RETURNED_AGAINST_RETURN_ORDER: Stock item was returned against a Return Order
SENT_TO_CUSTOMER: Stock item was sent to a customer
RETURNED_FROM_CUSTOMER: Stock item was returned from a customer
"""
LEGACY = 0, _('Legacy stock tracking entry')
@@ -55,7 +106,7 @@ class StockHistoryCode(StatusCode):
STOCK_REMOVE = 12, _('Stock manually removed')
STOCK_SERIALIZED = 13, _('Serialized stock items')
RETURNED_TO_STOCK = 15, _('Returned to stock') # Stock item returned to stock
RETURNED_TO_STOCK = 15, _('Returned to stock')
# Location operations
STOCK_MOVE = 20, _('Location changed')
+15 -1
View File
@@ -7,7 +7,21 @@ from generic.enums import StringEnum
class RuleSetEnum(StringEnum):
"""Enumeration of ruleset names."""
"""Enumeration of ruleset names.
Attributes:
ADMIN: Assigning user permissions, and other administrative tasks
PART_CATEGORY: Accessing Part Category data
PART: Accessing Part data
BOM: Accessing Bill of Materials data
STOCK_LOCATION: Accessing Stock Location data
STOCK: Accessing Stock Item data
BUILD: Accessing manufacturing / Build Order data
PURCHASE_ORDER: Accessing Purchase Order data
SALES_ORDER: Accessing Sales Order data
RETURN_ORDER: Accessing Return Order data
TRANSFER_ORDER: Accessing Transfer Order data
"""
ADMIN = 'admin'
PART_CATEGORY = 'part_category'