- add scripts/annotate_roster_invoices.py: match passenger names to invoice PDFs, write status + relative encoded hyperlinks into roster xlsx - add scripts/add_invoice_passenger_name.py, scripts/calibrate.py - add .opencode/skills/invoice-wrapup skill - improve invoice_tool.py / web_ui.py / vision_fallback.py automation - add device/screen/windows adaptation docs - ignore out/ (delivered invoice PDFs contain sensitive data)
67 lines
3.2 KiB
Markdown
67 lines
3.2 KiB
Markdown
---
|
||
name: invoice-wrapup
|
||
description: 铁路发票批次收尾:把交付目录里的发票 PDF 提取乘客姓名加进文件名,再把名单 xlsx 逐人标注开票状态并附上 PDF 超链接。当用户说"收尾这批发票""给发票 PDF 加姓名""名单里标开票状态/附发票链接""处理 output/<批次> 目录""invoice-wrapup"时触发。适用于一个批次跑完后、要交付名单前的整理动作。不负责:跑开票自动化本身(那是 invoice_tool.py 的 android 子命令)、生成名单/台账。
|
||
---
|
||
|
||
# 铁路发票批次收尾(invoice-wrapup)
|
||
|
||
一个开票批次跑完后,交付目录(通常 `output/<批次号>/`,可能还带一个 `手动/` 子目录放补开的发票)里散落着发票 PDF,名单 xlsx 还没标状态。这个 skill 把两步收尾动作固化下来。
|
||
|
||
## 输入
|
||
|
||
- **PDF 目录**:一个或多个,含发票 PDF。两种文件名形态都支持:
|
||
- 自动流水线:`YYYYMMDD_HHMMSS_真实姓名_脱敏名.pdf`(姓名已在名里)
|
||
- 官方下载:`<长数字>-电子发票[ (n)].pdf`(姓名还没加,需要先第 1 步)
|
||
- **名单 xlsx**:至少有「姓名」列(默认第 2 列),第一行是表头。
|
||
|
||
## 两步流程
|
||
|
||
### 第 1 步 · 给 PDF 加姓名
|
||
|
||
只对**还没有姓名**的 PDF(官方下载那种)需要。用现成脚本,从 PDF 正文里抽脱敏证件号后面的乘客名,插进文件名:
|
||
|
||
```bash
|
||
# 先干跑看结果
|
||
python3 scripts/add_invoice_passenger_name.py "<PDF目录>"
|
||
# 确认无误再落地
|
||
python3 scripts/add_invoice_passenger_name.py "<PDF目录>" --apply
|
||
```
|
||
|
||
`YYYYMMDD_...` 那种文件名里已带姓名,跳过本步。
|
||
|
||
### 第 2 步 · 名单标状态 + 附链接
|
||
|
||
扫所有 PDF 目录建「姓名 → PDF」映射,在 xlsx 尾部追加两列:`开票状态`(已开票 / 未开票)和 `发票PDF`(文件名 + `file://` 超链接):
|
||
|
||
```bash
|
||
python3 scripts/annotate_roster_invoices.py "<名单.xlsx>" "<PDF目录1>" ["<PDF目录2>" ...]
|
||
```
|
||
|
||
例(本次的用法,主目录 + 手动补开目录):
|
||
|
||
```bash
|
||
python3 scripts/annotate_roster_invoices.py \
|
||
"output/01/测试名单-成都(1).xlsx" \
|
||
"output/01" "output/01/手动"
|
||
```
|
||
|
||
常用可选项(默认值通常够用):
|
||
- `--sheet 名单` 指定工作表(默认第一个 sheet)
|
||
- `--name-col 2` 姓名所在列(1-based,默认 2)
|
||
- `--status-header` / `--link-header` / `--done-label` / `--missing-label` 改列名和标签文案
|
||
|
||
## 收尾核对
|
||
|
||
脚本跑完会打印:
|
||
- `matched rows`:匹配上发票的人数
|
||
- `roster without pdf`:名单里没找到发票的人 → 大概率是**没开成/漏开**,回报给用户
|
||
- `pdf without roster`:有发票但名单里没有的名字 → 大概率是**姓名不一致或多开**,人工核对
|
||
|
||
姓名匹配前会去掉空格和全角空格(`王 艳`、`王楚渃 ` 这类),但错别字/异体字不会自动对齐,落在 `without pdf` 里就要人工看。
|
||
|
||
## 硬规则
|
||
|
||
- xlsx 是**原地改写**,跑之前确认是副本或已受 git 跟踪;本项目 `output/` 在 `.gitignore` 里,改坏了没有历史,先备份。
|
||
- 不删任何 PDF;第 1 步只重命名,且遇到重名会自动加 `_2` 后缀。
|
||
- 不覆盖原始发票资料含义,只往文件名/表格尾部**追加**信息。
|