feat(核算)!: 添加 T+ 正式核算与采集托管
补齐源快照、资料预演、正式导入及工资核算的依赖链路。 新增版本化输入、逐段 FIFO、生成锁和结构化当月调整, 并提供默认关闭的周期采集、有限重试及 Windows 托管。 原始客户资料、私有配置及首页改动不纳入本次提交。 BREAKING CHANGE: 升级前需应用新增迁移,并通过 PAYROLL_MAKER_USER_ID 绑定实际工资制作人,否则业务只读。 旧单批次核算默认关闭;历史兼容需显式启用 PAYROLL_ALLOW_LEGACY_CALCULATION。生产启用和真实金额待验收。
这个提交包含在:
1 父节点
1b074576fe
当前提交
108bf87225
154 个文件已更改
+9515
-645
没有与搜索条件相匹配的文件
@@ -26,7 +26,7 @@ from app.models import PerformanceLedger, Personnel, Receipt, SecondaryAllocatio
|
||||
from app.models.receipt import SETTLEMENT_DONE
|
||||
from tests.integration.factories import business_payload, customer
|
||||
|
||||
pytestmark = pytest.mark.integration
|
||||
pytestmark = [pytest.mark.integration, pytest.mark.usefixtures("legacy_calculation")]
|
||||
|
||||
_CALC = "/api/v1/calc"
|
||||
_BUSINESSES = "/api/v1/business/businesses"
|
||||
@@ -338,8 +338,8 @@ class TestGuards:
|
||||
assert float(ledger["converted_profit"]) == -2000.0
|
||||
assert float(ledger["performance_amount"]) < 0
|
||||
|
||||
def test_准入_normal403_marketing_ops可用(
|
||||
self, client: TestClient, admin: dict, normal: dict, make_user, auth_headers
|
||||
def test_准入_未指定账号拒绝_指定制作人可用(
|
||||
self, client: TestClient, admin: dict, normal: dict, make_user, auth_headers, monkeypatch
|
||||
) -> None:
|
||||
_biz, receipt = _create_full_chain(
|
||||
client,
|
||||
@@ -354,6 +354,9 @@ class TestGuards:
|
||||
|
||||
ops = make_user(["marketing_ops"])
|
||||
ops["headers"] = auth_headers(ops)
|
||||
from app.core.config import get_settings
|
||||
assert _calc(client, ops["headers"], receipt["id"]).status_code == 403
|
||||
monkeypatch.setattr(get_settings(), "payroll_maker_user_id", ops["id"])
|
||||
resp = _calc(client, ops["headers"], receipt["id"])
|
||||
assert resp.status_code == 200, resp.text
|
||||
|
||||
@@ -426,7 +429,8 @@ class TestRecalc:
|
||||
)
|
||||
assert _calc(client, admin["headers"], receipt["id"]).status_code == 200
|
||||
|
||||
fin = finance
|
||||
assert client.post(f"{_CALC}/receipts/{receipt['id']}/recalc", json={"reason": "非制作人拒绝"}, headers=finance["headers"]).status_code == 403
|
||||
fin = admin
|
||||
resp = client.post(
|
||||
f"{_CALC}/receipts/{receipt['id']}/recalc",
|
||||
json={"reason": "成本录入修正"},
|
||||
@@ -726,7 +730,7 @@ class TestSecondaryAllocation:
|
||||
resp = client.post(
|
||||
f"{_CALC}/receipts/{receipt['id']}/recalc",
|
||||
json={"reason": "用例:分摊重算"},
|
||||
headers=finance["headers"],
|
||||
headers=admin["headers"],
|
||||
)
|
||||
assert resp.status_code == 200, resp.text
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户