用途
invoice 技能用于根据客户计费数据生成专业的 PDF 发票,适合需要向客户开具账单的咨询、自由职业或服务类场景。它支持固定费用(fixed-fee)和按小时(hourly)两种计费方式,并自动递增发票编号。
主要能力
- 支持固定费用与按小时计费。
- 发票编号自动递增:扫描输出目录中匹配 invoice-#*.pdf 的文件,取最大编号 N,新发票使用 N+1;若无历史发票则从 1 开始。
- 客户匹配:根据客户 slug 或别名(不区分大小写)匹配客户 YAML 文件;若未找到,会列出可用客户并提示选择。
- 交互式补全:未通过参数提供的字段(描述、金额、账期、数量、备注)会提示用户输入。
- 按小时模式:交互式收集多个明细项(描述、小时数、费率),金额按小时数 × 费率计算,并循环询问是否继续添加。
- 日期计算:发票日期为当天,到期日为当天 + NET 天数,格式为 MM/DD/YYYY。
- 生成临时 YAML 配置,合并客户信息、sender 信息和明细项,调用生成脚本输出 PDF,完成后删除临时配置。
- 支持自定义 logo:若客户目录的父目录存在 logo 覆盖文件,则使用 --logo 参数;否则使用内置默认 logo。
- 生成后展示 PDF 供审阅,报告发票编号、客户、金额、到期日和文件路径,并询问是否提交;若批准,则用类似
feat: Generate <client> invoice #N ($X,XXX)的消息提交。
使用方式
命令格式:/invoice <client> [description] [amount] [options]
示例:
- 完整内联,立即生成:
/invoice validcodes "AI Training Pack" 7500 --net 15 - 仅客户,提示输入明细和条款:
/invoice validcodes - 带备注:
/invoice validcodes "Sprint Phase 1" 40000 --net 1 --notes "50% upfront per SOW" - 按小时,交互模式支持多个明细项:
/invoice acme --hourly - 自定义数量:
/invoice validcodes "Advisory Call" 300 --quantity 4 --net 15
参数说明:
| 参数 | 必填 | 默认值 | 说明 |
|---|---|---|---|
client |
是 | — | 客户 slug 或别名(匹配客户 YAML 文件) |
description |
否 | 提示输入 | 明细项描述 |
amount |
否 | 提示输入 | 总金额(美元) |
--net N |
否 | 客户默认或 15 | 付款条款(NET-N 天) |
--quantity N |
否 | 1 | 明细项数量 |
--notes "..." |
否 | 无 | 显示在总额下方的备注 |
--hourly |
否 | false | 交互模式,支持多个明细项及费率 |
配置要求
需要配置以下目录:
| 路径 | 用途 | 示例 |
|---|---|---|
| 客户目录 | 存放含计费信息的 YAML 文件 | 02_Areas/consulting/templates/invoicing/clients/ |
| 输出目录 | 生成的 PDF 保存位置 | 02_Areas/consulting/invoices/ |
| Logo 覆盖 | 可选自定义 logo | 02_Areas/consulting/templates/invoicing/logo.png |
生成脚本、HTML 模板和默认 logo 随本技能捆绑提供。
客户 YAML 结构
在客户目录中为每个客户创建一个 YAML 文件:
# clients/acme.yaml
name: "Acme Corporation"
aliases: [acme, acme-corp]
default_net: 30
| 字段 | 必填 | 说明 |
|---|---|---|
| name | 是 | 发票上的完整法定名称 |
| aliases | 否 | 用于匹配的替代名称(不区分大小写) |
| default_net | 否 | 该客户的默认付款条款(回退值:15) |
发送方信息
在客户 YAML 文件所在目录创建 sender.yaml:
# clients/sender.yaml
name: "Your Name"
address_1: "123 Main St"
address_2: "City, ST 12345"
生成器从临时配置读取发送方信息,填充发票上的“Pay to”区块。
依赖
生成器需要通过 uv 安装 Python 包:
uv run --with weasyprint --with pyyaml --with jinja2 python3 generate-invoice.py <config.yaml>
工作流程
- 读取第一个参数作为客户标识。
- 在客户目录中匹配所有 YAML 文件:文件名(不含 .yaml)不区分大小写匹配参数,或 aliases 数组包含参数(不区分大小写)。若无匹配,列出可用客户并提示选择。
- 加载匹配客户的计费信息。
- 收集发票明细:未提供的字段会提示输入描述、金额、NET 条款(优先 --net,其次客户 default_net,最后回退 15)、数量(默认 1)、备注(可选)。按小时模式则交互收集多个明细项。
- 确定发票编号:扫描输出目录中 invoice-#*.pdf,取最大编号 N,新编号为 N+1;无历史则从 1 开始。
- 生成发票:计算发票日期和到期日,格式化日期,创建客户 slug,写入临时 YAML 配置(合并客户、sender、明细项),确定技能目录,检查 logo 覆盖,运行生成器,删除临时配置。
- 审阅与提交:展示 PDF,报告发票编号、客户、金额、到期日、文件路径,询问是否正确并提交;若批准则暂存并提交,否则返回调整。
适用场景
- 咨询顾问、自由职业者向客户开具固定费用或按小时计费的发票。
- 需要自动递增发票编号并保持客户计费信息集中管理的场景。
- 需要生成带自定义 logo 和付款条款的专业 PDF 发票。
限制
- 金额单位为美元(USD)。
- 需要预先配置客户目录、输出目录和 sender.yaml。
- 依赖 uv 及 weasyprint、pyyaml、jinja2 等 Python 包。
- 发票编号基于输出目录中已有 PDF 文件名推断,若文件命名不规范可能影响编号。
- 其他未在资料中说明的功能、收费、价格、平台或效果暂未提供。