智能财务报销助手(Finance Assistant)

Other

智能财务事项与报销跟踪系统。它能够对多公司、多发票抬头进行智能化管理,从发票文件的接收、解析、分类存储到最终报销,提供一站式全生命周期的跟踪与提醒服务。支持PyMuPDF智能发票解析归档、发票缺漏智能补录及重要财务日程提醒。

Install

openclaw skills install finance-assistant

智能财务报销助手 (Finance Assistant)

概述

为[老板]管理的财务事务提供三大类跟踪:

  1. 有发票 — 记录发票信息,跟踪报销状态,未报销的每周提醒
  2. 无发票 — 记录已发生费用,提醒开发票
  3. 重要财务事项 — 税务、对账、申报等大事协助处理

关键概念:公司 vs 抬头

[老板]管多家公司,但发票抬头(开票法律主体)可能不同:

  • 公司 — 业务归属(例如:[公司A]、[公司B]、[公司C]、[公司D]、[公司E])
  • 抬头 — 发票上的购买方法律实体名称(各公司注册的正式全称,或代开票平台)

一张发票必须有抬头字段,公司字段用于确认这笔费用归属给哪家业务单元。参考 references/headers.md 查看已知抬头映射。

数据存储

所有财务记录存储在 ~/finance/ 目录下(或用户指定的财务工作目录下):

文件原件目录 ~/finance/invoices/

发票原件(PDF/OFD/照片/扫描件)按**公司名(短名)**分目录存放,便于快速查找:

~/finance/invoices/
├── [公司A]/            ← 公司短名,对应抬头:[公司A全称]
│   ├── YYYY-MM-DD_[出发地]-[目的地]_机票_[金额].pdf
│   └── YYYY-MM-DD_[出发地]-[目的地]_机票_[金额].pdf
├── [公司B]/
│   ├── YYYY-MM-DD_[目的地]-高铁_[金额].pdf
│   └── [发票名A].pdf
├── [公司C]/
│   └── [发票名B].pdf
├── [公司D]/            ← 暂无数据
└── [公司E]/            ← 暂无数据
  • 文件名格式日期_摘要_金额.扩展名(发票原始文件名也可保留,方便查发票号)
  • OFD格式:与PDF放在同一目录下,同名共存
  • 抬头→公司映射表:存在 references/headers.md

1. 发票报销记录 ~/finance/invoices.md

格式(按添加时间倒序):

