certflow.services.cert_numbering_policy module

合格证编号策略(配置驱动)——步骤 6:编号时机与编码模式。

对应蓝图 §4.4:把「编号时机」与「编码模式判定」从硬编码抽到 config.yaml

  • certificate.numbering.timing``on_demand``(默认,查询页手动触发) / ``on_import``(写入 Certificate 时对未编号记录自动编号)。

  • certificate.numbering.modes:按 when_field 的关键词匹配 → number_model, 替代原先硬编码的 number_model = 0``(复用 ``printer.numbering_modes 数值)。

  • certificate.numbering.range_regex:范围编码解析正则(如 V2603121XL---125XL → 起止流水),供逐台展开 / 校验。

本模块的核心判定函数为**纯函数**(resolve_number_model / parse_number_range), 不依赖配置加载与 Qt,可独立单测;get_* 系列为读取配置的薄封装。

设计原则(与总原则一致):默认配置保持现状语义——timing 默认 on_demandmodes 默认为空(一律回退 default_mode=0),即与既有行为零差异; 启用只需改 YAML,无需改代码。

certflow.services.cert_numbering_policy.resolve_number_model(record, modes, default=0)[源代码]

按配置的编码模式规则判定 ``number_model``(纯函数)。

规则按顺序匹配:某规则的 when_field``(或兼容键 ``field)对应字段值包含 keywords 中任一关键词时,返回该规则的 mode;全部未命中返回 default

参数:
  • record (Any) -- SalePlan / Certificate ORM 对象,或字段字典。

  • modes (list[dict] | None) -- 模式规则列表(每项含 when_field / keywords / mode)。

  • default (int) -- 未命中任何规则时的默认编码模式。

返回:

判定出的 number_model 数值。

返回类型:

int

certflow.services.cert_numbering_policy.resolve_sn_kks_position(record, modes, default='')[源代码]

按配置的编码模式规则判定双编码位置约定(纯函数,对齐 VBA ar(2,8))。

resolve_number_model 共用命中规则:某规则的 when_field 对应字段值 含 keywords 中任一关键词时,返回该规则的 sn_kks_position;全部未命中 返回 ``default``(空串=默认不互换)。

参数:
  • record (Any) -- SalePlan / Certificate ORM 对象,或字段字典。

  • modes (list[dict] | None) -- 模式规则列表(每项含 when_field / keywords / sn_kks_position)。

  • default (str) -- 未命中时的默认位置约定(空串)。

返回:

双编码位置约定("B12单元格为产品编号,B13单元格为KKS编码" 等,

或空串)。

返回类型:

str

certflow.services.cert_numbering_policy.parse_number_range(code, regex=None)[源代码]

解析范围编码的起止流水(纯函数)。

V2603121XL---125XL(121, 125)V2604520Y-524Y(520, 524); 非范围编码返回 None

参数:
  • code (str) -- 完整编码字符串。

  • regex (str | None) -- 自定义解析正则(需含命名组 start / end);None 时用内置逻辑。

返回:

(起始流水, 结束流水);无法解析返回 None

返回类型:

tuple[int, int] | None

certflow.services.cert_numbering_policy.get_military_prefix()[源代码]

读取军工模式前缀(mode:7,无 V+YYMM 的军工前缀,如 "JG")。

默认 "JG";军工三位流水模式自动编号时用此前缀 + 三位流水。

返回类型:

str

certflow.services.cert_numbering_policy.parse_military_code_meta(code)[源代码]

解析军工三位流水区间串(mode:7,无 V+YYMM 前缀)。

JG001A-JG100A``{"prefix": "JG", "seq_start": 1, "seq_end": 100, "suffix": "A",

"quantity": 100}``;单台 JG001A → seq_end==seq_start。

军工码特征:前缀非 V 且其后直接是 3 位以上流水(无 4 位年月), 与标准 V{YYMM}{流水} 区分。供 G2 逐台展开写入 Certificate。

参数:

code (str) -- 军工产品编号区间串(SalePlan.product_code / Certificate.product_code_range)。

返回:

