#!/usr/bin/env python3 """按月生成独立Excel文件 - 里程考核绩效,支持1-7月""" import os, openpyxl from calc_engine import * from excel_writer import * os.chdir('/Users/kkfluous/Downloads') JULY_SOURCE = os.environ.get('JULY_SOURCE', os.path.join('7月核算结果', '租赁任务考核_2026年7月.xlsx')) JULY_OUTPUT_DIR = os.environ.get('JULY_OUTPUT_DIR', '7月核算结果') # 读取1-7月;7月优先读取核算结果目录内已完成GPS干预的源表 print("读取源数据...") months = [] for m in range(1, 8): fp = JULY_SOURCE if m == 7 else f'租赁任务考核_2026年{m}月.xlsx' if os.path.exists(fp): months.append(m) D = {} for m in months: fp = JULY_SOURCE if m == 7 else f'租赁任务考核_2026年{m}月.xlsx' D[m] = read_file(fp, m) print(f" {m}月: {len(D[m])}条") # 分组 G = {m: grp(D[m], m) for m in months} # 1月初始化 calc_jan_carryover(G[1]) all_data = {} all_data[1] = {'当月': [{'车牌':k[0],'销售':g['销售'],'部门':g['部门'],'额':g['奖金']} for k,g in G[1].items() if g['奖金'] > 0]} # 逐月计算: 2→7 for m in range(2, 8): if m not in G: continue data_m, G[m] = calc_month(m, G, all_data, G[m-1], G[m]) # 钱婧已离职:从2026年7月起所有结转、当月、补发及累计补发均不再发放。 all_data[7] = { cat: [item for item in items if item.get('销售') != '钱婧'] for cat, items in all_data[7].items() } # 发放追踪 vehicle_payments, vehicle_info = collect_vehicle_payments(G, all_data) master_vehicles = read_master_vehicles() # 亏损表 print("\n读取亏损表...") loss_data = {} for m in months: ld = read_loss_data(m) if ld: loss_clients = sum(1 for v in ld.values() if v == '是') print(f" {m}月: {len(ld)}个客户, 其中亏损{loss_clients}个") loss_data[m] = ld else: # 无亏损表的月份不管亏损全发 → 构造全'否'的代理 from collections import defaultdict as dd ld_tmp = dd(lambda: '否') for r in D[m]: c = r.get('客户名称') if c: ld_tmp[c] = '否' print(f" {m}月: 无亏损表,按全部不亏损处理(全发)") loss_data[m] = ld_tmp # 车牌→客户名称映射 plate_client = get_vehicle_client_map(D) # 所有业务员 all_persons = {} for m in G: for k, g in G[m].items(): all_persons[g['销售']] = g['部门'] # 打印汇总 print("\n考核应发汇总:") grand = 0 for m in months: total_m = sum(sum(d['额'] for d in v) for v in all_data[m].values()) grand += total_m print(f" {m}月: {total_m:.2f}") print(f" 合计: {grand:.2f}") # ============================================================ # 按月生成(只生成7月) # ============================================================ for settle_month in [7]: print(f"\n生成 {settle_month}月核算文件...") wb = openpyxl.Workbook() # 当月数据 month_data = all_data[settle_month] # Sheet 1: 考核奖励规则 write_rules_sheet(wb) # Sheet 2: 里程明细 write_detail_sheet(wb, D[settle_month], settle_month) # Sheet 3: 计算过程 write_calc_process_generic(wb, settle_month, G, all_data) # Sheet 5: 车辆考核追踪 write_vehicle_tracking_sheet(wb, settle_month, G, master_vehicles, vehicle_payments, vehicle_info, loss_data[settle_month], plate_client) # Sheet 6: 奖金发放记录(叠加亏损筛选,补发查对应月盈亏) # 不做任何亏损拦截,全发 class _AllPass: def get(self, _k, _d=None): return '否' def __bool__(self): return True payment_records = build_payment_records(settle_month, month_data, {m: _AllPass() for m in months}, plate_client) write_payment_record_sheet(wb, settle_month, payment_records) # Sheet 7: 月汇总。离职人员仅当月奖金转给现销售,其余结转/补发不发; # 发放记录和个人明细仍保留原归属,方便审计。 resignation_transfer = {'赵连飞': '刘念念', '伍仲文': '钟祥', '岑彦': '钟祥'} summary_records = [] for rec in payment_records: item = dict(rec) sales = item.get('业务员') or item.get('销售人员') or item.get('销售') ptype = item.get('发放类型') or item.get('类型') if sales in resignation_transfer: if ptype != '当月': continue new_sales = resignation_transfer[sales] if '业务员' in item: item['业务员'] = new_sales if '销售人员' in item: item['销售人员'] = new_sales if '销售' in item: item['销售'] = new_sales summary_records.append(item) write_summary_from_records(wb, settle_month, summary_records) # 业务员sheets for person in sorted(all_persons.keys()): write_salesperson_sheet(wb, person, all_persons[person], settle_month, D, G, month_data, vehicle_payments) if 'Sheet' in wb.sheetnames: del wb['Sheet'] for old in ['二部-赵连飞', '六部-伍仲文', '六部-岑彦', '三部-钱婧']: if old in wb.sheetnames: wb[old].title = f'【已离职】{old}' wb.move_sheet(wb[f'【已离职】{old}'], offset=len(wb.sheetnames)) os.makedirs(JULY_OUTPUT_DIR, exist_ok=True) fname = os.path.join(JULY_OUTPUT_DIR, f'里程任务考核_{settle_month}月核算.xlsx') wb.save(fname) print(f" ✅ {fname} ({len(wb.sheetnames)} sheets)")