"""月度指导价检查必须读取同账套的历史封存发货。""" 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"))