Files
zkxw/docs/superpowers/specs/2026-07-29-storage-release-hide-voided-related-design.md
T

6.2 KiB
Raw Blame History

入库放行审核 · 关联单据无效/全作废时列表隐藏

日期:2026-07-29
状态:已实现
模块:细胞存储 / 质检 → 入库放行审核
关联:

  • docs/superpowers/specs/2026-05-23-storage-release-review-design.md
  • docs/superpowers/specs/2026-07-16-storage-release-review-tabs-design.md
  • docs/superpowers/specs/2026-07-29-storage-release-pending-ready-filter-design.md
    界面模式:P22(审核列表)
    参考:backend/app/crud/storage_release_review.py · apply_exclude_inactive_protocol_filter(生产工单)

1. 背景与目标

现状

「入库放行审核」列表在样本接收通过后即生成记录,并按 Tab / 就绪过滤展示。关联的采集/捐赠协议、入库质检工单、入库生产工单作废后,审核行仍可能出现在待审核/已审核列表中。

目标

列表(待审核 + 已审核)在满足下列任一条件时不展示该入库放行审核记录:

  1. 关联协议处于无效态(yzf 已作废 或 sdfq 属地废弃)
  2. 该样本入库质检工单存在,且全部为作废(yzf)
  3. 该样本入库生产工单存在,且全部为作废(yzf)

分页与 total 与过滤一致。

范围外

  • 不改详情、单条/批量审核、入库接口(直链仍可打开与操作)
  • 不软删 biz_storage_release_review 行
  • 不改表结构、菜单、筛选项 UI
  • 不改「展示全部待审核」就绪过滤语义(作废隐藏为常驻列表规则,与复选框无关)
  • 出库/临时工单不参与本规则

2. 需求确认记录

维度 决定
协议无效态 yzf + sdfq(与 INACTIVE_PROTOCOL_STATUSES 一致)
作用 Tab 待审核 + 已审核(全局列表)
多张工单 该侧「有工单且全部 yzf」才因该侧隐藏;混有非作废则不因该侧隐藏
相关工单范围 仅入库:质检 qc_biz_type=inbound;生产 work_order_type=inbound
无入库工单 不因该侧触发隐藏
实现效果 仅列表隐藏;详情/审核/入库 API 不变
实现路径 方案 1:list_reviews 常驻 SQL 过滤

3. 隐藏语义(精确)

关联键:审核行 tenant_no + sample_code(工单);协议用审核行 protocol_id + reception_source。工单均要求 del_flag=0。

3.1 协议无效 → 隐藏

reception_source 条件
cell_storage(或缺省按细胞存储) 存在有效采集协议 id = protocol_id,且 protocol_status IN ('yzf','sdfq')
research_donation 存在有效捐赠协议 id = protocol_id,且 donation_status IN ('yzf','sdfq')

protocol_id 为空:不因协议侧触发隐藏(无法判定无效协议)。

3.2 入库质检全作废 → 隐藏

同时满足:

  1. 存在至少一张:同租户、del_flag=0、sample_code 匹配、qc_biz_type = 'inbound' 的质检工单
  2. 不存在任何一张:同上条件且 work_order_status != 'yzf'(即全部为 yzf)

3.3 入库生产全作废 → 隐藏

同时满足:

  1. 存在至少一张:同租户、del_flag=0、sample_code 匹配、work_order_type = 'inbound' 的生产工单
  2. 不存在任何一张:同上条件且 work_order_status != 'yzf'

3.4 组合

列表可见 ⇔ 非(协议无效 OR 入库质检全作废 OR 入库生产全作废)

与 readyForReviewOnly / reviewPhase 等条件叠加(AND)。作废隐藏始终应用,无查询参数开关。

说明:就绪过滤曾将单侧仅 yzf 视为「该侧已完成」;若该侧工单全部为 yzf,本规则会隐藏整行,优先于「就绪可见」。

3.5 样例

场景 列表
协议 sxz,无入库质检/生产工单 可见
协议 yzf 或 sdfq 隐藏
入库质检:1×ywc + 1×yzf;生产无;协议有效 可见(质检侧非全作废)
入库质检:全部 yzf;协议有效 隐藏
入库生产:全部 yzf;质检有 ywc;协议有效 隐藏
仅出库质检作废,无入库质检 不因质检侧隐藏

4. API 与实现

4.1 接口

沿用 GET /web/admin/storage-release-reviews。不新增查询参数;过滤在 list_reviews 内常驻。

详情 GET .../{id}、审核、入库接口行为不变。

4.2 SQL 形态(示意)

在现有租户 / 软删 / 数据权限 / Tab / 关键词等条件之后增加:

NOT ( protocol_inactive OR qc_inbound_all_void OR production_inbound_all_void )

各分支用 SQLAlchemy exists() + eq_unicode(sample_code)(与现有质检/生产关联一致)。协议侧按 reception_source 分支关联 BizCollectionProtocol / BizResearchDonation,状态集复用 INACTIVE_PROTOCOL_STATUSES。

过滤必须在 COUNT 与分页之前应用。

4.3 前端

列表页无需改筛选项;请求参数不变。总数随后端过滤自然正确。

5. 改动面

层 路径 变更
Backend CRUD backend/app/crud/storage_release_review.py list_reviews 增加协议无效 / 入库质检全作废 / 入库生产全作废排除;可抽 exists 辅助函数
Backend tests backend/tests/test_storage_release_review_hide_voided.py(新建) 覆盖样例与叠加过滤

不改:API 路由签名、前端页面与 API 类型、表结构、详情 enrichment。

6. 测试要点

  1. 协议 yzf/sdfq → 待审核与已审核均不出现;sxz 且工单未全作废 → 可出现。
  2. 入库质检全 yzf → 隐藏;混有非 yzf → 不因质检隐藏。
  3. 入库生产全 yzf → 隐藏;work_order_type=outbound 作废不影响。
  4. 质检 qc_biz_type=temporary/outbound 作废不影响。
  5. 无入库工单 + 协议有效 → 可见。
  6. total / 分页与过滤一致。
  7. 直链详情仍可按 id 查询(不在本需求改接口时可只测列表;详情行为保持现状即可)。

7. 方案取舍(记录)

方案 结论
1. list_reviews 常驻 SQL 过滤 采用
2. 前端拉全量再滤 拒绝(分页/total 错误)
3. 作废钩子软删审核行 拒绝(可逆与钩子成本;客户接受仅列表隐藏)