refactor: extract domain.py (shared site/file/colmap config)

Move ALL_REPORT_SITES / SITE_UNDELIVERED_FILE / BAISHI_FILE / BAISHI_COLUMNS / arrived_pieces_* / STATIONS / _site_cfg out of expected_undelivered into a new leaf module inbound_verify/domain.py. store.py and runtime.py now read site/file config from domain directly instead of through the compare engine (store keeps eu only for _read_business_dates). Behavior identical.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Misaka_Company
2026-07-24 08:38:18 +08:00
parent bd0df8909f
commit 91ef8970b8
4 changed files with 114 additions and 94 deletions

92
inbound_verify/domain.py Normal file
View File

@@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
"""domain.py — 站点 / 文件名 / 列映射的共享配置(单一来源)。
比对compare与入库store都依赖这套配置抽出独立 leaf 模块,
让 store 不必为读配置而依赖整个比对引擎。纯数据,无 state_store / 文件 IO 依赖。
"""
from collections import defaultdict
# 汇总报表覆盖的全部站点4 站在前、百世在末;汇总页图表只取 4 站)
ALL_REPORT_SITES = ["顺心", "中通", "韵达", "安能", "百世"]
# 4 站单站未到明细文件名(百世未到文件由站点直接产出,名为 BAISHI_FILE
SITE_UNDELIVERED_FILE = "{name}-未到数据.xlsx"
BAISHI_FILE = "百世-应到未到货物数据.xlsx"
BAISHI_COLUMNS = ["类型", "子单号", "运单号", "最新扫描记录"]
def arrived_pieces_zhongtong(df):
"""中通实到「运单号」为复合串H + 运单号(12) + 总数(4) + 顺序(4))。
基号 = v[:-8](与应到表运单号对齐),单件 = 整串(每串即一件)。"""
res = defaultdict(set)
for v in df["运单号"]:
v = str(v).strip()
if len(v) > 8 and v[-4:].isdigit():
res[v[:-8]].add(v) # 以完整复合串作为“已到单号”存入
return res
def arrived_pieces_by_cols(wb_col, piece_col):
"""顺心 / 韵达 / 安能:按干净运单列分组,单件 = 子单号 / 扫描单号。
wb_col实到表中与应到运单号对齐的干净列
(顺心=运单号 / 韵达=主单号 / 安能=所属单号)
piece_col实到表中每件货物的单号列子单号 / 扫描单号)"""
def parse(df):
res = defaultdict(set)
for m, s in zip(df[wb_col], df[piece_col]):
m, s = str(m).strip(), str(s).strip()
if m and s:
res[m].add(s)
return res
return parse
STATIONS = [
{
"name": "中通",
"exp": "中通-应到货物数据.xlsx",
"act": "中通-实到货物数据.xlsx",
"exp_qty": "交接件数", # 应到件数口径:交接件数(非录单件数)
"exp_wb": "运单号", # 应到表运单号列(兼作去重键)
"exp_jd": "交接单号", # 未到数据需展示的交接单号
"arrived_pieces": arrived_pieces_zhongtong,
"columns": ["交接单号", "运单号", "总件数"],
},
{
"name": "顺心",
"exp": "顺心-应到货物数据.xlsx",
"act": "顺心-实到货物数据.xlsx",
"exp_qty": "交接件数",
"exp_wb": "运单号",
"exp_jd": "交接单号",
"arrived_pieces": arrived_pieces_by_cols("运单号", "子单号"),
"columns": ["交接单号", "运单号", "总件数"],
},
{
"name": "韵达",
"exp": "韵达-应到货物数据.xlsx",
"act": "韵达-实到货物数据.xlsx",
"exp_qty": "交接件数",
"exp_wb": "运单号",
"exp_jd": "交接单号",
"arrived_pieces": arrived_pieces_by_cols("主单号", "子单号"),
"columns": ["交接单号", "运单号", "总件数"],
},
{
"name": "安能",
"exp": "安能-应到货物数据.xlsx",
"act": "安能-实到货物数据.xlsx",
"exp_qty": "交接件数",
"exp_wb": "运单号",
"exp_jd": "交接单号",
"arrived_pieces": arrived_pieces_by_cols("所属单号", "扫描单号"),
"columns": ["交接单号", "运单号", "总件数"],
},
]
def _site_cfg(name):
"""按名称取 4 站配置(百世不在 STATIONS返回 None"""
return next((c for c in STATIONS if c["name"] == name), None)