生鲜直播 · 毛利核算(v2)
> 一次核算 = 取数 → 匹配 → 测算 → 出表 → 给判定。
> 主干读这一份就够;细节按需查 references/。
零、三条铁律(违反即返工)
| # | 铁律 | 落地方式 |
|---|---|---|
| 1 | 只用「最新报价日」的价格判定 | 每个货源取其 报价日期 最大的一条,不取均值、不取历史最低 |
| 2 | 判定用 16 列标准表 | 列序固定、活公式、最后一列给结论,不得增减列 |
| 3 | 价格/毛利/毛利率全部 1 位小数 | 尾数取舍就低不就高,红线不放宽 |
铁律 1 的三个推论
- 用户没说供应商/仓库 → 全部货源逐仓列出、逐仓给毛利率,再给总判定。
- 用户明确说了供应商/仓库/报价 → 只算那一个,不铺开。
- 标注报价日期 + 距今月数;超 3 个月必须写「需重新询价」,并给成本上限反推让人拿到新价一秒判定。
一、计算口径(唯一版本)
佣金 = 售价 × 佣金率
平台扣点 = 售价 × 3% ← 必须扣,漏扣会得出偏乐观结论
毛利 = 售价 − 佣金 − 成本 − 运费险(默认0) − 平台扣点
毛利率 = 毛利 ÷ 售价
| 毛利率 | 判定 | 色值 |
|---|---|---|
| ≥ 10% | 可合作 |
C6EFCE 绿 |
| 5% – 10% | 薄利(5-10%) |
FFEB9C 黄 |
| < 5% | 不可合作 |
FFC7CE 红 |
红线 5% 是业务方定的,不可放宽。成本缺失时判定写 待补成本。
二、数据源(先确认坐标,别猜)
不同团队的表结构不同,首次使用必须向用户确认三张表的位置,之后固化到本地配置:
| 源 | 定位 | 取什么 |
|---|---|---|
| 在售表 | 电子表格,按品类分子表 | 售价、佣金率、规格档、发货地、快递方式 |
| 成本表 | 多维表格(Base),一个表一档报价 | 含税成本价、规格档、仓库、产地、报价日期 |
| 自营品成本 | 内部结算价明细(xlsx 或截图) | 快递分档的内部结算价 |
自营/联营品在成本表里价格常为空,需另走内部结算价——先查明细表,再判"无法核算"。
字段语义与取数坑:references/02-数据源.md
三、五步执行流程
Step 1 · 取数
# 成本表(单页上限 2000,需分页 0/2000/4000/6000)
<你的表格CLI> base record-list --base-token "$BASE_TOKEN" \
--table-id "$TABLE_ID" --limit 2000 --offset 0 --format ndjson
在售表由 scripts/calc_margin.py 自动拉取并缓存到 .cache/。
⚠️ 多维表格 CLI 的 stdout 往往只有 manifest,真实记录在 manifest 的 record_file 指向的 <cwd>/<table>*.ndjson。别把 stdout 当数据。
Step 2 · 匹配(在售表名 → 成本表名)
python scripts/calc_margin.py --list # 在售表有哪些品
python scripts/calc_margin.py --product "人参果" # 出分档+候选打分
先选名、后锁规格。四档评级,只有前两档可下结论:
| 级别 | 条件 | 可否下结论 |
|---|---|---|
| 精确同名 | 完全一致 | ✅ |
| 自动匹配 | 品类核心词相等 + 无产地冲突 + 分 ≥4 | ✅ |
| 低置信 | 产地冲突 / 鲜果↔加工品 / 分 <4 | 🚫 拒绝 |
| 无匹配 | 成本表无此品 | 🚫 拒绝 |
匹配不确定时用 --cost-name "成本表实际名" 手动锁定。
宁缺毋滥:绝不用相似品替代。
Step 3 · 测算(口径 B 唯一决策用)
python scripts/calc_margin.py --product "人参果" --slot 1 --cost-name "云南人参果"
输出须含:分档对照 / 命中品名 + Top5 打分 / 逐仓最新报价 / 毛利率 / 判定。
口径 A(历史区间)只看波动,不参与判定。
Step 4 · 出表(一条命令出两个文件)
python scripts/build_margin_sheet.py \
--in data.json --out 成本核算机制表_<品>_<日期>.xlsx --html 结论.html
data.json 结构见 references/04-交付模板.md,可参考 examples/data.example.json。
Step 5 · 给判定(决策树)
指定了供应商/仓库?
├─ 是 → 只算该货源最新报价 → 直接判
└─ 否 → 逐仓算完,看两端:
├─ 最优仓 <5% → 不可合作(换仓也救不回来)
├─ 最优 ≥5% 且 最差 <5% → 取成本定生死
│ ★必须点名"哪个仓能做、哪个不能"
└─ 全部 ≥5% → 可合作(附最优仓建议)
成本表查不到价时不等于不给结论——见下节。
四、成本缺失的标准动作(做过就不许偷懒)
- 说清"查不到"而非"没查":给记录条数、日期跨度、空字段名、仓库归属。
- 给成本上限反推:
保本上限 = 售价 × (1 − 佣金率 − 3%)
保5%上限 = 售价 × (1 − 佣金率 − 3% − 5%)
差额 = 当前成本 − 保5%上限,正数即不达标。
⚠️ 旧式售价×(1−佣金率)×0.95漏扣 3% 平台扣点,已废弃,不要再用。 - 指出补数路径:内部结算价常只在商务截图/线下报价 → 直接让用户找商务要,别反复翻表假装努力。
五、交付形态(默认动作,不用提醒)
任何测算/填报任务,同时产出:
1. xlsx:16 列核算表(含「口径与说明」Sheet)
2. HTML 结论视图:① 一句话结论 ② KPI 卡 ③ 档位来源核对表 ④ 风险与数据质量 ⑤ 数据源脚注
16 列字段定义、配色、列宽、HTML 版式:references/04-交付模板.md
六、绝对禁止
- ❌ 用均值/历史最低价下结论
- ❌ 在 16 列表里自行加列、改列序
- ❌ 用相似品替代无匹配的产品
- ❌ 漏扣 3% 平台扣点
- ❌ 只用「仅斤数」降级锁定就下结论(果径档混入会把成本区间拉宽到失真)
- ❌ 报"成本表无此品"却不给成本上限反推
- ❌ 往 xlsx 插图用会污染公式的接口;统一用 openpyxl 浮动图
七、references 索引(按需加载,别一次全读)
| 文件 | 什么时候读 |
|---|---|
references/01-口径与判定.md |
口径细节、双口径 A/B、分档边界、精度规则 |
references/02-数据源.md |
字段语义、两段式取数输出、快照与跨设备部署 |
references/03-匹配规则.md |
名称打分算法、规格锁定、果径换算、降级陷阱 |
references/04-交付模板.md |
16 列定义、data.json 结构、HTML 版式、提报表字段 |
references/05-踩坑实录.md |
遇到异常先查这里,历史坑按品类归档 |
references/06-派生任务.md |
提报表填报、选品登记、图片补充通道 |