# -*- coding: utf-8 -*-
"""刘子研 2026-11-02 ~ 11-07 差旅报销：建汇总表草稿 + 票据待补清单。"""
import os, shutil, json
from datetime import datetime
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
import sys
sys.path.insert(0, os.path.expanduser('~/Desktop/Hermes输出-工作类/报销助手/脚本'))
import xlsx_fill_min

BASE = os.path.expanduser('~/Desktop/Hermes输出-工作类')
TEMPLATE = os.path.join(BASE, '报销助手/规则文件/CA-01-03-A3付款、费用报销管理制度/附件2-差旅费报销汇总表.xlsx')
BATCH = os.path.join(BASE, '报销助手/归档/2026-11/20261102_20261107')
DIRS = ['01_报销汇总表', '02_报销打印包', '03_材料清单', '04_票据索引', '05_待补材料']
for d in DIRS:
    os.makedirs(os.path.join(BATCH, d), exist_ok=True)

OUT_XLSX = os.path.join(BATCH, '01_报销汇总表/附件2-差旅费报销汇总表-2026年11月W1_草稿.xlsx')
OUT_CHECK = os.path.join(BATCH, '03_材料清单/差旅票据待补清单_20261102-1107.xlsx')
OUT_MD = os.path.join(BATCH, '03_材料清单/任务状态_20261102-1107.md')

# 1) copy blank template
shutil.copy2(TEMPLATE, OUT_XLSX)

# 2) fill itinerary skeleton (amounts blank; per diem provisional 80/day)
edits = {
    'A2': ' 部 门：大客户销售部',
    'E2': '刘子研',
    'K2': 6,
    'P2': '2026-11-07',
    # row 5 11/2
    'B5': '11月2', 'C5': '珠海-上海',
    'K5': '无', 'M5': 80, 'P5': '机票、上海住宿待补；出发日补助按80暂计',
    # row 6 11/3
    'B6': '11月3', 'C6': '上海',
    'K6': '无', 'M6': 80, 'P6': '11/3上海住宿有票（¥593.30）但入住人刘新元，待确认；拜访上海之江',
    # row 7 11/4
    'B7': '11月4', 'C7': '上海-西安',
    'D7': 535, 'K7': '无', 'M7': 80, 'P7': 'HO1235 上海虹桥→西安咸阳 535元已收（发票号26318018111087214036，乘机11/4）；西安住宿有票¥474.30但入住人刘新元，待确认；科华待定',
    # row 8 11/5
    'B8': '11月5', 'C8': '西安',
    'K8': '无', 'M8': 80, 'P8': '11/5西安住宿有票（¥491.30）但入住人刘新元，待确认；拜访西安佰奥莱博',
    # row 9 11/6
    'B9': '11月6', 'C9': '西安-武汉',
    'E9': 428, 'M9': 80, 'P9': '高铁票428元已收（发票号26619140399000333557，乘车11/6）；武汉住宿不报销；拜访西安天隆',
    # row 10 11/7
    'B10': '11月7', 'C10': '武汉-珠海',
    'M10': 80, 'P10': '机票待补；返程日补助按80暂计',
}
filled, skipped = xlsx_fill_min.fill(TEMPLATE, OUT_XLSX, '差旅费报销汇总表', edits, overwrite=True)
same, diff = xlsx_fill_min.verify(TEMPLATE, OUT_XLSX, '差旅费报销汇总表')
print('filled', len(filled), 'skipped', skipped)
print('verify same', same, 'diff', diff)

# 3) verify formulas survived
wb = openpyxl.load_workbook(OUT_XLSX, data_only=False)
ws = wb['差旅费报销汇总表']
for ref in ['O5','O6','D19','M19','O19','K21']:
    print(ref, ws[ref].value)

# 4) checklist workbook
wb2 = openpyxl.Workbook()
ws2 = wb2.active
ws2.title = '票据待补清单'
ws2.sheet_view.showGridLines = False
NAVY = '0F2B52'; BLUE = '1A56DB'; LIGHT = 'EEF4FF'; GREY = 'F4F7FB'; WHITE = 'FFFFFF'
thin = Side(style='thin', color='D9E2EF')
border = Border(left=thin, right=thin, top=thin, bottom=thin)

def title(ws, text, sub):
    ws.merge_cells('A1:I1')
    c = ws['A1']; c.value = text
    c.font = Font(name='宋体', size=14, bold=True, color=WHITE)
    c.fill = PatternFill('solid', fgColor=NAVY)
    c.alignment = Alignment(horizontal='left', vertical='center')
    ws.row_dimensions[1].height = 32
    ws.merge_cells('A2:I2')
    c = ws['A2']; c.value = sub
    c.font = Font(name='宋体', size=8.5, color='5D6B80')
    c.fill = PatternFill('solid', fgColor=GREY)
    c.alignment = Alignment(horizontal='left', vertical='center')
    ws.row_dimensions[2].height = 26

