vault backup: 2026-05-26 01:13:17
This commit is contained in:
279
prop-acc/scenarios/billing/exception-partial-payment.md
Normal file
279
prop-acc/scenarios/billing/exception-partial-payment.md
Normal file
@@ -0,0 +1,279 @@
|
||||
---
|
||||
title: prop-acc · billing · 场景 - 部分付状态处理(Partial)
|
||||
aliases:
|
||||
- 部分付
|
||||
- Partial 状态
|
||||
- exception-partial-payment
|
||||
- 场景-部分付账单
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 账单
|
||||
- 部分付
|
||||
audience:
|
||||
- 业务人员
|
||||
- 财务
|
||||
status: 已发布
|
||||
sub_feature: billing
|
||||
last_review: 2026-05-26
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:部分付状态处理(Partial)
|
||||
|
||||
业户**只付了一部分**账单金额,系统状态从 Unpaid 进入 **Partial**(部分付)。后续业务人员需要跟进:**继续催收剩余款** / 提醒业户 / 或视情况调整账单。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 王先生(15-7-203)5 月物业费 ¥800,他到前台说"现在只能付 ¥300,剩下 ¥500 月底再补"。业务人员小李录入收款 ¥300:
|
||||
>
|
||||
> - Bill.paid_amount = 300
|
||||
> - Bill.status:Unpaid → **Partial**
|
||||
> - 建 CollectionOrderBill(allocated=300)+ CollectionOrder(+300)+ Receipt(¥300)
|
||||
>
|
||||
> 后续:王先生 5 月底再付 ¥500 → Bill.paid_amount = 800 → Bill.status: Partial → Paid。
|
||||
|
||||
## 业户视角
|
||||
|
||||
### 部分付场景
|
||||
|
||||
| 业户原因 | 频率 |
|
||||
|---|---|
|
||||
| 现金不够 | 中 |
|
||||
| 短期资金紧张 | 中 |
|
||||
| 对账单部分有异议(剩余部分协商中)| 低 |
|
||||
| 拆分多次付方便记账(罕见)| 低 |
|
||||
| 业户搬走前部分清账 | 低 |
|
||||
|
||||
### 您会感受到什么
|
||||
|
||||
- 收据上显示**实付金额**(¥300,不是账单总额 ¥800)
|
||||
- 推送 / 小程序:"已付 ¥300,剩余 ¥500 待付"
|
||||
- 余额显示 Partial 状态(账单未完全清)
|
||||
- 月底前 reminder(若有催收机制)
|
||||
|
||||
### 您要做什么
|
||||
|
||||
- 在到期日前补齐剩余款
|
||||
- 走 [[collect-payment-single|继续收款]](第 2 笔 ¥500)
|
||||
- 若有困难 → 与物业沟通(协商分期 / 减免 / 挂起)
|
||||
|
||||
## 业务人员视角
|
||||
|
||||
### 部分付的触发
|
||||
|
||||
走 [[collect-payment-single|单张收款]] Modal,**手动改"收款金额"小于全额**:
|
||||
|
||||
```
|
||||
收款金额:300(改成 300,不是默认的 800)
|
||||
支付方式:现金
|
||||
```
|
||||
|
||||
提交后:
|
||||
|
||||
- Bill.paid_amount: 0 → 300
|
||||
- Bill.status: Unpaid → **Partial**
|
||||
|
||||
### Partial 状态的能力
|
||||
|
||||
| 操作 | Partial 状态 |
|
||||
|---|---|
|
||||
| `CollectPaymentAction`(继续收款)| ✅(canBePaid=true)|
|
||||
| `SuspendBillAction`(挂起)| ✅ |
|
||||
| `VoidBillAction`(作废)| ✅(canBeVoided=true,但需配套退款已付部分)|
|
||||
| `DeleteAction`(物理删)| ❌(canBeDeleted 要求 Unpaid + 无付款)|
|
||||
| `SplitBillAction`(拆账单)| 可能不允许(已付款拆分复杂,见 [[split-bill]])|
|
||||
|
||||
### 第 2 笔收款
|
||||
|
||||
业户来补付时:
|
||||
|
||||
1. 找到 Partial 账单
|
||||
2. 走 `CollectPaymentAction`(状态守护 canBePaid=true,Partial 也允许)
|
||||
3. 收款金额 = ¥500(剩余应付,Modal 应默认带入 remaining)
|
||||
4. 提交 → Bill.paid_amount = 800,status: Partial → Paid
|
||||
|
||||
### 监控 Partial 账单
|
||||
|
||||
业务人员**定期查看** Partial 状态账单:
|
||||
|
||||
```sql
|
||||
SELECT bill_no, resident_id, amount, paid_amount, (amount - paid_amount) AS remaining
|
||||
FROM acc_bills
|
||||
WHERE status = 'partial'
|
||||
AND community_id = ?
|
||||
ORDER BY due_at ASC;
|
||||
```
|
||||
|
||||
或后台 → 账单 → 过滤"状态=Partial"列表。
|
||||
|
||||
业务人员对 Partial 业户:
|
||||
|
||||
- 临近 due_at:发提醒
|
||||
- 已逾期:走 [[exception-overdue-bills|催收]]
|
||||
- 业户失联:走 [[suspend-bill|挂起]]
|
||||
|
||||
## 系统流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 业户
|
||||
participant 业务
|
||||
participant Filament
|
||||
participant Action[CollectPaymentAction]
|
||||
participant DB
|
||||
|
||||
业户->>业务: 我只付 300(账单 800)
|
||||
业务->>Filament: ViewBill → CollectPayment(modal,改金额=300)
|
||||
Filament->>Action: handle(bill, 300, channel)
|
||||
Action->>DB: 1. 建 CO(+300)+ COBill(allocated=300)
|
||||
Action->>DB: 2. Bill.paid_amount = 300
|
||||
Action->>DB: 3. Bill.status: Unpaid → Partial(因 300 < 800)
|
||||
|
||||
Note over Filament: 几周后业户补付
|
||||
|
||||
业户->>业务: 现在付剩下 500
|
||||
业务->>Filament: ViewBill(Partial)→ CollectPayment(默认带 500)
|
||||
Filament->>Action: handle(bill, 500, channel)
|
||||
Action->>DB: 4. 建 CO(+500)+ COBill(allocated=500)
|
||||
Action->>DB: 5. Bill.paid_amount = 800
|
||||
Action->>DB: 6. Bill.status: Partial → Paid
|
||||
```
|
||||
|
||||
## 数据示例(完整流水)
|
||||
|
||||
业户付 ¥300 后:
|
||||
|
||||
### Bill 表
|
||||
|
||||
```
|
||||
id: 12345
|
||||
amount: 800
|
||||
paid_amount: 300
|
||||
status: Partial
|
||||
```
|
||||
|
||||
### CollectionOrderBill(1 条)
|
||||
|
||||
```
|
||||
bill_id: 12345
|
||||
collection_order_id: 67890
|
||||
allocated_amount: 300
|
||||
```
|
||||
|
||||
### CollectionOrder(1 条)
|
||||
|
||||
```
|
||||
id: 67890
|
||||
actual_amount: +300
|
||||
payment_channel: 现金
|
||||
status: Completed
|
||||
```
|
||||
|
||||
### Receipt(1 条)
|
||||
|
||||
```
|
||||
amount: +300
|
||||
line_items: [{ 物业费(5月)分付, 300 }]
|
||||
```
|
||||
|
||||
业户再付 ¥500 后:
|
||||
|
||||
### Bill 表(更新)
|
||||
|
||||
```
|
||||
paid_amount: 800
|
||||
status: Paid ← 收齐
|
||||
```
|
||||
|
||||
### CollectionOrderBill(2 条总)
|
||||
|
||||
```
|
||||
1: bill_id=12345, collection_order_id=67890, allocated=300
|
||||
2: bill_id=12345, collection_order_id=67891, allocated=500
|
||||
```
|
||||
|
||||
业户两次付,流水**完整保留**。
|
||||
|
||||
## 部分付的几种异常
|
||||
|
||||
### 异常 1:业户长期不补付
|
||||
|
||||
业户付了 ¥300 后**消失**,剩余 ¥500 长期不付:
|
||||
|
||||
| 处置 | 路径 |
|
||||
|---|---|
|
||||
| 临时不催(可能有困难)| 不动,等业户主动 |
|
||||
| 走逾期催收 | [[exception-overdue-bills]] |
|
||||
| 业户失联 | [[suspend-bill|挂起]] |
|
||||
| 协议放弃剩余 | [[void-paid-bill|作废]](但已付 ¥300 不退,业务上协商决定)|
|
||||
|
||||
### 异常 2:业户付错金额
|
||||
|
||||
业户原本想付 ¥300 给物业费,误付到了水费:
|
||||
|
||||
- 物业费 Bill 仍 Unpaid
|
||||
- 水费 Bill 多付了(超过 ¥54)
|
||||
|
||||
处置:看实施细节,可能需手工调整 CollectionOrderBill(危险,破坏审计)。**预防**:Modal 提交前确认 Bill ID。
|
||||
|
||||
### 异常 3:业务人员录错 paid_amount
|
||||
|
||||
业务人员收 ¥500 现金,误录入 ¥300:
|
||||
|
||||
- Bill.paid_amount = 300(应该 500)
|
||||
- 物业账面少记 ¥200 → 账上 vs 银行不一致
|
||||
|
||||
处置:走 [[void-paid-bill|作废]] 原 CollectionOrder + 重录,或运维 tinker 修字段。
|
||||
|
||||
## Partial 的边界
|
||||
|
||||
> [!info] 严格部分付 vs 宽松部分付
|
||||
>
|
||||
> 严格实现(本系统倾向):
|
||||
> - Modal `amount` 校验 `<= remaining`
|
||||
> - 不允许超付(避免凭空多记 paid_amount)
|
||||
>
|
||||
> 宽松实现:
|
||||
> - 允许超付 → 多余部分转入业户预存款 / 留作"未分配收款"
|
||||
>
|
||||
> 当前实现看 `CollectPaymentAction` 代码。
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 多次部分付的 Receipt 是合并还是分开?
|
||||
> **分开**(每次收款一张 Receipt)。业户拿到的是两张:
|
||||
>
|
||||
> - Receipt 1:¥300(5/15 现金付)
|
||||
> - Receipt 2:¥500(5/30 现金付)
|
||||
>
|
||||
> 不合并(合并破坏每次收款的独立凭证)。
|
||||
|
||||
> [!question] Partial 账单挂起后能恢复继续收吗?
|
||||
> 可以。走 [[suspend-bill|挂起]] → [[resume-bill|恢复]] → 状态智能判定为 Partial(因有付款)→ 继续收款。
|
||||
|
||||
> [!question] 部分付能预存款抵吗?
|
||||
> 看实施。理论上业户预存款余额 ¥200 + 账单剩余 ¥500 = 预存款抵 ¥200 → 仍 Partial(还差 ¥300)。需要部分抵扣功能(见 [[../prepaid/consume-multiple-bills-priority]] 部分抵讨论)。当前不一定支持。
|
||||
|
||||
> [!question] 业户付的钱比账单总额还多(超付)?
|
||||
> 见上方"严格 vs 宽松"段。严格实现拒绝;宽松实现允许多付转入预存款。
|
||||
|
||||
> [!question] activitylog 怎么追踪 Partial 状态历史?
|
||||
> 每次 CollectPayment 都有 log(event=collected),可看到状态从 Unpaid → Partial 的转变。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 单张全付 → [[collect-payment-single]](标准路径)
|
||||
- 批量付(多张一次)→ [[collect-payment-batch]]
|
||||
- 长期 Partial 无解 → [[suspend-bill]] / [[void-paid-bill]]
|
||||
- 部分付逾期催收 → [[exception-overdue-bills]]
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[bill-six-state-machine]]
|
||||
- [[bill-vs-collection-order]]
|
||||
- [[collect-payment-single]]
|
||||
- [[suspend-bill]]
|
||||
- [[exception-overdue-bills]]
|
||||
- [[void-paid-bill]]
|
||||
Reference in New Issue
Block a user