Files
Auto-Finance/README.md
2026-06-09 16:25:20 +08:00

258 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 财务报销自动化
自动从 PDF 发票提取信息,生成发票汇总表与易耗品出库单,并可选在财务系统中自动填报报销单。
**支持发票类型区分**:系统自动识别高铁票、酒店住宿等差旅发票与普通发票。差旅发票不生成易耗品出库单,走差旅报销流程;普通发票生成出库单,走普通报销流程。
## 项目结构
```
├── pyproject.toml # 项目配置(依赖、工具链)
├── uv.lock # 依赖锁定文件
├── Makefile # 任务脚本(跨平台)
├── tasks.py # 任务脚本Windows 兼容)
├── config.json # 配置文件(登录凭据、默认值等)
├── config.example.json # 配置示例
├── 易耗品、出库单.doc # 易耗品出库单 Word 模板
├── src/
│ ├── __init__.py # 包初始化 / 日志器
│ ├── config.py # 配置加载
│ ├── bot.py # 浏览器自动填报
│ ├── pipeline.py # CLI 流程编排
│ ├── main.py # CLI 入口
│ ├── doc/ # 文档处理模块
│ │ ├── extractor.py # 编排入口:串联 PDF 读取 → LLM 提取 → 分类
│ │ ├── pdf.py # PDF 文件发现与文本提取
│ │ ├── llm_extractor.py # LLM 信息提取
│ │ ├── invoice.py # 发票类型常量、分类逻辑、CSV 读写工具
│ │ ├── fill_consumable_doc.py # 将 CSV 填入易耗品出库单Word COM
│ │ ├── prompt.py # LLM 提示词模板
│ │ └── prompts/ # 提示词模板文件
│ └── web/
│ ├── app.py # Web 服务入口
│ ├── templates/
│ │ ├── index.html # PC 端主页
│ │ └── mobile_upload.html # 移动端扫码上传
│ ├── static/ # 前端 CSS / JS
│ └── uploads/ # 按会话隔离的上传与产物目录
├── tests/ # 测试目录
├── *.pdf # 发票 PDFCLI 模式,放在项目根目录)
├── invoice_summary.csv # 发票汇总表CLI 产物)
└── images/ # 浏览器调试截图
```
## 数据流
```mermaid
flowchart TB
PDF[PDF 发票] --> Extract[extractor 提取]
Extract --> Classify{发票类型分类}
Classify -->|差旅发票| Travel[高铁票 / 酒店住宿]
Classify -->|普通发票| General[普通发票]
Travel --> CSV[(invoice_summary.csv)]
General --> CSV
CSV -->|仅普通发票| Fill[fill_consumable_doc]
Fill --> Doc[易耗品、出库单.doc]
CSV --> Bot[bot 浏览器自动化]
Bot -->|差旅模式| Submit_T[差旅报销填报<br/>TODO]
Bot -->|普通模式| Submit_G[普通报销填报]
```
## 环境要求
- **Python 3.12+**
- **uv** 包管理器([安装指南](https://docs.astral.sh/uv/getting-started/installation/)
- Windows易耗品出库单填写依赖 Microsoft Word + COM仅 Windows 可用)
## 快速开始
### 1. 安装依赖
```bash
# 同步所有依赖(运行时 + 开发工具)
make install
# Windows 上等效命令:
python tasks.py install
```
项目使用 `uv` 管理依赖,所有包版本锁定在 `uv.lock` 中,确保可复现。
| 依赖 | 用途 |
|------|------|
| pdfplumber | PDF 发票文本提取 |
| playwright | 财务系统浏览器自动化 |
| flask | Web 服务 |
| pywin32 | 填写 Word 出库单(`fill_consumable_doc` |
### 2. 准备数据CLI 模式)
将发票 PDF 放在项目根目录下。
### 3. 配置
编辑 `config.json`
```json
{
"username": "你的工号",
"password": "你的密码",
"default_name": "默认报销人姓名",
"default_card_no": "默认公务卡号",
"default_person_id": "默认人员编号",
"consumable_storage": "躬行楼 C205"
}
```
| 字段 | 说明 |
|------|------|
| `username` / `password` | 信息门户登录凭据 |
| `default_name` | 默认报销人姓名 |
| `default_card_no` | 默认公务卡号 |
| `default_person_id` | 默认人员编号(工号) |
| `consumable_storage` | 出库单「存放地点」列默认值 |
| `sso_login_url` 等 | 系统 URL一般无需修改 |
### 4. 运行CLI
```bash
# 全流程(发票提取 → 浏览器填报)
make run
# Windows 等效:
python tasks.py run
# 仅执行某一步
uv run python src/main.py --step invoice # 仅发票提取
uv run python src/main.py --step submit # 仅浏览器填报
# 覆盖配置中的登录凭据
uv run python src/main.py -u 工号 -p 密码
```
### 5. 填写易耗品出库单CLI
需已生成 `invoice_summary.csv`,且本机已安装 **Microsoft Word**
```bash
uv run python -m src.doc.fill_consumable_doc
uv run python -m src.doc.fill_consumable_doc --csv invoice_summary.csv --doc "易耗品、出库单.doc"
uv run python -m src.doc.fill_consumable_doc --no-backup # 不生成 .doc.bak 备份
```
填写规则概要:
- 表头「日期」使用**填写当天**的日期(非发票开票日期)
-`规格型号` 解析品名、规格、单位、数量、单价;`价税合计` 写入金额列
- 单价/金额保留两位小数;表格内统一为 **宋体五号10.5 磅)**
- 存放地点取自 `consumable_storage`;购货人/领用人签字、备注保持空白
## 执行步骤说明
| 步骤 | 命令 | 说明 |
|------|------|------|
| 发票提取 | `--step invoice` | 扫描根目录 PDF生成 `invoice_summary.csv` |
| 浏览器填报 | `--step submit` | 登录信息门户 → 报销系统 → 自动填单、上传附件 |
> 分步执行时,上一步的 CSV 会自动成为下一步的输入。
### CSV 字段说明
| 列名 | 说明 |
|------|------|
| 序号 | 行号 |
| 发票类型 | 自动识别:`高铁票` / `酒店住宿` / `普通发票` |
| 发票号码 | 电子发票号码 |
| 开票日期 | 开票日期 |
| 项目名称 / 规格型号 | 货物或应税劳务信息(差旅发票为出发站→到达站) |
| 价税合计 | 发票含税金额 |
| 销售方名称 | 销方名称 |
| 出发站 / 到达站 / 车次 / 乘车日期 / 座位等级 | 高铁票专用字段 |
| 人员姓名 / 刷卡日期 / 公务卡号 / 刷卡金额 | 可手工或 Web 端编辑补充 |
| 备注 / 工号 | 可手工或 Web 端编辑补充 |
## Web 服务
提供浏览器界面:上传文件 → 自动处理 → 在线编辑 → 下载产物 → 可选提交财务系统。
```bash
uv run python src/web/app.py
```
访问 `http://localhost:5000`
### 推荐使用流程
1. 上传 PDF或上传已有 CSV
2. 填写配置(账号、密码、姓名、公务卡号、存放地点等),可上传 `config.json` 一键填充
3. 点击 **开始处理** — 完成发票提取、生成 CSV系统自动识别发票类型并分类统计
4. **普通发票**:自动生成 **易耗品、出库单.doc**,可下载
5. **差旅发票**(高铁票/酒店住宿):跳过出库单生成,直接进入差旅报销流程
6. 在表格中核对、修改发票数据(提交财务系统前会自动保存)
7. 确认无误后点击 **提交到财务系统**
### 处理模式
| 模式 | 入口 | 说明 |
|------|------|------|
| **PDF 模式** | 上传 PDF | 提取发票 → 生成 CSV + 自动分类 → 普通发票生成出库单 |
| **CSV 快捷模式** | 仅上传 CSV | 跳过提取,读取 CSV 中的发票类型,按需生成出库单 |
### 发票类型区分
系统自动识别以下发票类型并按类型分流:
| 发票类型 | 识别依据 | 出库单 | 填报模式 |
|----------|----------|--------|----------|
| **高铁票** | 含"电子客票"、"中国铁路"、"12306"等关键词 | 不生成 | 差旅报销TODO |
| **酒店住宿** | 含"住宿费"、"餐饮服务"、"租赁服务"等关键词 | 不生成 | 差旅报销TODO |
| **普通发票** | 其他所有发票 | 自动生成 | 普通报销(已实现) |
当同一批次同时包含差旅发票和普通发票时,系统会为普通发票生成出库单,并在填报时分别处理。
### 功能一览
| 功能 | 说明 |
|------|------|
| 发票提取 | 上传 PDF 后自动完成 |
| 发票类型自动分类 | 高铁票/酒店住宿/普通发票,自动分流处理 |
| 易耗品出库单 | 仅普通发票自动生成 Word差旅发票跳过 |
| 表格在线编辑 | 处理完成后可修改 CSV 各字段;保存后重新生成出库单 |
| 财务系统填报 | 单独按钮触发,处理阶段不会自动提交 |
| 实时日志 | SSE 推送处理进度 |
| 配置上传 | 支持上传 `config.json` 填充表单 |
| 手机扫码上传 | 二维码打开移动端页面拍照上传PC 端轮询同步 |
> Web 端浏览器填报以无头模式运行。未上传 PDF 时,填报阶段会跳过附件上传。
> 出库单生成需要 **Windows + Word + pywin32**若失败页面会显示具体原因CSV 等其它产物仍可正常使用。
接口说明见 [API.md](./API.md)。
## 开发任务
项目提供统一的任务脚本,支持跨平台使用:
| 任务 | Makefile | tasks.py | 说明 |
|------|----------|----------|------|
| 安装依赖 | `make install` | `python tasks.py install` | 同步依赖 + 安装 pre-commit |
| 代码检查 | `make check` | `python tasks.py check` | Ruff lint + 格式化 + MyPy 类型检查 + deptry 依赖检查 |
| 运行测试 | `make test` | `python tasks.py test` | pytest + 覆盖率报告 |
| 运行 CLI | `make run` | `python tasks.py run` | 执行全流程 |
| 清理缓存 | `make clean` | `python tasks.py clean` | 删除虚拟环境和缓存 |
## 代码质量
项目配置了完整的代码质量工具链:
- **Ruff** — 快速 lint 检查和代码格式化(替代 flake8 + isort + black
- **MyPy** — 严格模式类型检查(`strict = true`
- **deptry** — 检测未声明、未使用、过时依赖
- **pre-commit** — 提交前自动运行 Ruff 检查和格式化
所有检查通过后方可提交代码。
## 注意事项
- 浏览器填报时会打开或使用 Chromium请勿手动干扰自动化流程
- 调试截图保存在 `images/` 目录
- 项目根目录需保留 `易耗品、出库单.doc` 模板Web 每次从模板复制到会话目录再填写,不修改原模板
- `config.json` 含敏感信息,请勿提交到公开仓库
- **发票类型区分**:差旅发票(高铁票/酒店住宿不会生成易耗品出库单当前差旅报销填报流程仍在开发中TODO