9.1 KiB
9.1 KiB
SKILL.md - vala-order-amortization-stat 订单均摊结算统计技能
技能描述
用于统计指定账期内的订单均摊收入、退费冲销,按天计算均摊金额,支持部分退费场景的退后订单金额和周期自动计算。
触发场景
当用户提到以下关键词组合时激活本技能:
- 订单均摊、按天均摊、收入均摊
- 账期结算、月度结算、季度结算
- 退费冲销、部分退款均摊
前置依赖
- 已连接线上PostgreSQL数据库 vala_bi 库
- 依赖表:
- bi_vala_order:订单主表
- bi_refund_order:退费订单表
- bi_vala_seasonal_ticket:季卡周期表
- bi_vala_app_account:用户账户表(用于关联,不限制status)
- 表关联规则:
- bi_vala_order.out_trade_no ↔ bi_refund_order.out_trade_no 关联
- bi_vala_order.trade_no ↔ bi_refund_order.trade_no 关联
- 两种关联方式 UNION ALL 后聚合去重,退费金额 SUM 累加 [李承龙确认 2026-06-18]
执行方式
本技能已预置为可直接执行的脚本。
快速执行
python3 ~/.openclaw/workspace/skills/vala-order-amortization-stat/run.py --start {账期起始日} --end {账期结束日}
示例
# 2026年3月账期
python3 ~/.openclaw/workspace/skills/vala-order-amortization-stat/run.py --start 2026-03-01 --end 2026-03-31
# 也支持位置参数
python3 ~/.openclaw/workspace/skills/vala-order-amortization-stat/run.py 2026-03-01 2026-03-31
输出
- Excel报表保存到:
output/订单均摊结算报表_{start}_{end}.xlsx(三个Sheet:汇总表、订单明细、本月预收账款) - 控制台输出JSON格式的汇总结果
目录结构
vala-order-amortization-stat/
├── SKILL.md # 技能说明(本文件)
├── run.py # 执行脚本(传入账期参数即可)
└── sql/
├── _common.sql # 公共CTE链(detail/summary 共用),含 order_base → order_with_cycle → order_with_cycle_fixed → order_classified → order_with_days
├── detail.sql # 订单明细输出(SELECT from order_with_days)
├── summary.sql # 汇总输出(聚合 SELECT from order_with_days)
└── prepaid.sql # 月度预收账款(独立查询)
操作流程
步骤1:确认核心参数
执行前向用户确认:
- 账期起始日期(格式:YYYY-MM-DD)
- 账期结束日期(格式:YYYY-MM-DD)
步骤2:数据过滤规则
- 订单范围:
- 2025-06-01 至 账期结束日 内创建的所有订单
- bi_vala_order.order_status IN (3,4)(已完成、已退款订单)
- 订单实际支付金额≥10元:bi_vala_order.pay_amount_int ≥ 1000(单位:分)
- 关联 bi_vala_app_account 表(不限制 status,不剔除测试账号)
- 退费范围:
- 退费记录范围:截至账期结束日前的所有退费成功记录,用于标记订单退费状态
- 退费金额 SUM 累加:同时按
out_trade_no和trade_no关联bi_refund_order,对同一订单的多笔status=3退费记录做 SUM(refund_amount) 累加 [李承龙确认 2026-06-18] - 退费判定:
order_status=4直接视为退费;order_status=3需退费表有status=3记录才视为退费 - 账期内退费判定:bi_refund_order.updated_at 在账期起止范围内,status = 3
- 账期前退费订单处理规则:
- 全额退费(is_full_refund = 1,累计退费金额 ≥ 原订单金额):本账期完全不统计该订单
- 部分退费(is_full_refund = 0):按退后订单金额/退后周期在本账期内正常均摊
- 试用期内退费处理规则:
- 退费日期 < 转正日(下单日+7天)的退费订单,从未产生均摊收入,不触发冲销
步骤3:核心计算逻辑
3.1 周期计算
- 原始均摊周期 = bi_vala_seasonal_ticket 中同一 out_trade_no 下所有不同 id 数量 × 90 天
- 退后均摊周期 = bi_vala_seasonal_ticket 中同一 out_trade_no 下 status != -1 的不同 id 数量 × 90 天
- 转正日期 = 订单下单日 + 7 天(下单日取 bi_vala_order.pay_success_date 的日期部分)
- 示例:4月22日下单,4月29日00:00:00为转正日
3.1.1 退费在账期后 + 季卡已删的fallback(2026-05-15 修复)
当退费发生在账期结束后,季卡状态已经被置为 status=-1,导致 active_cycle_days=0,但账期内该订单仍处于正常均摊状态,不应被排除。
- 判定条件:
active_cycle_days=0 AND original_cycle_days>0 AND has_refund=0(退费记录被DATE(updated_at) <= period_end过滤掉) - 处理:
total_cycle_days回退到original_cycle_days,后续计算(均摊结束日、日均摊金额、日税费)均在order_with_cycle_fixedCTE 中用 effectivetotal_cycle_days重算 - 避免此问题的正确做法:不应依赖季卡状态判断订单是否在本账期内正常,退费过滤的时效性需要与订单状态独立判断
3.2 税率与税费计算(价外税)
- 税率判定依据:按下单时间(pay_success_date)判定,与退费发生时间无关
- 下单时间 < 2026-05-01 → 1%
- 下单时间 ≥ 2026-05-01 → 6%
- 示例:4月下单的订单即使5月发生退费,仍按1%税率计算退后金额和税费
- 计税时机:订单在下单日即计税,不等待转正日(下单日+7天)
- 计税方式:价外税,订单金额为含税价
- 税后金额(元)= (pay_amount_int / 100) / (1 + tax_rate)
- 税费金额(元)= tax_amount = 税后金额 × tax_rate
3.3 均摊规则
- 所有均摊计算均基于税后金额进行
- 日均摊金额(税后)= 税后金额 / 总均摊周期
- 🔹 周期最后一天补差规则:订单均摊周期的最后一天,均摊金额 = 税后总金额 - 前(N-1)天累计已均摊金额,避免浮点尾差
3.4 退费场景分类(6类)
| 场景 | 描述 | 处理方式 |
|---|---|---|
| A | 账期内下单 + 部分退费 | 按退后金额从转正日均摊(period_amort_days) |
| B | 历史下单 + 账期内部分退费 | 冲销历史均摊 + 按退后金额重新均摊(refunded_amort_days_to_period_end) |
| C | 账期前部分退费 | 按退后金额正常均摊(period_amort_days),无冲销 |
| D | 账期内下单 + 全额退费 | 不产生均摊,不触发冲销 |
| E | 历史下单 + 账期内全额退费 | 冲销全部历史均摊,无退后均摊 |
| F | 账期前全额退费 | 本账期完全排除 |
输出格式
- Excel报表存放于
output/目录,命名格式:订单均摊结算报表_{start}_{end}.xlsx - 报表包含以下Sheet:
汇总表(Sheet1)
| 列 | 说明 |
|---|---|
| 订单数 | 账期内下单的订单总数 |
| 正式订单数 | 账期内下单且已过7天试用期的订单数 |
| 试用订单数 | 账期内下单但仍处于试用期的订单数 |
| 冲销历史累计摊销金额 | 场景B/E冲销的历史均摊金额总和(负数) |
| 退后订单历史累计摊销金额 | 仅计算账期内发生退费的订单的历史有效摊销金额总和 |
| 冲销原税款 | 场景B/E冲销的税费总和(负数) |
| 冲销未确认收入 | 场景B/E冲销的未确认收入总和(负数) |
| 当期摊销金额 | 本账期内所有订单产生的均摊收入总和(核心指标) |
| 账期税额 | 账期内下单的订单税费总和(下单即计税,不等待转正) |
| 部分退退后税费 | 三类部分退费订单(试用期内/历史下单账期内/账期内下单)的当前税额总和 |
| 未确认收入 | 截至账期最后一天尚未均摊的税后金额总和 |
订单明细(Sheet2)
每笔订单一行,包含:订单号、下单日期、退费日期、订单分类、原订单金额、退款金额、退后金额、税率、原订单税额、当前税后金额、当前税额、部分退退后税费、原始均摊周期、退后均摊周期、历史累计均摊金额、冲销历史累计摊销金额、退后订单历史累计摊销金额、冲销原税款、冲销未确认收入、当期摊销金额、账期税额、未确认收入、剩余周期
部分退退后税费:仅对三类部分退费订单有值(试用期内部分退/历史下单账期内部分退/账期内下单部分退),值为退后订单的当前税额;其余订单为0
本月预收账款(Sheet3)
按"上月订单转正"/"本月订单转正"/"本月订单未转正"三类统计新增和退费含税金额。
- 文字回复核心指标:
📊 账期{start}至{end}均摊结算结果: 总订单数:XXX单 | 正式订单数:XXX单 | 试用订单数:XXX单 当期摊销金额(税后净收入):XXX元 | 部分退退后税费:XXX元 账期税额:XXX元 | 冲销历史累计摊销金额:XXX元 未确认收入:XXX元
注意事项
- 所有金额保留2位小数,百分比保留1位小数
- 部分退费场景:需确保 bi_vala_seasonal_ticket 中对应退费部分的 status 已更新为 -1
- 税后金额计算使用价外税公式:含税价 / (1 + 税率)
- SQL 模板统一使用
{period_start}和{period_end}占位符,由 run.py 替换 - 公共 CTE 链位于
sql/_common.sql,detail/summary 共享,修改业务逻辑只需改一处