fix(T+与核算): 对齐抵顶口径和托管说明

根据审查结果统一以物抵顶的线下核实口径,移除当前模型、初始化脚本和前端接口中的自动折算误导文案。\n补充业务接入必须持有共享 T+ 命名锁的执行契约,明确来源快照稳定性依赖。\nWindows 部署说明区分新 supervisor 与旧任务迁移检查,避免现场并行启动旧 worker。\n\n影响范围:T+ 托管文档、业务接入契约、回款/台账模型注释和参数试算说明。\n\nCo-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxin committed 2026-11-06 14:49:06 +08:00
1 parent eb4e06d1e8
commit a4794489b1
8 files changed
+127 -26

No files matched your search

+9 -2
View File
@@ -73,8 +73,11 @@ def converted_profit(revenue: Decimal, rate: Fraction, threshold: Fraction) -> D
rate 为纯比例(profit_rate 的输出);threshold 为 % 数(存储口径,如 30)。
化简式等价于定义式「毛利润额 / 毛利润率 × (毛利润率 − 阈值)」,且避免
毛利润率为 0 时除零(对照表 #12/#13)。毛利润率低于阈值时结果为负 ——
业务确认负值正常计算、不归零。
业务确认负值正常计算、不归零。零毛利润是独立特例:rate=0 时折算为 0,
不能将该特例扩大为低于阈值的折算额一律归零。
"""
if rate == 0:
return Decimal("0")
return _to_decimal(Fraction(revenue) * (rate - threshold / 100))
@@ -84,7 +87,11 @@ def performance_amount(base: Decimal, rate: Fraction) -> Decimal:
def apply_barter(amount: Decimal, discount: Fraction) -> Decimal:
"""以物抵顶折算:应发绩效 × 折算比例(discount 为 % 数,默认 80,对照表 #24)。"""
"""保留的历史以物抵顶折算函数;当前正式核算不调用。
当前口径是特殊抵顶由线下核实,系统不自动折算;参数和函数仅为历史
快照兼容保留,新增正式计算路径不得调用。
"""
return _to_decimal(Fraction(amount) * discount / 100)
+8 -8
View File
@@ -622,14 +622,14 @@ def _preview_earning(ctx: _PreviewContext, decision: _PreviewRateDecision) -> _P
def _preview_barter(ctx: _PreviewContext, performance: Decimal) -> _PreviewBarter:
"""以物抵顶折算(按应发绩效的固定比例折算,比例来自参数)。"""
applied = ctx.payload.barter
after_barter: Decimal | None = None
if applied:
discount = ctx.take("barter.discount")
after_barter = formula.apply_barter(performance, discount)
base_amount = after_barter if applied else performance
return _PreviewBarter(applied=applied, after_barter=after_barter, base_amount=base_amount)
"""以物抵顶标记(2026-11-03 口径:抵顶线下核算,系统不做自动折算)。
applied 为 False 表示没有自动折算;base_amount 照常取全额应发绩效,
after_barter 恒 None。barter.discount 参数保留作历史兼容,不参与当前试算。
"""
applied = False
base_amount = performance
return _PreviewBarter(applied=applied, after_barter=None, base_amount=base_amount)
def _preview_payment(
+6 -1
View File
@@ -621,7 +621,12 @@ def _apply_document(ctx, entity, record, children, run_no, start):
def execute_sync(session, run):
"""按单据提交;中断后幂等重跑,不生成 PayrollInput 或工资。"""
"""按单据提交;中断后幂等重跑,不生成 PayrollInput 或工资。
调用方必须先持有与 T+ 原始采集相同的 MySQL 命名锁;这样完整来源
manifest 在本次接入期间不会被另一进程发布新版本。这里仍在结束时
复核 manifest,作为防御性校验,不在本函数内再次获取同一把锁。
"""
from app.models import User
from app.services.authorization_service import require_permission
operator = session.get(User, run.requested_by)