InvenTree 制造管理实战:从 BOM、库存分配到生产工单完成与拆解的全链路指南
【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree
InvenTree 提供了一套完整且灵活的制造系统,用于简化生产工作流、管理库存消耗并实时跟踪生产进度,适合管理内部制造、子装配与生产线,实现高可见性与强控制。本文以 InvenTree 官方制造文档(docs/docs/manufacturing/index.md)为骨架,完整继承其中 BOM 支持、生产工单(Build Order)、库存分配(Stock Allocation)与拆解(Disassembly)四大核心主题,并结合后端源码中的数量计算逻辑与数据模型,帮助读者掌握从 BOM 维护、需求数量计算、物料分配到工单完成乃至反向拆解的完整生产实战方案。
制造系统全景:四大核心能力
InvenTree 的制造系统由四个相互衔接的部分组成,覆盖了"定义物料 → 下达生产 → 分配库存 → 产出成品/反向拆解"的完整闭环:
| 能力 | 作用 | 详细文档 |
|---|---|---|
| BOM 支持 | 定义多层级物料清单,描述装配所需的全部组件 | docs/docs/manufacturing/bom.md |
| 生产工单(Build Orders) | 管理与跟踪针对特定装配的生产任务,工单关联特定 BOM,确保制造过程消耗正确的组件 | docs/docs/manufacturing/index.md |
| 库存分配(Stock Allocation) | 将库存项分配到特定生产工单,为生产预留物料,防止缺货 | docs/docs/manufacturing/allocate.md |
| 拆解(Disassembly) | 将已装配的库存项按其 BOM 拆回组件,用于返工、报废或拆分"套件"产品 | docs/docs/stock/disassemble.md |
从后端源码结构看,制造模块独立成 Django app,核心数据模型(Build、BuildLine、BuildItem)定义在 build/models.py 中:其中BuildLine(build/models.py#L2159)表示工单内某个 BOM 行的需求与分配状态,BuildItem(build/models.py#L2279)表示一次具体的库存分配记录。这与文档描述的"工单关联 BOM、库存项分配到工单"的模型一一对应。
BOM 管理:装配的物料定义
BOM 与 BOM 行项目
物料清单(Bill of Materials,BOM)定义了制造某个装配所需的组件零件列表,是创建生产工单与分配库存的基础。可以由其他子组件构建的零件称为装配(Assembly)。
特定装配的 BOM 由零个或多个"BOM 行项目"(BOM Line Item)组成,每个行项目的属性如下(完整继承自 BOM 文档):
| 属性 | 说明 |
|---|---|
| Part | 指向构建此装配所需的另一个Part对象的引用 |
| Reference | 可选的参考字段,用于描述该 BOM 行项目,如位号(part designator) |
| Raw Amount | 制造该装配所需零件的原始数量,可用不同的计量单位表示,如2 cm、1/2 inch、200 kg |
| Quantity | 制造该装配所需Part的数量——该值由 "Raw Amount" 字段自动计算,并计入底层零件关联的计量单位 |
| Attrition | 预计的生产损耗,按基础数量的百分比表示(如 2%) |
| Setup Quantity | 为补偿生产过程中的固定设置损耗而额外需要的数量,加到 BOM 行项目的基础数量上 |
| Piece Count | 每个装配所需的单件数量(用于定长切割类物料),默认 1;总材料 = quantity × piece_count |
| Rounding Multiple | 表示所需数量应向上取整为该值最近倍数的舍入倍数 |
| Consumable | 布尔字段,表示该 BOM 行项目是否"可消耗"(consumable) |
| Inherited | 布尔字段,表示该 BOM 行项目是否会被"继承"到该零件的变体(或子变体)零件的 BOM 中 |
| Optional | 布尔字段,表示该 BOM 行项目是否"可选" |
| Note | 可选的备注字段,提供附加信息 |
计量单位与分数表示
raw_amount字段允许用户以不同的计量单位指定特定零件所需数量(单位体系见 docs/docs/concepts/units.md),单位由底层零件定义决定。例如,若零件默认计量单位为 "kg",用户可以用 "g"、"mg"、"lb" 等表示所需数量。raw_amount以字符串存储,quantity由raw_amount结合单位换算自动计算——这既保证了录入灵活性,又维持了库存与生产需求的精确跟踪。若底层零件未定义计量单位,则raw_amount不允许带单位,quantity即为其数值表示。
raw_amount还支持分数表示:若所需数量为 0.5 kg,用户可以写成500 g、0.5 kg或1/2 kg,quantity都会自动计算为 0.5 kg。
Piece Count:定长切割零件
piece_count字段支持"材料被切割/分割为多个相同单件"的场景,常见于线缆、导线、管材、型材等按长度计量的材料。当piece_count > 1时,quantity表示每件的尺寸/长度,piece_count表示每个装配需要多少件,总需求材料为:
Total material = quantity x piece_count x build_quantity示例 1:线束装配——某装配需要 10 根各 200mm 长的导线:
| 字段 | 值 | 说明 |
|---|---|---|
| Quantity | 200 (mm) | 每根导线的长度 |
| Piece Count | 10 | 每个装配的导线根数 |
| Build Quantity | 5 | 要制造的装配数 |
| Total Required | 10,000 mm (10m) | 200 × 10 × 5 = 10,000 mm |
示例 2:液压系统管材——某装配需要 4 段各 500mm 的管材,损耗率 5%:
| 字段 | 值 | 说明 |
|---|---|---|
| Quantity | 500 (mm) | 每段管材的长度 |
| Piece Count | 4 | 每个装配的管段数 |
| Build Quantity | 3 | 要制造的装配数 |
| Attrition | 5% | 补偿切割损耗 |
| Total Required | 6,300 mm (6.3m) | (500 × 4 × 3) × 1.05 = 6,300 mm |
默认行为:piece_count保持默认值 1 时,BOM 行项目行为与引入该特性之前完全一致,现有 BOM 不受影响。若每段长度不同,则应建立多个独立的 BOM 行项目。
可消耗、可选与替代 BOM 行项目
- 可消耗(Consumable)行项目:标记为 consumable 的行项目,其零件与数量信息虽被 BOM 跟踪,但不会在生产工单中被分配。适用于低价值、库存充裕或跟踪成本过高的物料。例如"木螺钉"每装配需 12 颗,但标记为 consumable 后不进入工单分配流程。注意:这是按装配的覆盖项——只影响该零件在这个特定 BOM 中的处理方式,不改变底层零件定义(零件本身也可被标记为 consumable,二者区别见 docs/docs/part/consumable.md)。
- 可选(Optional)行项目:标记为 optional 的行项目在完工工单时可选——包含则正常分配;不包含则工单可以不分配该物料即完工。
- 替代(Substitute)行项目:若制造装配时可使用替代零件,则在 BOM 中为该行项目指定多个替代零件。向生产工单分配库存时,任一替代零件关联的库存项都可以分配到该行项目;计算该行项目的可用数量时,替代零件的库存数量也会被计入。
继承 BOM 行项目
结合 InvenTree 的模板/变体(template/variant,见 docs/docs/part/template.md)功能,BOM 行项目支持继承能力:若某个 BOM 行项目被设为Inherited,它会自动出现在任何该零件的变体(或子变体)的 BOM 中。特别适合在模板零件上定义"所有变体共有"的 BOM 行。
以文档中的继承链路为例:模板零件 A定义了两条行项目A1(可继承)与A2(不可继承):
- 变体 B:继承A1,自有B1(也标记为可继承)
- 变体 C:继承A1,自有C1
- 变体 D:继承A1(来自 A)与B1(来自 B),自有D1
- 变体 E:以此类推
两点关键规则:继承只沿变体链向下流动(上级零件不能继承子零件的 BOM 项);编辑模板零件的继承 BOM 行项目时,变体零件的 BOM 会自动同步变化。
BOM 编辑与导入
BOM 可以手工逐行编辑,也可以从 CSV、Excel 等文件导入(属于通用数据导入流程的特例,见 docs/docs/concepts/data_import.md)。
- 编辑模式:BOM 默认处于"查看"模式,点击 BOM 面板顶部的编辑图标进入编辑模式,即可增改删行项目。只有具备相应权限的用户能看到编辑入口。
- 导入 BOM:在特定零件/装配的BOM面板顶部点击"Import BOM Data"图标打开导入对话框。
- 手动添加 BOM 项:进入零件/装配详情页的BOM面板 → 点击编辑图标 → 页面重载后点击"Add BOM Item"图标,填写
Create BOM Item表单后提交。 - 添加替代件:点击行项目Actions列的 transfer 图标,在
Edit BOM Item Substitutes表单中选择零件并确认 "Add Substitute"。
多层级 BOM
InvenTree 原生支持多层级(层级式)BOM:BOM 中可包含自身也有 BOM 的子装配,且层级数量不限。
BOM 校验:校验标志与校验和
InvenTree 为每个装配零件维护"validated"标志:一旦设置,表示该零件的生产需求已验证、BOM 自上次验证后未发生变化。每个零件上存储着一个 BOM "checksum"——对该零件关联的 BOM 行项目计算的哈希值。每当 BOM 行项目被创建、修改或删除,与之相关的装配都必须重新验证。
参与 BOM 校验和计算的行项目字段包括:Assembly ID、Component ID、Reference、Quantity、Attrition、Setup Quantity、Rounding Multiple、Piece Count、Consumable、Inherited、Optional、Allow Variants。这些字段任何一项变化都会触发校验和重算,相关装配被标记为"未验证",用户需手动重新验证。
源码印证:在 part/models.py 中,BomItem的post_save信号接收器update_bom_build_lines会在任何 BOM 行项目创建或编辑后,将build.tasks.update_build_order_lines卸载为后台任务——即 BOM 变动会自动联动刷新既有生产工单的需求行,这正是文档所述"工单需求随 BOM 自动维护"的实现机制。
查看校验状态:在零件详情页的 "Bill of Materials" 标签页顶部可看到校验状态;若 BOM 需要重新验证,状态显示为 "Not Validated",并出现 "Validate BOM" 按钮供重新验证。
BOM 比较与批量替换组件
- BOM 比较:可以比较两个装配的 BOM,突出差异组件、数量与属性。在 BOM 表格顶部点击比较图标,选择第二个装配后即可并排显示两方 BOM 行项目,差异高亮。支持三种显示模式:Show all parts(显示双方全部行项目并高亮差异)、Show different parts(仅显示不同行项目)、Show common parts(仅显示共同行项目)。
- 替换组件:当同一组件被多个装配的 BOM 使用时,InvenTree 提供 "Replace Component" 功能简化跨 BOM 的组件替换:进入组件零件详情页的Used In标签(见 docs/docs/part/views.md)→ 勾选要更新的装配 → 点击替换图标,在对话框中选定新组件零件即可。
需求数量计算:从 BOM 到工单的实际采购量
创建新的生产工单时,每个组件零件的需求生产数量会基于该装配的 BOM 行项目自动计算。计算顺序为:基础数量 → 损耗 → 设置数量 → 舍入倍数(完整继承自 docs/docs/manufacturing/required.md)。
计算步骤
1. 基础数量(Base Quantity)——BOM 行项目的Quantity字段表示制造单个装配所需数量,乘以装配生产总数:
Required Quantity = Base Quantity * Number of Assemblies2. 损耗(Attrition)——按百分比计入生产预期损耗,作用在已计算的Required Quantity上(可选,默认 0%):
Required Quantity = Required Quantity * (1 + Attrition Percentage)3. 设置数量(Setup Quantity)——补偿固定设置损耗,直接加到Required Quantity(可选,默认 0):
Required Quantity = Required Quantity + Setup Quantity4. 舍入倍数(Rounding Multiple)——向上取整到指定倍数的最近倍数,保证数量为整数或满足包装规格(可选,不指定则不取整):
Required Quantity = ceil(Required Quantity / Rounding Multiple) * Rounding Multiple完整算例:BOM 行项目为 Base Quantity = 3、Attrition = 2%、Setup Quantity = 10、Rounding Multiple = 25,生产 100 个装配:
Required Quantity = 3 * 100 = 300 Attrition Value = 300 * 0.02 = 6 Required Quantity = 300 + 6 = 306 Required Quantity = 306 + 10 = 316 Required Quantity = ceil(316 / 25) * 25 = 13 * 25 = 325最终该组件零件的需求生产数量为325。该计算在生产工单创建时自动完成。
源码印证:上述四步与BomItem.get_required_quantity()的实现逐行对应,见 part/models.py#L4304-L4349:
# 基础需求(quantity 为单件尺寸,piece_count 为件数) required = self.quantity * self.piece_count * build_quantity # 计入损耗 if self.attrition > 0: attrition = Decimal(self.attrition) / Decimal(100) required *= 1 + attrition # 计入设置数量 if self.setup_quantity > 0: required += Decimal(self.setup_quantity) # 向上取整到舍入倍数 if self.rounding_multiple and self.rounding_multiple > 0: value = math.ceil(Decimal(required) / Decimal(self.rounding_multiple)) * Decimal(self.rounding_multiple) required = float(value)可以看到:实现中采用Decimal运算保证精度,且注释明确说明定长切割零件的"总材料 = quantity × piece_count × build_quantity"公式,与 BOM 文档中的 Piece Count 章节完全一致。
库存分配:为生产工单预留物料
将库存项分配到生产工单,表达"这些库存项将在工单完成时从 InvenTree 中移除"的意图。注意:将工单标记为完成会移除已分配库存项,此操作不可逆。
未跟踪库存与跟踪库存
分配前必须理解未跟踪(untracked)与跟踪(tracked)零件的区别(跟踪概念见 docs/docs/part/trackable.md):
- 未跟踪库存:工单完成后,被分配的未跟踪(不可跟踪)库存项被标记为consumed(已消耗)。它们仍保留在数据库中,但不再可用于任何库存操作。示例:生产一批 PCB 需要 15 个 47K 电阻,分配一整卷 1000 个电阻,工单完成后可用库存减为 985。
- 跟踪库存:需要特别处理——这些零件要与具体的生产输出(Build Output)关联。工单完成时,跟踪库存项被安装(installed)进装配好的生产输出中。示例:上面生产的 PCB 是可跟踪零件并带有序列号 #001;当它被用于后续工单制造更大装配、且该工单完成时,这块带序列号的 PCB 就被安装进该装配。
一个装配的 BOM 完全可以混合包含未跟踪与跟踪组件,工单流程同时支持两者。
跟踪生产输出的额外约束:若装配 BOM 含一个或多个跟踪组件,创建生产输出时有额外限制——创建时必须提供序列号(以便跟踪子组件分配到具体单元),且每个生产输出为单件(一个序列号对应一个输出)。反之,若被装配零件本身可跟踪但 BOM 不含跟踪组件,则创建时不要求序列号,可创建批量输出并稍后序列化。
未跟踪库存的分配
未跟踪库存项是分配到生产工单本身的——无需跟踪其装进哪个生产输出,因此流程更简单。进入Allocate Stock标签查看分配表:
- 每个 BOM 行显示进度条,指示已分配数量占需求数量的比例;
- 点击某一行可展开查看分配到该工单的库存项列表;
- 单个库存项数量不足时,可为同一 BOM 行分配多个库存项。
自动分配规则:对每个 BOM 行,若在工单指定的来源位置内恰好只找到一个对应零件的库存项,则自动分配。选择Allocate Stock会弹出对话框,展示自动分配过程将使用的库存项:若某零件只有唯一对应库存项,则可自动分配;若某 BOM 行的库存分布在多个位置,则无法自动分配,需要用户手动选择。
手动操作:
- 逐行分配(Row Allocation):使用分配表每行的Allocate stock按钮手动分配;
- 调整分配(Edit Allocations):使用行内操作按钮手动调整或删除分配;
- 取消分配(Deallocate Stock):移除工单上所有未跟踪库存项的分配。
自动分配(Auto Allocate)
Auto Allocate按钮可一键自动分配库存项到工单(作为后台任务运行,UI 显示进度指示器)。默认处理全部符合条件的 BOM 行项目;若要限定子集,先在分配表中勾选目标行——对话框会显示选中行数。
Automatic Allocation对话框的选项:
Source Location(来源位置):指定库存项分配自哪个主位置;留空则从任意可用位置分配。
Exclude Location(排除位置):排除某特定位置(及其全部子位置)的库存,适合为特定区域预留物料。
Interchangeable Stock(可互换库存):设为True表示多个可用库存项可互换使用——存在多个库存项时,自动分配算法不关心用哪一个。注意:开启该选项且存在多个库存项时,分配结果可能略出乎意料。示例:有 5 卷C_100nF_0603电容(每卷 4,000 个),若不在乎从哪一卷取料,开启该选项后将从其中一卷分配,并在工单完成时从库存中扣减。
Substitute Stock(替代库存):设为True时,主零件不可用则允许按 BOM 分配的替代零件参与分配。
Optional Items(可选物料):设为True时将可选 BOM 行项目纳入自动分配;默认不自动分配可选项。
Item Type(行项目类型)——控制考虑哪类 BOM 行:
| 选项 | 说明 |
|---|---|
| Untracked Items | 仅分配未跟踪(非序列化)BOM 行(默认) |
| Tracked Items | 仅分配跟踪 BOM 行 |
| All Items | 同时分配跟踪与未跟踪 BOM 行 |
Stock Priority(库存优先级)——控制匹配库存项的消耗顺序:
| 选项 | 说明 |
|---|---|
| Oldest stock first (FIFO) | 最久未更新的库存项先消耗(默认) |
| Newest stock first (LIFO) | 最近更新的库存项先消耗 |
| Smallest quantity first | 可用数量最低的库存项先消耗 |
| Largest quantity first | 可用数量最高的库存项先消耗 |
| Soonest expiry date first | 最早到期的库存项先消耗;无到期日的最后使用 |
跟踪库存的分配
跟踪库存项的分配更复杂:它们不是分配到生产工单,而是必须分配到单个生产输出。在Incomplete Outputs标签中操作——每个生产输出都有一条必须在完工前满足的库存分配需求:
- 每个未完成输出有进度条指示跟踪库存分配状态(如序列号 15 已全部分配、可完工;序列号 14 未全部分配、尚不能完工);
- 分配到所选输出的跟踪库存项会从库存中移除并安装"进"输出装配内部;它们仍存在于数据库中,但不再可用于常规库存操作;
- 示例:库存中有 5 个 "Tracked Part",1 个已分配到生产输出;完成该输出后,库存剩 4 个,1 个被标记为"已安装"在装配内部。
跟踪库存自动分配:Incomplete Outputs标签的Auto Allocate按钮会尝试基于序列号匹配自动分配跟踪库存项——对每个生产输出,寻找具有相同序列号的组件库存项;若找到且可用,即分配到该输出。
消耗库存(Consuming Stock)
分配库存项到工单不会立即将其从库存移除,而是标记为"已分配",只有在被工单"消耗"时才真正移除。在Required Parts标签可看到每行 BOM 的consumed与allocated状态对比。消耗方式有两种:
- 手动消耗:库存分配后即可在工单完成前任意时刻执行,适用于分阶段生产或保持库存实时准确。入口有二:
- Required Parts标签:选中要消耗的 BOM 行项目(单行或多行)→ 点击Consume Stock按钮;
- Allocated Stock标签:选中要消耗的库存分配(单个或多个)→ 点击Consume Stock按钮。
- 自动消耗:工单完成时,所有剩余已分配库存项自动被工单消耗。
退回库存:已消耗项如有需要可在Consumed Stock标签手动退回库存。
完成生产工单
注意:若存在未完结的生产输出,工单不能完成——必须先完成所有生产输出。所有输出完工后,选择Complete Build按钮完成工单本身:该工单上所有已分配的未跟踪库存项将从库存移除并被工单消耗,后续可在 consumed stock 标签中查看。
生产输出(Build Outputs):从创建到完工/报废/取消
*生产输出(Build Output)*是完成工单所预期产出的成品:一个工单可含多个生产输出(不同时间、不同操作员产出);单个输出可以是单件或一批;可关联序列号与批次码。
- Incomplete Outputs 标签:显示当前工单所有未完成/进行中的生产输出;
- Completed Outputs 标签:显示当前工单所有已完成或已报废的输出。
创建生产输出
在Incomplete Outputs标签下点击 "New Build Output" 按钮创建新输出,可配置选项:
| 选项 | 说明 |
|---|---|
| Quantity | 该生产输出创建的物品数量 |
| Serial Numbers | 生成输出的可选序列号(何时可留空见下节) |
| Batch Code | 生成输出的批次码标识 |
| Auto Allocate Serial Numbers | 若选中,已分配序列号的可用跟踪子组件会自动分配到匹配的生产输出 |
序列号输入规则参见 docs/docs/stock/tracking.md。
无序列号创建输出:即使被制造零件标记为可跟踪,创建生产输出时序列号也非必填——这允许先产出批量(如尚不单独序列化的 PCB 批次,或外部工单中尚未序列化的收货项)。若Serial Numbers留空,则按指定Quantity创建单个生产输出,而非每件一个。该输出保持为单一(未序列化的)库存项,可稍后序列化(例如拆分为单件并赋序列号)再完工。注意:若 BOM 含跟踪子组件,创建输出时仍必须提供序列号(见"跟踪生产输出的额外约束")。
完成生产输出
点击某输出关联的 "Complete build output" 按钮即可完工。完工时需选择目标位置与库存状态。标记完成后执行:
- 工单的已完成数量增加所选输出的数量;
- 输出被标记为 "completed",可参与库存操作;
- 分配到该输出的跟踪 BOM 项被安装进该输出。
完工选项:
| 选项 | 说明 |
|---|---|
| Status | 完成输出的库存状态(见 docs/docs/stock/status.md) |
| Location | 输出所在的库存位置(见 docs/docs/stock/index.md) |
| Notes | 与本次完工相关的备注 |
| Accept Incomplete Allocation | 选中后,允许在所需 BOM 项未完全分配时完工跟踪生产输出 |
部分完成(Partial Completion):可指定小于输出总量的数量部分完工——输出被"拆分"为两个;指定数量标记为已完成并计入完成数量;剩余数量保留为未完成输出,供后续完工。注意:已序列化的生产输出不能部分完工。
报废与取消生产输出
报废(Scrap):标记该输出为拒收并移出工单。执行动作:输出被标记为 "rejected" 并移除;工单完成数量不增加;输出不再可用于任何库存操作;可选地将已分配到输出的跟踪 BOM 项安装进被拒输出。
| 选项 | 说明 |
|---|---|
| Location | 报废输出所在的库存位置 |
| Notes | 与本次报废相关的备注 |
| Discard Allocations | 选中后,先移除已安装 BOM 项再报废输出——当安装件可回收、可再用于他处时使用 |
部分报废:指定小于输出总量的数量即可部分报废——输出拆分为两个;指定数量标记为报废(完成数量不增加);剩余保留为未完成输出。已序列化输出不能部分报废。
取消(Cancel):直接删除生产输出并将其彻底移出数据库——适用于该输出物理上不存在(或从未制造)的场景。执行动作:所有已分配库存项退回库存;输出从数据库移除。
生产工单全流程示例
以"创建 10 个 Widget"为例走一遍完整流程(见 docs/docs/manufacturing/example.md):Widget是带跟踪子组件的序列化零件,因此生产输出本身必须序列化——需要为工单生成 10 个独立的生产输出。
- 创建工单:为Widget装配创建新工单(数量 10),表达意图按量 10 组装 Widget;
- 生成生产输出:由于是带跟踪子组件的可跟踪项,生成序列化的生产输出列表;
- 分配未跟踪库存:在Allocate Stock标签将未跟踪库存项分配到工单;
- 分配跟踪库存:将跟踪库存项分配到各个独立的生产输出;
- 完工生产输出:逐一将每个生产输出标记为完成;
- 完成工单:输出全部完工、库存全部分配后,完成生产工单本身。
拆解(Disassembly):把装配拆回组件
已装配的库存项可以按其 BOM反向拆解回组件零件——即构建装配的逆过程:不是消耗组件创建装配,而是把装配拆回其组成组件。典型场景:
- 装配返工或报废,仍可用的组件需退回库存;
- 供应商以单行项目形式发货"捆绑/套件"产品,需拆分后才能单独使用或销售;
- 纠正误建或误收的装配。
前提:该库存项的零件必须标记为装配,且至少定义了一个 BOM 行项目。操作路径:进入库存项详情页 → 在动作菜单中选择Disassemble。这要求用户具备Stock: Add权限,且库存项当前在库存(in stock)。
拆解表单与数量规则
拆解表单按 BOM 行项目数量预填(基于被拆解的装配数量),标记为可消耗(无论 BOM 行本身还是底层零件被标记)或指向虚拟零件的行项目会被排除——这类组件本就不预期作为物理库存跟踪;该排除由 API 强制,此类 BOM 行即使被直接引用也无法提交拆解。
每行可调整字段:
| 字段 | 说明 |
|---|---|
| Quantity | 要生成的组件零件总数量;随顶部Quantity字段变化自动缩放,除非用户已手动编辑 |
| Location | 生成库存项的可选目标位置;未指定则放入被拆解项同位置(或表单顶部指定的默认位置) |
| Status | 生成库存项的可选库存状态;未指定则按默认OK状态创建 |
| Unit Price | 生成库存项上记录的可选采购价;留空则自动计算(见下文) |
若某组件不需要拆出(例如直接报废而非回库),可将该行从表单整体移除;但关联有已安装项的行不可移除。
数量规则:只能拆解库存项的可用数量;序列化库存项数量不可调——它代表单个物理单元,必须整体拆解。原始库存项永不删除:其数量按拆解量扣减以保留可追溯性;即使拆到零数量,该项也保留在数据库(unavailable状态),即使设置了 Delete on Deplete 标志;序列化项不能减到零,此时改为将其标记为Destroyed状态。
已安装项的处理
若被拆解项内部已安装了其他库存项(例如工单中安装的跟踪组件),这些已安装项必须在拆解中被处理:
- 每个已安装项基于组件零件(包括该行允许的替代或变体零件)与 BOM 行匹配;
- 匹配到的已安装项被直接解除安装(uninstalled),而非丢弃重建——保留原始库存项及其跟踪历史、批次码、采购价;
- 匹配 BOM 行的需求量减去已安装项已覆盖的数量;仅为剩余数量创建新库存项——若已安装项完全覆盖需求,则该行不创建新库存项;
- 未匹配到任何所选 BOM 行的已安装项仍会被解除安装(不能"安装"在更小或已不存在的父项中),但其数量不会从任何行中扣减。
由于已安装项不能部分处理,含已安装项的库存项必须整体拆解——若当前有已安装项,部分拆解会被拒绝。拆解表单会对每个匹配的 BOM 行显示已安装项数量,并在单独的警告面板中列出"遗留"的未匹配已安装项。
自动成本分摊与可追溯性
自动成本分摊:若原始库存项有采购价且未显式填写Unit Price,InvenTree 会尝试将成本分摊到新生成的组件:
- 总成本(单位采购价 × 拆解数量)按各组件零件现有定价数据(整体价的最低/最高平均值,见 docs/docs/part/pricing.md)加权分摊到各行;
- 若并非所有行都有定价数据,则按单位在所有生成单位间均摊;
- 成本只分摊到新建的库存项——匹配到的已安装项保留其自身采购价,完全排除在分摊之外;
- 若任一行有用户显式填写的Unit Price,则整体跳过自动成本分摊,价格仅按显式设置应用。
可追溯性:拆解生成完整审计轨迹——原始库存项的跟踪历史增加Disassembled into components记录;每个新建组件库存项收到引用原始项的Created from disassembly跟踪记录;原始库存项的批次码与来源采购订单直接复制到每个生成组件;若原库存项由工单生成,则该工单不能直接复制到新组件(因为组件并非该工单实际制造)——它作为引用记录在Created from disassembly跟踪条目中。
强制限制(拆解时强制执行):零件必须标记为装配;库存项必须当前在库存(不能被销售订单分配、安装在其他装配中、或已完全消耗);至少选择一条 BOM 行;拆解数量不能超过可用数量;序列化项必须整体拆解;每个 BOM 行在单次拆解操作中只能被引用一次;所选 BOM 行必须是该零件的有效行项目;含已安装项必须整体拆解。
采购捆绑件:部分供应商只以单一"套件"产品销售一组组件,而非单独的可采购行项目。可将该捆绑建模为装配零件,作为单个库存项采购收货,之后再拆解为独立组件——采购价与追溯数据会自动分摊到生成组件(设置方法另见 docs/docs/purchasing/purchase_order.md)。
外部制造:委外生产的工单管理
当某些组件或装配需要委外给外部供应商制造时,InvenTree 提供了管理外部制造流程的简洁界面。在 InvenTree 语境下,*外部生产工单(external build order)*是向外部供应商提出制造特定装配或组件的请求,它关联特定 BOM 与工单,确保制造出正确的组件。
前置要求(Extra Requirements):
- 被制造的"装配"零件必须是*可采购(purchaseable)*零件,并关联有指向该外部供应商的Supplier Part(见 docs/docs/purchasing/supplier.md),以保证外部工单只能为可向该供应商采购的零件创建;
- 外部供应商在 InvenTree 中必须被标记为 "manufacturer"。
功能开关:外部制造默认关闭,需启用BUILDORDER_EXTERNAL_BUILDS全局设置(见 docs/docs/settings/global.md)。
外部工单流程
- 创建工单:创建新工单,指定装配零件与数量;创建时选择 "External" 选项表明这是外部工单。工单详情页会显示外部工单标识,Incomplete Outputs面板也会提示该工单关联外部采购订单、输出将在采购项收货时生成。
- 创建采购订单(Purchase Order):外部 采购订单 是工单与incoming货物(履行工单的货物)之间的桥梁。对负责制造的外部供应商创建 PO(前提已存在关联装配零件与该供应商的 supplier part)。
- 向 PO 添加行项目:添加装配零件到 PO 时,务必将行项目的 "Build Order" 字段设为前面创建的外部工单——这一关联使 InvenTree 在收货时自动把收货项分配到工单。
- 收货:按常规流程对 PO 收货。收货后,收到的物品自动标记为外部工单的 "build outputs";若装配零件可跟踪,收货时可选填序列号,或先无序列号收货、稍后再序列化(与内部工单"无序列号创建输出"逻辑一致)。收货项随即登记为该外部工单的未完成输出。
库存分配:外部工单的库存分配与常规工单流程一致。外部制造商可能提供完成工单所需的全部组件,也可能只负责一部分——两种情况下都应确保正确的库存项被分配到外部工单;部分分配时,用户只需选择应包含在订单中的库存项。
履行(Fulfillment):外部工单的履行流程与标准工单不同——不是手动创建生产输出,而是在关联 PO 项收货时生成输出。工单与采购订单流程紧密联动,从开始到结束覆盖外部制造的进度跟踪、库存分配与物料准时交付管理。
小结
InvenTree 的制造系统以 BOM 为定义层、生产工单为执行层、库存分配为资源层、拆解为逆向层:BOM 行项目通过Quantity / Attrition / Setup Quantity / Rounding Multiple / Piece Count五个参数驱动需求数量计算(part/models.py#L4304-L4349 中的get_required_quantity与 docs/docs/manufacturing/required.md 的公式完全一致),分配与消耗把"预留"与"实际扣减"解耦为两阶段操作,跟踪/未跟踪双轨制让序列号组件能够精确"安装"进具体生产输出。配合可消耗/可选/替代/继承四类 BOM 行项目、BOM 校验和机制、外部制造与库存拆解能力,可以覆盖从简单组装到多供应商委外、从正向生产到逆向拆套件的完整制造场景。相关实现集中在 build/models.py(Build/BuildLine/BuildItem数据模型)与 part/models.py(BOM 模型与需求计算),可作为进一步深入源码的入口。
【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考