fix(reports): profit-summary 真实科目取数重建(去 KPI 比率倒推/硬编码 0.50 + 勾稽自检 + entity 隔离)
ci/woodpecker/push/main Pipeline was canceled
ci/woodpecker/push/main Pipeline was canceled
This commit is contained in:
@@ -91,31 +91,46 @@ class TestProfitSummary:
|
||||
BASE = "/api/cma/reports/profit-summary"
|
||||
|
||||
def test_profit_summary_with_data(self, client: TestClient, db: Session):
|
||||
"""有数据时:营收/变动成本/边际贡献/固定成本/息税前利润 + 环比"""
|
||||
"""有真账数据时:收入/变动成本/边际贡献/固定成本/营业利润 + 勾稽自检
|
||||
|
||||
2026-10-14 重建:原断言编码了被审计实锤的 3 处硬伤(KPI 比率倒推 / 变动成本=营收×五成 /
|
||||
末行装净利率值却贴「息税前利润」),故改为断言**真实科目发生额**与勾稽自检。
|
||||
口径与逐行取数证据见 tests/test_profit_summary_real_caliber_20261014.py。
|
||||
"""
|
||||
import datetime as _dt
|
||||
from app.models import VoucherDetail
|
||||
|
||||
create_test_user(db)
|
||||
token = get_token_for_user(client)
|
||||
seed_profit_kpis(db)
|
||||
# e1 口径真账:收入 5001 贷 1,000,000;变动 5401 借 600,000;固定 5602 借 250,000(元)
|
||||
d = _dt.datetime(2026, 6, 30)
|
||||
for i, (code, dr, cr) in enumerate(
|
||||
[("5001", 0.0, 1_000_000.0), ("5401", 600_000.0, 0.0), ("5602", 250_000.0, 0.0)], start=1):
|
||||
db.add(VoucherDetail(entity_id=1, voucher_no=f"U{i}", voucher_date=d,
|
||||
subject_code=code, subject_name="单测科目",
|
||||
debit_amount=dr, credit_amount=cr, summary="单测",
|
||||
carry_forward=0, period="2026-06", batch="unit-test"))
|
||||
db.commit()
|
||||
|
||||
resp = client.get(f"{self.BASE}?period=2026-06", headers=auth_header(token))
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()
|
||||
assert data["period"] == "2026-06"
|
||||
assert data["prev_period"] == "2026-05"
|
||||
assert data["available"] is True
|
||||
items = {i["name"]: i for i in data["items"]}
|
||||
# 营业收入 100 vs 上期80 → +25%
|
||||
assert items["营业收入"]["value"] == 100.0
|
||||
assert items["营业收入"]["prev_value"] == 80.0
|
||||
assert items["营业收入"]["change_rate"] == 25.0
|
||||
# 变动成本 = 营收×50% = 50
|
||||
assert items["减:变动成本"]["value"] == 50.0
|
||||
# 边际贡献 = 毛利 = 100×20% = 20
|
||||
assert items["= 边际贡献"]["value"] == 20.0
|
||||
assert items["减:变动成本"]["value"] == 60.0 # 5401 借 600,000 元
|
||||
assert items["= 边际贡献"]["value"] == 40.0
|
||||
assert items["= 边际贡献"]["is_subtotal"] is True
|
||||
# 固定成本 = 总成本60 - 变动成本50 = 10
|
||||
assert items["减:固定成本"]["value"] == 10.0
|
||||
# 息税前利润 = 100×10% = 10
|
||||
assert items["= 息税前利润"]["value"] == 10.0
|
||||
assert items["= 息税前利润"]["is_total"] is True
|
||||
assert items["减:固定成本"]["value"] == 25.0
|
||||
# 末行标签与算法一致(原为「= 息税前利润」装净利率值)
|
||||
assert data["bottom_label"] == "营业利润"
|
||||
assert items["= 营业利润"]["value"] == 15.0
|
||||
assert items["= 营业利润"]["is_total"] is True
|
||||
# 勾稽自检:收入 − 变动成本 − 固定成本 = 末行
|
||||
assert data["reconciliation"]["balanced"] is True
|
||||
assert data["reconciliation"]["diff"] == 0.0
|
||||
|
||||
def test_profit_summary_empty_db(self, client: TestClient, db: Session):
|
||||
"""无任何KPI数据 → 200,值全部为None,不报错"""
|
||||
|
||||
Reference in New Issue
Block a user