From 95f168561230c0066fe5dae235f8e930c2962227 Mon Sep 17 00:00:00 2001 From: kkfluous Date: Thu, 2 Apr 2026 14:37:13 +0800 Subject: [PATCH] =?UTF-8?q?V2.1.0=20=E4=B8=9A=E5=8A=A1=E5=91=98sheet?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0"=E5=8F=91=E6=94=BE=E8=AF=B4=E6=98=8E"?= =?UTF-8?q?=E5=88=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将技术化的"发放类型"改为动态生成的"发放说明",用一句话解释为什么发/不发: - 当月达标 → "当月达标" - 结转 → "1月多跑9578≥3000,结转(完整月奖金)" - 累计补发 → "1-2月累计10620≥10000,累计达标补发" - 未达标 → "未达标(实际1486<目标5000)" - 补发过去月 → "1-3月累计14427≥10161,补发1月" 包含关键数字,非技术人员一眼看懂计算依据。 Co-Authored-By: Claude Opus 4.6 (1M context) --- excel_writer.py | 43 +++++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/excel_writer.py b/excel_writer.py index 56db5c1..dbda88a 100644 --- a/excel_writer.py +++ b/excel_writer.py @@ -217,7 +217,7 @@ def write_salesperson_sheet(wb, person, dept, settle_month, D, G, month_data, ve rn += 1 # 表头 - headers = ['月份','考核天数','应考核里程','实际里程','完成率','达标','本月奖金','发放类型'] + headers = ['月份','考核天数','应考核里程','实际里程','完成率','达标','奖金','发放说明'] if settle_month >= 2: headers += ['累计应完成','累计实际','累计达标'] WH(ws, headers, rn); rn += 1 @@ -232,20 +232,42 @@ def write_salesperson_sheet(wb, person, dept, settle_month, D, G, month_data, ve t=gm['应考核']; a=gm['实际']; cum_t+=t; cum_a+=a qual='达标' if gm['有达标'] else '未达标' rate=R(a/t*100,0) if t>0 else 0 + mkm=gm['目标km'] - # 发放类型和金额 - pay_type=''; pay_amt=0 + # 发放金额和说明(动态生成,包含关键数字) + pay_amt=0; desc='' if m == settle_month: carry=gm.get('结转',0); bonus=gm.get('当月奖金',0) cum_bp=gm.get(f'累计补发{m}月',0) - if carry>0: pay_type='结转'; pay_amt=carry - elif bonus>0: pay_type='当月达标'; pay_amt=bonus - elif cum_bp>0: pay_type=f'累计补发'; pay_amt=cum_bp + excess=sum(r['多跑'] for r in gm['recs'] if r['是否达标']=='达标') + if carry>0: + # 结转:上月多跑够整月 + prev=m-1 + g_prev=G.get(prev,{}).get((plate,person)) + prev_excess=sum(r['多跑'] for r in g_prev['recs'] if r['是否达标']=='达标') if g_prev else 0 + desc=f'{prev}月多跑{R(prev_excess,0)}≥{mkm},结转(完整月奖金)' + pay_amt=carry + elif bonus>0: + desc='当月达标' + if excess>0 and int(excess//mkm)>=1: + desc+=f',多跑{R(excess,0)}≥{mkm}可结转' + pay_amt=bonus + elif cum_bp>0: + desc=f'1-{m}月累计{R(cum_a,0)}≥{R(cum_t,0)},累计达标补发' + pay_amt=cum_bp + elif gm.get('结转占位'): + desc='结转占位,本月不另发' + else: + desc=f'未达标(实际{R(a,0)}<目标{R(t,0)})' else: - if gm['有达标']: pay_type='(已发)'; pay_amt=gm.get('奖金',0) - else: pay_type='(未达标)' + # 历史月份 + if gm['有达标']: + pay_amt=gm.get('奖金',0) + desc=f'({m}月已发{R(pay_amt)})' + else: + desc=f'未达标(实际{R(a,0)}<目标{R(t,0)})' - row_data=[f'{m}月',gm['天数'],R(t),R(a),f'{rate}%',qual,R(pay_amt) if pay_amt>0 else 0,pay_type] + row_data=[f'{m}月',gm['天数'],R(t),R(a),f'{rate}%',qual,R(pay_amt) if pay_amt>0 else 0,desc] if settle_month>=2: cum_q='达标' if (cum_a>=cum_t and cum_t>0) else '未达标' row_data+=[R(cum_t),R(cum_a),cum_q] @@ -258,7 +280,8 @@ def write_salesperson_sheet(wb, person, dept, settle_month, D, G, month_data, ve bp_key = f'补发{prev_m}月' bp_amt = g_s.get(bp_key, 0) if isinstance(g_s, dict) else 0 if bp_amt > 0: - row_data = [f'→补发{prev_m}月','','','','','',R(bp_amt),f'补发{prev_m}月'] + desc=f'1-{settle_month}月累计{R(cum_a,0)}≥{R(cum_t,0)},补发{prev_m}月' + row_data = [f'→补发{prev_m}月','','','','','',R(bp_amt),desc] if settle_month>=2: row_data += ['','',''] WR(ws,rn,row_data); rn+=1