"""核算资料参照必须能完整遍历大于单页的发货和人员。""" from datetime import date from decimal import Decimal import pytest from sqlalchemy import select from app.models import ( Business, BusinessRole, Personnel, Shipment, ShipmentItem, TPlusFact, TPlusSourceLink, User, ) from app.services import authorization_metadata, authorization_service 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)) role = session.scalar(select(BusinessRole).where(BusinessRole.role_code == "salesperson")) for number in range(205): shipment = Shipment(business_id=business.id, shipment_no=f"P{number:04}", ship_date=date(2026, 3, 1), total_amount=Decimal("1")) session.add(shipment) session.flush() session.add(ShipmentItem(shipment_id=shipment.id, product_name="测试产品", spec_model="", quantity=Decimal("1"), amount=Decimal("1"))) session.add(Personnel(personnel_name=f"测试人员{number:04}", business_role_id=role.id)) session.flush() monkeypatch.setattr(authorization_service, "require_permission", lambda *args: None) first = authorization_metadata.payroll_options(session, session.get(User, 1), business.id, page_num=1, page_size=200) second = authorization_metadata.payroll_options(session, session.get(User, 1), business.id, page_num=2, page_size=200) assert first["business_key"] == second["business_key"] == "customer:8" assert first["shipments_total"] == second["shipments_total"] == 206 assert first["personnel_total"] == second["personnel_total"] == 205 assert (len(first["shipments"]), len(second["shipments"])) == (200, 6) assert (len(first["personnel"]), len(second["personnel"])) == (200, 5) assert len({row["id"] for row in first["shipments"] + second["shipments"]}) == 206 def test_来源人员只按已确认身份关联预填且未匹配保持空值(work_session, monkeypatch): session = work_session dataset(session, shipping=True) sync(session) business = session.scalar(select(Business)) monkeypatch.setattr(authorization_service, "require_permission", lambda *args: None) before = authorization_metadata.payroll_options(session, session.get(User, 1), business.id) assert before["shipments"][0]["source_personnel_name"] == "来源员工" assert before["shipments"][0]["matched_personnel_id"] is None role = session.scalar(select(BusinessRole).where(BusinessRole.role_code == "salesperson")) person = Personnel(personnel_name="来源员工", business_role_id=role.id) session.add(person) session.flush() # 相同姓名本身不是身份关联。 unmatched = authorization_metadata.payroll_options(session, session.get(User, 1), business.id) assert unmatched["shipments"][0]["matched_personnel_id"] is None other_source = TPlusSourceLink(source_database="other_source", entity_type="personnel", source_id="1", target_id=person.id) session.add(other_source) session.flush() assert authorization_metadata.payroll_options(session, session.get(User, 1), business.id)["shipments"][0]["matched_personnel_id"] is None session.delete(other_source) session.flush() session.add(TPlusSourceLink(source_database="test_source", entity_type="personnel", source_id="1", target_id=person.id)) session.flush() matched = authorization_metadata.payroll_options(session, session.get(User, 1), business.id) assert matched["shipments"][0]["matched_personnel_id"] == person.id def test_核算参照复用同来源已封存的单位指导成本(work_session, monkeypatch): session = work_session dataset(session, shipping=True) sync(session) business = session.scalar(select(Business)) item = session.scalar(select(ShipmentItem)) monkeypatch.setattr(authorization_service, "require_permission", lambda *args: None) initial = authorization_metadata.payroll_options(session, session.get(User, 1), business.id)["shipments"][0] assert initial["guidance_status"] == "MISSING" and initial["guidance_unit_cost"] is None data = {"product_id": "9", "month": "2026-03", "basis": "UNIT", "amount": "2.1234", "unit": item.unit, "is_finalized": True} session.add(TPlusFact(source_database="test_source", kind="GUIDANCE", fact_key="price9-03", version=1, data_json=data, evidence="历史记录", requested_by=1)) session.flush() ready = authorization_metadata.payroll_options(session, session.get(User, 1), business.id)["shipments"][0] assert (ready["guidance_status"], ready["guidance_unit_cost"]) == ("FINALIZED_UNIT", "2.1234") session.add(TPlusFact(source_database="test_source", kind="GUIDANCE", fact_key="duplicate9-03", version=1, data_json=data, evidence="历史重复记录", requested_by=1)) session.flush() conflict = authorization_metadata.payroll_options(session, session.get(User, 1), business.id)["shipments"][0] assert conflict["guidance_status"] == "AMBIGUOUS" and conflict["guidance_unit_cost"] is None @pytest.mark.parametrize("page_num,page_size", [(0, 200), (1, 0), (1, 201)]) def test_核算参照拒绝无效页码与页大小(work_session, monkeypatch, page_num, page_size): monkeypatch.setattr(authorization_service, "require_permission", lambda *args: None) with pytest.raises(ValueError): authorization_metadata.payroll_options(work_session, work_session.get(User, 1), 1, page_num=page_num, page_size=page_size)