PayrollManagementSystem/backend/tests/unit/test_tplus_guidance_history.py
liuwenxin 1e53792ad6 feat(T+): 完成数据贯通与自动接入闭环
打通 T+ 快照、业务、发货、回款和核算准备链路,保留来源差异并提供待补状态。
新增业务自动接入任务、跨平台读取服务托管、权限复核、来源关联和前端核对页面。
补充迁移、隔离集成测试、浏览器模拟验收及角色授权边界修复。
2026-11-05 18:47:13 +08:00

96 lines
4.5 KiB
Python

"""月度指导价检查必须读取同账套的历史封存发货。"""
from datetime import date
from decimal import Decimal
import pytest
from sqlalchemy import select
from app.core.exceptions import BadRequestError
from app.models import (
Business,
Customer,
PayrollInput,
Product,
Shipment,
ShipmentItem,
TPlusBusinessDocument,
TPlusSourceLink,
User,
)
from app.schemas.business_source import GuidanceConfirmIn
from app.services import business_source
from app.services.tplus.guidance import frozen_guidance_shipments
from tests.unit.test_tplus_business_sync import dataset, sync
from tests.unit.test_tplus_workbench import work_session as work_session
def test_登记指导成本校验已应用的发货单版本(work_session, monkeypatch):
session = work_session
dataset(session, shipping=True)
sync(session)
business = session.scalar(select(Business))
item = session.scalar(select(ShipmentItem))
actor = session.get(User, 1)
monkeypatch.setattr(business_source, "source_snapshot_ready", lambda *_: True)
payload = GuidanceConfirmIn(shipment_item_id=item.id, amount="2.1234", evidence="核对指导成本")
created = business_source.confirm_guidance(session, business.id, payload, actor)
assert created["status"] == "CREATED"
assert business_source.confirm_guidance(session, business.id, payload, actor)["status"] == "REUSED"
parent = session.scalar(select(TPlusBusinessDocument).where(
TPlusBusinessDocument.entity_type == "shipments"
))
line = session.scalar(select(TPlusBusinessDocument).where(
TPlusBusinessDocument.entity_type == "shipment_items"
))
parent.applied_record_id = line.applied_record_id
session.commit()
with pytest.raises(BadRequestError, match="来源单据已变化"):
business_source.confirm_guidance(session, business.id, payload, actor)
def test_只返回来源产品与历史月份匹配的已封存发货(work_session):
session = work_session
customer = Customer(company_name="测试客户", owner_name="", customer_type="personal")
product = Product(product_name="测试产品", spec_model="", unit="根", product_category="municipal_water")
session.add_all([customer, product])
session.flush()
session.add(TPlusSourceLink(source_database="test_source", entity_type="products", source_id="9", target_id=product.id))
business = Business(business_no="GUIDE-HISTORY", customer_id=customer.id)
session.add(business)
session.flush()
shipment = Shipment(business_id=business.id, shipment_no="GUIDE-SHIP", ship_date=date(2026, 4, 1))
session.add(shipment)
session.flush()
item = ShipmentItem(shipment_id=shipment.id, product_id=product.id, product_name="测试产品", spec_model="",
unit="根", quantity=Decimal("2"), amount=Decimal("100"))
session.add(item)
session.flush()
record = {"line_id": "source-line-999", "product_id": "9", "date": "2026-03-10", "unit": "根", "unit_cost": "10"}
session.add_all([
PayrollInput(business_id=business.id, version=1, source_database="test_source", group_key="g",
fingerprint="a" * 64, data_json={"shipments": [record]}, requested_by=1),
PayrollInput(business_id=business.id, version=2, source_database="test_source", group_key="g",
fingerprint="b" * 64, data_json={"shipments": [{**record, "unit_cost": "11"}]}, requested_by=1),
])
session.flush()
rows = list(frozen_guidance_shipments(session, "test_source", "9", "2026-03"))
assert [row["unit_cost"] for row in rows] == ["10", "11"]
assert list(frozen_guidance_shipments(session, "test_source", "9", "2026-04")) == []
assert list(frozen_guidance_shipments(session, "other_source", "9", "2026-03")) == []
assert list(frozen_guidance_shipments(session, "test_source", "10", "2026-03")) == []
session.delete(item)
session.flush()
assert len(list(frozen_guidance_shipments(session, "test_source", "9", "2026-03"))) == 2
broken = session.get(PayrollInput, 1)
broken.data_json = {"shipments": [{**record, "product_id": None}]}
session.flush()
with pytest.raises(BadRequestError, match="缺少来源产品身份"):
list(frozen_guidance_shipments(session, "test_source", "9", "2026-03"))
broken = session.get(PayrollInput, 1)
broken.data_json = {"shipments": [{"date": "2026-03-10", "unit_cost": "10"}]}
session.flush()
with pytest.raises(BadRequestError, match="已封存发货数据异常"):
list(frozen_guidance_shipments(session, "test_source", "9", "2026-03"))