Files
InboundVerify/docs/韵达安能计算逻辑梳理.md
Misaka 8f79cbc5d7 修复安能实到日期设定 + 站点统计口径重构
- site_anneng.py: set_scan_date 改用 execCommand 全选替换+回车(修复 Ant DatePicker 受控组件未写入导致实到下成当天); wait_scan_form_ready 增加 settle 与 DatePicker 预热,消除首设竞态
- expected_undelivered.py: 应到口径改交接件数、实到改单号去重、未到明细列已到单号(不再编子单号),百世排除
- docs: 补充站点统计逻辑审查报告与韵达/安能计算逻辑梳理
2026-07-19 13:16:01 +08:00

125 lines
7.1 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.
# 韵达 / 安能 应到未到计算逻辑梳理(基于 expected_undelivered.py 重构版代码)
> 用途:供审核两站「应到件数 / 实到件数 / 未到件数」的实现逻辑与关联键。
> 代码基准:`InboundVerify/expected_undelivered.py`(重构版)。行号对应本次读取。
---
## 、两站共用的计算骨架process 函数,第 134216 行)
无论韵达还是安能,最终都走同一个 `process(name)`
1. 读应到表 + 实到表(第 148149 行)。
2. 应到表按关联键列去重、保留首条(第 152153 行)。
3. **应到件数** = 应到表「交接件数」之和(第 158168 行)。
4. **实到件数** = 实到表单件号列的**全局去重数**(第 176177 行,`act_pieces = sum(len(s) for s in arrived.values())`)。
5. 逐运单比较:实到扫到数 `<` 应到件数 的运单,才进未到明细(第 183201 行)。
6. **未到件数** = `max(0, 应到件数 实到件数)`(第 210 行)。
两站差异**只在配置**(关联键列、单件号列不同),算法完全一致。
---
## 一、韵达
### 1.1 配置STATIONS 第 106115 行)
| 配置项 | 值 | 含义 |
|---|---|---|
| exp应到文件 | `韵达-应到货物数据.xlsx` | 源 |
| act实到文件 | `韵达-实到货物数据.xlsx` | 源 |
| exp_qty | `交接件数` | 应到件数的取值列 |
| exp_wb | `运单号` | 应到表去重键 **+ 关联键** |
| exp_jd | `交接单号` | 未到明细展示字段 |
| arrived_pieces | `arrived_pieces_by_cols("主单号", "子单号")` | 实到解析 |
|  ├ wb_col | `主单号`(实到表) | 实到侧**关联基号**列 |
|  └ piece_col | `子单号`(实到表) | 实到侧**单件号**列 |
### 1.2 两套表的字段角色
- **应到表**`运单号`(去重+关联)、`交接件数`(该单应到件数)、`交接单号`(展示)。
- **实到表**`主单号`(关联基号,须与应到`运单号`同值域)、`子单号`(每件货物的单号,一个单号=一件)。
### 1.3 关联Join条件
```
应到表.运单号 == 实到表.主单号
```
机制:`arrived_pieces_by_cols` 以「主单号」为 key 建 dict第 7681 行);`process` 第 185 行 `arrived.get(wb)` 用**应到运单号 wb** 去查该 dict。两列值必须相等才对得上。
### 1.4 计算口径
- 应到件数 = Σ 交接件数(按运单号去重后)。
- 实到件数 = 实到表「子单号」全局去重数(不同主单号下即使子单号文本相同也只计一次)。
- 未到件数 = `max(0, 应到 实到)`
- 未到明细(每行一个短少运单):`交接单号 | 运单号 | 总件数(=应到件数) | 已到单号1..k`
「已到单号1..k」= 该主单号下所有子单号排序后填入k = 实际扫到件数(第 199200 行)。
仅当「实到扫到数 < 应到件数」才列入(第 187188 行 `arrived_cnt >= n` 跳过)。
### 1.5 当前数据状态实测2026-07-19 10:50
- 应到运单数 **57**,实到基号数 **58**,交集命中 **57**
- 应到件数 = 140实到单号去重 = 141
- 样本:`应到 617936212` == `实到主单号 617936212`,完全对齐
- **结论:韵达关联键现已对齐,逻辑可正确产出结果。**(此前 2/57 为旧数据,已失效)
---
## 二、安能
### 2.1 配置STATIONS 第 116125 行)
| 配置项 | 值 | 含义 |
|---|---|---|
| exp应到文件 | `安能-应到货物数据.xlsx` | 源 |
| act实到文件 | `安能-实到货物数据.xlsx` | 源 |
| exp_qty | `交接件数` | 应到件数取值列 |
| exp_wb | `运单号` | 应到表去重键 **+ 关联键** |
| exp_jd | `交接单号` | 未到明细展示字段 |
| arrived_pieces | `arrived_pieces_by_cols("所属单号", "扫描单号")` | 实到解析 |
|  ├ wb_col | `所属单号`(实到表) | 实到侧**关联基号**列 |
|  └ piece_col | `扫描单号`(实到表) | 实到侧**单件号**列 |
### 2.2 两套表的字段角色
- **应到表**`运单号`(去重+关联)、`交接件数`(应到件数)、`交接单号`(展示)。
- **实到表**`所属单号`(关联基号,须与应到`运单号`同值域)、`扫描单号`(每件单号,格式=`所属单号`+总数4位+顺序4位一个=一件)。
### 2.3 关联Join条件
```
应到表.运单号 == 实到表.所属单号
```
机制同韵达:`arrived_pieces_by_cols` 以「所属单号」建 key dict`process` 用应到运单号去查。
### 2.4 计算口径(与韵达结构完全一致)
- 应到件数 = Σ 交接件数。
- 实到件数 = 实到表「扫描单号」全局去重数。
- 未到件数 = `max(0, 应到 实到)`
- 未到明细:`交接单号 | 运单号 | 总件数 | 已到单号1..k`k=该所属单号下扫描单号数)。
### 2.5 当前数据状态实测2026-07-19 10:50
- 应到运单数 **97**,实到基号数 **140**,交集命中 **4**
- 应到件数 = 236实到单号去重 = 279
- 样本:`应到 750101236894` vs `实到所属单号 760237639793` —— 两套不同编号体系
- **后果**:实到 279 件几乎全无法对应到任何应到运单 → 明细把 93 个运单列「完全未到」,但汇总层 `实到=279 > 应到=236` → 未到净额被 `max(0,…)` 截断为 **0**,于是「明细列 96 行短少」与「汇总未到=0」自相矛盾。
- **结论:安能关联键未对齐,当前产出不可信。**
---
## 三、两站逻辑差异对照
| 维度 | 韵达 | 安能 |
|---|---|---|
| 应到关联键列 | `运单号` | `运单号` |
| 实到关联基号列 | `主单号` | `所属单号` |
| 实到单件号列 | `子单号` | `扫描单号` |
| 单件号是否带后缀 | 是(主单号+顺序号) | 是(所属单号+总数+顺序) |
| 关联键是否对齐(当前数据) | ✅ 57/57 | ❌ 4/97 |
| 计算结果是否可信 | 可信 | 不可信(自相矛盾) |
> 两站**算法完全相同**,唯一区别是实到侧的「基号列 / 单件号列」列名不同。因此问题不在代码逻辑,而在**安能的关联键取值域对不上**。
---
## 四、审核要点(请你判断)
1. **韵达**:关联键 `应到.运单号 == 实到.主单号` 是否符合业务实际?当前数据已对齐,似乎正确;若你确认,韵达逻辑可定稿。
2. **安能**:关联键 `应到.运单号 == 实到.所属单号` 是否正确实测两套编号不重合97 个应到运单仅 4 个能在实到找到)。可能的方向:
- (a) 实到表存在另一列能与应到`运单号`对应(需确认列名,可能改 `wb_col`
- (b) 应到/实到文件是按不同条件/批次拉的,需要按同一天、同线路重新拉取;
- (c) 暂时把安能排除(同百世),等数据对齐再加回。
3. **共同结构问题**:汇总「未到件数」用净额 `max(0, 应到−实到)`,而明细按「逐运单短少」列——当关联键断裂时二者会矛盾(安能现例)。关联键对齐后此矛盾自然消失;是否需要在代码里对「净额 vs 明细」做一致性校验/告警,也请你定。