vault backup: 2026-05-26 01:08:16
This commit is contained in:
220
prop-acc/scenarios/billing/split-bill.md
Normal file
220
prop-acc/scenarios/billing/split-bill.md
Normal file
@@ -0,0 +1,220 @@
|
||||
---
|
||||
title: prop-acc · billing · 场景 - 拆账单(SplitBillAction)
|
||||
aliases:
|
||||
- 拆账单
|
||||
- 账单分摊
|
||||
- SplitBillAction
|
||||
- split-bill
|
||||
- 场景-拆账单
|
||||
tags:
|
||||
- 场景
|
||||
- prop-acc
|
||||
- 账单
|
||||
- 调整
|
||||
audience:
|
||||
- 业务人员
|
||||
- 财务
|
||||
status: 已发布
|
||||
sub_feature: billing
|
||||
last_review: 2026-05-26
|
||||
code_version: 2026-05-22
|
||||
---
|
||||
|
||||
# 场景:拆账单(SplitBillAction)
|
||||
|
||||
业户**多人共住一户**(房东 + 租户 / 合租),物业费 / 水电气**按比例分摊**到各自账户,业务人员走 `SplitBillAction` 把一张账单**拆成多张**。
|
||||
|
||||
## 典型情境
|
||||
|
||||
> [!example] 真实情境
|
||||
> 12-3-501 房屋:
|
||||
>
|
||||
> - 房东陈先生(产权人)
|
||||
> - 租户李先生(2026 年 1 月起租)
|
||||
>
|
||||
> 合同约定:**物业费房东付,水电气租户付**。但系统月初按"业户=陈先生"批量生成的:
|
||||
>
|
||||
> - 5 月物业费 ¥800(应给陈先生)
|
||||
> - 5 月水费 ¥54(实际应租户付)
|
||||
> - 5 月电费 ¥168(实际应租户付)
|
||||
> - 5 月燃气 ¥30(实际应租户付)
|
||||
>
|
||||
> 业务人员王主管要把后 3 张账单**重新分给租户李先生**(从陈先生的账户拆出去)。
|
||||
|
||||
## 业务人员视角
|
||||
|
||||
### 第 1 步:确认拆单需求
|
||||
|
||||
业户来电话 / 合同约定:
|
||||
|
||||
- 房东本人来报备"水电气以后租户付"
|
||||
- 看合同 / 租赁备案
|
||||
- 确认租户身份(可能已在 `community_user_profiles` 注册)
|
||||
|
||||
### 第 2 步:逐张拆单
|
||||
|
||||
**(本场景默认逐张拆,不是一次 SplitAll)**
|
||||
|
||||
后台 → 账单 → 找到 5 月水费 Bill → 进 `ViewBill` → 点 `SplitBillAction`(标签"拆账单")。
|
||||
|
||||
> [!warning] 按钮可见性
|
||||
> 看 `SplitBillAction` 守护(应该是 Unpaid + 业务权限)。Paid / Void 状态可能不允许拆(已付的钱难撤)。
|
||||
|
||||
### 第 3 步:Modal 填参数
|
||||
|
||||
| 字段 | 填什么 |
|
||||
|---|---|
|
||||
| **原账单** | 5 月水费 ¥54(陈先生)|
|
||||
| **拆分方式** | 按比例 / 按金额 / 按目标业户 |
|
||||
| **新业户** | 李先生(下拉选)|
|
||||
| **拆给新业户的金额** | ¥54(全部 → 全转给李先生 = 业户更换;或部分 → 拆成两张)|
|
||||
| **拆分原因** | 必填,如 "房东与租户合同约定:水费由租户付"|
|
||||
|
||||
### 第 4 步:提交
|
||||
|
||||
`SplitBillAction` 业务逻辑(看实现):
|
||||
|
||||
**模式 1:全转给新业户**(本场景常见)
|
||||
|
||||
```
|
||||
- 原 Bill #X(陈先生):状态翻 Void(原账单作废)+ 标 split_to=新 Bill ID
|
||||
- 新建 Bill #Y(李先生):amount=54, status=Unpaid
|
||||
- 关联(meta 记拆分来源)
|
||||
```
|
||||
|
||||
**模式 2:部分拆分**(罕见)
|
||||
|
||||
```
|
||||
- 原 Bill #X(陈先生):amount 改为 30(原 54 - 拆出 24)
|
||||
- 新建 Bill #Y(李先生):amount=24
|
||||
- 两张同存
|
||||
```
|
||||
|
||||
> [!info] 实施细节看代码
|
||||
> `SplitBillAction` 的具体行为(全转 vs 部分拆 vs 按比例)看 `packages/prop-acc/src/Actions/Bills/SplitBillAction.php`。本文按业务场景描述。
|
||||
|
||||
### 第 5 步:通知双方
|
||||
|
||||
- 陈先生:"5 月水费已转给租户李先生付,您不必付了"
|
||||
- 李先生:"您 5 月水费 ¥54 新账单已生成,请于 6 月 15 日前付清"
|
||||
|
||||
### 第 6 步:重复对电费 / 燃气
|
||||
|
||||
逐张拆。3 张全拆完后:
|
||||
|
||||
- 陈先生只欠 5 月物业费 ¥800
|
||||
- 李先生欠 5 月水费 + 电费 + 燃气 ¥252
|
||||
|
||||
## 系统流程(全转模式)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 业务
|
||||
participant Filament
|
||||
participant Action[SplitBillAction]
|
||||
participant DB
|
||||
participant Activity[activitylog]
|
||||
|
||||
业务->>Filament: ViewBill(陈先生水费)→ SplitBillAction
|
||||
Filament->>Action: handle(bill=陈先生水费, mode=Full, target=李先生, reason)
|
||||
Action->>Action: 校验 bill.status (Unpaid)
|
||||
Action->>Action: 校验 target_resident 在同 community
|
||||
|
||||
Action->>DB: 开启事务
|
||||
Action->>DB: 1. 原 Bill 翻 Void + meta.split_to=新 ID
|
||||
Action->>DB: 2. 新建 Bill(target=李先生, amount=54, status=Unpaid, meta.split_from=原 ID)
|
||||
Action->>Activity: log(event=split, properties)
|
||||
Action->>DB: 提交
|
||||
|
||||
Filament-->>业务: 跳转新 Bill
|
||||
```
|
||||
|
||||
## 业户视角
|
||||
|
||||
### 陈先生(原账单业户)
|
||||
|
||||
收到通知:
|
||||
|
||||
> 陈先生您好,您的 5 月水费 ¥54 已根据合同拆给租户李先生付。您原账单已作废,无需付款。
|
||||
|
||||
### 李先生(新账单业户)
|
||||
|
||||
收到通知:
|
||||
|
||||
> 李先生您好,您 5 月水费 ¥54 账单已生成(由 12-3-501 房屋的合同拆分而来),请于 6 月 15 日前付清。
|
||||
|
||||
## 拆单的几种业务场景
|
||||
|
||||
| 场景 | 频率 | 拆法 |
|
||||
|---|---|---|
|
||||
| **房东 / 租户合同分摊** | 中(本场景)| 按费用类型分,水电气给租户 |
|
||||
| **多业主分摊**(共有产权)| 罕见 | 按比例 |
|
||||
| **公摊费用追溯** | 中(本月才发现某费用应分摊)| 按户数 |
|
||||
| **企业内部子公司分摊**(商铺)| 罕见 | 按合同 |
|
||||
|
||||
## 与"作废 + 重建"的对比
|
||||
|
||||
| 维度 | 拆账单(SplitBillAction)| 作废 + 手动重建 |
|
||||
|---|---|---|
|
||||
| 单一操作 | ✅(一个 Action 完成)| ❌(走 2-3 个 Action)|
|
||||
| 关联追溯 | ✅(meta 标 split_from/to)| ❌(无系统关联)|
|
||||
| 审计 | activitylog event=split | 多条 activitylog(void + create)|
|
||||
| 灵活性 | 受 SplitBillAction 限制 | 更灵活(可改任意字段)|
|
||||
| 推荐场景 | 简单拆分(全转 / 部分按金额)| 复杂拆分 / 拆完还要改其他字段 |
|
||||
|
||||
## 拆单后已付款的复杂情况
|
||||
|
||||
> [!warning] 已付款 Bill 拆单的复杂度
|
||||
>
|
||||
> 如果原账单**已付一部分**(Partial 状态):
|
||||
>
|
||||
> - 原账单作废 → 已付的部分怎么办?
|
||||
> - 退还给原业户 → 走作废 + 退款([[void-paid-bill]] 类似)
|
||||
> - 新账单上记 paid_amount? 不行(原业户付的钱不该算到新业户)
|
||||
>
|
||||
> 实施上 `SplitBillAction` 可能**不允许 Partial 状态拆**(只允许 Unpaid)。看具体实现。
|
||||
>
|
||||
> **推荐**:拆单前先处理已付款(作废 + 退款 / 退现金后)再拆。
|
||||
|
||||
## 常见问题
|
||||
|
||||
> [!question] 拆给的业户不存在(系统里没注册)怎么办?
|
||||
> 先建业户档案(community 模块的 `community_user_profiles`)→ 然后拆。
|
||||
|
||||
> [!question] 拆错了(应该拆给李先生,选成王先生)?
|
||||
> 看实施:
|
||||
> - 若新 Bill 仍 Unpaid → 走 [[delete-bill-unpaid|删除]] + 重拆
|
||||
> - 若已 Paid → 麻烦,需走作废 + 退款 + 重拆
|
||||
|
||||
> [!question] 按比例自动拆所有账单(房东 50% / 租户 50% 物业费)?
|
||||
> 当前 `SplitBillAction` 应是**逐张操作**。按比例批量拆需要业务方提需求 + 加 `BulkSplitBillsAction`(待实现)。
|
||||
|
||||
> [!question] 拆单的合规性?
|
||||
> 物业要确保:
|
||||
> - 业户合同明确分摊条款
|
||||
> - 双方书面同意拆分
|
||||
> - 物业内部审批留底
|
||||
>
|
||||
> 系统层面只管账单数据,合规由物业流程保障。
|
||||
|
||||
> [!question] 一张账单能拆成 3+ 份吗(多人合租 3 人均摊)?
|
||||
> 看 SplitBillAction 设计。简单实现是**一次拆 2 份**(原账单 + 新账单)。要拆 3 份需 2 次操作:
|
||||
>
|
||||
> 1. 第 1 次:原账单(¥54)→ 拆出 ¥18(给租户 A),原账单剩 ¥36
|
||||
> 2. 第 2 次:原账单(¥36)→ 拆出 ¥18(给租户 B),原账单剩 ¥18(给房东自己)
|
||||
>
|
||||
> 累加得到三份 ¥18 各自归一人。
|
||||
|
||||
## 异常分支
|
||||
|
||||
- 拆错了 → 删除 / 作废新 Bill,原 Bill 状态可能要恢复(看实施)
|
||||
- 已付的拆 → 走 [[void-paid-bill]] 流程,复杂
|
||||
- 简单"换业户"(不拆,只改账单的 resident_id)→ 可能用 Edit Bill 直接改(若 Policy 允许),但**强烈不推荐**(破坏追溯)→ 用拆单更标准
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [[bill-six-state-machine]]
|
||||
- [[delete-bill-unpaid]]
|
||||
- [[void-paid-bill]]
|
||||
- [[suspend-bill]]
|
||||
- [[bill-vs-collection-order]]
|
||||
Reference in New Issue
Block a user