chore: curate monthly assessment evidence and scripts
This commit is contained in:
@@ -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)")
|
||||
|
||||
Reference in New Issue
Block a user