PayrollManagementSystem/backend/app/services/rate_rules.py

57 lines
2.4 KiB
Python
Raw Normal View History

"""正式核算与试算共用计提规则;比例保持 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", "个人户按产品分类及回款阶段计提"