Files
InboundVerify/docs/2026-08-04-实到按扫描日提取修正-design.md
2026-08-04 17:04:03 +08:00

100 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实到按「归属日当天扫描」提取修正 · 设计方案
> 日期2026-08-04
> 分支:`refactor/undelivered-by-expected`
> 状态:待审核
> 目标:把差缺对比中的「实到货物数据」提取口径修正为「目标归属日当天实际扫描」,与业务口径对齐
---
## 一、业务口径(与业务部门对齐后的最终陈述)
差缺对比在**归属日期业务日期D** 这一维度上进行:
1. **应到货物数据**:取**归属日 = D** 的应到批次(批次归属日 = 出库大头日,已实现为 `expected_record.batch_out_date`)。
- 站点"提前下载"(韵达固定提前 1 天、个别站点偶发提前 1~2 天)不影响取数——提前提交的批次按其**出库日**自动归属到 D 日。
2. **实到货物数据**:取 **D 日当天实际扫描**的记录(`actual_record.scan_time::date = D`)。
- "当天实际扫描"指扫描行为发生在 D 日,与运单属于哪个批次无关。
3. 对取到的双方数据按运单号进行差缺对比。
**关键原则**:说"同一天"指的是**归属日期**,不是数据产生/下载的日期。
---
## 二、现状问题
| 环节 | 现状 | 问题 |
|------|------|------|
| 应到提取 | `WHERE batch_out_date = D`(应到驱动入口) | ✅ 已对齐 |
| 实到提取 | `WHERE waybill_no = ANY(批次运单)`**无扫描日过滤** | ❌ 跨日扫描混入 |
**实证案例(安能 08-03**
- 08-03 实到下载文件 = 355 行,全部扫描于 08-03获取层正确
- 今天 15:03 另有一次 08-04 实到下载176 行),其中 **6 件扫描于 08-04、运单属于 08-03 批次**
- 对比 SQL 按运单号取实到 → 08-03 实到 = 350当天+ 6次日= **356**,与"当天实际扫描"定义不符。
根因:`db_compare.py` 三处取实到的 SQL 只按运单号匹配,未按扫描日过滤。
---
## 三、修正方案
### 3.1 实到提取统一加扫描日过滤
| 函数 | 用途 | 改动 |
|------|------|------|
| `compare_site_outdate` | 汇总报表(应到驱动,主入口) | 实到 SQL 增加 `AND scan_time::date = %s`D |
| `compare_site_date` | 实到驱动对照模式 | 同上加过滤Step 4Step 1 锚点本已按当天扫描) |
| `compare_site_batch` | 单批次审计(无日期语境) | **保持全量**docstring 注明"全批次全量实到,不受日期过滤" |
修正后统计口径:
```
应到 = 归属日 D 的批次全量应到(交接件数,不变)
实到 = 批次运单 ∩ 扫描日 = D 的扫描件数(非 SF 子单号去重 / SF 行计数,不变)
未到 = max(0, 应到 实到)
```
### 3.2 边界语义确认
| 场景 | 修正后行为 |
|------|-----------|
| 批次 D 的件扫描于 D+1迟到件 | 不计入 D 日实到 → D 日计"未到";该件属 D+1 日实到(其运单若在 D+1 批次内则正常核销) |
| 批次 D 的件提前扫描于 D1 | 不计入 D 日实到 |
| 当天扫描但运单不在 D 日应到批次(孤儿) | 不入 D 日比对(属其他归属日批次,与现状一致) |
| 一件多扫(同日) | 非 SF 按子单号去重SF 行计数(不变) |
### 3.3 不做的事(范围外)
- 下载层各站查询日期口径已验证正确08-03 四站文件 100% 当天扫描),**不改下载层**。
- 获取层"日期回读校验"(韵达/中通/顺心选完日期后未校验输入框值)另立改进项,不阻塞本次。
- 百世为站级日聚合(已扫/应扫,固定当天),不涉及。
---
## 四、涉及改动清单
| 文件 | 改动 |
|------|------|
| `inbound_verify/db_compare.py` | `compare_site_outdate``compare_site_date` 两处实到 SQL 加 `AND scan_time::date = %s``compare_site_batch` docstring 注明口径 |
仅此一处文件、两处 SQL + 一处注释。
---
## 五、验证计划
1. **重跑 08-03 全站汇总**`build_full_report("2026-08-03")`),核对:
- 安能实到 356 → **350**= 355 当天 5 孤儿,或 350 匹配批次),未到件数相应变化;
- 顺心 / 中通 / 韵达先实查 DB 中是否有跨日扫描匹配各自 08-03 批次,预期无变化(各自文件全为 08-03 扫描)。
2. **明细抽查**:差缺明细表内各运单的"已到单号"扫描日全部 = 08-03。
3. **口径复核**:安能 6 件 08-04 扫描确认不再出现在 08-03 报表实到/已到明细中。
---
## 六、决策记录(待确认)
- ✅ 实到 = 归属日当天实际扫描(`scan_time::date = D`),跨日扫描不计入。
-`compare_site_batch` 保持全批次全量(审计工具语义,不按日过滤)。
- ⏳ 其余边界(迟到件计"未到"的呈现、获取层日期回读校验)按上表执行,如有异议请指出。