certflow.services.cert_log_service module

合格证打印日志服务

从 PrintView 迁移出来,负责打印后数据持久化: - PrintLog 51 字段构建与写入 - Certificate 打印状态更新与回填 - SN/KKS 推导、年月提取等数据清理

对标 VBA: 将打印内容添加到数据库() + 取消自动筛选后静默保存当前工作簿

certflow.services.cert_log_service.is_duplicate_print_record(session, log)[源代码]

打印存库重复检测(§5.7.2-C / 维度11,对齐 VBA「大连大高重复跳过存库」)。

仅当配置 certificate.print_duplicate_check.enabled=true 且当前打印记录的 订货单位(DingHuoDanWei)命中 customers 关键词时启用:在 PrintLog 表中 查找与当前记录在 compare_fields 上字段值相等数 ≥ threshold 的既有记录, 命中则返回 True(调用方跳过新增 PrintLog 行,仅更新合格证清单/ Certificate 状态)。

默认配置 enabled=false → 永远返回 False,零差异(所有客户照常落库)。

参数:
  • session (Session) -- SQLAlchemy 会话。

  • log (PrintLog) -- 已构建但未落库的 PrintLog 对象(取 DingHuoDanWei / compare_fields 值)。

返回:

是否应跳过落库(True=重复,跳过)。

返回类型:

bool

class certflow.services.cert_log_service.CertLogService(session, certificate_id=None)[源代码]

基类:object

打印日志保存服务

参数:
  • session (Session)

  • certificate_id (int | None)

static derive_sn_kks(serial)[源代码]

从完整编码推导 SN(短编号)和 KKS(完整编码)

  • SN = 去掉中间4位年月,如 "V2512123Y" → "V123Y"

  • KKS = 完整编码原样返回

参数:

serial (str)

返回类型:

tuple[str, str]

static derive_manufacture_ym(serial)[源代码]

从完整编码提取出厂年月,例如 "V2512123Y" → (25, 12)

参数:

serial (str)

返回类型:

tuple[int | None, int | None]

get_cert_data()[源代码]

从 Certificate 表获取当前批次的业务数据,关联 SalePlan 获取销售信息。

返回:

合格证及关联销售计划的业务数据字典。

返回类型:

dict[str, Any]

get_sn_dup_count(sn)[源代码]

查询 SN 重复条目数,格式 "重复条目数:02"

参数:

sn (str)

返回类型:

str

build_print_log(serial, data, printer_name, now=None)[源代码]

构建单条 PrintLog 记录(51字段对齐 Access SignTb)。

参数:
  • serial (str) -- 产品完整编码。

  • data (dict[str, Any]) -- 表单/打印数据字典。

  • printer_name (str) -- 打印机名称。

  • now (datetime | None) -- 打印时间戳,为 None 时使用当前时间。

返回:

已构建但尚未提交的打印日志对象。

返回类型:

PrintLog

update_certificate_status(data, printer_name, now=None)[源代码]

更新 Certificate 打印状态,用表单数据覆盖(以实际打印内容为准)。

参数:
  • data (dict[str, Any]) -- 表单/打印数据字典。

  • printer_name (str) -- 打印机名称。

  • now (datetime | None) -- 打印时间戳,为 None 时使用当前时间。

返回类型:

None

get_recent_logs(limit=200)[源代码]

获取最近的打印日志

参数:

limit (int) -- 返回条数上限,默认 200

返回:

PrintLog 列表,按 id 降序排列

返回类型:

list[PrintLog]

query_logs(filters=None, limit=2000)[源代码]

按条件查询打印日志(参数化,防注入)

支持按日期区间(hgz_PrintTime 或 JiHuaRiQi)与产品型号模糊搜索。

参数:
  • filters (dict | None) -- 过滤条件字典,可选键: date_field: "hgz_PrintTime"(默认) 或 "JiHuaRiQi" date_from: datetime 起始(含) date_to: datetime 结束(含) model_keyword: 产品型号模糊关键字(LIKE,不区分大小写)

  • limit (int) -- 返回条数上限,默认 2000

返回:

PrintLog 列表,按 id 降序排列

返回类型:

list[PrintLog]

auto_save(serials, data, printer_name)[源代码]

逐台保存 PrintLog + 更新 Certificate,统一提交。

参数:
  • serials (list[str]) -- 产品编码列表(逐台打印)。

  • data (dict[str, Any]) -- 表单/打印数据字典。

  • printer_name (str) -- 打印机名称。

返回类型:

None

certflow.services.cert_log_service.backfill_dual_codes_if_fully_printed(session, certificate_id)[源代码]

G3: 打印后回填 SalePlan 的 sn_code/kks_code。

设计意图(§11.4.1):SN/KKS 为「打印后记录」字段——编号阶段不再派生, 打印时逐台由 product_code_range 正则拆分得到短码 SN(如 V520Y)/长码 KKS(如 V2604520Y) 写入 PrintLog;SalePlan 的 sn_code/kks_code 仅在 该计划全部台数(quantity)对应的 PrintLog 均已写入时才回填。

G5 补充触发点:SalePlan.fully_shipped``(全部台数发完,等价 ``shipping_status='已发货')为真时也执行回填——满足「全部发完才回填」 的语义,且不必等到逐台 PrintLog 全部落库。

回填值由**实际打印的编号**推导(补丁36 修正):优先取 Certificate.product_code_range``(用户可能手动修订过编号,打印出的 serial 即来自此);仅在空时回退 ``SalePlan.product_code。 一般件 kks_code=长 V 码区间串、sn_code=剥 YYMM 短码;电厂件已录入的真 KKS(不以 V 开头)受保护不被覆盖。

参数:
  • session (Session) -- SQLAlchemy 会话

  • certificate_id (int) -- 本次打印关联的 Certificate.id

返回:

是否执行了回填(False 表示尚未全部打印/发完或无需回填)

返回类型:

bool