- 派生器/口径:F_BEP_VC_RATE 新增;卡面/公式行文案改「月固定成本 ÷ 边际贡献率」 - 保本额 = 月固定成本 ÷ (1 − 变动成本率);实测渠补率(F_BEP_REBATE)降为 e1 专用 chip - 报告卡口径说明文字同步(固定成本=固定费用合计) 任务: finance-20261003-cvp-fix-and-bohai-coverage-fullstack ⑤
This commit is contained in:
committed by
Hermes CI Fix
parent
4fe956fcf9
commit
587d5b3983
@@ -6,11 +6,14 @@
|
||||
F_BEP_GAP 保本缺口(%) = (保本销售额-月均销售) ÷ 保本销售额 × 100 (反向: <=0绿 <=15黄 >15红)
|
||||
F_BEP_REVENUE_CASH 现金保本销售额(万元) = (月均固定成本-月均折旧) ÷ 边际贡献率 (现金口径,中性无阈值)
|
||||
F_BEP_COVER_CASH 现金保本覆盖率(%) = 月均销售 ÷ 现金保本销售额 × 100 (正向: >=100绿 >=85黄 <85红)
|
||||
F_BEP_REBATE 变动/渠补率(%) = 见下方「实体口径注册表」 (YTD累计; 卡面单一事实源,无阈值)
|
||||
F_BEP_VC_RATE 变动成本率(%) = 见下方「实体口径注册表」 (YTD累计; 保本公式分母,无阈值)
|
||||
F_BEP_REBATE 实测渠补率(%) = e1 专用展示 chip(Σ571103÷Σ5001,YTD; e2 无渠补科目 ⇒ NULL)
|
||||
|
||||
实体口径注册表(2026-10-03 新增,任务 finance-20261003-cvp-fix-and-bohai-coverage-fullstack):
|
||||
· entity 1 陕西酣客:变动成本率 = Σ571103借方 ÷ Σ5001贷方(实测渠补率);固定成本 = 5602% 净额;
|
||||
折旧剔除 = 560213(管理费用-折旧叶子)。
|
||||
· entity 1 陕西酣客:变动成本率 = Σ(5401销货成本 + 5403税金及附加 + 571103渠补 − 530103厂补) ÷ Σ5001贷方
|
||||
〔⑤口径统一 2026-10-03,任总 18:00「统一」;勾稽:808.80 − 672.65 − 224.16 = −88.01 ≈ −88.00 营业利润〕;
|
||||
固定成本 = 5601% + 5602% + 5603% 净额;折旧剔除 = 560213(管理费用-折旧叶子)。
|
||||
实测渠补率 F_BEP_REBATE 保留(仍是渠补单一事实源),但**不再充当变动成本率**。
|
||||
· entity 2 博海:**无渠补科目(571103)**,变动成本 = Σ6401借(主营业务成本),
|
||||
变动成本率 = Σ6401借 ÷ Σ6001贷;固定成本 = (6601 销售费用 + 6602 管理费用 + 6603 财务费用) 净额;
|
||||
折旧剔除 = 1602 累计折旧「当期贷方发生额」(博海科目表只到 4 位一级,无费用类折旧叶子;
|
||||
@@ -21,11 +24,11 @@
|
||||
|
||||
口径(与财务Bot报告一致):
|
||||
- 销售收入: entity1 = subject_code='5001'(主营业务收入) 贷方合计;entity2 = '6001' 贷方合计。当年1月至目标月 YTD 月均
|
||||
- 固定成本: entity1 = subject_code LIKE '5602%'(管理费用,含560213折旧) 借−贷净额合计(carry_forward=0),YTD 月均
|
||||
- 固定成本: entity1 = subject_code LIKE '5601%'/'5602%'/'5603%'(销售/管理/财务费用,含560213折旧) 借−贷净额合计(carry_forward=0),YTD 月均〔⑤扩容〕
|
||||
entity2 = 6601/6602/6603 借−贷净额合计(同上,但另需剔除结转腿)
|
||||
- 折旧: entity1 = '560213' 借−贷净额;entity2 = '1602' 贷方发生额(现金口径剔除项)
|
||||
- 变动成本率: **实测累计口径**(2026-10-02 财务裁定,任总 11:43 CST 放行「改,这样数据更加真实」)
|
||||
酣客 渠补率(实测) = Σ(571103 借方) ÷ Σ(5001 贷方) × 100,期间 = 年初至当期(YTD),保留 2 位小数。
|
||||
- 变动成本率: **完整实测口径**(⑤口径统一 2026-10-03,任总 18:00「统一」;勾稽件 _reports/陕西酣客_边际贡献式损益表_20261003.md)
|
||||
酣客 = Σ(5401销货成本 + 5403税金及附加 + 571103渠补 − 530103厂补) ÷ Σ(5001 贷方) × 100,YTD,保留 2 位小数。
|
||||
`POLICY_REBATE_RATE_PCT = 84.61` 政策常量**仅作对照展示**(写进返回值 rebate_policy_pct / remark),
|
||||
**不参与任何计算**;`--rebate-rate` 显式传值时视为人工诊断覆盖(正常调用不再使用)。
|
||||
- 边际贡献率 = 100 − 变动成本率
|
||||
@@ -85,13 +88,17 @@ TARGET_KPIS = [
|
||||
("F_BEP_GAP", "保本缺口"),
|
||||
("F_BEP_REVENUE_CASH", "现金口径保本销售额"),
|
||||
("F_BEP_COVER_CASH", "现金口径保本覆盖率"),
|
||||
("F_BEP_VC_RATE", "变动成本率"),
|
||||
("F_BEP_REBATE", "实测渠补率"),
|
||||
]
|
||||
|
||||
# 实测渠补率 KPI 编码(卡面单一事实源;无阈值,不参与预警级别判定)
|
||||
# 变动成本率 KPI(⑤ 口径统一 2026-10-03:保本公式分子口径 = 销货成本+税金及附加+渠补−厂补)
|
||||
VC_RATE_KPI = "F_BEP_VC_RATE"
|
||||
|
||||
# 实测渠补率 KPI 编码(卡面单一事实源;无阈值,不参与预警级别判定;⑤ 后**不再充当变动成本率**)
|
||||
REBATE_KPI = "F_BEP_REBATE"
|
||||
|
||||
# 保本口径 KPI(缺 F_BEP_REBATE 定义时不阻断派生主流程,仅跳过渠补率落库并告警)
|
||||
# 保本口径 KPI(缺 F_BEP_REBATE 定义时不阻断派生主流程,见 run_derive 告警分支)
|
||||
CORE_KPI_CODES = [c for c, _ in TARGET_KPIS if c != REBATE_KPI]
|
||||
|
||||
# 现金口径 KPI 编码(计算路径独立于账面,remark 文案用现金口径)
|
||||
@@ -222,6 +229,42 @@ def _subject_clause(kind: str, code: str):
|
||||
raise ValueError(f"未知科目过滤类型: {kind}")
|
||||
|
||||
|
||||
# 带号科目项的字段映射(terms 记法见 bep_caliber.ENTITY_CALIBERS)
|
||||
_TERM_FIELD = {
|
||||
"debit": lambda: VoucherDetail.debit_amount,
|
||||
"credit": lambda: VoucherDetail.credit_amount,
|
||||
"net": lambda: VoucherDetail.debit_amount - VoucherDetail.credit_amount,
|
||||
}
|
||||
|
||||
|
||||
def _sum_terms(db, entity_id: int, period_from: str, period_to: str,
|
||||
terms, *, exclude_closing: bool = False) -> float:
|
||||
"""按「带号科目项」聚合金额(元)。terms = [(sign, code, field), ...]
|
||||
|
||||
· sign='+' ⇒ 加该科目 field 发生额;sign='-' ⇒ 减之
|
||||
· field ∈ {debit, credit, net}
|
||||
· code 以 '%' 结尾时按前缀(like)匹配,否则精确匹配
|
||||
⑤ 口径统一(2026-10-03):酣客变动成本 = (Σ5401借 + Σ5403借 + Σ571103借 − Σ530103贷)。
|
||||
"""
|
||||
total = 0.0
|
||||
for sign, code, field in terms:
|
||||
expr = _TERM_FIELD[field]()
|
||||
q = db.query(func.sum(expr)).filter(
|
||||
VoucherDetail.entity_id == entity_id,
|
||||
VoucherDetail.carry_forward == 0,
|
||||
VoucherDetail.period >= period_from,
|
||||
VoucherDetail.period <= period_to,
|
||||
)
|
||||
q = (q.filter(VoucherDetail.subject_code.like(code)) if code.endswith("%")
|
||||
else q.filter(VoucherDetail.subject_code == code))
|
||||
if exclude_closing:
|
||||
q = q.filter(or_(VoucherDetail.summary.is_(None),
|
||||
~VoucherDetail.summary.like(CLOSING_SUMMARY_LIKE)))
|
||||
v = float(q.scalar() or 0.0)
|
||||
total += v if sign == "+" else -v
|
||||
return total
|
||||
|
||||
|
||||
def compute_margin_rate(db, entity_id: int, period_from: str, period_to: str,
|
||||
caliber: dict = None) -> dict:
|
||||
"""变动成本率(YTD 累计,2 位小数)—— 按实体口径现算。
|
||||
@@ -236,9 +279,8 @@ def compute_margin_rate(db, entity_id: int, period_from: str, period_to: str,
|
||||
(调用方不得回落政策常量,须按「不可得」处理)。
|
||||
"""
|
||||
cal = caliber or ENTITY_CALIBERS[entity_id]
|
||||
num_raw = _sum_field(db, entity_id, period_from, period_to,
|
||||
cal["varcost_field"], cal["varcost_filter"],
|
||||
exclude_closing=cal["exclude_closing"])
|
||||
num_raw = _sum_terms(db, entity_id, period_from, period_to,
|
||||
cal["varcost_terms"], exclude_closing=cal["exclude_closing"])
|
||||
den_raw = _sum_field(db, entity_id, period_from, period_to,
|
||||
cal["revenue_field"], cal["revenue_filter"],
|
||||
exclude_closing=cal["exclude_closing"])
|
||||
@@ -256,7 +298,7 @@ def compute_margin_rate(db, entity_id: int, period_from: str, period_to: str,
|
||||
info["reason"] = f"{cal['margin_label']}不可得:{cal['revenue_filter'][1]} 累计缺数或为 0"
|
||||
return info
|
||||
if num_w <= 0:
|
||||
info["reason"] = f"{cal['margin_label']}不可得:{cal['varcost_filter'][1]} 累计缺数或为 0"
|
||||
info["reason"] = f"{cal['margin_label']}不可得:变动成本累计缺数或为 0"
|
||||
return info
|
||||
info["available"] = True
|
||||
info["rebate_pct"] = round(num_w / den_w * 100.0, 2)
|
||||
@@ -264,17 +306,39 @@ def compute_margin_rate(db, entity_id: int, period_from: str, period_to: str,
|
||||
|
||||
|
||||
def compute_rebate_rate(db, entity_id: int, period_from: str, period_to: str) -> dict:
|
||||
"""实测累计渠补率(2026-10-02 财务裁定口径)—— 酣客(entity1) 专用薄封装。
|
||||
"""实测累计**渠补率**(F_BEP_REBATE,2026-10-02 口径)—— 酣客(entity1) 专用。
|
||||
|
||||
渠补率(实测) = Σ(571103 借方) ÷ Σ(5001 贷方) × 100,期间 = 年初至当期(YTD),保留 2 位小数。
|
||||
· 571103 = 渠补/捐赠支出(损益类费用科目)⇒ 本期发生额落**借方**;
|
||||
· 5001 = 主营业务收入 ⇒ 本期发生额落**贷方**;
|
||||
· 行域 = carry_forward=0(与 _sum_field 一致,排除期间损益结转腿)。
|
||||
· 行域 = carry_forward=0(排除期间损益结转腿)。
|
||||
|
||||
保留本函数名/键名以兼容既有调用方与单测;通用实现见 compute_margin_rate。
|
||||
⚠️ ⑤ 口径统一(2026-10-03)后:本函数只算**渠补口径**,是 F_BEP_REBATE 的单一事实源;
|
||||
保本公式所用的**变动成本率**(销货成本+税金及附加+渠补−厂补)见 compute_margin_rate。
|
||||
博海(rebate_terms=None)无渠补科目 ⇒ 返回 available=False(F_BEP_REBATE=NULL)。
|
||||
"""
|
||||
return compute_margin_rate(db, entity_id, period_from, period_to,
|
||||
ENTITY_CALIBERS.get(entity_id))
|
||||
cal = ENTITY_CALIBERS.get(entity_id)
|
||||
if not cal or not cal.get("rebate_terms"):
|
||||
return {"available": False, "rebate_pct": None, "rebate_sum_w": 0.0,
|
||||
"sales_sum_w": 0.0, "label": "实测渠补率",
|
||||
"reason": f"{cal['name'] if cal else entity_id} 无渠补科目"}
|
||||
num_raw = _sum_terms(db, entity_id, period_from, period_to,
|
||||
cal["rebate_terms"], exclude_closing=cal["exclude_closing"])
|
||||
den_raw = _sum_field(db, entity_id, period_from, period_to,
|
||||
cal["revenue_field"], cal["revenue_filter"],
|
||||
exclude_closing=cal["exclude_closing"])
|
||||
num_w, den_w = num_raw / 10000.0, den_raw / 10000.0
|
||||
info = {"rebate_sum_w": round(num_w, 2), "sales_sum_w": round(den_w, 2),
|
||||
"rebate_pct": None, "available": False, "reason": "", "label": "实测渠补率"}
|
||||
if den_w <= 0:
|
||||
info["reason"] = "渠补率不可得:Σ5001贷累计缺数或为 0"
|
||||
return info
|
||||
if num_w <= 0:
|
||||
info["reason"] = "渠补率不可得:Σ571103借累计缺数或为 0"
|
||||
return info
|
||||
info["available"] = True
|
||||
info["rebate_pct"] = round(num_w / den_w * 100.0, 2)
|
||||
return info
|
||||
|
||||
|
||||
def _month_sales(db, entity_id: int, period: str, caliber: dict = None) -> float:
|
||||
@@ -460,9 +524,11 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
dep_avg = dep_sum_w / months
|
||||
cash_admin_avg = admin_avg - dep_avg # 现金口径固定成本(剔除折旧纸面费用)
|
||||
|
||||
# 2. 变动成本率:默认逐期实测累计(不再取政策常量;常量仅对照,仅 entity1 有)
|
||||
# 2. 变动成本率(⑤ 后=销货成本+税金及附加+渠补−厂补 完整口径):默认逐期实测累计
|
||||
rebate_info = compute_margin_rate(db, entity_id, period_from, period_to, cal)
|
||||
calc_pct = rebate_info["rebate_pct"]
|
||||
# ⑤:渠补率(e1 专用;e2 无 ⇒ available=False)。F_BEP_REBATE 专用,独立于上面变动成本率。
|
||||
rebate_kpi_info = compute_rebate_rate(db, entity_id, period_from, period_to)
|
||||
if rebate_rate_pct is not None:
|
||||
rebate_info = dict(rebate_info, available=True, rebate_pct=round(float(rebate_rate_pct), 2),
|
||||
reason="人工覆盖(--rebate-rate)")
|
||||
@@ -484,7 +550,8 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
period, cal["margin_label"], rebate_pct)
|
||||
return _fail_closed_cm_non_positive(db, entity_id, period, months, rebate_info, cal,
|
||||
kpis, write_kpi, sales_avg=sales_avg,
|
||||
admin_avg=admin_avg, dep_avg=dep_avg)
|
||||
admin_avg=admin_avg, dep_avg=dep_avg,
|
||||
rebate_kpi_info=rebate_kpi_info)
|
||||
|
||||
# 2c. fail-closed ③(2026-10-03,同族补充):固定成本退化 ⇒ 保本点不适用
|
||||
# 边际贡献率 > 0 但分子(固定成本)退化时,公式给出 保本额≈0 / 覆盖率趋于无穷,
|
||||
@@ -498,7 +565,8 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
return _fail_closed_cm_non_positive(db, entity_id, period, months, rebate_info, cal,
|
||||
kpis, write_kpi, sales_avg=sales_avg,
|
||||
admin_avg=admin_avg, dep_avg=dep_avg, guard="fixed",
|
||||
cash_admin_avg=cash_admin_avg)
|
||||
cash_admin_avg=cash_admin_avg,
|
||||
rebate_kpi_info=rebate_kpi_info)
|
||||
|
||||
# 3. 派生计算(万元 / %)——账面3条路径不变;现金口径在账面基础上剔除折旧
|
||||
bep = admin_avg / (cm_pct / 100.0)
|
||||
@@ -513,7 +581,9 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
"F_BEP_GAP": round(gap, 1),
|
||||
"F_BEP_REVENUE_CASH": round(cash_bep, 1),
|
||||
"F_BEP_COVER_CASH": round(cash_cover, 1),
|
||||
"F_BEP_REBATE": round(rebate_pct, 2),
|
||||
"F_BEP_VC_RATE": round(rebate_pct, 2), # 变动成本率(⑤ 保本分子口径)
|
||||
"F_BEP_REBATE": (round(rebate_kpi_info["rebate_pct"], 2)
|
||||
if rebate_kpi_info["available"] else None), # 实测渠补率(e1;e2=NULL)
|
||||
}
|
||||
|
||||
# 4. upsert kpi_values (source_type='derived',幂等)
|
||||
@@ -526,15 +596,20 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
if kpi is None: # 定义缺失(仅可能为 F_BEP_REBATE,见上方告警)
|
||||
written[code] = "no-definition"
|
||||
continue
|
||||
if code == REBATE_KPI:
|
||||
if entity_id == 1:
|
||||
remark = (f"实测渠补率(YTD累计): Σ571103借方 {rebate_info['rebate_sum_w']:.2f}万 ÷ "
|
||||
f"Σ5001贷方 {rebate_info['sales_sum_w']:.2f}万 × 100 = {rebate_pct:.2f}%"
|
||||
f"(政策常量 {POLICY_REBATE_RATE_PCT:.2f}% 仅供对照,不参与计算)")
|
||||
if code == VC_RATE_KPI:
|
||||
remark = (f"变动成本率(YTD累计): {cal['margin_desc']} = "
|
||||
f"{rebate_info['rebate_sum_w']:.2f}万 ÷ {rebate_info['sales_sum_w']:.2f}万 "
|
||||
f"× 100 = {rebate_pct:.2f}%(⑤口径统一:销货成本+税金及附加+渠补−厂补;"
|
||||
f"保本额 = 固定成本月均 ÷ (1−变动成本率))")
|
||||
elif code == REBATE_KPI:
|
||||
if rebate_kpi_info["available"]:
|
||||
rr = rebate_kpi_info["rebate_pct"]
|
||||
remark = (f"实测渠补率(YTD累计): Σ571103借方 {rebate_kpi_info['rebate_sum_w']:.2f}万 ÷ "
|
||||
f"Σ5001贷方 {rebate_kpi_info['sales_sum_w']:.2f}万 × 100 = {rr:.2f}%"
|
||||
f"(政策常量 {POLICY_REBATE_RATE_PCT:.2f}% 仅供对照;⑤ 后**不再充当变动成本率**,"
|
||||
f"变动成本率见 F_BEP_VC_RATE)")
|
||||
else:
|
||||
remark = (f"{cal['margin_label']}(YTD累计): {cal['margin_desc']} = "
|
||||
f"{rebate_info['rebate_sum_w']:.2f}万 ÷ {rebate_info['sales_sum_w']:.2f}万 "
|
||||
f"× 100 = {rebate_pct:.2f}%({cal['name']}口径,无渠补科目)")
|
||||
remark = f"{cal['name']}无渠补科目(实测渠补率不适用);⑤ 后变动成本率见 F_BEP_VC_RATE"
|
||||
elif code in CASH_CODES:
|
||||
if entity_id == 1:
|
||||
remark = (f"现金口径: 管理费月均{admin_avg:.2f}万-折旧月均{dep_avg:.2f}万"
|
||||
@@ -560,9 +635,11 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
is_new = existing is None
|
||||
if existing:
|
||||
old_value = float(existing.actual_value) if existing.actual_value is not None else None
|
||||
new_value = float(values[code])
|
||||
value_changed = old_value is None or abs(old_value - new_value) > 1e-9
|
||||
existing.actual_value = values[code]
|
||||
nv = values[code]
|
||||
new_value = float(nv) if nv is not None else None
|
||||
value_changed = ((old_value is None) != (new_value is None)
|
||||
or (old_value is not None and abs(old_value - new_value) > 1e-9))
|
||||
existing.actual_value = nv
|
||||
existing.source_batch = batch
|
||||
if value_changed:
|
||||
existing.remark = (f"{remark}|值已更新(batch={batch}, "
|
||||
@@ -651,8 +728,10 @@ def run_derive(db, entity_id: int, period: str, rebate_rate_pct: float = None,
|
||||
"rebate_sum_w": rebate_info["rebate_sum_w"],
|
||||
"rebate_sales_base_w": rebate_info["sales_sum_w"],
|
||||
"rebate_actual_pct": rebate_pct,
|
||||
"vc_rate_pct": rebate_pct,
|
||||
"rebate_kpi_pct": (rebate_kpi_info["rebate_pct"] if rebate_kpi_info["available"] else None),
|
||||
"rebate_policy_pct": POLICY_REBATE_RATE_PCT,
|
||||
"rebate_source": rebate_info.get("reason") or "YTD实测累计(Σ571103借方/Σ5001贷方)",
|
||||
"rebate_source": rebate_info.get("reason") or "YTD实测累计(⑤完整口径)",
|
||||
"rebate_calc_pct": round(calc_pct, 2) if calc_pct is not None else None,
|
||||
"cm_pct": round(cm_pct, 2),
|
||||
"values": values,
|
||||
@@ -734,7 +813,8 @@ def _fail_closed_cm_non_positive(db, entity_id: int, period: str, months: int,
|
||||
rebate_info: dict, cal: dict, kpis: dict, write_kpi: bool,
|
||||
sales_avg: float = None, admin_avg: float = None,
|
||||
dep_avg: float = None, guard: str = "cm",
|
||||
cash_admin_avg: float = None) -> dict:
|
||||
cash_admin_avg: float = None,
|
||||
rebate_kpi_info: dict = None) -> dict:
|
||||
"""fail-closed ② 落库:保本点**不适用**(2026-10-03 财务裁定)。
|
||||
|
||||
五条保本派生值(REVENUE/COVER/GAP/REVENUE_CASH/COVER_CASH)写
|
||||
@@ -758,14 +838,16 @@ def _fail_closed_cm_non_positive(db, entity_id: int, period: str, months: int,
|
||||
detail = (f"边际贡献非正,保本点不适用({cal['margin_label']} {rebate_pct:.2f}% ≥ 100%,"
|
||||
f"边际贡献率 {cm_pct:.2f}% ⇒ 每增一元销售不产生正贡献,保本点无经济意义;"
|
||||
f"fail-closed,禁写 0.0)")
|
||||
if entity_id == 1:
|
||||
rebate_remark = (f"实测渠补率(YTD累计): Σ571103借方 {rebate_info['rebate_sum_w']:.2f}万 ÷ "
|
||||
f"Σ5001贷方 {rebate_info['sales_sum_w']:.2f}万 × 100 = {rebate_pct:.2f}%"
|
||||
f"(政策常量 {POLICY_REBATE_RATE_PCT:.2f}% 仅供对照,不参与计算)")
|
||||
vc_rate_remark = (f"变动成本率(YTD累计): {cal['margin_desc']} = "
|
||||
f"{rebate_info['rebate_sum_w']:.2f}万 ÷ {rebate_info['sales_sum_w']:.2f}万 "
|
||||
f"× 100 = {rebate_pct:.2f}%(⑤口径统一;保本点因边际贡献非正/固定成本退化不适用)")
|
||||
if rebate_kpi_info and rebate_kpi_info.get("available"):
|
||||
rebate_remark = (f"实测渠补率(YTD累计): Σ571103借方 {rebate_kpi_info['rebate_sum_w']:.2f}万 ÷ "
|
||||
f"Σ5001贷方 {rebate_kpi_info['sales_sum_w']:.2f}万 × 100 = "
|
||||
f"{rebate_kpi_info['rebate_pct']:.2f}%(政策常量 {POLICY_REBATE_RATE_PCT:.2f}% 仅供对照;"
|
||||
f"⑤ 后不再充当变动成本率)")
|
||||
else:
|
||||
rebate_remark = (f"{cal['margin_label']}(YTD累计): {cal['margin_desc']} = "
|
||||
f"{rebate_info['rebate_sum_w']:.2f}万 ÷ {rebate_info['sales_sum_w']:.2f}万 "
|
||||
f"× 100 = {rebate_pct:.2f}%({cal['name']}口径,无渠补科目)")
|
||||
rebate_remark = f"{cal['name']}无渠补科目(实测渠补率不适用);变动成本率见 F_BEP_VC_RATE"
|
||||
batch = f"bep-{datetime.now().strftime('%Y%m%d%H%M%S')}"
|
||||
written = {}
|
||||
changed = []
|
||||
@@ -775,9 +857,16 @@ def _fail_closed_cm_non_positive(db, entity_id: int, period: str, months: int,
|
||||
if kpi is None:
|
||||
written[code] = "no-definition"
|
||||
continue
|
||||
is_rebate = (code == REBATE_KPI)
|
||||
new_val = round(float(rebate_pct), 2) if is_rebate else None
|
||||
rm = rebate_remark if is_rebate else detail
|
||||
if code == VC_RATE_KPI:
|
||||
new_val = round(float(rebate_pct), 2) # 变动成本率可测 ⇒ 照常落库
|
||||
rm = vc_rate_remark
|
||||
elif code == REBATE_KPI:
|
||||
new_val = (round(float(rebate_kpi_info["rebate_pct"]), 2)
|
||||
if rebate_kpi_info and rebate_kpi_info.get("available") else None)
|
||||
rm = rebate_remark
|
||||
else:
|
||||
new_val = None
|
||||
rm = detail
|
||||
existing = db.query(KPIValue).filter(
|
||||
KPIValue.kpi_id == kpi.id,
|
||||
KPIValue.period == period,
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
-- CMA BEP 变动成本率派生KPI定义 — F_BEP_VC_RATE(2026-10-03 ⑤ 口径统一)
|
||||
-- 依据: 任总 2026-10-03 18:00 DM「统一」+ 任务 finance-20261003-cvp-fix-and-bohai-coverage-fullstack §追加⑤
|
||||
-- 口径: 变动成本率 = 变动成本 ÷ 收入基数(YTD 累计,2位小数)
|
||||
-- · 酣客(e1): 变动成本 = Σ5401借(销货成本)+Σ5403借(税金及附加)+Σ571103借(渠补)−Σ530103贷(厂补)
|
||||
-- · 博海(e2): 变动成本 = Σ6401借(主营业务成本)
|
||||
-- 保本额 = 固定成本月均 ÷ (1 − 变动成本率)
|
||||
-- 说明: F_BEP_REBATE(实测渠补率/博海主营成本率) 保留,⑤ 后**不再充当变动成本率**
|
||||
-- 幂等: NOT EXISTS 守卫,可安全重跑
|
||||
INSERT INTO kpi_definitions
|
||||
(entity_id, kpi_code, kpi_name, dimension, category, formula, formula_desc,
|
||||
data_source_type, data_source, data_owner, frequency, unit, target_value,
|
||||
target_calc_type, threshold_green, threshold_yellow, threshold_red,
|
||||
kpi_level, status, bot_source, epic, created_by)
|
||||
SELECT 1, 'F_BEP_VC_RATE', '变动成本率', 'finance', 'profitability',
|
||||
'round((sum(5401借)+sum(5403借)+sum(571103借)-sum(530103贷))/sum(5001贷)*100,2)',
|
||||
'变动成本率(YTD累计,⑤完整口径)=(Σ5401借+Σ5403借+Σ571103借−Σ530103贷)÷Σ5001贷; 供保本点卡面单一事实源; 缺数期不出值(fail-closed)',
|
||||
'derived', 'BEP派生器 kpi_bep_deriver.py(voucher_details 5401/5403/571103/530103/5001 累计)', '财务部', 'monthly', '%', 0.00,
|
||||
'ratio', NULL, NULL, NULL,
|
||||
'strategic', 'active', 'finance-bot', 'Epic2', 1
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM kpi_definitions WHERE entity_id = 1 AND kpi_code = 'F_BEP_VC_RATE'
|
||||
);
|
||||
|
||||
INSERT INTO kpi_definitions
|
||||
(entity_id, kpi_code, kpi_name, dimension, category, formula, formula_desc,
|
||||
data_source_type, data_source, data_owner, frequency, unit, target_value,
|
||||
target_calc_type, threshold_green, threshold_yellow, threshold_red,
|
||||
kpi_level, status, bot_source, epic, created_by)
|
||||
SELECT 2, 'F_BEP_VC_RATE', '变动成本率(主营业务成本率)', 'finance', 'profitability',
|
||||
'round(sum(6401借)/sum(6001贷)*100,2)',
|
||||
'变动成本率(实测,YTD累计)=Σ6401借方÷Σ6001贷方(剔结转账腿); 博海无渠补科目; 供保本点卡面单一事实源, 无阈值',
|
||||
'derived', 'BEP派生器 kpi_bep_deriver.py(voucher_details 6401/6001 累计)', '财务部', 'monthly', '%', 0,
|
||||
'ratio', NULL, NULL, NULL,
|
||||
'strategic', 'active', 'finance-bot', 'Epic2', 1
|
||||
FROM DUAL
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM kpi_definitions WHERE entity_id = 2 AND kpi_code = 'F_BEP_VC_RATE'
|
||||
);
|
||||
Reference in New Issue
Block a user