From 963d432d62e1d7811fc7770c13804d4c4a42f3bf Mon Sep 17 00:00:00 2001 From: Willie Date: Mon, 25 May 2026 22:27:38 +0800 Subject: [PATCH] vault backup: 2026-05-25 22:27:38 --- .obsidian/workspace.json | 28 +-- .../deposit/forfeit-damage-public-area.md | 189 +++++++++++++++++ .../deposit/forfeit-violation-no-permit.md | 190 ++++++++++++++++++ .../deposit/refund-partial-after-forfeit.md | 161 +++++++++++++++ .../refund-with-payment-channel-switch.md | 146 ++++++++++++++ 5 files changed, 700 insertions(+), 14 deletions(-) create mode 100644 prop-acc/scenarios/deposit/forfeit-damage-public-area.md create mode 100644 prop-acc/scenarios/deposit/forfeit-violation-no-permit.md create mode 100644 prop-acc/scenarios/deposit/refund-partial-after-forfeit.md create mode 100644 prop-acc/scenarios/deposit/refund-with-payment-channel-switch.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index eae0ecc..acdc62f 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -13,12 +13,12 @@ "state": { "type": "markdown", "state": { - "file": "prop-acc/maps/deposit-knowledge-map.md", + "file": "prop-acc/index.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "deposit-knowledge-map" + "title": "index" } } ] @@ -94,7 +94,7 @@ "state": { "type": "backlink", "state": { - "file": "prop-acc/maps/deposit-knowledge-map.md", + "file": "prop-acc/index.md", "collapseAll": false, "extraContext": false, "sortOrder": "alphabetical", @@ -104,7 +104,7 @@ "unlinkedCollapsed": true }, "icon": "links-coming-in", - "title": "Backlinks for deposit-knowledge-map" + "title": "Backlinks for index" } }, { @@ -113,12 +113,12 @@ "state": { "type": "outgoing-link", "state": { - "file": "prop-acc/maps/deposit-knowledge-map.md", + "file": "prop-acc/index.md", "linksCollapsed": false, "unlinkedCollapsed": true }, "icon": "links-going-out", - "title": "Outgoing links from deposit-knowledge-map" + "title": "Outgoing links from index" } }, { @@ -156,13 +156,13 @@ "state": { "type": "outline", "state": { - "file": "prop-acc/maps/deposit-knowledge-map.md", + "file": "prop-acc/index.md", "followCursor": false, "showSearch": false, "searchQuery": "" }, "icon": "lucide-list", - "title": "Outline of deposit-knowledge-map" + "title": "Outline of index" } }, { @@ -196,14 +196,18 @@ }, "active": "b06ed69835363258", "lastOpenFiles": [ + "prop-acc/scenarios/deposit/forfeit-violation-no-permit.md", + "prop-acc/scenarios/deposit/forfeit-damage-public-area.md", + "prop-acc/scenarios/deposit/deposit-first-time-renovation.md", + "prop-acc/scenarios/deposit/refund-with-payment-channel-switch.md", + "prop-acc/maps/deposit-knowledge-map.md", + "prop-acc/scenarios/deposit/refund-partial-after-forfeit.md", "prop-acc/scenarios/deposit/refund-full-no-damage.md", "prop-acc/index.md", "prop-acc/scenarios/deposit/deposit-additional-topup.md", "prop-acc/concepts/adhoc/collection-order-and-receipt.md", "prop-acc/scenarios/deposit/deposit-on-behalf-by-company.md", - "prop-acc/scenarios/deposit/deposit-first-time-renovation.md", "prop-acc/scenarios/deposit", - "prop-acc/maps/deposit-knowledge-map.md", "prop-acc/concepts/deposit/deposit-vs-adhoc-vs-prepaid.md", "prop-acc/concepts/deposit/red-receipt-design.md", "prop-acc/concepts/deposit/transaction-types.md", @@ -220,10 +224,6 @@ "prop-acc/maps/knowledge-map.md", "prop-acc · 知识地图.md", "index.md", - "patrol/index.md", - "业户.md", - "prop-acc/scenarios/adhoc/config-add-item.md", - "prop-acc/scenarios/adhoc/config-delist-item-handle-pending.md", "prop-acc/scenarios/adhoc", "prop-acc/concepts/adhoc", "resident-portal/scenarios", diff --git a/prop-acc/scenarios/deposit/forfeit-damage-public-area.md b/prop-acc/scenarios/deposit/forfeit-damage-public-area.md new file mode 100644 index 0000000..f2386da --- /dev/null +++ b/prop-acc/scenarios/deposit/forfeit-damage-public-area.md @@ -0,0 +1,189 @@ +--- +title: prop-acc · deposit · 场景 - 损坏公共走道墙面扣 800 +aliases: + - 损坏扣罚 + - 墙面损坏扣押金 + - forfeit-damage-public-area + - 场景-损坏扣罚 +tags: + - 场景 + - prop-acc + - 保证金 + - 扣罚 +audience: + - 业户 + - 业务人员 +status: 已发布 +sub_feature: deposit +last_review: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:损坏公共走道墙面扣 800 + +最常见的扣罚场景。装修过程中工人**损坏了公共区域**(走道墙面、电梯轿厢、楼栋出入口等),物业凭损坏证据和修复成本从押金扣除。 + +## 典型情境 + +> [!example] 真实情境 +> 陈先生家装修运输板材时,工人在 12 楼到 1 楼搬运过程中**撞坏了公共走道墙面**(凹陷一块,约 50cm × 30cm)。物业找施工方维修报价 ¥800(刮腻子重新粉刷)。陈先生当初交了 ¥5,000 装修保证金,要扣这 ¥800。 + +## 业户视角 + +### 第 1 步:物业告知发现损坏 + +通常装修验收时发现,或装修过程中物业巡查发现。物业会: + +- 拍照(损坏部位、范围) +- 出**定损报价单**(找的施工方报价) +- 联系您说明情况 + +### 第 2 步:决定接受或拒绝 + +| 决定 | 后续 | +|---|---| +| **接受** | 物业从押金扣 ¥800,装修结束后剩余退还,本场景 | +| **拒绝** | 物业冻结账户进入纠纷,走 [[freeze-during-dispute]] | + +> [!tip] 接受不等于"没事" +> 接受扣罚是同意"我损坏了,这 ¥800 修复成本由我承担"。如果对损坏归责有异议(可能是装修前就坏的、可能是其他业户损坏),应**先拒绝走调解**,而不是先接受再反悔(已扣的钱难以追回)。 + +### 第 3 步:收到红字收据 + +"装修保证金扣罚 ¥-800(公共走道墙面损坏)" + +> [!info] 钱去哪了 +> 这 ¥800 从物业**代管负债**科目转入**装修维修收入**科目。账上的资金没有离开物业账户,只是性质变了 —— 用于支付实际修复成本。 + +### 第 4 步:剩余款怎么办 + +账户里还剩 ¥4,200。可以: + +- **当下退** → 走 [[refund-partial-after-forfeit]](合并扣罚+退款的完整场景) +- **暂留账户** → 万一装修后续还有问题,从余额继续扣;无问题再退 + +## 业务人员视角(物业财务) + +### 第 1 步:准备扣罚证据 + +- 损坏照片(多角度) +- 定损报价单(第三方或物业内部维修队的) +- 业户书面同意(签字 / 微信确认截图) + +> [!warning] 没有证据不能扣 +> 没有上述材料就执行扣罚等于**单方面挪用代管资金**,审计大忌。即使业户口头同意也必须留书面凭证。 + +### 第 2 步:打开账户 + +后台 → 保证金 → 账户列表 → 找到陈先生账户(Active,balance=5000)→ 进入 `ViewDepositAccount`。 + +### 第 3 步:点击 `ForfeitureAction`(标签"扣罚") + +右上角状态管理组。Modal 表单: + +| 字段 | 填什么 | +|---|---| +| **扣罚金额** | ¥800 | +| **扣罚事由(memo)** | "公共走道墙面损坏,12-1F 楼梯口,定损报价 ¥800" | +| **关联凭证(选填)** | 上传定损报价单 PDF / 损坏照片 | + +> [!warning] Policy 守护 +> `ForfeitureAction` 加了 `->authorize('forfeit')` 守护:`update` 权限 + `canWithdraw()` 状态。Frozen 账户该按钮灰化。 + +### 第 4 步:提交 + +系统调 `ForfeitFromDepositAccountAction`,事务内: + +1. 校验账户 `canWithdraw()`(Active only) +2. 校验扣罚金额 ≤ 当前余额 +3. 建 `CollectionOrder`(`actual_amount=-800` 红字,`status=Completed`) +4. 加 `DepositTransaction`(`type=forfeiture`,`amount=800`,`balance_before=5000`,`balance_after=4200`,关联红字 CO) +5. 更新 `DepositAccount.balance=4200` +6. 触发 `CollectionOrderCompleted` → Listener 建红字 Receipt"装修保证金扣罚 ¥-800(公共走道墙面损坏)" + +注意:扣罚**不会自动关账**,因为余额非 0,账户保持 Active,后续可继续操作。 + +### 第 5 步:给业户红字收据 + +后台找到 Receipt → 打印 / 发微信 → 通知陈先生剩余款 ¥4,200。 + +## 系统流程 + +```mermaid +sequenceDiagram + participant 业户 + participant 财务 + participant Filament + participant ForfeitFromDepositAccountAction + participant 数据库 + participant 监听器 + + 财务->>业户: 拍照 + 定损 + 告知 + 业户->>财务: 接受扣 800 + 财务->>Filament: ViewDepositAccount → ForfeitureAction(modal) + Filament->>ForfeitFromDepositAccountAction: handle(account, 800, reason) + ForfeitFromDepositAccountAction->>ForfeitFromDepositAccountAction: canWithdraw()? (Active=true) + ForfeitFromDepositAccountAction->>ForfeitFromDepositAccountAction: 800 ≤ 5000? yes + ForfeitFromDepositAccountAction->>数据库: 开启事务 + ForfeitFromDepositAccountAction->>数据库: 1. 建 CollectionOrder (-800 红字, Completed) + ForfeitFromDepositAccountAction->>数据库: 2. 建 DepositTransaction (forfeiture, 5000→4200) + ForfeitFromDepositAccountAction->>数据库: 3. balance=4200(不自动关账) + ForfeitFromDepositAccountAction->>监听器: 4. 触发 CollectionOrderCompleted + 监听器->>数据库: 5. 建 Receipt (装修保证金扣罚 ¥-800) + ForfeitFromDepositAccountAction->>数据库: 提交事务 + Filament-->>财务: 成功通知 + 财务-->>业户: 红字收据 + 余额通知 +``` + +## 常见问题 + +> [!question] 扣罚金额 > 押金余额怎么办? +> 系统校验 `amount ≤ balance`,提交时会被守护拦截抛错。**业务上**: +> - 扣全部余额(走本流程,金额改成余额),账户余额 0 自动关 +> - 不足的部分**需要业户单独补缴**(开新订单 / 走司法程序),系统不自动处理 +> +> 物业不应"先借后扣"或"超额扣罚",任何缺口必须有独立追偿凭证。 + +> [!question] 扣罚后能撤销吗? +> **不能直接撤销**(`DepositTransaction` 不可变)。如果扣错了: +> - 走一笔 `Deposit` 反向冲回(等于"退还扣罚款") +> - 备注清楚写明"撤销 2026-XX-XX 扣罚误判" +> - 审计上能完整追溯"扣 → 撤" 全过程 +> +> 这种做法虽然多两笔流水,但**每笔都有合规凭证**,不留信息空白。 + +> [!question] 多次损坏分多次扣可以吗? +> 可以。例如: +> - 周一:墙面损坏扣 ¥800 +> - 周三:电梯按钮被砸扣 ¥200 +> - 周五:楼栋玻璃损坏扣 ¥500 +> +> 三笔独立 `ForfeitureAction`,各自有事由、各自有凭证。账户余额累计减少。 + +> [!question] 扣罚事由写多详细? +> 越详细越好。审计、复盘、纠纷都需要。推荐结构: +> - 损坏部位:"公共走道墙面,12-1F 楼梯口" +> - 损坏程度:"凹陷 50×30cm,需刮腻子重新粉刷" +> - 定损依据:"物业维修队报价 ¥800" 或 "第三方[xxx 装修公司] 报价单" +> - 业户确认:"业户陈某某 2026-XX-XX 微信确认接受" + +> [!question] 业户拿到收据后反悔怎么办? +> 已扣的钱难追回。**预防胜于补救**: +> - 扣罚前务必拿到业户书面同意 +> - 不要在业户犹豫时强扣 +> - 复杂纠纷先 [[freeze-during-dispute|冻结]] 调解 + +## 异常分支 + +- 业户拒绝接受扣罚 → [[freeze-during-dispute]] +- 扣罚后退余款 → [[refund-partial-after-forfeit]] +- 扣全部余额清零关账 → 继续走 [[close-after-zero-balance]](本流程余额非零,不适用) +- 未申请直接动工的违约扣罚 → [[forfeit-violation-no-permit]] + +## 相关文档 + +- [[transaction-types]] +- [[red-receipt-design]] +- [[forfeit-violation-no-permit]] +- [[refund-partial-after-forfeit]] +- [[freeze-during-dispute]] diff --git a/prop-acc/scenarios/deposit/forfeit-violation-no-permit.md b/prop-acc/scenarios/deposit/forfeit-violation-no-permit.md new file mode 100644 index 0000000..82eae44 --- /dev/null +++ b/prop-acc/scenarios/deposit/forfeit-violation-no-permit.md @@ -0,0 +1,190 @@ +--- +title: prop-acc · deposit · 场景 - 未申请直接动工违约扣罚 +aliases: + - 违约扣罚 + - 未报装修扣押金 + - forfeit-violation-no-permit + - 场景-违约扣罚 +tags: + - 场景 + - prop-acc + - 保证金 + - 扣罚 +audience: + - 业户 + - 业务人员 +status: 已发布 +sub_feature: deposit +last_review: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:未申请直接动工违约扣罚 + +业户**未走申请流程**(没向物业报备、没办出入证、没交押金)就**直接开工装修**,物业按装修管理协议扣罚违约金。 + +## 典型情境 + +> [!example] 真实情境 +> 物业巡查员发现 8 楼 8-2-302 房间内**正在敲墙**,但物业**没有这家业户的装修报备记录**。物业上门要求停工,业户(刘先生)解释"刚开始,以为周末没人来管"。 +> +> 按装修管理协议第 X 条:"未向物业报备私自动工,违约金 ¥3,000"。物业要求刘先生**立即补办装修申请 + 缴装修保证金 ¥5,000 + 缴违约金 ¥3,000**。 + +## 业户视角 + +### 第 1 步:被物业告知违约 + +物业上门 / 电话告知: + +- 您家正在装修但未报备 +- 违反装修管理协议第 X 条 +- 需停工 + 补办手续 + 缴违约金 + +### 第 2 步:补办手续 + +- 签装修管理协议 +- 提供施工合同 / 施工方信息 +- **缴 ¥5,000 装修保证金 + ¥3,000 违约金** + +### 第 3 步:扣罚方式 + +物业操作: + +| 步骤 | 操作 | +|---|---| +| 1. 缴款 | 您交 ¥8,000(押金 5000 + 违约金 3000)到物业账户 | +| 2. 开 DepositAccount | 押金账户首次缴款 ¥5,000([[deposit-first-time-renovation]] 流程) | +| 3. **同时扣罚** | 从押金账户**扣 ¥3,000**(违约金,实际钱已收) | +| 4. 账户余额 | ¥5,000 - ¥3,000 = ¥2,000 留作真正押金 | + +> [!warning] 这是简化做法,严格说应分两笔账 +> 严格的会计做法: +> - 押金账户记 ¥5,000(代管负债) +> - 违约金 ¥3,000 走独立 [[adhoc-flow-a-vs-flow-b|adhoc 一次性收费]] 流(直接进收入) +> +> 当前简化:让一笔押金账户兼"扣罚"用,本质上是把 ¥3,000 通过 forfeiture 流水转入维修收入科目。审计可追溯但科目映射略粗。 + +### 第 4 步:收到 2 张收据 + +- 蓝字:"装修保证金缴纳 ¥5,000"(押金缴款) +- 红字:"装修保证金扣罚 ¥-3,000(违约金:未报备私自动工)" + +> [!info] 业户感受 +> 您一共付了 ¥8,000,实际押金账户里只剩 ¥2,000。装修结束无其他损坏的话,退您 ¥2,000。 + +## 业务人员视角(物业财务 + 装修管理) + +### 第 1 步:取证 + +- 现场照片(动工迹象、装修工具、施工人员) +- 业户书面承认违约 +- 物业巡查记录 + +### 第 2 步:补办流程 + +催业户带材料到物业前台: + +- 装修管理协议(签字) +- 施工合同 +- 身份证 / 房产证 + +### 第 3 步:做两笔操作 + +**操作 A — 开账户首次缴款**(详见 [[deposit-first-time-renovation]]): +- `CreateDepositAccount`,首次缴款 ¥5,000,业户支付方式 +- 系统建账户 + DepositTransaction(deposit, 0→5000)+ Receipt + +**操作 B — 扣罚违约金**(详见 [[forfeit-damage-public-area]]): +- `ViewDepositAccount` → `ForfeitureAction`(modal) +- 扣罚金额 ¥3,000 +- 扣罚事由 "违约金:未报备私自动工,2026-XX-XX 巡查发现,业户已书面承认" +- 系统建红字 CO + DepositTransaction(forfeiture, 5000→2000)+ 红字 Receipt + +### 第 4 步:把两张收据交业户 + +- 蓝字缴款收据 ¥5,000 +- 红字扣罚收据 ¥-3,000 + +业户余额 ¥2,000,后续装修按正常流程管理。 + +## 系统流程 + +```mermaid +sequenceDiagram + participant 业户 + participant 财务 + participant Filament + participant 数据库 + + Note over 业户,财务: 业户已支付 8000(押 5000 + 违约 3000) + + 财务->>Filament: CreateDepositAccount + 首次缴 5000 + Filament->>数据库: 建 Account (Active, 5000) + CO (+5000) + Transaction (deposit) + Receipt + 数据库-->>财务: 账户已建,余额 5000 + + 财务->>Filament: ViewDepositAccount → ForfeitureAction (3000, 违约金) + Filament->>数据库: 建 CO (-3000 红字) + Transaction (forfeiture, 5000→2000) + 红字 Receipt + 数据库-->>财务: 账户余额 2000(Active 状态保持) + + 财务-->>业户: 蓝字 + 红字 2 张收据 +``` + +## 流水台账(本场景完整记录) + +| 流水 | type | amount | balance_before | balance_after | 关联 CO | Receipt | +|---|---|---|---|---|---|---| +| 1 | deposit | 5000 | 0 | 5000 | CO #1(+5000) | "装修保证金缴纳 ¥5,000" | +| 2 | forfeiture | 3000 | 5000 | 2000 | CO #2(-3000) | "装修保证金扣罚 ¥-3,000(违约金:未报备私自动工)" | + +净流入物业:¥5,000 - ¥3,000 = ¥2,000 代管 + ¥3,000 计入收入(通过 forfeiture)。 + +## 常见问题 + +> [!question] 业户拒不补办怎么办? +> 物业可: +> - 张贴停工通知 +> - 通知房管局 / 街道办 +> - 切断装修施工水电(看物业管理权限) +> - 业户继续违规 → 报警 / 走司法 +> +> 系统层面不处理这类强制措施,只在业户**配合补办**时支持上述操作。 + +> [!question] 违约金是直接扣还是先收押金再扣? +> 两种方式: +> +> | 方式 | 优 | 缺 | +> |---|---|---| +> | 一笔单独"违约金"adhoc 收入 | 科目清晰(进收入,不入押金账户) | 业户感受是"两笔不同性质的钱",流程长 | +> | 押金账户内扣罚(本场景) | 一笔进账简单,押金账户也兼违约金 | 科目较粗(违约金通过 forfeiture 路径转收入) | +> +> 当前推荐**前者**(严格会计),实际很多物业用**后者**(简单)。两种做法系统都支持。 + +> [!question] 业户已经把装修做完了才被发现未报备怎么办? +> 看具体情境: +> - 物业完全没收押金:补办手续 + 缴押金 + 扣违约金,本场景 +> - 物业已收押金但没开账户:补办账户,补扣违约金 +> - 装修已完成无损坏:可只扣违约金不留押金,余额 0 关账 + +> [!question] 同一户多次违约可以累计扣吗? +> 可以。每次违约一笔 `ForfeitureAction`,各自有事由。账户余额持续减少。**累计扣超过押金余额时**: +> - 系统拒绝(`amount ≤ balance` 守护) +> - 需让业户**补缴押金**后再扣 +> - 或者**部分扣 + 剩余追偿** —— 系统只处理账内部分 + +> [!question] 违约扣罚业户不接受走纠纷怎么办? +> [[freeze-during-dispute]] 冻结调解。但违约扣罚一般有**协议+证据**,业户胜诉概率低。 + +## 异常分支 + +- 损坏类扣罚 → [[forfeit-damage-public-area]] +- 业户接受扣罚后退余款 → [[refund-partial-after-forfeit]] +- 全部扣罚清零关账(罕见,违约严重)→ [[close-after-zero-balance]] +- 业户拒绝接受 → [[freeze-during-dispute]] + +## 相关文档 + +- [[forfeit-damage-public-area]] +- [[deposit-first-time-renovation]] +- [[transaction-types]] +- [[red-receipt-design]] +- [[refund-partial-after-forfeit]] diff --git a/prop-acc/scenarios/deposit/refund-partial-after-forfeit.md b/prop-acc/scenarios/deposit/refund-partial-after-forfeit.md new file mode 100644 index 0000000..6c8076e --- /dev/null +++ b/prop-acc/scenarios/deposit/refund-partial-after-forfeit.md @@ -0,0 +1,161 @@ +--- +title: prop-acc · deposit · 场景 - 部分扣罚后退还差额 +aliases: + - 扣罚后退差额 + - 部分退款 + - refund-partial-after-forfeit + - 场景-押金扣罚后退差额 +tags: + - 场景 + - prop-acc + - 保证金 + - 退款 + - 扣罚 +audience: + - 业户 + - 业务人员 +status: 已发布 +sub_feature: deposit +last_review: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:部分扣罚后退还差额 + +业户装修**有损坏**,物业扣一部分赔偿,剩下的部分退还。两步流水:先 [[forfeit-damage-public-area|扣罚]] 再 refund,账户余额清零自动关闭。 + +## 典型情境 + +> [!example] 真实情境 +> 陈先生家装修完了,公共走道墙面被工人撞坏一小块,**修复成本 ¥800**(物业找人修)。陈先生当初交了 ¥5,000 装修保证金,扣 ¥800 后退还 ¥4,200。 + +## 业户视角 + +### 第 1 步:装修完通知验收 + +同 [[refund-full-no-damage|无损退还]] 第 1 步。 + +### 第 2 步:验收发现损坏 + +- 物业验收员拍照、定损、出具修复报价 +- 给您看证据,告知"墙面修复需 ¥800,从您押金扣" +- 您可选: + - **同意扣罚** → 走本流程,扣 800 退 4200 + - **不同意** → 进入纠纷,账户冻结(走 [[freeze-during-dispute]]) + +### 第 3 步:扣罚后等退款 + +物业先扣 ¥800,再退 ¥4,200。 + +### 第 4 步:收到 2 张红字收据 + +- 红字收据 1:"装修保证金扣罚 ¥-800(公共走道墙面损坏)" +- 红字收据 2:"装修保证金退还 ¥-4,200" + +> [!info] 为什么是两张? +> 系统每笔流水生成一张独立收据,**扣罚和退款是两件事**。各自有金额、各自有事由,合并到一张反而看不清。详见 [[transaction-types]]。 + +## 业务人员视角(物业财务) + +### 第 1 步:做扣罚(`ForfeitureAction`) + +详见 [[forfeit-damage-public-area]]。要点: + +- Modal 表单填扣罚金额 ¥800、事由"公共走道墙面损坏" +- 系统建红字 CollectionOrder + DepositTransaction(forfeiture)+ Receipt +- 账户余额从 ¥5,000 变 ¥4,200 + +### 第 2 步:做退款(`RefundAction`) + +详见 [[refund-full-no-damage]]。要点: + +- Modal 表单**退款金额自动带入当前余额 ¥4,200** +- 选退款渠道 +- 系统建红字 CollectionOrder + DepositTransaction(refund)+ Receipt +- 账户余额从 ¥4,200 变 ¥0 +- **自动关账**(status=Closed) + +### 第 3 步:走线下退款 + 给收据 + +- 银行 / 微信退 ¥4,200 +- 把 2 张红字收据 + 1 张扣罚说明(可选,详细解释扣罚事由)交业户 + +## 系统流程 + +```mermaid +sequenceDiagram + participant 业户 + participant 财务 + participant Filament + participant ForfeitFromDepositAccountAction + participant RefundFromDepositAccountAction + participant 数据库 + + Note over 业户,财务: 验收发现墙面损坏 + + 业户->>财务: 同意扣 800 + 财务->>Filament: ViewDepositAccount → ForfeitureAction(modal) + Filament->>ForfeitFromDepositAccountAction: handle(account, 800, reason) + ForfeitFromDepositAccountAction->>数据库: 建红字 CO + DepositTransaction(forfeiture) + 数据库-->>数据库: balance 5000→4200 + + Note over 业户,财务: 接着退差额 + + 财务->>Filament: ViewDepositAccount → RefundAction(modal, 默认 4200) + Filament->>RefundFromDepositAccountAction: handle(account, 4200, channel) + RefundFromDepositAccountAction->>数据库: 建红字 CO + DepositTransaction(refund) + 数据库-->>数据库: balance 4200→0, status→Closed + 财务-->>业户: 2 张红字收据 + 银行/微信退 4200 +``` + +> [!info] 两步分别提交 +> 扣罚和退款**是两次独立操作**,各自一笔流水、一张收据、一个 CollectionOrder。这样保留独立审计痕迹,任何一步出问题不影响另一步。 + +## 流水台账(本场景完整记录) + +| 流水 ID | type | amount | balance_before | balance_after | 关联 CO | 凭证 Receipt | +|---|---|---|---|---|---|---| +| 1 | deposit | 5000 | 0 | 5000 | CO #1(+5000)| "装修保证金缴纳 ¥5,000" | +| 2 | forfeiture | 800 | 5000 | 4200 | CO #2(-800)| "装修保证金扣罚 ¥-800(公共走道墙面损坏)" | +| 3 | refund | 4200 | 4200 | 0 | CO #3(-4200)| "装修保证金退还 ¥-4,200" | + +`SUM(actual_amount of all CO) = +5000 - 800 - 4200 = 0` —— 账面平,物业代管资金净流入为 0,800 通过扣罚转入物业收入,4200 退还业户。 + +## 常见问题 + +> [!question] 业户不同意扣罚怎么办? +> 不要强扣。**先 [[freeze-during-dispute|冻结账户]]**,等沟通 / 调解结果再操作: +> - 调解结果"业户责任" → [[unfreeze-after-mediation|解冻]] → 走本场景 +> - 调解结果"物业误判" → 解冻 → 走 [[refund-full-no-damage|全额退还]] +> - 调解结果"双方妥协金额" → 解冻 → 按妥协金额走本场景 +> - **调解陷入僵局,业户失联或拒绝沟通** → 走 [[force-close-forfeit]] 或 [[force-close-retain]] + +> [!question] 扣罚 + 退款必须连续做吗? +> 不必须。可以: +> - 验收当天先扣罚(留账户 Active 余额 ¥4,200) +> - 第二天业户提供回款账号后再退 +> 中间间隔多久都行,只要账户保持 Active。 + +> [!question] 扣罚的钱去哪了? +> 扣罚的 CollectionOrder 是红字,`actual_amount=-800`,但**这笔钱实际上从"代管负债"科目转入"装修维修收入"科目**(物业收入)。账上的资金从未离开物业账户,只是性质从"代管"变为"收入"。 + +> [!question] 一次扣罚不够后续追加可以吗? +> 可以。例如先扣 ¥500,事后发现另有损坏再扣 ¥300。每次独立 `ForfeitureAction`,账户余额累计减少。 + +> [!question] 扣罚 + 退款后业户反悔说"墙是装修前就坏的"? +> 走 [[freeze-during-dispute|冻结]] 已晚(账户已 Closed)。线下沟通 + 财务通过 tinker / 后端补正(走 deposit 一笔反向流水冲),业务上属"事后追溯",系统不主动支持。 + +## 异常分支 + +- 全无损 → [[refund-full-no-damage]] +- 全是损坏要全扣 → 只走 [[forfeit-damage-public-area]],不退,账户余额 0 自动关 +- 业户拒绝扣罚进入纠纷 → [[freeze-during-dispute]] +- 账户 Frozen 时被迫处置 → [[force-close-refund]] / [[force-close-forfeit]] + +## 相关文档 + +- [[refund-full-no-damage]] +- [[forfeit-damage-public-area]] +- [[transaction-types]] +- [[red-receipt-design]] +- [[freeze-during-dispute]] diff --git a/prop-acc/scenarios/deposit/refund-with-payment-channel-switch.md b/prop-acc/scenarios/deposit/refund-with-payment-channel-switch.md new file mode 100644 index 0000000..65809db --- /dev/null +++ b/prop-acc/scenarios/deposit/refund-with-payment-channel-switch.md @@ -0,0 +1,146 @@ +--- +title: prop-acc · deposit · 场景 - 退款渠道与缴款渠道不同 +aliases: + - 退款换渠道 + - 现金缴款银行转账退 + - refund-with-payment-channel-switch + - 场景-押金退款换渠道 +tags: + - 场景 + - prop-acc + - 保证金 + - 退款 +audience: + - 业户 + - 业务人员 +status: 已发布 +sub_feature: deposit +last_review: 2026-05-25 +code_version: 2026-05-22 +--- + +# 场景:退款渠道与缴款渠道不同 + +业户当初**现金缴款**,现在想**银行转账退**(或反之)。系统支持渠道切换 —— `PaymentChannel` 在退款时独立选择,不绑死缴款时的渠道。 + +## 典型情境 + +> [!example] 真实情境(一) +> 张阿姨当年装修来交押金时**带的现金 ¥5,000**,留下了银行卡号。现在装修完无损要退,张阿姨说"现金我也不方便领,直接转我卡上吧"。 + +> [!example] 真实情境(二) +> 王装修公司当年**对公账户转账**交了 ¥15,000(3 户业主代缴)。退款时公司账号变更,要退到**新的对公账号**。 + +## 业户视角 + +### 第 1 步:告诉物业退款方式 + +退押前**主动说明**期望的退款渠道: + +- "退到我微信" +- "退到我建行卡 6228xxxxxx1234" +- "退到我公司新账户" + 提供新账户信息 + +### 第 2 步:等退款 + 收到红字收据 + +红字收据上的"退款渠道"字段反映**实际操作的渠道**(银行转账 / 微信),与缴款时的不同。例如: + +- 缴款 Receipt:"装修保证金缴纳 ¥5,000(现金)" +- 退款 Receipt:"装修保证金退还 ¥-5,000(银行转账)" + +> [!info] 系统不强制原路返回 +> 不像信用卡退款"必须原卡原路退",押金退款可以**任意渠道**,只要业务方同意。 + +## 业务人员视角(物业财务) + +### 第 1 步:打开账户做退款 + +同 [[refund-full-no-damage|无损全额退还]] 流程,在 `RefundAction` Modal 表单里: + +| 字段 | 填什么 | +|---|---| +| 退款金额 | 全额或部分 | +| **退款渠道(PaymentChannel)** | **关键!** 选当前业户指定的方式,不要被原缴款渠道误导 | +| 收款银行账户 | 若选银行转账,填**回款用的物业付款账户**(不是业户账户) | +| 备注 | 推荐写"原现金缴,退银行转账" 提示后续审计 | + +> [!warning] PaymentChannel 选错的后果 +> - 选错只影响后续线下退款操作和审计追溯,不影响系统资金流 +> - 但建议**事前与业户确认**,事后改字段是没法的(`DepositTransaction` 不可变) + +### 第 2 步:走线下退款流程 + +按选定的渠道实际转账: + +| PaymentChannel | 线下动作 | +|---|---| +| 微信 | 用物业微信账号给业户转 | +| 银行转账 | 导出转账指令,银行办理 | +| POS | 在 POS 机上做退款(注意:**只能退到原 POS 卡**,不适合渠道切换) | +| 现金 | 业户到前台领现金 | + +### 第 3 步:给红字收据 + +收据的"退款渠道"字段会反映实际操作渠道,业户能看到。 + +## 系统视角 + +退款的 `CollectionOrder.payment_channel_id` 字段**独立于**缴款 CollectionOrder 的同字段。 + +```mermaid +flowchart LR + A[缴款 CO #1
payment=现金
actual=+5000] -.关联.-> B[DepositAccount
balance=5000] + B -.关联.-> C[退款 CO #2
payment=银行转账
actual=-5000] + B --> D[balance=0, Closed] +``` + +每张 CO 各自记录自己的支付渠道,不互相影响。审计时看 2 张 CO 就知道"原现金,退银行转账"。 + +## 字段映射(渠道切换涉及的所有字段) + +| 字段 | 缴款时(CO #1) | 退款时(CO #2) | 是否必须一致 | +|---|---|---|---| +| `payment_channel_id` | 现金 | 银行转账 | ❌ 独立 | +| `bank_account_id` | NULL(现金不需要)| 物业银行账户 | ❌ 独立 | +| `actual_amount` | +5000 | -5000 | ❌ 相反符号 | +| `community_id` | 物业项目 | 同 | ✅ 必须 | +| `community_user_profile_id` | 张阿姨 | 同 | ✅ 必须(若业户账户)| + +## 常见问题 + +> [!question] 业户没提供银行卡能不能退? +> 不能退。退款必须有**可执行的回款渠道**。如果业户失联无法联系,走 [[force-close-retain|资金保留并关账]] 路径:账户翻 Closed,资金记入 `meta.balance_held_*` 审计字段,留待业户回来再操作。 + +> [!question] POS 缴款想退到银行卡可以吗? +> 看 POS 机和银行政策。一般 POS 退款必须原卡原路退。如果业户想换卡: +> - 方案 1:在 POS 机上做"原卡退款",业户收到后自行转去新卡 +> - 方案 2:走"虚拟"现金退款 —— 系统记 PaymentChannel=现金,实际走对公转账业户新卡(需财务有完整凭证支撑) +> - 推荐方案 1,合规度高 + +> [!question] 退款渠道与缴款渠道不一致会触发什么审计风险? +> 主要风险:**洗钱嫌疑**(虚假交易、套现等)。审计抽查会重点看这类"换渠道"的退款,要求物业留下: +> - 业户书面要求换渠道的依据(签字 / 微信记录截图存档) +> - 物业内部审批记录 +> - 银行流水回单 +> +> 系统只保证账面记录正确(红字 CO + 渠道字段),合规凭证靠物业流程保障。 + +> [!question] 公司账户变更了,如何确保打到新账户? +> 退款前更新 `DepositAccount.payer_contact` 字段(纯参考性,不影响支付),并在 Modal 表单"备注"清楚写明"新对公账号:xxx"。线下转账时财务按这个备注操作。 + +> [!question] 部分渠道(微信 / POS)有退款金额上限吗? +> 微信单笔退款 / POS 单日上限由对应支付网关决定,系统不限制。如超限,实际线下转账需分多笔或走银行转账,但**系统记录上仍是一张 Receipt**(单笔退款流水)。 + +## 异常分支 + +- 业户失联无法退款 → [[force-close-retain]] +- 退款触发支付网关失败(微信渠道异常等)→ 当前系统不处理回调,需财务沟通业户后线下补救 +- 业户拒绝任何退款方式 → [[freeze-during-dispute]] 冻结调解 + +## 相关文档 + +- [[refund-full-no-damage]] +- [[refund-partial-after-forfeit]] +- [[force-close-retain]] +- [[deposit-on-behalf-by-company]] +- [[red-receipt-design]]