feat(finance): 完成成本快照运行层、销售事实与人工支出登记
迁移 108-111:快照业务时间与预估转实际、销售事实表、系统成本项、公司人工支出登记。接单平台按工单实际 reward 入账;人工支出支持登记/审批/驳回/报销并写 actual 快照。新增销售毛利页、人工支出页与订单入口。
This commit is contained in:
+15
-15
@@ -1,6 +1,6 @@
|
||||
# order_site 文档索引
|
||||
|
||||
> 最后校准:2026-10-18,代码基线 `main @ 7542d547`。
|
||||
> 最后校准:2026-10-22,代码基线 `dev @ 15989af8 + 财务 103–111`。
|
||||
> 本文是 `docs/` 的唯一入口。新增文档必须在上表登记状态;过期文档不再直接改写结论,统一移入 `docs/archive/`。
|
||||
|
||||
## 一、先记住五条口径
|
||||
@@ -35,7 +35,7 @@
|
||||
| 名称 | 业务含义 | 当前状态 |
|
||||
| --- | --- | --- |
|
||||
| `manual_expenses` | **客服备用金支出明细**:客服从自己的备用金里充值/采购/赔偿,减少客服余额 | 已实施(迁移 100) |
|
||||
| `manual_expense_records` | **公司人工支出/垫付登记**:按订单/成本项记录公司实际付出去的钱、付款人、收款人、凭证、审批 | 仅草案,未实施 |
|
||||
| `manual_expense_records` | **公司人工支出/垫付登记**:按订单/成本项记录公司实际付出去的钱、付款人、收款人、凭证、审批 | 已实施 P0(迁移 111) |
|
||||
|
||||
后续做财务系统时,**不要把 `manual_expenses` 直接改名或复用为 `manual_expense_records`**。两者业务含义、审批链和报表口径不同,应通过 `fund_expense_id` 建立关联。
|
||||
|
||||
@@ -54,22 +54,22 @@
|
||||
| --- | --- | --- |
|
||||
| 客服备用金台账 | **已实施 P0** | `fund_accounts` / `fund_entries` / `manual_expenses` / `fund_reconciliations`;后台页面、权限、审计已完成 |
|
||||
| 后台用户中文显示名 | **已实施** | `admin_users.display_name`,备用金姓名触发器同步;审计、登录记录、任务处理人优先显示中文名 |
|
||||
| 商品主数据 + 渠道 SKU 映射 | **已实施 P0(feat 分支)** | 迁移 `103`(映射消歧在 `106`);`product_catalog` / `channel_product_mappings`,后台「商品与成本」页支持维护、历史订单项回填与按载体分区 |
|
||||
| 成本中心 | **已实施 P0(feat 分支)** | 迁移 `104` + 修正 `105`;`107` 增加商品履约载体。`cost_items` / `cost_versions` / `cost_snapshots` / `cost_exceptions` 支持版本、预览、快照、异常队列、自动发货价格导入 |
|
||||
| 销售事实 / 订单毛利 | 未实施 | `sales_daily_facts` 仍是 DDL 草案;现有财务页不能按商品/店铺/载体算真实毛利 |
|
||||
| 公司人工支出登记 | 未实施 | 与已实施的客服备用金支出不是同一张表 |
|
||||
| 商品主数据 + 渠道 SKU 映射 | **已实施 P0(dev 分支)** | 迁移 `103`(映射消歧在 `106`);`product_catalog` / `channel_product_mappings`,后台「商品与成本」页支持维护、历史订单项回填与按载体分区 |
|
||||
| 成本中心 | **已实施 P0(dev 分支)** | 迁移 `104/105/107/108/110`;`cost_items` / `cost_versions` / `cost_snapshots` / `cost_exceptions` 支持版本、预览、快照、异常队列、自动发货价格导入;接单平台按工单实际报酬、人工按支出登记写入实际快照 |
|
||||
| 销售事实 / 订单毛利 | **已实施 P0(dev 分支)** | 迁移 `109`;`sales_daily_facts` 按店铺×日期×标准商品×载体汇总,未归一商品单独成行;后台新增「销售毛利」页,成本缺失会显式告警 |
|
||||
| 公司人工支出登记 | **已实施 P0(dev 分支)** | 迁移 `111`;`manual_expense_records` / `manual_expense_events`,后台「人工支出」页支持登记、审批、驳回、报销;与客服备用金 `manual_expenses` 通过 `fund_expense_id` 关联 |
|
||||
| 影子总账 | 未实施 | 现有财务页仍是 `UNION ALL` 业务事件拼装,不是复式总账 |
|
||||
| 平台对账 / 期间关账 | 未实施 | 仅方案 |
|
||||
|
||||
> 分支状态(2026-10-22):商品主数据、渠道映射、成本中心与自动发货价格在 `feat/cost-center-wip`,尚未合并 `main`、未部署生产;生产口径仍以 `main` 为准。
|
||||
> 分支状态(2026-10-22):商品主数据、渠道映射、成本中心、成本快照运行层、销售事实与公司人工支出登记在 `dev` 分支(原 `feat/cost-center-wip` 已合并),**尚未合并 `main`、未部署生产**;生产口径仍以 `main` 为准。
|
||||
|
||||
## 三、统一实施顺序
|
||||
|
||||
```text
|
||||
1. 商品主数据 + 渠道 SKU 映射 已完成 P0
|
||||
2. 成本中心 + 销售事实(先接收入与标准成本) 成本中心已完成 P0;销售事实未实施
|
||||
3. 订单毛利 / 店铺日报 未实施
|
||||
4. 公司人工支出登记(桥接现有客服备用金支出) 未实施
|
||||
2. 成本中心 + 销售事实(先接收入与标准成本) 已完成 P0(迁移 108/109)
|
||||
3. 订单毛利 / 店铺日报 已完成 P0(销售毛利页,成本缺失显式告警)
|
||||
4. 公司人工支出登记(桥接现有客服备用金支出) 已完成 P0(迁移 111)
|
||||
5. 影子总账(订单、工单、押金、提现、寄卖、售后) 未实施
|
||||
6. 平台对账、报表、期间关账 未实施
|
||||
```
|
||||
@@ -81,7 +81,7 @@
|
||||
| # | 问题 | 当前结论 | 影响 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | 收入金额口径 | ✅ 用户实付(`orders.total_amount`) | 收入基数 |
|
||||
| 2 | 收入确认时点 | ⏳ 待定:付款 / 发货 / 验收 / 售后期结束 | 利润表与预收账款 |
|
||||
| 2 | 收入确认时点 | ✅ 先按 `paid_at` 归属销售日;成本在快照生成后回填 | 利润表与预收账款 |
|
||||
| 3 | 打手报酬 | ✅ 支出/成本,总额法 | 履约成本 |
|
||||
| 4 | 退款/仲裁 | ✅ 暂不实现,只预留反向凭证 | 后续冲减 |
|
||||
| 5 | 人工支出如何入账 | ✅ 以人工支出登记为入口;需与客服备用金支出桥接 | 人工成本与应付垫付人 |
|
||||
@@ -95,8 +95,8 @@
|
||||
| --- | --- | --- |
|
||||
| [项目全量分析报告-2026-10-17.md](项目全量分析报告-2026-10-17.md) | 参考 | 当前架构、业务链路、风险与改进路线;代码基线早于备用金实现,涉及财务部分以本索引为准 |
|
||||
| [财务系统集成方案.md](财务系统集成方案.md) | 现行方案(未实施) | 财务系统边界、复式记账模型、核心表、API、分期落地 |
|
||||
| [成本中心与三块履约模型.md](成本中心与三块履约模型.md) | 现行(P0 已实施) | 自动发货/接单平台/人工客服三块、商品映射与成本中心;销售事实仍为方案 |
|
||||
| [人工支出登记落地方案-2026-10-17.md](人工支出登记落地方案-2026-10-17.md) | 现行方案(未实施) | 公司人工支出登记:字段、入口、状态机、权限、与备用金/成本中心/总账的衔接 |
|
||||
| [成本中心与三块履约模型.md](成本中心与三块履约模型.md) | 现行(P0 已实施) | 自动发货/接单平台/人工客服三块、商品映射、成本中心与销售事实 |
|
||||
| [人工支出登记落地方案-2026-10-17.md](人工支出登记落地方案-2026-10-17.md) | 现行(P0 已实施) | 公司人工支出登记:字段、入口、状态机、权限、与备用金/成本中心/总账的衔接 |
|
||||
| [影子总账说明.md](影子总账说明.md) | 现行说明(未实施) | 影子总账是什么、和钱包流水的区别、对账与转正标准 |
|
||||
| [客服备用金台账实施方案-2026-10-18.md](客服备用金台账实施方案-2026-10-18.md) | **已实施 P0** | 客服备用金账户、流水、支出、对账、权限与上线记录 |
|
||||
| [接单模板匹配引擎重构设计.md](接单模板匹配引擎重构设计.md) | 现行(P0/P1 已实施) | `kuaishou-91 / pdd / douyin-mashida` 三来源匹配引擎 |
|
||||
@@ -117,8 +117,8 @@
|
||||
| 文件 | 用途 | 接入前必须处理 |
|
||||
| --- | --- | --- |
|
||||
| [drafts/2026-10-17-载体判定与人工块量化.sql](drafts/2026-10-17-载体判定与人工块量化.sql) | 载体分布/人工块量化查询、`carrier_type` 判定与回填 | 只读查询可直接用;DDL 部分按当前迁移号顺延,不占用 100/101 |
|
||||
| [drafts/2026-10-17-成本中心与销售事实-DDL草案.sql](drafts/2026-10-17-成本中心与销售事实-DDL草案.sql) | `product_catalog`、`channel_product_mappings`、`cost_items/versions/snapshots/exceptions`、`sales_daily_facts` | 商品与成本部分已落地为 `102/103/104`;剩余销售事实按新迁移号继续,草案不再作为建表依据 |
|
||||
| [drafts/2026-10-17-人工支出登记-DDL草案.sql](drafts/2026-10-17-人工支出登记-DDL草案.sql) | `manual_fulfillment_cases`、`manual_expense_records`、`manual_expense_events` | 已改用 `*_manual_expense_records_*` 命名,并补 `fund_expense_id`;接入前仍需复核与迁移号 |
|
||||
| [drafts/2026-10-17-成本中心与销售事实-DDL草案.sql](drafts/2026-10-17-成本中心与销售事实-DDL草案.sql) | `product_catalog`、`channel_product_mappings`、`cost_items/versions/snapshots/exceptions`、`sales_daily_facts` | 商品、成本、销售事实均已落地(`103–109`);系统成本项在 `110`;草案仅作设计追溯,不再作为建表依据 |
|
||||
| [drafts/2026-10-17-人工支出登记-DDL草案.sql](drafts/2026-10-17-人工支出登记-DDL草案.sql) | `manual_fulfillment_cases`、`manual_expense_records`、`manual_expense_events` | 人工支出登记已落地为 `111`;轻量人工 case 仍为草案 |
|
||||
|
||||
## 六、厂商协议与外部资料
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
-- ============================================================================
|
||||
-- 人工支出登记 + 轻量人工处理记录(建表草案)
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 状态:草案(DRAFT)。**未接入** apps/backend/src/db/migrations。
|
||||
-- 依赖:本文引用 product_catalog / cost_items / cost_snapshots / manual_expenses,
|
||||
-- 必须**在** `2026-10-17-成本中心与销售事实-DDL草案.sql` **之后**应用;
|
||||
-- `manual_expenses` 已由迁移 100 创建(客服备用金支出)。
|
||||
-- 当前已使用迁移至 107(成本中心落在 103–107);本文建议顺延为
|
||||
-- `108_manual_cases.sql`、`109_manual_expenses.sql`,接入时按实际最大号调整并先跑 `npm run check:sql`。
|
||||
-- 状态:已实施 P0。`manual_expense_records` / `manual_expense_events` 已接入
|
||||
-- `111_manual_expense_records.sql`;`manual_fulfillment_cases` 仍未实施。
|
||||
-- 依赖:product_catalog / cost_items / cost_snapshots / manual_expenses。
|
||||
-- 当前已使用迁移至 111(成本中心 103–108,系统成本项 110,人工支出 111)。
|
||||
-- 基线:main @ 7542d547;依据:2026-10-17 业务口径确认 + 2026-10-18 备用金落地复核。
|
||||
--
|
||||
-- 重要命名边界:
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
-- ============================================================================
|
||||
-- 通用成本中心 + 标准商品 + 销售事实(建表草案)
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- 状态:部分落地。商品主数据 + 渠道映射 + 成本中心已接入 `103_product_catalog.sql`、
|
||||
-- `104_cost_center.sql`、`105_cost_center_bootstrap_fix.sql`;本文件仅保留设计追溯。
|
||||
-- 尚未实施的 `sales_daily_facts` 等后续内容,接入时从新迁移号继续,并先跑 `npm run check:sql`。
|
||||
-- 状态:商品、成本、销售事实均已落地。商品主数据 + 渠道映射接入 `103_product_catalog.sql`,
|
||||
-- 成本中心接入 `104_cost_center.sql` / `105_cost_center_bootstrap_fix.sql` / `108_cost_snapshot_runtime.sql`,
|
||||
-- 销售事实接入 `109_sales_daily_facts.sql`;本文件仅保留设计追溯。
|
||||
-- 注意:实际 `sales_daily_facts.canonical_product_id` 允许为空(未归一桶),与下方草案的 NOT NULL 不同。
|
||||
-- 基线:main @ 7542d547;数据依据:本地只读克隆(生产快照,orders 316,597,数据截至 2026-10-14)。
|
||||
-- 金额单位:分(BIGINT)。本文件所有 *_fen 列均为分。
|
||||
-- 设计依据:docs/成本中心与三块履约模型.md(三块载体、成本版本与快照)、docs/财务系统集成方案.md。
|
||||
-- 当前状态:商品主数据、渠道映射、成本中心已实施 P0;销售事实未实施。客服备用金支出已实施,但不是本文件的成本中心。
|
||||
-- 当前状态:商品主数据、渠道映射、成本中心、销售事实均已实施 P0。
|
||||
--
|
||||
-- 目标(业务原话):以后改成本只在一个地方。
|
||||
-- -> 所有成本金额只写 cost_versions;业务表只保存 cost_snapshot_id 与派生金额,永不回写历史。
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
# 人工支出登记落地方案(2026-10-18 修订)
|
||||
|
||||
> 状态:**现行方案(未实施)**
|
||||
> 最后校准:2026-10-18
|
||||
> 代码基线:`main @ 7542d547`
|
||||
> 状态:**已实施 P0(`dev` 分支,迁移 111)**
|
||||
> 最后校准:2026-10-22
|
||||
> 代码基线:`dev @ 15989af8 + 财务 108/109/110/111`
|
||||
> 依据:业务口径「人工块当前不以 SLA 监管为目标,先把流程搞清楚:哪个客服处理了哪些东西、付了多少钱、什么项目、关联哪个订单」。
|
||||
> 数据来源:本地只读克隆(生产快照,数据截至 2026-10-14)+ 现有代码盘点。
|
||||
> 重要:**客服备用金支出已经实施**(`manual_expenses`),但本文的**公司人工支出登记**(`manual_expense_records`)尚未实施;两张表不是一回事,不能直接复用或改名。
|
||||
> 重要:**客服备用金支出已经实施**(`manual_expenses`);**公司人工支出登记**(`manual_expense_records`)也已实施,两张表通过 `fund_expense_id` 关联,不是同一张表。
|
||||
> 相关文档:[成本中心与三块履约模型.md](成本中心与三块履约模型.md) §8 · [财务系统集成方案.md](财务系统集成方案.md) §八 · [客服备用金台账实施方案](客服备用金台账实施方案-2026-10-18.md) ·
|
||||
> DDL 草案 [drafts/2026-10-17-人工支出登记-DDL草案.sql](drafts/2026-10-17-人工支出登记-DDL草案.sql)
|
||||
|
||||
@@ -16,22 +16,32 @@
|
||||
| 表 | 业务含义 | 当前状态 | 关键字段 |
|
||||
| --- | --- | --- | --- |
|
||||
| `manual_expenses` | **客服备用金支出**:客服从自己的备用金账户里充值/采购/赔偿 | **已实施** | `account_id` / `fund_entry_id` / `category` / `payee_*` / `evidence_json` |
|
||||
| `manual_expense_records` | **公司人工支出/垫付登记**:按订单/成本项记录公司实际付出去的钱 | 仅草案 | `order_id` / `order_item_id` / `cost_item_id` / `paid_by_admin_user_id` / `status` / `cost_snapshot_id` |
|
||||
| `manual_expense_records` | **公司人工支出/垫付登记**:按订单/成本项记录公司实际付出去的钱 | **已实施 P0(迁移 111)** | `order_id` / `order_item_id` / `cost_item_id` / `paid_by_admin_user_id` / `status` / `cost_snapshot_id` |
|
||||
|
||||
结论:
|
||||
|
||||
1. 客服侧已经收口的是“备用金余额与用途”,解决“客服手里有多少钱、这笔钱花到哪”。
|
||||
2. 财务侧还缺的是“公司口径的实际支出/垫付”,解决“公司为哪个订单、哪个成本项、付给谁、谁垫的、有没有审批和凭证”。
|
||||
2. **公司口径的实际支出/垫付已落地**:后台「人工支出」页(`/admin/manual-expenses`)支持登记、审批、驳回、报销;通过后按成本项写 `cost_snapshots`,没有有效成本版本时进入异常队列。
|
||||
3. 两张表通过 `fund_expense_id` 关联:如果这笔公司支出来源于客服备用金,就填;公司直付则留空。
|
||||
4. **不要**把 `manual_expenses` 直接改名为 `manual_expense_records`,也不要让两张表共用索引/约束名。
|
||||
|
||||
实现落点(2026-10-22):
|
||||
|
||||
- 迁移:`apps/backend/src/db/migrations/111_manual_expense_records.sql`
|
||||
- 服务:`apps/backend/src/services/finance/manual-expense-service.ts`
|
||||
- 接口:`apps/backend/src/routes/admin/finance.ts` 的 `/finance/manual-expenses*`
|
||||
- 页面:`apps/frontend/src/pages/admin/AdminManualExpensePage.tsx`,入口 `/admin/manual-expenses`
|
||||
- 订单入口:订单详情「登记人工支出」按钮,自动带入订单 ID
|
||||
- 权限:查看 `finance.view` / `fund.view`,登记 `fund.expense` / `finance.config`,审核 `finance.review`
|
||||
- 成本快照:通过后以 `subject_type='manual_case'`、`subject_id=expense.id` 写 `actual` 快照;同一订单项多笔支出可累加,不会互相覆盖
|
||||
|
||||
---
|
||||
|
||||
|
||||
## 一、结论先行
|
||||
|
||||
1. **订单里的数据足够预填 90%**:店铺、商品、规格、数量、用户实付、支付时间、平台单号、履约标签、状态,后台订单列表/详情已经全部具备。客服实际只需要补 **4 件事**:渠道/项目、金额、收款方、凭证(外加默认带出的「谁、什么时候」)。
|
||||
2. **现有财务页没有“支出”这一侧**。财务页现有 7 个账目类别(订单收款、订单退款、打手报酬、打手提现、打手充值、打手资金回收、售后追缴退还)**全部是收款或打手侧资金**;客服备用金支出已经落在 `fund` 模块,但还没有汇总进财务页,也没有公司口径的人工支出/垫付登记。
|
||||
2. **原有财务页没有“支出”这一侧**:7 个账目类别全部是收款或打手侧资金。现在公司人工支出已有独立「人工支出」页;客服备用金支出仍在 `fund` 模块,两者通过 `fund_expense_id` 桥接。
|
||||
3. **落地成本低、风险小**:不需要改订单主表,不需要新角色体系(现有 `admin/finance/operator/support` 四角色 + `finance.*` 权限即可覆盖),只需新增「公司人工支出登记」表 + 订单侧入口 + 财务侧新类别。
|
||||
4. **登记必须“发生在垫付当天”**才有监管价值;事后补记只能算账,不能算监管。
|
||||
5. **本轮只补公司口径**:客服备用金台账已完成,不重复做一套客服余额系统;通过 `fund_expense_id` 关联即可。
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
>
|
||||
> 边界:影子总账解决“钱怎么记、怎么对”,不负责“商品是什么、成本是多少、人工谁处理”。商品与成本见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md),人工履约见同一文档第八节。
|
||||
|
||||
> 当前进度:客服备用金已实施;`finance_*` 表、分录、对账、转正均未实施。
|
||||
> 当前进度:客服备用金、商品与成本中心、成本快照运行层、销售事实、公司人工支出登记已实施;`finance_*` 表、分录、对账、转正均未实施。
|
||||
|
||||
---
|
||||
|
||||
|
||||
+61
-54
@@ -1,8 +1,8 @@
|
||||
# 成本中心与三块履约模型
|
||||
|
||||
> 状态:**现行(P0 已实施)**。商品主数据、渠道映射、成本项目/版本/快照/异常已落地;销售事实仍为后续方案。
|
||||
> 最后校准:2026-10-18
|
||||
> 代码基线:`main @ 7542d547` + 未提交的商品/成本中心 P0
|
||||
> 状态:**现行(P0 已实施)**。商品主数据、渠道映射、成本中心、成本快照运行层、销售事实与公司人工支出登记已落地;轻量人工 case 与影子总账仍为后续方案。
|
||||
> 最后校准:2026-10-22
|
||||
> 代码基线:`dev @ 15989af8 + 财务 108/109/110/111`
|
||||
> 数据基线:2026-10-17 生产库只读聚合(`default_transaction_read_only=on`,仅 SELECT,无写入)
|
||||
> 实施顺序以 [README.md](README.md) §三 为准;本文负责“商品、成本、销售事实”的数据模型,不重复总账与页面设计。
|
||||
> 关联:
|
||||
@@ -18,32 +18,33 @@
|
||||
| 能力 | 状态 |
|
||||
| --- | --- |
|
||||
| 客服备用金支出(`manual_expenses`) | **已实施**;只解决客服备用金余额与用途,不等于公司人工支出登记 |
|
||||
| 商品主数据 / 渠道 SKU 映射 | **已实施 P0**;迁移 `102` + 匹配键修正 `105`,后台「商品与成本」页可批量初始化、维护与回填历史订单项 |
|
||||
| `cost_items` / `cost_versions` / `cost_snapshots` / `cost_exceptions` | **已实施 P0**;迁移 `103` + 修正 `104`,支持版本解析、预览、快照、异常队列 |
|
||||
| 销售事实 / 订单毛利 | 未实施;`sales_daily_facts` 仍为草案 |
|
||||
| 公司人工支出登记(`manual_expense_records`) | 未实施 |
|
||||
| 商品主数据 / 渠道 SKU 映射 | **已实施 P0**;迁移 `103` + 匹配键修正 `106`,后台「商品与成本」页可批量初始化、维护与回填历史订单项 |
|
||||
| `cost_items` / `cost_versions` / `cost_snapshots` / `cost_exceptions` | **已实施 P0**;迁移 `104` + 修正 `105`,`107` 增加商品载体,`108` 增加业务时间与预估/实际替代 |
|
||||
| 销售事实 / 订单毛利 | **已实施 P0**;迁移 `109`,`sales_daily_facts` + 后台「销售毛利」页,未归一商品单独成行 |
|
||||
| 公司人工支出登记(`manual_expense_records`) | **已实施 P0**;迁移 `111`,支持登记/审批/驳回/报销;轻量人工 case 尚未实施 |
|
||||
| 影子总账 | 未实施;必须在本文件的成本与销售事实之后 |
|
||||
|
||||
### 0.1 本期已实现边界
|
||||
|
||||
已实现:
|
||||
|
||||
- `product_catalog`、`channel_product_mappings`,以及 `order_items.canonical_product_id` / `normalized_quantity`;
|
||||
- `product_catalog`、`channel_product_mappings`,以及 `order_items.canonical_product_id` / `normalized_quantity` / `revenue_amount_fen` / `revenue_basis`;
|
||||
- 按 `provider + shop_id + platform_sku_code` 建映射,空 `shop_id` 为来源级映射、具体店铺优先;`provider` 必须与 `orders.provider` 一致(91 为 `91kaquan`,不是匹配层的 `kuaishou-91`,服务层会归一别名);
|
||||
- 映射回填与 SKU 文本数量回填;
|
||||
- 映射回填、SKU 文本数量回填与订单项收入固化(一单一品归整单,多品按等额拆分并标 `equal_split`);
|
||||
- `cost_items` / `cost_versions` / `cost_snapshots` / `cost_exceptions`;
|
||||
- 成本版本优先级 `rule > product > shop > provider > global`;
|
||||
- 订单项成本预览、成本快照、缺失成本异常;
|
||||
- 成本版本优先级 `rule > product > shop > provider > global`,按 `paid_at` / `accepted_at` 等业务时间解析;
|
||||
- 订单项成本预览、预估快照、工单验收实际快照、缺失成本异常;
|
||||
- `sync-cost-finance` 脚本与定时任务:批量回填快照并重算销售事实;
|
||||
- `sales_daily_facts` 与后台「销售毛利」页,未归一商品单独成行,成本缺失显式告警;
|
||||
- 后台「商品与成本」页、`finance.view` / `finance.config` 权限与审计。
|
||||
|
||||
本期不做:
|
||||
|
||||
- `sales_daily_facts` 与订单毛利报表;
|
||||
- 订单进单时自动写 `canonical_product_id` / `normalized_quantity`;
|
||||
- 自动发货、工单验收、人工 case 在业务事务内自动生成成本快照;
|
||||
- 上游 `cost_amount` 自动同步为 `cost_versions`;
|
||||
- 多订单项订单的收入分摊(当前按订单总额传给成本解析器);
|
||||
- 公司人工支出登记与影子总账。
|
||||
- 订单进单时自动写 `canonical_product_id` / `normalized_quantity`(目前用后台回填);
|
||||
- 上游 `cost_amount` 实时自动同步为 `cost_versions`(目前用价格导入脚本);
|
||||
- 人工 case 在业务事务内自动生成成本快照;
|
||||
- 退款按日冲减与退款金额字段;
|
||||
- 影子总账。
|
||||
|
||||
---
|
||||
|
||||
@@ -141,6 +142,11 @@ product_catalog
|
||||
|
||||
上游自动发货商品价格用 `apps/backend/scripts/sync-affiliate-dash-prices.ts` 批量导入(价格清单见 `apps/backend/scripts/data/affiliate-dash-prices.json`):按 `aff:<skuCode>` 补建/更新商品,并给指定成本项生成 `scope=product` 的按件版本;金额取上游 `cost_amount`(分),价格变化时先停用旧版本再插入新版本,历史快照不变。示例:`npx tsx scripts/sync-affiliate-dash-prices.ts --cost-item-id=5`。
|
||||
|
||||
接单平台与人工客服各有一个系统成本项(迁移 `110_system_cost_items.sql`):
|
||||
|
||||
- `sys_work_order_reward`:工单验收后直接按 `work_orders.reward_amount` 写 `actual` 快照,版本金额 0 只是占位,不进入预估阶段;本地最近 30 天已回填 38,023 条实际快照,金额与工单 reward 逐条一致。
|
||||
- `sys_manual_service`:人工支出登记通过后按登记金额写 `actual` 快照;成本版本先为 `draft` 占位,不参与预估,但允许人工支出使用实际金额入账。财务填写正式按单单价后可将版本改为 `active`。
|
||||
|
||||
### 3.2 渠道 SKU 映射
|
||||
|
||||
```text
|
||||
@@ -311,54 +317,54 @@ cost_snapshots
|
||||
|
||||
```text
|
||||
sales_daily_facts
|
||||
stat_date -- Asia/Shanghai
|
||||
stat_date -- Asia/Shanghai,按 paid_at 归属
|
||||
provider
|
||||
shop_id
|
||||
canonical_product_id
|
||||
sales_channel -- auto / work_order / manual
|
||||
canonical_product_id -- 允许为空:未归一桶
|
||||
carrier_type -- affiliate_dash / work_order / manual / shared / unknown
|
||||
order_count
|
||||
item_count
|
||||
quantity -- 归一化件数(SKU 文本解析后)
|
||||
gross_revenue_fen
|
||||
refund_fen
|
||||
refund_amount_fen
|
||||
net_revenue_fen
|
||||
auto_cost_fen
|
||||
work_order_cost_fen
|
||||
manual_cost_fen
|
||||
platform_fee_fen
|
||||
after_sales_loss_fen
|
||||
gross_profit_fen
|
||||
cost_amount_fen
|
||||
cost_missing_count
|
||||
cost_stage -- missing / partial / estimated / actual
|
||||
gross_profit_fen
|
||||
```
|
||||
|
||||
### 5.2 三个必须统一的字段
|
||||
|
||||
1. **商品**:`canonical_product_id`,不是原始 `sku_code`。
|
||||
1. **商品**:`canonical_product_id`,不是原始 `sku_code`;为空表示未归一,报表单独成行,不能丢。
|
||||
2. **数量**:`normalized_quantity`,不是简单的 `order_items.quantity`。
|
||||
3. **收入**:`revenue_amount_fen` + `revenue_basis`,不是直接 `orders.total_amount`。
|
||||
3. **收入**:`revenue_amount_fen` + `revenue_basis`,不是直接 `orders.total_amount`。一单一品归整单;多品当前按等额拆分,余数给最后一项。
|
||||
|
||||
收入口径建议:
|
||||
收入口径(2026-10-22 已确认):
|
||||
|
||||
| 来源 | 当前字段 | 建议 |
|
||||
| 来源 | 当前字段 | 口径 |
|
||||
| --- | --- | --- |
|
||||
| 91 | `maxAmount` | 明确是结算收入还是成本上限,再归一 |
|
||||
| PDD | `order_amount` | 作为订单收入候选 |
|
||||
| 抖音 | `pay_amount` | 作为买家支付收入候选 |
|
||||
| 91 | `orders.total_amount` | 用户实付,已与快手 `paymentFen` 核验一致 |
|
||||
| PDD | `orders.total_amount` | 用户实付 |
|
||||
| 抖音 | `orders.total_amount` | 用户实付 |
|
||||
|
||||
### 5.3 退款日期
|
||||
|
||||
现在只有 `pay_status=refunded` 和 `updated_at`,不足以做按日净销售。建议补 `refunded_at` / `refund_amount_fen`,或从退款事件表聚合。
|
||||
现在只有 `pay_status=refunded` 和 `updated_at`,不足以做按日净销售。`sales_daily_facts` 已预留 `refund_amount_fen`,但退款逻辑仍未接入;后续补 `refunded_at` / `refund_amount_fen` 或退款事件表。
|
||||
|
||||
### 5.4 统计实现
|
||||
|
||||
第一版可以用物化视图:
|
||||
当前是增量重算表,不是物化视图:
|
||||
|
||||
```text
|
||||
orders + order_items + channel_product_mappings + cost_snapshots
|
||||
-> sales_daily_facts
|
||||
-> sales_daily_facts(按日期范围 DELETE + INSERT)
|
||||
```
|
||||
|
||||
数据量目前约 35 万订单、每天 4k+ 单,物化视图 + 索引足够;后续再改增量表。
|
||||
后台入口:`/admin/sales-profit`。回填脚本:`npm run finance:sync -- --days=14 --mode=all`;定时任务 `cost-finance-sync` 每 5 分钟处理最近 7 天。成本缺失会写入 `cost_missing_count`,毛利在补齐成本前只作参考。
|
||||
|
||||
数据校验:本地 2026-07-10 ~ 2026-10-14 共 316,597 个已支付订单,其中 12 单没有订单项(¥2,480.60),无法归集到商品/成本,销售事实会排除并在页面单独提示;其余 316,585 个订单项收入与订单总额完全对平。
|
||||
最近 30 天回填后,接单平台实际成本快照 38,023 条、金额 1,633,917.74 元;其中落在销售事实日期范围内的成本 1,563,232.98 元,与工单 reward 逐条一致;自动发货与人工客服仍因缺少映射/正式单价显示成本缺失。
|
||||
|
||||
---
|
||||
|
||||
@@ -548,22 +554,22 @@ flowchart LR
|
||||
|
||||
## 十、分期落地
|
||||
|
||||
### P0:商品与销售事实(先能做报表)
|
||||
### P0:商品与销售事实(先能做报表)——已实施
|
||||
|
||||
- `product_catalog`
|
||||
- `channel_product_mappings`
|
||||
- `sales_daily_facts`(可先物化视图)
|
||||
- 数量归一、收入口径、退款日期补齐
|
||||
- `product_catalog`(迁移 `103/107`)
|
||||
- `channel_product_mappings`(迁移 `103/106`)
|
||||
- `sales_daily_facts`(迁移 `109`,日期范围重算表)
|
||||
- 数量归一、收入固化;退款日期字段仍待补
|
||||
|
||||
### P1:成本中心影子期
|
||||
### P1:成本中心影子期——已实施运行层
|
||||
|
||||
- `cost_items` / `cost_versions` / `cost_snapshots`
|
||||
- 自动发货先接固定成本
|
||||
- 工单先接现有规则金额
|
||||
- 人工先接按单/按小时成本
|
||||
- `cost_items` / `cost_versions` / `cost_snapshots`(迁移 `104/105/108`)
|
||||
- 自动发货接固定成本与价格导入
|
||||
- 接单平台:系统成本项 `sys_work_order_reward` 在工单验收后按 `reward_amount` 直接写实际快照
|
||||
- 人工客服:系统成本项 `sys_manual_service` + 人工支出登记通过后写实际快照;正式单价版本待财务填写
|
||||
- 缺失成本进异常队列
|
||||
|
||||
### P2:公司人工支出登记 + 轻量处理记录
|
||||
### P2:公司人工支出登记 + 轻量处理记录——支出登记已完成,轻量 case 未实施
|
||||
|
||||
- 载体判定(`carrier_type`)
|
||||
- 无载体自动建轻量 case(谁在处理哪个订单项)
|
||||
@@ -590,14 +596,15 @@ flowchart LR
|
||||
| 2 | 打手报酬是成本还是代收代付? | **支出/成本**:工单结算后打手会提现,我方实际付款给他们 → 按**总额法**(收入记用户实付全额,报酬记履约成本) | 业务确认 |
|
||||
| 3 | 人工块的目标是什么? | **先做流程可见与支出可追溯**(谁处理了哪些、付了多少钱、什么项目、关联订单号、凭证),SLA/监管指标延后 | 业务确认 |
|
||||
| 4 | 退款/仲裁怎么冲减? | **暂未接入,先预留**:字段、反向冲正关系与事件类型先留好,本轮不实现逻辑 | 业务确认 |
|
||||
| 5 | 收入确认时点? | **2026-10-22 确认:先按 `paid_at` 归属销售日**;成本在快照生成后回填到同一销售日,后续再评估验收/售后期口径 | 业务确认 |
|
||||
| 6 | 未归一商品怎么进报表? | **2026-10-22 确认:允许 `canonical_product_id` 为空,单独成“未归一”行**,保证总收入与订单总额对平 | 业务确认 |
|
||||
|
||||
### 11.2 仍待确认
|
||||
|
||||
1. 收入确认时点:付款 / 发货 / 验收 / 售后期结束?(金额口径已定 = 用户实付)
|
||||
2. 自动发货的 `cost_amount` 是否稳定、是否含平台积分/汇率?
|
||||
3. 人工支出按单还是按小时归集?(先按单登记,工时字段后续再加)
|
||||
4. 平台服务费/支付通道费由谁承担、结算周期与账单口径?
|
||||
5. 寄卖货款的采购成本确认时点?
|
||||
1. 自动发货的 `cost_amount` 是否稳定、是否含平台积分/汇率?
|
||||
2. 人工支出按单还是按小时归集?(先按单登记,工时字段后续再加)
|
||||
3. 平台服务费/支付通道费由谁承担、结算周期与账单口径?
|
||||
4. 寄卖货款的采购成本确认时点?
|
||||
|
||||
---
|
||||
|
||||
|
||||
+25
-9
@@ -1,9 +1,9 @@
|
||||
# 财务系统集成方案
|
||||
|
||||
> 状态:**现行方案(未实施)**。本文描述 `finance_*` 总账层;当前代码尚未建表,现有财务页仍是 `UNION ALL` 业务事件拼装。
|
||||
> 最后校准:2026-10-18
|
||||
> 代码基线:`main @ 7542d547`
|
||||
> 前置:商品主数据、渠道 SKU 映射、成本中心与销售事实必须先完成;商品映射与成本中心已完成 P0,销售事实仍待实施。实施顺序以 [README.md](README.md) §三 为准。
|
||||
> 状态:**现行方案(总账层未实施)**。本文描述 `finance_*` 总账层;当前 `finance_*` 尚未建表,现有财务页仍是 `UNION ALL` 业务事件拼装。商品、成本中心、销售事实与公司人工支出登记已完成 P0。
|
||||
> 最后校准:2026-10-22
|
||||
> 代码基线:`dev @ 15989af8 + 财务 108/109/110/111`
|
||||
> 前置:商品主数据、渠道 SKU 映射、成本中心、销售事实与公司人工支出登记必须先完成;这些前置已完成 P0。实施顺序以 [README.md](README.md) §三 为准。
|
||||
> 目标:在**不破坏现有抢单、押金、结算、寄卖、提现链路**的前提下,为 order_site 增加一套可对账、可关账、可追溯的财务系统。
|
||||
> 结论先说:**不要直接在 `worker_wallets` / `worker_wallet_ledgers` 上继续加字段。** 现有表是业务钱包与流水,不是会计总账;正确做法是新增复式记账底座,让现有钱包成为它的“余额投影”。
|
||||
>
|
||||
@@ -16,10 +16,11 @@
|
||||
| 能力 | 状态 |
|
||||
| --- | --- |
|
||||
| 客服备用金台账(`fund_*` / 备用金 `manual_expenses`) | **已实施 P0**,见 [客服备用金台账实施方案](客服备用金台账实施方案-2026-10-18.md) |
|
||||
| 商品主数据 / 渠道 SKU 映射 / 成本中心 | **已实施 P0(`feat/cost-center-wip`)**,迁移 `103/104/105/106/107`,含商品履约载体与自动发货价格版本,见 [成本中心与三块履约模型](成本中心与三块履约模型.md) |
|
||||
| 商品主数据 / 渠道 SKU 映射 / 成本中心 | **已实施 P0(`dev` 分支)**,迁移 `103/104/105/106/107/108`,含商品履约载体、自动发货价格版本与成本快照运行层,见 [成本中心与三块履约模型](成本中心与三块履约模型.md) |
|
||||
| `sales_daily_facts` / 订单级毛利 | **已实施 P0(`dev` 分支)**,迁移 `109`;后台「销售毛利」页按店铺/商品/载体汇总,未归一商品单独成行 |
|
||||
| 公司人工支出登记 `manual_expense_records` | **已实施 P0(`dev` 分支)**,迁移 `111`;后台「人工支出」页支持登记、审批、驳回、报销,通过后写 `cost_snapshots` |
|
||||
| `finance_accounts` / `finance_business_events` / `finance_journal_*` | 未实施 |
|
||||
| `finance_settlements` / `finance_reconciliations` | 未实施 |
|
||||
| 订单级收入/成本/毛利 | 未实施;成本中心已完成,仍需销售事实与收入分摊 |
|
||||
| 现有 `admin-finance-service.ts` | 仍是业务事件 `UNION ALL`,不是总账 |
|
||||
|
||||
**不要复用客服备用金的 `manual_expenses` 作为公司人工支出表。** 两者口径不同;公司人工支出应使用 `manual_expense_records`,并通过 `fund_expense_id` 关联备用金支出。
|
||||
@@ -384,7 +385,22 @@ postBusinessEvent({
|
||||
|
||||
### 5.2 API
|
||||
|
||||
建议新增前缀 `/api/v1/admin/finance`:
|
||||
已实现(P0,销售事实、成本快照与人工支出):
|
||||
|
||||
```text
|
||||
GET /api/v1/admin/finance/sales-profit/overview
|
||||
GET /api/v1/admin/finance/sales-facts
|
||||
POST /api/v1/admin/finance/sales-facts/rebuild
|
||||
POST /api/v1/admin/cost-center/snapshots/sync
|
||||
GET /api/v1/admin/finance/manual-expenses
|
||||
GET /api/v1/admin/finance/manual-expenses/overview
|
||||
POST /api/v1/admin/finance/manual-expenses
|
||||
POST /api/v1/admin/finance/manual-expenses/:id/approve
|
||||
POST /api/v1/admin/finance/manual-expenses/:id/reject
|
||||
POST /api/v1/admin/finance/manual-expenses/:id/reimburse
|
||||
```
|
||||
|
||||
总账层建议新增前缀 `/api/v1/admin/finance`:
|
||||
|
||||
```text
|
||||
GET /accounts
|
||||
@@ -474,12 +490,12 @@ POST /periods/:key/close
|
||||
|
||||
## 八、需要业务拍板的问题
|
||||
|
||||
> 2026-10-17 已确认 4 条口径,明细见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md) §11。
|
||||
> 2026-10-17 已确认 4 条口径,2026-10-22 追加确认收入时点与未归一商品口径;明细见 [成本中心与三块履约模型.md](成本中心与三块履约模型.md) §11。
|
||||
|
||||
| # | 问题 | 状态 | 影响 |
|
||||
| --- | --- | --- | --- |
|
||||
| 1 | 收入金额口径 | ✅ **已确认:收入 = 用户实付(`orders.total_amount`)**,与快手 `paymentFen` 数据核验 100% 一致 | 收入基数 |
|
||||
| 2 | 收入确认时点:付款 / 发货 / 验收 / 售后期结束? | ⏳ 待定(金额口径已定) | 决定利润表与预收账款 |
|
||||
| 2 | 收入确认时点:付款 / 发货 / 验收 / 售后期结束? | ✅ **先按 `paid_at` 归属销售日**;成本快照生成后回填到同一销售日 | 决定利润表与预收账款 |
|
||||
| 3 | 平台结算周期与账单口径(91、快手、PDD、抖音、affiliate-dash) | ⏳ 待定 | 决定对账与应收 |
|
||||
| 4 | 打手报酬是“成本”还是“代收代付”? | ✅ **已确认:支出/成本**(最终提现打款),按**总额法** | 收入总额法/净额法 |
|
||||
| 5 | 寄卖货款的采购成本确认时点 | ⏳ 待定 | 决定存货/成本 |
|
||||
|
||||
Reference in New Issue
Block a user