def header(ws, row, cols):
    for j, (name, width) in enumerate(cols, 1):
        c = ws.cell(row=row, column=j, value=name)
        c.font = Font(name='宋体', size=9, bold=True, color=WHITE)
        c.fill = PatternFill('solid', fgColor=NAVY)
        c.alignment = Alignment(horizontal='left', vertical='center', wrap_text=True)
        c.border = border
        ws.column_dimensions[get_column_letter(j)].width = width
    ws.row_dimensions[row].height = 30

def row(ws, r, vals, alt=False, bold_first=False):
    for j, v in enumerate(vals, 1):
        c = ws.cell(row=r, column=j, value=v)
        c.font = Font(name='宋体', size=8.5, bold=(bold_first and j == 1))
        c.fill = PatternFill('solid', fgColor=(GREY if alt else WHITE))
        c.alignment = Alignment(horizontal='left', vertical='top', wrap_text=True)
        c.border = border
    ws.row_dimensions[r].height = 46

title(ws2, '刘子研 2026-11-02 ~ 11-07 差旅报销：票据待补清单', '行程依据：202611.03-11.06拜访计划-刘子研.xlsx；内部材料，含客户行程，勿外发')
header(ws2, 4, [('日期', 10), ('行程/城市', 18), ('业务事项', 26), ('交通票据', 22), ('住宿票据', 22), ('市内交通', 18), ('补助', 8), ('状态', 10), ('备注', 30)])
rows = [
    ('11月2', '珠海-上海', '出发，上海住宿', '珠海→上海 机票行程单/电子发票', '上海酒店发票 + 结账单（11/2 1晚）；未收到', '珠海机场/上海机场交通票', 80, '待补', '11/2住宿未收到；11/3-11/4住宿票入住人刘新元，待确认'),
    ('11月3', '上海', '拜访上海之江；张阳明/曹丽君/张含嫣', '无长途', '已收但入住人刘新元：汉庭优佳上海龙吴路 11/3-11/4 ¥593.30（超350上限243.30）', '市内打车/地铁票', 80, '待确认', '发票号26312000007124263666；入住人不是刘子研，需确认同住/代订或换开'),
    ('11月4', '上海-西安', '上海科华（待定）；转西安', '已收：HO1235 上海虹桥→西安咸阳 11/4 19:50，¥535.00；发票号 26318018111087214036', '已收但入住人刘新元：汉庭西安高新软件新城 11/4-11/5 ¥474.30（超300上限174.30）', '上海/西安机场交通票', 80, '已收/待核', '机票开票日11/5，按乘机日归11/4；住宿入住人待确认'),
    ('11月5', '西安', '拜访西安佰奥莱博；孙欢/颜艳/杜巧云', '无长途', '已收但入住人刘新元：西安钟楼南门CitiGO 11/5-11/6 ¥491.30（超300上限191.30）', '市内打车/地铁票', 80, '待确认', '发票号26612000002247613876；入住人不是刘子研，需确认同住/代订或换开'),
    ('11月6', '西安-武汉', '拜访西安天隆；李洪东/王新旺；转武汉', '已收：G3926 西安东→汉口 11/6 16:41，二等座，¥428.00；发票号 26619140399000333557', '武汉住宿不报销（不要贴票）', '西安/武汉站交通票', 80, '已收/待核', '已入台账 INV-20261107-0001；开票日11/7，按乘车日归11/6'),
    ('11月7', '武汉-珠海', '返程', '武汉→珠海 机票行程单/电子发票', '无住宿', '武汉机场/珠海机场交通票', 80, '待补', '返程日；补助暂按80计'),
]
for i, vals in enumerate(rows, 5):
    row(ws2, i, vals, alt=(i % 2 == 0), bold_first=True)

ws2.merge_cells('A11:I11')
c = ws2['A11']; c.value = '汇总口径：出差 6 个自然日；可报住宿 4 晚（上海 2 + 西安 2；武汉 1 晚不报销）；补助暂按 6×80=480 元，出发/返程是否按半天（40）待财务确认。'
c.font = Font(name='宋体', size=8.5, bold=True, color='B45309')
c.fill = PatternFill('solid', fgColor='FFF8EB')
c.alignment = Alignment(wrap_text=True, vertical='center')
ws2.row_dimensions[11].height = 34

