vault backup: 2026-05-25 13:44:33

This commit is contained in:
Willie
2026-05-25 13:44:33 +08:00
parent 9f688120cd
commit 0f4882b83f
6 changed files with 749 additions and 0 deletions

View File

@@ -186,6 +186,11 @@
}, },
"active": "b06ed69835363258", "active": "b06ed69835363258",
"lastOpenFiles": [ "lastOpenFiles": [
"prop-acc/一次性收费/场景-取消-录错金额作废重做.md",
"prop-acc/一次性收费/场景-取消-业户改主意主动撤单.md",
"prop-acc/一次性收费/场景-B流-小程序下单+支付宝.md",
"prop-acc/一次性收费/场景-A流-装修公司批量采购出入证.md",
"prop-acc/一次性收费/场景-A流-前台办理充电桩电费充值.md",
"prop-acc/一次性收费/场景-A流-前台购买泳票.md", "prop-acc/一次性收费/场景-A流-前台购买泳票.md",
"prop-acc/一次性收费/场景-A流-前台购买装修出入证.md", "prop-acc/一次性收费/场景-A流-前台购买装修出入证.md",
"prop-acc/一次性收费/场景-B流-小程序下单+微信支付.md", "prop-acc/一次性收费/场景-B流-小程序下单+微信支付.md",

View File

@@ -0,0 +1,146 @@
---
title: 场景 - A 流 - 前台办理充电桩电费充值
tags:
- prop-acc
- 一次性收费
- 业务场景
- A流
audience:
- 业户
- 业务人员
status: stable
last_reviewed: 2026-05-25
code_version: 2026-05-22
---
# 场景:前台办理充电桩电费充值
电动车业主**预付式电费充值**。充值后电费从余额扣减。
> [!warning] 这其实更适合预存款模块
> 严格说,这种"预存后逐次抵扣"的场景应该走 **[[../预存款/index|预存款模块]]**(`PrepaidAccount` + `ConsumeAction`),而不是一次性收费。本场景描述的是**一次性买"电费券" / "充值码"** 的简化模式 —— 适合不需要逐次扣减的小区。
## 两种实现方式
### 方式 A:走一次性收费(简化,本场景)
业户付钱买**预付电费充值码**(类似话费充值卡),自己输入到充电桩。
- **适合**:充电桩支持充值码兑换
- **优点**:简单,后台只记一笔交易
- **缺点**:业户余额不在物业系统里,核对靠物理充值码
### 方式 B:走预存款模块(规范)
业户预存到物业开的"预付电费账户"(`PrepaidAccount`),用电时由集抄系统调用 `ConsumeAction` 自动扣减。
- **适合**:充电桩有联网,能实时上报用电量
- **优点**:业户余额清楚,系统自动扣减,可生成月度账单
- **缺点**:需要充电桩硬件支持联网
> [!info] 本文档继续讲方式 A
> 方式 B 详见预存款模块的"业户充值场景"(待补)。
## 典型情境
> [!example] 真实情境
> 张先生家有一辆电动车,小区充电桩需要预付费才能用。他来物业前台想充 ¥200。
## 业户视角
### 第 1 步:到前台
"我要给充电桩充 ¥200。"
### 第 2 步:付款
- 现金 / 微信 / POS
- 物业职员录入金额、提交
### 第 3 步:拿到充值码
- 职员给您**一张小票** 或 **微信发您一串充值码**
- 您在充电桩上输入,余额到账
> [!tip] 也可以打到 IC 卡
> 如果您的门禁 IC 卡支持电费(常见高档小区),职员可以**直接把 ¥200 余额写入您的 IC 卡**,不用记充值码。
## 业务人员视角
### Filament 录入(与 IC 卡几乎一样)
| 字段 | 填什么 |
|---|---|
| 业户 | 通过房号搜业户 |
| 收费项目 | "充电桩电费充值" |
| 数量 | 1(几张充值卡) |
| 金额 | 业户要充多少 |
| 支付方式 | 现金 / 微信 / POS |
| 备注 | 充值码 / 卡号(便于核对)|
### 与其他充值的对比
| 充值类型 | 模块 | 单价规则 |
|---|---|---|
| 充电桩(本场景)| 一次性收费 | 业户付多少充多少(无固定单价)|
| IC 卡 | 一次性收费 | 固定单价 ¥30-50 / 张 |
| 装修出入证 | 一次性收费 | 固定单价 ¥10-50 / 张 |
| 预存物业费 | 预存款模块 | 业户付多少存多少 |
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 前台
participant 一次性收费
participant 充电桩
业户->>前台: 充 ¥200 电费
前台->>一次性收费: 录入金额 + 提交
一次性收费-->>前台: 完成 + 充值码
前台->>业户: 给充值码 + 收据
业户->>充电桩: 输入充值码
充电桩-->>业户: 余额 ¥200
```
## 常见问题
> [!question] 充值码丢了能补办吗?
> 不能。充值码本质是"一次性使用"的密码。建议立刻在充电桩输入,不要保留。
> [!question] 业户充错金额(想充 ¥200 充成 ¥2000)能改吗?
> **作废重做**:走 [[场景-已收款作废]] 退还 ¥2000,重新录 ¥200。**前提是充值码还没用**。
> [!question] 业户余额没用完想退怎么办?
> 取决于物业政策。技术上**这条订单不能"部分退"**(订单是原子的)。变通方案:
> - 联系业户,作废原订单(退全款 ¥200)
> - 业户重新付实际使用金额(比如已用 ¥50 → 重新录一笔 ¥50)
> [!question] 充值码能给别人用吗?
> 系统不限制 —— 充值码是"凭码兑换",**谁拿到谁能用**。业务上各物业政策不同。
## 何时换成预存款模块?
> [!tip] 升级到方式 B 的信号
> 如果你们小区出现以下情况,该考虑切换到预存款模块:
> - 业户经常问"我还剩多少钱"
> - 财务想月底对账"全小区欠多少预付费"
> - 充电桩硬件升级了能联网
切换路径:
1. 业户开 PrepaidAccount(预存款账户)
2. 充值走 `DepositAction`(预付款模块)
3. 用电由集抄系统自动 `ConsumeAction` 扣减
## 相关概念
- [[概念-A流与B流]]
- [[概念-CollectionOrder与Receipt]]
- [[场景-A流-前台购买IC卡]] — 模板
- 预存款模块文档(待补) — 方式 B 的实现
## 异常分支
- 充错金额 → [[场景-已收款作废]] + 重做
- 充值码丢失 → 不可补办,业务沟通退款

View File

@@ -0,0 +1,150 @@
---
title: 场景 - A 流 - 装修公司批量采购出入证
tags:
- prop-acc
- 一次性收费
- 业务场景
- A流
audience:
- 业务人员
status: stable
last_reviewed: 2026-05-25
code_version: 2026-05-22
---
# 场景:装修公司批量采购出入证
**与个人业户买装修证不同**:大型装修公司同时承包小区里几十户装修,每户都要发出入证 —— 一次买 50-200 张的场景。
> [!info] 主要给业务人员看
> 这个场景对业户(装修公司联系人)而言是"批量买 + 一笔结清";对业务人员是"录入快、对账难"。
## 典型情境
> [!example] 真实情境
> 鸿基装修公司在小区里承包 12 户精装修业务,共需要 60 张出入证。公司财务下午到物业,要一次性办完 60 张 + 一张发票。
## 业户(装修公司联系人)视角
### 您要准备什么
| 材料 | 数量 |
|---|---|
| 公司营业执照复印件 | 1 份 |
| 法人 / 经办人身份证 | 1 份 |
| **每户的装修合同**(原件 + 复印件)| 12 份 |
| 60 个工人的身份证复印件 | 60 份 |
| **可开发票的公司抬头 / 税号** | 用于开发票 |
### 流程
1. 到物业前台,出示材料
2. 物业核对身份和合同
3. 物业算总价:60 张 × ¥30 = ¥1800
4. 您付款(**通常公司账户转账或 POS 公司卡**)
5. 拿到 60 张装修证 + 发票(发票流程独立)
6. 把 60 张证按工地分发给工头
## 业务人员视角
### 关键策略:**一笔订单 vs 多笔订单**?
> [!warning] 重要决策
> 60 张装修证,**应该录成 1 笔订单(数量=60),还是 12 笔订单(每户一笔)**?
| 录法 | 优点 | 缺点 |
|---|---|---|
| **1 笔订单**(数量=60) | 操作快、收据 1 张 | 业户对账难,出问题作废只能整体作废 60 张 |
| **12 笔订单**(每户 1 笔) | 业户能按户对账,作废粒度细 | 录入慢、收据多张 |
| **15-30 笔混合** | 灵活,按楼栋分 | 取决于业务习惯 |
**推荐**:**按户分笔**(12 笔订单)。原因:
- 每户的装修合同号、工人名册都不一样,对账时能精确到户
- 后续如果某户停工要作废,只影响那一户的几张证
- 发票可以多张合并出(发票流程不绑定订单数量)
### Filament 录入(12 笔订单的版本)
```
1. 收公司财务的总金额 ¥1800
2. 对照装修合同清单,按户录入 12 笔:
├── 户 12-3-501,5 张装修证 ¥150
├── 户 12-3-502,4 张装修证 ¥120
├── ...
3. 12 笔订单的支付方式都填"公司转账"
4. 备注栏写"鸿基装修公司批量采购,合同号 XX"
5. 检查总金额 = ¥1800
6. 出 12 张收据 + 1 张发票(发票合并)
```
### 一笔订单的版本(快速版)
```
1. Filament 后台 → 一次性收费 → 新建
2. 业户:不绑定具体房号,填"鸿基装修公司"
3. 收费项目:装修出入证
4. 数量:60
5. 金额:1800
6. 支付方式:公司转账
7. 备注:"60 张,涉及房号:12-3-501, 12-3-502, ...(12 户)"
8. 提交
```
> [!warning] 一笔录入的副作用
> 这笔订单的 `community_user_profile_id` 不一定挂得上(装修公司不是常规业户)。
> 如果系统里没有装修公司的 `CommunityUserProfile`,**得先建一个"客户档案"再下订单**。
## 系统流程
```mermaid
sequenceDiagram
participant 装修公司
participant 前台
participant 系统
participant 财务
装修公司->>前台: 60 张装修证 + 12 户合同
前台->>前台: 核对合同 + 工人名册
Note over 前台,系统: 推荐:按户分 12 笔
loop 每户
前台->>系统: 录入一笔 AdHocEvent
系统-->>前台: 收据 1 张
end
装修公司->>前台: 公司账户转账 ¥1800
前台->>系统: 12 笔订单状态 Completed
前台->>财务: 走发票合并流程
财务-->>装修公司: 发票 1 张(¥1800)
```
## 常见问题
> [!question] 公司转账有时差,前台先发证还是先收款?
> 业界惯例是**先入账后发证**。技术上 12 笔订单可以**先建 Pending 状态**(B 流),等转账到账后再统一翻 Completed。
>
> 当前 A 流是即收即付,只能等款到账后录入。如果转账走 1-2 天,可以折中:
> 1. 当天先录 Pending(用 B 流的 `CreatePendingAdHocEventAction`)
> 2. 到账日再批量翻 Completed
> [!question] 业户要求开**一张大发票** 还是 **12 张小发票**?
> 发票流程独立于订单,系统不强制对应关系。多数公司要一张大发票(便于报销),物业方按业户需求开即可。
> [!question] 60 张证录 12 笔太慢了,有批量录入吗?
> 当前 Filament 后台**没有批量录入入口**。如果业务上批量场景很多,可以考虑加一个"批量下单" Filament Action(类似 ImportMeterReadingsAction 的导入模式)。**等业务方反馈再做**。
> [!question] 装修公司中途停工(只用了 30 张证)能退一半吗?
> 技术上每笔订单可以**单独作废**(详见 [[场景-已收款作废]])。30 张证对应作废 6 笔订单(假设按户分笔且每户 5 张),保留另外 6 户的 30 张。
>
> 如果是 1 笔大订单,**只能整体作废 60 张**,粒度不够。这就是推荐"按户分笔"的关键原因之一。
## 相关概念
- [[概念-A流与B流]]
- [[概念-CollectionOrder与Receipt]]
- [[场景-A流-前台购买装修出入证]] — 单户场景
## 异常分支
- 某户中途停工 → [[场景-已收款作废]] 作废对应那几笔
- 录入金额错误 → [[场景-已收款作废]] 重做

View File

@@ -0,0 +1,135 @@
---
title: 场景 - B 流 - 小程序下单 + 支付宝
tags:
- prop-acc
- 一次性收费
- 业务场景
- B流
audience:
- 业户
- 业务人员
status: stable
last_reviewed: 2026-05-25
code_version: 2026-05-22
---
# 场景:小程序下单 + 支付宝
业户在小程序内下单,**用支付宝(而非微信)** 完成支付。
> [!info] 几乎与微信流程一致
> 这个场景与 [[场景-B流-小程序下单+微信支付]] 99% 相同。本文档只描述**两种支付渠道的差异**。
## 业户视角
### 与微信支付流程的区别
| 维度 | 微信支付 | 支付宝 |
|---|---|---|
| 入口 | 微信小程序内拉起微信支付 | 微信小程序中**通过 H5 跳转支付宝**(或扫支付宝二维码)|
| 跳转体验 | 流畅(同一应用内) | 略多 1-2 步(跨应用)|
| 适用业户 | 偏年轻用户、华南地区 | 全国通用、商务用户更习惯 |
| 商户费率 | 0.2-0.6% | 0.55% |
| 回调速度 | 秒级 | 秒级(偶尔几十秒) |
### 业户实际操作
1. 在小程序选项目下单(完全相同)
2. 提交后选择"支付宝支付"
3. **微信小程序提示**:"即将跳转到支付宝完成支付"
4. 点确认 → 自动跳转支付宝 App
5. 输入支付宝密码 / 指纹完成支付
6. **自动跳回小程序**,显示支付成功
> [!success] 完成
> 跨应用跳转 → 回跳整个过程通常 < 10 秒。
## 业务人员视角
### 与微信流程的唯一区别:对账
> [!warning] 月底对账要分账户
> - 微信支付的款进**物业微信商户号**
> - 支付宝的款进**物业支付宝商户号**
>
> 两个商户号一般绑定**两个不同的银行账户**。月底对账时,要分别拉两边的流水。
在 Filament 后台,`CollectionOrder.payment_channel` 字段区分了不同支付方式:
```
collection_orders
├── payment_channel: "微信支付" → 对账走微信流水
└── payment_channel: "支付宝" → 对账走支付宝流水
```
财务月底查询:
```sql
-- 微信渠道
SELECT SUM(actual_amount) FROM acc_collection_orders
WHERE collection_completed_at BETWEEN '2026-05-01' AND '2026-05-31'
AND payment_method LIKE '%微信%';
-- 支付宝渠道
SELECT SUM(actual_amount) FROM acc_collection_orders
WHERE collection_completed_at BETWEEN '2026-05-01' AND '2026-05-31'
AND payment_method LIKE '%支付宝%';
```
详见 [[场景-审计-月底现金对账]]。
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 小程序
participant 系统
participant 支付宝
业户->>小程序: 下单,选支付宝
小程序->>系统: POST /api/ad-hoc-events
系统-->>小程序: 订单号 CO-xxx + 支付宝拉起参数
Note over 小程序,支付宝: 跨应用跳转
小程序->>支付宝: 拉起支付(H5/SDK)
业户->>支付宝: 密码 / 指纹
支付宝->>系统: POST /webhook/alipay
系统->>系统: MarkAdHocEventPaidAction (payment_channel='支付宝')
系统->>系统: 同微信流程,翻 Completed + 生成 Receipt
系统-->>小程序: 推通知
支付宝-->>业户: 跳回小程序
小程序-->>业户: 显示已付款
```
## 常见问题
> [!question] 业户没装支付宝怎么办?
> 微信小程序内拉起支付宝**要求业户手机里装了支付宝 App**。没装的话会失败。变通方案:让业户选微信支付,或换 [[场景-跨渠道补缴|跨渠道到前台]] 现金/POS。
> [!question] 支付宝跳转回小程序失败怎么办?
> 这种情况钱已经扣了但小程序没显示成功。**支付宝有"支付成功通知"** 推送给业户,业户在支付宝里能看到。系统的支付宝回调一般 30 秒内能到,**让业户等等**,不要重复支付。
> [!question] 为什么不直接做支付宝小程序?
> 单独做一个支付宝小程序意味着双套代码,运营也要双倍发文章。**等业户群超过 30% 用支付宝时再考虑**。当前**微信小程序 + 跳转支付宝**是最划算的方案。
> [!question] 业务人员能在后台手动加一笔"支付宝退款"吗?
> 当前不在 UI 暴露(同微信)。退款流程:
> 1. 业户申诉
> 2. 业务人员去支付宝商户后台手动发起退款(支付宝平台操作)
> 3. 在 Filament 后台对应订单走 [[场景-已收款作废]] 标记
>
> 等支付网关 webhook 上线后,可以自动化。
## 相关概念
- [[概念-A流与B流]]
- [[概念-CollectionOrder与Receipt]] — `payment_method` 字段区分渠道
- [[场景-B流-小程序下单+微信支付]] — 标准 B 流
- [[场景-审计-月底现金对账]] — 多渠道对账
## 异常分支
- 支付完成但小程序卡死 → 系统会按 webhook 数据为准,后台可见已收款
- 想取消未付订单 → 场景-取消-业户改主意主动撤单

View File

@@ -0,0 +1,167 @@
---
title: 场景 - 取消 - 业户改主意主动撤单
tags:
- prop-acc
- 一次性收费
- 业务场景
- 取消退款
audience:
- 业户
- 业务人员
status: stable
last_reviewed: 2026-05-25
code_version: 2026-05-22
---
# 场景:业户改主意主动撤单
**B 流场景**:业户在小程序下完单但还没付款,自己主动取消。
> [!info] 与超时作废的区别
> [[场景-超时未付自动作废|超时作废]]是系统**被动**作废(到期了机器自动废)。本场景是**业户主动**操作。两者都只针对 Pending 状态,**已支付订单走 [[场景-已收款作废]]**。
## 典型情境
> [!example] 真实情境
> 周先生在小程序下单 2 张游泳卡 ¥400,准备明天带朋友来游泳。下单后 5 分钟接到朋友电话说出差不来了,他想取消订单。
## 业户视角
### 第 1 步:打开"我的订单"
小程序底部 → 我家 → 我的订单
### 第 2 步:找到待付款订单
```
我的订单
├── 🟡 待付款
│ └── 游泳卡 × 2 ¥400
│ 订单号 CO-20260525-XXX
│ 下单于 5 分钟前
│ ⏰ 剩余 25 分钟自动取消
│ [立即支付] [取消订单]
└── ✅ 已完成
└── ...
```
### 第 3 步:点"取消订单"
弹出确认框:
```
确认取消订单?
取消后此订单不可恢复,如需购买请重新下单。
[再想想] [确认取消]
```
点"确认取消"。
### 第 4 步:订单消失
```
我的订单
├── 🟡 待付款
│ (空)
└── ✅ 已完成 / ❌ 已取消
└── 游泳卡 × 2 ¥400
状态:已取消
原因:用户主动取消
```
> [!success] 完成
> 您未付款,**不涉及任何退款**。订单从"待付款"列表移除,显示在"已取消"区。
## 业务人员视角
### 几乎不用关心
> [!tip] 全自动
> 业户撤单 → 小程序 API → 后端 `VoidAdHocEventAction` → 完成。**业务人员不参与**。
### 业务人员能看到什么
Filament 后台 → 一次性收费 → 切到"已作废" tab:
```
状态:Voided
meta.voided_at: 2026-05-25 15:42:11
meta.voided_reason: "[业户主动取消] 用户在小程序点击取消"
meta.voided_by: null (业户操作,无运营员工)
```
### 如何区分"业户主动撤单"和"系统超时作废"?
`voided_reason` 前缀:
| 前缀 | 来源 |
|---|---|
| `[业户主动取消] ...` | 业户在小程序点取消 |
| `[订单超时作废] ...` | Scheduled job 自动作废 |
| `[临时收费事件作废] ...` | 业务人员在 Filament 后台手动作废 |
详见 `VoidAdHocEventAction``$reason` 参数处理。
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 小程序
participant 系统
业户->>小程序: 我的订单 → 点取消
小程序->>业户: 弹确认框
业户->>小程序: 确认
小程序->>系统: DELETE /api/ad-hoc-events/{id}
系统->>系统: 检查订单是否 Pending
alt 是 Pending
系统->>系统: VoidAdHocEventAction
系统->>系统: AdHocEvent → Voided
系统->>系统: CollectionOrder → Failed
系统->>系统: 写 meta.voided_reason = "[业户主动取消] ..."
系统-->>小程序: 成功
小程序-->>业户: 显示"已取消"
else 已是 Completed
系统-->>小程序: 失败,提示"订单已支付,请走退款"
小程序-->>业户: 提示
end
```
## 常见问题
> [!question] 取消后还能恢复吗?
> **不能**。取消是终态。要继续买,请重新下单。
> [!question] 我已经付款了想取消怎么办?
> 走 [[场景-已收款作废]] —— 但需要**联系物业**(小程序不直接暴露付款后的取消按钮,以防误操作)。
> [!question] 我取消的时候系统说"操作失败"?
> 可能是:
> 1. **订单已超时**:你点取消的瞬间订单刚被系统自动作废了 —— 实际效果一样,刷新页面看
> 2. **网络问题**:重试一次
> 3. **订单已被支付**:支付回调与你的取消操作同时到达,以支付为准
> [!question] 取消会影响我的信用吗?
> 不会。系统**不记录**业户取消次数。
## 与超时作废的对照
| 维度 | 业户主动撤单(本场景)| [[场景-超时未付自动作废\|系统超时作废]] |
|---|---|---|
| 触发方 | 业户 | 系统(scheduled job)|
| 时间窗 | 任何时候(只要未付)| 超过 expires_at |
| meta.voided_by | null | null |
| 业户感知 | 主动,即时反馈 | 被动,登录小程序才发现 |
| 适用场景 | 业户明确不想要 | 业户忘记付 |
两种情况**底层都走 `VoidAdHocEventAction`** —— 同一份级联废逻辑,只是触发来源不同。
## 相关概念
- [[概念-AdHocEvent状态机]] — Pending → Voided 流转
- [[概念-CollectionOrder与Receipt]] — Pending 单作废时收据未生成,无需处理
- [[场景-B流-小程序下单+微信支付]] — 上游下单流程
- [[场景-超时未付自动作废]] — 系统自动版本
- [[场景-已收款作废]] — 已支付场景

View File

@@ -0,0 +1,146 @@
---
title: 场景 - 取消 - 录错金额作废重做
tags:
- prop-acc
- 一次性收费
- 业务场景
- 取消退款
audience:
- 业务人员
status: stable
last_reviewed: 2026-05-25
code_version: 2026-05-22
---
# 场景:录错金额作废重做
业务人员**手滑录错金额**(常见:多打/少打一个零、串到隔壁字段)的修正流程。
## 典型情境
> [!example] 真实情境
> 周末下午泳池前台高峰期,职员小赵给陈太太录入泳票订单:
> - **应该录**:¥40(2 张 × ¥20)
> - **实际录**:¥400(数量栏串到金额栏)
>
> 陈太太微信支付完跳出来,看到收据写 ¥400 当场愣住:"这怎么扣这么多?!"
## 业务人员视角
### 应急步骤(2 分钟内搞定)
```
1. 当场承认错误,安抚业户
"对不起阿姨,这是我录错了,我马上给您处理。"
2. 在 Filament 后台找到这笔订单
├── 状态 Completed
├── 金额 ¥400
└── 业户名:陈太太
3. 走 VoidAction(作废)
├── 必填作废原因:
│ "录入金额错误,实际应为¥40。
│ 已向业户致歉,通过微信原路退款 ¥400。
│ 重新建一笔正确订单。"
├── 提交
└── 系统瞬间:订单 → Voided, 收据 → Voided
4. 微信商户后台发起退款 ¥400(原路退回业户)
5. 重新录入正确订单
├── 数量:2
├── 金额:¥40
├── 支付方式:现金(因为业户当面拿现金给你)
├── 备注:"对上一笔订单 CO-XXX 作废后重做"
└── 提交
6. 给业户出新收据
```
### 关键细节
> [!warning] 关键:**作废 + 重做必须连贯**
> 中间不要去做别的事,容易忘记重做。**一气呵成最稳妥**。
> [!tip] 重做时的支付方式怎么填?
> - 业户原本微信付的 ¥400 已经在退款中(需要几小时到账)
> - **重新付 ¥40 走现金最简单**(业户钱包随便拿)
> - 也可以让业户重新微信支付 ¥40(完全一笔新交易)
> - **不建议**:让业户等微信退款到账后再交 —— 业户体验差
## 与"已收款作废"的区别
| 维度 | 已收款作废([[场景-已收款作废]]) | 录错重做(本场景)|
|---|---|---|
| 触发场景 | 业户反悔、缺货、退货 | 业务人员录入失误 |
| 是否重做 | **不重做**(纯取消)| **必须重做**(业户确实要这个商品)|
| 复杂度 | 1 步:作废 | 2 步:作废 + 重做 |
| 资金 | 全额退给业户 | **退原金额** + **重收正确金额** |
| 业户体验 | 一切照常,只是没了 | 短暂困惑,但快速纠正 |
## 系统流程
```mermaid
sequenceDiagram
participant 业户
participant 业务人员
participant 系统
participant 微信商户
业户->>业务人员: 出示错单 ¥400
业务人员->>系统: 找到 Completed 订单
业务人员->>系统: VoidAction (reason="录入金额错误...")
系统->>系统: AdHocEvent → Voided
系统->>系统: CollectionOrder → Failed
系统->>系统: Receipt → Voided
系统-->>业务人员: 作废成功
业务人员->>微信商户: 后台发起退款 ¥400
微信商户-->>业户: 几小时内到账
Note over 业户,业务人员: 同时,重新录入正确订单
业户->>业务人员: 拿出现金 ¥40
业务人员->>系统: 新建 AdHocEvent (¥40, 现金)
系统->>系统: 一气呵成三件套
系统-->>业务人员: 完成
业务人员->>业户: 新收据 + 实物
```
## 常见问题
> [!question] 重做的订单要不要在备注里写"对应原作废订单"?
> **强烈建议**。写"对上一笔订单 CO-XXX 作废后重做"。这样:
> - 财务对账时能看出"这两笔金额是同一笔业务"
> - 半年后审计抽查,能反查到完整事件
> [!question] 业户离开物业前没发现错单,事后才发现怎么办?
> 一样走作废 + 退款,但**沟通成本高**:
> - 联系业户:"系统发现一笔订单可能有误..."
> - 业户确认是否要重做
> - 退款走微信(原路)
> - 重做订单如果要新付款,**线上付款最方便**(让业户在小程序重新下单 + 支付)
> [!question] 业务人员自己发现录错 vs 业户发现录错,处理方式有区别吗?
> 没区别。但**业务人员自己发现要立刻处理**,不要等业户来质疑。
> [!question] 高峰期录单忙容易错,有什么预防方法?
> 1. **金额自动填**:在 Filament 后台,选 RatePlan 后金额自动算出 = `unit_price × quantity`,不要手改
> 2. **复核机制**:提交前 Modal 弹"确认 ¥XXX?" 让业务人员肉眼复核
> 3. **拆分付款步骤**:先收钱 + 数现金,再录入(确保实收金额对得上)
## 系统设计上的预防
> [!info] Filament Modal 已有的保护
> 当前 `CreateAdHocEvent` 表单:
> - 选 RatePlan 后**单价 + 总金额自动填**(避免手输错)
> - 提交前 Modal 显示金额(让业务人员肉眼复核)
> - 提交后给 success toast 通知(业务人员能即时看到结果)
>
> 如果还是错了 —— 通常是高峰期注意力分散,需要业务培训提醒。
## 相关概念
- [[概念-AdHocEvent状态机]] — Completed → Voided
- [[场景-已收款作废]] — 基础作废流程
- [[场景-A流-前台购买IC卡]] — 录入的正向流程