Files
mileage-bonus/main.py
T

150 lines
5.4 KiB
Python

#!/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)")