"""正式核算与试算共用计提规则;比例保持 Fraction,产品覆盖存于参数版本。""" from fractions import Fraction from app.services import formula PERSONAL_FIELDS = ("first", "start", "slope", "floor", "boundary") BASE_CODES = { "first": "salesperson.rate.start", "start": "salesperson.rate.start", "slope": "salesperson.rate.slope", "floor": "salesperson.rate.floor", "boundary": "salesperson.days.boundary", } def personal_values(snapshot, category): """未维护产品专属项时,继续使用同日期的通用参数,不复制初始值。""" result = {} for field in PERSONAL_FIELDS: code = f"coefficient.personal.{field}" overrides = snapshot._values.get(code, {}) result[field] = overrides.get( category, overrides.get("", snapshot.get(BASE_CODES[field], role_code="salesperson")) ) return result def decide(params, *, category, customer_type, role_code, days, prepayment=False): """返回纯比例和计算基数类型。经理个人户排除优先于预收/企业户。""" if role_code == "sales_manager" or customer_type == "manager_personal": return Fraction(0), "converted", "经理本人/经理个人户不单笔计提" if role_code == "info_officer": return Fraction(str(params.get("info", "1"))) / 1000, "sales", "信息员按销售额计提" if prepayment: personal = params.get("personal", {}).get(category, params) maximum = max( Fraction(str(personal.get(key, personal["start"]))) for key in ("first", "start", "floor") ) return maximum / 1000, "converted", "预收发货后按最高比例计提" if customer_type == "enterprise": value = params.get("enterprise_by_category", {}).get(category, params["enterprise"]) return Fraction(str(value)) / 1000, "converted", "企业户按产品分类固定计提" values = params.get("personal", {}).get(category, params) if days <= 1: rate = Fraction(str(values.get("first", values["start"]))) / 1000 else: rate = formula.salesperson_rate( days, start=Fraction(str(values["start"])), slope=Fraction(str(values["slope"])), floor=Fraction(str(values["floor"])), boundary_days=int(Fraction(str(values.get("boundary", 360)))), ) return rate, "converted", "个人户按产品分类及回款阶段计提"