feat: CMA P1+P2 Round1 — 成本法对比+杜邦分析+本量利
This commit is contained in:
@@ -96,3 +96,59 @@ def api_scenario_analysis(data: dict):
|
||||
raise
|
||||
except Exception as e:
|
||||
raise HTTPException(400, f"情景模拟失败: {str(e)}")
|
||||
|
||||
|
||||
@router.post("/cvp-detailed")
|
||||
def api_cvp_detailed(data: dict):
|
||||
"""CVP本量利详细分析 — 含改善方案推演和保本图数据 (CMA P2)"""
|
||||
try:
|
||||
fixed_cost = float(data.get("fixed_cost", 617))
|
||||
variable_cost_rate = float(data.get("variable_cost_rate", 0.4862))
|
||||
unit_price = float(data.get("unit_price", 228))
|
||||
current_volume = float(data.get("current_volume", 5300))
|
||||
|
||||
contribution_margin_rate = 1 - variable_cost_rate
|
||||
breakeven_revenue = round(fixed_cost / contribution_margin_rate, 2)
|
||||
breakeven_units = round(breakeven_revenue * 10000 / unit_price, 0)
|
||||
|
||||
current_revenue = round(current_volume * unit_price / 10000, 2)
|
||||
current_profit = round(current_revenue * (1 - variable_cost_rate) - fixed_cost, 2)
|
||||
safety_margin = round((current_revenue - breakeven_revenue) / current_revenue * 100, 2) if current_revenue > 0 else 0
|
||||
|
||||
scenarios = [
|
||||
{"name": "降固定费用至300万", "fixed_cost": 300, "variable_cost_rate": variable_cost_rate,
|
||||
"breakeven_revenue": round(300 / contribution_margin_rate, 2),
|
||||
"breakeven_units": round(300 / contribution_margin_rate * 10000 / unit_price, 0)},
|
||||
{"name": "降变动成本率至30%", "fixed_cost": fixed_cost, "variable_cost_rate": 0.3,
|
||||
"breakeven_revenue": round(fixed_cost / 0.7, 2),
|
||||
"breakeven_units": round(fixed_cost / 0.7 * 10000 / unit_price, 0)},
|
||||
{"name": "两者同时改善", "fixed_cost": 300, "variable_cost_rate": 0.3,
|
||||
"breakeven_revenue": round(300 / 0.7, 2),
|
||||
"breakeven_units": round(300 / 0.7 * 10000 / unit_price, 0)},
|
||||
]
|
||||
|
||||
# 保本图数据点
|
||||
chart_data = []
|
||||
max_volume = int(max(breakeven_units * 2, current_volume * 3))
|
||||
step = max(1, int(max_volume / 20))
|
||||
for vol in range(0, int(max_volume) + step, step):
|
||||
rev = round(vol * unit_price / 10000, 2)
|
||||
tc = round(fixed_cost + rev * variable_cost_rate, 2)
|
||||
chart_data.append({"volume": vol, "revenue": rev, "total_cost": tc, "profit": round(rev - tc, 2)})
|
||||
|
||||
return {
|
||||
"fixed_cost": fixed_cost,
|
||||
"variable_cost_rate": round(variable_cost_rate * 100, 2),
|
||||
"unit_price": unit_price,
|
||||
"contribution_margin_rate": round(contribution_margin_rate * 100, 2),
|
||||
"breakeven_revenue": breakeven_revenue,
|
||||
"breakeven_units": int(breakeven_units),
|
||||
"current_revenue": current_revenue,
|
||||
"current_profit": current_profit,
|
||||
"current_volume": int(current_volume),
|
||||
"safety_margin": safety_margin,
|
||||
"scenarios": scenarios,
|
||||
"chart_data": chart_data,
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(400, f"CVP详细分析失败: {str(e)}")
|
||||
|
||||
Reference in New Issue
Block a user