From c5f219423b8412710b8dc5ccee167ab0c16ab459 Mon Sep 17 00:00:00 2001 From: liuwenxin <1009266660@qq.com> Date: Mon, 19 Oct 2026 13:49:42 +0800 Subject: [PATCH] =?UTF-8?q?docs:=202026-10-19=20=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?=E7=AD=94=E5=A4=8D=E4=B8=8E=E9=9C=80=E6=B1=82=E7=95=99=E6=A1=A3?= =?UTF-8?q?=E2=80=94=E2=80=94T+=20=E6=B8=85=E5=8D=95=20v1.4=E3=80=81?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E8=A1=A8=E3=80=81=E5=82=AC=E5=8A=9E=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E4=B8=8E=20M4=20=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - T+ 对接数据需求清单 v1.4 与业务方答复回执 - 待确认事项排序表两版、待答复催办清单 - 剩余开发计划回填 3.3.1 答复落定状态 - 新增 M4 报表统计实施计划 Co-Authored-By: Claude Code --- ...接数据需求清单_v1.4_2026-10-19.xlsx | Bin 0 -> 18204 bytes .../plans/2026-10-12-剩余开发计划.md | 14 ++ .../plans/2026-10-19-M4-报表统计.md | 156 ++++++++++++++++++ ...¾…澄清问题清单_2026-10-15(1)(2).xlsx | Bin 0 -> 16156 bytes docs/待确认事项排序表_2026-10-16.xlsx | Bin 0 -> 12871 bytes ...…确认事项排序表_2026-10-16_new.xlsx | Bin 0 -> 16715 bytes docs/待答复催办清单_2026-10-19.md | 82 +++++++++ 7 files changed, 252 insertions(+) create mode 100644 docs/T+对接数据需求清单_v1.4_2026-10-19.xlsx create mode 100644 docs/superpowers/plans/2026-10-19-M4-报表统计.md create mode 100644 docs/待澄清问题清单_2026-10-15(1)(2).xlsx create mode 100644 docs/待确认事项排序表_2026-10-16.xlsx create mode 100644 docs/待确认事项排序表_2026-10-16_new.xlsx create mode 100644 docs/待答复催办清单_2026-10-19.md diff --git a/docs/T+对接数据需求清单_v1.4_2026-10-19.xlsx b/docs/T+对接数据需求清单_v1.4_2026-10-19.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f3337d8074f267f3e810d338dc9d7f46ff06c75f GIT binary patch literal 18204 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 A;s5{u literal 0 HcmV?d00001 diff --git a/docs/superpowers/plans/2026-10-12-剩余开发计划.md b/docs/superpowers/plans/2026-10-12-剩余开发计划.md index e5e2d9d..96683ec 100644 --- a/docs/superpowers/plans/2026-10-12-剩余开发计划.md +++ b/docs/superpowers/plans/2026-10-12-剩余开发计划.md @@ -718,6 +718,20 @@ git commit -m "test(system): 参数体系模块用例与测试记录" | 6 | 调整单是否走同一审批链;能否跨月调整已锁定月份 | ④⑦ | 建议走同一审批链;「后续月份扣补」为默认路径,跨月调整需授权留痕 —— 待确认 | | 7 | 待办事项的范围(除审批/同步失败外还含哪些,回款未指定批次是否算待办) | ⑧ | 按 3.2(二) 默认清单起步,业务确认后扩充 | +### 3.3.1 答复回填(2026-10-19) + +> 业务方 24 项答复已到(2026-10-16,回执见《待澄清问题清单_2026-10-15(1)(2).xlsx》H 列),2026-10-19 全部落实并实现;本节为 3.3 各项的落定状态,供后续引用。答复与默认不同处以答复为准;仍未答复项见 `docs/待答复催办清单_2026-10-19.md`。 + +| 3.3# | 事项 | 落定状态 | +| --- | --- | --- | +| 1 | 二次分配标的与余额归属(含与 #15 协助 25% 关系) | **答复仍空白;2026-10-19 已按建议默认实现分摊拆行**——分配标的=绩效金额份额(参与人份额×比例、负责人拿余额、行合计守恒、合计>100% 与负责人自分 400 拦截);协助 25% 维持仅记录不核算;业务答复后如有变更走口径调整 | +| 2 | 二次分配审批开关默认值 | 已答复:**默认开启**,可手动关闭(已落实 V8 参数种子) | +| 3 | 「确认回款」定义 | 已答复:需人工确认动作,可手动关闭(系统已按此预留并实现) | +| 4 | 审批角色权限清单 | 部分答复:先预设角色,名称与职权待客户确认;现按最小授权运行(后勤=提交录入,财务=复核+导出,领导=审核只读),营销后勤暂不可见审批列表 | +| 5 | 风险预警规则 | 已答复:方向确认参数化;首批三条(逾期 90 天/同步失败/超时 3 天)未点名,按默认起步——⑧ 工作台实现 | +| 6 | 调整单是否走同一审批链;能否跨月调整已锁月份 | 已答复:同一审批链;跨月调整需管理员授权并留痕(已实现) | +| 7 | 待办事项范围 | 已答复:待审批 + 同步失败 + 回款未指定批次起步——⑧ 工作台实现 | + ### 3.4 对路线图的影响(本次已修订) 1.1 依赖图、1.3 范围与验收、1.4 里程碑、1.5 依据对照均已并入本批内容;第三章待 3.3 各项澄清后,按第二章同粒度补齐 M3 各增量块的任务级实施计划。 diff --git a/docs/superpowers/plans/2026-10-19-M4-报表统计.md b/docs/superpowers/plans/2026-10-19-M4-报表统计.md new file mode 100644 index 0000000..1a1976e --- /dev/null +++ b/docs/superpowers/plans/2026-10-19-M4-报表统计.md @@ -0,0 +1,156 @@ +# M4 ⑤ 报表统计 · 任务级实施计划 + +> 立项日期 2026-10-19;分支 feat/m3-increments。依据:需规 2.4 /《需求规格说明书》FR-029~FR-032 / 开发计划第五章 1.3 验收行 / 2026-10-15 补充(四)「导出模板围绕财务复核和领导签字设计」。 +> 前置已满足:④ 台账/月结/调整单全部交付(台账即「报表 2.4.1 的数据源」,`performance_ledger.py` 注释锚点)。 +> **纯只读模块,无数据库迁移**。 + +## 〇、代码核实结论(实施时按此避坑) + +| # | 结论 | 影响 | +| --- | --- | --- | +| 1 | `require_roles` 403 文案硬编码「无权访问审批管理」(`api/deps.py:135`) | 给 `require_roles` 增可选 `message` 参数(默认值不变),报表传「无权访问报表统计」 | +| 2 | `PageQuery.page_size` 上限 200(`core/response.py:57`) | 打印视图循环翻页取全量;导出走专用无分页查询 | +| 3 | `settlement_service._confirm_scope` 带 `settlement_id IS NULL`(可入结口径) | 报表取数**不复用**,新增同月全量生效单笔行查询 | +| 4 | `list_adjustments` 无月份筛选、limit 200、含全部状态 | 调整单并入需新写仓储查询(月份 + status=2) | +| 5 | `GET /system/settings` 是 AdminUser,`/public` 才无角色限制 | 打印视图页眉必须走 `getPublicSettings()` | +| 6 | 台账 `payment_days` 可空可负(先款后货);进度登记回款无台账行(#25) | 区间桶含「≤0 天」「无天数」兜底;回款统计注明「不含进度登记回款」 | +| 7 | 二次分摊拆行使同一回款多行(负责人+参与人,business_id 相同) | 回款金额按 receipt_id 去重;个人明细不放「关联回款金额」列 | +| 8 | 经理聚合行 calc_type=2 的 business_id 是锚点、receipt_id=NULL、payment_days=NULL | 业务统计/个人明细/回款统计一律 `calc_type=1 AND is_active=1`,防聚合额污染 | +| 9 | openpyxl `NUMERIC_TYPES` 含 Decimal,原样落数值不转 float | 精度红线导出侧成立;`number_format='#,##0.00'` 控显示 | +| 10 | `test_param_registry.py` 锁 registry 19 项 | 新增参数需四处同改(本计划不新增参数,规避) | +| 11 | `PRODUCT_CATEGORIES` 常量不含 `mixed`,台账行有 `mixed` | 标签映射额外覆盖 mixed,单测防漂移 | +| 12 | `audit_service.audit` 可用于只读导出留痕(独立 commit) | 直接复用;上下文内 bytes 在 commit 前固化 | +| 13 | `test_settlement_helpers.py` 直接 import `settlement_service._month_end` | 抽共享模块时保留薄委托包装 | +| 14 | 前端无任何打印/PDF/xlsx 代码 | 打印从零建:独立顶层路由 + `@media print` | +| 15 | Starlette 响应头 latin-1,中文文件名会 UnicodeEncodeError | 导出文件名服务端 ASCII、中文名前端 `link.download` 赋 | + +## 一、全局口径(写进 report_service docstring) + +1. 数据源 `performance_ledgers` 固定 `is_active=1 AND calc_type=1`;聚合行只在部门汇总作冻结对照单读;月份维度 `settlement_month`。 +2. 金额全程 `Decimal` 出参字符串;比例原样 `rate_text`,禁 float/截断。 +3. 调整单并入:仅 `status=2`,按 `(settlement_month, personnel_id)` 并入,`direction=1` 记 +、`2` 记 −;归属按实时 `manager_id`。 +4. 离职人员不按 `status` 过滤(历史业绩留在原团队);零行经理枚举仅在职经理。 +5. 汇总 = 明细合计(团队/公司基数 == 成员明细绩效合计,测试逐项断言)。 + +### 已定设计决策 + +- 部门口径 = `personnel.manager_id` 实时上溯(无独立部门表,人员模型 docstring 已声明;已入催办清单 R1 向业务确认) +- 导出 = 后端 openpyxl + StreamingResponse(ASCII 文件名);打印 = 前端独立打印视图 + `@media print`,PDF 走浏览器另存为;不引前端 PDF/xlsx 依赖 +- 不做图表(需求无要求,不引 ECharts) +- 区间桶 = 代码常量 + 服务端下发元数据(前端零硬编码);不进参数体系避免迁移;配置缝收在 `get_payment_day_buckets()` 单函数,升级路径:`report.payment_days.buckets` 参数 → V10 迁移种子 → init-dev → registry 测试 19→20 +- 权限 `require_roles(ROLE_ADMIN, ROLE_FINANCE, ROLE_LEADER)` 粗粒度,前后端双层(admin 显式列入) + +## 二、后端任务 + +### T1 常量与元数据(`core/constants.py` 改 + `services/report_meta.py` 新) + +- `MODULE_REPORT = "报表统计"`、`ACTION_EXPORT = "导出"` +- `report_meta.py`(叶子模块,禁 app 内导入防循环依赖):`DayBucket` frozen dataclass + `PAYMENT_DAY_BUCKETS` 8 档(≤0 天(先款后货)/1-30/31-60/61-90/91-180/181-360/361+/无天数)、`CUSTOMER_TYPE_LABELS`、`PRODUCT_CATEGORY_LABELS`(含 mixed)、`REPORT_TEMPLATE_VERSION = "V1.0"`、`REPORT_EXPORT_MAX_ROWS = 20000` + +### T2 仓储 `repositories/report_repository.py`(新) + +| 函数 | 说明 | +| --- | --- | +| `list_personal_detail / count_personal_detail` | 单笔生效行分页(month/personnel/customer_type/product_category/role_code 筛选,id desc) | +| `sum_personal_detail` | 全筛选口径 SUM(分页合计与页内合计分开,禁内存当前页求和) | +| `list_month_receipt_rows` | 同月全量生效单笔行(部门汇总取数,不复用 _confirm_scope) | +| `list_month_manager_aggregates` | 同月 calc_type=2 生效行(冻结对照) | +| `list_month_adjustments` | status=2 + 月份 | +| `list_business_stats / count / sum` | Business×Customer×Personnel 左联 + 三个 scalar_subquery(发货额 SUM(shipments.total_amount)、回款额 SUM(receipts.amount)、绩效 SUM(台账 performance_amount WHERE calc_type=1 AND is_active=1));keyword 双列 OR contains(autoescape=True) | +| `list_payment_group_by_days` | GROUP BY (payment_days, customer_type, product_category) 出 SUM 绩效/应付/COUNT | +| `list_payment_receipt_group_by_days` | 先 DISTINCT receipt_id 再 JOIN receipts 求和(拆行防翻倍) | +| `list_payment_detail / count` | 区间下钻分页(闭区间 between、开区间 >=、none 桶 IS NULL),JOIN receipts 取金额与批次号 | + +### T3 经理分成共享口径(`services/manager_share.py` 新 + `settlement_service.py` 改薄委托) + +- 迁出(复制实现 + 薄委托,行为零变化):`month_end`、`ManagerShareParams`(含 `manager_share_params(session, month)`,锚定月末 resolve_snapshot)、`collect_team_buckets`、`company_base_of` +- 报表侧分成额调用 `formula.manager_team_share(...)`——月结聚合行与报表汇总同源,杜绝口径漂移 +- **协调点**:84 会话已拆 settlement_service(028a94a);本任务在其基础上做,验证 `test_settlement_helpers.py` 全绿 + +### T4 服务与 schemas(`services/report_service.py` + `schemas/report.py` 新) + +1. **个人明细**:`ReportPage[T]` = 标准分页四字段 + `summary`(全筛选合计);行含 ledger_id/business_id/business_no/人员/岗位/客户类型/产品类别/ship_date/receipt_date/payment_days/rate_text/weight_r/payment_weight/performance_amount/payable_amount;**不含回款金额列** +2. **部门汇总**(月份必填):`collect_team_buckets` 分团队 → 团队基数/成员内联明细(personnel_id 聚合 + 台账 id 列表 + 调整 extra/deduct/net);`company` 块 5% 单列(team_base_total/company_base/company_share_amount;各团队 5% 之和 ≠ 全局 5%,UI 注明);零行经理并集枚举(在职 sales_manager JOIN business_roles + 数据中出现的 manager_id);对比 `company_base_ratio` 除零→0;冻结对照 `aggregate_ledger_id + frozen_amount`;出参 `params`(team_pct/company_pct/manager_personal_included/params_as_of) +3. **业务统计**:分页 + summary;回款/绩效为该业务累计值(不随日期筛选变,页面 hint) +4. **回款统计**:SQL 精确值聚合 → Python 按 `PAYMENT_DAY_BUCKETS` 分桶(恒含全桶、空桶 0);正负绩效直接求和不 ABS;出参 buckets/by_customer_type/by_product_category/totals +5. **区间下钻**:`GET /reports/payment-detail`(bucket 必填,分页) +6. **导出编排** `export_report(session, code, q, *, operator, meta)`:先 count 判上限(超限 400 中文提示按月缩小);`audit_service.audit(MODULE_REPORT, ACTION_EXPORT, ...)` 包取数+构建;出参 `(bytes, filename)` 在 commit 语义闭合前固化 + +### T5 Excel 模板(`services/report_export.py` 新,纯函数) + +- 普通 `Workbook`(上限封顶 2 万行内存可承受);版式:公司页眉行(logo `read_logo` try/except 降级纯文本)→ 标题(合并居中)→ 筛选条件行 → 导出时间/人/模板版本 → 表头(加粗底纹边框 + freeze_panes)→ 数据行 → 合计行(service 侧 Decimal SUM quantize HALF_UP,**不写 Excel 公式**)→ 空两行 → 财务复核栏 / 领导签字栏 / 日期栏 +- 精度:金额 Decimal 直接写 + `#,##0.00`;比例 `'0.00"%"'`;`rate_text` 原样文本;日期 `date` + `YYYY-MM-DD` +- 防公式注入:文本以 `= + - @ \t` 开头前置 `'`;CJK 列宽;部门汇总/回款统计多 sheet(各带页眉与签字栏);空数据允许(表头 + 提示行 + 签字栏) + +### T6 API 与路由(`api/v1/reports.py` 新 + `router.py` 改 + `deps.py` 改) + +| 方法 | 路径 | 入参(Query 蛇形) | +| --- | --- | --- | +| GET | `/api/v1/reports/personal-detail` | pageNum/pageSize + settlement_month, personnel_id, customer_type, product_category, role_code | +| GET | `/api/v1/reports/department-summary` | settlement_month(必填), manager_id | +| GET | `/api/v1/reports/business-stats` | pageNum/pageSize + keyword, customer_id, owner_personnel_id, status, date_from, date_to | +| GET | `/api/v1/reports/payment-stats` | settlement_month, date_from, date_to, customer_type, product_category | +| GET | `/api/v1/reports/payment-detail` | pageNum/pageSize + bucket(必填) + 同上 | +| GET | `/api/v1/reports/{code}/export` | code ∈ 四表,参数同对应页 → StreamingResponse xlsx | + +- 全部 `def` 同步路由 + `Annotated[User, Depends(require_roles(ROLE_ADMIN, ROLE_FINANCE, ROLE_LEADER, message="无权访问报表统计"))]` +- Content-Disposition 文件名 ASCII(`personal_detail_20261019.xlsx`),沿用 `system/params.py` 导出先例 + +### T7 后端文档(`backend/README.md` 改) + +报表接口表 + 「报表口径」小节(生效行/调整单并入/回款去重/不含进度登记回款/区间桶常量与升级路径)。 + +## 三、前端任务 + +### T8 API 与常量(`api/reports.ts` 新 + `utils/constants.ts` 改) + +类型逐字段对齐(金额 string);`exportReport(code, params)` 裸 axios `responseType:'blob'`;MODULE_OPTIONS 与后端 `core/constants.py` 全量对齐 + +### T9 四个页面(`views/reports/{personal-detail,department-summary,business-stats,payment-stats}/index.vue` 新) + +统一骨架:`filters(reactive)` + `usePagedList`(非分页表 ref+手动 load)+ `el-table stripe` + `AppPagination` + 工具条「导出 Excel」「打印」+ `handledError`;日期区间 `el-date-picker value-format="YYYY-MM-DD"`(必写);下拉复用 `useDropdownOptions` + +| 页面 | 路由 order | 关键列与下钻 | +| --- | --- | --- | +| 个人绩效明细表 | `/reports/personal-detail` 19 | 需规 10 列 + 页脚全筛选合计(注明非当前页);expand 懒加载 `getLedger(ledger_id)` 快照下钻 | +| 部门绩效汇总表 | `/reports/department-summary` 20 | 团队表 + 全公司 5% 卡片 + 参数取值提示;展开成员 → 跨页下钻个人明细(router.push query)→ 台账下钻复用 `listLedger` | +| 业务统计表 | `/reports/business-stats` 21 | 发货额/回款额/绩效三列;expand 两小表(复用 `listReceipts`/`listLedger`);hint「累计值」 | +| 回款统计表 | `/reports/payment-stats` 22 | buckets 元数据渲染(空桶 0)+ 桶展开下钻 `payment-detail` + 客户类型/产品类别对比小表 | + +路由 meta:`{ title, group: '报表统计', order: 19..22, allowedRoles: [ROLE_ADMIN, 'finance', 'leader'] }`(admin 显式列入) + +### T10 打印视图(`views/reports/print/index.vue` 新 + `router/index.ts` 改) + +- 顶层路由 `/reports/print/:code`(不挂 BasicLayout),`menu:false` + allowedRoles 同上 +- 循环翻页取全量(pageSize 200、上限 2000 截断提示);页眉 `getPublicSettings()`(非管理员拿不到 `/system/settings`) +- `window.print()`(按钮区 `@media print { display:none }`);`@page A4 landscape`;`thead { display: table-header-group }` 每页带表头;打印态白底黑字沿用 `--ys-*` + +### T11 前端文档(`frontend/README.md` 改) + +报表页与打印视图小节 + 权限矩阵 + +## 四、测试(模块整体完成时统一编写) + +### T12 后端(`tests/unit/test_report_helpers.py` + `tests/integration/test_reports.py` 新) + +- 单元:分桶边界(0/1/30/31/60/61/180/181/360/361/负值/NULL);标签键集合 ⊇ CUSTOMER_TYPES ∪ PRODUCT_CATEGORIES ∪ {"mixed"};Excel 结构断言(load_workbook 读回:页眉/合计/签字栏/number_format/注入前缀/空数据);占比除零→0 +- 集成(factories 造数):① 个人明细对拍 `/calc/ledger`、summary==全量和;② 部门汇总成员合计==团队基数==公司基数、`aggregate_amount==manager_team_share` 预期、生成月结后 computed==frozen;③ 无团队成员经理 0 行、离职成员计入原团队;④ 调整单生效行并入(status≠2 不计);⑤ 回款统计空桶恒在、负绩效计入、**分摊拆行金额只计一次**;⑥ 业务统计排除 calc_type=2;⑦ 导出 200/400/审计留痕(成功与失败);⑧ 普通 user 403(文案「无权访问报表统计」) + +### T13 e2e(`frontend/e2e/report_flow.py` 新) + +菜单可见 → 四页筛选与数字 → `page.expect_download()` 断言导出 → 打印视图注入 `window.print` 桩断言 → console 无错;造数用 API + 登录 token(远未来月份隔离,参照 calc_settlement_flow.py) + +### T14 收尾 + +回归(pytest 全量 + ruff + type-check + build + e2e report_flow 与复跑两条既有脚本);三 README 更新;提交拆分 `feat(report): 报表统计后端取数与导出` → `feat(report): 报表统计前端四页与打印视图` → `test(report): 报表模块用例与测试记录` + +## 五、开放项(不阻塞,随催办确认) + +| 事项 | 默认 | +| --- | --- | +| 部门口径(R1) | manager_id 实时上溯 | +| 区间档位(R2) | 8 档代码常量 | +| 签字栏要素(R3) | 页眉/标题/筛选/时间人/版本/复核/签字/日期 | +| 导出上限 | 20000 行超限 400 | +| 打印上限 | 2000 行截断提示 | +| Excel logo | 有则嵌、无则纯文本 | diff --git a/docs/待澄清问题清单_2026-10-15(1)(2).xlsx b/docs/待澄清问题清单_2026-10-15(1)(2).xlsx new file mode 100644 index 0000000000000000000000000000000000000000..dd2e2c856782fdb6bef332731f3a8230ea7ee0e4 GIT binary patch literal 16156 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

UF5C+eM=c`Gu587p^wEO>TJTf3=? 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%0AhgAX{Lo92mlZR4gjD6pg?s*?d_aR?VR;h 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 literal 0 HcmV?d00001 diff --git a/docs/待答复催办清单_2026-10-19.md b/docs/待答复催办清单_2026-10-19.md new file mode 100644 index 0000000..0a3540f --- /dev/null +++ b/docs/待答复催办清单_2026-10-19.md @@ -0,0 +1,82 @@ +# 待答复事项催办清单(2026-10-19) + +> **用途**:对外跟催材料,分三块可直接拆分发送——一、业务方;二、IT/T+ 侧;三、报表口径补充确认(本轮新增)。 +> **基线**:《待澄清问题清单_2026-10-15(1)(2).xlsx》(业务 24 项,2026-10-16 已回 15 项)、《T+对接数据需求清单》v1.3「待IT确认事项」18 项 + v1.4(2026-10-19 勘误)、《问题与解决方案对照表_v2》(28 项已裁决口径)。 +> **原则**:已答复项不重复询问;未答复项按清单内「建议默认」执行中,答复后以答复为准并回填文档。 + +## 一、业务方(建议回复期限:____) + +### A. 仍未答复 —— 阻塞对应模块开工(4 项) + +| # | 问题(原文口径) | 当前执行默认 | 阻塞 | +| --- | --- | --- | --- | +| 1 | 二次分配的分配标的是什么——绩效工资金额、折算毛利润额,还是销售额(业绩额)? | 未答复前只做方案录入,**不实现分摊计算**(已按此交付) | ④ 分摊计算 | +| 2 | 分配比例合计不足 100% 时,剩余部分归属谁? | 余额归合同负责营销人员(仅展示不落库) | ④ 分摊计算 | +| 3 | 二次分配与已作废的「协助 25% 分成」是什么关系? | 独立新机制;协助仍仅记录不核算 | ④ 分摊 | +| 20 | 含税口径:销售/成本/毛利润/运费各项是否含税?价税合计与折扣折让如何处理? | 按不含税口径实现中 | ④ 核算口径终验、⑥ 同步建列(是否建税率/税额列) | + +> 说明:#1–#3 未答复期间,二次分配方案可正常录入与审批,但**分摊金额不会出现在绩效中**;#20 影响历史算出的绩效是否需要按含税口径重算,越早答复返工面越小。 + +### B. 已有答复但需补具体值 / 勾选(4 项) + +| # | 事项 | 需补充 | +| --- | --- | --- | +| 12 | 经理个人户业绩是否计入其 12.5% 团队基数 | 答复为「做参数可调」,**请给出初始值**:计入 / 不计入(系统已实现为开关参数,当前默认不计入) | +| 14 | 「第 1 天 10‰」实现口径 | 请勾选:**A 仅首日覆盖**(推荐,保「360 天 = 6‰」锚点)或 B 整体平移(破坏锚点)。系统当前按 A 实现(首日 10‰、其余按公式 10 − 天数 × 4/360) | +| 4 | 二次分配方案修改窗口与权限 | 答复「暂定允许修改,走调整单」——请定:首次月结前可改(留痕)?月结后只读、仅走调整单?谁有权改(管理员 / 营销后勤)? | +| 6 | 营销后勤/财务/领导三类角色的账号归属、可见菜单、可操作点 | 答复「先预设角色,需与客户确认」——请给权限清单(三类角色各能看什么、能操作什么)。系统已按最小授权运行:后勤=提交录入,财务=复核+导出,领导=审核只读,营销后勤暂不可见审批列表 | + +### C. 请确认两处勘误(已按勘误实施,需业务回执存档)(2 项) + +| 项 | 原表述 | 现行勘误(v1.4) | +| --- | --- | --- | +| 人员识别 | 「负责营销人员以姓名为唯一识别」 | 改为「以人员编码(工号)为唯一识别、姓名辅助核对」——原表述与「编码为业绩归属唯一锚点(防重名错钱)」矛盾,疑笔误,请确认 | +| 回款↔发货批次 | 「由 T+ 收款分配关系指定,人工辅助」 | 改为「**系统人工指定**(对照表 #18 定稿),T+ 收款分配关系仅作辅助」——主次相反疑漏改,请确认 | + +### 已按默认执行、无需回复的项(供核阅) + +#7 月结审批链默认开启、#8 人工确认回款可手动关闭、#9 调整单同链且跨月需授权、#10 风险预警参数化、#11 待办范围(待审批+同步失败+回款未指定批次)、#13 支付环节 5 默认值、#15 一期仅 FULL 模式、#17 参数查看放开/修改限管理员、#18 企业户 2‰ 回溯、#21 退货当期冲减已结算走调整单、#22 预收/保证金/代收款暂不计入、#23 按到账金额、#24 负绩效照算不归零。 + +## 二、IT / T+ 侧(建议回复期限:____) + +> 2026-10-15 回稿收到后,v1.3「待IT确认事项」18 项**未逐项答复**(回稿仅做了必要性升级与第七节补充),机制性内容(同步频率/幂等/格式要求)未包含,「同步不覆盖字段」表被引用但未附。现有 v1.4 清单中「系统侧目标表.字段」列**全表留空待回填**。 + +### A. 高优先(9 项,阻塞核算口径与同步程序开工) + +| # | 事项 | 为什么高 | +| --- | --- | --- | +| 1 | **成本额取数口径**:成本类型/毛利计算方式/更新时间/精度 | 毛利润 = 销售额 − 成本额,是绩效金额全部源头;缺此则同步无法自动跑,只能人工录入 | +| 2 | 发货日期口径:出库日 / 签收日 / 开票日 | 回款天数基准日(发货日首日计第 1 天),直接决定计提比例 | +| 3 | 到账日期口径:收款日 / 银行到账日 / 核销日 | 计提参数版本匹配日,直接决定适用哪一版比例 | +| 4 | 幂等唯一键规则:作废重开是否换号 | 重复同步不重复入库的前提 | +| 5 | 三单关联键:订单 / 发货 / 回款如何互相关联 | 一笔业务可分批发货;回款↔批次系统内人工指定,但订单↔发货关联仍必须由 T+ 提供 | +| 6 | **人员唯一编码(工号)** + 业务员↔营销经理隶属关系 | 业绩归属唯一锚点(重名即错钱);经理 12.5% 团队聚合依隶属关系展开 | +| 7 | 对接方式与安全:REST / 数据库视图 / 中间表 / 文件交换 | 未定则同步程序无法开工(一期人工录入可闭环) | +| 8 | 负数 / 红字 / 退货 / 冲销处理规则与原单关联 | 决定第七节补充字段如何建列;如不提供则只能靠人工补录 | +| 16 | 回款确认 / 核销状态字段与枚举 | 月度结算按「确认回款」生成,需 T+ 核销/确认类字段作人工确认依据 | + +### B. 回稿三缺口(请补) + +1. v1.3 第七节曾漏「人员唯一编码(工号)」——v1.4 数据清单第一节已补★项并注明「待IT确认 #19:T+ 档案编码是否即工号,若为自动内部编码请指明工号字段」; +2. 「客户档案是否同步」(待IT确认 #10)未点名答复——v1.4 第六节已列客户档案 5 项,请确认可提供; +3. 「系统侧目标表.字段(T+ 确认映射)」列全表留空——请回填,这是同步程序的字段契约。 + +### C. 中低优先(9 项,模块实现期内答复即可) + +存量数据起始日期与增量口径(影响能出多早的报表)、客户匹配与唯一键、收款方式完整枚举清单、产品「数量」语义(库存量/在途/累计销量)、发货单价口径(订单价/发货时价)、特殊业务标记字段、同步窗口时间、市场拓展计划数据、待IT确认 #18(口径裁决 5 项已转业务方,见第一部分)。 + +## 三、报表口径补充确认(2026-10-19 新增,随本轮开发一并排) + +> 报表统计模块(需规 2.4 / FR-029~FR-032)开工在即,以下三项请确认;未答复按「建议默认」实现,后续可调。 + +| # | 事项 | 建议默认(将按此实现) | +| --- | --- | --- | +| R1 | 部门绩效汇总表的「部门」口径 | 部门 = 经理团队(经理 + 其直属业务员),按人员档案的隶属关系展开;离职人员历史业绩留在原团队;经理的 5% 全公司部分单独一列 | +| R2 | 回款统计的「回款天数区间」档位 | ≤0 天(先款后货)|1-30|31-60|61-90|91-180|181-360|361 以上|无回款天数,共 8 档;未命中区间显示 0 | +| R3 | 导出/打印模板要素 | 公司信息页眉(名称+logo)、报表标题、筛选条件、导出时间与导出人、模板版本号、财务复核栏、领导签字栏、日期栏 | + +另:报表查看权限(FR-029 参与者含「营销后勤(授权范围内)」)——请随第一部分 B-6 权限清单一并明确营销后勤是否需要查看报表、可见哪些列。 + +--- + +**发送建议**:第一部分发业务方(含 C 两项勘误确认);第二部分发 IT/T+(v1.4 附表一并);第三部分随开发进度与业务方顺带确认。