pricing.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. from __future__ import annotations
  2. from app.market.scoring import CustomerSignals
  3. def round_amount(value: float, unit: int) -> float:
  4. return float(round(value / unit) * unit)
  5. def customer_adjustment_rate(customer: CustomerSignals) -> tuple[float, list[str]]:
  6. rate = 0.0
  7. reasons: list[str] = []
  8. if customer.repeat_purchase_count >= 15:
  9. rate -= 0.005
  10. reasons.append("高复购客户优惠0.5%")
  11. if customer.overdue_days > 0:
  12. rate += 0.003
  13. reasons.append("历史逾期风险调整0.3%")
  14. if customer.reliability_sensitivity >= 0.85:
  15. rate += 0.008
  16. reasons.append("高服务可靠性要求溢价0.8%")
  17. if customer.price_sensitivity >= 0.75:
  18. rate -= 0.005
  19. reasons.append("价格敏感客户优惠0.5%")
  20. return rate, reasons
  21. def build_prices(
  22. benchmark_amount: float,
  23. strategy_rate: float,
  24. solution_type: str,
  25. customer: CustomerSignals,
  26. salesperson_adjustment: float,
  27. supplier_cost: float,
  28. config: dict,
  29. ) -> dict:
  30. rounding = int(config["quote_rounding"])
  31. base_recommended = round_amount(benchmark_amount * (1 + strategy_rate), rounding)
  32. solution_delta = config["solution_price_adjustments"].get(solution_type, 0)
  33. recommended = base_recommended + solution_delta
  34. adjustment_rate, adjustment_reasons = customer_adjustment_rate(customer)
  35. customer_adjustment = round_amount(recommended * adjustment_rate, rounding)
  36. final_quote = recommended + customer_adjustment + salesperson_adjustment
  37. allowed_lower = recommended - config["allowed_lower_delta"]
  38. allowed_upper = recommended + config["allowed_upper_delta"]
  39. gross_margin_rate = (final_quote - supplier_cost) / final_quote if final_quote else 0
  40. if gross_margin_rate >= 0.12:
  41. cost_risk = "利润安全"
  42. elif gross_margin_rate >= 0.08:
  43. cost_risk = "利润偏低,建议复核"
  44. else:
  45. cost_risk = "低于利润底线,需要审批"
  46. return {
  47. "market_benchmark_amount": benchmark_amount,
  48. "strategy_adjustment_rate": strategy_rate,
  49. "ai_recommended_amount": recommended,
  50. "allowed_quote_lower_amount": allowed_lower,
  51. "allowed_quote_upper_amount": allowed_upper,
  52. "customer_adjustment_rate": round(adjustment_rate, 4),
  53. "customer_adjustment_amount": customer_adjustment,
  54. "salesperson_adjustment_amount": salesperson_adjustment,
  55. "final_quote_amount": final_quote,
  56. "currency": "CNY",
  57. "cost_risk_status": cost_risk,
  58. "adjustment_reasons": adjustment_reasons,
  59. }