certflow.services.bom_part_classifier module

BOM 零件归类器(阶段 C:报告生成时按生产令号带出主材)

list[BomMaterial] 按「零件名称 → 报告主材位」关键词映射归类为 {主材位: [BomMaterial, ...]} + 待核对明细 [BomMaterial, ...]

纯逻辑、无 IO、可单测;关键词映射由 config 驱动(见 report.bom_report), 不在代码里硬编码,便于用户维护(阶段 C 原则 5 / §3)。

归类规则(详见 docs/PATCH_LOG.md 补丁 14「阶段 C:BOM 材质集成到报告生成」): - 遍历 part_name,按 part_keywords 优先级(自上而下)匹配**首个命中**关键词

→ 归入对应主材位;优先级保证「阀体盖」不会误归 body(C2.3)。

  • 同一主材位命中多个零件(多对一)时按 multi_match_strategy: - first → 取 seq 最小(首条)落主材位; - detail → 全部进待核对明细,不自动填; - ``same_grade``→ 牌号完全一致(含均无牌号,无歧义)取首条落主材位,

    牌号不一致(有歧义)才全部进待核对明细(默认,兼顾「避免错误回填」 与「同牌号零件正常填入」,如阀体+阀盖均为 35 应填阀体而非丢明细)。

  • 未命中任何关键词的零件 → 进待核对明细(fallback_to_detail 开关)。

class certflow.services.bom_part_classifier.BomClassifyResult(slots=<factory>, detail=<factory>)[源代码]

基类:object

BOM 归类结果。

参数:
slots

主材位 → 命中该位的 BOM 零件列表(已按 seq 排序,每个位 0~N 条)。

Type:

dict[str, list[Any]]

detail

待核对明细(未命中关键词 + 多对一被剔除的零件),不落报告主材位。

Type:

list[Any]

slots: dict[str, list[Any]]
detail: list[Any]
certflow.services.bom_part_classifier.classify(parts, cfg=None)[源代码]

把 BOM 零件列表按 config 关键词映射归类为主材位 + 待核对明细。

入参 parts 为鸭子类型:只需具备 part_name``(str)、``seq``(int,可选)、 ``material_grade``(可选)属性即可(``BomMaterial 或测试桩均可)。

参数:
  • parts (list[Any]) -- BOM 零件列表(同生产令号,已按 seq 排序或无序均可)。

  • cfg (dict[str, Any] | None) -- 归类配置(含 part_keywords / fallback_to_detail / multi_match_strategy);缺省回退 DEFAULT_BOM_REPORT_CFG

返回:

BomClassifyResult:slots 为主材位→零件列表(每个位已 <=1 条,除非 strategy=first),detail 为待核对零件列表。

返回类型:

BomClassifyResult

示例

>>> class P:  # 测试桩
...     def __init__(self, name, seq=0, grade=""):
...         self.part_name = name; self.seq = seq; self.material_grade = grade
>>> r = classify([P("阀体A", 1, "WCB"), P("法兰盘", 2, "Q235")])
>>> r.slots["body"][0].material_grade
'WCB'
>>> [p.part_name for p in r.detail]
['法兰盘']