feat(formula): 首日计提比例取整 10‰(#14 答复——图示口径覆盖公式)

- salesperson_rate 首日特判:第 1 天不递减直接取起始值(原公式 9.9889‰ 作废)
- 第 2 天起公式段不变、360 天=6‰ 锚点与 361 天=4‰ 分界不变;preview/核算共用一处
- 用例反转:首日断言改 Fraction(10,1000),补第 2 天公式段边界

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxin 2026-10-19 11:40:07 +08:00
parent cb4f38dfd9
commit 7a460cb682
2 changed files with 14 additions and 3 deletions

View File

@ -41,6 +41,10 @@ def salesperson_rate(
≤分界天数按「起始 − 天数×斜率」线性递减;超过分界天数固定取下限 ≤分界天数按「起始 − 天数×斜率」线性递减;超过分界天数固定取下限
(对照表 #4:360 天=6‰,361 天起固定 4‰)。 (对照表 #4:360 天=6‰,361 天起固定 4‰)。
首日取整(澄清 #14 业务答复 2026-10-19):第 1 天**不递减**、直接取
起始值(需规图示「第 1 天 10‰」覆盖公式的 9.9889‰)——第 2 天起按公式
递减,360 天=6‰ 锚点与 361 天=4‰ 分界均不受影响。
先款后货的回款(payment_days 为负)钳制为 0 天:负天数线性外插会算出 先款后货的回款(payment_days 为负)钳制为 0 天:负天数线性外插会算出
高于起始值的比例(多算绩效),钳到 0 天即按起始比例计提;payment_days 高于起始值的比例(多算绩效),钳到 0 天即按起始比例计提;payment_days
的出参仍照实输出负值(回款登记照常入库,录入异常由台账留痕暴露)。 的出参仍照实输出负值(回款登记照常入库,录入异常由台账留痕暴露)。
@ -48,6 +52,8 @@ def salesperson_rate(
days = max(days, 0) days = max(days, 0)
if days > boundary_days: if days > boundary_days:
return floor / 1000 return floor / 1000
if days <= 1:
return start / 1000
return (start - days * slope) / 1000 return (start - days * slope) / 1000

View File

@ -61,9 +61,14 @@ class TestSalespersonRate:
# 公式外推为 5.989‰,业务确认「360 为分界线,360 以后按千分之四」 # 公式外推为 5.989‰,业务确认「360 为分界线,360 以后按千分之四」
assert _sp_rate(361) == Fraction(4, 1000) assert _sp_rate(361) == Fraction(4, 1000)
def test_第1天按公式为899比90000_非取整为10(self) -> None: def test_首日取整10千分_图示口径裁决(self) -> None:
# 需规图示「第 1 天对应 10‰」为上限参考;公式值 = (10 − 4/360)/1000 = 899/90000 # 需规图示「第 1 天 10‰」2026-10-19 裁决覆盖公式(公式值 9.9889‰ 作废):
assert _sp_rate(1) == Fraction(899, 90000) # 首日不递减、直接取起始值;第 2 天起才进入公式段
assert _sp_rate(1) == Fraction(10, 1000)
def test_第2天起进入公式递减段(self) -> None:
# 10‰ − 2×4/360‰ = 9.9778‰(首日取整裁决只影响第 1 天,第 2 天起不变)
assert _sp_rate(2) == Fraction(10, 1000) - Fraction(2 * 4, 360 * 1000)
def test_第180天线性段中点千分之8(self) -> None: def test_第180天线性段中点千分之8(self) -> None:
assert _sp_rate(180) == Fraction(8, 1000) assert _sp_rate(180) == Fraction(8, 1000)