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
+6
View File
@@ -39,6 +39,12 @@ Some models allow for mapping based on other "natural key" fields (e.g. the `ref
Importing data is a multi-step process, which is managed via an *import session*. An import session is created when the user initiates a data import, and is used to track the progress of the data import process.
### Import Session Status
Each import session has a specific status code, indicating where it is in the import process:
{{ statuscodes("DataImportStatusCode") }}
### Import Session List
The import session is managed by the InvenTree server, and all import session data is stored on the server. As the import process can be time-consuming, the user can navigate away from the import page and return later to check on the progress of the import.
+62 -1
View File
@@ -260,14 +260,75 @@ def on_config(config, *args, **kwargs):
return config
def check_status_codes_documented(gen_base):
"""Check that every 'StatusCode' class is documented somewhere in the docs.
A class counts as documented if the `statuscodes()` macro has been called
for it from at least one markdown page (recorded in 'observed_status_codes.json').
"""
expected_status_codes_file = gen_base.joinpath('inventree_status_codes.json')
observed_status_codes_file = gen_base.joinpath('observed_status_codes.json')
with open(observed_status_codes_file, encoding='utf-8') as f:
observed_status_codes = json.loads(f.read())
with open(expected_status_codes_file, encoding='utf-8') as f:
expected_status_codes = json.loads(f.read())
missing = [
name for name in expected_status_codes if name not in observed_status_codes
]
if missing:
raise NotImplementedError(
'Missing Status Codes:\n'
+ f'There are {len(missing)} status code classes not documented via the `statuscodes()` macro:\n- '
+ '\n- '.join(missing)
)
def check_status_code_values_documented(gen_base):
"""Check that every value of every 'StatusCode' class has a description.
Descriptions are sourced from the class docstring's `Attributes:` block (see
`export_status_codes.py` / e.g. `build.status_codes.BuildStatus`) - a status
value with no matching `Attributes:` entry exports with an empty description,
which this check catches.
"""
expected_status_codes_file = gen_base.joinpath('inventree_status_codes.json')
with open(expected_status_codes_file, encoding='utf-8') as f:
expected_status_codes = json.loads(f.read())
missing = [
f'{class_name}.{value["name"]}'
for class_name, info in expected_status_codes.items()
for value in info['values']
if not value['description']
]
if missing:
raise NotImplementedError(
'Missing Status Code Descriptions:\n'
+ f'There are {len(missing)} status code values with no description in their '
+ "class docstring's `Attributes:` block:\n- "
+ '\n- '.join(missing)
)
def on_post_build(*args, **kwargs):
"""Run after the build is complete.
Here we check that all global settings and user settings are documented.
Here we check that all global settings and user settings are documented,
that every status code class is documented (via the `statuscodes` macro),
and that every individual status code value has a description.
"""
here = Path(__file__).parent
gen_base = here.parent.joinpath('generated')
check_status_codes_documented(gen_base)
check_status_code_values_documented(gen_base)
expected_settings_file = gen_base.joinpath('inventree_settings.json')
observed_settings_file = gen_base.joinpath('observed_settings.json')
+1 -19
View File
@@ -71,25 +71,7 @@ Read more about build outputs [here](./output.md).
Each *Build Order* has an associated *Status* flag, which indicates the state of the build:
| Status | Description |
| ----------- | ----------- |
| `Pending` | Build order has been created, but is not yet in production |
| `Production` | Build order is currently in production |
| `On Hold` | Build order has been placed on hold, but is still active |
| `Cancelled` | Build order has been cancelled |
| `Completed` | Build order has been completed |
**Source Code**
Refer to the source code for the Build Order status codes:
::: build.status_codes.BuildStatus
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []
{{ statuscodes("BuildStatus") }}
### Stock Allocations
+2 -6
View File
@@ -10,17 +10,13 @@ Label printer machines can directly print labels for various items in InvenTree.
To implement a custom label printer driver, you need to write a plugin which implements the [MachineDriverMixin](../mixins/machine.md) and returns a list of label printer drivers in the `get_machine_drivers` method.
Take a look at the most basic required code for a driver in this [example](./overview.md#example-driver). Next either implement the [`print_label`](#machine.machine_types.LabelPrinterBaseDriver.print_label) or [`print_labels`](#machine.machine_types.LabelPrinterBaseDriver.print_labels) function.
Take a look at the most basic required code for a driver in this [example](./overview.md#example-driver). Next either implement the [`print_label`](#labelprintingdriver-api) or [`print_labels`](#labelprintingdriver-api) function.
### Label Printer Status
There are a couple of predefined status codes for label printers. By default the `UNKNOWN` status code is set for each machine, but they can be changed at any time by the driver. For more info about status code see [Machine status codes](./overview.md#machine-status).
::: machine.machine_types.label_printer.LabelPrinterStatus
options:
heading_level: 4
show_bases: false
show_docstring_description: false
{{ statuscodes("LabelPrinterStatus") }}
### LabelPrintingDriver API
+1 -21
View File
@@ -30,27 +30,7 @@ The following view modes are available:
Each Purchase Order has a specific status code which indicates the current state of the order:
| Status | Description |
| --- | --- |
| Pending | The purchase order has been created, but has not been submitted to the supplier |
| In Progress | The purchase order has been issued to the supplier, and is in progress |
| On Hold | The purchase order has been placed on hold, but is still active |
| Complete | The purchase order has been completed, and is now closed |
| Cancelled | The purchase order was cancelled, and is now closed |
| Lost | The purchase order was lost, and is now closed |
| Returned | The purchase order was returned, and is now closed |
**Source Code**
Refer to the source code for the Purchase Order status codes:
::: order.status_codes.PurchaseOrderStatus
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []
{{ statuscodes("PurchaseOrderStatus") }}
Purchase Order Status supports [custom states](../concepts/custom_states.md).
+2 -27
View File
@@ -55,25 +55,7 @@ Various filters are available to configure which orders are displayed, and how t
Each Return Order has a specific status code, as follows:
| Status | Description |
| --- | --- |
| Pending | The return order has been created, but not sent to the customer |
| In Progress | The return order has been issued to the customer |
| On Hold | The return order has been placed on hold, but is still active |
| Complete | The return order was marked as complete, and is now closed |
| Cancelled | The return order was cancelled, and is now closed |
**Source Code**
Refer to the source code for the Return Order status codes:
::: order.status_codes.ReturnOrderStatus
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []
{{ statuscodes("ReturnOrderStatus") }}
Return Order Status supports [custom states](../concepts/custom_states.md).
@@ -126,14 +108,7 @@ Each line item tracks a *Cost* (the cost associated with the return, repair, or
Each line item has an *Outcome*, which records the disposition decided for the returned item:
| Outcome | Description |
| --- | --- |
| 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 |
{{ statuscodes("ReturnOrderLineStatus") }}
The *Outcome* is not available when a line item is first created - it can only be set afterwards, by editing the line item. Selecting an outcome is a manual, record-keeping step only: InvenTree does not automatically create a replacement order, issue a refund, or link to a [repair](../manufacturing/index.md) process based on the selected outcome. Any follow-up action (raising a new [Sales Order](./sales_order.md) for a replacement, processing a refund, or tracking a repair) must currently be actioned separately.
+1 -22
View File
@@ -31,28 +31,7 @@ The following view modes are available:
Each Sales Order has a specific status code, which represents the state of the order:
| Status | Description |
| --- | --- |
| Pending | The sales order has been created, but has not been finalized or submitted |
| In Progress | The sales order has been issued, and is in progress |
| On Hold | The sales order has been placed on hold, but is still active |
| Shipped | The sales order has been shipped, but is not yet complete |
| Complete | The sales order is fully completed, and is now closed |
| Cancelled | The sales order was cancelled, and is now closed |
| Lost | The sales order was lost, and is now closed |
| Returned | The sales order was returned, and is now closed |
**Source Code**
Refer to the source code for the Sales Order status codes:
::: order.status_codes.SalesOrderStatus
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []
{{ statuscodes("SalesOrderStatus") }}
Sales Order Status supports [custom states](../concepts/custom_states.md).
+1 -12
View File
@@ -25,18 +25,7 @@ A *role* is a set of distinct permissions linked to a given subset of InvenTree
InvenTree functionality is split into a number of distinct roles. A group will have a set of permissions assigned to each of the following roles:
| Role | Description |
| ---- | ----------- |
| **Admin** | The *admin* role is related to assigning user permissions. |
| **BOM** | The *bom* role is related to accessing Bill of Materials data |
| **Build** | The *build* role is related to accessing manufacturing / Build Order |
| **Part** | The *part* role is related to accessing Part data |
| **Part Category** | The *part category* role is related to accessing Part Category data |
| **Purchase Order** | The *purchase* role is related to accessing Purchase Order data |
| **Return Order** | The *return* role is related to accessing Return Order data |
| **Sales Order** | The *sales* role is related to accessing Sales Order data |
| **Stock Item** | The *stock item* role is related to accessing Stock Item data |
| **Stock Location** | The *stock location* role is related to accessing Stock Location data |
{{ roles() }}
{{ image("admin/roles.png", "Roles") }}
+3 -21
View File
@@ -10,32 +10,14 @@ Certain stock item status codes will restrict the availability of the stock item
Below is the list of available stock status codes and their meaning:
| Status | Description | Available |
| ----------- | ----------- | --- |
| <span class='badge inventree success'>OK</span> | Stock item is healthy, nothing wrong to report | <span class='badge inventree success'>Yes</span> |
| <span class='badge inventree warning'>Attention needed</span> | Stock item hasn't been checked or tested yet | <span class='badge inventree success'>Yes</span> |
| <span class='badge inventree warning'>Damaged</span> | Stock item is not functional in its present state | <span class='badge inventree success'>Yes</span> |
| <span class='badge inventree danger'>Destroyed</span> | Stock item has been destroyed | <span class='badge inventree danger'>No</span> |
| <span class='badge inventree'>Lost</span> | Stock item has been lost | <span class='badge inventree danger'>No</span> |
| <span class='badge inventree danger'>Rejected</span> | Stock item did not pass the quality control standards | <span class='badge inventree danger'>No</span> |
| <span class='badge inventree info'>Quarantined</span> | Stock item has been intentionally isolated and it unavailable | <span class='badge inventree danger'>No</span> |
{{ statuscodes("StockStatus") }}
Of these, only *OK*, *Attention needed*, *Damaged* and *Returned* count as "available" stock - the remainder are excluded from availability calculations.
The *status* of a given stock item is displayed on the stock item detail page:
{{ image("stock/stock_status_label.png", title="Stock status label") }}
**Source Code**
Refer to the source code for the Stock status codes:
::: stock.status_codes.StockStatus
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []
### Custom Status Codes
Stock Status supports [custom states](../concepts/custom_states.md).
+6
View File
@@ -17,6 +17,12 @@ Some examples of events that may trigger stock tracking entries include:
- Allocation of stock items to orders (e.g. shipping items against sales orders)
- Consumption of stock items during build processes (e.g. using items to complete a build order)
### Tracking Entry Types
Each stock tracking entry records a specific *type*, indicating which event triggered it:
{{ statuscodes("StockHistoryCode") }}
## Viewing Stock Tracking History
There are multiple ways to view the stock tracking history for a particular stock item or part via the user interface.
+1 -19
View File
@@ -31,25 +31,7 @@ The following view modes are available:
Each Transfer Order has a specific status code, which represents the state of the order:
| Status | Description |
| --- | --- |
| Pending | The transfer order has been created, but has not been finalized or submitted |
| Issued | The transfer order has been issued, and is in progress |
| On Hold | The transfer order has been placed on hold, but is still active |
| Complete | The transfer order is fully completed, and is now closed |
| Cancelled | The transfer order was cancelled, and is now closed |
**Source Code**
Refer to the source code for the Transfer Order status codes:
::: order.status_codes.TransferOrderStatus
options:
show_bases: False
show_root_heading: False
show_root_toc_entry: False
show_source: True
members: []
{{ statuscodes("TransferOrderStatus") }}
Transfer Order Status supports [custom states](../concepts/custom_states.md).
+66
View File
@@ -40,6 +40,8 @@ global USER_SETTINGS
global TAGS
global FILTERS
global REPORT_CONTEXT
global STATUS_CODES
global ROLES
# Read in the InvenTree settings file
here = Path(__file__).parent
@@ -60,6 +62,13 @@ with open(observed_settings_file, 'w', encoding='utf-8') as f:
# This is used to track which settings we have observed during the build process
f.write(json.dumps(data, indent=4))
# File where we will *store* information on the status code classes we have observed
observed_status_codes_file = gen_base.joinpath('observed_status_codes.json')
# Overwrite the observed status codes file
with open(observed_status_codes_file, 'w', encoding='utf-8') as f:
f.write(json.dumps({}, indent=4))
with open(settings_file, encoding='utf-8') as sf:
settings = json.load(sf)
@@ -73,9 +82,15 @@ with open(gen_base.joinpath('inventree_tags.yml'), encoding='utf-8') as f:
# Filters
with open(gen_base.joinpath('inventree_filters.yml'), encoding='utf-8') as f:
FILTERS = yaml.load(f, yaml.BaseLoader)
# Status codes
with open(gen_base.joinpath('inventree_status_codes.json'), encoding='utf-8') as f:
STATUS_CODES = json.load(f)
# Report context
with open(gen_base.joinpath('inventree_report_context.json'), encoding='utf-8') as f:
REPORT_CONTEXT = json.load(f)
# User permission roles
with open(gen_base.joinpath('inventree_roles.json'), encoding='utf-8') as f:
ROLES = json.load(f)
def get_repo_url(raw=False):
@@ -297,6 +312,38 @@ def define_env(env):
return includefile(fn, f'Template: {base}', fmt='html')
@env.macro
def statuscodes(class_name: str):
"""Render a markdown table of status codes for the given StatusCode class.
Arguments:
class_name: The name of the `StatusCode` subclass to render (e.g. 'BuildStatus')
The table is built directly from `docs/generated/inventree_status_codes.json`
(produced by the `export_status_codes` management command), so it can never
drift out of sync with the status codes actually defined in the source code.
"""
global STATUS_CODES
status_class = STATUS_CODES[class_name]
# Record that this status code class has been rendered somewhere in the docs
with open(observed_status_codes_file, encoding='utf-8') as f:
data = json.load(f)
data[class_name] = True
with open(observed_status_codes_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4)
ret_data = '| Status | Value | Description |\n| --- | --- | --- |\n'
for item in status_class['values']:
description = item['description'] or item['label']
ret_data += f'| {item["label"]} | {item["key"]} | {description} |\n'
return ret_data
def observe_setting(key: str, group: str):
"""Record that a particular setting has been observed.
@@ -429,6 +476,25 @@ def define_env(env):
return ret_data
@env.macro
def roles():
"""Render a markdown table of the available user permission roles.
The table is built directly from `docs/generated/inventree_roles.json`
(produced by the `export_roles` management command, sourced from
`users.ruleset.RULESET_CHOICES`), so it can never drift out of sync with
the roles actually defined in the source code.
"""
global ROLES
ret_data = '| Role | Description |\n| --- | --- |\n'
for role in ROLES:
description = role['description'] or role['label']
ret_data += f'| **{role["label"]}** | {description} |\n'
return ret_data
@env.macro
def report_context(type_: Literal['models', 'base'], model: str):
"""Extract information on a particular report context."""