Files
uniprop-manual/prop-acc/scenarios/billing/exception-partial-payment.md

280 lines
7.5 KiB
Markdown
Raw Normal View History

2026-05-26 01:13:17 +08:00
---
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]]