from __future__ import annotations from app.market.scoring import CustomerSignals def round_amount(value: float, unit: int) -> float: return float(round(value / unit) * unit) def customer_adjustment_rate(customer: CustomerSignals) -> tuple[float, list[str]]: rate = 0.0 reasons: list[str] = [] if customer.repeat_purchase_count >= 15: rate -= 0.005 reasons.append("高复购客户优惠0.5%") if customer.overdue_days > 0: rate += 0.003 reasons.append("历史逾期风险调整0.3%") if customer.reliability_sensitivity >= 0.85: rate += 0.008 reasons.append("高服务可靠性要求溢价0.8%") if customer.price_sensitivity >= 0.75: rate -= 0.005 reasons.append("价格敏感客户优惠0.5%") return rate, reasons def build_prices( benchmark_amount: float, strategy_rate: float, solution_type: str, customer: CustomerSignals, salesperson_adjustment: float, supplier_cost: float, config: dict, ) -> dict: rounding = int(config["quote_rounding"]) base_recommended = round_amount(benchmark_amount * (1 + strategy_rate), rounding) solution_delta = config["solution_price_adjustments"].get(solution_type, 0) recommended = base_recommended + solution_delta adjustment_rate, adjustment_reasons = customer_adjustment_rate(customer) customer_adjustment = round_amount(recommended * adjustment_rate, rounding) final_quote = recommended + customer_adjustment + salesperson_adjustment allowed_lower = recommended - config["allowed_lower_delta"] allowed_upper = recommended + config["allowed_upper_delta"] gross_margin_rate = (final_quote - supplier_cost) / final_quote if final_quote else 0 if gross_margin_rate >= 0.12: cost_risk = "利润安全" elif gross_margin_rate >= 0.08: cost_risk = "利润偏低,建议复核" else: cost_risk = "低于利润底线,需要审批" return { "market_benchmark_amount": benchmark_amount, "strategy_adjustment_rate": strategy_rate, "ai_recommended_amount": recommended, "allowed_quote_lower_amount": allowed_lower, "allowed_quote_upper_amount": allowed_upper, "customer_adjustment_rate": round(adjustment_rate, 4), "customer_adjustment_amount": customer_adjustment, "salesperson_adjustment_amount": salesperson_adjustment, "final_quote_amount": final_quote, "currency": "CNY", "cost_risk_status": cost_risk, "adjustment_reasons": adjustment_reasons, }