Reference for critical_materials and substitution_groups in procurement, with fields, routes, rules, and how MRP and purchase requests use them.
This page describes two sub-modules of src/cluster_erp/modules/procurement/. critical_materials/ marks materials that must not run short, with lead-time bounds and an alert threshold. substitution_groups/ groups product breakdowns that can stand in for each other, with a preference order and a conversion factor. Both are read by the MRP run, described on material requirements planning.
Defined in: models.py, services.py, routes.py, and metadata.py of both sub-modules (plus member_metadata.py for substitution members); query handlers in src/cluster_erp/modules/procurement/module.py:578-652.
Count: 3 tables; 6 critical material routes and 10 substitution group routes (@router. decorators); no ActionMeta entries.
A product can be a critical material only once among live rows. The check and the partial unique index use product_id alone, not the breakdown (src/cluster_erp/modules/procurement/critical_materials/models.py:14-21, src/cluster_erp/modules/procurement/critical_materials/services.py:80-91).
Critical material and member breakdowns are checked with ensure_product_breakdown (src/cluster_erp/modules/procurement/critical_materials/services.py:93, src/cluster_erp/modules/procurement/substitution_groups/services.py:203).
A breakdown appears once per group among live members (src/cluster_erp/modules/procurement/substitution_groups/models.py:58-66, src/cluster_erp/modules/procurement/substitution_groups/services.py:208-228).
The last member of a group cannot be removed (src/cluster_erp/modules/procurement/substitution_groups/services.py:308-322).
GetSubstitutesForProduct skips inactive groups and members outside their validity window, and sorts by preference_order (src/cluster_erp/modules/procurement/module.py:604-652).
A purchase request whose items include an active critical material gets priority high (src/cluster_erp/modules/procurement/purchase_requests/services.py:270-273).
MRP emits CriticalMaterialAlert once per product when the planned order date is within the product's alert threshold (src/cluster_erp/modules/procurement/mrp/engine.py:4090-4118).