feat(P1-3): 相关成本决策模块 — 官方25%权重'商业决策分析'核心
新增 /predict/relevant-decision API + 前端Tab(3场景):
1. 自制vs外购: 相关成本比较+无差别点(增量成本视角)
2. 特殊订单: 剩余产能下价格>变动成本即接受(增量利润)
3. 产品组合(约束理论): 单位约束资源边际贡献排序
验证: 自制850k vs 外购900k→自制; 特殊订单单位贡献25→接受;
产品组合B产品单位约束贡献50最高→优先
This commit is contained in:
@@ -161,6 +161,97 @@ def api_cvp_detailed(data: dict):
|
||||
raise HTTPException(400, f"CVP详细分析失败: {str(e)}")
|
||||
|
||||
|
||||
# ── 相关成本决策(CMA P2商业决策分析25%权重核心) ──────────────────
|
||||
|
||||
|
||||
@router.post("/relevant-decision")
|
||||
def api_relevant_decision(data: dict):
|
||||
"""相关成本决策分析(CMA P2 商业决策分析核心内容)
|
||||
场景: make-or-buy自制外购 / special-order特殊订单 / product-mix产品组合
|
||||
"""
|
||||
try:
|
||||
decision_type = data.get("type", "make_or_buy")
|
||||
|
||||
if decision_type == "make_or_buy":
|
||||
# 自制vs外购决策
|
||||
# 相关成本 = 增量成本(只有随决策变化的成本才是相关的)
|
||||
make_var_cost = float(data.get("make_variable_cost", 0)) # 自制单位变动成本
|
||||
make_fixed = float(data.get("make_fixed_cost", 0)) # 自制新增固定成本
|
||||
buy_price = float(data.get("buy_price", 0)) # 外购单价
|
||||
demand = float(data.get("demand", 0)) # 需求量
|
||||
existing_fixed = float(data.get("existing_fixed_cost", 0)) # 现有固定成本(无关成本,自制不增加则忽略)
|
||||
|
||||
make_total = make_var_cost * demand + make_fixed
|
||||
buy_total = buy_price * demand
|
||||
diff = buy_total - make_total # >0自制省钱
|
||||
|
||||
return {
|
||||
"type": "自制vs外购",
|
||||
"make_total_cost": round(make_total, 2),
|
||||
"buy_total_cost": round(buy_total, 2),
|
||||
"difference": round(diff, 2),
|
||||
"recommendation": "自制" if diff > 0 else "外购",
|
||||
"reason": f"自制总成本{make_total:.2f} vs 外购总成本{buy_total:.2f},{'自制节省' + str(round(diff,2)) if diff > 0 else '外购节省' + str(round(-diff,2))}",
|
||||
"unit_make_cost": round(make_var_cost + (make_fixed / demand if demand else 0), 2),
|
||||
"unit_buy_price": buy_price,
|
||||
"indifferent_point": round(make_fixed / (buy_price - make_var_cost), 2) if buy_price > make_var_cost else None,
|
||||
"notes": "仅考虑相关成本(增量成本);现有固定成本若不受决策影响则无关",
|
||||
}
|
||||
|
||||
elif decision_type == "special_order":
|
||||
# 特殊订单决策(有剩余产能时,只要价格>单位变动成本即接受)
|
||||
normal_price = float(data.get("normal_price", 0))
|
||||
special_price = float(data.get("special_price", 0))
|
||||
var_cost = float(data.get("variable_cost", 0))
|
||||
order_qty = float(data.get("order_qty", 0))
|
||||
capacity_used = float(data.get("capacity_used", 0)) # 特殊订单占用产能%
|
||||
extra_fixed = float(data.get("extra_fixed_cost", 0)) # 一次性额外固定成本
|
||||
|
||||
contribution_per_unit = special_price - var_cost
|
||||
total_contribution = contribution_per_unit * order_qty - extra_fixed
|
||||
accept = total_contribution > 0 and capacity_used <= 100
|
||||
|
||||
return {
|
||||
"type": "特殊订单",
|
||||
"unit_contribution": round(contribution_per_unit, 2),
|
||||
"total_contribution": round(total_contribution, 2),
|
||||
"extra_fixed_cost": extra_fixed,
|
||||
"capacity_used_pct": capacity_used,
|
||||
"recommendation": "接受" if accept else "拒绝",
|
||||
"reason": f"单价{special_price} - 变动成本{var_cost} = 单位贡献{contribution_per_unit:.2f}" +
|
||||
(f",共{total_contribution:.2f} > 0 且产能{capacity_used}%够用 → 接受(增量利润)" if accept else
|
||||
f",总贡献{total_contribution:.2f} ≤ 0 或产能不足 → 拒绝"),
|
||||
"notes": "有剩余产能时,只要价格>变动成本且不冲击正常市场即可接受;固定成本无关",
|
||||
}
|
||||
|
||||
elif decision_type == "product_mix":
|
||||
# 产品组合决策(约束理论:单位约束资源的边际贡献最大者优先)
|
||||
products = data.get("products", []) # [{name, price, var_cost, constraint_usage, demand}]
|
||||
results = []
|
||||
for p in products:
|
||||
cm_per_unit = float(p.get("price", 0)) - float(p.get("var_cost", 0))
|
||||
cm_per_constraint = cm_per_unit / float(p.get("constraint_usage", 1))
|
||||
results.append({
|
||||
"name": p.get("name", ""),
|
||||
"unit_contribution": round(cm_per_unit, 2),
|
||||
"constraint_usage": float(p.get("constraint_usage", 1)),
|
||||
"contribution_per_constraint": round(cm_per_constraint, 2),
|
||||
"demand": float(p.get("demand", 0)),
|
||||
})
|
||||
# 按单位约束资源贡献排序(约束理论优先)
|
||||
results.sort(key=lambda x: x["contribution_per_constraint"], reverse=True)
|
||||
return {
|
||||
"type": "产品组合(约束理论)",
|
||||
"ranking": results,
|
||||
"recommendation": f"优先生产「{results[0]['name']}」(单位约束贡献{results[0]['contribution_per_constraint']}最高)",
|
||||
"notes": "瓶颈资源下,按单位约束资源的边际贡献排序,而非单位边际贡献",
|
||||
}
|
||||
|
||||
raise HTTPException(400, "未知决策类型: " + str(decision_type))
|
||||
except Exception as e:
|
||||
raise HTTPException(400, f"相关成本决策失败: {str(e)}")
|
||||
|
||||
|
||||
# ── 现金流预测(AI事前预警) ────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user