Files
mileage-bonus/audit_recalculate_july_from_multi_source.py
T

50 lines
2.1 KiB
Python

import openpyxl
import re
from collections import Counter
from datetime import datetime
from pathlib import Path
NEW = Path('/Users/kkfluous/Downloads/7月考核车辆多源里程汇总_用户确认版.xlsx')
OLD = Path('/Users/kkfluous/Downloads/7月核算结果/租赁任务考核_2026年7月.xlsx')
def norm(v):
return re.sub(r'\s+', '', str(v or '')).upper()
def day(v):
return v.date() if isinstance(v, datetime) else v
nw = openpyxl.load_workbook(NEW, data_only=True, read_only=False)
ns = nw['7月考核车辆里程汇总']
nh = {ns.cell(2, c).value: c for c in range(1, ns.max_column + 1)}
ow = openpyxl.load_workbook(OLD, data_only=True, read_only=False)
os = ow['业务考核视图']
oh = {os.cell(1, c).value: c for c in range(1, os.max_column + 1)}
N = [(norm(ns.cell(r, nh['车牌']).value), day(ns.cell(r, nh['考核开始日期']).value),
day(ns.cell(r, nh['考核结束日期']).value), ns.cell(r, nh['核算里程(km)']).value)
for r in range(3, ns.max_row + 1)]
O = [(norm(os.cell(r, oh['车牌号']).value), day(os.cell(r, oh['考核开始日期']).value),
day(os.cell(r, oh['考核结束日期']).value), os.cell(r, oh['实际行驶里程(km)']).value)
for r in range(2, os.max_row + 1)]
nk, ok = Counter(x[:3] for x in N), Counter(x[:3] for x in O)
nd = {x[:3]: x[3] for x in N}
changes = []
for x in O:
nv, ov = nd.get(x[:3]), x[3]
if isinstance(nv, (int, float)) and abs(float(nv) - float(ov or 0)) > 0.005:
changes.append((*x[:3], ov, nv, nv - float(ov or 0)))
print({
'new_rows': len(N), 'old_rows': len(O),
'new_dup_keys': sum(v > 1 for v in nk.values()), 'old_dup_keys': sum(v > 1 for v in ok.values()),
'missing_in_new': len(set(ok) - set(nk)), 'extra_in_new': len(set(nk) - set(ok)),
'changed_rows': len(changes),
'old_total': round(sum(float(x[3] or 0) for x in O), 2),
'new_total': round(sum(float(x[3] or 0) for x in N if isinstance(x[3], (int, float))), 2),
})
print('missing', list(set(ok) - set(nk))[:10])
print('extra', list(set(nk) - set(ok))[:10])
for x in sorted(changes, key=lambda x: abs(x[5]), reverse=True)[:15]:
print(x)