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>
93 lines
3.6 KiB
Python
93 lines
3.6 KiB
Python
# -*- 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)
|