Files
uniprop-manual/prop-acc/scenarios/deposit/audit-monthly-deposit-balance.md

242 lines
7.8 KiB
Markdown
Raw Normal View History

2026-05-25 22:37:41 +08:00
---
title: prop-acc · deposit · 场景 - 月度押金账户余额对账
aliases:
- 押金月对账
- 押金账面与银行对账
- audit-monthly-deposit-balance
- 场景-押金月度对账
tags:
- 场景
- prop-acc
- 保证金
- 审计
audience:
- 财务
- 业务人员
status: 已发布
sub_feature: deposit
last_review: 2026-05-25
code_version: 2026-05-22
---
# 场景:月度押金账户余额对账
物业财务**每月底**对所有押金账户做一次余额校验,确保系统账面 = 银行专户余额 = 流水累计净值,三方平衡。是审计内控的标准动作。
## 典型情境
> [!example] 真实情境
> 物业财务王主管每月最后一个工作日做"押金账户余额三方对账":
>
> 1. 系统所有 Active + Closed-retain 账户的 `balance` + `meta.balance_held_amount` 之和
> 2. 银行"装修押金专户"的实际余额
> 3. 全部 `DepositTransaction` 按净值累加 + retain 保留金额
>
> 三者必须**完全相等**,任何差额都要查清。
## 三方对账详解
### 1. 系统账面余额(System Balance)
```sql
-- Active 账户的当前余额
SELECT SUM(balance) FROM acc_deposit_accounts WHERE status = 'active';
-- + Frozen 账户的当前余额(冻结期间余额仍属业户)
SELECT SUM(balance) FROM acc_deposit_accounts WHERE status = 'frozen';
-- + Closed 但保留资金的账户(retain disposition)
SELECT SUM(JSON_EXTRACT(meta, '$.balance_held_amount'))
FROM acc_deposit_accounts
WHERE status = 'closed' AND JSON_EXTRACT(meta, '$.force_closed_disposition') = 'retain';
```
三者之和 = **物业代管负债总额**
### 2. 银行专户余额(Bank Balance)
物业的"装修押金银行专户"(单独开立的隔离账户)的月底余额。
> [!info] 为什么要专户隔离
> 押金是代管资金,**不应与物业自有资金混同**。专户的好处:
> - 内控明确,资金不被挪用
> - 对账简单(银行余额 == 应付业户的钱)
> - 监管合规(部分地区物业法规要求)
### 3. 流水累计净值(Transaction Sum)
```sql
-- 全部 DepositTransaction 的净值(deposit 加,refund/forfeiture 减)
SELECT
SUM(CASE WHEN type = 'deposit' THEN amount ELSE -amount END) AS net_balance
FROM acc_deposit_transactions;
-- 这个值理论上 == 所有 Active + Frozen 账户的 balance 之和
-- (不包括 retain Closed 账户,因为它们的 balance 字段未变,但已不在 Transaction 累加范围内 —— 实际上也累加了,因为 forfeiture/refund 没发生)
```
> [!info] 完整公式
> ```
> SUM(transactions 净值) = SUM(active.balance) + SUM(frozen.balance) + SUM(closed.balance where status=closed and balance>0)
> ```
> 任何不一致 → 有 bug 或人为绕过(详见 [[deposit-account-vs-transaction]] "两者的契约")。
### 三方平衡的预期
```
系统账面余额 == 银行专户余额 == 流水累计净值
```
任何一对不等 → 调查。
## 业务人员视角(月底操作)
### 第 1 步:导出系统账面余额报表
后台 → 保证金 → 列表 → 按"状态 Active / Frozen / Closed-retain"过滤 → 导出 Excel,合计 `balance` 列 + `meta.balance_held_amount` 列。
(或运行 SQL 查询,见上方)
### 第 2 步:取银行专户对账单
- 登录银行网银 / 联系银行客户经理
- 取本月最后一天的余额(精确到分)
### 第 3 步:做对账
| 维度 | 数值 | 来源 |
|---|---|---|
| A. 系统账面余额 | ¥X | 后台导出 |
| B. 银行专户余额 | ¥Y | 银行对账单 |
| C. 流水累计净值 | ¥Z | SQL 查询 |
| **差额(应 0)** | A - B 和 A - C | |
如果三个值不相等,**这才是对账的核心工作**:查清差异。
### 第 4 步:差额排查
常见差异原因:
| 差异 | 可能原因 | 排查方法 |
|---|---|---|
| A > B(系统多于银行) | 账面收了但银行未到账(在途资金) | 查最近 deposit 的支付渠道(POS / 微信)是否回滚 |
| A < B(系统少于银行) | 银行多了钱但系统没记(混账)| 查银行流水那笔多的钱来源 |
| A ≠ C(系统账面与流水不一致)| 系统 bug 或 tinker 改过余额 | `$account->verifyBalance()` 找出哪个账户不一致 |
> [!warning] 任何不一致都是事故
> 即使差额很小(¥1),也必须查清。押金是负债 = 业户的钱,任何不平都是合规风险。
### 第 5 步:出对账报告
格式:
```markdown
# 2026 年 5 月 装修押金账户对账报告
## 三方余额
- 系统账面:¥152,300.00(Active 89 + Frozen 3 + Retain 4)
- 银行专户:¥152,300.00
- 流水净值:¥152,300.00
## 平衡情况:✅ 完全平衡
## 本月新增账户:12
## 本月关账:8(其中 retain 1)
## 本月扣罚 / 退款总额:¥85,400 / ¥73,200
```
如有差异:
```markdown
## ⚠️ 差异
- 系统账面 ¥X 与银行 ¥Y 差 ¥Z
- 已查:第 N 笔 deposit on 2026-05-22 的微信支付实际未到账(支付平台冻结审核)
- 处理:待 5-28 微信渠道放款,再次对账确认
## 本月需复盘
- ID 4567 账户余额异常:`verifyBalance()` 返 false,差 ¥0.5(疑似浮点误差或人为编辑)
- 已 tinker 修复 + 加备注
```
## 系统流程
```mermaid
flowchart TD
A[月底触发] --> B[导出系统账面]
A --> C[取银行专户对账单]
A --> D[查询流水累计]
B --> E{三方相等?}
C --> E
D --> E
E -- 是 --> F[出对账报告 ✅]
E -- 否 --> G[排查差异]
G --> H[追溯交易 / 查 verifyBalance / 排查 tinker 操作]
H --> I[修复 + 备注]
I --> J[重新对账]
J --> E
```
## 报表 SQL 汇总(供财务复用)
```sql
-- 本月新增账户
SELECT COUNT(*) FROM acc_deposit_accounts
WHERE created_at BETWEEN '2026-05-01' AND '2026-05-31 23:59:59';
-- 本月关账(含自动关账 + 主动关账 + ForceClose)
SELECT COUNT(*),
COUNT(*) FILTER (WHERE JSON_EXTRACT(meta, '$.force_closed_disposition') IS NOT NULL) AS force_closed,
COUNT(*) FILTER (WHERE JSON_EXTRACT(meta, '$.force_closed_disposition') = 'retain') AS retain_count
FROM acc_deposit_accounts
WHERE status = 'closed'
AND updated_at BETWEEN '2026-05-01' AND '2026-05-31 23:59:59';
-- 本月扣罚总额
SELECT SUM(amount) FROM acc_deposit_transactions
WHERE type = 'forfeiture'
AND created_at BETWEEN '2026-05-01' AND '2026-05-31 23:59:59';
-- 本月退款总额
SELECT SUM(amount) FROM acc_deposit_transactions
WHERE type = 'refund'
AND created_at BETWEEN '2026-05-01' AND '2026-05-31 23:59:59';
```
## 常见问题
> [!question] 没有银行专户怎么对账?
> 退一步,与物业总账户对账,但只能看"已收 / 已退"流水净值,**无法判断资金是否被挪用**(被混入其他业务用资金池)。**强烈建议设置专户**。
> [!question] retain 账户的资金算物业代管负债吗?
> **算**。即使账户 Closed,只要 `meta.balance_held_amount > 0`,资金法律上仍属业户,会计上仍是"其他应付款"。详见 [[force-close-retain]]。
> [!question] 月度对账要审计师参与吗?
> 内部对账物业财务自己做。**年度审计**时审计师会重点检查这部分(物业的代管资金合规性、是否有挪用迹象)。月度对账留下完整记录是年审顺利的前提。
> [!question] 差额查不出来怎么办?
> 上报物业财务总监 + 法务。可能需要:
> - 委托第三方审计核对
> - 银行流水逐笔重对
> - tinker 操作日志审查(谁改了什么)
>
> **不能放任**,押金对账差异是严重合规问题。
> [!question] 多个物业项目的押金一起对吗?
> 通常每个 `community_id` 独立对账(每个物业项目一个银行专户)。系统层面也可按 community 分组导出。
## 异常分支
- 发现 `verifyBalance()=false` 的账户 → tinker 修复 + 排查根因
- 发现银行专户少于账面 → 资金挪用嫌疑,法务介入
- 发现长期 retain 的资金对应不上 → [[audit-long-pending-accounts|长期账户排查]]
## 相关文档
- [[deposit-account-vs-transaction]]
- [[transaction-types]]
- [[force-close-retain]]
- [[audit-long-pending-accounts]]
- [[deposit-vs-adhoc-vs-prepaid]]