第3章 应收管理(AR):从发票到回款的全链路实战
应收管理,说白了就是盯着客户把钱收回来。我做了这么多年ERP财务系统,发现很多开发同学容易把AR模块想简单了——不就是记个账嘛?其实不然。应收模块是财务系统里最考验业务理解深度的模块之一,因为它直接关系到企业的现金流。
今天我就带大家把AR模块的核心流程拆开揉碎了讲。嗯,咱们从业务流程开始。
3.1 应收模块的核心业务流程
先看一张我手绘的业务流转图(用文字描述):
销售订单 → 发货/出库 → 开票 → 应收确认 → 收款 → 核销 → 账龄分析
这个链条里,每个环节都可能出幺蛾子。我记得刚入行时,有个项目上线后客户投诉说应收余额对不上,查了一整天发现是开票环节和发货环节的时间差没处理好。
具体来说,业务流程包含这几个关键节点:
- 销售出库:货物发出,库存减少,但此时还没产生应收
- 开票确认:开具销售发票,正式确认应收账款
- 收款登记:客户打款,银行到账
- 核销处理:将收款与对应发票匹配,关闭应收
- 账龄分析:定期检查应收逾期情况
3.2 客户管理:不只是个通讯录
客户管理在AR模块里,绝不仅仅是存个公司名称和地址。我个人的习惯是把客户信息分为三层:
| 层级 | 字段示例 | 业务意义 |
|---|---|---|
| 基础信息 | 客户编码、名称、税号、地址 | 用于发票抬头、税务申报 |
| 信用信息 | 信用额度、账期、信用等级 | 控制应收风险 |
| 结算信息 | 银行账户、付款方式、对账周期 | 用于收款和对账 |
这里有个坑:很多系统把客户信息和财务信息混在一个表里。我建议分开设计,因为客户基础信息由销售部门维护,而信用和结算信息由财务部门维护。权限分离能避免很多麻烦。
3.3 发票处理:税务合规是底线
发票处理是AR模块里最敏感的部分。为什么?因为发票直接关联到税务申报,错一张发票可能让企业多交或少交几万块的税。
发票处理的核心流程:
- 发票生成:根据销售订单或发货单生成发票草稿
- 发票校验:检查金额、税率、客户信息是否正确
- 发票过账:正式生成应收凭证,更新总账
- 发票打印/导出:生成纸质发票或电子发票
代码层面,发票过账的核心逻辑大概是这样的:
-- 发票过账时生成应收凭证
INSERT INTO ar_invoice (
invoice_no, customer_id, invoice_date,
total_amount, tax_amount, status
) VALUES (
'INV-2024-001', 'CUST-001', '2024-01-15',
11300.00, 1300.00, 'POSTED'
);
-- 同时更新总账
INSERT INTO gl_entries (
account_code, debit_amount, credit_amount,
reference_type, reference_id
) VALUES
('1122', 11300.00, 0, 'AR_INVOICE', 'INV-2024-001'), -- 应收账款增加
('6001', 0, 10000.00, 'AR_INVOICE', 'INV-2024-001'), -- 销售收入
('2221', 0, 1300.00, 'AR_INVOICE', 'INV-2024-001'); -- 应交税费
你想想看,如果这里税率算错了,或者科目配错了,月底结账时对账对不上,那才叫一个头大。
3.4 收款与核销:钱和票的匹配艺术
收款和核销,是AR模块里最考验设计功力的部分。为什么?因为客户的付款方式五花八门:
- 一笔付款对应一张发票(最简单的情况)
- 一笔付款对应多张发票(客户合并付款)
- 多笔付款对应一张发票(分期付款)
- 预付款+尾款(先打一部分钱,货到后再付清)
我建议的核销设计思路是这样的:
-- 核销表结构(简化版)
CREATE TABLE ar_receipt_apply (
apply_id INT PRIMARY KEY,
receipt_id INT, -- 收款单ID
invoice_id INT, -- 发票ID
apply_amount DECIMAL, -- 本次核销金额
apply_date DATE, -- 核销日期
status VARCHAR(20) -- 状态:DRAFT/POSTED
);
-- 核销时更新应收余额
UPDATE ar_invoice
SET paid_amount = paid_amount + @apply_amount,
status = CASE
WHEN paid_amount + @apply_amount >= total_amount
THEN 'CLOSED'
ELSE 'PARTIAL'
END
WHERE invoice_id = @invoice_id;
这里有个细节:核销时一定要记录「核销差额」。为什么?因为客户付款时可能会有抹零、折扣等情况。比如发票金额是1000元,客户只打了999.5元,那0.5元怎么处理?
我的做法是引入「核销差异科目」,允许小额差异自动计入财务费用。当然,这个差异阈值需要由财务总监设定,比如单笔不超过1元。
3.5 应收报表与账龄分析
最后说说报表。应收模块的报表,财务最关心的是这两张:
| 报表名称 | 用途 | 关键字段 |
|---|---|---|
| 应收余额表 | 查看每个客户的当前欠款 | 客户、期初余额、本期新增、本期收款、期末余额 |
| 账龄分析表 | 分析应收逾期情况 | 客户、未到期、逾期1-30天、31-60天、60天以上 |
账龄分析的计算逻辑其实不复杂:
-- 计算账龄(按发票日期)
SELECT
customer_id,
SUM(CASE
WHEN DATEDIFF(NOW(), invoice_date) <= 30
THEN unpaid_amount ELSE 0
END) AS '0-30天',
SUM(CASE
WHEN DATEDIFF(NOW(), invoice_date) BETWEEN 31 AND 60
THEN unpaid_amount ELSE 0
END) AS '31-60天',
SUM(CASE
WHEN DATEDIFF(NOW(), invoice_date) > 60
THEN unpaid_amount ELSE 0
END) AS '60天以上'
FROM ar_invoice
WHERE status IN ('OPEN', 'PARTIAL')
GROUP BY customer_id;
嗯,这里要注意:账龄的起点是发票日期还是到期日?不同企业要求不一样。我建议做成可配置的,让财务自己选。
好了,应收模块的核心内容就这些。说白了,AR模块就是管好「客户欠我多少钱,什么时候还,还了没有」这三件事。但要把这三件事做好,需要把业务流程、数据模型、税务合规都考虑进去。希望今天的分享对你有帮助。