请款单 · 节点到了就开票,钱到了就核销
合同签完只是开始:哪个节点该请款、开了多少票、回了多少款、还有哪一期的钱压了三个月没人催,
这些通常散在项目经理的 Excel、财务的台账和一堆微信截图里,月底对一次账要花半天。
本技能吃的是一张请款计划表(期次 / 节点名称 / 计划请款日 / 请款金额 / 税率 / 已开票金额 /
开票日期 / 已收款金额 / 收款日期 / 备注),吐出的是三份能直接拿去走审批的东西:请款单 DOCX
(含人民币金额大写)、收款台账 XLSX(请款计划 / 到款核销 / 账龄分析 / 汇总看板四张表)、
收款结算摘要 MD。金额再脏也能读:12,000、¥12000、12000.50、8,650.75 都能落到同一个口径上。
为什么选它(最硬的差异点):纯标准库、本地离线运行,不依赖 openpyxl / python-docx,无需
pip install,合同与回款数据不联网、不离开本机。同类「请款单」工具大多是网页表单模板(要把客户名称、
金额、账号粘到别人的网站上)或要求先装第三方库;本包只用 Python 自带模块手写 OOXML,断网可用,
也没有依赖冲突。
身份定位
本包是「合同履行执行阶段」的财务跟进工具,站在项目经理 / 商务 / 财务专员的工位上,
回答的是「这一期该申请多少钱、票开了没有、钱到账没有、压了多久、该谁去催」。
它与「报价」类包的分工是一刀切的:
- 报价类 skill 管签前:算成本、定价格区间、做投标报价打分——那一步不归本包管。
- 本包管签后:合同金额排成一串期次节点之后,请款、开票、到款核销、账龄催办这一整条执行链。
- 不提供法律意见:催款函措辞、逾期违约金主张、诉讼时效判断请转法务,本包只给数据底稿与台账。
执行原则
- 以「票款两条线」为口径。 未开票 = 请款金额 − 已开票金额;未收余额 = 已开票金额 − 已收款金额;
两笔各自独立向下取整到 0,绝不用一个「欠款」糊过去。 - 逾期只对真欠款算。 未收余额 > 0 的行才计逾期天数(基准日 − 计划请款日,负数记 0);
票都没开的行不进账龄,进「待开票」,避免虚构催收对象。 - 金额口径统一用 Decimal。 全链路 Decimal 计算、分位四舍五入,最后才转 float 写 xlsx,
不让浮点误差把 8,650.75 写成 8,650.74。 - 金额大写照票据规矩写。 零/壹/贰/叁…拾佰仟万亿、元角分、整,覆盖 0、整万元、有角分、
超过亿元、纯角/纯分等情形,并带 25 条单元自测(--selftest)。 - 产物不进包。 一切输出只落在
_test/payment-request-kit-out/(或--out-dir指定目录),
样例数据同样写在产物目录,包内永远只有 SKILL.md 与 scripts。 - 只用标准库、不联网。 无网络请求,无
subprocess/eval/exec,不引入任何第三方库。
适合谁
- 项目经理 / 交付负责人:节点验收完要发起请款,得知道请哪几期、还剩多少没收。
- 商务 / 销售:对着甲方财务催款,要一份能发邮件的请款单和账龄底稿。
- 财务 / 会计:月度开票与回款对账,要把开票率、回款率、逾期笔数一次性摆出来。
- 中小团队负责人:手上同时跑好几个项目,需要一张台账看清哪些钱卡在哪一期。
何时使用
CRITICAL: 只要用户提出要开一份请款单、要发一期付款申请给甲方、要统计哪几笔钱还没回来、
要算账龄或逾期多久、要做开票与回款台账,就必须使用本 skill,即使看起来可以用别的方式解决。
- 到了某个付款节点(预付款、到货款、验收款、质保期满款),要生成请款单走内部/甲方审批。
- 月底或季度末要盘一遍:开票率多少、回款率多少、哪几期欠着、平均压了多少天。
- 想按 0-30 / 31-60 / 61-90 / 90+ 分档排催办优先级,并把建议动作写进给老板的汇报里。
- 财务要一张能直接打开筛选的台账(谁核销了、谁还没核销、收款日期升序)。
- 需要把金额写成中文大写填进票据或合同付款条款。
不适用:测算报价与投标报价上去多少合适(那是报价类 skill 的活);开具真实增值税发票、
对接税控盘与发票池;银行流水自动对账与 OCR 识别回单;诉讼时效、逾期利息、违约金主张等
需要法律判断的事项;多币种折算、外币结算与供应链金融贴现。这类需求请用对应的专业工具或转财务/法务。
怎么用
# 1) 内置样例端到端(产物落在项目根 _test/payment-request-kit-out/,不写进包内)
python scripts/payment_request.py --sample
# 2) 用自己的请款计划表生成三件套
python scripts/payment_request.py --file 请款计划.csv --out-dir ../_test/out
# 3) 读财务导出的 xlsx(指定工作表名)
python scripts/payment_request.py --file 台账.xlsx --sheet 请款计划
# 4) 按指定基准日重算逾期(默认今天)
python scripts/payment_request.py --file 请款计划.csv --as-of 2026-09-30
# 5) 脚本串联:只要 JSON 摘要
python scripts/payment_request.py --file 请款计划.csv --json
# 6) 只跑人民币金额大写的单元自测
python scripts/payment_request.py --selftest
在对话里可以直接说:「按这份请款计划出一版请款单和收款台账」,并给出文件路径。
常用参数:
| 参数 | 作用 |
|---|---|
--file <csv/xlsx路径> |
输入请款计划表,首行为表头,缺列按缺省值处理 |
--out-dir <目录> |
输出目录,缺省 _test/payment-request-kit-out/ |
--sheet <工作表名> |
输入为 xlsx 时指定工作表,缺省取第一个 |
--as-of YYYY-MM-DD |
逾期与账龄的基准日,缺省今天 |
--project-code <编号> |
写进请款单副标题的项目编号 |
--json |
额外输出结构化摘要(总额、已收、未收、逾期笔数、账龄分布)到 stdout |
--sample |
内置样例端到端生成,同时导出一份样例 CSV 便于照着填 |
--selftest |
只跑金额大写单元自测,25 条用例全过返回 0 |
退出码:0 成功,1 失败(输入文件缺失、格式不支持、表头为空、无数据行、参数写错)。
所有失败都以一行 [错误] … 报出原因,不会抛 traceback。
输入与算法
输入是首行为表头的一张表,十列,可以缺列(缺了按缺省值走):计划日期缺失则不进逾期,
开票/收款日期缺失则该行不落到账核销台账。
| 列名 | 作用 | 缺省值 |
|---|---|---|
| 期次 | 台账主键,如 P1 / 第1期 | 自动编号 |
| 节点名称 | 请款节点,如到货款、验收款 | 未命名节点 |
| 计划请款日 | 合同约定的付款日,逾期的起算点 | 空(不进逾期) |
| 请款金额 | 该节点应收金额,容错解析 ¥12,000 / 12,000.50 |
0 |
| 税率 | 票面税率,6% / 13% / 0.06 均可,只作展示不参与金额计算 |
6% |
| 已开票金额 | 累计开票额 | 0 |
| 开票日期 | 最近一次开票日 | 空 |
| 已收款金额 | 累计到账额 | 0 |
| 收款日期 | 最近一次到账日 | 空 |
| 备注 | 带进台账与摘要 | 空 |
计算口径:
| 指标 | 口径 |
|---|---|
| 未开票 | 请款金额 − 已开票金额,小于 0 记 0 |
| 未收余额 | 已开票金额 − 已收款金额,小于 0 记 0 |
| 逾期天数 | 仅未收余额 > 0 的行:基准日 − 计划请款日,负数记 0 |
| 账龄分档 | 0-30 / 31-60 / 61-90 / 90+,按逾期天数归档 |
| 状态 | 已结清(未收为 0 且已开票等于请款额)> 逾期(逾期天数 > 0)> 待开票(有未开票)> 部分收款 |
| 开票率 / 回款率 | 已开票 ÷ 请款总额 / 已收款 ÷ 请款总额 |
账龄分档对应的催办建议:0-30 正常跟进、31-60 电话催办、61-90 发催款函、90+ 升级处理。
输出
| 文件 | 内容 |
|---|---|
请款单.docx |
标题「请款单」+ 项目编号副标题;合同/双方/期次/日期键值区;本期请款明细表(8 列,含合计行);金额大写行;付款方式与账户信息占位(【待填写】);样张提示;甲乙方签署栏 |
收款台账.xlsx |
四张表:请款计划(11 列,金额 money 格式,逾期天数 > 0 标红)/到款核销(按收款日期升序,含已核销/部分核销)/账龄分析(四档 + 合计,含占比与催办建议)/汇总看板(合同总额、已请款、已开票、已收款、未收余额、开票率、回款率、逾期笔数、平均逾期天数) |
收款结算摘要.md |
一期一行的 Markdown 汇总表 + 开票率/回款率/未收大写/逾期统计的脚注 |
请款计划样例.csv |
仅 --sample 生成,可直接照着改成自己的真实数据 |
终端摘要 / --json |
上述核心指标与四个档位的笔数金额占比 |
账户、开户行、纳税人识别号等涉及付款安全的信息一律留【待填写】,不臆造。
设计边界
- 只按输入表里的数据说话:表外没有隐藏假设,也不会替用户猜行业规则;
阶梯付款、保函替换、背靠背付款等复杂条款,请先在表里拆成一行一个节点。 - 逾期天数按自然日计算,不区分工作日、节假日与账期宽限;没有合同约定的宽限期概念。
- 「状态」只有已结清 / 逾期 / 待开票 / 部分收款四种,足够驱动日常跟催,不替代项目会计的收入确认口径。
- 金额大写遵循常见票据写法(只有角写作「X角整」、只有分写作「零X分」、无角无分以「整」收尾),
若付款方票据另有成文规则,请按其规则复核后再用。 - 不访问任何外部系统:不连税控、不查银行流水、不做发票真伪检验,也不替用户发送任何文件或邮件。
--sample的样例日期按基准日回推生成,每次运行的绝对值不同,但四档账龄都会出现。- 产出的 docx / xlsx 是真实可编辑的 Office 文件,打印或发出前请通读一遍,尤其是账户与税号。
依赖
纯标准库,无需安装任何包,本地离线运行。 只用 zipfile / csv / argparse / json /
datetime / decimal / xml 等 Python 自带模块,自己手写 OOXML 并用 zipfile 打包:
- 不依赖
openpyxl/python-docx/pandas/lxml等任何第三方库,不需要pip install; - 不做任何网络请求,请款金额、账号、客户名称全程留在本机;
- 不启动
subprocess、不使用eval/exec,不调用 Office / LibreOffice / WPS 等外部程序。
相对「请款单」池里依赖网页表单模板或第三方库的方案,这是本包最大的差异点。需要 Python 3.8 及以上。