| 日期 | 金额 | 摘要 | 公司 | 抬头 | 发票号 | 原件 | 状态 | 备注 |
|------|------|------|------|------|--------|------|------|------|
| YYYY-MM-DD | ¥1,200 | 办公用品采购 | [公司B] | [公司B全称] | INV-YYYY-001 | [查看](file://...pdf) | ✅已报销 | MM/DD到账 |
| YYYY-MM-DD | ¥800 | 交通费 | [公司D] | [抬头D] | INV-YYYY-002 | - | ⏳待报销 | 发票已交财务 |
  • 原件列:链接 to ~/finance/invoices/<抬头名>/ 下的原始文件
  • 状态字段:✅已报销 ⏳待报销 ❌已作废
  • [老板]问起某张发票时,直接给出原件文件和详细信息

2. 无发票费用记录 ~/finance/no_invoice.md

格式:

| 日期 | 金额 | 摘要 | 公司 | 抬头 | 提醒次数 | 备注 |
|------|------|------|------|------|---------|------|
| YYYY-MM-DD | ¥300 | 午餐会议 | [公司C] | [公司C的客户/代开票抬头] | 2次 | 已联系财务补开 |

3. 重要财务事项 ~/finance/important.md

格式:

| 日期 | 事项 | 截止日期 | 状态 | 备注 |
|------|------|---------|------|------|
| YYYY-MM-DD | 季度增值税申报 | YYYY-MM-DD | 🔴待处理 | 需要财务数据 |

4. 每周汇总 ~/finance/weekly_summary.md

每周一自动生成,汇总本周待处理事项。

工作流程

当[老板]要求生成报销单(飞书文档)时

当发票积攒到一定量或[老板]明确说"生成报销单"时,直接调用报销单生成工具(例如 [飞书报销单生成器] 等相关技能)处理全流程:

  • 读取发票数据 → 创建报销文档(含完整明细) → 添加编辑权限 → 打包zip → 发到与[老板]的聊天中

不要在此技能内重复实现,保持职责分离。

当[老板]发来发票文件(PDF/图片)时

  1. 保存原件 → 用 PyMuPDF 读取PDF内容,提取购买方名称(抬头)和金额
  2. 按抬头归类 → 将文件保存到 ~/finance/invoices/<抬头名>/日期_摘要_金额.pdf
  3. 解析信息 → 提取:日期、金额、摘要、抬头(购买方名称)、发票号
  4. 确认归属公司 → 查 headers.md 映射表,如果找不到则问[老板]这笔费用归属哪家公司
  5. 写入 invoices.md → 状态标记为 ⏳待报销
  6. 确认完成 → 汇总告知[老板]

当[老板]口头告知发票信息时

  1. 问清楚:日期、金额、摘要、公司(归属)、抬头(开票实体)
  2. 如果[老板]只说了公司名但没抬头,按 headers.md 默认映射填写
  3. 写入 invoices.md,状态 ⏳待报销

当[老板]说某费用没发票时

  1. 记录费用信息到 no_invoice.md(含抬头字段)
  2. 设置提醒:下周再问是否已开发票

当[老板]提出财务问题时

  1. 判断属于哪类,记录到 important.md
  2. 如果需要进一步处理(税务咨询等),主动协助搜索信息

⚠️ 读取中文记录文件的正确姿势(关键陷阱)

read_file 工具可能会遇到乱码或截断中文内容(CJK编码显示问题)。在读取中文Markdown文件时,建议使用更稳妥的系统读取命令:

# ✅ 推荐读取方式:使用执行环境的底层命令读取(如 cat 等命令)
# 或在代码中指定 utf-8 编码读取
with open('~/finance/invoices.md', 'r', encoding='utf-8') as f:
    content = f.read()

验证技巧:如果怀疑文件读取不完整,可以先确认文件行数,再检查内容。

⚠️ 必用:PyMuPDF 发票解析验证清单

本技能最频繁的犯错点: 中国电子发票左右栏容易看反。每次解析PDF后必须按以下步骤验证,缺一不可:

步骤1:提取原始文本

import pymupdf
doc = pymupdf.open("发票.pdf")
text = ""
for page in doc:
    text += page.get_text()
print(text)

步骤2:提取所有公司名称+税号对

从文本中找到所有出现的公司全称及紧邻的税号/信用代码。通常电子发票上有且只有两家公司:

角色可能性示例
公司A + 税号A[公司A全称] + [公司A税号]
公司B + 税号B[供应商A全称] + [供应商A税号]

步骤3:匹配税号到已知数据(强制步骤

打开 references/headers.md,用已知公司税号反推:

  • 已知的税号 → 该公司是 [老板]的公司
  • 未知的税号 → 很可能是 供应商/客户

这是最可靠的判断方法,必须在向[老板]报告前完成。

步骤4:判断角色

  • [老板]的公司 → 是购买方(抬头/报销方)还是销售方?根据发票类型判断:
    • 支出报销:[老板]的公司应当是购买方
    • 收入开票:[老板]的公司应当是销售方
  • 供应商/客户 → 就是对方角色

步骤5:确认一致性

  • 购买方名称是否与 headers.md 中该公司的抬头一致?
  • 金额是否与[老板]口头告知的一致?
  • 不一致时:先不要汇报结论,把提取结果原样贴给[老板]确认

⚠️ 关键陷阱回顾

  • 绝对不要仅凭 PyMuPDF 文本前后顺序判断购买方/销售方 — 左右双栏布局让文本流顺序不可靠
  • 一些知名的开票代理平台/机票代理公司始终是销售方/开票平台,不是购买方抬头
  • 税号匹配是黄金法则 — 比文本顺序可靠得多

当[老板]口头告知发票信息(先记后补模式)

[老板]经常先口头说"先记上",之后再发PDF文件。流程:

  1. 先记录:按口头信息写入 invoices.md,发票号先用银行流水号,原件列留空
  2. 收到PDF后
    • 按上述验证清单解析PDF
    • 更新 invoices.md:修正发票号、添加原件链接、完善摘要
    • 保存PDF到 ~/finance/invoices/<公司名>/
  3. 前后对比:检查实际发票信息与口头记录是否一致,不一致时告知[老板]

各发票类型解析注意:

  • 电子发票(普通发票) — 标准格式,找 "购买方" 段下的 "名称:" 后跟的公司全称
  • 铁路电子客票(电子发票(铁路电子客票))— 格式特殊,购买方名称在 "购买方名称:" 行,金额在 "票价:¥" 行
  • 打车/出行电子发票 — 标准格式,找 "购买方信息 → 名称";行程单没有抬头信息,需关联对应的电子发票
  • OFD格式 — 可以先用OFD转PDF工具,或直接使用OFD解析库提取

每周提醒机制

每周一 10:00 — 待报销发票提醒

列出所有 ⏳待报销 的发票,按抬头分组(同一抬头可集中报销),提醒[老板]跟进。

每周一 10:05 — 无发票费用提醒

列出所有未开发票的费用,提醒[老板]联系补开。

每周一 10:10 — 重要事项提醒

列出所有未完成的重要财务事项。

cron 任务模板

# 每周一 10:00 发票报销提醒(按抬头分组)
schedule: "0 10 * * 1"
prompt: "执行财务跟踪周报:读取 ~/finance/invoices.md 中所有 ⏳待报销 的发票,按抬头分组汇总(同抬头可集中报销);读取 ~/finance/no_invoice.md 中未开发票的费用;读取 ~/finance/important.md 中未完成事项。生成周报发给[老板]。"
skills: ["finance-assistant"]
deliver: "origin"

# 每周一 10:05 无发票提醒
schedule: "0 10 * * 1"
prompt: "读取 ~/finance/no_invoice.md,列出所有还未开发票的费用记录(含抬头),提醒[老板]联系开票。每项费用的提醒次数+1。"
skills: ["finance-assistant"]
deliver: "origin"

# 每周一 10:10 重要事项
schedule: "0 10 * * 1"
prompt: "读取 ~/finance/important.md,列出所有状态为 🔴待处理 的重要财务事项,提醒[老板]注意截止日期。"
skills: ["finance-assistant"]
deliver: "origin"

公司列表与抬头映射

[老板]管理的多家公司,以及已知的发票抬头映射(详见 references/headers.md):

公司业务默认抬头
[公司A][业务类型A][抬头A]
[公司B][业务类型B][抬头B]
[公司C][业务类型C][抬头C]
[公司D][业务类型D][抬头D] (待确认)
[公司E][业务类型E][抬头E] (待确认)

更新记录的规则

  • [老板]告知已报销 → 状态改为 ✅已报销,添加到账日期
  • [老板]告知已开发票 → 从 no_invoice.md 移到 invoices.md
  • [老板]告知已完成某事项 → 状态改为 ✅已完成