# 5) summary sheet
ws3 = wb2.create_sheet('汇总与缺口')
ws3.sheet_view.showGridLines = False
title(ws3, '汇总与缺口', '只填已核实金额；当前票据未到，金额留空')
header(ws3, 4, [('项目', 24), ('口径/金额', 28), ('状态', 16), ('说明', 40)])
summary = [
    ('出差天数', '6 个自然日（11/2–11/7）', '已确认', '按行程文件+用户口述'),
    ('可报住宿', '4 晚：上海 2 + 西安 2', '待确认', '武汉 1 晚按用户指示不报销；已抓住宿票入住人均为刘新元'),
    ('住宿上限参考', '上海 350/晚；西安 300/晚', '参考', '公司制度：超一类/一类；同住规则另核'),
    ('出差补助', '暂计 480 元（6×80）', '待财务确认', '出发/返程是否按半天40，以财务核定为准'),
    ('长途交通', '3 段飞机 + 1 段高铁', '部分已收', '11/2 珠海→上海、11/7 武汉→珠海待补；11/4 HO1235 已收535；11/6 高铁已收428'),
    ('市内交通', '按实际票据', '待票', '机场/高铁站/客户往返；制度上限 80/天'),
    ('业务招待', '无', '不涉及', '本行程未说明招待'),
    ('打印包', '未生成', '待票据齐', '票据齐后按公司顺序生成，汇总表单独 Excel'),
]
for i, vals in enumerate(summary, 5):
    row(ws3, i, vals, alt=(i % 2 == 0), bold_first=True)
ws3.merge_cells('A14:D14')
c = ws3['A14']; c.value = '票据齐后动作：1) 逐张核对抬头/税号/金额；2) 住宿发票配结账单；3) 机票配行程单；4) 生成打印包；5) 汇总表金额复核后再提交。'
c.font = Font(name='宋体', size=8.5, bold=True, color='1A56DB')
c.fill = PatternFill('solid', fgColor=LIGHT)
c.alignment = Alignment(wrap_text=True, vertical='center')
ws3.row_dimensions[14].height = 38

for sh in [ws2, ws3]:
    sh.freeze_panes = 'A5'
    sh.page_setup.orientation = 'landscape'
    sh.page_setup.fitToWidth = 1
    sh.page_setup.fitToHeight = 0
    sh.sheet_properties.pageSetUpPr.fitToPage = True

wb2.save(OUT_CHECK)

md = f'''# 刘子研 2026-11-02 ~ 11-07 差旅报销任务

状态：**已建骨架，待票据**（不是最终版）

## 行程
- 11/2 珠海→上海，住上海
- 11/3 上海（拜访上海之江），住上海
- 11/4 上海（科华待定）→西安（飞机），住西安
- 11/5 西安（拜访西安佰奥莱博），住西安
- 11/6 西安（拜访西安天隆）→武汉，住武汉（不报销）
- 11/7 武汉→珠海

## 已生成
- 汇总表草稿：`01_报销汇总表/附件2-差旅费报销汇总表-2026年11月W1_草稿.xlsx`
- 票据待补清单：`03_材料清单/差旅票据待补清单_20261102-1107.xlsx`

## 口径
- 出差 6 个自然日；可报住宿 4 晚（上海 2 + 西安 2）；武汉 1 晚不报销。
- 补助暂按 6×80=480 元；出发/返程是否按半天 40，待财务确认。
- 11/4 上海→西安按飞机，机票已收 535 元；西安住宿票入住人待确认。
- 所有金额只填已核实票据；当前可计算合计 **1,443 元**（机票535 + 高铁428 + 补助480），住宿票待确认。

## 待补
1. 11/2 珠海→上海机票行程单/电子发票。
2. 上海 11/2、11/3 两晚住宿发票 + 结账单；11/3-11/4 住宿票入住人为刘新元，待确认。
3. 11/7 武汉→珠海机票行程单/电子发票。
4. 各城市机场/高铁站/客户往返市内交通票。
5. 出差申请/外出申请（如公司要求事前关联）。

## 已收票据
- 11/4 上海虹桥→西安咸阳 HO1235，¥535.00；发票号 26318018111087214036；乘机 11/4 19:50；开票 11/5。已入台账 INV-20261107-0002，汇总表填 D7=535。
- 11/6 西安东→汉口 G3926，二等座，¥428.00；发票号 26619140399000333557；乘车 11/6 16:41；开票 11/7。已入台账 INV-20261107-0001，汇总表填 E9=428。
- 住宿票三张已抓到，但入住人均为刘新元，不是刘子研：上海 11/3-11/4 ¥593.30；西安 11/4-11/5 ¥474.30；西安 11/5-11/6 ¥491.30。均未填入汇总，待确认同住/代订或换开。
'''
open(OUT_MD, 'w', encoding='utf-8').write(md)
print('WROTE', OUT_XLSX)
print('WROTE', OUT_CHECK)
print('WROTE', OUT_MD)
