chore: curate monthly assessment evidence and scripts

This commit is contained in:
kkfluous
2026-08-25 12:26:35 +08:00
parent 2956496fb0
commit 52dde9195a
117 changed files with 10743 additions and 179 deletions
+84 -40
View File
@@ -1,40 +1,69 @@
#!/usr/bin/env python3
"""按月生成独立Excel文件 - 里程考核绩效(含亏损筛选)"""
"""按月生成独立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("读取源数据...")
D = {1: read_file('租赁任务考核_2026年1月.xlsx', 1),
2: read_file('租赁任务考核_2026年2月.xlsx', 2),
3: read_file('租赁任务考核_2026年3月.xlsx', 3)}
for m in [1,2,3]: print(f" {m}月: {len(D[m])}")
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 [1,2,3]}
# 分组
G = {m: grp(D[m], m) for m in months}
# 1月初始化
calc_jan_carryover(G[1])
feb_data = calc_feb(G[1], G[2])
mar_data = calc_mar(G[1], G[2], G[3], feb_data)
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, feb_data, mar_data)
vehicle_payments, vehicle_info = collect_vehicle_payments(G, all_data)
master_vehicles = read_master_vehicles()
# 亏损表
print("\n读取亏损表...")
loss_data = {}
for m in [1,2,3]:
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:
print(f" {m}月: 无亏损表")
loss_data[m] = None
# 无亏损表的月份不管亏损全发 → 构造全'否'的代理
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)
@@ -46,27 +75,23 @@ for m in G:
all_persons[g['销售']] = g['部门']
# 打印汇总
jan_total = sum(r['奖金'] for r in D[1] if r['是否达标']=='达标')
feb_total = sum(sum(d[''] for d in v) for v in feb_data.values())
mar_total = sum(sum(d[''] for d in v) for v in mar_data.values())
print(f"\n考核应发: 1月{jan_total:.2f}, 2月{feb_total:.2f}, 3月{mar_total:.2f}")
print(f"Q1考核应发合计: {jan_total + feb_total + mar_total:.2f}")
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 [1, 2, 3]:
for settle_month in [7]:
print(f"\n生成 {settle_month}月核算文件...")
wb = openpyxl.Workbook()
# 当月数据
if settle_month == 1:
month_data = {'当月': [{'车牌':r['车牌号'],'销售':r['销售经理'],'部门':r['部门名称'],'':r['奖金']}
for r in D[1] if r['是否达标']=='达标']}
elif settle_month == 2:
month_data = feb_data
else:
month_data = mar_data
month_data = all_data[settle_month]
# Sheet 1: 考核奖励规则
write_rules_sheet(wb)
@@ -75,31 +100,50 @@ for settle_month in [1, 2, 3]:
write_detail_sheet(wb, D[settle_month], settle_month)
# Sheet 3: 计算过程
if settle_month == 1:
write_calc_process_jan(wb, G[1])
elif settle_month == 2:
write_calc_process_feb(wb, G[1], G[2])
else:
write_calc_process_mar(wb, G[1], G[2], G[3], feb_data)
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: 奖金发放记录(叠加亏损筛选,补发查对应月盈亏)
payment_records = build_payment_records(settle_month, month_data, loss_data, plate_client)
# 不做任何亏损拦截,全发
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: 月汇总(从发放记录生成)
write_summary_from_records(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)
# Sheet 6-17: 业务员
# 业务员sheets
for person in sorted(all_persons.keys()):
write_salesperson_sheet(wb, person, all_persons[person], settle_month, D, G, month_data, vehicle_payments)
# 删除默认空sheet
if 'Sheet' in wb.sheetnames:
del wb['Sheet']
fname = f'里程任务考核_{settle_month}月核算.xlsx'
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)")