fix(business): 行金额乘积显式两位固化,计提比例对负天数钳制

- 明细行金额(数量2位×单价4位可产 6 位小数)直写 DECIMAL(14,2) 被
  MySQL 静默舍入且回显漂移(创建响应读内存值、复查读库值不一致);
  显式 quantize HALF_UP 固化,舍入方向与 MySQL 一致(业务/发货同改)
- 先款后货回款(payment_days 为负)线性外插会算出高于起始值的计提
  比例(多算绩效);钳制到 0 天按起始比例计提,payment_days 出参仍
  照实输出负值(口径:2026-10-14 用户裁决)
- 新增 formula 负天数钳制单测与 quantize 回显/库值一致性集成用例

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
liuwenxinandClaude Code committed 2026-10-14 18:58:30 +08:00
1 parent 91fc6f6293
commit e6c2c71d1b
5 files changed
+56 -4

No files matched your search

@@ -225,6 +225,31 @@ class TestCreate:
)
assert resp.status_code == 400, resp.text
def test_行金额乘积显式两位固化_回显与库值一致(self, client: TestClient, normal: dict) -> None:
"""数量(2位)×单价(4位) 可产 6 位小数:显式 HALF_UP 固化,与 MySQL 的
DECIMAL(14,2) 舍入方向一致 —— 直写不 quantize 会被库端静默舍入,
创建响应(读内存值)与复查(读库值)前后显示不一致。"""
headers = normal["headers"]
customer = _customer(client, headers)
data = _create(
client,
headers,
customer["id"],
items=[_item(quantity="1.55", sale_price="3.3333", cost_amount=None)],
)
# 1.55 × 3.3333 = 5.166615 → 5.17(HALF_UP;MySQL 同值同向)
item = client.get(f"{_BUSINESSES}/{data['id']}", headers=headers).json()["data"]["items"][0]
assert item["sale_amount"] == "5.17"
assert Decimal(data["total_sale_amount"]) == Decimal("5.17")
# 库值与回显一致(无「内存 5.166615 / 库里 5.17」的漂移)
factory = get_session_factory()
with factory() as session:
db_amount = session.execute(
select(BusinessItem.sale_amount).where(BusinessItem.business_id == data["id"])
).scalar_one()
assert db_amount == Decimal("5.17")
def test_明细行数量为0_400(self, client: TestClient, normal: dict) -> None:
customer = _customer(client, normal["headers"])
resp = client.post(
+8
View File
@@ -69,6 +69,14 @@ class TestSalespersonRate:
assert _sp_rate(360) == Fraction(6, 1000)
assert _sp_rate(360) != Fraction(6)
def test_负天数钳制为0天_按起始比例计提(self) -> None:
"""先款后货(payment_days 为负)不线性外插:钳到 0 天取起始比例。
修复前 days=-5 会算出 (10 + 5×4/360)‰ —— 高于起始值,多算绩效。
"""
assert _sp_rate(-5) == _sp_rate(0)
assert _sp_rate(-1) == Fraction(10, 1000)
class TestProfitRate:
"""毛利润率:不含运费口径(对照表 #2),毛利润额 / 销售额。"""