274 lines
8.8 KiB
Markdown
274 lines
8.8 KiB
Markdown
|
|
---
|
|||
|
|
title: prop-acc · meter · 场景 - 单笔账单上下限封顶(防异常用量爆账)
|
|||
|
|
aliases:
|
|||
|
|
- min max 封顶
|
|||
|
|
- 账单封顶
|
|||
|
|
- generate-bill-min-max-cap
|
|||
|
|
- 场景-账单上下限封顶
|
|||
|
|
tags:
|
|||
|
|
- 场景
|
|||
|
|
- prop-acc
|
|||
|
|
- 计量表
|
|||
|
|
- 账单生成
|
|||
|
|
- 异常防御
|
|||
|
|
audience:
|
|||
|
|
- 业务人员
|
|||
|
|
- 财务
|
|||
|
|
- 业户
|
|||
|
|
status: 已发布
|
|||
|
|
sub_feature: meter
|
|||
|
|
last_review: 2026-05-26
|
|||
|
|
code_version: 2026-05-22
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# 场景:单笔账单上下限封顶(防异常用量爆账)
|
|||
|
|
|
|||
|
|
`RatePlan` 上的 `min_amount` / `max_amount` 字段为单笔账单设置**上下限**:
|
|||
|
|
|
|||
|
|
- **`max_amount`** 防止极端用量(漏水 / 设备故障)导致离谱账单 → 业户友好,但物业承担差额
|
|||
|
|
- **`min_amount`** 防止零用量 / 极低用量逃避基础服务费 → 物业兜底,但业户可能不爽
|
|||
|
|
|
|||
|
|
本场景演示三种触发情境。
|
|||
|
|
|
|||
|
|
## 典型情境
|
|||
|
|
|
|||
|
|
### 情境 1:漏水触发 max 封顶
|
|||
|
|
|
|||
|
|
> [!example] 真实情境
|
|||
|
|
> 张阿姨家**水管漏水**(藏在墙里没发现),5 月用水 **800 吨**(平时 12 吨)。按阶梯计价:
|
|||
|
|
>
|
|||
|
|
> ```
|
|||
|
|
> 0-20 吨段:20 × 3.0 = 60
|
|||
|
|
> 21-30 吨段:10 × 4.5 = 45
|
|||
|
|
> 31-800 吨段:770 × 6.0 = 4,620
|
|||
|
|
> 算出金额:4,725 元
|
|||
|
|
> ```
|
|||
|
|
>
|
|||
|
|
> RatePlan 配置 `max_amount = 1,500`,触发封顶:
|
|||
|
|
>
|
|||
|
|
> ```
|
|||
|
|
> final_amount = min(4725, 1500) = 1500
|
|||
|
|
> ```
|
|||
|
|
>
|
|||
|
|
> 账单 ¥1,500,差额 ¥3,225 物业承担(走维修保险 / 业务减免)。
|
|||
|
|
|
|||
|
|
### 情境 2:零用量触发 min 兜底
|
|||
|
|
|
|||
|
|
> [!example] 真实情境
|
|||
|
|
> 王先生整月**出差不在家**,水表读数无变化(consumption=0)。按阶梯算 = 0 元。但物业配置 `min_amount = 20`,兜底:
|
|||
|
|
>
|
|||
|
|
> ```
|
|||
|
|
> final_amount = max(0, 20) = 20
|
|||
|
|
> ```
|
|||
|
|
>
|
|||
|
|
> 账单 ¥20,理由"基础服务费 / 管网维护费"。王先生抱怨"我没用水为什么收钱?",物业解释:小区水管 / 表的维护是公共成本,按户分摊。
|
|||
|
|
|
|||
|
|
### 情境 3:正常范围,无封顶
|
|||
|
|
|
|||
|
|
> [!example] 真实情境
|
|||
|
|
> 陈先生 5 月用水 35 吨,按阶梯算 135 元。RatePlan 配置 `min_amount=20`, `max_amount=1500`:
|
|||
|
|
>
|
|||
|
|
> ```
|
|||
|
|
> final_amount = max(20, min(135, 1500)) = 135
|
|||
|
|
> ```
|
|||
|
|
>
|
|||
|
|
> 账单 ¥135,封顶规则**不触发**(在合理范围内)。
|
|||
|
|
|
|||
|
|
## min / max 算法
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
if (max_amount !== null && calculated > max_amount) calculated = max_amount;
|
|||
|
|
if (min_amount !== null && calculated < min_amount) calculated = min_amount;
|
|||
|
|
final_amount = calculated;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或等价:`final_amount = max(min_amount ?? 0, min(calculated, max_amount ?? INF))`。
|
|||
|
|
|
|||
|
|
详见 [[multiplier-and-tiered-pricing|倍率与阶梯计价]]"第 3 层 min/max 封顶"段。
|
|||
|
|
|
|||
|
|
## 系统流程
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Calc[MeterBillCalculator]
|
|||
|
|
participant Service[MeterBillGenerationService]
|
|||
|
|
participant DB
|
|||
|
|
|
|||
|
|
Calc->>Calc: 阶梯算法 → calculated_amount
|
|||
|
|
Note over Calc: 假设漏水算出 4725
|
|||
|
|
|
|||
|
|
Calc->>Calc: max_amount 检查
|
|||
|
|
alt calculated > max_amount(4725 > 1500)
|
|||
|
|
Calc->>Calc: final = max_amount = 1500
|
|||
|
|
else 在范围内
|
|||
|
|
Calc->>Calc: 通过
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
Calc->>Calc: min_amount 检查
|
|||
|
|
alt final < min_amount
|
|||
|
|
Calc->>Calc: final = min_amount
|
|||
|
|
else 在范围内
|
|||
|
|
Calc->>Calc: 通过
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
Calc-->>Service: 1500
|
|||
|
|
Service->>DB: 建 Bill(amount=1500, sourceable=reading)
|
|||
|
|
Note over DB: 业务上是否记录"封顶减免"?目前 Bill 表无此字段,留作业务备注
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 业户视角
|
|||
|
|
|
|||
|
|
### Max 封顶(漏水)
|
|||
|
|
|
|||
|
|
业户收到的账单:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
2026 年 5 月水费账单
|
|||
|
|
|
|||
|
|
用水量:800 吨 ⚠️ 用量异常高
|
|||
|
|
按阶梯算应付:¥4,725.00
|
|||
|
|
封顶后实付:¥1,500.00
|
|||
|
|
差额减免:¥3,225.00(由物业 / 维修保险承担)
|
|||
|
|
|
|||
|
|
应付:¥1,500.00
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> [!info] 账单展示封顶信息
|
|||
|
|
> **强烈推荐**账单展示"按阶梯算 X,封顶 Y,差额 Z 由物业承担"。让业户明白封顶的存在 + 物业的友好。
|
|||
|
|
|
|||
|
|
业户会**感激物业封顶**,但更会**自查漏水 / 设备故障**。
|
|||
|
|
|
|||
|
|
### Min 兜底(零用量)
|
|||
|
|
|
|||
|
|
业户收到的账单:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
2026 年 5 月水费账单
|
|||
|
|
|
|||
|
|
用水量:0 吨
|
|||
|
|
按阶梯算应付:¥0.00
|
|||
|
|
基础费(min):¥20.00
|
|||
|
|
|
|||
|
|
应付:¥20.00
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
业户可能**不接受**:"我没用水为什么收钱?"。物业要解释:
|
|||
|
|
|
|||
|
|
- 水管 / 公共部位维护成本
|
|||
|
|
- 物业服务费的"基础保障"性质(签合同时已告知)
|
|||
|
|
- 法律 / 政策依据(若有)
|
|||
|
|
|
|||
|
|
## 业务人员视角
|
|||
|
|
|
|||
|
|
### 配置 min / max
|
|||
|
|
|
|||
|
|
后台 → 费率管理 → RatePlan → 编辑 → 填字段:
|
|||
|
|
|
|||
|
|
| 字段 | 推荐值(参考)|
|
|||
|
|
|---|---|
|
|||
|
|
| `min_amount` | 10-30 元(看物业 + 费用类型)|
|
|||
|
|
| `max_amount` | 1000-5000 元(看业户类型,商铺可以更高)|
|
|||
|
|
|
|||
|
|
> [!warning] 配置要谨慎
|
|||
|
|
>
|
|||
|
|
> **max 配低**:正常用量也被封顶 → 物业损失收入。例如 max=300,商铺正常月费 ¥500 → 物业每月被减免 ¥200。**严重 bug**。
|
|||
|
|
>
|
|||
|
|
> **max 配高**(或不配):无封顶 → 极端用量爆账户,业户投诉 + 法律风险。
|
|||
|
|
>
|
|||
|
|
> **min 配高**:业户不满 + 投诉。
|
|||
|
|
>
|
|||
|
|
> **配置后用极端值算例验证**(0 度 / 极少 / 正常 / 极高 各算一遍看是否合理)。
|
|||
|
|
|
|||
|
|
### 触发封顶后的业务流程
|
|||
|
|
|
|||
|
|
| 触发 | 业务人员动作 |
|
|||
|
|
|---|---|
|
|||
|
|
| max 触发(异常高用量)| 联系业户排查([[exception-high-consumption]]) → 减免数额可能要审批 |
|
|||
|
|
| min 触发(零 / 极低用量)| 通常无需介入,业户接受 min 即可 |
|
|||
|
|
| 频繁 max 触发 | 评估是否表 / 设备有问题(漏水 / 故障)|
|
|||
|
|
|
|||
|
|
### 封顶减免的会计处理
|
|||
|
|
|
|||
|
|
封顶差额(`max_amount` 触发时,实际应付 vs 物业承担)的会计处理:
|
|||
|
|
|
|||
|
|
| 选项 | 实现 |
|
|||
|
|
|---|---|
|
|||
|
|
| **物业直接承担**(本系统当前简化)| Bill.amount 直接是封顶后金额。账面收入 ¥1,500(实际应是 ¥4,725)→ 物业少收 ¥3,225 |
|
|||
|
|
| **走维修保险**(高大上)| 物业向保险公司报销 ¥3,225,账面通过应收 / 已收 走完整流程 |
|
|||
|
|
| **业户与物业分摊**(罕见)| 部分协议:超过封顶部分 50% 业户 50% 物业 |
|
|||
|
|
|
|||
|
|
当前**最简单实现**:物业直接承担。其他方案需要业务方提需求。
|
|||
|
|
|
|||
|
|
## 财务视角
|
|||
|
|
|
|||
|
|
### 月度报表统计封顶情况
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 本月触发 max 封顶的 reading(假设 Bill 不存"封顶前 amount",我们用 reading 算)
|
|||
|
|
SELECT
|
|||
|
|
r.id AS reading_id,
|
|||
|
|
r.consumption,
|
|||
|
|
-- 重算应付(简化,实际要走 Calculator 逻辑)
|
|||
|
|
-- calculate(consumption, ratePlan) AS expected_amount
|
|||
|
|
b.amount AS billed_amount,
|
|||
|
|
-- (expected - billed) AS reduction
|
|||
|
|
rp.max_amount
|
|||
|
|
FROM acc_meter_readings r
|
|||
|
|
JOIN acc_meters m ON r.meter_id = m.id
|
|||
|
|
JOIN fee_types ft ON m.fee_type_id = ft.id
|
|||
|
|
JOIN rate_plans rp ON ft.current_rate_plan_id = rp.id
|
|||
|
|
JOIN acc_bills b ON r.bill_id = b.id
|
|||
|
|
WHERE b.amount = rp.max_amount -- 简化判断:Bill 金额刚好等于封顶值 = 大概率封顶触发了
|
|||
|
|
AND b.created_at BETWEEN '2026-05-01' AND '2026-05-31';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
业务用途:看月度物业因封顶减免多少收入。若太多 → 调整 max 或排查根因(频繁漏水 / 设备故障)。
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
> [!question] min_amount 是 0 / null 时不兜底?
|
|||
|
|
> 是的。若 `min_amount=null`,系统不兜底,零用量账单 = 0 元(可能不开账单)。物业政策决定是否兜底。
|
|||
|
|
|
|||
|
|
> [!question] max 触发后业户反悔说"我自查没漏水,你怎么算出我用 800 吨的?"
|
|||
|
|
> 业务人员排查:
|
|||
|
|
> - 看 reading 数据(读数对吗?抄表照片有吗?)
|
|||
|
|
> - 派人现场核对物理表
|
|||
|
|
> - 找漏水点(物业派维修人员)
|
|||
|
|
> - 若证实表故障 → 走 [[replace-broken-meter|换表]],并重算账单(走 [[exception-readings-locked-after-bill|修正流程]])
|
|||
|
|
>
|
|||
|
|
> 若所有证据都指向"确实用了 800 吨"(且业户家有漏水迹象)→ 业户认账,封顶后金额是优惠了。
|
|||
|
|
|
|||
|
|
> [!question] min 触发后业户拒付怎么办?
|
|||
|
|
> 物业说服 + 法律协议层面要求(物业合同里通常有"基础服务费"条款)。坚决拒付 → 进入逾期催收。
|
|||
|
|
|
|||
|
|
> [!question] 不同业户(住宅 vs 商铺)封顶不同可以吗?
|
|||
|
|
> 看 RatePlan 设计。当前可能"每个 FeeType 一份 RatePlan",所以同 FeeType 共用 min/max。如果要区分,可:
|
|||
|
|
>
|
|||
|
|
> - 给商铺单独建 FeeType + RatePlan
|
|||
|
|
> - 或扩展 RatePlan 支持多档 min/max(改 schema)
|
|||
|
|
|
|||
|
|
> [!question] 跨月用量(忘了抄一个月,两个月用量算一笔)会触发 max 吗?
|
|||
|
|
> 可能会(双月用量翻倍)。**预防**:不要漏抄(走 [[audit-meters-needing-reading|审计]] 监控)。漏抄了发现:
|
|||
|
|
> - 把这笔大账单**人工拆**成两个月(系统不直接支持,业务流程做)
|
|||
|
|
> - 或当作正常账单收 + 与业户沟通
|
|||
|
|
|
|||
|
|
> [!question] 封顶后差额怎么入账?
|
|||
|
|
> 当前最简单实现:Bill.amount 直接是封顶后金额,差额不入账(物业默默承担)。
|
|||
|
|
>
|
|||
|
|
> 严格会计:差额应记入"管理费用 / 维修保险报销 / 服务减免"科目。需扩展 schema 才能精确处理。
|
|||
|
|
|
|||
|
|
## 异常分支
|
|||
|
|
|
|||
|
|
- 阶梯计价(本场景叠加)→ [[generate-bill-tiered-pricing]]
|
|||
|
|
- 工业表倍率叠加 → [[generate-bill-with-multiplier]]
|
|||
|
|
- 异常高用量(可能触发 max)→ [[exception-high-consumption]]
|
|||
|
|
- 读数错误导致离谱算账 → [[exception-readings-locked-after-bill]] 修正
|
|||
|
|
|
|||
|
|
## 相关文档
|
|||
|
|
|
|||
|
|
- [[multiplier-and-tiered-pricing]]
|
|||
|
|
- [[bill-generation-pipeline]]
|
|||
|
|
- [[generate-bill-tiered-pricing]]
|
|||
|
|
- [[generate-bill-with-multiplier]]
|
|||
|
|
- [[exception-high-consumption]]
|