含 prefix/seq_start/seq_end/suffix/quantity;无法解析返回 None。

返回类型:

dict | None

certflow.services.cert_numbering_policy.parse_product_code_meta(code)[源代码]

解析产品编号区间串的元信息(前缀/年月/起止流水/台数)。

V2604520Y---524Y``{"prefix": "V", "ym": "2604", "seq_start": 520, "seq_end": 524,

"suffix": "Y", "quantity": 5}``;单台 V2604520Y → seq_end==seq_start。

供 G2 在 create_certificates 中将区间串拆填入 Certificate.product_code_range / product_code_prefix / product_code_ym / product_code_seq_start / product_code_seq_end / ``quantity``(本批台数 = seq_end - seq_start + 1)。

参数:

code (str) -- 产品编号区间串(SalePlan.product_code / Certificate.product_code_range)。

返回:

含 prefix/ym/seq_start/seq_end/suffix/quantity;无法解析返回 None。

返回类型:

dict | None

certflow.services.cert_numbering_policy.get_numbering_timing()[源代码]

读取编号时机:on_demand``(默认)或 ``on_import

返回类型:

str

certflow.services.cert_numbering_policy.get_issue_date_source()[源代码]

读取出厂日期年月来源(BUG-006 J,配置驱动)。

  • sync_numbering_ym``(默认):出厂日期年月同步产品编号年月 (``product_code_ym,如 V2607…2026.07)。

  • current_ym:出厂日期取当前年月(datetime.now())。

返回:

sync_numbering_ym``current_ym``(未知值回退默认)。

返回类型:

str

certflow.services.cert_numbering_policy.get_number_model(record)[源代码]

certificate.numbering.modes 判定记录的 number_model

默认(modes 为空)回退 certificate.numbering.default_mode``(默认 0), 与既有硬编码 ``number_model = 0 行为一致。

参数:

record (Any)

返回类型:

int

certflow.services.cert_numbering_policy.get_sn_kks_position(record)[源代码]

certificate.numbering.modes 判定记录的 sn_kks_position

默认(modes 为空)回退空串(默认不互换)。与 get_number_model 共用命中 规则,使双编码位置约定随客户/关键词一并确定(对齐 VBA ar(2,8))。

参数:

record (Any) -- SalePlan / Certificate ORM 对象,或字段字典。

返回:

双编码位置约定("B12单元格为产品编号,B13单元格为KKS编码" 等,

或空串)。

返回类型:

str

certflow.services.cert_numbering_policy.get_range_regex()[源代码]

读取范围编码解析正则(未配置返回 None → 用内置默认)。

返回类型:

str | None

certflow.services.cert_numbering_policy.get_no_cert_categories()[源代码]

读取免编号品类关键词列表(默认空列表)。

返回类型:

list[str]

certflow.services.cert_numbering_policy.is_auto_calc_dn_pn()[源代码]

自动计算口径压力开关(§5.7.2-E / 维度8,对齐 VBA G11)。

默认 True(现状:打印前自动从型号解析口径/压力并预填); certificate.numbering.auto_calc_dn_pn: false 时关闭自动推算, 仅用已存值、不就口径/压力缺失弹补充对话框。

返回:

是否启用自动计算口径压力。

返回类型:

bool

certflow.services.cert_numbering_policy.is_yellow_skip_enabled()[源代码]

读取是否按源表黄底(65535)跳过编号(默认 False)。

返回类型:

bool

certflow.services.cert_numbering_policy.derive_needs_numbering(record)[源代码]

导入期派生是否需要编号(对齐 VBA 黄底跳过语义,维度16/H)。

返回 False``(不需要编号)当满足任一条件: - 品类/产品名/型号命中 ``no_cert_categories 关键词(螺栓/密封圈等免出证铭牌件); - yellow_skip_enabled 且背景色含黄底(65535)。

其余返回 True;历史 NULL 视为需要编号(兼容旧数据)。

参数:

record (Any) -- SalePlan ORM 对象或字段字典(需含 category / product_name / product_model / _background_colors)。

返回:

是否需要编号。

返回类型:

bool