from pathlib import Path import json,hashlib P=Path(__file__).parent;S=P.parent;R=S.parents[1] a=json.loads((P/'audit_results.json').read_text());d=json.loads((S/'september_calculation.json').read_text()) lines=['# 1—8月已发与9月发放核对','', '核对对象:2026年9月40,211.67元版本,145条发放项。原Excel保持不变。核对以用户确认的1—7月历史最终表、8月纯氢修正版实际已发45,065.47元为基准。', '','## 结论','', '**补发与金额算术检查通过;结转资格存在规则分支不一致,需要澄清后再将结果作为最终付款依据。**', '按8月表内结转余额逐月减1的现行逻辑,独立重算9月仍为40,211.67元,未发现金额公式错误或重复历史补发。此结论不等于认可结转余额的形成口径。', '','## 1. 结转两种算法不一致:9月有150元需要复核','', '有实际考核记录的车组按“累计多跑里程÷月目标取整−实际已用结转期数”计算余额;无本月考核记录的车组却按“上期余额−1”,同时在累计目标中增加一个月目标。这是代码中不同分支的实际行为。', '8月底有5辆车的表内结转余额比统一累计公式多1期。尚建华的粤AGP5158会影响9月当期150元,其余4辆在两种口径下9月都有至少1期可用结转,主要影响后续余额。', '','|车辆|负责人|8月底表内余额|累计公式余额|1—8月已领结转次数|9月结转|', '|---|---|---:|---:|---:|---:|'] for x in a['prior_carry_basis_differences']:lines.append(f"|{x['plate']}|{x['sales']}|{x['aug_saved_balance']}|{x['aug_formula_balance']}|{x['carry_paid_jan_aug']}|{x['sep_payment']:.2f}|") lines += ['', '粤AGP5158截至8月累计实际41,174.00公里、累计目标22,451.61公里、月目标3,000公里,实际已领6次结转。统一累计公式得到 floor((41,174.00−22,451.61)/3,000)−6=0期;8月表却保存1期,9月据此发150元。', '**不能直接将150元定为多发并扣除。** 无考核月份是否应增加虚拟考核目标,决定了两种余额计算哪一种适用;若增加虚拟目标又扣除已领期数,可能重复消耗同一结转额度。应先统一规则,再调整9月及后续余额,1—8月实际已发保持不变。若明确要求保留目前累计目标、全部统一累计公式,则这笔150元不满足资格,9月在其他条件不变时为40,061.67元。这只是该口径下的测算,不是建议直接改付。', '','## 2. 同车新旧负责人同时领取,共涉及原负责人970元','', '本月无考核记录的结转共33笔、5,940元。其中以下5辆同时给新负责人发当月奖金、给旧负责人发历史结转。按目前“车牌+负责人”分账、历史结转继续发放的规则可以复现,并非同一负责人重复发放。若制度要求交接后原负责人停止领取,才会影响这970元。不能把它直接作为错付款扣除。', '','|车辆|原负责人|原负责人结转|新负责人发放|','|---|---|---:|---|'] for x in a['cross_owner_payments']: new=';'.join(f"{y['sales']} {y['category']} {y['amount']:.2f}元" for y in x['current_payments']) lines.append(f"|{x['plate']}|{x['carry_owner']}|{x['carry_amount']:.2f}|{new}|") lines += ['', '','## 3. 9月底17辆结转余额不同,33条累计状态显示不准确','', '17个无本月考核车组的表内结转余额与统一累计公式合计相差20期。这是口径差异,不能直接换算成确定多发金额;不同车辆奖励基准、未来有无考核及补数均可能变化。', '','|车辆|负责人|9月底表内余额|统一累计公式余额|','|---|---|---:|---:|'] for x in a['next_balance_differences']:lines.append(f"|{x['plate']}|{x['sales']}|{x['sep_saved_balance']}|{x['sep_formula_balance']}|") lines += ['', '33个无本月考核车组在程序中把累计达标标志固定为否,但显示的累计实际里程均已达到累计目标。例如粤AGP5158累计实际41,174.00大于目标25,451.61,计算过程仍显示“已有里程未达标”。这是展示语义问题,并不等于应额外补发。建议将“累计里程是否达标”与“本月是否有考核、是否具备补发资格”分开显示。', '','## 4. 已确认没有重复的7笔历史补发','', '按“车辆+原考核负责人+考核月”逐项检查1—8月已发;7笔合计819.67元,没有重复,非虚拟考核车组也未发现符合现行规则而遗漏的补发。', '','|车辆|负责人|补发类别|金额|9月累计实际|9月累计目标|','|---|---|---|---:|---:|---:|'] for x in a['historical_backpay']:lines.append(f"|{x['plate']}|{x['sales']}|{x['category']}|{x['amount']:.2f}|{x['sep_cumulative_actual']:.2f}|{x['sep_cumulative_target']:.2f}|") lines += ['', '粤AGP3612尚建华到9月累计超目标122.04公里,8月底尚差1,023.06公里,因此9月才补5月33.55元、7月260元、8月260元。6月已经实际发放,未重复补发。', '粤AGR0772尚建华补8月19.35元,与谯云8月已发116.13元不是重复:分别为8月28—31日与8月1—24日两个负责人区间。', '','## 5. 台账、取数及报表一致性','', '- 1—6月已发台账逐条吻合历史最终表;6月人员转接后的个人合计也一致。', '- 7月原明细仍列9笔离职不发款2,749.35元,已发台账已正确剔除。最终汇总62,616.73元与逐项和62,616.76元相差0.03元,是历史原表舍入差。', '- 8月纯氢修正版实际已发45,065.47元及原扣减9.68元保持不变,扣减项不再次补发。', '- 9月145条发放项与Excel缓存值一致,金额公式未发现错误。结转、当月、累计补发当月之间未发现同负责人同车的重复占用。', '- 实际已领结转次数与1—8月台账逐车一致,问题发生在余额计算方式,不是漏记已领次数。', '- 9月刘念念全部归业务一部,部门汇总与明细一致;新政策名单沿用原39辆、当月匹配36辆。', '- 8,737个考核车辆日无重复计入,原始来源文件哈希未改变。此前中断月份清零触发误补发的问题在当前版本未再出现。', '','## 6. 仍有数据缺口','', '9月1,000个车辆日缺少所需来源,涉及176辆车;其中991个需仪表、9个需GPS。6条考核记录整段缺少可用里程。61条发放项(16,662.34元)带有本月或8月缺口标记,标记不代表这些金额均算错:部分已有里程已经足够达标,结转也可能来自历史。补齐数据后仍可能改变未达标、补发和结转余额。', '尚建华粤AGR5535虽然9月2天全缺,仍列累计补发9月10元:仅历史已知里程4,246.80公里已经大于包含9月目标后的3,521.43公里,按现行累计达标规则可以复现;0仅为当前已知累计,不是实测零里程。', '','## 处理建议','', '1. 优先统一无本月考核车辆的结转目标、余额消耗方式,避免一边增加虚拟目标、一边重复扣已用期数。先核实粤AGP5158的150元,再统一17辆后续余额。', '2. 明确交接后原负责人能否继续领取历史结转;若允许,表内将旧负责人历史结转与新负责人当月奖励清楚分开即可。', '3. 更正无本月考核车组的累计状态文字,保持累计结果与补发资格两个概念分开。', '4. 补齐1,000个车辆日缺口后重算。当前40,211.67元保留为现行口径暂算,不表示以上规则问题已解决。', '','## 核对范围及证据','', '全量核对145条9月发放、1—8月对应已发状态、369个当前车组的历史累计及结转次数;重复展示的个人页沿用已完成金额核验。没有重新从平台获取GPS,也未重新审核1—6月纯氢原始采集准确性。银行支付未另取流水,按用户确认的历史最终表作为已发。', '',f"当前9月文件SHA256:`{a['workbook_sha256']}`",''] paths=[R/f'里程任务考核_{m}月核算.xlsx' for m in range(1,7)]+[R/'7月绩效重算_多源考核里程_20260817/里程任务考核_7月核算.xlsx',S.parent/'hydrogen-history-20260916/里程任务考核_8月核算_纯氢修正版.xlsx',S/'里程任务考核_2026年9月_含缺口核算.xlsx'] lines.extend(f'- [{p.name}]({p})' for p in paths) lines+=['','复核脚本:audit_september_against_paid.py、independent.py;逐项结果:audit_results.json、history_checks.json。'] (P/'1-8月与9月发放核对报告.md').write_text('\n'.join(lines)) nb={'nbformat':4,'nbformat_minor':5,'metadata':{'kernelspec':{'display_name':'Python 3','language':'python','name':'python3'}},'cells':[{'cell_type':'markdown','metadata':{},'source':['# 1—8月与9月发放只读核验\n','先阅读核对报告,代码只读取原表并写出核验结果,不修改奖金工作簿。']},{'cell_type':'code','metadata':{},'execution_count':None,'outputs':[],'source':(P/'audit_september_against_paid.py').read_text().replace("P=Path(__file__).resolve().parent",f"P=Path({str(P.resolve())!r})").splitlines(True)}]} (P/'历史与9月发放核验.ipynb').write_text(json.dumps(nb,ensure_ascii=False,indent=2)) files=[{'label':p.name} for p in paths] def q(id,title,rows,columns,caveats,method): return {'id':id,'title':title,'queries':[{'id':id+'-evidence','source':{'label':'2026年里程绩效核算表','files':files,'filters':['按车辆与原考核负责人区分资格','历史已发锁定,不追扣'],'caveats':caveats},'reportingPeriod':'2026年1—8月已发,对比9月核算','columns':columns,'rows':rows,'methods':[{'language':'calculation','code':method}]}]} receipt={'schemaVersion':1,'items':[ q('historical-backpay','7笔历史补发未发现重复',a['historical_backpay'],['plate','sales','category','amount'],['已发以用户确认的历史最终表为准,未另取银行流水。'],'33.55 + 260 + 260 + 72.58 + 19.35 + 150 + 24.19 = 819.67元;逐笔排除同车、同负责人、同考核月已经发放。'), q('carry-balance','无本月考核车辆的结转余额存在两种口径',a['prior_carry_basis_differences'],['plate','sales','aug_saved_balance','aug_formula_balance','carry_paid_jan_aug'],['150元是口径待确认金额,不能直接认定多发;虚拟考核目标是否应增加尚需明确。'],'粤AGP5158:floor((41174.00 − 22451.61) / 3000) − 6 = 0期;8月表内余额1期,9月据此发150元。9月底另有17组余额与统一公式不一致。'), q('owner-handover','5辆车原负责人领结转且新负责人领当月奖金',[{'plate':x['plate'],'owner':x['carry_owner'],'carry_amount':x['carry_amount'],'current':str(x['current_payments'])} for x in a['cross_owner_payments']],['plate','owner','carry_amount','current'],['按目前车牌加负责人分账可以复现,不等于同一负责人重复发放;是否交接后停止旧负责人结转属于业务规则。'],'150 + 150 + 150 + 260 + 260 = 970元原负责人结转,包含在33笔无本月考核结转5940元中。') ]} (P/'sources_receipt.json').write_text(json.dumps(receipt,ensure_ascii=False,indent=2)) assert hashlib.sha256((S/'里程任务考核_2026年9月_含缺口核算.xlsx').read_bytes()).hexdigest()==a['workbook_sha256'] print('Read-only audit report and notebook saved; workbook unchanged.')